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
February 2022
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
17 participants
108 discussions
Start a n
N
ew thread
[reactos] 01/01: [README] Add Discord server join link (#4352)
by Andrej Bartulin
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7bfc35c3664721dd4559e…
commit 7bfc35c3664721dd4559e62c8c9363c44f4f44ee Author: Andrej Bartulin <andrej.bartulinvr(a)gmail.com> AuthorDate: Wed Feb 16 17:04:44 2022 +0100 Commit: GitHub <noreply(a)github.com> CommitDate: Wed Feb 16 19:04:44 2022 +0300 [README] Add Discord server join link (#4352) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7aca79cd35f..67c367f8c63 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ [Official
chat](https://chat.reactos.org/)
• [
Wiki](https://reactos.org/wiki/)
• [
Forum](https://reactos.org/forum/)
• +[Community Discord](https://discord.gg/7knjvhT) • [JIRA Bug
Tracker](https://jira.reactos.org/issues/)
• [ReactOS Git
mirror](https://git.reactos.org/)
• [
Testman](https://reactos.org/testman/)
2 years, 10 months
1
0
0
0
[reactos] 01/01: [SHELL32] Stop SHELL_execute from always executing files (#4363)
by Alex Miccolis
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9b716539182864bc077e3…
commit 9b716539182864bc077e362febcda74da50287ed Author: Alex Miccolis <alex.miccolis1(a)gmail.com> AuthorDate: Tue Feb 15 17:54:20 2022 -0600 Commit: GitHub <noreply(a)github.com> CommitDate: Wed Feb 16 00:54:20 2022 +0100 [SHELL32] Stop SHELL_execute from always executing files (#4363) CORE-18038 Add a check (PathIsExeW) to SHELL_execute to prevent it from executing non-exe files. --- dll/win32/shell32/shlexec.cpp | 55 ++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index b8f3bb2ca16..f1fce51cc9f 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -25,6 +25,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(exec); +EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath); + #define SEE_MASK_CLASSALL (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY) typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, @@ -2139,32 +2141,37 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) lpFile = sei_tmp.lpFile; wcmd = wcmdBuffer; - len = lstrlenW(wszApplicationName) + 3; - if (sei_tmp.lpParameters[0]) - len += 1 + lstrlenW(wszParameters); - if (len > wcmdLen) - { - wcmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - wcmdLen = len; - } - swprintf(wcmd, L"\"%s\"", wszApplicationName); - if (sei_tmp.lpParameters[0]) - { - strcatW(wcmd, L" "); - strcatW(wcmd, wszParameters); - } - retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei); - if (retval > 32) + /* Only execute if it has an executable extension */ + if (PathIsExeW(lpFile)) { - HeapFree(GetProcessHeap(), 0, wszApplicationName); - if (wszParameters != parametersBuffer) - HeapFree(GetProcessHeap(), 0, wszParameters); - if (wszDir != dirBuffer) - HeapFree(GetProcessHeap(), 0, wszDir); - if (wcmd != wcmdBuffer) - HeapFree(GetProcessHeap(), 0, wcmd); - return TRUE; + len = lstrlenW(wszApplicationName) + 3; + if (sei_tmp.lpParameters[0]) + len += 1 + lstrlenW(wszParameters); + if (len > wcmdLen) + { + wcmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + wcmdLen = len; + } + swprintf(wcmd, L"\"%s\"", wszApplicationName); + if (sei_tmp.lpParameters[0]) + { + strcatW(wcmd, L" "); + strcatW(wcmd, wszParameters); + } + + retval = execfunc(wcmd, NULL, FALSE, &sei_tmp, sei); + if (retval > 32) + { + HeapFree(GetProcessHeap(), 0, wszApplicationName); + if (wszParameters != parametersBuffer) + HeapFree(GetProcessHeap(), 0, wszParameters); + if (wszDir != dirBuffer) + HeapFree(GetProcessHeap(), 0, wszDir); + if (wcmd != wcmdBuffer) + HeapFree(GetProcessHeap(), 0, wcmd); + return TRUE; + } } /* Else, try to find the executable */
2 years, 10 months
1
0
0
0
[reactos] 01/01: [USER32] Use UINT as parameter for DrawText() (#4357)
by Robert Naumann
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d64ab28b5f945cac402e2…
commit d64ab28b5f945cac402e2c36b5e283bc2c292d0a Author: Robert Naumann <gonzomdx(a)gmail.com> AuthorDate: Wed Feb 16 00:50:51 2022 +0100 Commit: GitHub <noreply(a)github.com> CommitDate: Wed Feb 16 00:50:51 2022 +0100 [USER32] Use UINT as parameter for DrawText() (#4357) Import Wine Commit 0ba1bfb0624d5e95f15499d6cfc9af1910c7c5be by Marcus Meissner: user32: DrawText gets a 32bit flag, not a 16bit flag. Fixes CORE-17315 - spottted by I_Kill_Bugs --- win32ss/user/user32/controls/static.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/win32ss/user/user32/controls/static.c b/win32ss/user/user32/controls/static.c index 5ddd4d8e677..3ae50684b6f 100644 --- a/win32ss/user/user32/controls/static.c +++ b/win32ss/user/user32/controls/static.c @@ -158,7 +158,7 @@ static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style ) SetWindowPos( hwnd, 0, 0, 0, bm.bmWidth, bm.bmHeight, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); } - + } return hOldBitmap; } @@ -327,7 +327,7 @@ static BOOL hasTextStyle( DWORD style ) case SS_OWNERDRAW: return TRUE; } - + return FALSE; } @@ -616,7 +616,7 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style ) RECT rc; HBRUSH hBrush; HFONT hFont, hOldFont = NULL; - WORD wFormat; + UINT format; INT len, buf_size; WCHAR *text; @@ -625,23 +625,23 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style ) switch (style & SS_TYPEMASK) { case SS_LEFT: - wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK; + format = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK; break; case SS_CENTER: - wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK; + format = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK; break; case SS_RIGHT: - wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK; + format = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK; break; case SS_SIMPLE: - wFormat = DT_LEFT | DT_SINGLELINE; + format = DT_LEFT | DT_SINGLELINE; break; case SS_LEFTNOWORDWRAP: - wFormat = DT_LEFT | DT_EXPANDTABS; + format = DT_LEFT | DT_EXPANDTABS; break; default: @@ -649,25 +649,25 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style ) } if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_RIGHT) - wFormat = DT_RIGHT | (wFormat & ~(DT_LEFT | DT_CENTER)); + format = DT_RIGHT | (format & ~(DT_LEFT | DT_CENTER)); if (style & SS_NOPREFIX) - wFormat |= DT_NOPREFIX; + format |= DT_NOPREFIX; else if (GetWindowLongW(hwnd, UISTATE_GWL_OFFSET) & UISF_HIDEACCEL) // ReactOS r30727 - wFormat |= DT_HIDEPREFIX; + format |= DT_HIDEPREFIX; if ((style & SS_TYPEMASK) != SS_SIMPLE) { if (style & SS_CENTERIMAGE) - wFormat |= DT_SINGLELINE | DT_VCENTER; + format |= DT_SINGLELINE | DT_VCENTER; if (style & SS_EDITCONTROL) - wFormat |= DT_EDITCONTROL; + format |= DT_EDITCONTROL; if (style & SS_ENDELLIPSIS) - wFormat |= DT_SINGLELINE | DT_END_ELLIPSIS; + format |= DT_SINGLELINE | DT_END_ELLIPSIS; if (style & SS_PATHELLIPSIS) - wFormat |= DT_SINGLELINE | DT_PATH_ELLIPSIS; + format |= DT_SINGLELINE | DT_PATH_ELLIPSIS; if (style & SS_WORDELLIPSIS) - wFormat |= DT_SINGLELINE | DT_WORD_ELLIPSIS; + format |= DT_SINGLELINE | DT_WORD_ELLIPSIS; } if ((hFont = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET ))) @@ -706,7 +706,7 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style ) } else { - DrawTextW( hdc, text, -1, &rc, wFormat ); + DrawTextW( hdc, text, -1, &rc, format ); } no_TextOut:
2 years, 10 months
1
0
0
0
[reactos] 02/02: [FREELDR:UI] Cleanup for the DrawMenu* functions.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a7e358406575d555b6ae8…
commit a7e358406575d555b6ae82aca45e5b8758049dc9 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Fri Jan 7 22:49:06 2022 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Wed Feb 16 00:49:48 2022 +0100 [FREELDR:UI] Cleanup for the DrawMenu* functions. - Remove duplicated code from directui.c and use the one from TUI instead, with the latter properly #ifdef'ed for _M_ARM. - Add SAL annotations. --- boot/freeldr/freeldr/include/ui/minitui.h | 16 +- boot/freeldr/freeldr/include/ui/noui.h | 16 +- boot/freeldr/freeldr/include/ui/tui.h | 31 ++- boot/freeldr/freeldr/ui/directui.c | 379 ++---------------------------- boot/freeldr/freeldr/ui/minitui.c | 11 +- boot/freeldr/freeldr/ui/noui.c | 4 +- boot/freeldr/freeldr/ui/tuimenu.c | 110 +++++++-- 7 files changed, 144 insertions(+), 423 deletions(-) diff --git a/boot/freeldr/freeldr/include/ui/minitui.h b/boot/freeldr/freeldr/include/ui/minitui.h index eba12bc1ec6..4a710cd8b6f 100644 --- a/boot/freeldr/freeldr/include/ui/minitui.h +++ b/boot/freeldr/freeldr/include/ui/minitui.h @@ -8,11 +8,7 @@ #pragma once -/////////////////////////////////////////////////////////////////////////////////////// -// -// Textual User Interface Functions -// -/////////////////////////////////////////////////////////////////////////////////////// +/* Textual User Interface Functions ******************************************/ VOID MiniTuiDrawBackdrop(VOID); VOID MiniTuiDrawStatusText(PCSTR StatusText); @@ -35,12 +31,10 @@ MiniTuiDrawProgressBar( _In_ ULONG Range, _Inout_z_ PSTR ProgressText); -/////////////////////////////////////////////////////////////////////////////////////// -// -// Menu Functions -// -/////////////////////////////////////////////////////////////////////////////////////// +/* Menu Functions ************************************************************/ -VOID MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo); +VOID +MiniTuiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo); extern const UIVTBL MiniTuiVtbl; diff --git a/boot/freeldr/freeldr/include/ui/noui.h b/boot/freeldr/freeldr/include/ui/noui.h index 1bd560ad25d..dca5db172e0 100644 --- a/boot/freeldr/freeldr/include/ui/noui.h +++ b/boot/freeldr/freeldr/include/ui/noui.h @@ -8,11 +8,7 @@ #pragma once -/////////////////////////////////////////////////////////////////////////////////////// -// -// No User Interface Functions -// -/////////////////////////////////////////////////////////////////////////////////////// +/* No User Interface Functions ***********************************************/ BOOLEAN NoUiInitialize(VOID); VOID NoUiUnInitialize(VOID); @@ -78,11 +74,7 @@ UCHAR NoUiTextToFillStyle(PCSTR FillStyleText); VOID NoUiFadeInBackdrop(VOID); VOID NoUiFadeOut(VOID); -/////////////////////////////////////////////////////////////////////////////////////// -// -// Menu Functions -// -/////////////////////////////////////////////////////////////////////////////////////// +/* Menu Functions ************************************************************/ BOOLEAN NoUiDisplayMenu( @@ -98,4 +90,6 @@ NoUiDisplayMenu( IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL, IN PVOID Context OPTIONAL); -VOID NoUiDrawMenu(PUI_MENU_INFO MenuInfo); +VOID +NoUiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo); diff --git a/boot/freeldr/freeldr/include/ui/tui.h b/boot/freeldr/freeldr/include/ui/tui.h index a486ef5cdec..27918f47bd7 100644 --- a/boot/freeldr/freeldr/include/ui/tui.h +++ b/boot/freeldr/freeldr/include/ui/tui.h @@ -28,11 +28,7 @@ TuiPrintf( #define TUI_TITLE_BOX_CHAR_HEIGHT 5 -/////////////////////////////////////////////////////////////////////////////////////// -// -// Textual User Interface Functions -// -/////////////////////////////////////////////////////////////////////////////////////// +/* Textual User Interface Functions ******************************************/ BOOLEAN TuiInitialize(VOID); // Initialize User-Interface VOID TuiUnInitialize(VOID); // Un-initialize User-Interface @@ -101,17 +97,20 @@ UCHAR TuiTextToFillStyle(PCSTR FillStyleText); // Converts the VOID TuiFadeInBackdrop(VOID); // Draws the backdrop and fades the screen in VOID TuiFadeOut(VOID); // Fades the screen out -/////////////////////////////////////////////////////////////////////////////////////// -// -// Menu Functions -// -/////////////////////////////////////////////////////////////////////////////////////// - -VOID TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo); -VOID TuiDrawMenu(PUI_MENU_INFO MenuInfo); -VOID TuiDrawMenuBox(PUI_MENU_INFO MenuInfo); -VOID TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, ULONG MenuItemNumber); -ULONG TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo, UiMenuKeyPressFilterCallback KeyPressFilter); +/* Menu Functions ************************************************************/ + +VOID +TuiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo); + +VOID +TuiDrawMenuBox( + _In_ PUI_MENU_INFO MenuInfo); + +VOID +TuiDrawMenuItem( + _In_ PUI_MENU_INFO MenuInfo, + _In_ ULONG MenuItemNumber); BOOLEAN TuiDisplayMenu( diff --git a/boot/freeldr/freeldr/ui/directui.c b/boot/freeldr/freeldr/ui/directui.c index 7021a86cdbc..dbd2ed41902 100644 --- a/boot/freeldr/freeldr/ui/directui.c +++ b/boot/freeldr/freeldr/ui/directui.c @@ -158,279 +158,10 @@ UiTruncateStringEllipsis(IN PCHAR StringText, } VOID -UiDrawMenuBox(IN PUI_MENU_INFO MenuInfo) +UiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo) { - CHAR MenuLineText[80], TempString[80]; - ULONG i; - - /* If there is a timeout draw the time remaining */ - if (MenuInfo->MenuTimeRemaining >= 0) - { - /* Copy the integral time text string, and remove the last 2 chars */ - strcpy(TempString, UiTimeText); - i = strlen(TempString); - TempString[i - 2] = 0; - - /* Display the first part of the string and the remaining time */ - strcpy(MenuLineText, TempString); - _itoa(MenuInfo->MenuTimeRemaining, TempString, 10); - strcat(MenuLineText, TempString); - - /* Add the last 2 chars */ - strcat(MenuLineText, &UiTimeText[i - 2]); - - /* Display under the menu directly */ - UiDrawText(0, - MenuInfo->Bottom + 4, - MenuLineText, - ATTR(UiMenuFgColor, UiMenuBgColor)); - } - else - { - /* Erase the timeout string with spaces, and 0-terminate for sure */ - for (i=0; i<sizeof(MenuLineText)-1; i++) - { - MenuLineText[i] = ' '; - } - MenuLineText[sizeof(MenuLineText)-1] = 0; - - /* Draw this "empty" string to erase */ - UiDrawText(0, - MenuInfo->Bottom + 4, - MenuLineText, - ATTR(UiMenuFgColor, UiMenuBgColor)); - } - - /* Loop each item */ - for (i = 0; i < MenuInfo->MenuItemCount; i++) - { - /* Check if it's a separator */ - if (MenuInfo->MenuItemList[i] == NULL) - { - /* Draw the separator line */ - UiDrawText(MenuInfo->Left, - MenuInfo->Top + i + 1, - "\xC7", - ATTR(UiMenuFgColor, UiMenuBgColor)); - UiDrawText(MenuInfo->Right, - MenuInfo->Top + i + 1, - "\xB6", - ATTR(UiMenuFgColor, UiMenuBgColor)); - } - } -} - -VOID -UiDrawMenuItem(IN PUI_MENU_INFO MenuInfo, - IN ULONG MenuItemNumber) -{ - CHAR MenuLineText[80]; - UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor); - - /* Simply left-align it */ - MenuLineText[0] = '\0'; - strcat(MenuLineText, " "); - - /* Now append the text string */ - if (MenuInfo->MenuItemList[MenuItemNumber]) - strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]); - - /* If it is a separator */ - if (MenuInfo->MenuItemList[MenuItemNumber] == NULL) - { - /* Make it a separator line and use menu colors */ - memset(MenuLineText, 0, sizeof(MenuLineText)); - memset(MenuLineText, 0xC4, (MenuInfo->Right - MenuInfo->Left - 1)); - Attribute = ATTR(UiMenuFgColor, UiMenuBgColor); - } - else if (MenuItemNumber == MenuInfo->SelectedMenuItem) - { - /* If this is the selected item, use the selected colors */ - Attribute = ATTR(UiSelectedTextColor, UiSelectedTextBgColor); - } - - /* Draw the item */ - UiDrawText(MenuInfo->Left + 1, - MenuInfo->Top + 1 + MenuItemNumber, - MenuLineText, - Attribute); -} - -VOID -UiDrawMenu(IN PUI_MENU_INFO MenuInfo) -{ - ULONG i; - - /* No GUI status bar text, just minimal text. Show the menu header. */ - if (MenuInfo->MenuHeader) - { - UiDrawText(0, - MenuInfo->Top - 2, - MenuInfo->MenuHeader, - ATTR(UiMenuFgColor, UiMenuBgColor)); - } - - /* Now tell the user how to choose */ - UiDrawText(0, - MenuInfo->Bottom + 1, - "Use \x18 and \x19 to move the highlight to your choice.", - ATTR(UiMenuFgColor, UiMenuBgColor)); - UiDrawText(0, - MenuInfo->Bottom + 2, - "Press ENTER to choose.", - ATTR(UiMenuFgColor, UiMenuBgColor)); - - /* And show the menu footer */ - if (MenuInfo->MenuFooter) - { - UiDrawText(0, - UiScreenHeight - 4, - MenuInfo->MenuFooter, - ATTR(UiMenuFgColor, UiMenuBgColor)); - } - - /* Draw the menu box */ - UiDrawMenuBox(MenuInfo); - - /* Draw each line of the menu */ - for (i = 0; i < MenuInfo->MenuItemCount; i++) - { - UiDrawMenuItem(MenuInfo, i); - } - - /* Display the boot options if needed */ - if (MenuInfo->ShowBootOptions) - { - DisplayBootTimeOptions(); - } -} - -ULONG -UiProcessMenuKeyboardEvent(IN PUI_MENU_INFO MenuInfo, - IN UiMenuKeyPressFilterCallback KeyPressFilter) -{ - ULONG KeyEvent = 0; - ULONG Selected, Count; - - /* Check for a keypress */ - if (!MachConsKbHit()) - return 0; // None, bail out - - /* Check if the timeout is not already complete */ - if (MenuInfo->MenuTimeRemaining != -1) - { - /* Cancel it and remove it */ - MenuInfo->MenuTimeRemaining = -1; - UiDrawMenuBox(MenuInfo); - } - - /* Get the key (get the extended key if needed) */ - KeyEvent = MachConsGetCh(); - if (KeyEvent == KEY_EXTENDED) - KeyEvent = MachConsGetCh(); - - /* - * Call the supplied key filter callback function to see - * if it is going to handle this keypress. - */ - if (KeyPressFilter && - KeyPressFilter(KeyEvent, MenuInfo->SelectedMenuItem, MenuInfo->Context)) - { - /* It processed the key character, so redraw and exit */ - UiDrawMenu(MenuInfo); - return 0; - } - - /* Process the key */ - if ((KeyEvent == KEY_UP ) || (KeyEvent == KEY_DOWN) || - (KeyEvent == KEY_HOME) || (KeyEvent == KEY_END )) - { - /* Get the current selected item and count */ - Selected = MenuInfo->SelectedMenuItem; - Count = MenuInfo->MenuItemCount - 1; - - /* Check the key and change the selected menu item */ - if ((KeyEvent == KEY_UP) && (Selected > 0)) - { - /* Deselect previous item and go up */ - MenuInfo->SelectedMenuItem--; - UiDrawMenuItem(MenuInfo, Selected); - Selected--; - - // Skip past any separators - if ((Selected > 0) && - (MenuInfo->MenuItemList[Selected] == NULL)) - { - MenuInfo->SelectedMenuItem--; - } - } - else if ( ((KeyEvent == KEY_UP) && (Selected == 0)) || - (KeyEvent == KEY_END) ) - { - /* Go to the end */ - MenuInfo->SelectedMenuItem = Count; - UiDrawMenuItem(MenuInfo, Selected); - } - else if ((KeyEvent == KEY_DOWN) && (Selected < Count)) - { - /* Deselect previous item and go down */ - MenuInfo->SelectedMenuItem++; - UiDrawMenuItem(MenuInfo, Selected); - Selected++; - - // Skip past any separators - if ((Selected < Count) && - (MenuInfo->MenuItemList[Selected] == NULL)) - { - MenuInfo->SelectedMenuItem++; - } - } - else if ( ((KeyEvent == KEY_DOWN) && (Selected == Count)) || - (KeyEvent == KEY_HOME) ) - { - /* Go to the beginning */ - MenuInfo->SelectedMenuItem = 0; - UiDrawMenuItem(MenuInfo, Selected); - } - - /* Select new item and update video buffer */ - UiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); - } - - /* Return the pressed key */ - return KeyEvent; -} - -VOID -UiCalcMenuBoxSize(IN PUI_MENU_INFO MenuInfo) -{ - ULONG i, Width = 0, Height, Length; - - /* Height is the menu item count plus 2 (top border & bottom border) */ - Height = MenuInfo->MenuItemCount + 2; - Height -= 1; // Height is zero-based - - /* Loop every item */ - for (i = 0; i < MenuInfo->MenuItemCount; i++) - { - /* Get the string length and make it become the new width if necessary */ - if (MenuInfo->MenuItemList[i]) - { - Length = (ULONG)strlen(MenuInfo->MenuItemList[i]); - if (Length > Width) Width = Length; - } - } - - /* Allow room for left & right borders, plus 8 spaces on each side */ - Width += 18; - - /* Put the menu in the default left-corner position */ - MenuInfo->Left = -1; - MenuInfo->Top = 4; - - /* The other margins are the same */ - MenuInfo->Right = (MenuInfo->Left) + Width; - MenuInfo->Bottom = (MenuInfo->Top) + Height; + MiniTuiDrawMenu(MenuInfo); } BOOLEAN @@ -447,99 +178,17 @@ UiDisplayMenu( IN UiMenuKeyPressFilterCallback KeyPressFilter OPTIONAL, IN PVOID Context OPTIONAL) { - UI_MENU_INFO MenuInformation; - ULONG LastClockSecond; - ULONG CurrentClockSecond; - ULONG KeyPress; - - /* - * Before taking any default action if there is no timeout, - * check whether the supplied key filter callback function - * may handle a specific user keypress. If it does, the - * timeout is cancelled. - */ - if (!MenuTimeOut && KeyPressFilter && MachConsKbHit()) - { - /* Get the key (get the extended key if needed) */ - KeyPress = MachConsGetCh(); - if (KeyPress == KEY_EXTENDED) - KeyPress = MachConsGetCh(); - - /* - * Call the supplied key filter callback function to see - * if it is going to handle this keypress. - */ - if (KeyPressFilter(KeyPress, DefaultMenuItem, Context)) - { - /* It processed the key character, cancel the timeout */ - MenuTimeOut = -1; - } - } - - /* Check if there's no timeout */ - if (!MenuTimeOut) - { - /* Return the default selected item */ - if (SelectedMenuItem) *SelectedMenuItem = DefaultMenuItem; - return TRUE; - } - - /* Setup the MENU_INFO structure */ - MenuInformation.MenuHeader = MenuHeader; - MenuInformation.MenuFooter = MenuFooter; - MenuInformation.ShowBootOptions = ShowBootOptions; - MenuInformation.MenuItemList = MenuItemList; - MenuInformation.MenuItemCount = MenuItemCount; - MenuInformation.MenuTimeRemaining = MenuTimeOut; - MenuInformation.SelectedMenuItem = DefaultMenuItem; - MenuInformation.Context = Context; - - /* Calculate the size of the menu box */ - UiCalcMenuBoxSize(&MenuInformation); - - /* Draw the menu */ - UiDrawMenu(&MenuInformation); - - /* Get the current second of time */ - LastClockSecond = ArcGetTime()->Second; - - /* Process keys */ - while (TRUE) - { - /* Process key presses */ - KeyPress = UiProcessMenuKeyboardEvent(&MenuInformation, KeyPressFilter); - - /* Check for ENTER or ESC */ - if (KeyPress == KEY_ENTER) break; - if (CanEscape && KeyPress == KEY_ESC) return FALSE; - - /* Check if there is a countdown */ - if (MenuInformation.MenuTimeRemaining > 0) - { - /* Get the updated time, seconds only */ - CurrentClockSecond = ArcGetTime()->Second; - - /* Check if more then a second has now elapsed */ - if (CurrentClockSecond != LastClockSecond) - { - /* Update the time information */ - LastClockSecond = CurrentClockSecond; - MenuInformation.MenuTimeRemaining--; - - /* Update the menu */ - UiDrawMenuBox(&MenuInformation); - } - } - else if (MenuInformation.MenuTimeRemaining == 0) - { - /* A time out occurred, exit this loop and return default OS */ - break; - } - } - - /* Return the selected item */ - if (SelectedMenuItem) *SelectedMenuItem = MenuInformation.SelectedMenuItem; - return TRUE; + return TuiDisplayMenu(MenuHeader, + MenuFooter, + ShowBootOptions, + MenuItemList, + MenuItemCount, + DefaultMenuItem, + MenuTimeOut, + SelectedMenuItem, + CanEscape, + KeyPressFilter, + Context); } #endif // _M_ARM diff --git a/boot/freeldr/freeldr/ui/minitui.c b/boot/freeldr/freeldr/ui/minitui.c index 6c231af8b11..373605a8b1b 100644 --- a/boot/freeldr/freeldr/ui/minitui.c +++ b/boot/freeldr/freeldr/ui/minitui.c @@ -114,15 +114,16 @@ MiniTuiDrawProgressBar( #endif } -#ifndef _M_ARM - VOID -MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo) +MiniTuiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo) { ULONG i; +#ifndef _M_ARM /* Draw the backdrop */ UiDrawBackdrop(); +#endif /* No GUI status bar text, just minimal text. Show the menu header. */ if (MenuInfo->MenuHeader) @@ -167,9 +168,13 @@ MiniTuiDrawMenu(PUI_MENU_INFO MenuInfo) DisplayBootTimeOptions(); } +#ifndef _M_ARM VideoCopyOffScreenBufferToVRAM(); +#endif } +#ifndef _M_ARM + const UIVTBL MiniTuiVtbl = { TuiInitialize, diff --git a/boot/freeldr/freeldr/ui/noui.c b/boot/freeldr/freeldr/ui/noui.c index e0e1b4b97e4..5e083dd8be0 100644 --- a/boot/freeldr/freeldr/ui/noui.c +++ b/boot/freeldr/freeldr/ui/noui.c @@ -167,7 +167,9 @@ NoUiDisplayMenu( return TRUE; } -VOID NoUiDrawMenu(PUI_MENU_INFO MenuInfo) +VOID +NoUiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo) { } diff --git a/boot/freeldr/freeldr/ui/tuimenu.c b/boot/freeldr/freeldr/ui/tuimenu.c index f1c229e947b..1e4a2c64d18 100644 --- a/boot/freeldr/freeldr/ui/tuimenu.c +++ b/boot/freeldr/freeldr/ui/tuimenu.c @@ -9,11 +9,19 @@ /* INCLUDES ******************************************************************/ -#ifndef _M_ARM #include <freeldr.h> /* FUNCTIONS *****************************************************************/ +static VOID +TuiCalcMenuBoxSize( + _In_ PUI_MENU_INFO MenuInfo); + +static ULONG +TuiProcessMenuKeyboardEvent( + _In_ PUI_MENU_INFO MenuInfo, + _In_ UiMenuKeyPressFilterCallback KeyPressFilter); + BOOLEAN TuiDisplayMenu( IN PCSTR MenuHeader, @@ -79,7 +87,11 @@ TuiDisplayMenu( TuiCalcMenuBoxSize(&MenuInformation); /* Draw the menu */ +#ifdef _M_ARM + UiDrawMenu(&MenuInformation); +#else UiVtbl.DrawMenu(&MenuInformation); +#endif /* Get the current second of time */ LastClockSecond = ArcGetTime()->Second; @@ -94,9 +106,11 @@ TuiDisplayMenu( if (KeyPress == KEY_ENTER) break; if (CanEscape && KeyPress == KEY_ESC) return FALSE; +#ifndef _M_ARM // FIXME: Theme-specific /* Update the date & time */ TuiUpdateDateTime(); VideoCopyOffScreenBufferToVRAM(); +#endif /* Check if there is a countdown */ if (MenuInformation.MenuTimeRemaining > 0) @@ -113,7 +127,9 @@ TuiDisplayMenu( /* Update the menu */ TuiDrawMenuBox(&MenuInformation); +#ifndef _M_ARM VideoCopyOffScreenBufferToVRAM(); +#endif } } else if (MenuInformation.MenuTimeRemaining == 0) @@ -122,7 +138,9 @@ TuiDisplayMenu( break; } +#ifndef _M_ARM MachHwIdle(); +#endif } /* Return the selected item */ @@ -130,8 +148,9 @@ TuiDisplayMenu( return TRUE; } -VOID -TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo) +static VOID +TuiCalcMenuBoxSize( + _In_ PUI_MENU_INFO MenuInfo) { ULONG i; ULONG Width = 0; @@ -156,6 +175,7 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo) /* Allow room for left & right borders, plus 8 spaces on each side */ Width += 18; +#ifndef _M_ARM /* Check if we're drawing a centered menu */ if (UiCenterMenu) { @@ -165,6 +185,7 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo) Height) / 2) + TUI_TITLE_BOX_CHAR_HEIGHT; } else +#endif { /* Put the menu in the default left-corner position */ MenuInfo->Left = -1; @@ -172,21 +193,56 @@ TuiCalcMenuBoxSize(PUI_MENU_INFO MenuInfo) } /* The other margins are the same */ - MenuInfo->Right = (MenuInfo->Left) + Width; - MenuInfo->Bottom = (MenuInfo->Top) + Height; + MenuInfo->Right = MenuInfo->Left + Width; + MenuInfo->Bottom = MenuInfo->Top + Height; } VOID -TuiDrawMenu(PUI_MENU_INFO MenuInfo) +TuiDrawMenu( + _In_ PUI_MENU_INFO MenuInfo) { ULONG i; +#ifdef _M_ARM // FIXME: Theme-specific + + /* No GUI status bar text, just minimal text. Show the menu header. */ + if (MenuInfo->MenuHeader) + { + UiDrawText(0, + MenuInfo->Top - 2, + MenuInfo->MenuHeader, + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + + /* Now tell the user how to choose */ + UiDrawText(0, + MenuInfo->Bottom + 1, + "Use \x18 and \x19 to move the highlight to your choice.", + ATTR(UiMenuFgColor, UiMenuBgColor)); + UiDrawText(0, + MenuInfo->Bottom + 2, + "Press ENTER to choose.", + ATTR(UiMenuFgColor, UiMenuBgColor)); + + /* And show the menu footer */ + if (MenuInfo->MenuFooter) + { + UiDrawText(0, + UiScreenHeight - 4, + MenuInfo->MenuFooter, + ATTR(UiMenuFgColor, UiMenuBgColor)); + } + +#else + /* Draw the backdrop */ UiDrawBackdrop(); /* Update the status bar */ UiVtbl.DrawStatusText("Use \x18 and \x19 to select, then press ENTER."); +#endif + /* Draw the menu box */ TuiDrawMenuBox(MenuInfo); @@ -202,15 +258,19 @@ TuiDrawMenu(PUI_MENU_INFO MenuInfo) DisplayBootTimeOptions(); } +#ifndef _M_ARM VideoCopyOffScreenBufferToVRAM(); +#endif } VOID -TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) +TuiDrawMenuBox( + _In_ PUI_MENU_INFO MenuInfo) { CHAR MenuLineText[80], TempString[80]; ULONG i; +#ifndef _M_ARM // FIXME: Theme-specific /* Draw the menu box if requested */ if (UiMenuBox) { @@ -224,6 +284,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) TRUE, // Shadow ATTR(UiMenuFgColor, UiMenuBgColor)); } +#endif /* If there is a timeout draw the time remaining */ if (MenuInfo->MenuTimeRemaining >= 0) @@ -241,6 +302,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) /* Add the last 2 chars */ strcat(MenuLineText, &UiTimeText[i - 2]); +#ifndef _M_ARM /* Check if this is a centered menu */ if (UiCenterMenu) { @@ -251,6 +313,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) ATTR(UiMenuFgColor, UiMenuBgColor)); } else +#endif { /* Display under the menu directly */ UiDrawText(0, @@ -269,6 +332,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) MenuLineText[sizeof(MenuLineText)-1] = 0; /* Draw this "empty" string to erase */ +#ifndef _M_ARM if (UiCenterMenu) { UiDrawText(MenuInfo->Right - (ULONG)strlen(MenuLineText) - 1, @@ -277,6 +341,7 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) ATTR(UiMenuFgColor, UiMenuBgColor)); } else +#endif { UiDrawText(0, MenuInfo->Bottom + 4, @@ -305,16 +370,20 @@ TuiDrawMenuBox(PUI_MENU_INFO MenuInfo) } VOID -TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, - ULONG MenuItemNumber) +TuiDrawMenuItem( + _In_ PUI_MENU_INFO MenuInfo, + _In_ ULONG MenuItemNumber) { +#ifndef _M_ARM ULONG i; - CHAR MenuLineText[80]; ULONG SpaceTotal; ULONG SpaceLeft; ULONG SpaceRight = 0; +#endif UCHAR Attribute = ATTR(UiTextColor, UiMenuBgColor); + CHAR MenuLineText[80]; +#ifndef _M_ARM /* Check if using centered menu */ if (UiCenterMenu) { @@ -329,10 +398,12 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, SpaceRight = (SpaceTotal - SpaceLeft) + 1; /* Insert the spaces on the left */ - for (i = 0; i < SpaceLeft; i++) MenuLineText[i] = ' '; + for (i = 0; i < SpaceLeft; i++) + MenuLineText[i] = ' '; MenuLineText[i] = '\0'; } else +#endif { /* Simply left-align it */ MenuLineText[0] = '\0'; @@ -343,12 +414,14 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, if (MenuInfo->MenuItemList[MenuItemNumber]) strcat(MenuLineText, MenuInfo->MenuItemList[MenuItemNumber]); +#ifndef _M_ARM /* Check if using centered menu, and add spaces on the right if so */ if (UiCenterMenu) { for (i = 0; i < SpaceRight; i++) strcat(MenuLineText, " "); } +#endif /* If it is a separator */ if (MenuInfo->MenuItemList[MenuItemNumber] == NULL) @@ -371,9 +444,10 @@ TuiDrawMenuItem(PUI_MENU_INFO MenuInfo, Attribute); } -ULONG -TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo, - UiMenuKeyPressFilterCallback KeyPressFilter) +static ULONG +TuiProcessMenuKeyboardEvent( + _In_ PUI_MENU_INFO MenuInfo, + _In_ UiMenuKeyPressFilterCallback KeyPressFilter) { ULONG KeyEvent = 0; ULONG Selected, Count; @@ -403,7 +477,11 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo, KeyPressFilter(KeyEvent, MenuInfo->SelectedMenuItem, MenuInfo->Context)) { /* It processed the key character, so redraw and exit */ +#ifdef _M_ARM + UiDrawMenu(MenuInfo); +#else UiVtbl.DrawMenu(MenuInfo); +#endif return 0; } @@ -461,11 +539,11 @@ TuiProcessMenuKeyboardEvent(PUI_MENU_INFO MenuInfo, /* Select new item and update video buffer */ TuiDrawMenuItem(MenuInfo, MenuInfo->SelectedMenuItem); +#ifndef _M_ARM VideoCopyOffScreenBufferToVRAM(); +#endif } /* Return the pressed key */ return KeyEvent; } - -#endif
2 years, 10 months
1
0
0
0
[reactos] 01/02: [BOOTDATA] Add /HAL=halpc98.dll to all the PC98 floppy disk's freeldr INI file boot entries.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ccddb4aaf284aaebf40e8…
commit ccddb4aaf284aaebf40e85c35dbf012be97cd8cb Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Mon Feb 14 03:00:16 2022 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Wed Feb 16 00:49:47 2022 +0100 [BOOTDATA] Add /HAL=halpc98.dll to all the PC98 floppy disk's freeldr INI file boot entries. --- boot/bootdata/floppy_pc98.ini | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/boot/bootdata/floppy_pc98.ini b/boot/bootdata/floppy_pc98.ini index 2488bb21482..3a27e48b743 100644 --- a/boot/bootdata/floppy_pc98.ini +++ b/boot/bootdata/floppy_pc98.ini @@ -36,33 +36,34 @@ LiveCD_LogFile="LiveCD (Log file)" [Setup] BootType=ReactOSSetup SystemPath=multi(0)disk(0)cdrom(0)\reactos +Options=/HAL=halpc98.dll [Setup_Debug] BootType=ReactOSSetup SystemPath=multi(0)disk(0)cdrom(0)\reactos -Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=9600 /NOGUIBOOT /SIFOPTIONSOVERRIDE +Options=/HAL=halpc98.dll /DEBUG /DEBUGPORT=COM1 /BAUDRATE=9600 /NOGUIBOOT /SIFOPTIONSOVERRIDE [Setup_Screen] BootType=ReactOSSetup SystemPath=multi(0)disk(0)cdrom(0)\reactos -Options=/DEBUG /DEBUGPORT=SCREEN /SIFOPTIONSOVERRIDE +Options=/HAL=halpc98.dll /DEBUG /DEBUGPORT=SCREEN /SIFOPTIONSOVERRIDE [LiveCD] BootType=Windows2003 SystemPath=multi(0)disk(0)cdrom(0)\reactos -Options=/MININT +Options=/HAL=halpc98.dll /MININT [LiveCD_Debug] BootType=Windows2003 SystemPath=multi(0)disk(0)cdrom(0)\reactos -Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=9600 /SOS /MININT +Options=/HAL=halpc98.dll /DEBUG /DEBUGPORT=COM1 /BAUDRATE=9600 /SOS /MININT [LiveCD_Screen] BootType=Windows2003 SystemPath=multi(0)disk(0)cdrom(0)\reactos -Options=/DEBUG /DEBUGPORT=SCREEN /SOS /MININT +Options=/HAL=halpc98.dll /DEBUG /DEBUGPORT=SCREEN /SOS /MININT [LiveCD_LogFile] BootType=Windows2003 SystemPath=multi(0)disk(0)cdrom(0)\reactos -Options=/DEBUG /DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log /SOS /MININT +Options=/HAL=halpc98.dll /DEBUG /DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log /SOS /MININT
2 years, 10 months
1
0
0
0
[reactos] 05/05: [AC97] Import the AC97 driver sample
by Obaid51
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9c79a7982b1627151045b…
commit 9c79a7982b1627151045b130627f63963fc88d63 Author: Obaid51 <16-se-51(a)students.uettaxila.edu.pk> AuthorDate: Tue Jan 4 12:16:01 2022 +0500 Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org> CommitDate: Wed Feb 16 01:31:28 2022 +0300 [AC97] Import the AC97 driver sample The source code is licensed under MIT license, taken from "MSDN Code Gallery Microsoft Samples" repository (
https://github.com/microsoftarchive/msdn-code-gallery-microsoft
) The original license was MS-PL, but the driver was later relicensed as MIT. Adopted to ReactOS code base by Michael Stamper. Co-authored-by: Michael Stamper <michaelstamper1(a)gmail.com> --- drivers/wdm/audio/drivers/CMakeLists.txt | 1 + drivers/wdm/audio/drivers/ac97/CMakeLists.txt | 30 + drivers/wdm/audio/drivers/ac97/ac97.inf | 482 ++++ drivers/wdm/audio/drivers/ac97/ac97.rc | 24 + drivers/wdm/audio/drivers/ac97/ac97reg.h | 170 ++ drivers/wdm/audio/drivers/ac97/adapter.cpp | 583 +++++ drivers/wdm/audio/drivers/ac97/adapter.h | 71 + drivers/wdm/audio/drivers/ac97/common.cpp | 2309 ++++++++++++++++++++ drivers/wdm/audio/drivers/ac97/common.h | 387 ++++ drivers/wdm/audio/drivers/ac97/debug.h | 93 + drivers/wdm/audio/drivers/ac97/guids.h | 188 ++ drivers/wdm/audio/drivers/ac97/ichreg.h | 107 + drivers/wdm/audio/drivers/ac97/license.txt | 21 + drivers/wdm/audio/drivers/ac97/miniport.cpp | 1462 +++++++++++++ drivers/wdm/audio/drivers/ac97/miniport.h | 145 ++ drivers/wdm/audio/drivers/ac97/mintopo.cpp | 2129 ++++++++++++++++++ drivers/wdm/audio/drivers/ac97/mintopo.h | 339 +++ drivers/wdm/audio/drivers/ac97/prophnd.cpp | 1824 ++++++++++++++++ drivers/wdm/audio/drivers/ac97/rtminiport.cpp | 252 +++ drivers/wdm/audio/drivers/ac97/rtminiport.h | 155 ++ drivers/wdm/audio/drivers/ac97/rtstream.cpp | 425 ++++ drivers/wdm/audio/drivers/ac97/rtstream.h | 118 + drivers/wdm/audio/drivers/ac97/shared.h | 504 +++++ drivers/wdm/audio/drivers/ac97/stream.cpp | 634 ++++++ drivers/wdm/audio/drivers/ac97/stream.h | 200 ++ drivers/wdm/audio/drivers/ac97/stream2.cpp | 159 ++ .../wdm/audio/drivers/ac97/wavecyclicminiport.cpp | 182 ++ .../wdm/audio/drivers/ac97/wavecyclicminiport.h | 77 + .../wdm/audio/drivers/ac97/wavecyclicstream.cpp | 230 ++ drivers/wdm/audio/drivers/ac97/wavecyclicstream.h | 116 + drivers/wdm/audio/drivers/ac97/wavepciminiport.cpp | 214 ++ drivers/wdm/audio/drivers/ac97/wavepciminiport.h | 79 + drivers/wdm/audio/drivers/ac97/wavepcistream.cpp | 885 ++++++++ drivers/wdm/audio/drivers/ac97/wavepcistream.h | 138 ++ media/doc/3rd Party Files.txt | 6 + 35 files changed, 14739 insertions(+) diff --git a/drivers/wdm/audio/drivers/CMakeLists.txt b/drivers/wdm/audio/drivers/CMakeLists.txt index 2f2f8289a9d..009a279a4a4 100644 --- a/drivers/wdm/audio/drivers/CMakeLists.txt +++ b/drivers/wdm/audio/drivers/CMakeLists.txt @@ -1,2 +1,3 @@ +add_subdirectory(ac97) add_subdirectory(CMIDriver) diff --git a/drivers/wdm/audio/drivers/ac97/CMakeLists.txt b/drivers/wdm/audio/drivers/ac97/CMakeLists.txt new file mode 100644 index 00000000000..ef182eee79e --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/CMakeLists.txt @@ -0,0 +1,30 @@ + +list(APPEND SOURCE + adapter.cpp + common.cpp + mintopo.cpp + prophnd.cpp + miniport.cpp + stream.cpp + stream2.cpp + rtminiport.cpp + rtstream.cpp + wavepciminiport.cpp + wavepcistream.cpp + wavecyclicminiport.cpp + wavecyclicstream.cpp) + +add_library(ac97 MODULE + ${SOURCE} + ac97.rc) + +target_link_libraries(ac97 stdunk libcntpr uuid) +set_module_type(ac97 wdmdriver) +add_importlibs(ac97 portcls hal ntoskrnl) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(ac97 PRIVATE -Wno-write-strings -Wno-switch) +endif() + +add_cd_file(TARGET ac97 DESTINATION reactos/system32/drivers FOR all) +add_driver_inf(ac97 ac97.inf) diff --git a/drivers/wdm/audio/drivers/ac97/ac97.inf b/drivers/wdm/audio/drivers/ac97/ac97.inf new file mode 100644 index 00000000000..abf1920b71c --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/ac97.inf @@ -0,0 +1,482 @@ +;Copyright (c) 1998-2000 Microsoft Corporation All rights Reserved +; +;Module Name: +; ac97.INF +; +;Abstract: +; INF file for installing AC97 WDM Driver +; +; +; During upgrade from Win98SE or Win ME, the default upgrade behavior won't upgrade the drivers +; to Win2k or Windows XP. The inf has implemented what's mentioned in +; WINDDK\..\src\setup\devupgrd\devupgrd.doc. +; If your driver would never be installed under Win98SE or Win ME, you don't need this new migrate.dll +; stuff. + + +[Version] +Signature="$CHICAGO$" +Class=MEDIA +ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318} +provider=%ProviderName% +;;The following line is used only when the INF comes with the Windows system +;;IHV needs to comment out the following line for their OEM redistributed disk. +;;LayoutFile=layout.inf, layout1.inf, layout2.inf +DriverVer=02/22/2007,6.00.6000.1 +CatalogFile=ac97.cat + +;You must specify which platform is supported by each SourceDisksNames section +;Valid platform identifiers include .x86, .ia64, .alpha, .axp64 +[SourceDisksNames] +222=%DiskDescription%,,, + +;You must also specify which platform is supported by each SourceDisksFiles section +;Valid platform identifiers include .x86, .ia64, .alpha, .axp64 +[SourceDisksFiles] +ac97.sys=222 +;ac97prop.dll=222 +;the entries below are used by the device migration dll, on Win95/98 to Win2K upgrades +;Migrate.dll=222 +ac97.inf=222 + +[Manufacturer] +%MfgName%=Intel,NTAMD64,NTIA64,NTARM + +;; Excluding drivers from the "Add New Hardware" list. +[ControlFlags] +ExcludeFromSelect = * + +[Intel] +%ac97_AA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2415 +%ac97_AB.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2425 +%ac97_BA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2445 + +;; This section enables installing on x64 systems + +[Intel.NTAMD64] +%ac97_AA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2415 +%ac97_AB.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2425 +%ac97_BA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2445 + +;; This section enables installing on Itanium systems + +[Intel.NTIA64] +%ac97_AA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2415 +%ac97_AB.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2425 +%ac97_BA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2445 + +;; This section enables installing on ARM systems + +[Intel.NTARM] +%ac97_AA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2415 +%ac97_AB.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2425 +%ac97_BA.DeviceDesc%=ac97, PCI\VEN_8086&DEV_2445 + +[DestinationDirs] +ac97.CopyList=10,system32\drivers +;AC97PROP.CopyList=10,system32 + +DevUpgrd_Files = 10, win9xmig\DevUpgrd +WDMDriver_Files = 10, win9xmig\DevUpgrd\AC97WDM ; Replace "AC97WDM" with your favorite vendor related name + +[ac97] +;;This inf is intended for use by IHV. So, it's going to be used as from OEM distributed disk +;;This is why AlsoInstall got used instead if Needs & Include +AlsoInstall=KS.Registration(ks.inf), WDMAUDIO.Registration(wdmaudio.inf) +CopyFiles=ac97.CopyList, DevUpgrd_Files, WDMDriver_Files +AddReg=ac97.AddReg,ac97_NAMES.AddReg,ac97_OEM.AddReg,DevUpgrd_AddReg +KnownRegEntries=AC97.KnownRegEntries +;;Exclude driver installation for those PnP ID's. +;;This PnP ID is an example of a machine where the driver won't work correctly +ExcludeId=PCI\VEN_8086&DEV_2415&SUBSYS_536011D4&REV_00 + +[AC97.KnownRegEntries] +IsWin98Gold=keep + +[IsWin98Gold] +1=HKLM,Software\Microsoft\Windows\CurrentVersion,VersionNumber,0,4.10.1998 + +[ac97.CopyList] +ac97.sys + +[DevUpgrd_Files] +;;This migrate.dll can be found in the DDK (beta2 or after) under src\setup\devupgrd +;Migrate.dll + +[WDMDriver_Files] +ac97.inf ; Name of your INF goes here +ac97.sys ; Name of your driver file(s) goes here +;ac97prop.dll + + + +[ac97.Interfaces] +AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_RENDER%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_CAPTURE%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_REALTIME%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Topology%,ac97.Interface.Topology + +[ac97.Interface.Wave] +AddReg=ac97.I.Wave.AddReg + +[ac97.I.Wave.AddReg] +HKR,,CLSID,,%Proxy.CLSID% +HKR,,FriendlyName,,%ac97.Wave.szPname% + +[ac97.Interface.Topology] +AddReg=ac97.I.Topo.AddReg + +[ac97.I.Topo.AddReg] +HKR,,CLSID,,%Proxy.CLSID% +HKR,,FriendlyName,,%ac97.Topology.szPname% + +[ac97.AddReg] +HKR,,AssociatedFilters,,"wdmaud,swmidi,redbook" +HKR,,Driver,,ac97.sys +HKR,,NTMPDriver,,"ac97.sys,sbemul.sys" + +HKR,Drivers,SubClasses,,"wave,midi,mixer" + +HKR,Drivers\wave\wdmaud.drv,Driver,,wdmaud.drv +HKR,Drivers\midi\wdmaud.drv,Driver,,wdmaud.drv +HKR,Drivers\mixer\wdmaud.drv,Driver,,wdmaud.drv + +HKR,Drivers\wave\wdmaud.drv,Description,,%ac97.DeviceDesc% +HKR,Drivers\midi\wdmaud.drv, Description,,%ac97.DeviceDesc% +HKR,Drivers\mixer\wdmaud.drv,Description,,%ac97.DeviceDesc% + + +[DevUpgrd_AddReg] +HKLM,"Software\Microsoft\Windows\CurrentVersion\Setup\Migration DLLs","Microsoft Device Upgrade Pack",,%10%\win9xmig\DevUpgrd +HKLM,"Software\Microsoft\Windows\CurrentVersion\Setup\UpgradeDrivers","PCI\VEN_8086&DEV_2415",,%10%\win9xmig\DevUpgrd\AC97WDM\ac97.inf +HKLM,"Software\Microsoft\Windows\CurrentVersion\Setup\UpgradeDrivers","PCI\VEN_8086&DEV_2425",,%10%\win9xmig\DevUpgrd\AC97WDM\ac97.inf +HKLM,"Software\Microsoft\Windows\CurrentVersion\Setup\UpgradeDrivers","PCI\VEN_8086&DEV_2445",,%10%\win9xmig\DevUpgrd\AC97WDM\ac97.inf + + +[ac97.Services] +AddService = ac97, 0x00000002, ac97_Service_Inst + +[ac97_Service_Inst] +DisplayName = %ac97.SvcDesc% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary = %10%\system32\drivers\ac97.sys + +[ac97_NAMES.AddReg] +;; Nodes +HKLM,%MediaCategories%\%ICHGUID.PhoneVolume%,Name,,%ICHNode.PhoneVolume% +HKLM,%MediaCategories%\%ICHGUID.PhoneVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.PhoneMute%,Name,,%ICHNode.PhoneMute% +HKLM,%MediaCategories%\%ICHGUID.PhoneMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.LineInMute%,Name,,%ICHNode.LineInMute% +HKLM,%MediaCategories%\%ICHGUID.LineInMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.MainMix%,Name,,%ICHNode.MainMix% +HKLM,%MediaCategories%\%ICHGUID.MainMix%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.3DBypass%,Name,,%ICHNode.3DBypass% +HKLM,%MediaCategories%\%ICHGUID.3DBypass%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.3DEnable%,Name,,%ICHNode.3DEnable% +HKLM,%MediaCategories%\%ICHGUID.3DEnable%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.BeepMix%,Name,,%ICHNode.BeepMix% +HKLM,%MediaCategories%\%ICHGUID.BeepMix%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.HPVolume%,Name,,%ICHNode.HPVolume% +HKLM,%MediaCategories%\%ICHGUID.HPVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.HPMute%,Name,,%ICHNode.HPMute% +HKLM,%MediaCategories%\%ICHGUID.HPMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.MonoOutSelect%,Name,,%ICHNode.MonoOutSelect% +HKLM,%MediaCategories%\%ICHGUID.MonoOutSelect%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.WaveInSelect%,Name,,%ICHNode.WaveInSelect% +HKLM,%MediaCategories%\%ICHGUID.WaveInSelect%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.MasterInVolume%,Name,,%ICHNode.MasterInVolume% +HKLM,%MediaCategories%\%ICHGUID.MasterInVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.MasterInMute%,Name,,%ICHNode.MasterInMute% +HKLM,%MediaCategories%\%ICHGUID.MasterInMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.MicInVolume%,Name,,%ICHNode.MicInVolume% +HKLM,%MediaCategories%\%ICHGUID.MicInVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.MicInMute%,Name,,%ICHNode.MicInMute% +HKLM,%MediaCategories%\%ICHGUID.MicInMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.SimulStereo%,Name,,%ICHNode.SimulStereo% +HKLM,%MediaCategories%\%ICHGUID.SimulStereo%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.SurroundVolume%,Name,,%ICHNode.SurroundVolume% +HKLM,%MediaCategories%\%ICHGUID.SurroundVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.SurroundMute%,Name,,%ICHNode.SurroundMute% +HKLM,%MediaCategories%\%ICHGUID.SurroundMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.CenterVolume%,Name,,%ICHNode.CenterVolume% +HKLM,%MediaCategories%\%ICHGUID.CenterVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.CenterMute%,Name,,%ICHNode.CenterMute% +HKLM,%MediaCategories%\%ICHGUID.CenterMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.LFEVolume%,Name,,%ICHNode.LFEVolume% +HKLM,%MediaCategories%\%ICHGUID.LFEVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.LFEMute%,Name,,%ICHNode.LFEMute% +HKLM,%MediaCategories%\%ICHGUID.LFEMute%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.FrontVolume%,Name,,%ICHNode.FrontVolume% +HKLM,%MediaCategories%\%ICHGUID.FrontVolume%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.FrontMute%,Name,,%ICHNode.FrontMute% +HKLM,%MediaCategories%\%ICHGUID.FrontMute%,Display,1,00,00,00,00 +;; Pins +HKLM,%MediaCategories%\%ICHGUID.Surround%,Name,,%ICHPin.Surround% +HKLM,%MediaCategories%\%ICHGUID.Surround%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.Center%,Name,,%ICHPin.Center% +HKLM,%MediaCategories%\%ICHGUID.Center%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.LFE%,Name,,%ICHPin.LFE% +HKLM,%MediaCategories%\%ICHGUID.LFE%,Display,1,00,00,00,00 +HKLM,%MediaCategories%\%ICHGUID.Front%,Name,,%ICHPin.Front% +HKLM,%MediaCategories%\%ICHGUID.Front%,Display,1,00,00,00,00 + + +[ac97_OEM.AddReg] +;;Default register value at driver startup +;;Uncomment some one of the lines if you want to overwrite the default setting +;;The value in these outcommented lines is the driver default. You can change +;;the register values (and uncomment the line) to overwrite the driver default. +;;low byte comes first, values are hexadezimal. +;HKR,Settings,MasterVolume,1,0,0 ;0dB +;HKR,Settings,HeadphoneVolume,1,0,0 ;0dB +;HKR,Settings,MonooutVolume,1,0,0 ;0dB +;HKR,Settings,ToneControls,1,F,F ;bypass +;HKR,Settings,BeepVolume,1,0,0 ;0dB +;HKR,Settings,PhoneVolume,1,8,80 ;muted +;HKR,Settings,MicVolume,1,8,80 ;muted +;HKR,Settings,LineInVolume,1,8,8 ;0dB +;HKR,Settings,CDVolume,1,8,8 ;0dB +;HKR,Settings,VideoVolume,1,8,8 ;0dB +;HKR,Settings,AUXVolume,1,8,8 ;0dB +;HKR,Settings,WaveOutVolume,1,8,8 ;0dB. This register is never touched by the system. +;HKR,Settings,RecordSelect,1,4,4 ;select LiniIn +;HKR,Settings,RecordGain,1,0,0 ;0dB +;HKR,Settings,RecordGainMic,1,0,0 ;0dB +;HKR,Settings,GeneralPurpose,1,0,0 ;pre 3D, 3D off, loudness off, mono=mix, mic1 +;HKR,Settings,3DControl,1,0,0 ;0% +;HKR,Settings,PowerDown,1,0,0 ;no power down +;HKR,Settings,ExtAudioCtrl,1,01,40 ;VRA, DACs on, MicIn off +;HKR,Settings,CenterLFEVolume,1,0,0 ;0dB +;HKR,Settings,SurroundVolume,1,0,0 ;0dB + +;;Configuration +;;You can disable some of the input lines by outcommenting some of the lines +;;below. This could be necessary if you have a AC97 codec on board that for +;;example supports Video input, but you don't have the Video input accessable +;;for the user (no plug in). +;HKR,Settings,DisablePCBeep,1,1 +;HKR,Settings,DisablePhone,1,1 +;HKR,Settings,DisableMic2,1,1 +;HKR,Settings,DisableVideo,1,1 +;HKR,Settings,DisableAUX,1,1 +;HKR,Settings,DisableHeadphone,1,1 +;HKR,Settings,DisableMonoOut,1,1 +HKR,Settings,DisableMicIn,1,1 +;HKR,Settings,DisableMic,1,1 ;disables all MIC lines, including MIC record. +;HKR,Settings,DisableLineIn,1,1 +;HKR,Settings,DisableCD,1,1 +;HKR,Settings,DisableSurround,1,1 +HKR,Settings,DisableCenterLFE,1,1 ;6ch playback is not supported. +;HKR,Settings,ChannelConfig,1,3,0,0,0 ;ChannelConfig set to stereo speakers. + +;;================= Windows NT ==================== +[ac97.NTX86] +Include=ks.inf,wdmaudio.inf +Needs=KS.Registration,WDMAUDIO.Registration +CopyFiles=ac97.CopyList +;,AC97PROP.CopyList +AddReg=ac97.AddReg,ac97_NAMES.AddReg,ac97_OEM.AddReg +;,AC97PROP.AddReg +;;Exclude driver installation for those PnP ID's. +;;This PnP ID is an example of a machine where the driver won't work correctly +ExcludeId=PCI\VEN_8086&DEV_2415&SUBSYS_536011D4&REV_00 + +[ac97.NTX86.Interfaces] +AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_RENDER%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_CAPTURE%,%KSNAME_Wave%,ac97.Interface.Wave +AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_Topology%,ac97.Interface.Topology + +[ac97.NTX86.Services] +AddService = ac97, 0x00000002, ac97_Service_Inst + +;[AC97PROP.CopyList] +;ac97prop.dll + +;[AC97PROP.AddReg] +;HKR,,EnumPropPages32,,"ac97prop.dll,AC97PropPageProvider" + + +[Strings] +ProviderName="FooProviderName" +MfgName="Intel" +DiskDescription="AC'97 WDM Driver Disk" + +ac97_AA.DeviceDesc="Intel 82801AA AC'97 Audio Controller" +ac97_AB.DeviceDesc="Intel 82801AB AC'97 Audio Controller" +ac97_BA.DeviceDesc="Intel 82801BA/BAM AC'97 Audio Controller" +ac97.DeviceDesc="Intel 82801 AC'97 Audio Controller" + +ac97.Wave.szPname="AC'97 Sound Card" +ac97.Topology.szPname="AC'97 Mixer" + +MediaCategories="SYSTEM\CurrentControlSet\Control\MediaCategories" + +Proxy.CLSID="{17CCA71B-ECD7-11D0-B908-00A0C9223196}" +KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}" +KSCATEGORY_RENDER="{65E8773E-8F56-11D0-A3B9-00A0C9223196}" +KSCATEGORY_CAPTURE="{65E8773D-8F56-11D0-A3B9-00A0C9223196}" +KSCATEGORY_REALTIME="{EB115FFC-10C8-4964-831D-6DCB02E6F23F}" +KSNAME_Wave="Wave" +KSNAME_Topology="Topology" + +ac97.SvcDesc = "Service for AC'97 Driver (WDM)" + +;; Nodes (non-localizeable) +ICHGUID.PhoneVolume ="{0A8C1A87-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.PhoneMute ="{0A8C1A88-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.LineInMute ="{0A8C1A91-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MainMix ="{0A8C1A9B-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.3DBypass ="{0A8C1A9E-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.3DEnable ="{766DB5A4-6E94-11D2-9ADE-00C04F8EFB68}" +ICHGUID.BeepMix ="{0A8C1A9F-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.HPVolume ="{0A8C1AA5-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.HPMute ="{0A8C1AA6-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MonoOutSelect ="{0A8C1AA9-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.WaveInSelect ="{0A8C1AAE-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MasterInVolume ="{0A8C1AAF-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MasterInMute ="{0A8C1AB0-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MicInVolume ="{0A8C1AB2-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MicInMute ="{0A8C1AB3-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.SimulStereo ="{B3AD50B5-3849-4983-ADD7-25E6268F912D}" +ICHGUID.SurroundVolume ="{A4B68BA4-6958-4ab4-BB01-E23C6F027C88}" +ICHGUID.SurroundMute ="{22654FBC-AC8F-4224-B19F-D858D2E10BDD}" +ICHGUID.CenterVolume ="{9B0F1946-ABD2-47a8-A778-BB86CDE1A167}" +ICHGUID.CenterMute ="{BEEF51ED-1041-43f8-9B96-5863D0A9342D}" +ICHGUID.LFEVolume ="{455FA6F2-21EC-4df4-B1E4-3155209797F3}" +ICHGUID.LFEMute ="{4A4D9210-C780-4768-BFD2-525FDBF4FCB4}" +ICHGUID.FrontVolume ="{9F4801BD-F746-4c7a-8A9D-F6E99004CC98}" +ICHGUID.FrontMute ="{C8E03B2A-EBD9-4554-A750-8E4472750A5B}" + +;; Pins (non-localizeable) +ICHGUID.Surround ="{81FBB14B-1BEE-4bf5-92EE-FFC4F75F326D}" +ICHGUID.Center ="{2D97372F-9CF6-4fd6-9E56-C68BACDF360D}" +ICHGUID.LFE ="{B60C4274-3BFD-430b-8364-D947E7D304B1}" +ICHGUID.Front ="{070395E2-BE7C-4b4d-B529-40CB9BFCF995}" + + +;; Nodes (localizeable) +ICHNode.PhoneVolume ="Phone Volume" +ICHNode.PhoneMute ="Phone Mute" +ICHNode.LineInMute ="Line In Mute" +ICHNode.MainMix ="Main Mix" +ICHNode.3DBypass ="3D Bypass" +ICHNode.3DEnable ="3D Enable" +ICHNode.BeepMix ="Beep Mix" +ICHNode.HPVolume ="Headphone Volume" +ICHNode.HPMute ="Headphone Mute" +ICHNode.MonoOutSelect ="Mono Out Select" +ICHNode.WaveInSelect ="Wave In Select" +ICHNode.MasterInVolume ="Wave In Volume" +ICHNode.MasterInMute ="Wave In Mute" +ICHNode.MicInVolume ="Mic In Volume" +ICHNode.MicInMute ="Mic In Mute" +ICHNode.SimulStereo ="Simulated Stereo" +ICHNode.SurroundVolume ="Rear Speaker Volume" +ICHNode.SurroundMute ="Rear Speaker Mute" +ICHNode.CenterVolume ="Center Volume" +ICHNode.CenterMute ="Center Mute" +ICHNode.LFEVolume ="Subwoofer Volume" +ICHNode.LFEMute ="Subwoofer Mute" +ICHNode.FrontVolume ="Front Volume" +ICHNode.FrontMute ="Front Mute" + +;; Pins +ICHPin.Surround ="Rear Speaker" +ICHPin.Center ="Center" +ICHPin.LFE ="Subwoofer" +ICHPin.Front ="Front Speaker" + +[Strings.0407] +ProviderName="FooProviderName" +MfgName="Intel" + +DiskDescription="Diskette für AC'97 WDM Treiberbeispiel" +ac97_AA.DeviceDesc="Intel 82801AA AC'97 Audiocontroller" +ac97_AB.DeviceDesc="Intel 82801AB AC'97 Audiocontroller" +ac97_BA.DeviceDesc="Intel 82801BA/BAM AC'97 Audiocontroller" +ac97.DeviceDesc="Intel 82801 AC'97 Audiocontroller" + +ac97.Wave.szPname="AC'97 Musikkarte" +ac97.Topology.szPname="AC'97 Mixer" + +MediaCategories="SYSTEM\CurrentControlSet\Control\MediaCategories" + +Proxy.CLSID="{17CCA71B-ECD7-11D0-B908-00A0C9223196}" +KSCATEGORY_AUDIO="{6994AD04-93EF-11D0-A3CC-00A0C9223196}" +KSCATEGORY_RENDER="{65E8773E-8F56-11D0-A3B9-00A0C9223196}" +KSCATEGORY_CAPTURE="{65E8773D-8F56-11D0-A3B9-00A0C9223196}" +KSCATEGORY_REALTIME="{EB115FFC-10C8-4964-831D-6DCB02E6F23F}" +KSNAME_Wave="Wave" +KSNAME_Topology="Topology" + +ac97.SvcDesc = "Installationshilfe für AC'97 Treiberbeispiel (WDM)" + + +;; Nodes (non-localizeable) +ICHGUID.PhoneVolume ="{0A8C1A87-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.PhoneMute ="{0A8C1A88-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.LineInMute ="{0A8C1A91-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MainMix ="{0A8C1A9B-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.3DBypass ="{0A8C1A9E-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.3DEnable ="{766DB5A4-6E94-11D2-9ADE-00C04F8EFB68}" +ICHGUID.BeepMix ="{0A8C1A9F-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.HPVolume ="{0A8C1AA5-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.HPMute ="{0A8C1AA6-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MonoOutSelect ="{0A8C1AA9-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.WaveInSelect ="{0A8C1AAE-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MasterInVolume ="{0A8C1AAF-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MasterInMute ="{0A8C1AB0-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MicInVolume ="{0A8C1AB2-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.MicInMute ="{0A8C1AB3-42B0-11D2-95D2-00C04FB925D3}" +ICHGUID.SimulStereo ="{B3AD50B5-3849-4983-ADD7-25E6268F912D}" +ICHGUID.SurroundVolume ="{A4B68BA4-6958-4ab4-BB01-E23C6F027C88}" +ICHGUID.SurroundMute ="{22654FBC-AC8F-4224-B19F-D858D2E10BDD}" +ICHGUID.CenterVolume ="{9B0F1946-ABD2-47a8-A778-BB86CDE1A167}" +ICHGUID.CenterMute ="{BEEF51ED-1041-43f8-9B96-5863D0A9342D}" +ICHGUID.LFEVolume ="{455FA6F2-21EC-4df4-B1E4-3155209797F3}" +ICHGUID.LFEMute ="{4A4D9210-C780-4768-BFD2-525FDBF4FCB4}" +ICHGUID.FrontVolume ="{9F4801BD-F746-4c7a-8A9D-F6E99004CC98}" +ICHGUID.FrontMute ="{C8E03B2A-EBD9-4554-A750-8E4472750A5B}" + +;; Pins (non-localizeable) +ICHGUID.Surround ="{81FBB14B-1BEE-4bf5-92EE-FFC4F75F326D}" +ICHGUID.Center ="{2D97372F-9CF6-4fd6-9E56-C68BACDF360D}" +ICHGUID.LFE ="{B60C4274-3BFD-430b-8364-D947E7D304B1}" +ICHGUID.Front ="{070395E2-BE7C-4b4d-B529-40CB9BFCF995}" + +;; Nodes (localizeable) + +ICHNode.PhoneVolume ="Phone Lautstärke" +ICHNode.PhoneMute ="Phone Aus" +ICHNode.LineInMute ="Line In Aus" +ICHNode.MainMix ="Hauptmixer" +ICHNode.3DBypass ="3D umgehen" +ICHNode.3DEnable ="3D Aktivieren" +ICHNode.BeepMix ="Piepmixer" +ICHNode.MonoOutSelect ="Mono Ausgang Selektor" +ICHNode.WaveInSelect ="Aufnahme Selektor" +ICHNode.MasterInVolume ="Aufnahme Lautstärke" +ICHNode.MasterInMute ="Aufnahme unterdrücken" +ICHNode.MicInVolume ="Mic In Lautstärke" +ICHNode.MicInMute ="Mic In Aus" +ICHNode.SimulStereo ="Simuliertes Stereo" +ICHNode.SurroundVolume ="Lautsprecherlautstärke Hinten" +ICHNode.SurroundMute ="Lautsprecher Hinten Aus" +ICHNode.CenterVolume ="Lautsprecherlautstärke Mitte" +ICHNode.CenterMute ="Lautsprecher Mitte Aus" +ICHNode.LFEVolume ="Bass Lautsprecherlautstärke" +ICHNode.LFEMute ="Bass Lautsprecher Aus" +ICHNode.FrontVolume ="Lautsprecherlautstärke Vorne" +ICHNode.HPVolume ="Kopfh�rer Lautst�rke" +ICHNode.HPMute ="Kopfh�rer Aus" + +;; Pins +ICHPin.Surround ="Lautsprecher Hinten" +ICHPin.Center ="Lautsprecher Mitte" +ICHPin.LFE ="Bass Lautsprecher" +ICHPin.Front ="Lautsprecher Vorne" diff --git a/drivers/wdm/audio/drivers/ac97/ac97.rc b/drivers/wdm/audio/drivers/ac97/ac97.rc new file mode 100644 index 00000000000..87c817afc40 --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/ac97.rc @@ -0,0 +1,24 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file ac97smpl.rc was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SOUND +#define VER_FILEDESCRIPTION_STR "Integrated Controller Hub Audio Driver (WDM)" +#define VER_INTERNALNAME_STR "ac97smpl.sys" +#define VER_ORIGINALFILENAME_STR "ac97smpl.sys" + +#define VER_LEGALCOPYRIGHT_YEARS "1998-2003" +#define VER_LEGALCOPYRIGHT_STR "Copyright (c) Microsoft Corp." VER_LEGALCOPYRIGHT_YEARS + +#include "common.ver" + diff --git a/drivers/wdm/audio/drivers/ac97/ac97reg.h b/drivers/wdm/audio/drivers/ac97/ac97reg.h new file mode 100644 index 00000000000..8361ef5fb88 --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/ac97reg.h @@ -0,0 +1,170 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file ac97reg.h was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#ifndef _AC97REG_H_ +#define _AC97REG_H_ + +// We use enum types cause the compiler can check variable passing if it is +// an enum (otherwise you could pass any value). That doesn't save us from +// doing reasonable run time checks in that range. +enum AC97Register +{ + AC97REG_RESET = 0, + AC97REG_MASTER_VOLUME, + AC97REG_HPHONE_VOLUME, + AC97REG_MMONO_VOLUME, + AC97REG_MASTER_TONE, + AC97REG_BEEP_VOLUME, + AC97REG_PHONE_VOLUME, + AC97REG_MIC_VOLUME, + AC97REG_LINE_IN_VOLUME, + AC97REG_CD_VOLUME, + AC97REG_VIDEO_VOLUME, + AC97REG_AUX_VOLUME, + AC97REG_PCM_OUT_VOLUME, + AC97REG_RECORD_SELECT, + AC97REG_RECORD_GAIN, + AC97REG_RECORD_GAIN_MIC, + AC97REG_GENERAL, + AC97REG_3D_CONTROL, + AC97REG_RESERVED, + AC97REG_POWERDOWN, + + // AC97-2.0 registers + AC97REG_EXT_AUDIO_ID, + AC97REG_EXT_AUDIO_CTRL, + AC97REG_FRONT_SAMPLERATE, + AC97REG_SURROUND_SAMPLERATE, + AC97REG_LFE_SAMPLERATE, + AC97REG_RECORD_SAMPLERATE, + AC97REG_MIC_SAMPLERATE, + AC97REG_CENTER_LFE_VOLUME, + AC97REG_SURROUND_VOLUME, + AC97REG_RESERVED2, + + // Modem registers from 0x3C to 0x58 (next 15 enums) + // Vendor Reserved = 0x5A-0x7A (next 16 enums) + + // Vendor IDs + AC97REG_VENDOR_ID1 = 0x3E, // thats register address 0x7C + AC97REG_VENDOR_ID2, + + // Defines an invalid register. Likewise, this is the highest + // possible value that can be used. + AC97REG_INVALID +}; + +#if (DBG) +// Note: This array only has the first 29 registers defined. +// There are many more. +const PCHAR RegStrings[] = +{ + "REG_RESET", + "REG_MASTER_VOLUME", + "REG_HPHONE_VOLUME", + "REG_MMONO_VOLUME", + "REG_MASTER_TONE", + "REG_BEEP_VOLUME", + "REG_PHONE_VOLUME", + "REG_MIC_VOLUME", + "REG_LINEIN_VOLUME", + "REG_CD_VOLUME", + "REG_VIDEO_VOLUME", + "REG_AUX_VOLUME", + "REG_PCMOUT_VOLUME", + "REG_RECORD_SELECT", + "REG_RECORD_GAIN", + "REG_RECORD_GAIN_MIC", + "REG_GENERAL", + "REG_3D_CONTROL", + "REG_RESERVED", + "REG_POWERDOWN", + "REG_EXT_AUDIO_ID", + "REG_EXT_AUDIO_CTRL", + "REG_FRONT_SAMPLERATE", + "REG_SURROUND_SAMPLERATE", + "REG_LFE_SAMPLERATE", + "REG_RECORD_SAMPLERATE", + "REG_MIC_SAMPLERATE", + "REG_CENTER_LFE_VOLUME", + "REG_SURROUND_VOLUME", + "REG_RESERVED2" +}; +#endif + +// This array maps the node controls to the AC97 registers. +// E.g. if you mute the master volume control you should modify AC97 +// register AC97REG_MASTER_VOLUME +typedef struct { + AC97Register reg; // we would only need one byte, but enums are int + WORD mask; // registers are 16 bit. +} tMapNodeToReg; + +const tMapNodeToReg stMapNodeToReg[] = +{ + // TODO: loopback + {AC97REG_PCM_OUT_VOLUME, 0x1F1F}, // NODE_WAVEOUT_VOLUME + {AC97REG_PCM_OUT_VOLUME, 0x8000}, // NODE_WAVEOUT_MUTE + {AC97REG_GENERAL, 0x8000}, // NODE_VIRT_WAVEOUT_3D_BYPASS + {AC97REG_BEEP_VOLUME, 0x001E}, // NODE_PCBEEP_VOLUME + {AC97REG_BEEP_VOLUME, 0x8000}, // NODE_PCBEEP_MUTE + {AC97REG_PHONE_VOLUME, 0x001F}, // NODE_PHONE_VOLUME + {AC97REG_PHONE_VOLUME, 0x8000}, // NODE_PHONE_MUTE + {AC97REG_GENERAL, 0x0100}, // NODE_MIC_SELECT + {AC97REG_MIC_VOLUME, 0x0040}, // NODE_MIC_BOOST + {AC97REG_MIC_VOLUME, 0x001F}, // NODE_MIC_VOLUME + {AC97REG_MIC_VOLUME, 0x8000}, // NODE_MIC_MUTE + {AC97REG_LINE_IN_VOLUME, 0x1F1F}, // NODE_LINEIN_VOLUME + {AC97REG_LINE_IN_VOLUME, 0x8000}, // NODE_LINEIN_MUTE + {AC97REG_CD_VOLUME, 0x1F1F}, // NODE_CD_VOLUME + {AC97REG_CD_VOLUME, 0x8000}, // NODE_CD_MUTE + {AC97REG_VIDEO_VOLUME, 0x1F1F}, // NODE_VIDEO_VOLUME + {AC97REG_VIDEO_VOLUME, 0x8000}, // NODE_VIDEO_MUTE + {AC97REG_AUX_VOLUME, 0x1F1F}, // NODE_AUX_VOLUME + {AC97REG_AUX_VOLUME, 0x8000}, // NODE_AUX_MUTE + {AC97REG_INVALID, 0x0000}, // NODE_MAIN_MIX doesn't has controls + {AC97REG_3D_CONTROL, 0x0F00}, // NODE_VIRT_3D_CENTER + {AC97REG_3D_CONTROL, 0x000F}, // NODE_VIRT_3D_DEPTH + {AC97REG_GENERAL, 0x2000}, // NODE_VIRT_3D_ENABLE + {AC97REG_INVALID, 0x0000}, // NODE_BEEP_MIX doesn't has controls + {AC97REG_MASTER_TONE, 0x0F00}, // NODE_BASS + {AC97REG_MASTER_TONE, 0x000F}, // NODE_TREBLE + {AC97REG_GENERAL, 0x1000}, // NODE_LOUDNESS + {AC97REG_GENERAL, 0x4000}, // NODE_SIMUL_STEREO + {AC97REG_MASTER_VOLUME, 0x3F3F}, // NODE_MASTEROUT_VOLUME + {AC97REG_MASTER_VOLUME, 0x8000}, // NODE_MASTEROUT_MUTE + {AC97REG_HPHONE_VOLUME, 0x3F3F}, // NODE_HPHONE_VOLUME + {AC97REG_HPHONE_VOLUME, 0x8000}, // NODE_HPHONE_MUTE + {AC97REG_GENERAL, 0x0200}, // NODE_MONOOUT_SELECT + {AC97REG_MMONO_VOLUME, 0x803F}, // NODE_VIRT_MONOOUT_VOLUME1 + {AC97REG_MMONO_VOLUME, 0x803F}, // NODE_VIRT_MONOOUT_VOLUME2 + {AC97REG_RECORD_SELECT, 0x0707}, // NODE_WAVEIN_SELECT + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME1 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME2 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME3 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME4 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME5 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME6 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME7 + {AC97REG_RECORD_GAIN, 0x0F0F}, // NODE_VIRT_MASTER_INPUT_VOLUME8 + {AC97REG_RECORD_GAIN_MIC, 0x000F}, // NODE_MICIN_VOLUME + {AC97REG_RECORD_GAIN_MIC, 0x8000}, // NODE_MICIN_MUTE + {AC97REG_SURROUND_VOLUME, 0x3F3F}, // NODE_SURROUND_VOLUME + {AC97REG_SURROUND_VOLUME, 0x8080}, // NODE_SURROUND_MUTE + {AC97REG_CENTER_LFE_VOLUME, 0x3F00},// NODE_CENTER_VOLUME + {AC97REG_CENTER_LFE_VOLUME, 0x8000},// NODE_CENTER_MUTE + {AC97REG_CENTER_LFE_VOLUME, 0x003F},// NODE_LFE_VOLUME + {AC97REG_CENTER_LFE_VOLUME, 0x0080},// NODE_LFE_MUTE + {AC97REG_MASTER_VOLUME, 0x3F3F}, // NODE_FRONT_VOLUME + {AC97REG_MASTER_VOLUME, 0x8000}, // NODE_FRONT_MUTE + {AC97REG_INVALID, 0x0000}, // NODE_VIRT_MASTERMONO_VOLUME doesn't have controls + {AC97REG_INVALID, 0x0000} // NODE_VIRT_MASTERMONO_MUTE doesn't have controls +}; + +#endif //_AC97REG_H_ diff --git a/drivers/wdm/audio/drivers/ac97/adapter.cpp b/drivers/wdm/audio/drivers/ac97/adapter.cpp new file mode 100644 index 00000000000..341abf7ea13 --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/adapter.cpp @@ -0,0 +1,583 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file adapter.cpp was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +// +// The name that is printed in debug output messages +// +#define STR_MODULENAME "AC97 Adapter: " + +// +// All the GUIDs from portcls and your own defined GUIDs end up in this object. +// +#define PUT_GUIDS_HERE + +// +// We want the global debug variables here. +// +#define DEFINE_DEBUG_VARS + +#include "adapter.h" + + +/***************************************************************************** + * Referenced forward + */ +DRIVER_ADD_DEVICE AddDevice; + +#ifdef _MSC_VER +#pragma code_seg("PAGE") +#endif +/***************************************************************************** + * InstallSubdevice + ***************************************************************************** + * This function creates and registers a subdevice consisting of a port + * driver, a minport driver and a set of resources bound together. It will + * also optionally place a pointer to an interface on the port driver in a + * specified location before initializing the port driver. This is done so + * that a common ISR can have access to the port driver during initialization, + * when the ISR might fire. + * This function is internally used and validates no parameters. + */ +NTSTATUS InstallSubdevice +( + _In_ PDEVICE_OBJECT DeviceObject, + _In_ PIRP Irp, + _In_ PWSTR Name, + _In_ REFGUID PortClassId, + _In_ REFGUID MiniportClassId, + _In_opt_ PFNCREATEMINIPORT MiniportCreate, + _In_opt_ PUNKNOWN UnknownAdapter, + _In_opt_ PRESOURCELIST ResourceList, + _In_opt_ REFGUID PortInterfaceId, + _Out_opt_ PMINIPORT * OutMiniport, + _Out_opt_ PUNKNOWN * OutPortUnknown +) +{ + PAGED_CODE (); + + NTSTATUS ntStatus; + PPORT port; + PMINIPORT miniport; + + DOUT (DBG_PRINT, ("[InstallSubdevice]")); + +#ifndef __REACTOS__ + UNREFERENCED_PARAMETER(PortInterfaceId); +#endif + + // + // Create the port driver object + // + ntStatus = PcNewPort (&port,PortClassId); + + // + // return immediately in case of an error + // + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Create the miniport object + // + if (MiniportCreate) + { + ntStatus = MiniportCreate ((PUNKNOWN*)&miniport, MiniportClassId, + NULL, NonPagedPool); + } + else + { + ntStatus = PcNewMiniport (&miniport,MiniportClassId); + } + + // + // return immediately in case of an error + // + if (!NT_SUCCESS (ntStatus)) + { + port->Release (); + return ntStatus; + } + + // + // Init the port driver and miniport in one go. + // +#ifdef _MSC_VER +#pragma warning(push) +#endif + // IPort::Init's annotation on ResourceList requires it to be non-NULL. However, + // for dynamic devices, we may no longer have the resource list and this should + // still succeed. + // +#ifdef _MSC_VER +#pragma warning(disable:6387) +#endif + ntStatus = port->Init (DeviceObject, Irp, miniport, UnknownAdapter, + ResourceList); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + if (NT_SUCCESS (ntStatus)) + { + // + // Register the subdevice (port/miniport combination). + // + ntStatus = PcRegisterSubdevice (DeviceObject, Name, port); + + // + // Deposit the port as an unknown if it's needed. + // + if (OutPortUnknown && NT_SUCCESS (ntStatus)) + { + ntStatus = port->QueryInterface (IID_IUnknown, + (PVOID *)OutPortUnknown); + } + + // + // Deposit the miniport as an IMiniport if it's needed. + // + if ( OutMiniport && NT_SUCCESS (ntStatus) ) + { + ntStatus = miniport->QueryInterface (IID_IMiniport, + (PVOID *)OutMiniport); + } + } + + // + // Release the reference for the port and miniport. This is the right + // thing to do, regardless of the outcome. + // + miniport->Release (); + port->Release (); + + + return ntStatus; +} + + +/***************************************************************************** + * ValidateResources + ***************************************************************************** + * This function validates the list of resources for the various functions on + * the card. This code is specific to the adapter. + * This function doesn't check the ResourceList parameter and returns + * STATUS_SUCCESS when the resources are valid. + */ +NTSTATUS ValidateResources +( + IN PRESOURCELIST ResourceList // All resources. +) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[ValidateResources]")); + + // + // Get counts for the types of resources. + // + ULONG countIO = ResourceList->NumberOfPorts (); + ULONG countIRQ = ResourceList->NumberOfInterrupts (); + ULONG countDMA = ResourceList->NumberOfDmas (); + + // validate resources + if ((countIO != 2) || (countIRQ != 1) || (countDMA != 0)) + { + DOUT (DBG_ERROR, ("Unknown configuration:\n" + " IO count: %d\n" + " IRQ count: %d\n" + " DMA count: %d", + countIO, countIRQ, countDMA)); + return STATUS_DEVICE_CONFIGURATION_ERROR; + } + + return STATUS_SUCCESS; +} + +/***************************************************************************** + * StartDevice + ***************************************************************************** + * This function is called by the operating system when the device is started. + * It is responsible for starting the miniports. This code is specific to + * the adapter because it calls out miniports for functions that are specific + * to the adapter. + */ +NTSTATUS GZCALL StartDevice +( + IN PDEVICE_OBJECT DeviceObject, // Device object. + IN PIRP Irp, // IO request packet. + IN PRESOURCELIST ResourceList // List of hardware resources. +) +{ + PAGED_CODE (); + + ASSERT (DeviceObject); + ASSERT (Irp); + ASSERT (ResourceList); + + NTSTATUS ntStatus; + + DOUT (DBG_PRINT, ("[StartDevice]")); + + // + // Determine which version of the OS we are running under. We don't want + // to run under Win98G. + // + + // create a wave cyclic port + PPORT pPort = 0; + ntStatus = PcNewPort (&pPort,CLSID_PortWaveCyclic); + + // check error code + if (NT_SUCCESS (ntStatus)) + { + // query for the event interface which is not supported in Win98 gold. + PPORTEVENTS pPortEvents = 0; + ntStatus = pPort->QueryInterface (IID_IPortEvents, + (PVOID *)&pPortEvents); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("This driver is not for Win98 Gold!")); + ntStatus = STATUS_UNSUCCESSFUL; // change error code. + } + else + { + pPortEvents->Release (); + } + pPort->Release (); + } + + // now return in case it was Win98 Gold. + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Validate the resources. + // We don't have to split the resources into several resource lists cause + // the topology miniport doesn't need a resource list, the wave pci miniport + // needs all resources like the adapter common object. + // + ntStatus = ValidateResources (ResourceList); + + // + // return immediately in case of an error + // + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // If the adapter has the right resources... + // + PADAPTERCOMMON pAdapterCommon = NULL; + PUNKNOWN pUnknownCommon; + + // create a new adapter common object + ntStatus = NewAdapterCommon (&pUnknownCommon, IID_IAC97AdapterCommon, + NULL, NonPagedPool); + + if (NT_SUCCESS (ntStatus)) + { + // query for the IAC97AdapterCommon interface + ntStatus = pUnknownCommon->QueryInterface (IID_IAC97AdapterCommon, + (PVOID *)&pAdapterCommon); + if (NT_SUCCESS (ntStatus)) + { + // Initialize the object + ntStatus = pAdapterCommon->Init (ResourceList, DeviceObject); + + if (NT_SUCCESS (ntStatus)) + { + // register with PortCls for power-management services + ntStatus = PcRegisterAdapterPowerManagement ((PUNKNOWN)pAdapterCommon, + DeviceObject); + } + } + + // release the IID_IAC97AdapterCommon on adapter common + pUnknownCommon->Release (); + } + + // print error message. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Could not create or query AdapterCommon.")); + } + + // + // These are the port driver pointers we are keeping around for registering + // physical connections. + // + PMINIPORT miniTopology = NULL; + PUNKNOWN unknownWave = NULL; + PUNKNOWN unknownTopology = NULL; + PAC97MINIPORTTOPOLOGY pMiniportTopology = NULL; + + // + // Start the topology miniport. + // + if (NT_SUCCESS (ntStatus)) + { + ntStatus = InstallSubdevice (DeviceObject, + Irp, + L"Topology", + CLSID_PortTopology, + CLSID_PortTopology, // not used + CreateAC97MiniportTopology, + pAdapterCommon, + NULL, + GUID_NULL, + &miniTopology, + &unknownTopology); + + if (NT_SUCCESS (ntStatus)) + { + // query for the IAC97MiniportTopology interface + ntStatus = miniTopology->QueryInterface (IID_IAC97MiniportTopology, + (PVOID *)&pMiniportTopology); + miniTopology->Release (); + miniTopology = NULL; + } + + // print error message. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Could not create or query TopologyICH")); + } + } + + // + // Start the wave miniport. + // + if (NT_SUCCESS (ntStatus)) + { +#if (NTDDI_VERSION >= NTDDI_VISTA) + ntStatus = InstallSubdevice (DeviceObject, + Irp, + L"Wave", + CLSID_PortWaveRT, + CLSID_PortWaveRT, // not used + CreateAC97MiniportWaveRT, + pAdapterCommon, + ResourceList, + IID_IPortWaveRT, + NULL, + &unknownWave); + + if (!NT_SUCCESS (ntStatus)) + { +#endif + // + // If creation of the RT port failed we can fall back to the WavePCI + // or WaveCyc port of portcls. In this case, we try the WavePCI port. + // +#if 1 + ntStatus = InstallSubdevice (DeviceObject, + Irp, + L"Wave", + CLSID_PortWaveCyclic, + CLSID_PortWaveCyclic, // not used + CreateAC97MiniportWaveCyclic, + pAdapterCommon, + ResourceList, + IID_IPortWaveCyclic, + NULL, + &unknownWave); +#else + ntStatus = InstallSubdevice (DeviceObject, + Irp, + L"Wave", + CLSID_PortWavePci, + CLSID_PortWavePci, // not used + CreateAC97MiniportWavePCI, + pAdapterCommon, + ResourceList, + IID_IPortWavePci, + NULL, + &unknownWave); +#endif + + +#if (NTDDI_VERSION >= NTDDI_VISTA) + } +#endif + // print error message. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("WaveRT and WavePCI miniport installation failed!")); + } + } + + // + // Establish physical connections between filters as shown. + // + // +------+ +------+ + // | Wave | | Topo | + // Capture <---|2 3|<===|x |<--- CD + // | | | | + // Render --->|0 1|===>|y |<--- Line In + // | | | | + // Mic <---|4 5|<===|z |<--- Mic + // +------+ | | + // | |---> Line Out + // +------+ + // + // Note that the pin numbers for the nodes to be connected + // vary depending on the hardware/codec configuration. + // Also, the mic input may or may not be present. + // + // So, + // Do a QI on unknownTopology to get an interface to call + // a method on to get the topology miniport pin IDs. + + if (NT_SUCCESS (ntStatus)) + { + ULONG ulWaveOut, ulWaveIn, ulMicIn; + + // get the pin numbers. + DOUT (DBG_PRINT, ("Connecting topo and wave.")); + ntStatus = pMiniportTopology->GetPhysicalConnectionPins (&ulWaveOut, + &ulWaveIn, &ulMicIn); + + // register wave render connection + if (NT_SUCCESS (ntStatus)) + { + ntStatus = PcRegisterPhysicalConnection (DeviceObject, + unknownWave, + PIN_WAVEOUT_BRIDGE, + unknownTopology, + ulWaveOut); + // print error message. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport" + " (render)!")); + } + } + + + if (NT_SUCCESS (ntStatus)) + { + // register wave capture connection + ntStatus = PcRegisterPhysicalConnection (DeviceObject, + unknownTopology, + ulWaveIn, + unknownWave, + PIN_WAVEIN_BRIDGE); + // print error message. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport" + " (capture)!")); + } + } + + if (NT_SUCCESS (ntStatus)) + { + // register mic capture connection + if (pAdapterCommon->GetPinConfig (PINC_MICIN_PRESENT)) + { + ntStatus = PcRegisterPhysicalConnection (DeviceObject, + unknownTopology, + ulMicIn, + unknownWave, + PIN_MICIN_BRIDGE); + // print error message. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport" + " (MIC)!")); + } + } + } + } + + // + // Release the adapter common object. It either has other references, + // or we need to delete it anyway. + // + if (pAdapterCommon) + pAdapterCommon->Release (); + + // + // Release the unknowns. + // + if (unknownTopology) + unknownTopology->Release (); + if (unknownWave) + unknownWave->Release (); + + // and the AC97 miniport. + if (pMiniportTopology) + pMiniportTopology->Release (); + + + return ntStatus; // whatever this is ... +} + +/***************************************************************************** + * AddDevice + ***************************************************************************** + * This function is called by the operating system when the device is added. + * All adapter drivers can use this code without change. + */ +// disable prefast warning 28152 because +// DO_DEVICE_INITIALIZING is cleared in PcAddAdapterDevice +#ifdef _MSC_VER +#pragma warning(disable:28152) +#endif +NTSTATUS GZCALL AddDevice +( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PhysicalDeviceObject +) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[AddDevice]")); + + + // + // Tell portcls (the class driver) to add the device. + // + return PcAddAdapterDevice (DriverObject, + PhysicalDeviceObject, + (PCPFNSTARTDEVICE)StartDevice, + MAX_MINIPORTS, + 0); +} + +/***************************************************************************** + * DriverEntry + ***************************************************************************** + * This function is called by the operating system when the driver is loaded. + * All adapter drivers can use this code without change. + */ +extern "C" DRIVER_INITIALIZE DriverEntry; +extern "C" NTSTATUS GZCALL DriverEntry +( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPathName +) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[DriverEntry]")); + + // + // Tell the class driver to initialize the driver. + // + NTSTATUS RetValue = PcInitializeAdapterDriver (DriverObject, + RegistryPathName, + (PDRIVER_ADD_DEVICE)AddDevice); + + + return RetValue; +} + + + diff --git a/drivers/wdm/audio/drivers/ac97/adapter.h b/drivers/wdm/audio/drivers/ac97/adapter.h new file mode 100644 index 00000000000..f5d5d4c2892 --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/adapter.h @@ -0,0 +1,71 @@ +/******************************************************************************** +** Copyright (c) 1998-1999 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file adapter.h was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#ifndef _ADAPTER_H_ +#define _ADAPTER_H_ + +#include "shared.h" + +/***************************************************************************** + * Defines + ***************************************************************************** + */ +const ULONG MAX_MINIPORTS = 2; + +/***************************************************************************** + * Functions + ***************************************************************************** + */ +// +// both wave & topology miniport create function prototypes have this form: +// +typedef HRESULT (*PFNCREATEMINIPORT)( + OUT PUNKNOWN * Unknown, + IN REFCLSID ClassId, + IN PUNKNOWN OuterUnknown OPTIONAL, + IN POOL_TYPE PoolType +); + +/***************************************************************************** + * Externals + ***************************************************************************** + */ +extern NTSTATUS CreateAC97MiniportWaveRT +( + OUT PUNKNOWN * Unknown, + IN REFCLSID, + IN PUNKNOWN UnknownOuter OPTIONAL, + IN POOL_TYPE PoolType +); + +extern NTSTATUS CreateAC97MiniportWavePCI +( + OUT PUNKNOWN * Unknown, + IN REFCLSID, + IN PUNKNOWN UnknownOuter OPTIONAL, + IN POOL_TYPE PoolType +); + +extern NTSTATUS CreateAC97MiniportWaveCyclic +( + OUT PUNKNOWN * Unknown, + IN REFCLSID, + IN PUNKNOWN UnknownOuter OPTIONAL, + IN POOL_TYPE PoolType +); + +extern NTSTATUS CreateAC97MiniportTopology +( + OUT PUNKNOWN * Unknown, + IN REFCLSID, + IN PUNKNOWN UnknownOuter OPTIONAL, + IN POOL_TYPE PoolType +); + +#endif //_ADAPTER_H_ diff --git a/drivers/wdm/audio/drivers/ac97/common.cpp b/drivers/wdm/audio/drivers/ac97/common.cpp new file mode 100644 index 00000000000..fd55d166d8c --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/common.cpp @@ -0,0 +1,2309 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file common.cpp was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +// Every debug output has "Modulname text" +#define STR_MODULENAME "AC97 Common: " + +#include "common.h" + + +/***************************************************************************** + * Static Members + ***************************************************************************** + */ + +// +// This is the register cache including registry names and default values. The +// first WORD contains the register value and the second WORD contains a flag. +// Currently, we only set SHREG_INVALID if we have to read the register at +// startup (that's true when there is no constant default value for the +// register). Note that we cache the registers only to prevent read access to +// the AC97 CoDec during runtime, because this is slow (40us). +// We only set SHREG_INIT if we want to set the register to default at driver +// startup. If needed, the third field contains the registry name and the +// forth field contains a default value that is used when there is no registry +// entry. +// The flag SHREG_NOCACHE is used when we don't want to cache the register +// at all. This is neccessary for status registers and sample rate registers. +// +tAC97Registers CAC97AdapterCommon::m_stAC97Registers[] = +{ +{0x0000, SHREG_INVALID, NULL, 0}, // AC97REG_RESET +{0x8000, SHREG_INIT, L"MasterVolume", 0x0000}, // AC97REG_MASTER_VOLUME +{0x8000, SHREG_INIT, L"HeadphoneVolume", 0x0000}, // AC97REG_HPHONE_VOLUME +{0x8000, SHREG_INIT, L"MonooutVolume", 0x0000}, // AC97REG_MMONO_VOLUME +{0x0F0F, SHREG_INIT, L"ToneControls", 0x0F0F}, // AC97REG_MASTER_TONE +{0x0000, SHREG_INVALID | + SHREG_INIT, L"BeepVolume", 0x0000}, // AC97REG_BEEP_VOLUME +{0x8008, SHREG_INIT, L"PhoneVolume", 0x8008}, // AC97REG_PHONE_VOLUME +{0x8008, SHREG_INIT, L"MicVolume", 0x8008}, // AC97REG_MIC_VOLUME +{0x8808, SHREG_INIT, L"LineInVolume", 0x0808}, // AC97REG_LINE_IN_VOLUME +{0x8808, SHREG_INIT, L"CDVolume", 0x0808}, // AC97REG_CD_VOLUME +{0x8808, SHREG_INIT, L"VideoVolume", 0x0808}, // AC97REG_VIDEO_VOLUME +{0x8808, SHREG_INIT, L"AUXVolume", 0x0808}, // AC97REG_AUX_VOLUME +{0x8808, SHREG_INIT, L"WaveOutVolume", 0x0808}, // AC97REG_PCM_OUT_VOLUME +{0x0000, SHREG_INIT, L"RecordSelect", 0x0404}, // AC97REG_RECORD_SELECT +{0x8000, SHREG_INIT, L"RecordGain", 0x0000}, // AC97REG_RECORD_GAIN +{0x8000, SHREG_INIT, L"RecordGainMic", 0x0000}, // AC97REG_RECORD_GAIN_MIC +{0x0000, SHREG_INIT, L"GeneralPurpose", 0x0000}, // AC97REG_GENERAL +{0x0000, SHREG_INIT, L"3DControl", 0x0000}, // AC97REG_3D_CONTROL +{0x0000, SHREG_NOCACHE, NULL, 0}, // AC97REG_RESERVED +{0x0000, SHREG_NOCACHE | + SHREG_INIT, L"PowerDown", 0}, // AC97REG_POWERDOWN +// AC97-2.0 registers +{0x0000, SHREG_INVALID, NULL, 0}, // AC97REG_EXT_AUDIO_ID +{0x0000, SHREG_NOCACHE | + SHREG_INIT, L"ExtAudioCtrl", 0x4001}, // AC97REG_EXT_AUDIO_CTRL +{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_FRONT_SAMPLERATE +{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_SURROUND_SAMPLERATE +{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_LFE_SAMPLERATE +{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_RECORD_SAMPLERATE +{0xBB80, SHREG_NOCACHE, NULL, 0}, // AC97REG_MIC_SAMPLERATE +{0x8080, SHREG_INIT, L"CenterLFEVolume", 0x0000}, // AC97REG_CENTER_LFE_VOLUME +{0x8080, SHREG_INIT, L"SurroundVolume", 0x0000}, // AC97REG_SURROUND_VOLUME +{0x0000, SHREG_NOCACHE, NULL, 0} // AC97REG_RESERVED2 + +// We leave the other values blank. There would be a huge gap with 31 +// elements that are currently unused, and then there would be 2 other +// (used) values, the vendor IDs. We just force a read from the vendor +// IDs in the end of ProbeHWConfig to fill the cache. +}; + + +// +// This is the hardware configuration information. The first struct is for +// nodes, which we default to FALSE. The second struct is for Pins, which +// contains the configuration (FALSE) and the registry string which is the +// reason for making a static struct so we can just fill in the name. +// +tHardwareConfig CAC97AdapterCommon::m_stHardwareConfig = +{ + // Nodes + {{FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, + {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, {FALSE}, + {FALSE}}, + // Pins + {{FALSE, L"DisablePCBeep"}, // PINC_PCBEEP_PRESENT + {FALSE, L"DisablePhone"}, // PINC_PHONE_PRESENT + {FALSE, L"DisableMic2"}, // PINC_MIC2_PRESENT + {FALSE, L"DisableVideo"}, // PINC_VIDEO_PRESENT + {FALSE, L"DisableAUX"}, // PINC_AUX_PRESENT + {FALSE, L"DisableHeadphone"}, // PINC_HPOUT_PRESENT + {FALSE, L"DisableMonoOut"}, // PINC_MONOOUT_PRESENT + {FALSE, L"DisableMicIn"}, // PINC_MICIN_PRESENT + {FALSE, L"DisableMic"}, // PINC_MIC_PRESENT + {FALSE, L"DisableLineIn"}, // PINC_LINEIN_PRESENT + {FALSE, L"DisableCD"}, // PINC_CD_PRESENT + {FALSE, L"DisableSurround"}, // PINC_SURROUND_PRESENT + {FALSE, L"DisableCenterLFE"}} // PINC_CENTER_LFE_PRESENT +}; + + +#ifdef _MSC_VER +#pragma code_seg("PAGE") +#endif +/***************************************************************************** + * NewAdapterCommon + ***************************************************************************** + * Create a new adapter common object. + */ +NTSTATUS NewAdapterCommon +( + OUT PUNKNOWN *Unknown, + IN REFCLSID, + IN PUNKNOWN UnknownOuter OPTIONAL, + _When_((PoolType & NonPagedPoolMustSucceed) != 0, + __drv_reportError("Must succeed pool allocations are forbidden. " + "Allocation failures cause a system crash")) + IN POOL_TYPE PoolType +) +{ + PAGED_CODE (); + + ASSERT (Unknown); + + DOUT (DBG_PRINT, ("[NewAdapterCommon]")); + + STD_CREATE_BODY_WITH_TAG_(CAC97AdapterCommon,Unknown,UnknownOuter,PoolType, + PoolTag, PADAPTERCOMMON); +} + + +/***************************************************************************** + * CAC97AdapterCommon::Init + ***************************************************************************** + * Initialize the adapter common object -> initialize and probe HW. + * Pass only checked resources. + */ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::Init +( + IN PRESOURCELIST ResourceList, + IN PDEVICE_OBJECT DeviceObject +) +{ + PAGED_CODE (); + + ASSERT (ResourceList); + ASSERT (DeviceObject); + + NTSTATUS ntStatus = STATUS_SUCCESS; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::Init]")); + + // + // Set the topology pointer to NULL. + // + m_Topology = NULL; + + // + // Save the device object + // + m_pDeviceObject = DeviceObject; + + // + // Get the base address for the AC97 codec and bus master. + // + ASSERT (ResourceList->FindTranslatedPort (0)); + m_pCodecBase = (PUSHORT)ResourceList->FindTranslatedPort (0)-> + u.Port.Start.QuadPart; + + ASSERT (ResourceList->FindTranslatedPort (1)); + m_pBusMasterBase = (PUCHAR)ResourceList->FindTranslatedPort (1)-> + u.Port.Start.QuadPart; + + DOUT (DBG_SYSINFO, ("Configuration:\n" + " Bus Master = 0x%p\n" + " Codec = 0x%p", + m_pBusMasterBase, m_pCodecBase)); + + // + // Set m_bDirectRead to TRUE so that all AC97 register read and + // writes are going directly to the HW + // + m_bDirectRead = TRUE; + + // + // Initialize the hardware. + // + ntStatus = InitAC97 (); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Probe hardware configuration + // + ntStatus = ProbeHWConfig (); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Probing of hardware configuration failed!")); + return ntStatus; + } + + // + // Now, every AC97 read access goes to the cache. + // + m_bDirectRead = FALSE; + + // + // Restore the AC97 registers now. + // +#if (DBG) + DumpConfig (); +#endif + ntStatus = SetAC97Default (); + + // + // Initialize the device state. + // + m_PowerState = PowerDeviceD0; + + return ntStatus; +} + + +/***************************************************************************** + * CAC97AdapterCommon::~CAC97AdapterCommon + ***************************************************************************** + * Destructor. + */ +CAC97AdapterCommon::~CAC97AdapterCommon () +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::~CAC97AdapterCommon]")); +} + + +#if (DBG) +/***************************************************************************** + * CAC97AdapterCommon::DumpConfig + ***************************************************************************** + * Dumps the HW configuration for the AC97 codec. + */ +void CAC97AdapterCommon::DumpConfig (void) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::DumpConfig]")); + + // + // Print debug output for MICIN. + // + if (GetPinConfig (PINC_MICIN_PRESENT)) + { + DOUT (DBG_PROBE, ("MICIN found")); + } + else + { + DOUT (DBG_PROBE, ("No MICIN found")); + } + + // + // Print debug output for tone controls. + // + if (GetNodeConfig (NODEC_TONE_PRESENT)) + { + DOUT (DBG_PROBE, ("Tone controls found")); + } + else + { + DOUT (DBG_PROBE, ("No tone controls found")); + } + + // + // Print debug output for mono out. + // + if (!GetPinConfig (PINC_MONOOUT_PRESENT)) + { + DOUT (DBG_PROBE, ("No mono out found")); + } + + // + // Print debug output for headphones. + // + if (!GetPinConfig (PINC_HPOUT_PRESENT)) + { + DOUT (DBG_PROBE, ("No headphone out found")); + } + + // + // Print debug output for loudness. + // + if (GetNodeConfig (NODEC_LOUDNESS_PRESENT)) + { + DOUT (DBG_PROBE, ("Loudness found")); + } + else + { + DOUT (DBG_PROBE, ("No Loudness found")); + } + + // + // Print debug output for 3D. + // + if (GetNodeConfig (NODEC_3D_PRESENT)) + { + DOUT (DBG_PROBE, ("3D controls found")); + } + else + { + DOUT (DBG_PROBE, ("No 3D controls found")); + } + + // + // Print debug output for pc beep. + // + if (GetPinConfig (PINC_PCBEEP_PRESENT)) + { + DOUT (DBG_PROBE, ("PC beep found")); + } + else + { + DOUT (DBG_PROBE, ("No PC beep found")); + } + + // + // Print debug output for phone line (or mono line input). + // + if (GetPinConfig (PINC_PHONE_PRESENT)) + { + DOUT (DBG_PROBE, ("Phone found")); + } + else + { + DOUT (DBG_PROBE, ("No Phone found")); + } + + // + // Print debug output for video. + // + if (GetPinConfig (PINC_VIDEO_PRESENT)) + { + DOUT (DBG_PROBE, ("Video in found")); + } + else + { + DOUT (DBG_PROBE, ("No Video in found")); + } + + // + // Print debug output for AUX. + // + if (GetPinConfig (PINC_AUX_PRESENT)) + { + DOUT (DBG_PROBE, ("AUX in found")); + } + else + { + DOUT (DBG_PROBE, ("No AUX in found")); + } + + // + // Print debug output for second miorophone. + // + if (GetPinConfig (PINC_MIC2_PRESENT)) + { + DOUT (DBG_PROBE, ("MIC2 found")); + } + else + { + DOUT (DBG_PROBE, ("No MIC2 found")); + } + + // + // Print debug output for 3D stuff. + // + if (GetNodeConfig (NODEC_3D_PRESENT)) + { + if (GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)) + { + DOUT (DBG_PROBE, ("Adjustable 3D center control found")); + } + if (GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)) + { + DOUT (DBG_PROBE, ("Nonadjustable 3D depth control found")); + } + } + + // + // Print debug output for quality of master volume. + // + if (GetNodeConfig (NODEC_6BIT_MASTER_VOLUME)) + { + DOUT (DBG_PROBE, ("6bit master out found")); + } + else + { + DOUT (DBG_PROBE, ("5bit master out found")); + } + + // + // Print debug output for quality of headphones volume. + // + if (GetPinConfig (PINC_HPOUT_PRESENT)) + { + if (GetNodeConfig (NODEC_6BIT_HPOUT_VOLUME)) + { + DOUT (DBG_PROBE, ("6bit headphone out found")); + } + else + { + DOUT (DBG_PROBE, ("5bit headphone out found")); + } + } + + // + // Print debug output for quality of mono out volume. + // + if (GetPinConfig (PINC_MONOOUT_PRESENT)) + { + if (GetNodeConfig (NODEC_6BIT_MONOOUT_VOLUME)) + { + DOUT (DBG_PROBE, ("6bit mono out found")); + } + else + { + DOUT (DBG_PROBE, ("5bit mono out found")); + } + } + + // + // Print sample rate information. + // + if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED)) + { + DOUT (DBG_PROBE, ("PCM variable sample rate supported")); + } + else + { + DOUT (DBG_PROBE, ("only 48KHz PCM supported")); + } + + // + // Print double rate information. + // + if (GetNodeConfig (NODEC_PCM_DOUBLERATE_SUPPORTED)) + { + DOUT (DBG_PROBE, ("PCM double sample rate supported")); + } + + // + // Print mic rate information. + // + if (GetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED)) + { + DOUT (DBG_PROBE, ("MIC variable sample rate supported")); + } + else + { + DOUT (DBG_PROBE, ("only 48KHz MIC supported")); + } + + // print DAC information + if (GetNodeConfig (NODEC_CENTER_DAC_PRESENT)) + { + DOUT (DBG_PROBE, ("center DAC found")); + } + if (GetNodeConfig (NODEC_SURROUND_DAC_PRESENT)) + { + DOUT (DBG_PROBE, ("surround DAC found")); + } + if (GetNodeConfig (NODEC_LFE_DAC_PRESENT)) + { + DOUT (DBG_PROBE, ("LFE DAC found")); + } +} +#endif + +/***************************************************************************** + * CAC97AdapterCommon::NonDelegatingQueryInterface + ***************************************************************************** + * Obtains an interface. This function works just like a COM QueryInterface + * call and is used if the object is not being aggregated. + * We basically just check any GUID we know and return this object in case we + * know it. + */ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::NonDelegatingQueryInterface +( + _In_ REFIID Interface, + _COM_Outptr_ PVOID * Object +) +{ + PAGED_CODE (); + + ASSERT (Object); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::NonDelegatingQueryInterface]")); + + // Is it IID_IUnknown? + if (IsEqualGUIDAligned (Interface, IID_IUnknown)) + { + *Object = (PVOID)(PUNKNOWN)(PADAPTERCOMMON)this; + } + else + // or IID_IAC97AdapterCommon ... + if (IsEqualGUIDAligned (Interface, IID_IAC97AdapterCommon)) + { + *Object = (PVOID)(PADAPTERCOMMON)this; + } + else + // or IID_IAdapterPowerManagement ... + if (IsEqualGUIDAligned (Interface, IID_IAdapterPowerManagement)) + { + *Object = (PVOID)(PADAPTERPOWERMANAGEMENT)this; + } + else + { + // nothing found, must be an unknown interface. + *Object = NULL; + return STATUS_INVALID_PARAMETER; + } + + // + // We reference the interface for the caller. + // + ((PUNKNOWN)*Object)->AddRef (); + return STATUS_SUCCESS; +} + +/***************************************************************************** + * CAC97AdapterCommon::InitAC97 + ***************************************************************************** + * Initialize the AC97 (without hosing the modem if it got installed first). + */ +NTSTATUS CAC97AdapterCommon::InitAC97 (void) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::InitAC97]")); + + // + // First check if there is an AC link to the primary CoDec. + // + NTSTATUS ntStatus = PrimaryCodecReady (); + if (NT_SUCCESS (ntStatus)) + { + // + // Second, reset this primary CoDec; If this is a AMC97 CoDec, only + // the audio registers are reset. If this is a MC97 CoDec, the CoDec + // should ignore the reset (according to the spec). + // + WriteCodecRegister (AC97REG_RESET, 0x00, 0xFFFF); + + ntStatus = PowerUpCodec (); + } + else + { + DOUT (DBG_ERROR, ("Initialization of AC97 CoDec failed.")); + } + + return ntStatus; +} + +/***************************************************************************** + * CAC97AdapterCommon::Check6thBitSupport + ***************************************************************************** + * Probes for 6th bit volume control support. + * The passed parameters are the AC97 register that has the volume control and + * the node config that should be set in this case. + */ +NTSTATUS CAC97AdapterCommon::Check6thBitSupport +( + IN AC97Register AC97Reg, + IN TopoNodeConfig Config +) +{ + PAGED_CODE(); + + NTSTATUS ntStatus; + WORD wCodecReg; + WORD wOriginal; + + // Read the current value. + ntStatus = ReadCodecRegister (AC97Reg, &wOriginal); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Write the 6th bit; for mono controls we write 0x20, for stereo + // controls 0x2020. + ntStatus = WriteCodecRegister (AC97Reg, + (AC97Reg == AC97REG_MMONO_VOLUME) ? 0x0020 : 0x2020, 0xFFFF); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // And read back. + ntStatus = ReadCodecRegister (AC97Reg, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Check return. For mono 0x20 and for stereo 0x2020. + if (((wCodecReg & 0x0020) && (AC97Reg == AC97REG_MMONO_VOLUME)) || + (wCodecReg & 0x2020)) + { + SetNodeConfig (Config, TRUE); + } + else + { + SetNodeConfig (Config, FALSE); + } + + // Restore original value. + WriteCodecRegister (AC97Reg, wOriginal, 0xFFFF); + + return ntStatus; +} + +/***************************************************************************** + * CAC97AdapterCommon::ProbeHWConfig + ***************************************************************************** + * Probes the hardware configuration. + * If this function returns with an error, then the configuration is not + * complete! Probing the registers is done by reading them (and comparing with + * the HW default value) or when the default is unknown, writing to them and + * reading back + restoring. + * Additionally, we read the registry so that a HW vendor can overwrite (means + * disable) found registers in case the adapter (e.g. video) is not visible to + * the user (he can't plug in a video audio there). + * + * This is a very long function with all of the error checking! + */ +NTSTATUS CAC97AdapterCommon::ProbeHWConfig (void) +{ + PAGED_CODE (); + + NTSTATUS ntStatus = STATUS_SUCCESS; + DWORD dwGlobalStatus; + WORD wCodecID; + WORD wCodecReg; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ProbeHWConfig]")); + + // + // Wait for the whatever 97 to complete reset and establish a link. + // + ntStatus = PrimaryCodecReady (); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Master volume is one of the supported registers on an AC97 + // + ntStatus = ReadCodecRegister (AC97REG_MASTER_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Default is x8000. + if (wCodecReg != 0x8000) + return STATUS_NO_SUCH_DEVICE; + + // + // This gives us information about the AC97 CoDec + // + ntStatus = ReadCodecRegister (AC97REG_RESET, &wCodecID); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Fill out the configuration stuff. + // + + SetPinConfig (PINC_MICIN_PRESENT, wCodecID & 0x0001); + + // Check if OEM wants to disable MIC record line. + if (DisableAC97Pin (PINC_MICIN_PRESENT)) + SetPinConfig (PINC_MICIN_PRESENT, FALSE); + + // If we still have MIC record line, enable the DAC in ext. audio register. + if (GetPinConfig (PINC_MICIN_PRESENT)) + // Enable ADC MIC. + WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, 0, 0x4000); + else + // Disable ADC MIC. + WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, 0x4000, 0x4000); + + // + // Continue setting configuration information. + // + + SetNodeConfig (NODEC_TONE_PRESENT, wCodecID & 0x0004); + SetNodeConfig (NODEC_SIMUL_STEREO_PRESENT, wCodecID & 0x0008); + SetPinConfig (PINC_HPOUT_PRESENT, wCodecID & 0x0010); + + // Check if OEM wants to disable headphone output. + if (DisableAC97Pin (PINC_HPOUT_PRESENT)) + SetPinConfig (PINC_HPOUT_PRESENT, FALSE); + + SetNodeConfig (NODEC_LOUDNESS_PRESENT, wCodecID & 0x0020); + SetNodeConfig (NODEC_3D_PRESENT, wCodecID & 0x7C00); + + // + // Test for the input pins that are always there but could be disabled + // by the HW vender + // + + // Check if OEM wants to disable mic input. + SetPinConfig (PINC_MIC_PRESENT, !DisableAC97Pin (PINC_MIC_PRESENT)); + + // Check if OEM wants to disable line input. + SetPinConfig (PINC_LINEIN_PRESENT, !DisableAC97Pin (PINC_LINEIN_PRESENT)); + + // Check if OEM wants to disable CD input. + SetPinConfig (PINC_CD_PRESENT, !DisableAC97Pin (PINC_CD_PRESENT)); + + + // + // For the rest, we have to probe the registers. + // + + // + // Test for Mono out. + // + ntStatus = ReadCodecRegister (AC97REG_MMONO_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Default is x8000. + SetPinConfig (PINC_MONOOUT_PRESENT, (wCodecReg == 0x8000)); + + // Check if OEM wants to disable mono output. + if (DisableAC97Pin (PINC_MONOOUT_PRESENT)) + SetPinConfig (PINC_MONOOUT_PRESENT, FALSE); + + // + // Test for PC beeper support. + // + ntStatus = ReadCodecRegister (AC97REG_BEEP_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // default is x0 or x8000. If it's 0x8000 then we know for sure that the + // CoDec has a PcBeep, otherwise we have to check the register + if (wCodecReg == 0x8000) + SetPinConfig (PINC_PCBEEP_PRESENT, TRUE); + else if (!wCodecReg) + { + // mute the pc beeper. + ntStatus = WriteCodecRegister (AC97REG_BEEP_VOLUME, 0x8000, 0xFFFF); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // read back + ntStatus = ReadCodecRegister (AC97REG_BEEP_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + if (wCodecReg == 0x8000) + { + // yep, we have support. + SetPinConfig (PINC_PCBEEP_PRESENT, TRUE); + // reset to default value. + WriteCodecRegister (AC97REG_BEEP_VOLUME, 0x0, 0xFFFF); + } + else + // nope, not present + SetPinConfig (PINC_PCBEEP_PRESENT, FALSE); + } + else + // any other value then 0x0 and 0x8000. + SetPinConfig (PINC_PCBEEP_PRESENT, FALSE); + + // Check if OEM wants to disable beeper support. + if (DisableAC97Pin (PINC_PCBEEP_PRESENT)) + SetPinConfig (PINC_PCBEEP_PRESENT, FALSE); + + // + // Test for phone support. + // + ntStatus = ReadCodecRegister (AC97REG_PHONE_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Default is x8008. + SetPinConfig (PINC_PHONE_PRESENT, (wCodecReg == 0x8008)); + + // Check if OEM wants to disable phone input. + if (DisableAC97Pin (PINC_PHONE_PRESENT)) + SetPinConfig (PINC_PHONE_PRESENT, FALSE); + + // + // Test for video support. + // + ntStatus = ReadCodecRegister (AC97REG_VIDEO_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Default is x8808. + SetPinConfig (PINC_VIDEO_PRESENT, (wCodecReg == 0x8808)); + + // Check if OEM wants to disable video input. + if (DisableAC97Pin (PINC_VIDEO_PRESENT)) + SetPinConfig (PINC_VIDEO_PRESENT, FALSE); + + // + // Test for Aux support. + // + ntStatus = ReadCodecRegister (AC97REG_AUX_VOLUME, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Default is 0x8808. + SetPinConfig (PINC_AUX_PRESENT, (wCodecReg == 0x8808)); + + // Check if OEM wants to disable aux input. + if (DisableAC97Pin (PINC_AUX_PRESENT)) + SetPinConfig (PINC_AUX_PRESENT, FALSE); + + // + // Test for Mic2 source. + // + ntStatus = ReadCodecRegister (AC97REG_GENERAL, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Test for Mic2 select bit. + if (wCodecReg & 0x0100) + SetPinConfig (PINC_MIC2_PRESENT, TRUE); + else + { + // Select Mic2 as source. + ntStatus = WriteCodecRegister (AC97REG_GENERAL, 0x0100, 0x0100); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Read back. + ntStatus = ReadCodecRegister (AC97REG_GENERAL, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + if (wCodecReg & 0x0100) + { + // Yep, we have support so set it to the default value. + SetPinConfig (PINC_MIC2_PRESENT, TRUE); + // reset to default value. + WriteCodecRegister (AC97REG_GENERAL, 0, 0x0100); + } + else + SetPinConfig (PINC_MIC2_PRESENT, FALSE); + } + + // Check if OEM wants to disable mic2 input. + if (DisableAC97Pin (PINC_MIC2_PRESENT)) + SetPinConfig (PINC_MIC2_PRESENT, FALSE); + + // + // Test the 3D controls. + // + if (GetNodeConfig (NODEC_3D_PRESENT)) + { + // + // First test for fixed 3D controls. Write default value ... + // + ntStatus = WriteCodecRegister (AC97REG_3D_CONTROL, 0, 0xFFFF); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // Read 3D register. Default is 0 when adjustable, otherwise it is + // a fixed value. + ntStatus = ReadCodecRegister (AC97REG_3D_CONTROL, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Check center and depth separately. + // + + // For center + SetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE, !(wCodecReg & 0x0F00)); + + // For depth + SetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE, !(wCodecReg & 0x000F)); + + // + // Test for adjustable controls. + // + WriteCodecRegister (AC97REG_3D_CONTROL, 0x0A0A, 0xFFFF); + + // Read 3D register. Now it should be 0x0A0A for adjustable controls, + // otherwise it is a fixed control or simply not there. + ReadCodecRegister (AC97REG_3D_CONTROL, &wCodecReg); + + // Restore the default value + WriteCodecRegister (AC97REG_3D_CONTROL, 0, 0xFFFF); + + // Check the center control for beeing adjustable + if (GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) && + (wCodecReg & 0x0F00) != 0x0A00) + { + SetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE, FALSE); + } + + // Check the depth control for beeing adjustable + if (GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) && + (wCodecReg & 0x000F) != 0x000A) + { + SetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE, FALSE); + } + } + + // + // Check for 6th bit support in volume controls. To check the 6th bit, + // we first have to write a value (with 6th bit set) and then read it + // back. After that, we should restore the register to its default value. + // + + // + // Start with the master volume. + // + Check6thBitSupport (AC97REG_MASTER_VOLUME, NODEC_6BIT_MASTER_VOLUME); + + // + // Check for a headphone volume control. + // + if (GetPinConfig (PINC_HPOUT_PRESENT)) + { + Check6thBitSupport (AC97REG_HPHONE_VOLUME, NODEC_6BIT_HPOUT_VOLUME); + } + + // + // Mono out there? + // + if (GetPinConfig (PINC_MONOOUT_PRESENT)) + { + Check6thBitSupport (AC97REG_MMONO_VOLUME, NODEC_6BIT_MONOOUT_VOLUME); + } + + // + // Get extended AC97 V2.0 information + // + ntStatus = ReadCodecRegister (AC97REG_EXT_AUDIO_ID, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Store the information + // + SetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED, wCodecReg & 0x0001); + SetNodeConfig (NODEC_PCM_DOUBLERATE_SUPPORTED, wCodecReg & 0x0002); + SetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED, wCodecReg & 0x0008); + SetNodeConfig (NODEC_CENTER_DAC_PRESENT, wCodecReg & 0x0040); + SetNodeConfig (NODEC_SURROUND_DAC_PRESENT, wCodecReg & 0x0080); + SetNodeConfig (NODEC_LFE_DAC_PRESENT, wCodecReg & 0x0100); + + // + // In case we have some features get some more information and program + // the codec. + // + if (wCodecReg) + { + // + // Enable variable sample rate in the control register and disable + // double rate. Also enable all DACs. + // + WriteCodecRegister (AC97REG_EXT_AUDIO_CTRL, wCodecReg & 0x0009, 0x380B); + + // + // Check for codecs that have only one sample rate converter. These + // codecs will stick registers AC97REG_FRONT_SAMPLERATE and + // AC97REG_RECORD_SAMPLERATE together. + // + if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED)) + { + // The default of the sample rate registers should be 0xBB80. + WriteCodecRegister (AC97REG_FRONT_SAMPLERATE, 0xBB80, 0xFFFF); + + // Write 44.1KHz into record VSR, then check playback again. + WriteCodecRegister (AC97REG_RECORD_SAMPLERATE, 0xAC44, 0xFFFF); + ntStatus = ReadCodecRegister (AC97REG_FRONT_SAMPLERATE, &wCodecReg); + WriteCodecRegister (AC97REG_RECORD_SAMPLERATE, 0xBB80, 0xFFFF); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Set the flag accordingly + // + SetNodeConfig (NODEC_PCM_VSR_INDEPENDENT_RATES, (wCodecReg == 0xBB80)); + } + + // + // Check multichanel support on the AC97. + // + if (GetNodeConfig (NODEC_SURROUND_DAC_PRESENT)) + { + dwGlobalStatus = ReadBMControlRegister32 (GLOB_STA); + + // + // Codec supports >2 chanel, does AC97 too? + // + if ((GetNodeConfig (NODEC_CENTER_DAC_PRESENT) || + GetNodeConfig (NODEC_LFE_DAC_PRESENT)) && + (dwGlobalStatus & GLOB_STA_MC6)) + { + SetPinConfig (PINC_CENTER_LFE_PRESENT, TRUE); + } + else + { + SetPinConfig (PINC_CENTER_LFE_PRESENT, FALSE); + } + + // + // Do we support at least 4 channels? + // + SetPinConfig (PINC_SURROUND_PRESENT, (dwGlobalStatus & GLOB_STA_MC4)); + } + else + { + // + // Only 2 channel (stereo) support. + // + SetPinConfig (PINC_CENTER_LFE_PRESENT, FALSE); + SetPinConfig (PINC_SURROUND_PRESENT, FALSE); + } + } + + // Check if OEM wants to disable surround output. + if (DisableAC97Pin (PINC_SURROUND_PRESENT)) + SetPinConfig (PINC_SURROUND_PRESENT, FALSE); + + // Check if OEM wants to disable center and LFE output. + if (DisableAC97Pin (PINC_CENTER_LFE_PRESENT)) + SetPinConfig (PINC_CENTER_LFE_PRESENT, FALSE); + + // + // Check the 6th bit support for the additional channels. + // + if (GetPinConfig (PINC_SURROUND_PRESENT)) + Check6thBitSupport (AC97REG_SURROUND_VOLUME, NODEC_6BIT_SURROUND_VOLUME); + + if (GetPinConfig (PINC_CENTER_LFE_PRESENT)) + Check6thBitSupport (AC97REG_CENTER_LFE_VOLUME, NODEC_6BIT_CENTER_LFE_VOLUME); + + // + // We read these registers because they are dependent on the codec. + // + ReadCodecRegister (AC97REG_VENDOR_ID1, &wCodecReg); + ReadCodecRegister (AC97REG_VENDOR_ID2, &wCodecReg); + + return STATUS_SUCCESS; +} + + +/***************************************************************************** + * CAC97AdapterCommon::AcquireCodecSemiphore + ***************************************************************************** + * Acquires the AC97 semiphore. This can not be called at dispatch level + * because it can timeout if a lower IRQL thread has the semaphore. + */ +NTSTATUS CAC97AdapterCommon::AcquireCodecSemiphore () +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::AcquireCodecSemiphore]")); + + ULONG ulCount = 0; + while (READ_PORT_UCHAR (m_pBusMasterBase + CAS) & CAS_CAS) + { + // + // Do we want to give up?? + // + if (ulCount++ > 100) + { + DOUT (DBG_ERROR, ("Cannot acquire semaphore.")); + return STATUS_IO_TIMEOUT; + } + + // + // Let's wait a little, 40us and then try again. + // + KeStallExecutionProcessor (40L); + } + + return STATUS_SUCCESS; +} + + +/***************************************************************************** + * CAC97AdapterCommon::ReadCodecRegister + ***************************************************************************** + * Reads a AC97 register. Don't call at PASSIVE_LEVEL. + */ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::ReadCodecRegister +( + _In_range_(0, AC97REG_INVALID) AC97Register reg, + _Out_ PWORD wData +) +{ + PAGED_CODE (); + + ASSERT (wData); + ASSERT (reg < AC97REG_INVALID); // audio can only be in the primary codec + _Analysis_assume_(reg < AC97REG_INVALID); + + NTSTATUS ntStatus; + ULONG Status; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadCodecRegister]")); + + // + // Check if we have to access the HW directly. + // + if (m_bDirectRead || (m_stAC97Registers[reg].wFlags & SHREG_INVALID) || + (m_stAC97Registers[reg].wFlags & SHREG_NOCACHE)) + { + // + // Grab the codec access semiphore. + // + ntStatus = AcquireCodecSemiphore (); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("ReadCodecRegister couldn't acquire the semiphore" + " for reg. %s", reg <= AC97REG_RESERVED2 ? RegStrings[reg] : + reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" : + reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : + "REG_INVALID")); + return ntStatus; + } + + // + // Read the data. + // + *wData = READ_PORT_USHORT (m_pCodecBase + reg); + + // + // Check to see if the read was successful. + // + Status = READ_PORT_ULONG ((PULONG)(m_pBusMasterBase + GLOB_STA)); + if (Status & GLOB_STA_RCS) + { + // + // clear the timeout bit + // + WRITE_PORT_ULONG ((PULONG)(m_pBusMasterBase + GLOB_STA), Status); + *wData = 0; + DOUT (DBG_ERROR, ("ReadCodecRegister timed out for register %s", + reg <= AC97REG_RESERVED2 ? RegStrings[reg] : + reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" : + reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : + "REG_INVALID")); + return STATUS_IO_TIMEOUT; + } + + // + // Clear invalid flag + // + m_stAC97Registers[reg].wCache = *wData; + m_stAC97Registers[reg].wFlags &= ~SHREG_INVALID; + + DOUT (DBG_REGS, ("AC97READ: %s = 0x%04x (HW)", + reg <= AC97REG_RESERVED2 ? RegStrings[reg] : + reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" : + reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : + "REG_INVALID", *wData)); + } + else + { + // + // Otherwise, use the value in the cache. + // + *wData = m_stAC97Registers[reg].wCache; + DOUT (DBG_REGS, ("AC97READ: %s = 0x%04x (C)", + reg <= AC97REG_RESERVED2 ? RegStrings[reg] : + reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" : + reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : + "REG_INVALID", *wData)); + } + + return STATUS_SUCCESS; +} + + +/***************************************************************************** + * CAC97AdapterCommon::WriteCodecRegister + ***************************************************************************** + * Writes to a AC97 register. This can only be done at passive level because + * the AcquireCodecSemiphore call could fail! + */ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::WriteCodecRegister +( + _In_range_(0, AC97REG_INVALID) AC97Register reg, + _In_ WORD wData, + _In_ WORD wMask +) +{ + PAGED_CODE (); + + ASSERT (reg < AC97REG_INVALID); // audio can only be in the primary codec + + WORD TempData = 0; + NTSTATUS ntStatus = STATUS_SUCCESS; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteCodecRegister]")); + + // + // No mask? Could happen when you try to prg. left channel of a + // mono volume. + // + if (!wMask) + return STATUS_SUCCESS; + + // + // Check to see if we are only writing specific bits. If so, we want + // to leave some bits in the register alone. + // + if (wMask != 0xffff) + { + // + // Read the current register contents. + // + ntStatus = ReadCodecRegister (reg, &TempData); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("WriteCodecRegiser read for mask failed")); + return ntStatus; + } + + // + // Do the masking. + // + TempData &= ~wMask; + TempData |= (wMask & wData); + } + else + { + TempData = wData; + } + + + // + // Grab the codec access semiphore. + // + ntStatus = AcquireCodecSemiphore (); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("WriteCodecRegister failed for register %s", + reg <= AC97REG_RESERVED2 ? RegStrings[reg] : + reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" : + reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : "REG_INVALID")); + return ntStatus; + } + + // + // Write the data. + // + WRITE_PORT_USHORT (m_pCodecBase + reg, TempData); + + // + // Update cache. + // + _Analysis_assume_(reg < AC97REG_INVALID); + m_stAC97Registers[reg].wCache = TempData; + + DOUT (DBG_REGS, ("AC97WRITE: %s -> 0x%04x", + reg <= AC97REG_RESERVED2 ? RegStrings[reg] : + reg == AC97REG_VENDOR_ID1 ? "REG_VENDOR_ID1" : + reg == AC97REG_VENDOR_ID2 ? "REG_VENDOR_ID2" : + "REG_INVALID", TempData)); + + + return STATUS_SUCCESS; +} + + +/***************************************************************************** + * CAC97AdapterCommon::PrimaryCodecReady + ***************************************************************************** + * Checks whether the primary codec is present and ready. This may take + * awhile if we are bringing it up from a cold reset so give it a second + * before giving up. + */ +NTSTATUS CAC97AdapterCommon::PrimaryCodecReady (void) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::PrimaryCodecReady]")); + + + // + // Enable the AC link and raise the reset line. + // + DWORD dwRegValue = ReadBMControlRegister32 (GLOB_CNT); + + // If someone enabled GPI Interrupt Enable, then he hopefully handles that + // too. + dwRegValue = (dwRegValue | GLOB_CNT_COLD) & ~(GLOB_CNT_ACLOFF | GLOB_CNT_PRIE); + WriteBMControlRegister (GLOB_CNT, dwRegValue); + + // + // Wait for the Codec to be ready. + // + ULONG WaitCycles = 200; + LARGE_INTEGER WaitTime; + + WaitTime.QuadPart = (-50000); // wait 5000us (5ms) relative + + do + { + if (READ_PORT_ULONG ((PULONG)(m_pBusMasterBase + GLOB_STA)) & + GLOB_STA_PCR) + { + return STATUS_SUCCESS; + } + + KeDelayExecutionThread (KernelMode, FALSE, &WaitTime); + } while (WaitCycles--); + + DOUT (DBG_ERROR, ("PrimaryCodecReady timed out!")); + return STATUS_IO_TIMEOUT; +} + + +/***************************************************************************** + * CAC97AdapterCommon::PowerUpCodec + ***************************************************************************** + * Sets the Codec to the highest power state and waits until the Codec reports + * that the power state is reached. + */ +NTSTATUS CAC97AdapterCommon::PowerUpCodec (void) +{ + PAGED_CODE (); + + WORD wCodecReg; + NTSTATUS ntStatus; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::PowerUpCodec]")); + + // + // Power up the Codec. + // + WriteCodecRegister (AC97REG_POWERDOWN, 0x00, 0xFFFF); + + // + // Wait for the Codec to be powered up. + // + ULONG WaitCycles = 200; + LARGE_INTEGER WaitTime; + + WaitTime.QuadPart = (-50000); // wait 5000us (5ms) relative + + do + { + // + // Read the power management register. + // + ntStatus = ReadCodecRegister (AC97REG_POWERDOWN, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + { + wCodecReg = 0; // Will cause an error. + break; + } + + // + // Check the power state. Should be ready. + // + if ((wCodecReg & 0x0f) == 0x0f) + break; + + // + // Let's wait a little, 5ms and then try again. + // + KeDelayExecutionThread (KernelMode, FALSE, &WaitTime); + } while (WaitCycles--); + + // Check if we timed out. + if ((wCodecReg & 0x0f) != 0x0f) + { + DOUT (DBG_ERROR, ("PowerUpCodec timed out. CoDec not powered up.")); + ntStatus = STATUS_DEVICE_NOT_READY; + } + + return ntStatus; +} + + +/***************************************************************************** + * CAC97AdapterCommon::ProgramSampleRate + ***************************************************************************** + * Programs the sample rate. If the rate cannot be programmed, the routine + * restores the register and returns STATUS_UNSUCCESSFUL. + * We don't handle double rate sample rates here, because the Intel AC97 con- + * troller cannot serve CoDecs with double rate or surround sound. If you want + * to modify this driver for another AC97 controller, then you might want to + * change this function too. + */ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::ProgramSampleRate +( + IN AC97Register Register, + IN DWORD dwSampleRate +) +{ + PAGED_CODE (); + + WORD wOldRateReg, wCodecReg; + NTSTATUS ntStatus; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ProgramSampleRate]")); + + // + // Check if we support variable sample rate. + // + switch(Register) + { + case AC97REG_MIC_SAMPLERATE: + // + // Variable sample rate supported? + // + if (GetNodeConfig (NODEC_MIC_VARIABLERATE_SUPPORTED)) + { + // Range supported? + if (dwSampleRate > 48000ul) + { + // Not possible. + DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate)); + return STATUS_NOT_SUPPORTED; + } + } + else + { + // Only 48000KHz possible. + if (dwSampleRate != 48000ul) + { + DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate)); + return STATUS_NOT_SUPPORTED; + } + + return STATUS_SUCCESS; + } + break; + + case AC97REG_FRONT_SAMPLERATE: + case AC97REG_SURROUND_SAMPLERATE: + case AC97REG_LFE_SAMPLERATE: + case AC97REG_RECORD_SAMPLERATE: + // + // Variable sample rate supported? + // + if (GetNodeConfig (NODEC_PCM_VARIABLERATE_SUPPORTED)) + { + // + // Check range supported + // + if (dwSampleRate > 48000ul) + { + DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate)); + return STATUS_NOT_SUPPORTED; + } + } + else + { + // Only 48KHz possible. + if (dwSampleRate != 48000ul) + { + DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate)); + return STATUS_NOT_SUPPORTED; + } + + return STATUS_SUCCESS; + } + break; + + default: + DOUT (DBG_ERROR, ("Invalid sample rate register!")); + return STATUS_UNSUCCESSFUL; + } + + + // + // Save the old sample rate register. + // + ntStatus = ReadCodecRegister (Register, &wOldRateReg); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // program the rate. + // + ntStatus = WriteCodecRegister (Register, (WORD)dwSampleRate, 0xFFFF); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Cannot program sample rate.")); + return ntStatus; + } + + // + // Read it back. + // + ntStatus = ReadCodecRegister (Register, &wCodecReg); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Cannot read sample rate.")); + return ntStatus; + } + + // + // Validate. + // + if (wCodecReg != dwSampleRate) + { + // + // restore sample rate and ctrl register. + // + WriteCodecRegister (Register, wOldRateReg, 0xFFFF); + + DOUT (DBG_VSR, ("Samplerate %d not supported", dwSampleRate)); + return STATUS_NOT_SUPPORTED; + } + + DOUT (DBG_VSR, ("Samplerate changed to %d.", dwSampleRate)); + return STATUS_SUCCESS; +} + + +/***************************************************************************** + * CAC97AdapterCommon::PowerChangeState + ***************************************************************************** + * Change power state for the device. We handle the codec, PowerChangeNotify + * in the wave miniport handles the DMA registers. + */ +STDMETHODIMP_(void) CAC97AdapterCommon::PowerChangeState +( + _In_ POWER_STATE NewState +) +{ + PAGED_CODE (); + + NTSTATUS ntStatus = STATUS_SUCCESS; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::PowerChangeNotify]")); + + // + // Check to see if this is the current power state. + // + if (NewState.DeviceState == m_PowerState) + { + DOUT (DBG_POWER, ("New device state equals old state.")); + return; + } + + // + // Check the new device state. + // + if ((NewState.DeviceState < PowerDeviceD0) || + (NewState.DeviceState > PowerDeviceD3)) + { + DOUT (DBG_ERROR, ("Unknown device state: D%d.", + (ULONG)NewState.DeviceState - (ULONG)PowerDeviceD0)); + return; + } + + DOUT (DBG_POWER, ("Changing state to D%d.", (ULONG)NewState.DeviceState - + (ULONG)PowerDeviceD0)); + + // + // Switch on new state. + // + switch (NewState.DeviceState) + { + case PowerDeviceD0: + // + // If we are coming from D2 or D3 we have to restore the registers cause + // there might have been a power loss. + // + if ((m_PowerState == PowerDeviceD3) || (m_PowerState == PowerDeviceD2)) + { + // + // Reset AD3 to indicate that we are now awake. + // Because the system has only one power irp at a time, we are sure + // that the modem driver doesn't get called while we are restoring + // power. + // + WriteBMControlRegister (GLOB_STA, + ReadBMControlRegister32 (GLOB_STA) & ~GLOB_STA_AD3); + + // + // Restore codec registers. + // + ntStatus = RestoreCodecRegisters (); + } + else // We are coming from power state D1 + { + ntStatus = PowerUpCodec (); + } + + // Print error code. + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("PowerChangeState failed to restore the codec.")); + } + break; + + case PowerDeviceD1: + // + // This sleep state is the lowest latency sleep state with respect + // to the latency time required to return to D0. If the + // driver is not being used an inactivity timer in portcls will + // place the driver in this state after a timeout period + // controllable via the registry. + // + + // Let's power down the DAC/ADC's and analog mixer. + WriteCodecRegister (AC97REG_POWERDOWN, 0x0700, 0xFFFF); + break; + + case PowerDeviceD2: + case PowerDeviceD3: + // + // This is a full hibernation state and is the longest latency sleep + // state. In this modes the power could be removed or reduced that + // much that the AC97 controller looses information, so we save + // whatever we have to save. + // + + // + // Powerdown ADC, DAC, Mixer, Vref, HP amp, and Exernal Amp but not + // AC-link and Clk + // + WriteCodecRegister (AC97REG_POWERDOWN, 0xCF00, 0xFFFF); + + // + // Only in D3 mode we set the AD3 bit and evtl. shut off the AC link. + // + if (NewState.DeviceState == PowerDeviceD3) + { + // + // Set the AD3 bit. + // + ULONG ulReg = ReadBMControlRegister32 (GLOB_STA); + WriteBMControlRegister (GLOB_STA, ulReg | GLOB_STA_AD3); + + // + // We check if the modem is sleeping. If it is, we can shut off the + // AC link also. We shut off the AC link also if the modem is not + // there. + // + if ((ulReg & GLOB_STA_MD3) || !(ulReg & GLOB_STA_SCR)) + { + // Set Codec to super sleep + WriteCodecRegister (AC97REG_POWERDOWN, 0xFF00, 0xFFFF); + + // Disable the AC-link signals + ulReg = ReadBMControlRegister32 (GLOB_CNT); + WriteBMControlRegister (GLOB_CNT, (ulReg | GLOB_CNT_ACLOFF) & ~GLOB_CNT_COLD); + } + } + break; + } + + // + // Save the new state. This local value is used to determine when to + // cache property accesses and when to permit the driver from accessing + // the hardware. + // + m_PowerState = NewState.DeviceState; + DOUT (DBG_POWER, ("Entering D%d", (ULONG)m_PowerState - + (ULONG)PowerDeviceD0)); +} + + +/***************************************************************************** + * CAC97AdapterCommon::QueryPowerChangeState + ***************************************************************************** + * Query to see if the device can change to this power state + */ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::QueryPowerChangeState +( + _In_ POWER_STATE NewState +) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::QueryPowerChangeState]")); + + // Check here to see of a legitimate state is being requested + // based on the device state and fail the call if the device/driver + // cannot support the change requested. Otherwise, return STATUS_SUCCESS. + // Note: A QueryPowerChangeState() call is not guaranteed to always preceed + // a PowerChangeState() call. + + // check the new state being requested + switch (NewState.DeviceState) + { + case PowerDeviceD0: + case PowerDeviceD1: + case PowerDeviceD2: + case PowerDeviceD3: + return STATUS_SUCCESS; + + default: + DOUT (DBG_ERROR, ("Unknown device state: D%d.", + (ULONG)NewState.DeviceState - (ULONG)PowerDeviceD0)); + return STATUS_NOT_IMPLEMENTED; + } +} + + +/***************************************************************************** + * CAC97AdapterCommon::QueryDeviceCapabilities + ***************************************************************************** + * Called at startup to get the caps for the device. This structure provides + * the system with the mappings between system power state and device power + * state. This typically will not need modification by the driver. + * If the driver modifies these mappings then the driver is not allowed to + * change the mapping to a weaker power state (e.g. from S1->D3 to S1->D1). + * + */ +_Use_decl_annotations_ +STDMETHODIMP_(NTSTATUS) CAC97AdapterCommon::QueryDeviceCapabilities +( + PDEVICE_CAPABILITIES PowerDeviceCaps +) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::QueryDeviceCapabilities]")); + + UNREFERENCED_PARAMETER(PowerDeviceCaps); + + return STATUS_SUCCESS; +} + + +/***************************************************************************** + * CAC97AdapterCommon::RestoreAC97Registers + ***************************************************************************** + * Preset the AC97 registers with default values. The routine first checks if + * There are registry entries for the default values. If not, we have hard + * coded values too ;) + */ +NTSTATUS CAC97AdapterCommon::SetAC97Default (void) +{ + PAGED_CODE (); + + PREGISTRYKEY DriverKey; + PREGISTRYKEY SettingsKey; + UNICODE_STRING sKeyName; + ULONG ulDisposition; + ULONG ulResultLength; + PVOID KeyInfo = NULL; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::SetAC97Default]")); + + // open the driver registry key + NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey + NULL, // OuterUnknown + DriverRegistryKey, // Registry key type + KEY_READ, // Access flags + m_pDeviceObject, // Device object + NULL, // Subdevice + NULL, // ObjectAttributes + 0, // Create options + NULL); // Disposition + if (NT_SUCCESS (ntStatus)) + { + // make a unicode string for the subkey name + RtlInitUnicodeString (&sKeyName, L"Settings"); + + // open the settings subkey + ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey + NULL, // OuterUnknown + KEY_READ, // Access flags + &sKeyName, // Subkey name + REG_OPTION_NON_VOLATILE, // Create options + &ulDisposition); + + if (NT_SUCCESS (ntStatus)) + { + // allocate data to hold key info + KeyInfo = ExAllocatePoolWithTag (PagedPool, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + + sizeof(WORD), PoolTag); + if (NULL != KeyInfo) + { + // loop through all mixer settings + for (AC97Register i = AC97REG_RESET; i <= AC97REG_RESERVED2; + i = (AC97Register)(i + 1)) + { + if (m_stAC97Registers[i].wFlags & SHREG_INIT) + { + // init key name + RtlInitUnicodeString (&sKeyName, + m_stAC97Registers[i].sRegistryName); + + // query the value key + ntStatus = SettingsKey->QueryValueKey (&sKeyName, + KeyValuePartialInformation, + KeyInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + + sizeof(WORD), + &ulResultLength); + if (NT_SUCCESS (ntStatus)) + { + PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = + (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfo; + + if (PartialInfo->DataLength == sizeof(WORD)) + { + // set mixer register to registry value + WriteCodecRegister + (i, *(PWORD)PartialInfo->Data, 0xFFFF); + } + else // write the hard coded default + { + // if key access failed, set to default + WriteCodecRegister + (i, m_stAC97Registers[i].wWantedDefault, 0xFFFF); + } + } + else // write the hard coded default + { + // if key access failed, set to default + WriteCodecRegister + (i, m_stAC97Registers[i].wWantedDefault, 0xFFFF); + } + } + } + + // we want to return status success even if the last QueryValueKey + // failed. + ntStatus = STATUS_SUCCESS; + + // free the key info + ExFreePoolWithTag (KeyInfo,PoolTag); + } + else + { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + } + + // release the settings key + SettingsKey->Release (); + } + + // release the driver key + DriverKey->Release (); + } + + + // in case we did not query the registry (cause of lack of resources) + // restore default values and return insufficient resources. + if (!NT_SUCCESS (ntStatus)) + { + // copy hard coded default settings + for (AC97Register i = AC97REG_RESET; i < AC97REG_RESERVED2; + i = (AC97Register)(i + 1)) + { + if (m_stAC97Registers[i].wFlags & SHREG_INIT) + { + WriteCodecRegister (i, m_stAC97Registers[i].wWantedDefault, 0xFFFF); + } + } + } + + return ntStatus; +} + + +/***************************************************************************** + * CAC97AdapterCommon::DisableAC97Pin + ***************************************************************************** + * Returns TRUE when the HW vendor wants to disable the pin. A disabled pin is + * not shown to the user (means it is not included in the topology). The + * reason for doing this could be that some of the input lines like Aux or + * Video are not available to the user (to plug in something) but the codec + * can handle those lines. + */ +BOOL CAC97AdapterCommon::DisableAC97Pin +( + IN TopoPinConfig pin +) +{ + PAGED_CODE (); + + PREGISTRYKEY DriverKey; + PREGISTRYKEY SettingsKey; + UNICODE_STRING sKeyName; + ULONG ulDisposition; + ULONG ulResultLength; + PVOID KeyInfo = NULL; + BOOL bDisable = FALSE; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::DisableAC97Pin]")); + + // open the driver registry key + NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey + NULL, // OuterUnknown + DriverRegistryKey, // Registry key type + KEY_READ, // Access flags + m_pDeviceObject, // Device object + NULL, // Subdevice + NULL, // ObjectAttributes + 0, // Create options + NULL); // Disposition + if (NT_SUCCESS (ntStatus)) + { + // make a unicode string for the subkey name + RtlInitUnicodeString (&sKeyName, L"Settings"); + + // open the settings subkey + ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey + NULL, // OuterUnknown + KEY_READ, // Access flags + &sKeyName, // Subkey name + REG_OPTION_NON_VOLATILE, // Create options + &ulDisposition); + + if (NT_SUCCESS (ntStatus)) + { + // allocate data to hold key info + KeyInfo = ExAllocatePoolWithTag (PagedPool, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + + sizeof(BYTE), PoolTag); + if (NULL != KeyInfo) + { + // init key name + RtlInitUnicodeString (&sKeyName, m_stHardwareConfig. + Pins[pin].sRegistryName); + + // query the value key + ntStatus = SettingsKey->QueryValueKey (&sKeyName, + KeyValuePartialInformation, + KeyInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + + sizeof(BYTE), + &ulResultLength ); + if (NT_SUCCESS (ntStatus)) + { + PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = + (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfo; + + if (PartialInfo->DataLength == sizeof(BYTE)) + { + // store the value + if (*(PBYTE)PartialInfo->Data) + bDisable = TRUE; + else + bDisable = FALSE; + } + } + + // free the key info + ExFreePoolWithTag (KeyInfo,PoolTag); + } + + // release the settings key + SettingsKey->Release (); + } + + // release the driver key + DriverKey->Release (); + } + + // if one of the stuff above fails we return the default, which is FALSE. + return bDisable; +} + + +/***************************************************************************** + * CAC97AdapterCommon::RestoreCodecRegisters + ***************************************************************************** + * write back cached mixer values to codec registers + */ +NTSTATUS CAC97AdapterCommon::RestoreCodecRegisters (void) +{ + PAGED_CODE (); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::RestoreCodecRegisters]")); + + // + // Initialize the AC97 codec. + // + NTSTATUS ntStatus = InitAC97 (); + if (!NT_SUCCESS (ntStatus)) + return ntStatus; + + // + // Restore all codec registers. Failure is not critical. + // + for (AC97Register i = AC97REG_MASTER_VOLUME; i < AC97REG_RESERVED2; + i = (AC97Register)(i + 1)) + { + WriteCodecRegister (i, m_stAC97Registers[i].wCache, 0xFFFF); + } + + return STATUS_SUCCESS; +} + +/***************************************************************************** + * CAC97AdapterCommon::ReadChannelConfigDefault + ***************************************************************************** + * This function reads the default channel config from the registry. The + * registry entry "ChannelConfig" is set every every time we get a + * KSPROPERTY_AUDIO_CHANNEL_CONFIG for the DAC node. + * In case the key doesn't exist we assume a channel config of stereo speakers, + * cause that is the default of DSOUND. + */ +STDMETHODIMP_(void) CAC97AdapterCommon::ReadChannelConfigDefault +( + PDWORD pdwChannelConfig, + PWORD pwChannels +) +{ + PAGED_CODE (); + + PREGISTRYKEY DriverKey; + PREGISTRYKEY SettingsKey; + UNICODE_STRING sKeyName; + ULONG ulDisposition; + ULONG ulResultLength; + PVOID KeyInfo = NULL; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadChannelConfigDefault]")); + + // This is the default: 2 speakers, stereo. + *pdwChannelConfig = KSAUDIO_SPEAKER_STEREO; + *pwChannels = 2; + + // open the driver registry key + NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey + NULL, // OuterUnknown + DriverRegistryKey, // Registry key type + KEY_READ, // Access flags + m_pDeviceObject, // Device object + NULL, // Subdevice + NULL, // ObjectAttributes + 0, // Create options + NULL); // Disposition + if (NT_SUCCESS (ntStatus)) + { + // make a unicode string for the subkey name + RtlInitUnicodeString (&sKeyName, L"Settings"); + + // open the settings subkey + ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey + NULL, // OuterUnknown + KEY_READ, // Access flags + &sKeyName, // Subkey name + REG_OPTION_NON_VOLATILE, // Create options + &ulDisposition); + + if (NT_SUCCESS (ntStatus)) + { + // allocate data to hold key info + KeyInfo = ExAllocatePoolWithTag (PagedPool, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + + sizeof(DWORD), PoolTag); + if (NULL != KeyInfo) + { + // init key name + RtlInitUnicodeString (&sKeyName, L"ChannelConfig"); + + // query the value key + ntStatus = SettingsKey->QueryValueKey (&sKeyName, + KeyValuePartialInformation, + KeyInfo, + sizeof(KEY_VALUE_PARTIAL_INFORMATION) + + sizeof(DWORD), + &ulResultLength ); + if (NT_SUCCESS (ntStatus)) + { + PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = + (PKEY_VALUE_PARTIAL_INFORMATION)KeyInfo; + + if (PartialInfo->DataLength == sizeof(DWORD)) + { + switch (*(PLONG)PartialInfo->Data) + { + case KSAUDIO_SPEAKER_QUAD: + case KSAUDIO_SPEAKER_SURROUND: + if (GetPinConfig (PINC_SURROUND_PRESENT)) + { + *pdwChannelConfig = *(PDWORD)PartialInfo->Data; + *pwChannels = 4; + } + break; + + case KSAUDIO_SPEAKER_5POINT1: + if (GetPinConfig (PINC_SURROUND_PRESENT) && + GetPinConfig (PINC_CENTER_LFE_PRESENT)) + { + *pdwChannelConfig = *(PDWORD)PartialInfo->Data; + *pwChannels = 6; + } + break; + } + } + } + + // free the key info + ExFreePoolWithTag (KeyInfo,PoolTag); + } + + // release the settings key + SettingsKey->Release (); + } + + // release the driver key + DriverKey->Release (); + } +} + +/***************************************************************************** + * CAC97AdapterCommon::WriteChannelConfigDefault + ***************************************************************************** + * This function writes the default channel config to the registry. The + * registry entry "ChannelConfig" is set every every time we get a + * KSPROPERTY_AUDIO_CHANNEL_CONFIG for the DAC node. + */ +STDMETHODIMP_(void) CAC97AdapterCommon::WriteChannelConfigDefault (DWORD dwChannelConfig) +{ + PAGED_CODE (); + + PREGISTRYKEY DriverKey; + PREGISTRYKEY SettingsKey; + UNICODE_STRING sKeyName; + ULONG ulDisposition; + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteChannelConfigDefault]")); + + // open the driver registry key + NTSTATUS ntStatus = PcNewRegistryKey (&DriverKey, // IRegistryKey + NULL, // OuterUnknown + DriverRegistryKey, // Registry key type + KEY_WRITE, // Access flags + m_pDeviceObject, // Device object + NULL, // Subdevice + NULL, // ObjectAttributes + 0, // Create options + NULL); // Disposition + if (NT_SUCCESS (ntStatus)) + { + // make a unicode string for the subkey name + RtlInitUnicodeString (&sKeyName, L"Settings"); + + // open the settings subkey + ntStatus = DriverKey->NewSubKey (&SettingsKey, // Subkey + NULL, // OuterUnknown + KEY_WRITE, // Access flags + &sKeyName, // Subkey name + REG_OPTION_NON_VOLATILE, // Create options + &ulDisposition); + + if (NT_SUCCESS (ntStatus)) + { + // init key name + RtlInitUnicodeString (&sKeyName, L"ChannelConfig"); + + // query the value key + ntStatus = SettingsKey->SetValueKey (&sKeyName, + REG_DWORD, + &dwChannelConfig, + sizeof (DWORD)); + if (!NT_SUCCESS (ntStatus)) + { + DOUT (DBG_ERROR, ("Could not write the ChannelConfig to registry.")); + } + + // release the settings key + SettingsKey->Release (); + } + + // release the driver key + DriverKey->Release (); + } +} + +/***************************************************************************** + * Non paged code begins here + ***************************************************************************** + */ + +#ifdef _MSC_VER +#pragma code_seg() +#endif +/***************************************************************************** + * CAC97AdapterCommon::WriteBMControlRegister + ***************************************************************************** + * Writes a byte (UCHAR) to BusMaster Control register. + */ +STDMETHODIMP_(void) CAC97AdapterCommon::WriteBMControlRegister +( + IN ULONG ulOffset, + IN UCHAR ucValue +) +{ + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteBMControlRegister] (UCHAR)")); + + WRITE_PORT_UCHAR ((PUCHAR)(m_pBusMasterBase + ulOffset), ucValue); + + DOUT (DBG_REGS, ("WriteBMControlRegister wrote 0x%2x to 0x%4p.", + ucValue, m_pBusMasterBase + ulOffset)); +} + +/***************************************************************************** + * CAC97AdapterCommon::WriteBMControlRegister + ***************************************************************************** + * Writes a word (USHORT) to BusMaster Control register. + */ +STDMETHODIMP_(void) CAC97AdapterCommon::WriteBMControlRegister +( + IN ULONG ulOffset, + IN USHORT usValue +) +{ + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteBMControlRegister (USHORT)]")); + + WRITE_PORT_USHORT ((PUSHORT)(m_pBusMasterBase + ulOffset), usValue); + + DOUT (DBG_REGS, ("WriteBMControlRegister wrote 0x%4x to 0x%4p", + usValue, m_pBusMasterBase + ulOffset)); +} + +/***************************************************************************** + * CAC97AdapterCommon::WriteBMControlRegister + ***************************************************************************** + * Writes a DWORD (ULONG) to BusMaster Control register. + */ +STDMETHODIMP_(void) CAC97AdapterCommon::WriteBMControlRegister +( + IN ULONG ulOffset, + IN ULONG ulValue +) +{ + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::WriteBMControlRegister (ULONG)]")); + + WRITE_PORT_ULONG ((PULONG)(m_pBusMasterBase + ulOffset), ulValue); + + DOUT (DBG_REGS, ("WriteBMControlRegister wrote 0x%8x to 0x%4p.", + ulValue, m_pBusMasterBase + ulOffset)); +} + +/***************************************************************************** + * CAC97AdapterCommon::ReadBMControlRegister8 + ***************************************************************************** + * Read a byte (UCHAR) from BusMaster Control register. + */ +STDMETHODIMP_(UCHAR) CAC97AdapterCommon::ReadBMControlRegister8 +( + IN ULONG ulOffset +) +{ + UCHAR ucValue = UCHAR(-1); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadBMControlRegister8]")); + + ucValue = READ_PORT_UCHAR ((PUCHAR)(m_pBusMasterBase + ulOffset)); + + DOUT (DBG_REGS, ("ReadBMControlRegister read 0x%2x from 0x%4p.", ucValue, + m_pBusMasterBase + ulOffset)); + + return ucValue; +} + +/***************************************************************************** + * CAC97AdapterCommon::ReadBMControlRegister16 + ***************************************************************************** + * Read a word (USHORT) from BusMaster Control register. + */ +STDMETHODIMP_(USHORT) CAC97AdapterCommon::ReadBMControlRegister16 +( + IN ULONG ulOffset +) +{ + USHORT usValue = USHORT(-1); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadBMControlRegister16]")); + + usValue = READ_PORT_USHORT ((PUSHORT)(m_pBusMasterBase + ulOffset)); + + DOUT (DBG_REGS, ("ReadBMControlRegister read 0x%4x = 0x%4p", usValue, + m_pBusMasterBase + ulOffset)); + + return usValue; +} + +/***************************************************************************** + * CAC97AdapterCommon::ReadBMControlRegister32 + ***************************************************************************** + * Read a dword (ULONG) from BusMaster Control register. + */ +STDMETHODIMP_(ULONG) CAC97AdapterCommon::ReadBMControlRegister32 +( + IN ULONG ulOffset +) +{ + ULONG ulValue = ULONG(-1); + + DOUT (DBG_PRINT, ("[CAC97AdapterCommon::ReadBMControlRegister32]")); + + ulValue = READ_PORT_ULONG ((PULONG)(m_pBusMasterBase + ulOffset)); + + DOUT (DBG_REGS, ("ReadBMControlRegister read 0x%8x = 0x%4p", ulValue, + m_pBusMasterBase + ulOffset)); + + return ulValue; +} + diff --git a/drivers/wdm/audio/drivers/ac97/common.h b/drivers/wdm/audio/drivers/ac97/common.h new file mode 100644 index 00000000000..8b5162ddffa --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/common.h @@ -0,0 +1,387 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file common.h was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include "shared.h" + +/***************************************************************************** + * Structs + ***************************************************************************** + */ + +// +// Contains pin and node configuration of the AC97 codec. +// +typedef struct +{ + // For nodes. + struct + { + BOOL bNodeConfig; + } Nodes[NODEC_TOP_ELEMENT]; + + // For pins. + struct + { + BOOL bPinConfig; + PWCHAR sRegistryName; + } Pins[PINC_TOP_ELEMENT]; +} tHardwareConfig; + +// +// We cache the AC97 registers. Additionally, we want some default values +// when the driver comes up first that are different from the HW default +// values. The string in the structure is the name of the registry entry +// that can be used instead of the hard coded default value. +// +typedef struct +{ + WORD wCache; + WORD wFlags; + PWCHAR sRegistryName; + WORD wWantedDefault; +} tAC97Registers; + + +/***************************************************************************** + * Constants + ***************************************************************************** + */ + +// +// This means shadow register are to be read at least once to initialize. +// +const WORD SHREG_INVALID = 0x0001; + +// +// This means shadow register should be overwritten with default value at +// driver init. +// +const WORD SHREG_INIT = 0x0002; + +// +// This constant is used to prevent register caching. +// +const WORD SHREG_NOCACHE = 0x0004; + + +/***************************************************************************** + * Classes + ***************************************************************************** + */ + +/***************************************************************************** + * CAC97AdapterCommon + ***************************************************************************** + * This is the common adapter object shared by all miniports to access the + * hardware. + */ +class CAC97AdapterCommon : public IAC97AdapterCommon, + public IAdapterPowerManagement, + public CUnknown +{ +private: + static tAC97Registers m_stAC97Registers[64]; // The shadow registers. + static tHardwareConfig m_stHardwareConfig; // The hardware configuration. + PDEVICE_OBJECT m_pDeviceObject; // Device object used for registry access. + PWORD m_pCodecBase; // The AC97 I/O port address. + PUCHAR m_pBusMasterBase; // The Bus Master base address. + BOOL m_bDirectRead; // Used during init time. + DEVICE_POWER_STATE m_PowerState; // Current power state of the device. + PAC97MINIPORTTOPOLOGY m_Topology; // Miniport Topology pointer. + + + /************************************************************************* + * CAC97AdapterCommon methods + ************************************************************************* + */ + + // + // Resets AC97 audio registers. + // + NTSTATUS InitAC97 (void); + + // + // Checks for existance of registers. + // + NTSTATUS ProbeHWConfig (void); + + // + // Checks for 6th bit support in the volume control. + // + NTSTATUS Check6thBitSupport (IN AC97Register, IN TopoNodeConfig); + + // + // Returns true if you should disable the input or output pin. + // + BOOL DisableAC97Pin (IN TopoPinConfig); + +#if (DBG) + // + // Dumps the probed configuration. + // + void DumpConfig (void); +#endif + + // + // Sets AC97 registers to default. + // + NTSTATUS SetAC97Default (void); + + // + // Aquires the semaphore for AC97 register access. + // + NTSTATUS AcquireCodecSemiphore (void); + + // + // Checks if there is a AC97 link between AC97 and codec. + // + NTSTATUS PrimaryCodecReady (void); + + // + // Powers up the Codec. + // + NTSTATUS PowerUpCodec (void); + + // + // Saves native audio bus master control registers values to be used + // upon suspend. + // + NTSTATUS ReadNABMCtrlRegs (void); + + // + // Writes back native audio bus master control resgister to be used upon + // resume. + // + NTSTATUS RestoreNABMCtrlRegs (void); + +public: + DECLARE_STD_UNKNOWN(); + DEFINE_STD_CONSTRUCTOR(CAC97AdapterCommon); + ~CAC97AdapterCommon(); + + /************************************************************************* + * IAdapterPowerManagement methods + ************************************************************************* + */ + IMP_IAdapterPowerManagement; + + /************************************************************************* + * IAC97AdapterCommon methods + ************************************************************************* + */ + + // + // Initialize the adapter common object -> initialize and probe HW. + // + STDMETHODIMP_(NTSTATUS) Init + ( + IN PRESOURCELIST ResourceList, + IN PDEVICE_OBJECT DeviceObject + ); + + // + // Returns if pin exists. + // + STDMETHODIMP_(BOOL) GetPinConfig + ( + IN TopoPinConfig pin + ) + { + return m_stHardwareConfig.Pins[pin].bPinConfig; + }; + + // + // Sets the pin configuration (exist/not exist). + // + STDMETHODIMP_(void) SetPinConfig + ( + IN TopoPinConfig pin, + IN BOOL config + ) + { + m_stHardwareConfig.Pins[pin].bPinConfig = config; + }; + + // + // Return if node exists. + // + STDMETHODIMP_(BOOL) GetNodeConfig + ( + IN TopoNodeConfig node + ) + { + return m_stHardwareConfig.Nodes[node].bNodeConfig; + }; + + // + // Sets the node configuration (exist/not exist). + // + STDMETHODIMP_(void) SetNodeConfig + ( + IN TopoNodeConfig node, + IN BOOL config + ) + { + m_stHardwareConfig.Nodes[node].bNodeConfig = config; + }; + + // + // Returns the AC97 register that is assosiated with the node. + // + STDMETHODIMP_(AC97Register) GetNodeReg + ( IN TopoNodes node + ) + { + return stMapNodeToReg[node].reg; + }; + + // + // Returns the AC97 register mask that is assosiated with the node. + // + STDMETHODIMP_(WORD) GetNodeMask + ( + IN TopoNodes node + ) + { + return stMapNodeToReg[node].mask; + }; + + // + // Reads a AC97 register. + // + STDMETHODIMP_(NTSTATUS) ReadCodecRegister + ( + _In_range_(0, AC97REG_INVALID) AC97Register Register, + _Out_ PWORD wData + ); + + // + // Writes a AC97 register. + // + STDMETHODIMP_(NTSTATUS) WriteCodecRegister + ( + _In_range_(0, AC97REG_INVALID) AC97Register Register, + _In_ WORD wData, + _In_ WORD wMask + ); + + // + // Reads a 8 bit AC97 bus master register. + // + STDMETHODIMP_(UCHAR) ReadBMControlRegister8 + ( + IN ULONG ulOffset + ); + + // + // Reads a 16 bit AC97 bus master register. + // + STDMETHODIMP_(USHORT) ReadBMControlRegister16 + ( + IN ULONG ulOffset + ); + + // + // Reads a 32 bit AC97 bus master register. + // + STDMETHODIMP_(ULONG) ReadBMControlRegister32 + ( + IN ULONG ulOffset + ); + + // + // Writes a 8 bit AC97 bus master register. + // + STDMETHODIMP_(void) WriteBMControlRegister + ( + IN ULONG ulOffset, + IN UCHAR Value + ); + + // + // writes a 16 bit AC97 bus master register. + // + STDMETHODIMP_(void) WriteBMControlRegister + ( + IN ULONG ulOffset, + IN USHORT Value + ); + + // writes a 32 bit AC97 bus master register. + STDMETHODIMP_(void) WriteBMControlRegister + ( + IN ULONG ulOffset, + IN ULONG Value + ); + + // + // Write back cached mixer values to codec registers. + // + STDMETHODIMP_(NTSTATUS) RestoreCodecRegisters(); + + // + // Programs a sample rate. + // + STDMETHODIMP_(NTSTATUS) ProgramSampleRate + ( + IN AC97Register Register, + IN DWORD dwSampleRate + ); + + // + // Stores the topology pointer. Used for DRM only. + // + STDMETHODIMP_(void) SetMiniportTopology (PAC97MINIPORTTOPOLOGY topo) + { + m_Topology = topo; + }; + + // + // Returns the topology pointer. Used for DRM only. + // + STDMETHODIMP_(PAC97MINIPORTTOPOLOGY) GetMiniportTopology (void) + { + return m_Topology; + }; + + // + // This function reads the default channel config and is called only by the + // wave miniport. + // + STDMETHODIMP_(void) ReadChannelConfigDefault + ( + PDWORD pdwChannelConfig, + PWORD pwChannels + ); + + // + // This function writes the default channel config and is called only by the + // wave miniport. + // + STDMETHODIMP_(void) WriteChannelConfigDefault + ( + DWORD dwChannelConfig + ); + + /************************************************************************* + * Friends + ************************************************************************* + */ + + friend NTSTATUS NewAdapterCommon + ( + OUT PADAPTERCOMMON *OutAdapterCommon, + IN PRESOURCELIST ResourceList + ); +}; + +#endif //_COMMON_H_ diff --git a/drivers/wdm/audio/drivers/ac97/debug.h b/drivers/wdm/audio/drivers/ac97/debug.h new file mode 100644 index 00000000000..78c5335c16d --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/debug.h @@ -0,0 +1,93 @@ +/******************************************************************************** +** Copyright (c) 1998-1999 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file debug.h was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +// +// Modified version of ksdebug.h to support runtime debug level changes. +// +const int DBG_NONE = 0x00000000; +const int DBG_PRINT = 0x00000001; // Blabla. Function entries for example +const int DBG_WARNING = 0x00000002; // warning level +const int DBG_ERROR = 0x00000004; // this doesn't generate a breakpoint + +// specific debug output; you don't have to enable DBG_PRINT for this. +const int DBG_STREAM = 0x00000010; // Enables stream output. +const int DBG_POWER = 0x00000020; // Enables power management output. +const int DBG_DMA = 0x00000040; // Enables DMA engine output. +const int DBG_REGS = 0x00000080; // Enables register outout. +const int DBG_PROBE = 0x00000100; // Enables hardware probing output. +const int DBG_SYSINFO = 0x00000200; // Enables system info output. +const int DBG_VSR = 0x00000400; // Enables variable sample rate output. +const int DBG_PROPERTY = 0x00000800; // Enables property handler output +const int DBG_POSITION = 0x00001000; // Enables printing of position on GetPosition +const int DBG_PINS = 0x10000000; // Enables dump of created pins in topology +const int DBG_NODES = 0x20000000; // Enables dump of created nodes in topology +const int DBG_CONNS = 0x40000000; // Enables dump of the connections in topology + +const int DBG_ALL = 0xFFFFFFFF; + +// +// The default statements that will print are warnings (DBG_WARNING) and +// errors (DBG_ERROR). +// +const int DBG_DEFAULT = 0x00000004; // Errors only. + + +// +// Define global debug variable. +// +#ifdef DEFINE_DEBUG_VARS +#if (DBG) +unsigned long ulDebugOut = DBG_DEFAULT; +#endif + +#else // !DEFINED_DEBUG_VARS +#if (DBG) +extern unsigned long ulDebugOut; +#endif +#endif + + +// +// Define the print statement. +// +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + +// +// DBG is 1 in checked builds +// +#if (DBG) +#define DOUT(lvl, strings) \ + if ((lvl) & ulDebugOut) \ + { \ + DbgPrint(STR_MODULENAME); \ + DbgPrint strings; \ + DbgPrint("\n"); \ + } + +#define BREAK() \ + DbgBreakPoint() + +#else // if (!DBG) +#define DOUT(lvl, strings) +#define BREAK() +#endif // !DBG + + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) + + + +#endif diff --git a/drivers/wdm/audio/drivers/ac97/guids.h b/drivers/wdm/audio/drivers/ac97/guids.h new file mode 100644 index 00000000000..8230403da81 --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/guids.h @@ -0,0 +1,188 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file guids.h was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#ifndef _GUIDS_H_ +#define _GUIDS_H_ + + +/***************************************************************************** + * GUIDs + ***************************************************************************** + * GUIDs for friendly names. + */ + +// PHONE Volume Name +#define STATIC_MYKSNAME_PHONE_VOLUME\ + 0x0A8C1A87, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1A87-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_PHONE_VOLUME); +#define MYKSNAME_PHONE_VOLUME DEFINE_GUIDNAMED(MYKSNAME_PHONE_VOLUME) + +// PHONE Mute Name +#define STATIC_MYKSNAME_PHONE_MUTE\ + 0x0A8C1A88, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1A88-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_PHONE_MUTE); +#define MYKSNAME_PHONE_MUTE DEFINE_GUIDNAMED(MYKSNAME_PHONE_MUTE) + +// LINEIN Mute Name +#define STATIC_MYKSNAME_LINEIN_MUTE\ + 0x0A8C1A91, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1A91-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_LINEIN_MUTE); +#define MYKSNAME_LINEIN_MUTE DEFINE_GUIDNAMED(MYKSNAME_LINEIN_MUTE) + +// Main Mix Name +#define STATIC_MYKSNAME_MAIN_MIX\ + 0x0A8C1A9B, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1A9B-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_MAIN_MIX); +#define MYKSNAME_MAIN_MIX DEFINE_GUIDNAMED(MYKSNAME_MAIN_MIX) + +// 3D Bypass Name +#define STATIC_MYKSNAME_WAVEOUT_3D_BYPASS\ + 0x0A8C1A9E, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1A9E-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_WAVEOUT_3D_BYPASS); +#define MYKSNAME_WAVEOUT_3D_BYPASS DEFINE_GUIDNAMED(MYKSNAME_WAVEOUT_3D_BYPASS) + +// 3D Enable Name +#define STATIC_MYKSNAME_3D_ENABLE\ + 0x766db5a4, 0x6e94, 0x11d2, 0x9a, 0xde, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("766DB5A4-6E94-11d2-9ADE-00C04F8EFB68", MYKSNAME_3D_ENABLE); +#define MYKSNAME_3D_ENABLE DEFINE_GUIDNAMED(MYKSNAME_3D_ENABLE) + +// Beep Mix Name +#define STATIC_MYKSNAME_BEEP_MIX\ + 0x0A8C1A9F, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1A9F-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_BEEP_MIX); +#define MYKSNAME_BEEP_MIX DEFINE_GUIDNAMED(MYKSNAME_BEEP_MIX) + +// HPOUT Volume Name +#define STATIC_MYKSNAME_HPOUT_VOLUME\ + 0x0A8C1AA5, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AA5-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_HPOUT_VOLUME); +#define MYKSNAME_HPOUT_VOLUME DEFINE_GUIDNAMED(MYKSNAME_HPOUT_VOLUME) + +// HPOUT Mute Name +#define STATIC_MYKSNAME_HPOUT_MUTE\ + 0x0A8C1AA6, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AA6-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_HPOUT_MUTE); +#define MYKSNAME_HPOUT_MUTE DEFINE_GUIDNAMED(MYKSNAME_HPOUT_MUTE) + +// MONOOUT Select Name +#define STATIC_MYKSNAME_MONOOUT_SELECT\ + 0x0A8C1AA9, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AA9-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_MONOOUT_SELECT); +#define MYKSNAME_MONOOUT_SELECT DEFINE_GUIDNAMED(MYKSNAME_MONOOUT_SELECT) + +// WAVEIN Select Name +#define STATIC_MYKSNAME_WAVEIN_SELECT\ + 0x0A8C1AAE, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AAE-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_WAVEIN_SELECT); +#define MYKSNAME_WAVEIN_SELECT DEFINE_GUIDNAMED(MYKSNAME_WAVEIN_SELECT) + +// MASTER INPUT Volume Name +#define STATIC_MYKSNAME_MASTER_INPUT_VOLUME\ + 0x0A8C1AAF, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AAF-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_MASTER_INPUT_VOLUME); +#define MYKSNAME_MASTER_INPUT_VOLUME DEFINE_GUIDNAMED(MYKSNAME_MASTER_INPUT_VOLUME) + +// MASTER INPUT Mute Name +#define STATIC_MYKSNAME_MASTER_INPUT_MUTE\ + 0x0A8C1AB0, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AB0-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_MASTER_INPUT_MUTE); +#define MYKSNAME_MASTER_INPUT_MUTE DEFINE_GUIDNAMED(MYKSNAME_MASTER_INPUT_MUTE) + +// MICIN Volume Name +#define STATIC_MYKSNAME_MICIN_VOLUME\ + 0x0A8C1AB2, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AB2-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_MICIN_VOLUME); +#define MYKSNAME_MICIN_VOLUME DEFINE_GUIDNAMED(MYKSNAME_MICIN_VOLUME) + +// MICIN Mute Name +#define STATIC_MYKSNAME_MICIN_MUTE\ + 0x0A8C1AB3, 0x42B0, 0x11D2, 0x95, 0xD2, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("0A8C1AB3-42B0-11D2-95D2-00C04FB925D3", MYKSNAME_MICIN_MUTE); +#define MYKSNAME_MICIN_MUTE DEFINE_GUIDNAMED(MYKSNAME_MICIN_MUTE) + +// Simulated Stereo Name +#define STATIC_MYKSNAME_SIMUL_STEREO\ + 0xB3AD50B5, 0x3849, 0x4983, 0xAD, 0xD7, 0x25, 0xE6, 0x26, 0x8F, 0x91, 0x2D +DEFINE_GUIDSTRUCT("B3AD50B5-3849-4983-ADD7-25E6268F912D", MYKSNAME_SIMUL_STEREO); +#define MYKSNAME_SIMUL_STEREO DEFINE_GUIDNAMED(MYKSNAME_SIMUL_STEREO) + +// Surround Volume Name +#define STATIC_MYKSNAME_SURROUND_VOLUME\ + 0xa4b68ba4, 0x6958, 0x4ab4, 0xbb, 0x1, 0xe2, 0x3c, 0x6f, 0x2, 0x7c, 0x88 +DEFINE_GUIDSTRUCT("A4B68BA4-6958-4ab4-BB01-E23C6F027C88", MYKSNAME_SURROUND_VOLUME); +#define MYKSNAME_SURROUND_VOLUME DEFINE_GUIDNAMED(MYKSNAME_SURROUND_VOLUME) + +// Surround Mute Name +#define STATIC_MYKSNAME_SURROUND_MUTE\ + 0x22654fbc, 0xac8f, 0x4224, 0xb1, 0x9f, 0xd8, 0x58, 0xd2, 0xe1, 0xb, 0xdd +DEFINE_GUIDSTRUCT("22654FBC-AC8F-4224-B19F-D858D2E10BDD", MYKSNAME_SURROUND_MUTE); +#define MYKSNAME_SURROUND_MUTE DEFINE_GUIDNAMED(MYKSNAME_SURROUND_MUTE) + +// Center Volume Name +#define STATIC_MYKSNAME_CENTER_VOLUME\ + 0x9b0f1946, 0xabd2, 0x47a8, 0xa7, 0x78, 0xbb, 0x86, 0xcd, 0xe1, 0xa1, 0x67 +DEFINE_GUIDSTRUCT("9B0F1946-ABD2-47a8-A778-BB86CDE1A167", MYKSNAME_CENTER_VOLUME); +#define MYKSNAME_CENTER_VOLUME DEFINE_GUIDNAMED(MYKSNAME_CENTER_VOLUME) + +// Center Mute Name +#define STATIC_MYKSNAME_CENTER_MUTE\ + 0xbeef51ed, 0x1041, 0x43f8, 0x9b, 0x96, 0x58, 0x63, 0xd0, 0xa9, 0x34, 0x2d +DEFINE_GUIDSTRUCT("BEEF51ED-1041-43f8-9B96-5863D0A9342D", MYKSNAME_CENTER_MUTE); +#define MYKSNAME_CENTER_MUTE DEFINE_GUIDNAMED(MYKSNAME_CENTER_MUTE) + +// LFE Volume Name +#define STATIC_MYKSNAME_LFE_VOLUME\ + 0x455fa6f2, 0x21ec, 0x4df4, 0xb1, 0xe4, 0x31, 0x55, 0x20, 0x97, 0x97, 0xf3 +DEFINE_GUIDSTRUCT("455FA6F2-21EC-4df4-B1E4-3155209797F3", MYKSNAME_LFE_VOLUME); +#define MYKSNAME_LFE_VOLUME DEFINE_GUIDNAMED(MYKSNAME_LFE_VOLUME) + +// LFE Mute Name +#define STATIC_MYKSNAME_LFE_MUTE\ + 0x4a4d9210, 0xc780, 0x4768, 0xbf, 0xd2, 0x52, 0x5f, 0xdb, 0xf4, 0xfc, 0xb4 +DEFINE_GUIDSTRUCT("4A4D9210-C780-4768-BFD2-525FDBF4FCB4", MYKSNAME_LFE_MUTE); +#define MYKSNAME_LFE_MUTE DEFINE_GUIDNAMED(MYKSNAME_LFE_MUTE) + +// Front Volume Name +#define STATIC_MYKSNAME_FRONT_VOLUME\ + 0x9f4801bd, 0xf746, 0x4c7a, 0x8a, 0x9d, 0xf6, 0xe9, 0x90, 0x4, 0xcc, 0x98 +DEFINE_GUIDSTRUCT("9F4801BD-F746-4c7a-8A9D-F6E99004CC98", MYKSNAME_FRONT_VOLUME); +#define MYKSNAME_FRONT_VOLUME DEFINE_GUIDNAMED(MYKSNAME_FRONT_VOLUME) + +// Front Mute Name +#define STATIC_MYKSNAME_FRONT_MUTE\ + 0xc8e03b2a, 0xebd9, 0x4554, 0xa7, 0x50, 0x8e, 0x44, 0x72, 0x75, 0xa, 0x5b +DEFINE_GUIDSTRUCT("C8E03B2A-EBD9-4554-A750-8E4472750A5B", MYKSNAME_FRONT_MUTE); +#define MYKSNAME_FRONT_MUTE DEFINE_GUIDNAMED(MYKSNAME_FRONT_MUTE) + +// Surround Pin Name +#define STATIC_MYKSNAME_SURROUND\ + 0x81fbb14b, 0x1bee, 0x4bf5, 0x92, 0xee, 0xff, 0xc4, 0xf7, 0x5f, 0x32, 0x6d +DEFINE_GUIDSTRUCT("81FBB14B-1BEE-4bf5-92EE-FFC4F75F326D", MYKSNAME_SURROUND); +#define MYKSNAME_SURROUND DEFINE_GUIDNAMED(MYKSNAME_SURROUND) + +// Center Pin Name +#define STATIC_MYKSNAME_CENTER\ + 0x2d97372f, 0x9cf6, 0x4fd6, 0x9e, 0x56, 0xc6, 0x8b, 0xac, 0xdf, 0x36, 0xd +DEFINE_GUIDSTRUCT("2D97372F-9CF6-4fd6-9E56-C68BACDF360D", MYKSNAME_CENTER); +#define MYKSNAME_CENTER DEFINE_GUIDNAMED(MYKSNAME_CENTER) + +// LFE Pin Name +#define STATIC_MYKSNAME_LFE\ + 0xb60c4274, 0x3bfd, 0x430b, 0x83, 0x64, 0xd9, 0x47, 0xe7, 0xd3, 0x4, 0xb1 +DEFINE_GUIDSTRUCT("B60C4274-3BFD-430b-8364-D947E7D304B1", MYKSNAME_LFE); +#define MYKSNAME_LFE DEFINE_GUIDNAMED(MYKSNAME_LFE) + +// Front Pin Name +#define STATIC_MYKSNAME_FRONT\ + 0x70395e2, 0xbe7c, 0x4b4d, 0xb5, 0x29, 0x40, 0xcb, 0x9b, 0xfc, 0xf9, 0x95 +DEFINE_GUIDSTRUCT("070395E2-BE7C-4b4d-B529-40CB9BFCF995", MYKSNAME_FRONT); +#define MYKSNAME_FRONT DEFINE_GUIDNAMED(MYKSNAME_FRONT) + +#endif // _GUIDS_H_ diff --git a/drivers/wdm/audio/drivers/ac97/ichreg.h b/drivers/wdm/audio/drivers/ac97/ichreg.h new file mode 100644 index 00000000000..504a2260c5a --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/ichreg.h @@ -0,0 +1,107 @@ +/******************************************************************************** +** Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved. +** +** Portions Copyright (c) 1998-1999 Intel Corporation +** +********************************************************************************/ + +/* The file ichreg.h was reviewed by LCA in June 2011 and is acceptable for use by Microsoft. */ + +#ifndef _ICHREG_H_ +#define _ICHREG_H_ + +// We define the offsets like PI_BDBAR as ULONG (instead of UCHAR) for run +// time efficiency. + +// CoDec AC97 register space offsets +const ULONG PRIMARY_CODEC = 0x00; +const ULONG SECONDARY_CODEC = 0x80; + +// Native audio bus master control registers (offsets) +const ULONG PI_BDBAR = 0x00; // PCM In Buffer Descriptor Base Address Register +const ULONG PI_CIV = 0x04; // PCM In Current Index Value +const ULONG PI_LVI = 0x05; // PCM In Last Valid Index +const ULONG PI_SR = 0x06; // PCM In Status Register +const ULONG PI_PICB = 0x08; // PCM In Position In Current Buffer +const ULONG PI_PIV = 0x0A; // PCM In Prefetch Index Value +const ULONG PI_CR = 0x0B; // PCM In Control Register +const ULONG PO_BDBAR = 0x10; // PCM Out Buffer Descriptor Base Address Register +const ULONG PO_CIV = 0x14; // PCM Out Current Index Value +const ULONG PO_LVI = 0x15; // PCM Out Last Valid Index +const ULONG PO_SR = 0x16; // PCM Out Status Register +const ULONG PO_PICB = 0x18; // PCM Out Position In Current Buffer +const ULONG PO_PIV = 0x1A; // PCM Out Prefetch Index Value +const ULONG PO_CR = 0x1B; // PCM Out Control Register +const ULONG MC_BDBAR = 0x20; // Mic In Buffer Descriptor Base Address Register +const ULONG MC_CIV = 0x24; // Mic In Current Index Value +const ULONG MC_LVI = 0x25; // Mic In Last Valid Index +const ULONG MC_SR = 0x26; // Mic In Status Register +const ULONG MC_PICB = 0x28; // Mic In Position In Current Buffer +const ULONG MC_PIV = 0x2A; // Mic In Prefetch Index Value +const ULONG MC_CR = 0x2B; // Mic In Control Register +const ULONG GLOB_CNT = 0x2C; // Global Control +const ULONG GLOB_STA = 0x30; // Global Status +const ULONG CAS = 0x34; // Codec Access Semiphore + +// Defines for relative accesses (offsets) +const ULONG X_PI_BASE = 0x00; // PCM In Base +const ULONG X_PO_BASE = 0x10; // PCM Out Base +const ULONG X_MC_BASE = 0x20; // Mic In Base +const ULONG X_BDBAR = 0x00; // Buffer Descriptor Base Address Register +const ULONG X_CIV = 0x04; // Current Index Value +const ULONG X_LVI = 0x05; // Last Valid Index +const ULONG X_SR = 0x06; // Status Register +const ULONG X_PICB = 0x08; // Position In Current Buffer +const ULONG X_PIV = 0x0A; // Prefetch Index Value +const ULONG X_CR = 0x0B; // Control Register + +// Bits defined in satatus register (*_SR) +const USHORT SR_FIFOE = 0x0010; // FIFO error +const USHORT SR_BCIS = 0x0008; // Buffer Completeion Interrupt Status +const USHORT SR_LVBCI = 0x0004; // Last Valid Buffer Completion Interrupt +const USHORT SR_CELV = 0x0002; // Last Valid Buffer Completion Interrupt + +// Global Control bit defines (GLOB_CNT) +const ULONG GLOB_CNT_PCM6 = 0x00200000; // 6 Channel Mode bit +const ULONG GLOB_CNT_PCM4 = 0x00100000; // 4 Channel Mode bit +const ULONG GLOB_CNT_SRIE = 0x00000020; // Secondary Resume Interrupt Enable +const ULONG GLOB_CNT_PRIE = 0x00000010; // Primary Resume Interrupt Enable +const ULONG GLOB_CNT_ACLOFF = 0x00000008; // ACLINK Off +const ULONG GLOB_CNT_WARM = 0x00000004; // AC97 Warm Reset +const ULONG GLOB_CNT_COLD = 0x00000002; // AC97 Cold Reset +const ULONG GLOB_CNT_GIE = 0x00000001; // GPI Interrupt Enable + +// Global Status bit defines (GLOB_STA) +const ULONG GLOB_STA_MC6 = 0x00200000; // Multichannel Capability 6 channel +const ULONG GLOB_STA_MC4 = 0x00100000; // Multichannel Capability 4 channel +const ULONG GLOB_STA_MD3 = 0x00020000; // Modem Power Down Semiphore +const ULONG GLOB_STA_AD3 = 0x00010000; // Audio Power Down Semiphore +const ULONG GLOB_STA_RCS = 0x00008000; // Read Completion Status +const ULONG GLOB_STA_B3S12 = 0x00004000; // Bit 3 Slot 12 +const ULONG GLOB_STA_B2S12 = 0x00002000; // Bit 2 Slot 12 +const ULONG GLOB_STA_B1S12 = 0x00001000; // Bit 1 Slot 12 +const ULONG GLOB_STA_SRI = 0x00000800; // Secondary Resume Interrupt +const ULONG GLOB_STA_PRI = 0x00000400; // Primary Resume Interrupt +const ULONG GLOB_STA_SCR = 0x00000200; // Secondary Codec Ready +const ULONG GLOB_STA_PCR = 0x00000100; // Primary Codec Ready +const ULONG GLOB_STA_MINT = 0x00000080; // Mic In Interrupt +const ULONG GLOB_STA_POINT = 0x00000040; // PCM Out Interrupt +const ULONG GLOB_STA_PIINT = 0x00000020; // PCM In Interrupt +const ULONG GLOB_STA_MOINT = 0x00000004; // Modem Out Interrupt + +// CoDec Access Semiphore bit defines (CAS) +const UCHAR CAS_CAS = 0x01; // Codec Access Semiphore Bit + +// DMA Engine Control Register (*_CR) bit defines +const UCHAR CR_IOCE = 0x10; // Interrupt On Completion Enable +const UCHAR CR_FEIE = 0x08; // FIFO Error Interrupt Enable +const UCHAR CR_LVBIE = 0x04; // Last Valid Buffer Interrupt Enable +const UCHAR CR_RPBM = 0x01; // Run/Pause Bus Master +const UCHAR CR_RR = 0x02; // Reset Registers (RR) + +// BDL policy bits +const USHORT IOC_ENABLE = 0x8000; +const USHORT BUP_SET = 0x4000; + +#endif //_ICHREG_H_ + diff --git a/drivers/wdm/audio/drivers/ac97/license.txt b/drivers/wdm/audio/drivers/ac97/license.txt new file mode 100644 index 00000000000..9e841e7a26e --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/license.txt @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/drivers/wdm/audio/drivers/ac97/miniport.cpp b/drivers/wdm/audio/drivers/ac97/miniport.cpp new file mode 100644 index 00000000000..83bb53d9d3c --- /dev/null +++ b/drivers/wdm/audio/drivers/ac97/miniport.cpp @@ -0,0 +1,1462 @@ +// Every debug output has "Modulname text" +#define STR_MODULENAME "AC97 Miniport: " + +//#include "shared.h" +//#include "miniport.h" +#include "wavepciminiport.h" + +/***************************************************************************** + * PinDataRangesPCMStream + ***************************************************************************** + * The next 3 arrays contain information about the data ranges of the pin for + * wave capture, wave render and mic capture. + * These arrays are filled dynamically by BuildDataRangeInformation(). + */ + +static KSDATARANGE_AUDIO PinDataRangesPCMStreamRender[WAVE_SAMPLERATES_TESTED]; +static KSDATARANGE_AUDIO PinDataRangesPCMStreamCapture[WAVE_SAMPLERATES_TESTED]; +static KSDATARANGE_AUDIO PinDataRangesMicStream[MIC_SAMPLERATES_TESTED]; + +static KSDATARANGE PinDataRangesAnalogBridge[] = +{ + { + sizeof(KSDATARANGE), + 0, + 0, + 0, + STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), + STATICGUIDOF(KSDATAFORMAT_SUBTYPE_ANALOG), + STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) + } +}; + +/***************************************************************************** + * PinDataRangesPointersPCMStream + ***************************************************************************** + * The next 3 arrays contain the pointers to the data range information of + * the pin for wave capture, wave render and mic capture. + * These arrays are filled dynamically by BuildDataRangeInformation(). + */ +static PKSDATARANGE PinDataRangePointersPCMStreamRender[WAVE_SAMPLERATES_TESTED]; +static PKSDATARANGE PinDataRangePointersPCMStreamCapture[WAVE_SAMPLERATES_TESTED]; +static PKSDATARANGE PinDataRangePointersMicStream[MIC_SAMPLERATES_TESTED]; + +/***************************************************************************** + * PinDataRangePointerAnalogStream + ***************************************************************************** + * This structure pointers to the data range structures for the wave pins. + */ +static PKSDATARANGE PinDataRangePointersAnalogBridge[] = +{ + (PKSDATARANGE) PinDataRangesAnalogBridge +}; + + +/***************************************************************************** + * Wave Miniport Topology + *======================== + * + * +-----------+ + * | | + * Capture (PIN_WAVEIN) <---|2 --ADC-- 3|<=== (PIN_WAVEIN_BRIDGE) + * | | + * Render (PIN_WAVEOUT) --->|0 --DAC-- 1|===> (PIN_WAVEOUT_BRIDGE) + * | | + * Mic (PIN_MICIN) <---|4 --ADC-- 5|<=== (PIN_MICIN_BRIDGE) + * +-----------+ + * + * Note that the exposed pins (left side) have to be a multiple of 2 + * since there are some dependencies in the stream object. + */ + +/***************************************************************************** + * MiniportPins + ***************************************************************************** + * This structure describes pin (stream) types provided by this miniport. + * The field that sets the number of data range entries (SIZEOF_ARRAY) is + * overwritten by BuildDataRangeInformation(). + */ +static PCPIN_DESCRIPTOR MiniportPins[] = +{ + // PIN_WAVEOUT + { + 1,1,0, // InstanceCount + NULL, // AutomationTable + { // KsPinDescriptor + 0, // InterfacesCount + NULL, // Interfaces + 0, // MediumsCount + NULL, // Mediums + SIZEOF_ARRAY(PinDataRangePointersPCMStreamRender), // DataRangesCount + PinDataRangePointersPCMStreamRender, // DataRanges + KSPIN_DATAFLOW_IN, // DataFlow + KSPIN_COMMUNICATION_SINK, // Communication + (GUID *) &KSCATEGORY_AUDIO, // Category + NULL, // Name + 0 // Reserved + } + }, + + // PIN_WAVEOUT_BRIDGE + { + 0,0,0, // InstanceCount + NULL, // AutomationTable + { // KsPinDescriptor + 0, // InterfacesCount + NULL, // Interfaces + 0, // MediumsCount + NULL, // Mediums + SIZEOF_ARRAY(PinDataRangePointersAnalogBridge), // DataRangesCount + PinDataRangePointersAnalogBridge, // DataRanges + KSPIN_DATAFLOW_OUT, // DataFlow + KSPIN_COMMUNICATION_NONE, // Communication + (GUID *) &KSCATEGORY_AUDIO, // Category + NULL, // Name + 0 // Reserved + } + }, + + // PIN_WAVEIN + { + 1,1,0, // InstanceCount + NULL, // AutomationTable + { // KsPinDescriptor + 0, // InterfacesCount + NULL, // Interfaces + 0, // MediumsCount + NULL, // Mediums + SIZEOF_ARRAY(PinDataRangePointersPCMStreamCapture), // DataRangesCount + PinDataRangePointersPCMStreamCapture, // DataRanges + KSPIN_DATAFLOW_OUT, // DataFlow + KSPIN_COMMUNICATION_SINK, // Communication + (GUID *) &PINNAME_CAPTURE, // Category + &KSAUDFNAME_RECORDING_CONTROL, // Name + 0 // Reserved + } + }, + + // PIN_WAVEIN_BRIDGE + { + 0,0,0, // InstanceCount + NULL, // AutomationTable + { // KsPinDescriptor + 0, // InterfacesCount + NULL, // Interfaces + 0, // MediumsCount + NULL, // Mediums + SIZEOF_ARRAY(PinDataRangePointersAnalogBridge), // DataRangesCount + PinDataRangePointersAnalogBridge, // DataRanges + KSPIN_DATAFLOW_IN, // DataFlow + KSPIN_COMMUNICATION_NONE, // Communication + (GUID *) &KSCATEGORY_AUDIO, // Category + NULL, // Name + 0 // Reserved + } + }, + + // + // The Microphone pins are not used if PINC_MICIN_PRESENT is not set. + // To remove them, Init() will reduce the "PinCount" in the + // MiniportFilterDescriptor. + // + // PIN_MICIN + { + 1,1,0, // InstanceCount + NULL, // AutomationTable + { // KsPinDescriptor + 0, // InterfacesCount + NULL, // Interfaces + 0, // MediumsCount + NULL, // Mediums + SIZEOF_ARRAY(PinDataRangePointersMicStream),// DataRangesCount + PinDataRangePointersMicStream, // DataRanges + KSPIN_DATAFLOW_OUT, // DataFlow + KSPIN_COMMUNICATION_SINK, // Communication + (GUID *) &KSCATEGORY_AUDIO, // Category + NULL, // Name + 0 // Reserved + } + }, + + // PIN_MICIN_BRIDGE + { + 0,0,0, // InstanceCount + NULL, // AutomationTable + { // KsPinDescriptor + 0, // InterfacesCount + NULL, // Interfaces + 0, // MediumsCount + NULL, // Mediums + SIZEOF_ARRAY(PinDataRangePointersAnalogBridge), // DataRangesCount + PinDataRangePointersAnalogBridge, // DataRanges + KSPIN_DATAFLOW_IN, // DataFlow + KSPIN_COMMUNICATION_NONE, // Communication + (GUID *) &KSCATEGORY_AUDIO, // Category + NULL, // Name + 0 // Reserved + } + } +}; + +/***************************************************************************** + * PropertiesDAC + ***************************************************************************** + * Properties for the DAC node. + */ +static PCPROPERTY_ITEM PropertiesDAC[] = +{ + { + &KSPROPSETID_Audio, + KSPROPERTY_AUDIO_CHANNEL_CONFIG, + KSPROPERTY_TYPE_SET, + CMiniport::PropertyChannelConfig + } +}; + +/***************************************************************************** + * AutomationVolume + ***************************************************************************** + * Automation table for volume controls. + */ +DEFINE_PCAUTOMATION_TABLE_PROP (AutomationDAC, PropertiesDAC); + +/***************************************************************************** + * TopologyNodes + ***************************************************************************** + * List of nodes. + */ +static PCNODE_DESCRIPTOR MiniportNodes[] = +{ + // NODE_WAVEOUT_DAC + { + 0, // Flags + &AutomationDAC, // AutomationTable + &KSNODETYPE_DAC, // Type + NULL // Name + }, + // NODE_WAVEIN_ADC + { + 0, // Flags + NULL, // AutomationTable + &KSNODETYPE_ADC, // Type + NULL // Name + }, + // + // The Microphone node is not used if PINC_MICIN_PRESENT is not set. + // To remove them, Init() will reduce the "NodeCount" in the + // MiniportFilterDescriptor. + // + // NODE_MICIN_ADC + { + 0, // Flags + NULL, // AutomationTable + &KSNODETYPE_ADC, // Type + NULL // Name + } +}; + +/***************************************************************************** + * MiniportConnections + ***************************************************************************** + * This structure identifies the connections between filter pins and + * node pins. + */ +static PCCONNECTION_DESCRIPTOR MiniportConnections[] = +{ + //from_node from_pin to_node to_pin + { PCFILTER_NODE, PIN_WAVEOUT, NODE_WAVEOUT_DAC, 1}, + { NODE_WAVEOUT_DAC, 0, PCFILTER_NODE, PIN_WAVEOUT_BRIDGE}, + { PCFILTER_NODE, PIN_WAVEIN_BRIDGE, NODE_WAVEIN_ADC, 1}, + { NODE_WAVEIN_ADC, 0, PCFILTER_NODE, PIN_WAVEIN}, + // + // The Microphone connection is not used if PINC_MICIN_PRESENT is not set. + // To remove them, Init() will reduce the "ConnectionCount" in the + // MiniportFilterDescriptor. + // + { PCFILTER_NODE, PIN_MICIN_BRIDGE, NODE_MICIN_ADC, 1}, + { NODE_MICIN_ADC, 0, PCFILTER_NODE, PIN_MICIN} +}; + +/***************************************************************************** + * MiniportFilterDescriptor + ***************************************************************************** + * Complete miniport description. + * Init() modifies the pin count, node count and connection count in absence + * of the MicIn recording line. + */ +static PCFILTER_DESCRIPTOR MiniportFilterDescriptor = +{ + 0, // Version + NULL, // AutomationTable + sizeof(PCPIN_DESCRIPTOR), // PinSize + SIZEOF_ARRAY(MiniportPins), // PinCount + MiniportPins, // Pins + sizeof(PCNODE_DESCRIPTOR), // NodeSize + SIZEOF_ARRAY(MiniportNodes), // NodeCount + MiniportNodes, // Nodes + SIZEOF_ARRAY(MiniportConnections), // ConnectionCount + MiniportConnections, // Connections + 0, // CategoryCount + NULL // Categories: NULL->use defaults (audio, render, capture) +}; + +#ifdef _MSC_VER +#pragma code_seg("PAGE") +#endif +/***************************************************************************** + * CMiniport::PropertyChannelConfig + ***************************************************************************** + * This is the property handler for KSPROPERTY_AUDIO_CHANNEL_CONFIG of the + * DAC node. It sets the channel configuration (how many channels, how user + * was setting up the speakers). + */ +NTSTATUS CMiniport::PropertyChannelConfig +( + IN PPCPROPERTY_REQUEST PropertyRequest +) +{ + PAGED_CODE (); + + ASSERT (PropertyRequest); + + DOUT (DBG_PRINT, ("[CMiniport::PropertyChannelConfig]")); + + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + + // The major target is the object pointer to the wave miniport. + // HACK ALERT - unsafe pointer cast - HACK ALERT + CMiniport *that = (CMiniport *)(CMiniportWaveICH*) + (PMINIPORTWAVEPCI)PropertyRequest->MajorTarget; + + ASSERT (that); + + // We only have a set defined. + if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) + { + // validate buffer size. + if (PropertyRequest->ValueSize < sizeof(LONG)) + return ntStatus; + + // The "Value" is the input buffer with the channel config. + if (PropertyRequest->Value) + { + // We can accept different channel configurations, depending + // on the number of channels we can play. + if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT)) + { + if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT)) + { + // we accept 5.1 + if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_5POINT1) + { + that->m_dwChannelMask = *(PLONG)PropertyRequest->Value; + that->m_wChannels = 6; + that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask); + ntStatus = STATUS_SUCCESS; + } + } + + // accept also surround or quad. + if ((*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_QUAD) || + (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_SURROUND)) + { + that->m_dwChannelMask = *(PLONG)PropertyRequest->Value; + that->m_wChannels = 4; + that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask); + ntStatus = STATUS_SUCCESS; + } + } + + // accept also stereo speakers. + if (*(PLONG)PropertyRequest->Value == KSAUDIO_SPEAKER_STEREO) + { + that->m_dwChannelMask = *(PLONG)PropertyRequest->Value; + that->m_wChannels = 2; + that->AdapterCommon->WriteChannelConfigDefault (that->m_dwChannelMask); + ntStatus = STATUS_SUCCESS; + } + } + } + + return ntStatus; +} + + +/***************************************************************************** + * CMiniport::BuildDataRangeInformation + ***************************************************************************** + * This function dynamically build the data range information for the pins. + * It also connects the static arrays with the data range information + * structure. + * If this function returns with an error the miniport should be destroyed. + * + * To build the data range information, we test the most popular sample rates, ... 10011 lines suppressed ...
2 years, 10 months
1
0
0
0
[reactos] 04/05: [DDK] Hack the IDmaChannel::PhysicalAddress ABI
by Bryan Kirk
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0944f808f8f2ef179f562…
commit 0944f808f8f2ef179f5627c10908e30a812ee5cd Author: Bryan Kirk <Zero3K(a)teknik.io> AuthorDate: Sun Jan 23 08:57:08 2022 -0500 Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org> CommitDate: Wed Feb 16 01:31:28 2022 +0300 [DDK] Hack the IDmaChannel::PhysicalAddress ABI --- sdk/include/ddk/portcls.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sdk/include/ddk/portcls.h b/sdk/include/ddk/portcls.h index 4a2342fe038..cb6c5939de4 100644 --- a/sdk/include/ddk/portcls.h +++ b/sdk/include/ddk/portcls.h @@ -704,6 +704,16 @@ typedef IUnregisterPhysicalConnection *PUNREGISTERPHYSICALCONNECTION; IDmaChannel Interface */ +/* C++ ABI HACK: IDmaChannel::PhysicalAddress */ +#if defined(__cplusplus) && !defined(_MSC_VER) +#define DEFINE_ABSTRACT_DMACHANNEL_PhysicalAddress \ + STDMETHOD_(PHYSICAL_ADDRESS*, PhysicalAddress)( THIS_ PHYSICAL_ADDRESS* pRet ) PURE; \ + PHYSICAL_ADDRESS PhysicalAddress() { PHYSICAL_ADDRESS tmp; PhysicalAddress(&tmp); return tmp; } +#else +#define DEFINE_ABSTRACT_DMACHANNEL_PhysicalAddress \ + STDMETHOD_(PHYSICAL_ADDRESS, PhysicalAddress)( THIS ) PURE +#endif + #define DEFINE_ABSTRACT_DMACHANNEL() \ STDMETHOD_(NTSTATUS, AllocateBuffer)( THIS_ \ IN ULONG BufferSize, \
2 years, 10 months
1
0
0
0
[reactos] 03/05: [PSDK] Add GUIDs used by AC97 sample driver
by Bryan Kirk
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3d9ef5c7e7e43e8d68c42…
commit 3d9ef5c7e7e43e8d68c424c8bc763bf6a8d4b63e Author: Bryan Kirk <Zero3K(a)teknik.io> AuthorDate: Sat Jan 22 19:38:50 2022 -0500 Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org> CommitDate: Wed Feb 16 01:31:28 2022 +0300 [PSDK] Add GUIDs used by AC97 sample driver --- sdk/include/psdk/ksmedia.h | 100 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/sdk/include/psdk/ksmedia.h b/sdk/include/psdk/ksmedia.h index 84f24abf4db..83e717e9e93 100644 --- a/sdk/include/psdk/ksmedia.h +++ b/sdk/include/psdk/ksmedia.h @@ -508,6 +508,106 @@ DEFINE_GUIDSTRUCT("DFF21CE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_COMMUNICATI DEFINE_GUIDSTRUCT("DFF21CE7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER); #define KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER) +#define STATIC_KSAUDFNAME_PC_SPEAKER_VOLUME\ + 0x185FEDF0L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF0-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER_VOLUME); +#define KSAUDFNAME_PC_SPEAKER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER_VOLUME) + +#define STATIC_KSNODETYPE_PHONE_LINE\ + DEFINE_USB_TERMINAL_GUID(0x0501) +DEFINE_GUIDSTRUCT("DFF21EE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PHONE_LINE); +#define KSNODETYPE_PHONE_LINE DEFINE_GUIDNAMED(KSNODETYPE_PHONE_LINE) + +#define STATIC_KSAUDFNAME_CD_AUDIO\ + 0x185FEDFBL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFB-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_AUDIO); +#define KSAUDFNAME_CD_AUDIO DEFINE_GUIDNAMED(KSAUDFNAME_CD_AUDIO) + +#define STATIC_KSAUDFNAME_PC_SPEAKER\ + 0x185FEDFFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER); +#define KSAUDFNAME_PC_SPEAKER DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER) + +#define STATIC_KSAUDFNAME_LINE_IN\ + 0x185FEDF9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN); +#define KSAUDFNAME_LINE_IN DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN) + +#define STATIC_KSAUDFNAME_VIDEO\ + 0x915daec4L, 0xa434, 0x11d2, 0xac, 0x52, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("915DAEC4-A434-11d2-AC52-00C04F8EFB68", KSAUDFNAME_VIDEO); +#define KSAUDFNAME_VIDEO DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO) + +#define STATIC_KSAUDFNAME_AUX\ + 0x185FEDFEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX); +#define KSAUDFNAME_AUX DEFINE_GUIDNAMED(KSAUDFNAME_AUX) + +#define STATIC_KSAUDFNAME_STEREO_MIX\ + 0xdff077L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("00DFF077-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX); +#define KSAUDFNAME_STEREO_MIX DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX) + +#define STATIC_KSAUDFNAME_MONO_MIX\ + 0xdff078L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("00DFF078-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX); +#define KSAUDFNAME_MONO_MIX DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX) + +#define STATIC_KSAUDFNAME_3D_CENTER\ + 0x9f0670b4L, 0x991f, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("9F0670B4-991F-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_3D_CENTER); +#define KSAUDFNAME_3D_CENTER DEFINE_GUIDNAMED(KSAUDFNAME_3D_CENTER) + +#define STATIC_KSAUDFNAME_MONO_MIX_VOLUME\ + 0x22b0eafeL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("22B0EAFE-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX_VOLUME); +#define KSAUDFNAME_MONO_MIX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX_VOLUME) + +#define STATIC_KSAUDFNAME_STEREO_MIX_VOLUME\ + 0x1ad247edL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("1AD247ED-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX_VOLUME); +#define KSAUDFNAME_STEREO_MIX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX_VOLUME) + +#define STATIC_KSAUDFNAME_VIDEO_VOLUME\ + 0x9b46e708L, 0x992a, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("9B46E708-992A-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_VIDEO_VOLUME); +#define KSAUDFNAME_VIDEO_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO_VOLUME) + +#define STATIC_KSAUDFNAME_TREBLE\ + 0x185FEDE1L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE1-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_TREBLE); +#define KSAUDFNAME_TREBLE DEFINE_GUIDNAMED(KSAUDFNAME_TREBLE) + +#define STATIC_KSAUDFNAME_BASS\ + 0x185FEDE0L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE0-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_BASS); +#define KSAUDFNAME_BASS DEFINE_GUIDNAMED(KSAUDFNAME_BASS) + +#define STATIC_KSAUDFNAME_3D_DEPTH\ + 0x63ff5747L, 0x991f, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("63FF5747-991F-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_3D_DEPTH); +#define KSAUDFNAME_3D_DEPTH DEFINE_GUIDNAMED(KSAUDFNAME_3D_DEPTH) + +#define STATIC_KSAUDFNAME_MONO_OUT\ + 0xf9b41dc3L, 0x96e2, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("F9B41DC3-96E2-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT); +#define KSAUDFNAME_MONO_OUT DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT) + +#define STATIC_KSAUDFNAME_PC_SPEAKER_MUTE\ + 0x185FEDF1L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF1-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER_MUTE); +#define KSAUDFNAME_PC_SPEAKER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER_MUTE) + +#define STATIC_KSAUDFNAME_ALTERNATE_MICROPHONE\ + 0x2bc31d6bL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("2BC31D6B-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_ALTERNATE_MICROPHONE); +#define KSAUDFNAME_ALTERNATE_MICROPHONE DEFINE_GUIDNAMED(KSAUDFNAME_ALTERNATE_MICROPHONE) + +#define STATIC_KSAUDFNAME_VIDEO_MUTE\ + 0x9b46e709L, 0x992a, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("9B46E709-992A-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_VIDEO_MUTE); +#define KSAUDFNAME_VIDEO_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO_MUTE) + /* Pins
2 years, 10 months
1
0
0
0
[reactos] 02/05: [DDK] Fix and add portcls definitions used by AC97 driver sample
by Bryan Kirk
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=07baa95a018a219f7057c…
commit 07baa95a018a219f7057c4fae7be37198e1ba9d0 Author: Bryan Kirk <Zero3K(a)teknik.io> AuthorDate: Sat Jan 22 18:59:49 2022 -0500 Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org> CommitDate: Wed Feb 16 01:31:27 2022 +0300 [DDK] Fix and add portcls definitions used by AC97 driver sample --- sdk/include/ddk/portcls.h | 67 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/sdk/include/ddk/portcls.h b/sdk/include/ddk/portcls.h index 1c88b2401b8..4a2342fe038 100644 --- a/sdk/include/ddk/portcls.h +++ b/sdk/include/ddk/portcls.h @@ -333,7 +333,7 @@ typedef struct { ULONG FromNodePin; ULONG ToNode; ULONG ToNodePin; -} PCCONNECTION_DESCRIPTOR, *PPCCONNECTIONDESCRIPTOR; +} PCCONNECTION_DESCRIPTOR, *PPCCONNECTION_DESCRIPTOR; typedef struct { ULONG MaxGlobalInstanceCount; @@ -719,7 +719,7 @@ typedef IUnregisterPhysicalConnection *PUNREGISTERPHYSICALCONNECTION; IN ULONG BufferSize) PURE; \ \ STDMETHOD_(PVOID, SystemAddress)( THIS ) PURE; \ - STDMETHOD_(PHYSICAL_ADDRESS, PhysicalAddress)( THIS ) PURE; \ + DEFINE_ABSTRACT_DMACHANNEL_PhysicalAddress; \ STDMETHOD_(PADAPTER_OBJECT, GetAdapterObject)( THIS ) PURE; \ \ STDMETHOD_(void, CopyTo)( THIS_ \ @@ -1432,6 +1432,13 @@ DECLARE_INTERFACE_(IMiniportTopology,IMiniport) typedef IMiniportTopology *PMINIPORTTOPOLOGY; +#define IMP_IMiniportTopology\ + IMP_IMiniport;\ + STDMETHODIMP_(NTSTATUS) Init(\ + IN PUNKNOWN UnknownAdapter,\ + IN PRESOURCELIST ResourceList,\ + IN PPORTTOPOLOGY Port); + /* =============================================================== IMiniportWaveCyclicStream Interface */ @@ -1625,6 +1632,24 @@ DECLARE_INTERFACE_(IMiniportWavePciStream,IUnknown) typedef IMiniportWavePciStream *PMINIPORTWAVEPCISTREAM; +#define IMP_IMiniportWavePciStream\ + STDMETHODIMP_(NTSTATUS) SetFormat(\ + IN PKSDATAFORMAT DataFormat);\ + STDMETHODIMP_(NTSTATUS) SetState(\ + IN KSSTATE State);\ + STDMETHODIMP_(NTSTATUS) GetPosition(\ + OUT PULONGLONG Position);\ + STDMETHODIMP_(NTSTATUS) NormalizePhysicalPosition(\ + IN OUT PLONGLONG PhysicalPosition);\ + STDMETHODIMP_(NTSTATUS) GetAllocatorFraming(\ + OUT PKSALLOCATOR_FRAMING AllocatorFraming);\ + STDMETHODIMP_(NTSTATUS) RevokeMappings(\ + IN PVOID FirstTag,\ + IN PVOID LastTag,\ + OUT PULONG MappingsRevoked);\ + STDMETHODIMP_(void) MappingAvailable(void);\ + STDMETHODIMP_(void) Service(void); + /* =============================================================== IMiniportWavePci Interface */ @@ -1661,6 +1686,25 @@ DECLARE_INTERFACE_(IMiniportWavePci,IMiniport) typedef IMiniportWavePci *PMINIPORTWAVEPCI; +#define IMP_IMiniportWavePci\ + IMP_IMiniport;\ + STDMETHODIMP_(NTSTATUS) Init(\ + IN PUNKNOWN UnknownAdapter,\ + IN PRESOURCELIST ResourceList,\ + IN PPORTWAVEPCI Port,\ + OUT PSERVICEGROUP * ServiceGroup);\ + STDMETHODIMP_(NTSTATUS) NewStream(\ + OUT PMINIPORTWAVEPCISTREAM * Stream,\ + IN PUNKNOWN OuterUnknown ,\ + IN POOL_TYPE PoolType,\ + IN PPORTWAVEPCISTREAM PortStream,\ + IN ULONG Pin,\ + IN BOOLEAN Capture,\ + IN PKSDATAFORMAT DataFormat,\ + OUT PDMACHANNEL * DmaChannel,\ + OUT PSERVICEGROUP * ServiceGroup);\ + STDMETHODIMP_(void) Service(void); + #if !defined(DEFINE_ABSTRACT_MINIPORTWAVERTSTREAM) @@ -2222,6 +2266,25 @@ DEFINE_GUID(IID_IMusicTechnology, /* =============================================================== IPreFetchOffset Interface */ +#undef INTERFACE +#define INTERFACE IPreFetchOffset + +#if (NTDDI_VERSION >= NTDDI_WINXP) +DEFINE_GUID(IID_IPreFetchOffset, 0x7000f480L, 0xed44, 0x4e8b, 0xb3, 0x8a, 0x41, 0x2f, 0x8d, 0x7a, 0x50, 0x4d); +#endif + +DECLARE_INTERFACE_(IPreFetchOffset, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + + STDMETHOD_(DWORD, SetPreFetchOffset)(THIS_ + IN ULONG PreFetchOffset) PURE; +}; + +#define IMP_IPreFetchOffset \ + STDMETHODIMP_(DWORD) SetPreFetchOffset(IN ULONG PreFetchOffset); + +typedef IPreFetchOffset *PPREFETCHOFFSET; /* =============================================================== PortCls API Functions
2 years, 10 months
1
0
0
0
[reactos] 01/05: [PORTCLS] Centralize AddRef/Release implementation.
by Victor Perevertkin
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6e97b4314f9550f771f38…
commit 6e97b4314f9550f771f38f3959b25bc5ef171bbb Author: Victor Perevertkin <victor.perevertkin(a)reactos.org> AuthorDate: Wed Feb 16 01:25:25 2022 +0300 Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org> CommitDate: Wed Feb 16 01:31:27 2022 +0300 [PORTCLS] Centralize AddRef/Release implementation. And make it thread-safe. Co-authored-by: Thomas Faber <thomas.faber(a)reactos.org> --- drivers/wdm/audio/backpln/portcls/connection.cpp | 22 +---------- drivers/wdm/audio/backpln/portcls/dma_slave.cpp | 23 +----------- drivers/wdm/audio/backpln/portcls/drm_port.cpp | 22 +---------- drivers/wdm/audio/backpln/portcls/filter_dmus.cpp | 19 +--------- .../wdm/audio/backpln/portcls/filter_topology.cpp | 19 +--------- .../audio/backpln/portcls/filter_wavecyclic.cpp | 19 +--------- .../wdm/audio/backpln/portcls/filter_wavepci.cpp | 20 +--------- .../wdm/audio/backpln/portcls/filter_wavert.cpp | 20 +--------- drivers/wdm/audio/backpln/portcls/interrupt.cpp | 20 +--------- drivers/wdm/audio/backpln/portcls/irpstream.cpp | 19 +--------- .../wdm/audio/backpln/portcls/miniport_dmus.cpp | 43 +--------------------- drivers/wdm/audio/backpln/portcls/pin_dmus.cpp | 20 +--------- .../wdm/audio/backpln/portcls/pin_wavecyclic.cpp | 24 +----------- drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp | 22 +---------- drivers/wdm/audio/backpln/portcls/pin_wavert.cpp | 20 +--------- drivers/wdm/audio/backpln/portcls/port_dmus.cpp | 21 +---------- .../wdm/audio/backpln/portcls/port_topology.cpp | 22 +---------- .../wdm/audio/backpln/portcls/port_wavecyclic.cpp | 23 +----------- drivers/wdm/audio/backpln/portcls/port_wavepci.cpp | 23 +----------- drivers/wdm/audio/backpln/portcls/port_wavert.cpp | 24 +----------- .../audio/backpln/portcls/port_wavertstream.cpp | 21 +---------- drivers/wdm/audio/backpln/portcls/private.hpp | 33 +++++++++++++++++ drivers/wdm/audio/backpln/portcls/registry.cpp | 25 +++---------- drivers/wdm/audio/backpln/portcls/resource.cpp | 32 ++++++---------- .../wdm/audio/backpln/portcls/service_group.cpp | 22 +---------- drivers/wdm/audio/backpln/portcls/unregister.cpp | 25 +------------ drivers/wdm/audio/backpln/portcls/version.cpp | 24 +----------- 27 files changed, 80 insertions(+), 547 deletions(-) diff --git a/drivers/wdm/audio/backpln/portcls/connection.cpp b/drivers/wdm/audio/backpln/portcls/connection.cpp index ebaa8431eba..ffa71c80137 100644 --- a/drivers/wdm/audio/backpln/portcls/connection.cpp +++ b/drivers/wdm/audio/backpln/portcls/connection.cpp @@ -25,36 +25,16 @@ RtlCreateUnicodeString( ); -class CUnregisterPhysicalConnection : public IUnregisterPhysicalConnection +class CUnregisterPhysicalConnection : public CUnknownImpl<IUnregisterPhysicalConnection> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IUnregisterPhysicalConnection; CUnregisterPhysicalConnection(IUnknown *OuterUnknown){} virtual ~CUnregisterPhysicalConnection(){} - -protected: - LONG m_Ref; - }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/dma_slave.cpp b/drivers/wdm/audio/backpln/portcls/dma_slave.cpp index 40d5132f6f4..ef71d248981 100644 --- a/drivers/wdm/audio/backpln/portcls/dma_slave.cpp +++ b/drivers/wdm/audio/backpln/portcls/dma_slave.cpp @@ -14,7 +14,7 @@ #include <debug.h> -class CDmaChannelInit : public IDmaChannelInit +class CDmaChannelInit : public CUnknownImpl<IDmaChannelInit> { public: inline @@ -29,22 +29,6 @@ public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IDmaChannelInit; CDmaChannelInit(IUnknown * OuterUnknown) : m_pDeviceObject(nullptr), @@ -60,8 +44,7 @@ public: m_Address({0}), m_Buffer(nullptr), m_Mdl(nullptr), - m_WriteToDevice(FALSE), - m_Ref(0) + m_WriteToDevice(FALSE) { } virtual ~CDmaChannelInit(){} @@ -89,8 +72,6 @@ protected: BOOLEAN m_WriteToDevice; friend IO_ALLOCATION_ACTION NTAPI AdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context); - - LONG m_Ref; }; diff --git a/drivers/wdm/audio/backpln/portcls/drm_port.cpp b/drivers/wdm/audio/backpln/portcls/drm_port.cpp index 04f694b12b2..6d10cd8d626 100644 --- a/drivers/wdm/audio/backpln/portcls/drm_port.cpp +++ b/drivers/wdm/audio/backpln/portcls/drm_port.cpp @@ -14,34 +14,14 @@ #include <debug.h> -class CDrmPort2 : public IDrmPort2 +class CDrmPort2 : public CUnknownImpl<IDrmPort2> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IDrmPort2; CDrmPort2(IUnknown *OuterUnknown){} virtual ~CDrmPort2(){} - -protected: - LONG m_Ref; - }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp b/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp index 3d86166c82f..b375cd8b67e 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_dmus.cpp @@ -14,27 +14,11 @@ #include <debug.h> -class CPortFilterDMus : public IPortFilterDMus +class CPortFilterDMus : public CUnknownImpl<IPortFilterDMus> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortFilterDMus; CPortFilterDMus(IUnknown *OuterUnknown){} virtual ~CPortFilterDMus(){} @@ -43,7 +27,6 @@ protected: IPortDMus* m_Port; IPortPinDMus ** m_Pins; SUBDEVICE_DESCRIPTOR * m_Descriptor; - LONG m_Ref; }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/filter_topology.cpp b/drivers/wdm/audio/backpln/portcls/filter_topology.cpp index 8acf5fed4dd..150de8c3cab 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_topology.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_topology.cpp @@ -14,27 +14,11 @@ #include <debug.h> -class CPortFilterTopology : public IPortFilterTopology +class CPortFilterTopology : public CUnknownImpl<IPortFilterTopology> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortFilterTopology; CPortFilterTopology(IUnknown *OuterUnknown){} virtual ~CPortFilterTopology(){} @@ -43,7 +27,6 @@ protected: IPortTopology * m_Port; SUBDEVICE_DESCRIPTOR * m_Descriptor; ISubdevice * m_SubDevice; - LONG m_Ref; }; diff --git a/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp index 29c9512a734..6a935da41c6 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp @@ -14,27 +14,11 @@ #include <debug.h> -class CPortFilterWaveCyclic : public IPortFilterWaveCyclic +class CPortFilterWaveCyclic : public CUnknownImpl<IPortFilterWaveCyclic> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortFilterWaveCyclic; CPortFilterWaveCyclic(IUnknown *OuterUnknown){} virtual ~CPortFilterWaveCyclic(){} @@ -44,7 +28,6 @@ protected: IPortPinWaveCyclic ** m_Pins; SUBDEVICE_DESCRIPTOR * m_Descriptor; ISubdevice * m_SubDevice; - LONG m_Ref; }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp b/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp index 5c5d262956f..9bf3a9465b8 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp @@ -14,27 +14,11 @@ #include <debug.h> -class CPortFilterWavePci : public IPortFilterWavePci +class CPortFilterWavePci : public CUnknownImpl<IPortFilterWavePci> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortFilterPci; CPortFilterWavePci(IUnknown *OuterUnknown){} virtual ~CPortFilterWavePci(){} @@ -43,8 +27,6 @@ protected: IPortWavePci* m_Port; IPortPinWavePci ** m_Pins; SUBDEVICE_DESCRIPTOR * m_Descriptor; - - LONG m_Ref; }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp b/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp index f421c2876e3..a91abafb880 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_wavert.cpp @@ -14,38 +14,20 @@ #include <debug.h> -class CPortFilterWaveRT : public IPortFilterWaveRT +class CPortFilterWaveRT : public CUnknownImpl<IPortFilterWaveRT> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortFilterWaveRT; CPortFilterWaveRT(IUnknown *OuterUnknown){} virtual ~CPortFilterWaveRT(){} protected: - IPortWaveRT* m_Port; IPortPinWaveRT ** m_Pins; SUBDEVICE_DESCRIPTOR * m_Descriptor; - LONG m_Ref; }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/interrupt.cpp b/drivers/wdm/audio/backpln/portcls/interrupt.cpp index 05f66253baf..f733c615974 100644 --- a/drivers/wdm/audio/backpln/portcls/interrupt.cpp +++ b/drivers/wdm/audio/backpln/portcls/interrupt.cpp @@ -21,27 +21,11 @@ typedef struct PVOID DynamicContext; }SYNC_ENTRY, *PSYNC_ENTRY; -class CInterruptSync : public IInterruptSync +class CInterruptSync : public CUnknownImpl<IInterruptSync> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IInterruptSync; CInterruptSync(IUnknown *OuterUnknown){} virtual ~CInterruptSync(){} @@ -59,8 +43,6 @@ public: PVOID m_DynamicContext; NTSTATUS m_Status; - LONG m_Ref; - friend BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext); friend BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext); }; diff --git a/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/drivers/wdm/audio/backpln/portcls/irpstream.cpp index 75f0717ec88..4e2b701eca1 100644 --- a/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -39,27 +39,11 @@ RemoveHeadList_IRP( /* no non canceled irp has been found */ return NULL; } -class CIrpQueue : public IIrpQueue +class CIrpQueue : public CUnknownImpl<IIrpQueue> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IIrpQueue; CIrpQueue(IUnknown *OuterUnknown){} virtual ~CIrpQueue(){} @@ -83,7 +67,6 @@ protected: ULONG m_CurrentOffset; PIRP m_Irp; - volatile LONG m_Ref; }; typedef struct diff --git a/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp b/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp index 1f28043738b..f57aa72a7dc 100644 --- a/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp +++ b/drivers/wdm/audio/backpln/portcls/miniport_dmus.cpp @@ -66,13 +66,9 @@ const ULONG kMPUInputBufferSize = 128; * so it can expose this interface and CUnknown so it automatically gets * reference counting and aggregation support. */ -class CMiniportDMusUART -: public IMiniportDMus, - public IMusicTechnology, - public IPowerNotify +class CMiniportDMusUART : public CUnknownImpl<IMiniportDMus, IMusicTechnology, IPowerNotify> { private: - LONG m_Ref; // Reference count KSSTATE m_KSStateInput; // Miniport state (RUN/PAUSE/ACQUIRE/STOP) PPORTDMUS m_pPort; // Callback interface. PUCHAR m_pPortBase; // Base port address. @@ -105,23 +101,6 @@ private: public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - CMiniportDMusUART(IUnknown * Unknown){} virtual ~CMiniportDMusUART(); @@ -204,10 +183,9 @@ public: * so it can expose this interface and CUnknown so it automatically gets * reference counting and aggregation support. */ -class CMiniportDMusUARTStream : public IMXF +class CMiniportDMusUARTStream : public CUnknownImpl<IMXF> { private: - LONG m_Ref; // Reference Count CMiniportDMusUART * m_pMiniport; // Parent. REFERENCE_TIME m_SnapshotTimeStamp; // Current snapshot of miniport's input timestamp. PUCHAR m_pPortBase; // Base port address. @@ -230,23 +208,6 @@ private: public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - virtual ~CMiniportDMusUARTStream(); STDMETHODIMP_(NTSTATUS) Init diff --git a/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp b/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp index 106ca82a48d..ef07aabed7d 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp @@ -14,27 +14,11 @@ #include <debug.h> -class CPortPinDMus : public IPortPinDMus +class CPortPinDMus : public CUnknownImpl<IPortPinDMus> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortPinDMus; IMP_IServiceSink; IMP_IMasterClock; @@ -76,8 +60,6 @@ protected: ULONG m_PostCompleted; ULONG m_LastTag; - - LONG m_Ref; }; typedef struct diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 07451f6190a..ec67bb50ef0 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -14,8 +14,7 @@ #include <debug.h> -class CPortPinWaveCyclic : public IPortPinWaveCyclic, - public IServiceSink +class CPortPinWaveCyclic : public CUnknownImpl<IPortPinWaveCyclic, IServiceSink> { public: inline @@ -30,22 +29,6 @@ public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortPinWaveCyclic; IMP_IServiceSink; CPortPinWaveCyclic(IUnknown *OuterUnknown) : @@ -73,8 +56,7 @@ public: m_EventListLock(0), m_EventList({nullptr}), m_ResetState(KSRESET_BEGIN), - m_Delay(0), - m_Ref(0) + m_Delay(0) { } virtual ~CPortPinWaveCyclic(){} @@ -125,8 +107,6 @@ protected: KSRESET m_ResetState; ULONG m_Delay; - - LONG m_Ref; }; diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp index 9f681a000c2..879965edc32 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp @@ -14,29 +14,11 @@ #include <debug.h> -class CPortPinWavePci : public IPortPinWavePci, - public IServiceSink, - public IPortWavePciStream +class CPortPinWavePci : public CUnknownImpl<IPortPinWavePci, IServiceSink, IPortWavePciStream> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortPinWavePci; IMP_IServiceSink; IMP_IPortWavePciStream; @@ -74,8 +56,6 @@ protected: KSALLOCATOR_FRAMING m_AllocatorFraming; - LONG m_Ref; - NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); }; diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp index fcdfd1ce812..d259649d3c0 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp @@ -14,27 +14,11 @@ #include <debug.h> -class CPortPinWaveRT : public IPortPinWaveRT +class CPortPinWaveRT : public CUnknownImpl<IPortPinWaveRT> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortPinWaveRT; CPortPinWaveRT(IUnknown *OuterUnknown){} virtual ~CPortPinWaveRT(){} @@ -68,8 +52,6 @@ protected: MEMORY_CACHING_TYPE m_CacheType; PMDL m_Mdl; - LONG m_Ref; - NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); VOID NTAPI SetStreamState(IN KSSTATE State); diff --git a/drivers/wdm/audio/backpln/portcls/port_dmus.cpp b/drivers/wdm/audio/backpln/portcls/port_dmus.cpp index 7eb94d2d6ec..8a3e8cdae13 100644 --- a/drivers/wdm/audio/backpln/portcls/port_dmus.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_dmus.cpp @@ -14,28 +14,11 @@ #include <debug.h> -class CPortDMus : public IPortDMus, - public ISubdevice +class CPortDMus : public CUnknownImpl<IPortDMus, ISubdevice> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortDMus; IMP_ISubdevice; CPortDMus(IUnknown *OuterUnknown){} @@ -55,8 +38,6 @@ protected: PPCFILTER_DESCRIPTOR m_pDescriptor; PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; - LONG m_Ref; - friend VOID GetDMusMiniport(IN IPortDMus * iface, IN PMINIPORTDMUS * Miniport, IN PMINIPORTMIDI * MidiMiniport); }; diff --git a/drivers/wdm/audio/backpln/portcls/port_topology.cpp b/drivers/wdm/audio/backpln/portcls/port_topology.cpp index 2c5cf4333fa..32467b3d6a4 100644 --- a/drivers/wdm/audio/backpln/portcls/port_topology.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_topology.cpp @@ -14,29 +14,11 @@ #include <debug.h> -class CPortTopology : public IPortTopology, - public ISubdevice, - public IPortEvents +class CPortTopology : public CUnknownImpl<IPortTopology, ISubdevice, IPortEvents> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortTopology; IMP_ISubdevice; IMP_IPortEvents; @@ -55,8 +37,6 @@ protected: PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; IPortFilterTopology * m_Filter; - LONG m_Ref; - friend PMINIPORTTOPOLOGY GetTopologyMiniport(PPORTTOPOLOGY Port); }; diff --git a/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp index cb54dcc275b..3a4f3545de7 100644 --- a/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp @@ -16,32 +16,15 @@ GUID IID_IDmaChannelSlave; -class CPortWaveCyclic : public IPortWaveCyclic, - public IPortEvents, - public ISubdevice +class CPortWaveCyclic : public CUnknownImpl<IPortWaveCyclic, IPortEvents, ISubdevice> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortWaveCyclic; IMP_ISubdevice; IMP_IPortEvents; - CPortWaveCyclic(IUnknown *OuterUnknown) : m_Ref(0) {} + CPortWaveCyclic(IUnknown *OuterUnknown) {} virtual ~CPortWaveCyclic(){} protected: @@ -53,8 +36,6 @@ protected: PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor; IPortFilterWaveCyclic * m_Filter; - LONG m_Ref; - friend PMINIPORTWAVECYCLIC GetWaveCyclicMiniport(IN IPortWaveCyclic* iface); friend PDEVICE_OBJECT GetDeviceObject(PPORTWAVECYCLIC iface); }; diff --git a/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp b/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp index 0186258c328..068d28256a8 100644 --- a/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_wavepci.cpp @@ -14,30 +14,11 @@ #include <debug.h> -class CPortWavePci : public IPortWavePci, - public IPortEvents, - public ISubdevice, - public IServiceSink +class CPortWavePci : public CUnknownImpl<IPortWavePci, IPortEvents, ISubdevice, IServiceSink> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortWavePci; IMP_ISubdevice; IMP_IPortEvents; @@ -59,8 +40,6 @@ protected: LIST_ENTRY m_EventList; KSPIN_LOCK m_EventListLock; - LONG m_Ref; - friend PDEVICE_OBJECT GetDeviceObjectFromPortWavePci(IPortWavePci* iface); friend PMINIPORTWAVEPCI GetWavePciMiniport(PPORTWAVEPCI iface); diff --git a/drivers/wdm/audio/backpln/portcls/port_wavert.cpp b/drivers/wdm/audio/backpln/portcls/port_wavert.cpp index 06e97c95b9c..c7f5f7d51ab 100644 --- a/drivers/wdm/audio/backpln/portcls/port_wavert.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_wavert.cpp @@ -14,29 +14,11 @@ #include <debug.h> -class CPortWaveRT : public IPortWaveRT, - public IPortEvents, - public ISubdevice +class CPortWaveRT : public CUnknownImpl<IPortWaveRT, IPortEvents, ISubdevice> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortWaveRT; IMP_ISubdevice; IMP_IPortEvents; @@ -57,8 +39,6 @@ protected: friend PMINIPORTWAVERT GetWaveRTMiniport(IN IPortWaveRT* iface); friend PDEVICE_OBJECT GetDeviceObjectFromPortWaveRT(PPORTWAVERT iface); - - LONG m_Ref; }; static GUID InterfaceGuids[3] = @@ -145,7 +125,7 @@ CPortWaveRT::QueryInterface( IsEqualGUIDAligned(refiid, IID_IUnknown)) { *Output = PVOID(PPORTWAVERT(this)); - PUNKNOWN(*Output)->AddRef(); + PUNKNOWN(*Output)->AddRef(); return STATUS_SUCCESS; } else if (IsEqualGUIDAligned(refiid, IID_IPortEvents)) diff --git a/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp b/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp index 3472c071f66..4689f07b609 100644 --- a/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp @@ -14,34 +14,15 @@ #include <debug.h> -class CPortWaveRTStreamInit : public IPortWaveRTStreamInit +class CPortWaveRTStreamInit : public CUnknownImpl<IPortWaveRTStreamInit> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } IMP_IPortWaveRTStreamInit; CPortWaveRTStreamInit(IUnknown *OuterUnknown) {} virtual ~CPortWaveRTStreamInit() {} -protected: - LONG m_Ref; - }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/private.hpp b/drivers/wdm/audio/backpln/portcls/private.hpp index 75549690577..f17d0788505 100644 --- a/drivers/wdm/audio/backpln/portcls/private.hpp +++ b/drivers/wdm/audio/backpln/portcls/private.hpp @@ -439,4 +439,37 @@ typedef struct PKSOBJECT_CREATE_ITEM CreateItem; }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; +template<typename... Interfaces> +class CUnknownImpl : public Interfaces... +{ +private: + volatile LONG m_Ref; +protected: + CUnknownImpl() : + m_Ref(0) + { + } + virtual ~CUnknownImpl() + { + } +public: + STDMETHODIMP_(ULONG) AddRef() + { + ULONG Ref = InterlockedIncrement(&m_Ref); + ASSERT(Ref < 0x10000); + return Ref; + } + STDMETHODIMP_(ULONG) Release() + { + ULONG Ref = InterlockedDecrement(&m_Ref); + ASSERT(Ref < 0x10000); + if (!Ref) + { + delete this; + return 0; + } + return Ref; + } +}; + #endif /* PORTCLS_PRIVATE_H */ diff --git a/drivers/wdm/audio/backpln/portcls/registry.cpp b/drivers/wdm/audio/backpln/portcls/registry.cpp index 35b7946d384..56a8cc144c8 100644 --- a/drivers/wdm/audio/backpln/portcls/registry.cpp +++ b/drivers/wdm/audio/backpln/portcls/registry.cpp @@ -14,30 +14,18 @@ #include <debug.h> -class CRegistryKey : public IRegistryKey +class CRegistryKey : public CUnknownImpl<IRegistryKey> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() + IMP_IRegistryKey; + CRegistryKey(IUnknown * OuterUnknown, HANDLE hKey, BOOL CanDelete) : + m_hKey(hKey), + m_Deleted(FALSE), + m_CanDelete(CanDelete) { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; } - - IMP_IRegistryKey; - CRegistryKey(IUnknown * OuterUnknown, HANDLE hKey, BOOL CanDelete) : m_hKey(hKey), m_Deleted(FALSE), m_CanDelete(CanDelete), m_Ref(0){} virtual ~CRegistryKey(); protected: @@ -45,7 +33,6 @@ protected: HANDLE m_hKey; BOOL m_Deleted; BOOL m_CanDelete; - LONG m_Ref; }; CRegistryKey::~CRegistryKey() diff --git a/drivers/wdm/audio/backpln/portcls/resource.cpp b/drivers/wdm/audio/backpln/portcls/resource.cpp index dfa4e7b7d83..19020345579 100644 --- a/drivers/wdm/audio/backpln/portcls/resource.cpp +++ b/drivers/wdm/audio/backpln/portcls/resource.cpp @@ -17,31 +17,22 @@ #include <debug.h> -class CResourceList : public IResourceList +class CResourceList : public CUnknownImpl<IResourceList> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - IMP_IResourceList; - CResourceList(IUnknown * OuterUnknown) : m_OuterUnknown(OuterUnknown), m_PoolType(NonPagedPool), m_TranslatedResourceList(0), m_UntranslatedResourceList(0), m_NumberOfEntries(0), m_MaxEntries(0), m_Ref(0) {} + CResourceList(IUnknown * OuterUnknown) : + m_OuterUnknown(OuterUnknown), + m_PoolType(NonPagedPool), + m_TranslatedResourceList(0), + m_UntranslatedResourceList(0), + m_NumberOfEntries(0), + m_MaxEntries(0) + { + } virtual ~CResourceList(); public: @@ -51,7 +42,6 @@ public: PCM_RESOURCE_LIST m_UntranslatedResourceList; ULONG m_NumberOfEntries; ULONG m_MaxEntries; - LONG m_Ref; }; CResourceList::~CResourceList() @@ -461,7 +451,7 @@ PcNewResourceSublist( /* Store members */ NewList->m_OuterUnknown = OuterUnknown; NewList->m_PoolType = PoolType; - NewList->m_Ref = 1; + NewList->AddRef(); NewList->m_NumberOfEntries = 0; NewList->m_MaxEntries = MaximumEntries; diff --git a/drivers/wdm/audio/backpln/portcls/service_group.cpp b/drivers/wdm/audio/backpln/portcls/service_group.cpp index 50ebd7335a4..d3688a92c14 100644 --- a/drivers/wdm/audio/backpln/portcls/service_group.cpp +++ b/drivers/wdm/audio/backpln/portcls/service_group.cpp @@ -29,28 +29,11 @@ typedef struct IN PSERVICESINK pServiceSink; }GROUP_ENTRY, *PGROUP_ENTRY; -class CServiceGroup : public IServiceGroup +class CServiceGroup : public CUnknownImpl<IServiceGroup> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - IMP_IServiceGroup; CServiceGroup(IUnknown * OuterUnknown); virtual ~CServiceGroup() {} @@ -65,9 +48,6 @@ protected: KSPIN_LOCK m_Lock; friend VOID NTAPI IServiceGroupDpc(IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2); - - LONG m_Ref; - }; diff --git a/drivers/wdm/audio/backpln/portcls/unregister.cpp b/drivers/wdm/audio/backpln/portcls/unregister.cpp index 9a3bc8cec66..ef9d7130888 100644 --- a/drivers/wdm/audio/backpln/portcls/unregister.cpp +++ b/drivers/wdm/audio/backpln/portcls/unregister.cpp @@ -14,37 +14,16 @@ #include <debug.h> -class CUnregisterSubdevice : public IUnregisterSubdevice +class CUnregisterSubdevice : public CUnknownImpl<IUnregisterSubdevice> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - - IMP_IUnregisterSubdevice; - CUnregisterSubdevice(IUnknown * OuterUnknown) : m_Ref(0) {} + CUnregisterSubdevice(IUnknown * OuterUnknown) {} virtual ~CUnregisterSubdevice(){} -protected: - LONG m_Ref; - }; NTSTATUS diff --git a/drivers/wdm/audio/backpln/portcls/version.cpp b/drivers/wdm/audio/backpln/portcls/version.cpp index 629c74a4a6a..c3571cc7bd1 100644 --- a/drivers/wdm/audio/backpln/portcls/version.cpp +++ b/drivers/wdm/audio/backpln/portcls/version.cpp @@ -14,42 +14,20 @@ #include <debug.h> -class CPortClsVersion : public IPortClsVersion +class CPortClsVersion : public CUnknownImpl<IPortClsVersion> { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); - STDMETHODIMP_(ULONG) AddRef() - { - InterlockedIncrement(&m_Ref); - return m_Ref; - } - STDMETHODIMP_(ULONG) Release() - { - InterlockedDecrement(&m_Ref); - - if (!m_Ref) - { - delete this; - return 0; - } - return m_Ref; - } - IMP_IPortClsVersion; CPortClsVersion(IUnknown *OuterUnknown) { - m_Ref = 0; } virtual ~CPortClsVersion() { } - -protected: - LONG m_Ref; - };
2 years, 10 months
1
0
0
0
← Newer
1
2
3
4
5
6
7
...
11
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
Results per page:
10
25
50
100
200