diff --git a/ReactOS-arm.rbuild b/ReactOS-arm.rbuild index 777a1aa2cc3..6d7abe77d6e 100644 --- a/ReactOS-arm.rbuild +++ b/ReactOS-arm.rbuild @@ -28,6 +28,7 @@ -ftracer + -fms-extensions -Wno-attributes -U_UNICODE -UUNICODE diff --git a/base/applications/cmdutils/reg/reg.rbuild b/base/applications/cmdutils/reg/reg.rbuild index ce9a744808d..ac33ef4fd0b 100644 --- a/base/applications/cmdutils/reg/reg.rbuild +++ b/base/applications/cmdutils/reg/reg.rbuild @@ -1,3 +1,5 @@ + + . 0x600 diff --git a/base/applications/downloader/downloader.rbuild b/base/applications/downloader/downloader.rbuild index 9ea43dc81f4..b45df064ce0 100644 --- a/base/applications/downloader/downloader.rbuild +++ b/base/applications/downloader/downloader.rbuild @@ -1,25 +1,26 @@ - - downloader.xml - - . - . + + +downloader.xml + + . + . - advapi32 - ntdll - user32 - gdi32 - shell32 - comctl32 - msimg32 - shlwapi - urlmon - uuid - expat + advapi32 + ntdll + user32 + gdi32 + shell32 + comctl32 + msimg32 + shlwapi + urlmon + uuid + expat - main.c - xml.c - download.c - downloader.rc - + main.c + xml.c + download.c + downloader.rc + diff --git a/base/applications/fontview/fontview.rbuild b/base/applications/fontview/fontview.rbuild index 8ceda786c4b..f5cad36f1a9 100644 --- a/base/applications/fontview/fontview.rbuild +++ b/base/applications/fontview/fontview.rbuild @@ -1,3 +1,5 @@ + + . gdi32 diff --git a/base/applications/kbswitch/kbswitch.rbuild b/base/applications/kbswitch/kbswitch.rbuild index 2eed0b22bb0..11ea960adae 100644 --- a/base/applications/kbswitch/kbswitch.rbuild +++ b/base/applications/kbswitch/kbswitch.rbuild @@ -1,4 +1,5 @@ + . diff --git a/base/applications/magnify/magnify.rbuild b/base/applications/magnify/magnify.rbuild index 995437d3826..8c06ce8e5bf 100644 --- a/base/applications/magnify/magnify.rbuild +++ b/base/applications/magnify/magnify.rbuild @@ -1,5 +1,5 @@ - + . user32 diff --git a/base/applications/mplay32/mplay32.rbuild b/base/applications/mplay32/mplay32.rbuild index c472e6f0207..77003d90898 100644 --- a/base/applications/mplay32/mplay32.rbuild +++ b/base/applications/mplay32/mplay32.rbuild @@ -1,3 +1,5 @@ + + . advapi32 diff --git a/base/applications/mscutils/eventvwr/eventvwr.rbuild b/base/applications/mscutils/eventvwr/eventvwr.rbuild index 367c19e5bb4..cb23e1f3eef 100644 --- a/base/applications/mscutils/eventvwr/eventvwr.rbuild +++ b/base/applications/mscutils/eventvwr/eventvwr.rbuild @@ -1,5 +1,5 @@ - + . user32 @@ -8,4 +8,3 @@ eventvwr.c eventvwr.rc - diff --git a/base/applications/network/ping/ping.c b/base/applications/network/ping/ping.c index b9635e24865..b2d48ca5ba3 100644 --- a/base/applications/network/ping/ping.c +++ b/base/applications/network/ping/ping.c @@ -630,8 +630,9 @@ int main(int argc, char* argv[]) while ((NeverStop) || (Count < PingCount)) { Ping(); - Sleep(Timeout); Count++; + if((NeverStop) || (Count < PingCount)) + Sleep(Timeout); }; Cleanup(); diff --git a/base/applications/notepad/settings.c b/base/applications/notepad/settings.c index 862e4fb755e..9a68c8b43db 100644 --- a/base/applications/notepad/settings.c +++ b/base/applications/notepad/settings.c @@ -147,16 +147,16 @@ void LoadSettings(void) if (dwPointSize != 0) Globals.lfFont.lfHeight = HeightFromPointSize(dwPointSize); - hFont = CreateFontIndirect(&Globals.lfFont); - if (hFont) - { - if (Globals.hFont) - DeleteObject(Globals.hFont); - Globals.hFont = hFont; - } - RegCloseKey(hKey); } + + hFont = CreateFontIndirect(&Globals.lfFont); + if (hFont) + { + if (Globals.hFont) + DeleteObject(Globals.hFont); + Globals.hFont = hFont; + } } static BOOL SaveDword(HKEY hKey, LPCTSTR pszValueNameT, DWORD dwValue) diff --git a/base/applications/notepad/text.c b/base/applications/notepad/text.c index 6ca1907dbd6..ed1015d04e9 100644 --- a/base/applications/notepad/text.c +++ b/base/applications/notepad/text.c @@ -51,7 +51,7 @@ BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding { DWORD dwSize; LPBYTE pBytes = NULL; - LPCWSTR pszText; + LPWSTR pszText; LPWSTR pszAllocText = NULL; DWORD dwPos, i; DWORD dwCharCount; @@ -110,7 +110,7 @@ BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding /* fall through */ case ENCODING_UNICODE: - pszText = (LPCWSTR) &pBytes[dwPos]; + pszText = (LPWSTR) &pBytes[dwPos]; dwCharCount = (dwSize - dwPos) / sizeof(WCHAR); break; @@ -174,6 +174,10 @@ BOOL ReadText(HANDLE hFile, LPWSTR *ppszText, DWORD *pdwTextLen, int *piEncoding else adwEolnCount[EOLN_LF]++; break; + + case '\0': + pszText[i] = ' '; + break; } } diff --git a/base/applications/paint/lang/it-IT.rc b/base/applications/paint/lang/it-IT.rc index d7b7c9ee218..2c381068586 100644 --- a/base/applications/paint/lang/it-IT.rc +++ b/base/applications/paint/lang/it-IT.rc @@ -60,8 +60,8 @@ BEGIN MENUITEM "800%", IDM_VIEWZOOM800 END MENUITEM SEPARATOR - MENUITEM "Show grid", IDM_VIEWSHOWGRID - MENUITEM "Show miniature", IDM_VIEWSHOWMINIATURE + MENUITEM "Mostra griglia", IDM_VIEWSHOWGRID + MENUITEM "Mostra miniature", IDM_VIEWSHOWMINIATURE END MENUITEM "Visualizza a schermo intero\tCtrl+F", IDM_VIEWFULLSCREEN END @@ -201,5 +201,5 @@ BEGIN IDS_OPENFILTER, "Bitmap files (*.bmp;*.dib)\1*.bmp;*.dib\1All files (*.*)\1*.*\1" IDS_SAVEFILTER, "24 bit bitmap (*.bmp;*.dib)\1*.bmp;*.dib\1" IDS_FILESIZE, "%d bytes" - IDS_PRINTRES, "%d x %d pixels per meter" + IDS_PRINTRES, "%d x %d pixels per metro" END diff --git a/base/applications/rapps/rapps.rbuild b/base/applications/rapps/rapps.rbuild index 066b3ba7a9b..bc83f3aade9 100644 --- a/base/applications/rapps/rapps.rbuild +++ b/base/applications/rapps/rapps.rbuild @@ -1,3 +1,5 @@ + + include/reactos diff --git a/base/applications/rapps/rapps/firefox3.txt b/base/applications/rapps/rapps/firefox3.txt index e6051802e00..e9313b7677a 100644 --- a/base/applications/rapps/rapps/firefox3.txt +++ b/base/applications/rapps/rapps/firefox3.txt @@ -2,41 +2,41 @@ [Section] Name = Mozilla Firefox 3.0 -Version = 3.0.18 +Version = 3.0.19 Licence = MPL/GPL/LGPL Description = The most popular and one of the best free Web Browsers out there. Size = 7.2M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/en-US/Firefox%20Setup%203.0.18.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/en-US/Firefox%20Setup%203.0.19.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. Size = 7.0M URLSite = http://www.mozilla-europe.org/de/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/de/Firefox%20Setup%203.0.18.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/de/Firefox%20Setup%203.0.19.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. Size = 7.0M URLSite = http://www.mozilla-europe.org/es/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/es-ES/Firefox%20Setup%203.0.18.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/es-ES/Firefox%20Setup%203.0.19.exe [Section.0414] Description = Mest populære og best også gratis nettleserene der ute. -Size = 6.9M +Size = 7.0M URLSite = http://www.mozilla-europe.org/no/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/nb-NO/Firefox%20Setup%203.0.18.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/nb-NO/Firefox%20Setup%203.0.19.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych. Size = 7.8M URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/pl/Firefox%20Setup%203.0.18.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/pl/Firefox%20Setup%203.0.19.exe [Section.0419] Description = Один из самых популярных и лучших бесплатных браузеров. Size = 7.4M URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/ru/Firefox%20Setup%203.0.18.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real/win32/ru/Firefox%20Setup%203.0.19.exe diff --git a/base/applications/rapps/rapps/mirandaim.txt b/base/applications/rapps/rapps/mirandaim.txt index 0fff6a4ea04..db0b17f1ab6 100644 --- a/base/applications/rapps/rapps/mirandaim.txt +++ b/base/applications/rapps/rapps/mirandaim.txt @@ -2,13 +2,13 @@ [Section] Name = Miranda IM -Version = 0.8.18 +Version = 0.8.19 Licence = GPL Description = Open source multiprotocol instant messaging application - May not work completely. Size = 1.6MB Category = 5 URLSite = http://www.miranda-im.org/ -URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.18-unicode.exe +URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.19-unicode.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/openttd.txt b/base/applications/rapps/rapps/openttd.txt index dfc94a95e43..2e70160c846 100644 --- a/base/applications/rapps/rapps/openttd.txt +++ b/base/applications/rapps/rapps/openttd.txt @@ -2,13 +2,13 @@ [Section] Name = OpenTTD -Version = 0.7.5 +Version = 1.0.0 Licence = GPL v2 Description = Open Source clone of the "Transport Tycoon Deluxe" game engine. You need a copy of Transport Tycoon. -Size = 2.9MB +Size = 3.5MB Category = 4 URLSite = http://www.openttd.org/ -URLDownload = http://binaries.openttd.org/releases/0.7.5/openttd-0.7.5-windows-win32.exe +URLDownload = http://binaries.openttd.org/releases/1.0.0/openttd-1.0.0-windows-win32.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/scite.txt b/base/applications/rapps/rapps/scite.txt index fc3d9d50cca..1f8208b2153 100644 --- a/base/applications/rapps/rapps/scite.txt +++ b/base/applications/rapps/rapps/scite.txt @@ -2,13 +2,13 @@ [Section] Name = SciTE -Version = 2.03 +Version = 2.10 Licence = Freeware Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs. Size = 0.6M Category = 7 URLSite = http://www.scintilla.org/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc203.exe +URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc210.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/scummvm.txt b/base/applications/rapps/rapps/scummvm.txt index 6365b1c1b63..ebe7b348a50 100644 --- a/base/applications/rapps/rapps/scummvm.txt +++ b/base/applications/rapps/rapps/scummvm.txt @@ -2,13 +2,13 @@ [Section] Name = ScummVM -Version = 1.0.0 +Version = 1.1.0 Licence = GPL Description = Sam and Max, Day of the Tentacle, etc on ReactOS. -Size = 3.1MB +Size = 3.4MB Category = 4 URLSite = http://scummvm.org/ -URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.0.0/scummvm-1.0.0-win32.exe +URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.1.0/scummvm-1.1.0-win32.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/seamonkey.txt b/base/applications/rapps/rapps/seamonkey.txt index 9c980d30b65..55d3be87f2f 100644 --- a/base/applications/rapps/rapps/seamonkey.txt +++ b/base/applications/rapps/rapps/seamonkey.txt @@ -2,31 +2,31 @@ [Section] Name = Mozilla SeaMonkey -Version = 2.0.3 +Version = 2.0.4 Licence = MPL/GPL/LGPL Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need. -Size = 10.0MB +Size = 10.1MB Category = 5 URLSite = http://www.seamonkey-project.org/ -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/en-US/SeaMonkey%20Setup%202.0.3.exe +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/en-US/SeaMonkey%20Setup%202.0.4.exe CDPath = none [Section.0407] Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen. -Size = 10.1MB -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/de/SeaMonkey%20Setup%202.0.3.exe +Size = 10.0MB +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/de/SeaMonkey%20Setup%202.0.4.exe [Section.040a] Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás. Size = 10.0MB -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/es-ES/SeaMonkey%20Setup%202.0.3.exe +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/es-ES/SeaMonkey%20Setup%202.0.4.exe [Section.0415] Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz. Size = 10.8MB -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/pl/SeaMonkey%20Setup%202.0.3.exe +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/pl/SeaMonkey%20Setup%202.0.4.exe [Section.0419] Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор. Size = 10.4MB -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.3/win32/ru/SeaMonkey%20Setup%202.0.3.exe +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0.4/win32/ru/SeaMonkey%20Setup%202.0.4.exe diff --git a/base/applications/rapps/rapps/thunderbird.txt b/base/applications/rapps/rapps/thunderbird.txt index 9f0cd328d89..a9e837cd7e0 100644 --- a/base/applications/rapps/rapps/thunderbird.txt +++ b/base/applications/rapps/rapps/thunderbird.txt @@ -2,35 +2,35 @@ [Section] Name = Mozilla Thunderbird -Version = 3.0.3 +Version = 3.0.4 Licence = MPL/GPL/LGPL Description = The most popular and one of the best free Mail Clients out there. Size = 8.6M Category = 5 URLSite = http://www.mozilla-europe.org/en/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/en-US/Thunderbird%20Setup%203.0.3.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/en-US/Thunderbird%20Setup%203.0.4.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Mail-Clients. -Size = 8.4M +Size = 8.5M URLSite = http://www.mozilla-europe.org/de/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/de/Thunderbird%20Setup%203.0.3.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/de/Thunderbird%20Setup%203.0.4.exe [Section.040a] Description = El más popular y uno de los mejores clientes mail que hay. Size = 8.4M URLSite = http://www.mozilla-europe.org/es/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/es-ES/Thunderbird%20Setup%203.0.3.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/es-ES/Thunderbird%20Setup%203.0.4.exe [Section.0415] Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty. Size = 9.3M URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/pl/Thunderbird%20Setup%203.0.3.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/pl/Thunderbird%20Setup%203.0.4.exe [Section.0419] Description = Один из самых популярных и лучших бесплатных почтовых клиентов. Size = 8.8M URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.3/win32/ru/Thunderbird%20Setup%203.0.3.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/ru/Thunderbird%20Setup%203.0.4.exe diff --git a/base/applications/taskmgr/applpage.c b/base/applications/taskmgr/applpage.c index 3ef6ee9394d..0c20e810817 100644 --- a/base/applications/taskmgr/applpage.c +++ b/base/applications/taskmgr/applpage.c @@ -49,7 +49,7 @@ void ApplicationPageOnNotify(WPARAM wParam, LPARAM lParam); void ApplicationPageShowContextMenu1(void); void ApplicationPageShowContextMenu2(void); int CALLBACK ApplicationPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); -int PerfGetIndexByProcessId(DWORD dwProcessId); +int ProcGetIndexByProcessId(DWORD dwProcessId); #if 0 void SwitchToThisWindow ( @@ -236,6 +236,13 @@ void UpdateApplicationListControlViewSetting(void) DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter) { + INT i; + BOOL bItemRemoved = FALSE; + LV_ITEM item; + LPAPPLICATION_PAGE_LIST_ITEM pAPLI = NULL; + HIMAGELIST hImageListLarge; + HIMAGELIST hImageListSmall; + /* Create the event */ hApplicationPageEvent = CreateEventW(NULL, TRUE, TRUE, NULL); @@ -269,6 +276,55 @@ DWORD WINAPI ApplicationPageRefreshThread(void *lpParameter) EnumWindows(EnumWindowsProc, 0); if (noApps) (void)ListView_DeleteAllItems(hApplicationPageListCtrl); + + /* Get the image lists */ + hImageListLarge = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_NORMAL); + hImageListSmall = ListView_GetImageList(hApplicationPageListCtrl, LVSIL_SMALL); + + /* Check to see if we need to remove any items from the list */ + for (i=ListView_GetItemCount(hApplicationPageListCtrl)-1; i>=0; i--) + { + memset(&item, 0, sizeof(LV_ITEM)); + item.mask = LVIF_IMAGE|LVIF_PARAM; + item.iItem = i; + (void)ListView_GetItem(hApplicationPageListCtrl, &item); + + pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; + if (!IsWindow(pAPLI->hWnd)|| + (wcslen(pAPLI->szTitle) <= 0) || + !IsWindowVisible(pAPLI->hWnd) || + (GetParent(pAPLI->hWnd) != NULL) || + (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) || + (GetWindowLongPtr(pAPLI->hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) + { + ImageList_Remove(hImageListLarge, item.iItem); + ImageList_Remove(hImageListSmall, item.iItem); + + (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem); + HeapFree(GetProcessHeap(), 0, pAPLI); + bItemRemoved = TRUE; + } + } + + /* + * If an item was removed from the list then + * we need to resync all the items with the + * image list + */ + if (bItemRemoved) + { + for (i=0; i=0; i--) - { - memset(&item, 0, sizeof(LV_ITEM)); - item.mask = LVIF_IMAGE|LVIF_PARAM; - item.iItem = i; - (void)ListView_GetItem(hApplicationPageListCtrl, &item); - - pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)item.lParam; - if (!IsWindow(pAPLI->hWnd)|| - (wcslen(pAPLI->szTitle) <= 0) || - !IsWindowVisible(pAPLI->hWnd) || - (GetParent(pAPLI->hWnd) != NULL) || - (GetWindow(pAPLI->hWnd, GW_OWNER) != NULL) || - (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) - { - ImageList_Remove(hImageListLarge, item.iItem); - ImageList_Remove(hImageListSmall, item.iItem); - - (void)ListView_DeleteItem(hApplicationPageListCtrl, item.iItem); - HeapFree(GetProcessHeap(), 0, pAPLI); - bItemRemoved = TRUE; - } - } - - /* - * If an item was removed from the list then - * we need to resync all the items with the - * image list - */ - if (bItemRemoved) - { - for (i=0; iFlink; + HeapFree(GetProcessHeap(), 0, pEntry); + } } static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize) @@ -86,6 +106,56 @@ static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize) LookupAccountSidW(NULL, Sid, szBuffer, &BufferSize, szDomainNameUnused, &DomainNameLen, &Use); } +VOID +WINAPI +CachedGetUserFromSid( + PSID pSid, + LPWSTR pUserName, + PULONG pcwcUserName) +{ + PLIST_ENTRY pCur; + PSIDTOUSERNAME pEntry; + ULONG cbSid, cwcUserName; + + cwcUserName = *pcwcUserName; + + /* Walk through the list */ + for(pCur = SidToUserNameHead.Flink; + pCur != &SidToUserNameHead; + pCur = pCur->Flink) + { + pEntry = CONTAINING_RECORD(pCur, SIDTOUSERNAME, List); + if (EqualSid((PSID)&pEntry->Data, pSid)) + { + wcsncpy(pUserName, pEntry->pszName, cwcUserName); + *pcwcUserName = cwcUserName; + return; + } + } + + /* We didn't find the SID in the list, get the name conventional */ + SidToUserName(pSid, pUserName, cwcUserName); + + /* Allocate a new entry */ + *pcwcUserName = wcslen(pUserName); + cwcUserName = *pcwcUserName + 1; + cbSid = GetLengthSid(pSid); + pEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(SIDTOUSERNAME) + cbSid + cwcUserName * sizeof(WCHAR)); + + /* Copy the Sid and name to our entry */ + CopySid(cbSid, (PSID)&pEntry->Data, pSid); + pEntry->pszName = (LPWSTR)(pEntry->Data + cbSid); + wcsncpy(pEntry->pszName, pUserName, cwcUserName); + + /* Insert the new entry */ + pEntry->List.Flink = &SidToUserNameHead; + pEntry->List.Blink = SidToUserNameHead.Blink; + SidToUserNameHead.Blink->Flink = &pEntry->List; + SidToUserNameHead.Blink = &pEntry->List; + + return; +} + void PerfDataRefresh(void) { ULONG ulSize; @@ -106,6 +176,7 @@ void PerfDataRefresh(void) PSECURITY_DESCRIPTOR ProcessSD; PSID ProcessUser; ULONG Buffer[64]; /* must be 4 bytes aligned! */ + ULONG cwcUserName; /* Get new system time */ status = NtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); @@ -341,7 +412,8 @@ ClearInfo: ZeroMemory(&pPerfData[Idx].IOCounters, sizeof(IO_COUNTERS)); } - SidToUserName(ProcessUser, pPerfData[Idx].UserName, sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0])); + cwcUserName = sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]); + CachedGetUserFromSid(ProcessUser, pPerfData[Idx].UserName, &cwcUserName); if (ProcessSD != NULL) { @@ -356,6 +428,29 @@ ClearInfo: LeaveCriticalSection(&PerfDataCriticalSection); } +ULONG PerfDataGetProcessIndex(ULONG pid) +{ + ULONG idx; + + EnterCriticalSection(&PerfDataCriticalSection); + + for (idx = 0; idx < ProcessCount; idx++) + { + if (PtrToUlong(pPerfData[idx].ProcessId) == pid) + { + break; + } + } + + LeaveCriticalSection(&PerfDataCriticalSection); + + if (idx == ProcessCount) + { + return -1; + } + return idx; +} + ULONG PerfDataGetProcessCount(void) { return ProcessCount; @@ -387,27 +482,6 @@ BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount) return bSuccessful; } -int PerfGetIndexByProcessId(DWORD dwProcessId) -{ - int FoundIndex = -1; - ULONG Index; - - EnterCriticalSection(&PerfDataCriticalSection); - - for (Index = 0; Index < ProcessCount; Index++) - { - if (PtrToUlong(pPerfData[Index].ProcessId) == dwProcessId) - { - FoundIndex = Index; - break; - } - } - - LeaveCriticalSection(&PerfDataCriticalSection); - - return FoundIndex; -} - ULONG PerfDataGetProcessId(ULONG Index) { ULONG ProcessId; diff --git a/base/applications/taskmgr/perfdata.h b/base/applications/taskmgr/perfdata.h index 00c2d6dc21a..6bb7005ceaa 100644 --- a/base/applications/taskmgr/perfdata.h +++ b/base/applications/taskmgr/perfdata.h @@ -60,6 +60,7 @@ void PerfDataUninitialize(void); void PerfDataRefresh(void); BOOL PerfDataGet(ULONG Index, PPERFDATA *lppData); +ULONG PerfDataGetProcessIndex(ULONG pid); ULONG PerfDataGetProcessCount(void); ULONG PerfDataGetProcessorUsage(void); ULONG PerfDataGetProcessorSystemUsage(void); diff --git a/base/applications/taskmgr/procpage.c b/base/applications/taskmgr/procpage.c index 4c3b636b91a..42bf5949ea7 100644 --- a/base/applications/taskmgr/procpage.c +++ b/base/applications/taskmgr/procpage.c @@ -28,7 +28,6 @@ typedef struct { - ULONG Index; ULONG ProcessId; } PROCESS_PAGE_LIST_ITEM, *LPPROCESS_PAGE_LIST_ITEM; @@ -54,6 +53,27 @@ BOOL PerfDataGetText(ULONG Index, ULONG ColumnIndex, LPTSTR lpText, int nMaxCoun DWORD WINAPI ProcessPageRefreshThread(void *lpParameter); int ProcessRunning(ULONG ProcessId); +int ProcGetIndexByProcessId(DWORD dwProcessId) +{ + int i; + LVITEM item; + LPPROCESS_PAGE_LIST_ITEM pData; + + for (i=0; iProcessId == dwProcessId) + { + return i; + } + } + return 0; +} + DWORD GetSelectedProcessId(void) { int Index; @@ -71,7 +91,7 @@ DWORD GetSelectedProcessId(void) (void)ListView_GetItem(hProcessPageListCtrl, &lvitem); if (lvitem.lParam) - return PerfDataGetProcessId(((LPPROCESS_PAGE_LIST_ITEM)lvitem.lParam)->Index); + return ((LPPROCESS_PAGE_LIST_ITEM)lvitem.lParam)->ProcessId; } return 0; @@ -219,7 +239,7 @@ void ProcessPageOnNotify(WPARAM wParam, LPARAM lParam) break; pData = (LPPROCESS_PAGE_LIST_ITEM)pnmdi->item.lParam; - Index = pData->Index; + Index = PerfDataGetProcessIndex(pData->ProcessId); ColumnIndex = pnmdi->item.iSubItem; PerfDataGetText(Index, ColumnIndex, pnmdi->item.pszText, pnmdi->item.cchTextMax); @@ -414,7 +434,7 @@ void UpdateProcesses() { int i; ULONG l; - LV_ITEM item; + LV_ITEM item; LPPROCESS_PAGE_LIST_ITEM pData; /* Remove old processes */ @@ -431,10 +451,17 @@ void UpdateProcesses() HeapFree(GetProcessHeap(), 0, pData); } } - for (l = 0; l < PerfDataGetProcessCount(); l++) + + /* Check for difference in listview process and performance process counts */ + if (ListView_GetItemCount(hProcessPageListCtrl) != PerfDataGetProcessCount()) { - AddProcess(l); + /* Add new processes by checking against the current items */ + for (l = 0; l < PerfDataGetProcessCount(); l++) + { + AddProcess(l); + } } + if (TaskManagerSettings.SortColumn != -1) { (void)ListView_SortItems(hProcessPageListCtrl, ProcessPageCompareFunc, NULL); @@ -482,7 +509,7 @@ void AddProcess(ULONG Index) item.iItem = i; (void)ListView_GetItem(hProcessPageListCtrl, &item); pData = (LPPROCESS_PAGE_LIST_ITEM)item.lParam; - if (PerfDataGetProcessId(pData->Index) == pid) + if (pData->ProcessId == pid) { bAlreadyInList = TRUE; break; @@ -491,7 +518,6 @@ void AddProcess(ULONG Index) if (!bAlreadyInList) /* Add */ { pData = (LPPROCESS_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM)); - pData->Index = Index; pData->ProcessId = pid; /* Add the item to the list */ @@ -686,6 +712,8 @@ int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lPara int ret = 0; LPPROCESS_PAGE_LIST_ITEM Param1; LPPROCESS_PAGE_LIST_ITEM Param2; + ULONG IndexParam1; + ULONG IndexParam2; WCHAR text1[260]; WCHAR text2[260]; ULONG l1; @@ -704,165 +732,167 @@ int CALLBACK ProcessPageCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lPara Param1 = (LPPROCESS_PAGE_LIST_ITEM)lParam2; Param2 = (LPPROCESS_PAGE_LIST_ITEM)lParam1; } + IndexParam1 = PerfDataGetProcessIndex(Param1->ProcessId); + IndexParam2 = PerfDataGetProcessIndex(Param2->ProcessId); if (TaskManagerSettings.SortColumn == COLUMN_IMAGENAME) { - PerfDataGetImageName(Param1->Index, text1, sizeof (text1) / sizeof (*text1)); - PerfDataGetImageName(Param2->Index, text2, sizeof (text2) / sizeof (*text2)); + PerfDataGetImageName(IndexParam1, text1, sizeof (text1) / sizeof (*text1)); + PerfDataGetImageName(IndexParam2, text2, sizeof (text2) / sizeof (*text2)); ret = _wcsicmp(text1, text2); } else if (TaskManagerSettings.SortColumn == COLUMN_PID) { - l1 = PerfDataGetProcessId(Param1->Index); - l2 = PerfDataGetProcessId(Param2->Index); + l1 = Param1->ProcessId; + l2 = Param2->ProcessId; ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_USERNAME) { - PerfDataGetUserName(Param1->Index, text1, sizeof (text1) / sizeof (*text1)); - PerfDataGetUserName(Param2->Index, text2, sizeof (text2) / sizeof (*text2)); + PerfDataGetUserName(IndexParam1, text1, sizeof (text1) / sizeof (*text1)); + PerfDataGetUserName(IndexParam2, text2, sizeof (text2) / sizeof (*text2)); ret = _wcsicmp(text1, text2); } else if (TaskManagerSettings.SortColumn == COLUMN_SESSIONID) { - l1 = PerfDataGetSessionId(Param1->Index); - l2 = PerfDataGetSessionId(Param2->Index); + l1 = PerfDataGetSessionId(IndexParam1); + l2 = PerfDataGetSessionId(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_CPUUSAGE) { - l1 = PerfDataGetCPUUsage(Param1->Index); - l2 = PerfDataGetCPUUsage(Param2->Index); + l1 = PerfDataGetCPUUsage(IndexParam1); + l2 = PerfDataGetCPUUsage(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_CPUTIME) { - time1 = PerfDataGetCPUTime(Param1->Index); - time2 = PerfDataGetCPUTime(Param2->Index); + time1 = PerfDataGetCPUTime(IndexParam1); + time2 = PerfDataGetCPUTime(IndexParam2); ret = largeintcmp(time1, time2); } else if (TaskManagerSettings.SortColumn == COLUMN_MEMORYUSAGE) { - l1 = PerfDataGetWorkingSetSizeBytes(Param1->Index); - l2 = PerfDataGetWorkingSetSizeBytes(Param2->Index); + l1 = PerfDataGetWorkingSetSizeBytes(IndexParam1); + l2 = PerfDataGetWorkingSetSizeBytes(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_PEAKMEMORYUSAGE) { - l1 = PerfDataGetPeakWorkingSetSizeBytes(Param1->Index); - l2 = PerfDataGetPeakWorkingSetSizeBytes(Param2->Index); + l1 = PerfDataGetPeakWorkingSetSizeBytes(IndexParam1); + l2 = PerfDataGetPeakWorkingSetSizeBytes(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_MEMORYUSAGEDELTA) { - l1 = PerfDataGetWorkingSetSizeDelta(Param1->Index); - l2 = PerfDataGetWorkingSetSizeDelta(Param2->Index); + l1 = PerfDataGetWorkingSetSizeDelta(IndexParam1); + l2 = PerfDataGetWorkingSetSizeDelta(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_PAGEFAULTS) { - l1 = PerfDataGetPageFaultCount(Param1->Index); - l2 = PerfDataGetPageFaultCount(Param2->Index); + l1 = PerfDataGetPageFaultCount(IndexParam1); + l2 = PerfDataGetPageFaultCount(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_PAGEFAULTSDELTA) { - l1 = PerfDataGetPageFaultCountDelta(Param1->Index); - l2 = PerfDataGetPageFaultCountDelta(Param2->Index); + l1 = PerfDataGetPageFaultCountDelta(IndexParam1); + l2 = PerfDataGetPageFaultCountDelta(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_VIRTUALMEMORYSIZE) { - l1 = PerfDataGetVirtualMemorySizeBytes(Param1->Index); - l2 = PerfDataGetVirtualMemorySizeBytes(Param2->Index); + l1 = PerfDataGetVirtualMemorySizeBytes(IndexParam1); + l2 = PerfDataGetVirtualMemorySizeBytes(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_PAGEDPOOL) { - l1 = PerfDataGetPagedPoolUsagePages(Param1->Index); - l2 = PerfDataGetPagedPoolUsagePages(Param2->Index); + l1 = PerfDataGetPagedPoolUsagePages(IndexParam1); + l2 = PerfDataGetPagedPoolUsagePages(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_NONPAGEDPOOL) { - l1 = PerfDataGetNonPagedPoolUsagePages(Param1->Index); - l2 = PerfDataGetNonPagedPoolUsagePages(Param2->Index); + l1 = PerfDataGetNonPagedPoolUsagePages(IndexParam1); + l2 = PerfDataGetNonPagedPoolUsagePages(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_BASEPRIORITY) { - l1 = PerfDataGetBasePriority(Param1->Index); - l2 = PerfDataGetBasePriority(Param2->Index); + l1 = PerfDataGetBasePriority(IndexParam1); + l2 = PerfDataGetBasePriority(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_HANDLECOUNT) { - l1 = PerfDataGetHandleCount(Param1->Index); - l2 = PerfDataGetHandleCount(Param2->Index); + l1 = PerfDataGetHandleCount(IndexParam1); + l2 = PerfDataGetHandleCount(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_THREADCOUNT) { - l1 = PerfDataGetThreadCount(Param1->Index); - l2 = PerfDataGetThreadCount(Param2->Index); + l1 = PerfDataGetThreadCount(IndexParam1); + l2 = PerfDataGetThreadCount(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_USEROBJECTS) { - l1 = PerfDataGetUSERObjectCount(Param1->Index); - l2 = PerfDataGetUSERObjectCount(Param2->Index); + l1 = PerfDataGetUSERObjectCount(IndexParam1); + l2 = PerfDataGetUSERObjectCount(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_GDIOBJECTS) { - l1 = PerfDataGetGDIObjectCount(Param1->Index); - l2 = PerfDataGetGDIObjectCount(Param2->Index); + l1 = PerfDataGetGDIObjectCount(IndexParam1); + l2 = PerfDataGetGDIObjectCount(IndexParam2); ret = CMP(l1, l2); } else if (TaskManagerSettings.SortColumn == COLUMN_IOREADS) { - PerfDataGetIOCounters(Param1->Index, &iocounters1); - PerfDataGetIOCounters(Param2->Index, &iocounters2); + PerfDataGetIOCounters(IndexParam1, &iocounters1); + PerfDataGetIOCounters(IndexParam2, &iocounters2); ull1 = iocounters1.ReadOperationCount; ull2 = iocounters2.ReadOperationCount; ret = CMP(ull1, ull2); } else if (TaskManagerSettings.SortColumn == COLUMN_IOWRITES) { - PerfDataGetIOCounters(Param1->Index, &iocounters1); - PerfDataGetIOCounters(Param2->Index, &iocounters2); + PerfDataGetIOCounters(IndexParam1, &iocounters1); + PerfDataGetIOCounters(IndexParam2, &iocounters2); ull1 = iocounters1.WriteOperationCount; ull2 = iocounters2.WriteOperationCount; ret = CMP(ull1, ull2); } else if (TaskManagerSettings.SortColumn == COLUMN_IOOTHER) { - PerfDataGetIOCounters(Param1->Index, &iocounters1); - PerfDataGetIOCounters(Param2->Index, &iocounters2); + PerfDataGetIOCounters(IndexParam1, &iocounters1); + PerfDataGetIOCounters(IndexParam2, &iocounters2); ull1 = iocounters1.OtherOperationCount; ull2 = iocounters2.OtherOperationCount; ret = CMP(ull1, ull2); } else if (TaskManagerSettings.SortColumn == COLUMN_IOREADBYTES) { - PerfDataGetIOCounters(Param1->Index, &iocounters1); - PerfDataGetIOCounters(Param2->Index, &iocounters2); + PerfDataGetIOCounters(IndexParam1, &iocounters1); + PerfDataGetIOCounters(IndexParam2, &iocounters2); ull1 = iocounters1.ReadTransferCount; ull2 = iocounters2.ReadTransferCount; ret = CMP(ull1, ull2); } else if (TaskManagerSettings.SortColumn == COLUMN_IOWRITEBYTES) { - PerfDataGetIOCounters(Param1->Index, &iocounters1); - PerfDataGetIOCounters(Param2->Index, &iocounters2); + PerfDataGetIOCounters(IndexParam1, &iocounters1); + PerfDataGetIOCounters(IndexParam2, &iocounters2); ull1 = iocounters1.WriteTransferCount; ull2 = iocounters2.WriteTransferCount; ret = CMP(ull1, ull2); } else if (TaskManagerSettings.SortColumn == COLUMN_IOOTHERBYTES) { - PerfDataGetIOCounters(Param1->Index, &iocounters1); - PerfDataGetIOCounters(Param2->Index, &iocounters2); + PerfDataGetIOCounters(IndexParam1, &iocounters1); + PerfDataGetIOCounters(IndexParam2, &iocounters2); ull1 = iocounters1.OtherTransferCount; ull2 = iocounters2.OtherTransferCount; ret = CMP(ull1, ull2); diff --git a/base/applications/taskmgr/taskmgr.c b/base/applications/taskmgr/taskmgr.c index 3f8bcbd9a4a..c409f808b1f 100644 --- a/base/applications/taskmgr/taskmgr.c +++ b/base/applications/taskmgr/taskmgr.c @@ -869,6 +869,7 @@ void TaskManager_OnTabWndSelChange(void) HMENU hViewMenu; HMENU hSubMenu; WCHAR szTemp[256]; + SYSTEM_INFO sysInfo; hMenu = GetMenu(hMainWnd); hViewMenu = GetSubMenu(hMenu, 2); @@ -947,16 +948,28 @@ void TaskManager_OnTabWndSelChange(void) DeleteMenu(hMenu, 3, MF_BYPOSITION); DrawMenuBar(hMainWnd); } - hSubMenu = CreatePopupMenu(); - LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256); - AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp); + GetSystemInfo(&sysInfo); - LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256); - AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp); + /* Hide CPU graph options on single CPU systems */ + if (sysInfo.dwNumberOfProcessors > 1) + { + hSubMenu = CreatePopupMenu(); - LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256); - AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp); + LoadStringW(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256); + AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp); + + LoadStringW(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256); + AppendMenuW(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp); + + LoadStringW(hInst, IDS_MENU_CPUHISTORY, szTemp, 256); + AppendMenuW(hViewMenu, MF_STRING|MF_POPUP, (UINT_PTR) hSubMenu, szTemp); + + if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) + CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); + else + CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); + } LoadStringW(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256); AppendMenuW(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp); @@ -965,10 +978,7 @@ void TaskManager_OnTabWndSelChange(void) CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED); else CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_UNCHECKED); - if (TaskManagerSettings.CPUHistory_OneGraphPerCPU) - CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, MF_BYCOMMAND); - else - CheckMenuRadioItem(hSubMenu, ID_VIEW_CPUHISTORY_ONEGRAPHALL, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, ID_VIEW_CPUHISTORY_ONEGRAPHALL, MF_BYCOMMAND); + /* * Give the tab control focus */ diff --git a/base/applications/winhlp32/hlpfile.c b/base/applications/winhlp32/hlpfile.c index 2d685ae493a..7031c760670 100644 --- a/base/applications/winhlp32/hlpfile.c +++ b/base/applications/winhlp32/hlpfile.c @@ -492,7 +492,7 @@ static int comp_FindSubFile(void *p, const void *key, int leaf, void** next) { *next = (char *)p+strlen(p)+(leaf?5:3); - WINE_TRACE("Comparing '%s' with '%s'\n", (char *)p, (char *)key); + WINE_TRACE("Comparing '%s' with '%s'\n", (char *)p, (const char *)key); return strcmp(p, key); } @@ -1601,7 +1601,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, struct RtfData* rd, case 0xEE: case 0xEF: { - char* ptr = (char*) format + 8; + const char* ptr = (const char*) format + 8; BYTE type = format[3]; int wnd = -1; diff --git a/base/applications/winver/winver.rbuild b/base/applications/winver/winver.rbuild index 89ff51c8ce4..4f24a7166bd 100644 --- a/base/applications/winver/winver.rbuild +++ b/base/applications/winver/winver.rbuild @@ -1,3 +1,5 @@ + + . shell32 diff --git a/base/services/rpcss/rpcss.rbuild b/base/services/rpcss/rpcss.rbuild index 04e42f81de9..95b29e83210 100644 --- a/base/services/rpcss/rpcss.rbuild +++ b/base/services/rpcss/rpcss.rbuild @@ -1,5 +1,5 @@ - + . diff --git a/base/services/telnetd/telnetd.rbuild b/base/services/telnetd/telnetd.rbuild index 8ccb81d2004..1b17bfcb83f 100644 --- a/base/services/telnetd/telnetd.rbuild +++ b/base/services/telnetd/telnetd.rbuild @@ -1,3 +1,5 @@ + + .. diff --git a/base/services/tftpd/tftpd.rbuild b/base/services/tftpd/tftpd.rbuild index be34bb7f3ab..0008cfb287e 100644 --- a/base/services/tftpd/tftpd.rbuild +++ b/base/services/tftpd/tftpd.rbuild @@ -1,11 +1,11 @@ + + .. - ntdll advapi32 ws2_32 wine - tftpd.cpp diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c index fe835ff5a1e..7abbcb1f4a0 100644 --- a/base/setup/usetup/bootsup.c +++ b/base/setup/usetup/bootsup.c @@ -428,7 +428,7 @@ CreateFreeLoaderIniForReactos(PWCHAR IniPath, /* ReactOS_KdSerial */ CreateFreeLoaderEntry(IniCache, IniSection, L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"", - L"ReactOS", ArcPath, + L"Windows2003", ArcPath, L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"); /* ReactOS_LogFile */ diff --git a/base/setup/vmwinst/vmwinst.c b/base/setup/vmwinst/vmwinst.c index 8f513033ec3..e53860cc9d2 100644 --- a/base/setup/vmwinst/vmwinst.c +++ b/base/setup/vmwinst/vmwinst.c @@ -111,7 +111,7 @@ DetectVMware(int *Version) /* try to open the file */ static BOOL -FileExists(WCHAR *Path, WCHAR *File) +DoesFileExist(WCHAR *Path, WCHAR *File) { WCHAR FileName[MAX_PATH + 1]; HANDLE FileHandle; @@ -195,9 +195,9 @@ IsVMwareCDInDrive(WCHAR *Drv) continue; } - if(FileExists(SrcPath, vmx_fb) && - (FileExists(SrcPath, vmx_mode) || FileExists(SrcPath, vmx_mode_v6)) && - FileExists(SrcPath, vmx_svga)) + if(DoesFileExist(SrcPath, vmx_fb) && + (DoesFileExist(SrcPath, vmx_mode) || DoesFileExist(SrcPath, vmx_mode_v6)) && + DoesFileExist(SrcPath, vmx_svga)) { *Drv = Current; return TRUE; @@ -1070,9 +1070,9 @@ wWinMain(HINSTANCE hInstance, SetCurrentDirectory(DestinationPath); - DriverFilesFound = FileExists(DestinationPath, vmx_fb) && - FileExists(DestinationPath, vmx_mode) && - FileExists(DestinationDriversPath, vmx_svga); + DriverFilesFound = DoesFileExist(DestinationPath, vmx_fb) && + DoesFileExist(DestinationPath, vmx_mode) && + DoesFileExist(DestinationDriversPath, vmx_svga); StartVMwConfigWizard = DriverFilesFound && IsVmwSVGAEnabled(); diff --git a/base/shell/cmd/console.c b/base/shell/cmd/console.c index 18541bf389f..8184af747ea 100644 --- a/base/shell/cmd/console.c +++ b/base/shell/cmd/console.c @@ -166,7 +166,7 @@ VOID ConOutChar (TCHAR c) VOID ConPuts(LPTSTR szText, DWORD nStdHandle) { ConWrite(szText, _tcslen(szText), nStdHandle); - ConWrite(_T("\n"), 1, nStdHandle); + ConWrite(_T("\r\n"), 2, nStdHandle); } VOID ConOutResPaging(BOOL NewPage, UINT resID) diff --git a/base/shell/cmd/filecomp.c b/base/shell/cmd/filecomp.c index 4ca8b837311..7cb99a72f12 100644 --- a/base/shell/cmd/filecomp.c +++ b/base/shell/cmd/filecomp.c @@ -703,7 +703,7 @@ VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor) LastSpace = i; } - /* insert the quoation and move things around */ + /* insert the quotation and move things around */ if(szPrefix[LastSpace + 1] != _T('\"') && LastSpace != -1) { memmove ( &szPrefix[LastSpace+1], &szPrefix[LastSpace], (_tcslen(szPrefix)-LastSpace+1) * sizeof(TCHAR) ); @@ -712,14 +712,17 @@ VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor) { _tcscat(szPrefix,_T("\"")); } - szPrefix[LastSpace + 1] = _T('\"'); + szPrefix[LastSpace + 1] = _T('\"'); } else if(LastSpace == -1) { - _tcscpy(szBaseWord,_T("\"")); - _tcscat(szBaseWord,szPrefix); - _tcscpy(szPrefix,szBaseWord); - + /* Add quotation only if none exists already */ + if (szPrefix[0] != _T('\"')) + { + _tcscpy(szBaseWord,_T("\"")); + _tcscat(szBaseWord,szPrefix); + _tcscpy(szPrefix,szBaseWord); + } } } diff --git a/base/system/format/format.c b/base/system/format/format.c index 59f9f302a0a..ba9f42b3a05 100755 --- a/base/system/format/format.c +++ b/base/system/format/format.c @@ -363,6 +363,12 @@ _tmain(int argc, TCHAR *argv[]) PrintWin32Error( szMsg, GetLastError()); return -1; } + else if ( driveType == 1 ) + { + LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); + PrintWin32Error( szMsg, GetLastError()); + return -1; + } if( driveType != DRIVE_FIXED ) { LoadString( GetModuleHandle(NULL), STRING_INSERT_DISK, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); diff --git a/base/system/runonce/runonce.rbuild b/base/system/runonce/runonce.rbuild index 950580d56ad..9dba7660b1c 100644 --- a/base/system/runonce/runonce.rbuild +++ b/base/system/runonce/runonce.rbuild @@ -1,3 +1,5 @@ + + . advapi32 diff --git a/boot/bootdata/bootcd/bootcd.rbuild b/boot/bootdata/bootcd/bootcd.rbuild index 471a7f4863e..f84fa71372b 100644 --- a/boot/bootdata/bootcd/bootcd.rbuild +++ b/boot/bootdata/bootcd/bootcd.rbuild @@ -1,12 +1,14 @@ - + isoboot - isoboot + diff --git a/boot/bootdata/livecd/livecd.rbuild b/boot/bootdata/livecd/livecd.rbuild index e92deca42ce..8a04d1289bc 100644 --- a/boot/bootdata/livecd/livecd.rbuild +++ b/boot/bootdata/livecd/livecd.rbuild @@ -1,12 +1,14 @@ - + isoboot - isoboot + diff --git a/boot/bootdata/packages/reactos.dff b/boot/bootdata/packages/reactos.dff index 895b3fc2fb5..a4d4de2a79b 100644 --- a/boot/bootdata/packages/reactos.dff +++ b/boot/bootdata/packages/reactos.dff @@ -489,8 +489,6 @@ drivers\base\nmidebug\nmidebug.sys 2 drivers\battery\battc\battc.sys 2 -drivers\bus\isapnp\isapnp.sys 2 - drivers\bus\acpi\cmbatt\cmbatt.sys 2 drivers\bus\acpi\compbatt\compbatt.sys 2 diff --git a/boot/bootdata/txtsetup.sif b/boot/bootdata/txtsetup.sif index 7977e447752..35f1c761937 100644 --- a/boot/bootdata/txtsetup.sif +++ b/boot/bootdata/txtsetup.sif @@ -22,6 +22,7 @@ c_1252.nls=,,,,,,,,,,,,2 cdfs.sys=,,,,,,x,,,,,,4 cdrom.sys=,,,,,,x,,,,,,4 class2.sys=,,,,,,x,,,,,,4 +isapnp.sys=,,,,,,,,,,,,4 kdcom.dll=,,,,,,,,,,,,2 disk.sys=,,,,,,x,,,,,,4 floppy.sys=,,,,,,x,,,,,,4 @@ -36,13 +37,16 @@ ramdisk.sys=,,,,,,x,,,,,,4 ext2.sys=,,,,,,x,,,,,,4 [HardwareIdsDatabase] -*PNP0C08 = acpi +;*PNP0A00 = isapnp *PNP0A03 = pci +*PNP0C08 = acpi +;PCI\CC_0601 = isapnp PCI\CC_0604 = pci [BootBusExtenders.Load] acpi = acpi.sys pci = pci.sys +isapnp = isapnp.sys [Cabinets] Cabinet=reactos.cab @@ -76,7 +80,7 @@ hal.dll=,,,,,,,,,,,,2 [Files.pci_mp] ntkrnlmp.exe=,,,,,,,,,,ntoskrnl.exe,,2 -halmp.dll=,,,,,,,,,,hal.dll,,2 +halmps.dll=,,,,,,,,,,hal.dll,,2 [Display] ; = ,,,,, diff --git a/boot/freeldr/freeldr/arch/amd64/arch.S b/boot/freeldr/freeldr/arch/amd64/arch.S index 0f6c257e34a..9def109221c 100644 --- a/boot/freeldr/freeldr/arch/amd64/arch.S +++ b/boot/freeldr/freeldr/arch/amd64/arch.S @@ -21,22 +21,22 @@ RealEntryPoint: mov ss, ax /* checkPoint Charlie - where it all began... */ - mov si, offset _CheckPoint0 + mov si, offset CheckPoint0 call writestr - + /* Setup a real mode stack */ mov sp, stack16 /* Zero BootDrive and BootPartition */ xor eax, eax - mov _BootDrive, eax - mov _BootPartition, eax + mov BootDrive, eax + mov BootPartition, eax /* Store the boot drive */ - mov _BootDrive, dl + mov BootDrive, dl /* Store the boot partition */ - mov _BootPartition, dh + mov BootPartition, dh /* Load the GDT */ lgdt gdtptr @@ -46,13 +46,13 @@ RealEntryPoint: call x86_16_EnableA20 /* checkPoint Charlie - where it all began... */ - mov si, offset _CheckPoint1 + mov si, offset CheckPoint1 call writestr call x86_16_BuildPageTables /* checkPoint Charlie - where it all began... */ - mov si, offset _CheckPoint2 + mov si, offset CheckPoint2 call writestr /* Check if CPU supports CPUID */ @@ -89,26 +89,26 @@ RealEntryPoint: /* X64 Processor */ /* checkPoint Charlie - where it all began... */ - mov si, offset _CheckPoint3 + mov si, offset CheckPoint3 call writestr - jmp _switch64 + jmp switch64 NO_X64_SUPPORT_DETECTED: - mov si, offset _NotAnX64Processor // Loading message + mov si, offset NotAnX64Processor // Loading message call writestr - jmp _fail + jmp fail NO_CPUID_SUPPORT_DETECTED: - mov si, offset _NoCPUIDSupport // Loading message - call writestr + mov si, offset NoCPUIDSupport // Loading message + call writestr -_fail: - jmp _fail +fail: + jmp fail nop nop -_switch64: +switch64: call x86_16_SwitchToLong .code64 @@ -119,7 +119,7 @@ _switch64: /* GO! */ xor rcx, rcx - call _BootMain + call BootMain /* Checkpoint */ // mov ax, LMODE_DS @@ -174,14 +174,14 @@ x86_16_BuildPageTables: push es /* Get segment of pml4 */ - mov eax, offset _pml4_startup + mov eax, offset pml4_startup shr eax, 4 mov es, ax cld xor di, di /* One entry in the PML4 pointing to PDP */ - mov eax, offset _pdp_startup + mov eax, offset pdp_startup or eax, 0x00f stosd /* clear rest */ @@ -190,7 +190,7 @@ x86_16_BuildPageTables: rep stosd /* One entry in the PDP pointing to PD */ - mov eax, offset _pd_startup + mov eax, offset pd_startup or eax, 0x00f stosd /* clear rest */ @@ -268,7 +268,7 @@ x86_16_SwitchToLong: mov eax, 0x00a0 // Set PAE and PGE: 10100000b mov cr4, eax - mov edx, offset _pml4_startup // Point cr3 at PML4 + mov edx, offset pml4_startup // Point cr3 at PML4 mov cr3, edx mov ecx, 0xC0000080 // Specify EFER MSR @@ -405,42 +405,42 @@ gdtptr: .long gdt /* Base Address */ -.global _BootDrive -_BootDrive: +.global BootDrive +BootDrive: .long 0 -.global _BootPartition -_BootPartition: +.global BootPartition +BootPartition: .long 0 -.global _NotAnX64Processor -_NotAnX64Processor: +.global NotAnX64Processor +NotAnX64Processor: .ascii "FreeLoader: No x64-compatible CPU detected! Exiting..." .byte 0x0d, 0x0a, 0 -.global _NoCPUIDSupport -_NoCPUIDSupport: +.global NoCPUIDSupport +NoCPUIDSupport: .ascii "FreeLoader: No CPUID instruction support detected! Exiting..." .byte 0x0d, 0x0a, 0 /////////////////////////// Checkpoint messages /////////////////////////////// -.global _CheckPoint0 -_CheckPoint0: +.global CheckPoint0 +CheckPoint0: .ascii "Starting FreeLoader..." .byte 0x0d, 0x0a, 0 -.global _CheckPoint1 -_CheckPoint1: +.global CheckPoint1 +CheckPoint1: .ascii "FreeLoader[16-bit]: building page tables..." .byte 0x0d, 0x0a, 0 -.global _CheckPoint2 -_CheckPoint2: +.global CheckPoint2 +CheckPoint2: .ascii "FreeLoader[16-bit]: checking CPU for x64 long mode..." .byte 0x0d, 0x0a, 0 -.global _CheckPoint3 -_CheckPoint3: +.global CheckPoint3 +CheckPoint3: .ascii "FreeLoader: Switching to x64 long mode..." .byte 0x0d, 0x0a, 0 diff --git a/boot/freeldr/freeldr/arch/amd64/boot.S b/boot/freeldr/freeldr/arch/amd64/boot.S index ce7bb355c90..eb3ba3c3c64 100644 --- a/boot/freeldr/freeldr/arch/amd64/boot.S +++ b/boot/freeldr/freeldr/arch/amd64/boot.S @@ -24,14 +24,14 @@ #include -EXTERN(_ChainLoadBiosBootSectorCode) +EXTERN(ChainLoadBiosBootSectorCode) .code64 call x86_64_SwitchToReal .code16 /* Set the boot drive */ - mov dl, _BootDrive + mov dl, BootDrive /* Load segment registers */ cli @@ -46,7 +46,7 @@ EXTERN(_ChainLoadBiosBootSectorCode) // ljmpl $0x0000,$0x7C00 jmp 0x7c00:0x0000 -EXTERN(_SoftReboot) +EXTERN(SoftReboot) .code64 call x86_64_SwitchToReal diff --git a/boot/freeldr/freeldr/arch/amd64/drvmap.S b/boot/freeldr/freeldr/arch/amd64/drvmap.S index d6b081ca60b..6871fe0f62d 100644 --- a/boot/freeldr/freeldr/arch/amd64/drvmap.S +++ b/boot/freeldr/freeldr/arch/amd64/drvmap.S @@ -24,7 +24,7 @@ #include -EXTERN(_DriveMapInt13HandlerStart) +EXTERN(DriveMapInt13HandlerStart) Int13Handler: pushw %bp @@ -82,7 +82,7 @@ CallOldInt13Handler: /* Call old int 13h handler with new drive number */ .byte 0x9a /* lcall */ -EXTERN(_DriveMapOldInt13HandlerAddress) +EXTERN(DriveMapOldInt13HandlerAddress) .word 0 .word 0 @@ -105,7 +105,7 @@ CallersFlags: PassedInDriveNumber: .byte 0 -EXTERN(_DriveMapInt13HandlerMapList) +EXTERN(DriveMapInt13HandlerMapList) Int13HandlerMapCount: .byte 0 @@ -129,4 +129,4 @@ Int13HandlerDrive4: Int13HandlerDriveNew4: .byte 0 -EXTERN(_DriveMapInt13HandlerEnd) +EXTERN(DriveMapInt13HandlerEnd) diff --git a/boot/freeldr/freeldr/arch/amd64/i386cpu.S b/boot/freeldr/freeldr/arch/amd64/i386cpu.S index 6dfb91dbf4a..ee3ee6fe256 100644 --- a/boot/freeldr/freeldr/arch/amd64/i386cpu.S +++ b/boot/freeldr/freeldr/arch/amd64/i386cpu.S @@ -33,7 +33,7 @@ * 0x00000400: Found 80486 CPU without CPUID support */ -EXTERN(_CpuidSupported) +EXTERN(CpuidSupported) .code32 pushl %ecx /* save ECX */ @@ -80,7 +80,7 @@ NoCpuid: * VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx); */ -EXTERN(_GetCpuid) +EXTERN(GetCpuid) .code32 pushl %ebp @@ -123,7 +123,7 @@ EXTERN(_GetCpuid) * U64 RDTSC(VOID); */ -EXTERN(_RDTSC) +EXTERN(RDTSC) .code32 rdtsc ret diff --git a/boot/freeldr/freeldr/arch/amd64/i386pnp.S b/boot/freeldr/freeldr/arch/amd64/i386pnp.S index ff0ae71eb1a..19589275bac 100644 --- a/boot/freeldr/freeldr/arch/amd64/i386pnp.S +++ b/boot/freeldr/freeldr/arch/amd64/i386pnp.S @@ -35,7 +35,7 @@ _pnp_bios_entry_point: _pnp_bios_data_segment: .word 0 -EXTERN(_PnpBiosSupported) +EXTERN(PnpBiosSupported) .code64 push rdi @@ -113,7 +113,7 @@ _pnp_node_size: _pnp_node_count: .word 0 -EXTERN(_PnpBiosGetDeviceNodeCount) +EXTERN(PnpBiosGetDeviceNodeCount) .code64 push rbp @@ -182,7 +182,7 @@ _pnp_buffer_offset: _pnp_node_number: .byte 0 -EXTERN(_PnpBiosGetDeviceNode) +EXTERN(PnpBiosGetDeviceNode) .code64 push rbp diff --git a/boot/freeldr/freeldr/arch/amd64/i386trap.S b/boot/freeldr/freeldr/arch/amd64/i386trap.S index 833fcc37104..195bf097cd0 100644 --- a/boot/freeldr/freeldr/arch/amd64/i386trap.S +++ b/boot/freeldr/freeldr/arch/amd64/i386trap.S @@ -273,7 +273,7 @@ i386CommonExceptionHandler: SAVE_CPU_REGS pushl $SCREEN_ATTR - call _MachVideoClearScreen + call MachVideoClearScreen add $4,%esp movl $i386ExceptionHandlerText,%esi @@ -485,7 +485,7 @@ i386PrintChar: pushl $SCREEN_ATTR andl $0xff,%eax pushl %eax - call _MachVideoPutChar + call MachVideoPutChar addl $16,%esp ret diff --git a/boot/freeldr/freeldr/arch/amd64/int386.S b/boot/freeldr/freeldr/arch/amd64/int386.S index 1c1f2dbdf0a..a22e409c61c 100644 --- a/boot/freeldr/freeldr/arch/amd64/int386.S +++ b/boot/freeldr/freeldr/arch/amd64/int386.S @@ -63,7 +63,7 @@ Int386_regsout: /* * int Int386(int ivec, REGS* in, REGS* out); */ -EXTERN(_Int386) +EXTERN(Int386) .code64 /* Get the function parameters */ diff --git a/boot/freeldr/freeldr/arch/amd64/loader.c b/boot/freeldr/freeldr/arch/amd64/loader.c index 9ca6f858644..cad77bf48d6 100644 --- a/boot/freeldr/freeldr/arch/amd64/loader.c +++ b/boot/freeldr/freeldr/arch/amd64/loader.c @@ -39,33 +39,6 @@ EnableA20() /* Already done */ } -void -DumpLoaderBlock() -{ - DbgPrint("LoaderBlock @ %p.\n", &LoaderBlock); - DbgPrint("Flags = 0x%x.\n", LoaderBlock.Flags); - DbgPrint("MemLower = 0x%p.\n", (PVOID)LoaderBlock.MemLower); - DbgPrint("MemHigher = 0x%p.\n", (PVOID)LoaderBlock.MemHigher); - DbgPrint("BootDevice = 0x%x.\n", LoaderBlock.BootDevice); - DbgPrint("CommandLine = %s.\n", LoaderBlock.CommandLine); - DbgPrint("ModsCount = 0x%x.\n", LoaderBlock.ModsCount); - DbgPrint("ModsAddr = 0x%p.\n", LoaderBlock.ModsAddr); - DbgPrint("Syms = 0x%s.\n", LoaderBlock.Syms); - DbgPrint("MmapLength = 0x%x.\n", LoaderBlock.MmapLength); - DbgPrint("MmapAddr = 0x%p.\n", (PVOID)LoaderBlock.MmapAddr); - DbgPrint("RdLength = 0x%x.\n", LoaderBlock.RdLength); - DbgPrint("RdAddr = 0x%p.\n", (PVOID)LoaderBlock.RdAddr); - DbgPrint("DrivesCount = 0x%x.\n", LoaderBlock.DrivesCount); - DbgPrint("DrivesAddr = 0x%p.\n", (PVOID)LoaderBlock.DrivesAddr); - DbgPrint("ConfigTable = 0x%x.\n", LoaderBlock.ConfigTable); - DbgPrint("BootLoaderName = 0x%x.\n", LoaderBlock.BootLoaderName); - DbgPrint("PageDirectoryStart = 0x%p.\n", (PVOID)LoaderBlock.PageDirectoryStart); - DbgPrint("PageDirectoryEnd = 0x%p.\n", (PVOID)LoaderBlock.PageDirectoryEnd); - DbgPrint("KernelBase = 0x%p.\n", (PVOID)LoaderBlock.KernelBase); - DbgPrint("ArchExtra = 0x%p.\n", (PVOID)LoaderBlock.ArchExtra); - -} - /*++ * FrLdrStartup * INTERNAL @@ -86,222 +59,7 @@ VOID NTAPI FrLdrStartup(ULONG Magic) { - /* Disable Interrupts */ - _disable(); - - /* Re-initalize EFLAGS */ - __writeeflags(0); - - /* Initialize the page directory */ - FrLdrSetupPageDirectory(); - - /* Set the new PML4 */ - __writecr3((ULONGLONG)pPML4); - - FrLdrSetupGdtIdt(); - - LoaderBlock.FrLdrDbgPrint = DbgPrint; - -// DumpLoaderBlock(); - - DbgPrint("Jumping to kernel @ %p.\n", KernelEntryPoint); - - /* Jump to Kernel */ - (*KernelEntryPoint)(Magic, &LoaderBlock); - + DbgPrint("ReactOS loader is unsupported! Halting.\n", KernelEntryPoint); + for(;;); } -PPAGE_DIRECTORY_AMD64 -FrLdrGetOrCreatePageDir(PPAGE_DIRECTORY_AMD64 pDir, ULONG Index) -{ - PPAGE_DIRECTORY_AMD64 pSubDir; - - if (!pDir) - return NULL; - - if (!pDir->Pde[Index].Valid) - { - pSubDir = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory); - if (!pSubDir) - return NULL; - RtlZeroMemory(pSubDir, PAGE_SIZE); - pDir->Pde[Index].PageFrameNumber = PtrToPfn(pSubDir); - pDir->Pde[Index].Valid = 1; - pDir->Pde[Index].Write = 1; - } - else - { - pSubDir = (PPAGE_DIRECTORY_AMD64)((ULONGLONG)(pDir->Pde[Index].PageFrameNumber) * PAGE_SIZE); - } - return pSubDir; -} - -BOOLEAN -FrLdrMapSinglePage(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress) -{ - PPAGE_DIRECTORY_AMD64 pDir3, pDir2, pDir1; - ULONG Index; - - pDir3 = FrLdrGetOrCreatePageDir(pPML4, VAtoPXI(VirtualAddress)); - pDir2 = FrLdrGetOrCreatePageDir(pDir3, VAtoPPI(VirtualAddress)); - pDir1 = FrLdrGetOrCreatePageDir(pDir2, VAtoPDI(VirtualAddress)); - - if (!pDir1) - return FALSE; - - Index = VAtoPTI(VirtualAddress); - if (pDir1->Pde[Index].Valid) - { - return FALSE; - } - - pDir1->Pde[Index].Valid = 1; - pDir1->Pde[Index].Write = 1; - pDir1->Pde[Index].PageFrameNumber = PhysicalAddress / PAGE_SIZE; - - return TRUE; -} - -ULONG -FrLdrMapRangeOfPages(ULONGLONG VirtualAddress, ULONGLONG PhysicalAddress, ULONG cPages) -{ - ULONG i; - - for (i = 0; i < cPages; i++) - { - if (!FrLdrMapSinglePage(VirtualAddress, PhysicalAddress)) - { - return i; - } - VirtualAddress += PAGE_SIZE; - PhysicalAddress += PAGE_SIZE; - } - return i; -} - - -/*++ - * FrLdrSetupPageDirectory - * INTERNAL - * - * Sets up the ReactOS Startup Page Directory. - * - * Params: - * None. - * - * Returns: - * None. - *--*/ -VOID -FASTCALL -FrLdrSetupPageDirectory(VOID) -{ - ULONG KernelPages; - PVOID UserSharedData; - - /* Allocate a Page for the PML4 */ - pPML4 = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory); - - ASSERT(pPML4); - - /* The page tables are located at 0xfffff68000000000 - * We create a recursive self mapping through all 4 levels at - * virtual address 0xfffff6fb7dbedf68 */ - pPML4->Pde[VAtoPXI(PXE_BASE)].Valid = 1; - pPML4->Pde[VAtoPXI(PXE_BASE)].Write = 1; - pPML4->Pde[VAtoPXI(PXE_BASE)].PageFrameNumber = PtrToPfn(pPML4); - - /* Setup low memory pages */ - if (FrLdrMapRangeOfPages(0, 0, 1024) < 1024) - { - DbgPrint("Could not map low memory pages.\n"); - } - - /* Setup kernel pages */ - KernelPages = (ROUND_TO_PAGES(NextModuleBase - KERNEL_BASE_PHYS) / PAGE_SIZE); - if (FrLdrMapRangeOfPages(KernelBase, KERNEL_BASE_PHYS, KernelPages) != KernelPages) - { - DbgPrint("Could not map %d kernel pages.\n", KernelPages); - } - - /* Setup a page for the idt */ - pIdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory); - IdtBase = KernelBase + KernelPages * PAGE_SIZE; - if (!FrLdrMapSinglePage(IdtBase, (ULONGLONG)pIdt)) - { - DbgPrint("Could not map idt page.\n", KernelPages); - } - - /* Setup a page for the gdt & tss */ - pGdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory); - GdtBase = IdtBase + PAGE_SIZE; - TssBase = GdtBase + 20 * sizeof(ULONG64); // FIXME: don't hardcode - if (!FrLdrMapSinglePage(GdtBase, (ULONGLONG)pGdt)) - { - DbgPrint("Could not map gdt page.\n", KernelPages); - } - - /* Setup KUSER_SHARED_DATA page */ - UserSharedData = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory); - if (!FrLdrMapSinglePage(KI_USER_SHARED_DATA, (ULONG64)UserSharedData)) - { - DbgPrint("Could not map KUSER_SHARED_DATA page.\n", KernelPages); - } - - /* Map APIC page */ - if (!FrLdrMapSinglePage(APIC_BASE, APIC_PHYS_BASE)) - { - DbgPrint("Could not map APIC page.\n"); - } - -} - -VOID -FrLdrSetupGdtIdt() -{ - PKGDTENTRY64 Entry; - KDESCRIPTOR Desc; - - RtlZeroMemory(pGdt, PAGE_SIZE); - - /* Setup KGDT_64_R0_CODE */ - Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_CODE); - *(PULONG64)Entry = 0x00209b0000000000ULL; - - /* Setup KGDT_64_R0_SS */ - Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_SS); - *(PULONG64)Entry = 0x00cf93000000ffffULL; - - /* Setup KGDT_64_DATA */ - Entry = KiGetGdtEntry(pGdt, KGDT_64_DATA); - *(PULONG64)Entry = 0x00cff3000000ffffULL; - - /* Setup KGDT_64_R3_CODE */ - Entry = KiGetGdtEntry(pGdt, KGDT_64_R3_CODE); - *(PULONG64)Entry = 0x0020fb0000000000ULL; - - /* Setup KGDT_32_R3_TEB */ - Entry = KiGetGdtEntry(pGdt, KGDT_32_R3_TEB); - *(PULONG64)Entry = 0xff40f3fd50003c00ULL; - - /* Setup TSS entry */ - Entry = KiGetGdtEntry(pGdt, KGDT_TSS); - KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0); - - /* Setup the gdt descriptor */ - Desc.Limit = 12 * sizeof(ULONG64) - 1; - Desc.Base = (PVOID)GdtBase; - - /* Set the new Gdt */ - __lgdt(&Desc.Limit); - DbgPrint("Gdtr.Base = %p\n", Desc.Base); - - /* Setup the idt descriptor */ - Desc.Limit = 12 * sizeof(ULONG64) - 1; - Desc.Base = (PVOID)IdtBase; - - /* Set the new Idt */ - __lidt(&Desc.Limit); - DbgPrint("Idtr.Base = %p\n", Desc.Base); - -} diff --git a/boot/freeldr/freeldr/arch/amd64/mb.S b/boot/freeldr/freeldr/arch/amd64/mb.S index 368338ed33b..2d515e90053 100644 --- a/boot/freeldr/freeldr/arch/amd64/mb.S +++ b/boot/freeldr/freeldr/arch/amd64/mb.S @@ -29,35 +29,35 @@ * This boots the kernel */ .code64 - .globl _PageDirectoryStart + .globl PageDirectoryStart - .globl _pml4_startup - .globl _pdp_startup - .globl _pd_startup + .globl pml4_startup + .globl pdp_startup + .globl pd_startup - .globl _PageDirectoryEnd + .globl PageDirectoryEnd // // Boot information structure // -EXTERN(_reactos_memory_map_descriptor_size) +EXTERN(reactos_memory_map_descriptor_size) .long 0 -EXTERN(_reactos_memory_map) +EXTERN(reactos_memory_map) .rept (32 * /*sizeof(memory_map_t)*/24) .byte 0 .endr .bss -_PageDirectoryStart: -_pml4_startup: +PageDirectoryStart: +pml4_startup: .fill 4096, 1, 0 -_pdp_startup: +pdp_startup: .fill 4096, 1, 0 -_pd_startup: +pd_startup: .fill 4096, 1, 0 -_PageDirectoryEnd: +PageDirectoryEnd: diff --git a/boot/freeldr/freeldr/arch/i386/hardware.c b/boot/freeldr/freeldr/arch/i386/hardware.c index d4654ccd138..1dff167c987 100644 --- a/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/boot/freeldr/freeldr/arch/i386/hardware.c @@ -1419,10 +1419,10 @@ DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey) /* Set Interrupt */ PartialDescriptor = &PartialResourceList->PartialDescriptors[1]; PartialDescriptor->Type = CmResourceTypeInterrupt; - PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; + PartialDescriptor->ShareDisposition = CmResourceShareShared; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; PartialDescriptor->u.Interrupt.Level = Irq[i]; - PartialDescriptor->u.Interrupt.Vector = 0; + PartialDescriptor->u.Interrupt.Vector = Irq[i]; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; /* Set serial data (device specific) */ @@ -1529,7 +1529,7 @@ DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey) PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; PartialDescriptor->u.Interrupt.Level = Irq[i]; - PartialDescriptor->u.Interrupt.Vector = 0; + PartialDescriptor->u.Interrupt.Vector = Irq[i]; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; } @@ -1715,7 +1715,7 @@ DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey) PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; PartialDescriptor->u.Interrupt.Level = 1; - PartialDescriptor->u.Interrupt.Vector = 0; + PartialDescriptor->u.Interrupt.Vector = 1; PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF; /* Set IO Port 0x60 */ @@ -1887,7 +1887,7 @@ DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey) PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined; PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED; PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12; - PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 0; + PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 12; PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF; /* Create controller key */ diff --git a/boot/freeldr/freeldr/freeldr_arch.rbuild b/boot/freeldr/freeldr/freeldr_arch.rbuild index 2b8a8b288ab..6aa231c258a 100644 --- a/boot/freeldr/freeldr/freeldr_arch.rbuild +++ b/boot/freeldr/freeldr/freeldr_arch.rbuild @@ -1,5 +1,5 @@ - + include cache diff --git a/boot/freeldr/freeldr/freeldr_base.rbuild b/boot/freeldr/freeldr/freeldr_base.rbuild index c8c2ab113c1..a8b784baf9b 100644 --- a/boot/freeldr/freeldr/freeldr_base.rbuild +++ b/boot/freeldr/freeldr/freeldr_base.rbuild @@ -23,7 +23,9 @@ disk.c partition.c ramdisk.c - scsiport.c + + scsiport.c + ext2.c diff --git a/boot/freeldr/freeldr/include/arch/amd64/amd64.h b/boot/freeldr/freeldr/include/arch/amd64/amd64.h index af46178d9db..9068e00f90a 100644 --- a/boot/freeldr/freeldr/include/arch/amd64/amd64.h +++ b/boot/freeldr/freeldr/include/arch/amd64/amd64.h @@ -45,7 +45,7 @@ #define HYPERSPACE_BASE 0xfffff70000000000ULL #define HAL_BASE 0xffffffff80000000ULL -#define APIC_BASE 0xfffffffffee00000ULL // FIXME +#define APIC_BASE 0xFFFFFFFFFFFE0000ULL #define APIC_PHYS_BASE 0xfee00000 diff --git a/boot/freeldr/freeldr/windows/amd64/wlmemory.c b/boot/freeldr/freeldr/windows/amd64/wlmemory.c index 3e3288a682a..5f979c4ca7b 100644 --- a/boot/freeldr/freeldr/windows/amd64/wlmemory.c +++ b/boot/freeldr/freeldr/windows/amd64/wlmemory.c @@ -252,28 +252,36 @@ WinLdrSetupGdt(PVOID GdtBase, ULONG64 TssBase) PKGDTENTRY64 Entry; KDESCRIPTOR GdtDesc; - /* Setup KGDT_64_R0_CODE */ - Entry = KiGetGdtEntry(GdtBase, KGDT_64_R0_CODE); + /* Setup KGDT64_NULL */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_NULL); + *(PULONG64)Entry = 0x0000000000000000ULL; + + /* Setup KGDT64_R0_CODE */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_R0_CODE); *(PULONG64)Entry = 0x00209b0000000000ULL; - /* Setup KGDT_64_R0_SS */ - Entry = KiGetGdtEntry(GdtBase, KGDT_64_R0_SS); + /* Setup KGDT64_R0_DATA */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_R0_DATA); *(PULONG64)Entry = 0x00cf93000000ffffULL; - /* Setup KGDT_64_DATA */ - Entry = KiGetGdtEntry(GdtBase, KGDT_64_DATA); + /* Setup KGDT64_R3_CMCODE */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CMCODE); + *(PULONG64)Entry = 0x00cffb000000ffffULL; + + /* Setup KGDT64_R3_DATA */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_DATA); *(PULONG64)Entry = 0x00cff3000000ffffULL; - /* Setup KGDT_64_R3_CODE */ - Entry = KiGetGdtEntry(GdtBase, KGDT_64_R3_CODE); + /* Setup KGDT64_R3_CODE */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CODE); *(PULONG64)Entry = 0x0020fb0000000000ULL; - /* Setup KGDT_32_R3_TEB */ - Entry = KiGetGdtEntry(GdtBase, KGDT_32_R3_TEB); + /* Setup KGDT64_R3_CMTEB */ + Entry = KiGetGdtEntry(GdtBase, KGDT64_R3_CMTEB); *(PULONG64)Entry = 0xff40f3fd50003c00ULL; /* Setup TSS entry */ - Entry = KiGetGdtEntry(GdtBase, KGDT_TSS); + Entry = KiGetGdtEntry(GdtBase, KGDT64_SYS_TSS); KiInitGdtEntry(Entry, TssBase, sizeof(KTSS), I386_TSS, 0); /* Setup GDT descriptor */ @@ -333,15 +341,8 @@ WinLdrSetProcessorContext(PVOID GdtIdt, IN ULONG64 Pcr, IN ULONG64 Tss) /* LDT is unused */ // __lldt(0); - /* Load selectors for DS/ES/FS/GS/SS */ - Ke386SetDs(KGDT_64_DATA | RPL_MASK); // 0x2b - Ke386SetEs(KGDT_64_DATA | RPL_MASK); // 0x2b - Ke386SetFs(KGDT_32_R3_TEB | RPL_MASK); // 0x53 - Ke386SetGs(KGDT_64_DATA | RPL_MASK); // 0x2b - Ke386SetSs(KGDT_64_R0_SS); // 0x18 - /* Load TSR */ - __ltr(KGDT_TSS); + __ltr(KGDT64_SYS_TSS); DPRINTM(DPRINT_WINDOWS, "leave WinLdrSetProcessorContext\n"); } diff --git a/dll/cpl/desk/appearance.c b/dll/cpl/desk/appearance.c index 9a09169283b..c3c21d4cd13 100644 --- a/dll/cpl/desk/appearance.c +++ b/dll/cpl/desk/appearance.c @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Display Control Panel * FILE: lib/cpl/desk/appearance.c @@ -486,11 +485,17 @@ AppearancePage_OnDestroy(HWND hwndDlg, GLOBALS *g) return TRUE; } +static void +UpdateSelectedThemeId(HWND hwndDlg, GLOBALS *g) +{ + int sel; + sel = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0); + g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)sel, 0); +} INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - INT i; GLOBALS *g; LPNMHDR lpnm; @@ -538,8 +543,7 @@ AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); g->Theme.bHasChanged = TRUE; - i = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETCURSEL, 0, 0); - g->Theme.Id = SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_COLORSCHEME, CB_GETITEMDATA, (WPARAM)i, 0); + UpdateSelectedThemeId(hwndDlg, g); LoadThemeFromReg(g); //SendDlgItemMessage(hwndDlg, IDC_APPEARANCE_PREVIEW, WM_PAINT, 0, 0); } @@ -557,6 +561,7 @@ AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) case PSN_APPLY: if (g->Theme.bHasChanged) { + UpdateSelectedThemeId(hwndDlg, g); ApplyTheme(g); } return TRUE; diff --git a/dll/cpl/desk/background.c b/dll/cpl/desk/background.c index fe4362a30a2..c03c66dc4a4 100644 --- a/dll/cpl/desk/background.c +++ b/dll/cpl/desk/background.c @@ -94,14 +94,17 @@ AddListViewItems(HWND hwndDlg, PGLOBAL_DATA pGlobalData) ZeroMemory(&listItem, sizeof(LV_ITEM)); listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; - listItem.state = LVIS_SELECTED; + listItem.state = 0; listItem.pszText = backgroundItem->szDisplayName; listItem.iImage = -1; listItem.iItem = pGlobalData->listViewItemCount; listItem.lParam = pGlobalData->listViewItemCount; (void)ListView_InsertItem(hwndBackgroundList, &listItem); - ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(hwndBackgroundList, + pGlobalData->listViewItemCount, + LVIS_SELECTED, + LVIS_SELECTED); pGlobalData->listViewItemCount++; @@ -143,14 +146,17 @@ AddListViewItems(HWND hwndDlg, PGLOBAL_DATA pGlobalData) ZeroMemory(&listItem, sizeof(LV_ITEM)); listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; - listItem.state = LVIS_SELECTED; + listItem.state = 0; listItem.pszText = backgroundItem->szDisplayName; listItem.iImage = sfi.iIcon; listItem.iItem = pGlobalData->listViewItemCount; listItem.lParam = pGlobalData->listViewItemCount; (void)ListView_InsertItem(hwndBackgroundList, &listItem); - ListView_SetItemState(hwndBackgroundList, pGlobalData->listViewItemCount, LVIS_SELECTED, LVIS_SELECTED); + ListView_SetItemState(hwndBackgroundList, + pGlobalData->listViewItemCount, + LVIS_SELECTED, + LVIS_SELECTED); pGlobalData->listViewItemCount++; } @@ -454,13 +460,17 @@ OnBrowseButton(HWND hwndDlg, PGLOBAL_DATA pGlobalData) ZeroMemory(&listItem, sizeof(LV_ITEM)); listItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; - listItem.state = LVIS_SELECTED; + listItem.state = 0; listItem.pszText = backgroundItem->szDisplayName; listItem.iImage = sfi.iIcon; listItem.iItem = pGlobalData->listViewItemCount; listItem.lParam = pGlobalData->listViewItemCount; (void)ListView_InsertItem(hwndBackgroundList, &listItem); + ListView_SetItemState(hwndBackgroundList, + pGlobalData->listViewItemCount, + LVIS_SELECTED, + LVIS_SELECTED); SendMessage(hwndBackgroundList, WM_VSCROLL, SB_BOTTOM, 0); pGlobalData->listViewItemCount++; diff --git a/dll/cpl/desk/effappdlg.c b/dll/cpl/desk/effappdlg.c index 6fd0ac7ba8d..3a7c8b4e0e3 100644 --- a/dll/cpl/desk/effappdlg.c +++ b/dll/cpl/desk/effappdlg.c @@ -1,5 +1,4 @@ -/* $Id: effappdlg.c 24836 2007-02-12 03:12:56Z tkreuzer $ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Display Control Panel * FILE: dll/cpl/desk/effappdlg.c diff --git a/dll/directx/bdaplgin/pincontrol.cpp b/dll/directx/bdaplgin/pincontrol.cpp index 4420b76e16b..2571abbf866 100644 --- a/dll/directx/bdaplgin/pincontrol.cpp +++ b/dll/directx/bdaplgin/pincontrol.cpp @@ -336,6 +336,7 @@ CBDAPinControl_fnConstructor( if (SUCCEEDED(hr)) { // register device filter + OutputDebugStringW(L"CBDAPinControl_fnConstructor registering device filter with network provider\n"); hr = pNetworkProvider->RegisterDeviceFilter(pUnknown, &RegistrationCtx); if (SUCCEEDED(hr)) { @@ -361,7 +362,6 @@ CBDAPinControl_fnConstructor( WCHAR Buffer[100]; swprintf(Buffer, L"CBDAPinControl_fnConstructor failed to register filter with %lx\n", hr); OutputDebugStringW(Buffer); - DebugBreak(); } } } diff --git a/dll/directx/ksproxy/allocator.cpp b/dll/directx/ksproxy/allocator.cpp index e7c4b1f2436..8229bd2f56e 100644 --- a/dll/directx/ksproxy/allocator.cpp +++ b/dll/directx/ksproxy/allocator.cpp @@ -357,6 +357,7 @@ CKsAllocator::GetBuffer( if (!m_FreeList.empty()) { + OutputDebugStringW(L"CKsAllocator::GetBuffer HACK\n"); Sample = m_FreeList.top(); m_FreeList.pop(); } diff --git a/dll/directx/ksproxy/enumpins.cpp b/dll/directx/ksproxy/enumpins.cpp index a6c3bdfbd16..da07796d066 100644 --- a/dll/directx/ksproxy/enumpins.cpp +++ b/dll/directx/ksproxy/enumpins.cpp @@ -71,7 +71,6 @@ CEnumPins::QueryInterface( OutputDebugStringW(Buffer); CoTaskMemFree(lpstr); -DebugBreak(); return E_NOINTERFACE; } diff --git a/dll/directx/ksproxy/input_pin.cpp b/dll/directx/ksproxy/input_pin.cpp index 51b78726ccb..e56eacb938c 100644 --- a/dll/directx/ksproxy/input_pin.cpp +++ b/dll/directx/ksproxy/input_pin.cpp @@ -700,7 +700,6 @@ CInputPin::Receive(IMediaSample *pSample) { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Receive NotImplemented\n"); - DebugBreak(); #endif return E_NOTIMPL; @@ -712,7 +711,6 @@ CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSample { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n"); - DebugBreak(); #endif return E_NOTIMPL; @@ -724,7 +722,6 @@ CInputPin::ReceiveCanBlock( void) { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n"); - DebugBreak(); #endif return S_FALSE; @@ -923,7 +920,6 @@ CInputPin::KsQualityNotify( OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n"); #endif - DebugBreak(); return E_NOTIMPL; } @@ -1114,7 +1110,6 @@ CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::Connect NotImplemented\n"); - DebugBreak(); #endif return NOERROR; } @@ -1199,7 +1194,6 @@ CInputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::ConnectionMediaType NotImplemented\n"); - DebugBreak(); #endif return E_NOTIMPL; @@ -1496,7 +1490,6 @@ CInputPin::CreatePin( WCHAR Buffer[100]; swprintf(Buffer, L"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName); OutputDebugStringW(Buffer); - DebugBreak(); #endif hr = E_FAIL; } @@ -1629,7 +1622,6 @@ CInputPin::CreatePinHandle( { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n"); - DebugBreak(); #endif return hr; } @@ -1640,7 +1632,6 @@ CInputPin::CreatePinHandle( { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n"); - DebugBreak(); #endif return hr; } @@ -1783,7 +1774,6 @@ CInputPin::LoadProxyPlugins( { // store plugin m_Plugins.push_back(pUnknown); -DebugBreak(); } // close key RegCloseKey(hSubKey); diff --git a/dll/directx/ksproxy/mediasample.cpp b/dll/directx/ksproxy/mediasample.cpp index e0411938444..28270cdc3bd 100644 --- a/dll/directx/ksproxy/mediasample.cpp +++ b/dll/directx/ksproxy/mediasample.cpp @@ -21,7 +21,6 @@ public: STDMETHODIMP_(ULONG) Release() { InterlockedDecrement(&m_Ref); - DebugBreak(); if (!m_Ref) { if (m_Allocator) @@ -280,7 +279,6 @@ STDMETHODCALLTYPE CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType) { OutputDebugStringW(L"CMediaSample::SetMediaType NotImplemented\n"); - DebugBreak(); return E_NOTIMPL; } diff --git a/dll/directx/ksproxy/output_pin.cpp b/dll/directx/ksproxy/output_pin.cpp index 17f07804a20..2bf85c8a06b 100644 --- a/dll/directx/ksproxy/output_pin.cpp +++ b/dll/directx/ksproxy/output_pin.cpp @@ -246,8 +246,16 @@ COutputPin::COutputPin( ZeroMemory(m_FramingProp, sizeof(m_FramingProp)); ZeroMemory(m_FramingEx, sizeof(m_FramingEx)); + ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE)); hr = KsGetMediaType(0, &m_MediaFormat, KsObjectParent->KsGetObjectHandle(), m_PinId); + +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::COutputPin Format %p pbFormat %lu\n", &m_MediaFormat, m_MediaFormat.cbFormat); + OutputDebugStringW(Buffer); +#endif + assert(hr == S_OK); InitializeCriticalSection(&m_Lock); @@ -1518,6 +1526,8 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) HRESULT hr; ALLOCATOR_PROPERTIES Properties; IMemAllocatorCallbackTemp *pMemCallback; + LPGUID pGuid; + ULONG NumGuids = 0; #ifdef KSPROXY_TRACE WCHAR Buffer[200]; @@ -1540,6 +1550,20 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) pmt = &m_MediaFormat; } + if (m_hPin == INVALID_HANDLE_VALUE) + { + hr = CreatePin(pmt); + if (FAILED(hr)) + { +#ifdef KSPROXY_TRACE + swprintf(Buffer, L"COutputPin::Connect CreatePin handle failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif + return hr; + } + } + + // query for IMemInput interface hr = pReceivePin->QueryInterface(IID_IMemInputPin, (void**)&m_MemInputPin); if (FAILED(hr)) @@ -1548,7 +1572,6 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) OutputDebugStringW(L"COutputPin::Connect no IMemInputPin interface\n"); #endif - DebugBreak(); return hr; } @@ -1649,10 +1672,24 @@ COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) return hr; } - if (!m_hPin) + + assert(m_hPin != INVALID_HANDLE_VALUE); + + // get all supported sets + if (m_Plugins.size() == 0) { - //FIXME create pin handle - assert(0); + if (GetSupportedSets(&pGuid, &NumGuids)) + { + // load all proxy plugins + if (FAILED(LoadProxyPlugins(pGuid, NumGuids))); + { +#ifdef KSPROXY_TRACE + OutputDebugStringW(L"COutputPin::Connect LoadProxyPlugins failed\n"); +#endif + } + // free sets + CoTaskMemFree(pGuid); + } } // receive connection; @@ -1946,13 +1983,26 @@ COutputPin::CreatePin( // query for pin medium hr = KsQueryMediums(&MediumList); if (FAILED(hr)) + { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePin KsQueryMediums failed %lx\n", hr); + OutputDebugStringW(Buffer); +#endif return hr; + } // query for pin interface hr = KsQueryInterfaces(&InterfaceList); if (FAILED(hr)) { // failed +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePin KsQueryInterfaces failed %lx\n", hr); + OutputDebugStringW(Buffer); +#endif + CoTaskMemFree(MediumList); return hr; } @@ -2003,6 +2053,12 @@ COutputPin::CreatePin( CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePin failed to create interface handler %lx\n", hr); + OutputDebugStringW(Buffer); +#endif + return hr; } @@ -2010,7 +2066,12 @@ COutputPin::CreatePin( hr = InterfaceHandler->KsSetPin((IKsPin*)this); if (FAILED(hr)) { - // failed to load interface handler plugin + // failed to initialize interface handler plugin +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePin failed to initialize interface handler %lx\n", hr); + OutputDebugStringW(Buffer); +#endif InterfaceHandler->Release(); CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); @@ -2027,7 +2088,6 @@ COutputPin::CreatePin( WCHAR Buffer[100]; swprintf(Buffer, L"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName); OutputDebugStringW(Buffer); - DebugBreak(); #endif hr = E_FAIL; @@ -2037,6 +2097,12 @@ COutputPin::CreatePin( CoTaskMemFree(MediumList); CoTaskMemFree(InterfaceList); +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePin Result %lx\n", hr); + OutputDebugStringW(Buffer); +#endif + return hr; } @@ -2058,11 +2124,14 @@ COutputPin::CreatePinHandle( //KSPROPERTY Property; //ULONG BytesReturned; + OutputDebugStringW(L"COutputPin::CreatePinHandle\n"); + if (m_hPin != INVALID_HANDLE_VALUE) { // pin already exists //CloseHandle(m_hPin); //m_hPin = INVALID_HANDLE_VALUE; + OutputDebugStringW(L"COutputPin::CreatePinHandle pin already exists\n"); return S_OK; } @@ -2075,9 +2144,10 @@ COutputPin::CreatePinHandle( if (!PinConnect) { // failed + OutputDebugStringW(L"COutputPin::CreatePinHandle out of memory\n"); return E_OUTOFMEMORY; } - + OutputDebugStringW(L"COutputPin::CreatePinHandle copy pinconnect\n"); // setup request CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE)); CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM)); @@ -2088,7 +2158,7 @@ COutputPin::CreatePinHandle( // get dataformat offset DataFormat = (PKSDATAFORMAT)(PinConnect + 1); - + OutputDebugStringW(L"COutputPin::CreatePinHandle copy format\n"); // copy data format DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat; DataFormat->Flags = 0; @@ -2101,13 +2171,19 @@ COutputPin::CreatePinHandle( if (pmt->cbFormat) { // copy extended format + WCHAR Buffer[100]; + swprintf(Buffer, L"COutputPin::CreatePinHandle copy format %p pbFormat %lu\n", pmt, pmt->cbFormat); + OutputDebugStringW(Buffer); CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat); } // get IKsObject interface hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent); if (FAILED(hr)) + { + OutputDebugStringW(L"COutputPin::CreatePinHandle no IID_IKsObject interface\n"); return hr; + } // get parent filter handle hFilter = KsObjectParent->KsGetObjectHandle(); @@ -2116,13 +2192,19 @@ COutputPin::CreatePinHandle( KsObjectParent->Release(); if (!hFilter) - return E_HANDLE; - - // create pin - hr = KsCreatePin(hFilter, PinConnect, GENERIC_READ, &m_hPin); - - if (SUCCEEDED(hr)) { + OutputDebugStringW(L"COutputPin::CreatePinHandle no filter handle\n"); + return E_HANDLE; + } + + OutputDebugStringW(L"COutputPin::CreatePinHandle before creating pin\n"); + // create pin + DWORD dwError = KsCreatePin(hFilter, PinConnect, GENERIC_READ, &m_hPin); + + if (dwError == ERROR_SUCCESS) + { + OutputDebugStringW(L"COutputPin::CreatePinHandle created pin\n"); + // store current interface / medium CopyMemory(&m_Medium, Medium, sizeof(KSPIN_MEDIUM)); CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE)); @@ -2173,42 +2255,14 @@ COutputPin::CreatePinHandle( if (FAILED(InitializeIOThread())) { OutputDebugStringW(L"COutputPin::CreatePinHandle failed to initialize i/o thread\n"); - DebugBreak(); } - LPGUID pGuid; - ULONG NumGuids = 0; - - // get all supported sets - hr = GetSupportedSets(&pGuid, &NumGuids); - if (FAILED(hr)) - { -#ifdef KSPROXY_TRACE - OutputDebugStringW(L"CInputPin::CreatePinHandle GetSupportedSets failed\n"); - DebugBreak(); -#endif - return hr; - } - - // load all proxy plugins - hr = LoadProxyPlugins(pGuid, NumGuids); - if (FAILED(hr)) - { -#ifdef KSPROXY_TRACE - OutputDebugStringW(L"CInputPin::CreatePinHandle LoadProxyPlugins failed\n"); - DebugBreak(); -#endif - return hr; - } - - // free sets - CoTaskMemFree(pGuid); - - //TODO // connect pin pipes } + else + OutputDebugStringW(L"COutputPin::CreatePinHandle failed to create pin\n"); // free pin connect CoTaskMemFree(PinConnect); @@ -2338,7 +2392,6 @@ COutputPin::LoadProxyPlugins( { // store plugin m_Plugins.push_back(pUnknown); -DebugBreak(); } // close key RegCloseKey(hSubKey); @@ -2357,17 +2410,48 @@ COutputPin::IoProcessRoutine() IMediaSample *Sample; LONG SampleCount; HRESULT hr; - PKSSTREAM_SEGMENT StreamSegment; + PKSSTREAM_SEGMENT * StreamSegment; HANDLE hEvent; - IMediaSample * Samples[1]; + IMediaSample ** Samples; + LONG NumHandles; + DWORD dwStatus; #ifdef KSPROXY_TRACE WCHAR Buffer[200]; #endif + NumHandles = m_Properties.cBuffers / 2; + + if (!NumHandles) + NumHandles = 8; + + assert(NumHandles); + + //allocate stream segment array + StreamSegment = (PKSSTREAM_SEGMENT*)CoTaskMemAlloc(sizeof(PKSSTREAM_SEGMENT) * NumHandles); + if (!StreamSegment) + { + OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n"); + return E_FAIL; + } + + // allocate handle array + Samples = (IMediaSample**)CoTaskMemAlloc(sizeof(IMediaSample*) * NumHandles); + if (!Samples) + { + OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n"); + return E_FAIL; + } + + // zero handles array + ZeroMemory(StreamSegment, sizeof(PKSSTREAM_SEGMENT) * NumHandles); + ZeroMemory(Samples, sizeof(IMediaSample*) * NumHandles); + // first wait for the start event to signal WaitForSingleObject(m_hStartEvent, INFINITE); + m_IoCount = 0; + assert(m_InterfaceHandler); do { @@ -2392,14 +2476,14 @@ COutputPin::IoProcessRoutine() // fill buffer SampleCount = 1; - Samples[0] = Sample; + Samples[m_IoCount] = Sample; Sample->SetTime(NULL, NULL); hr = m_InterfaceHandler->KsProcessMediaSamples(NULL, /* FIXME */ - Samples, + &Samples[m_IoCount], &SampleCount, KsIoOperation_Read, - &StreamSegment); + &StreamSegment[m_IoCount]); if (FAILED(hr) || !StreamSegment) { #ifdef KSPROXY_TRACE @@ -2409,14 +2493,26 @@ COutputPin::IoProcessRoutine() break; } - // get completion event - hEvent = StreamSegment->CompletionEvent; + // interface handle should increment pending i/o count + assert(m_IoCount >= 1); + + swprintf(Buffer, L"COutputPin::IoProcessRoutine m_IoCount %lu NumHandles %lu\n", m_IoCount, NumHandles); + OutputDebugStringW(Buffer); + + if (m_IoCount != NumHandles) + continue; + + // get completion handle + hEvent = StreamSegment[0]->CompletionEvent; // wait for i/o completion - WaitForSingleObject(hEvent, INFINITE); + dwStatus = WaitForSingleObject(hEvent, INFINITE); + + swprintf(Buffer, L"COutputPin::IoProcessRoutine dwStatus %lx Error %lx NumHandles %lu\n", dwStatus, GetLastError(), NumHandles); + OutputDebugStringW(Buffer); // perform completion - m_InterfaceHandler->KsCompleteIo(StreamSegment); + m_InterfaceHandler->KsCompleteIo(StreamSegment[0]); // close completion event CloseHandle(hEvent); @@ -2426,7 +2522,7 @@ COutputPin::IoProcessRoutine() assert(m_MemInputPin); // now deliver the sample - hr = m_MemInputPin->Receive(Sample); + hr = m_MemInputPin->Receive(Samples[0]); #ifdef KSPROXY_TRACE swprintf(Buffer, L"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName, hr, Sample, m_MemAllocator); @@ -2438,6 +2534,11 @@ COutputPin::IoProcessRoutine() Sample = NULL; } + + //circular stream segment array + RtlMoveMemory(StreamSegment, &StreamSegment[1], sizeof(PKSSTREAM_SEGMENT) * (NumHandles - 1)); + RtlMoveMemory(Samples, &Samples[1], sizeof(IMediaSample*) * (NumHandles - 1)); + }while(TRUE); // signal end of i/o thread diff --git a/dll/directx/ksproxy/precomp.h b/dll/directx/ksproxy/precomp.h index eae5de0f1aa..f7268b1e026 100644 --- a/dll/directx/ksproxy/precomp.h +++ b/dll/directx/ksproxy/precomp.h @@ -3,7 +3,7 @@ #define _FORCENAMELESSUNION #define BUILDING_KS #define _KSDDK_ -//#define KSPROXY_TRACE +#define KSPROXY_TRACE #include //#include #include diff --git a/dll/directx/ksproxy/proxy.cpp b/dll/directx/ksproxy/proxy.cpp index bd34ec8184b..175eff205ca 100644 --- a/dll/directx/ksproxy/proxy.cpp +++ b/dll/directx/ksproxy/proxy.cpp @@ -1954,7 +1954,6 @@ CKsProxy::IsDirty() { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CKsProxy::IsDirty Notimplemented\n"); - DebugBreak(); #endif return E_NOTIMPL; } @@ -2035,7 +2034,6 @@ CKsProxy::Load( }while(Length > 0); - DebugBreak(); return S_OK; } @@ -2059,7 +2057,6 @@ CKsProxy::GetSizeMax( { #ifdef KSPROXY_TRACE OutputDebugStringW(L"CKsProxy::GetSizeMax Notimplemented\n"); - DebugBreak(); #endif return E_NOTIMPL; @@ -2480,23 +2477,50 @@ CKsProxy::CreatePins() // query current instance count hr = GetPinInstanceCount(Index, &Instances); if (FAILED(hr)) + { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins GetPinInstanceCount failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif continue; + } + // query pin communication; hr = GetPinCommunication(Index, &Communication); if (FAILED(hr)) + { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins GetPinCommunication failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif continue; + } if (Instances.CurrentCount == Instances.PossibleCount) { // already maximum reached for this pin +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins Instances.CurrentCount == Instances.PossibleCount\n"); + OutputDebugStringW(Buffer); +#endif continue; } // get direction of pin hr = GetPinDataflow(Index, &DataFlow); if (FAILED(hr)) + { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins GetPinDataflow failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif continue; + } if (DataFlow == KSPIN_DATAFLOW_IN) hr = GetPinName(Index, DataFlow, InputPin, &PinName); @@ -2504,7 +2528,14 @@ CKsProxy::CreatePins() hr = GetPinName(Index, DataFlow, OutputPin, &PinName); if (FAILED(hr)) + { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins GetPinName failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif continue; + } // construct the pins if (DataFlow == KSPIN_DATAFLOW_IN) @@ -2512,6 +2543,11 @@ CKsProxy::CreatePins() hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, Communication, IID_IPin, (void**)&pPin); if (FAILED(hr)) { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins CInputPin_Constructor failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif CoTaskMemFree(PinName); continue; } @@ -2522,6 +2558,11 @@ CKsProxy::CreatePins() hr = COutputPin_Constructor((IBaseFilter*)this, PinName, Index, Communication, IID_IPin, (void**)&pPin); if (FAILED(hr)) { +#ifdef KSPROXY_TRACE + WCHAR Buffer[100]; + swprintf(Buffer, L"CKsProxy::CreatePins COutputPin_Constructor failed with %lx\n", hr); + OutputDebugStringW(Buffer); +#endif CoTaskMemFree(PinName); continue; } @@ -2627,9 +2668,12 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) hr = LoadProxyPlugins(pGuid, NumGuids); if (FAILED(hr)) { +#if 0 //HACK CloseHandle(m_hDevice); m_hDevice = NULL; return hr; +#endif + OutputDebugStringW(L"CKsProxy::LoadProxyPlugins failed!\n"); } // free sets @@ -2638,6 +2682,14 @@ CKsProxy::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog) // now create the input / output pins hr = CreatePins(); +#ifdef KSPROXY_TRACE + swprintf(Buffer, L"CKsProxy::Load CreatePins %lx\n", hr); + OutputDebugStringW(Buffer); +#endif + + //HACK + hr = S_OK; + return hr; } @@ -2986,10 +3038,6 @@ STDMETHODCALLTYPE CKsProxy::EnumPins( IEnumPins **ppEnum) { -#ifdef KSPROXY_TRACE - OutputDebugStringW(L"CKsProxy::EnumPins\n"); -#endif - return CEnumPins_fnConstructor(m_Pins, IID_IEnumPins, (void**)ppEnum); } diff --git a/dll/directx/msdvbnp/enumpins.cpp b/dll/directx/msdvbnp/enumpins.cpp index 567705907b7..9466aaae8f3 100644 --- a/dll/directx/msdvbnp/enumpins.cpp +++ b/dll/directx/msdvbnp/enumpins.cpp @@ -155,14 +155,6 @@ CEnumPins_fnConstructor( { CEnumPins * handler = new CEnumPins(NumPins, pins); -#ifdef MSDVBNP_TRACE - WCHAR Buffer[MAX_PATH]; - LPOLESTR lpstr; - StringFromCLSID(riid, &lpstr); - swprintf(Buffer, L"CEnumPins_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown); - OutputDebugStringW(Buffer); -#endif - if (!handler) return E_OUTOFMEMORY; diff --git a/dll/directx/msdvbnp/msdvbnp.cpp b/dll/directx/msdvbnp/msdvbnp.cpp index b67f232e13f..9c1d309a500 100644 --- a/dll/directx/msdvbnp/msdvbnp.cpp +++ b/dll/directx/msdvbnp/msdvbnp.cpp @@ -9,10 +9,14 @@ #include "precomp.h" +#ifndef _MSC_VER +const GUID KSCATEGORY_BDA_NETWORK_PROVIDER = {0x71985f4b, 0x1ca1, 0x11d3, {0x9c, 0xc8, 0x0, 0xc0, 0x4f, 0x79, 0x71, 0xe0}}; +#endif + static INTERFACE_TABLE InterfaceTable[] = { - {&CLSID_DVBTNetworkProvider, CNetworkProvider_fnConstructor}, - {NULL, NULL} + {&CLSID_DVBTNetworkProvider, CNetworkProvider_fnConstructor, L"ReactOS DVBT Network Provider"}, + {NULL, NULL, NULL} }; extern "C" @@ -53,8 +57,19 @@ DllUnregisterServer(void) HRESULT hr = S_OK; HKEY hClass; + + hr = StringFromCLSID(KSCATEGORY_BDA_NETWORK_PROVIDER, &pStr); + if (FAILED(hr)) + return hr; + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_SET_VALUE, &hClass) != ERROR_SUCCESS) + { + CoTaskMemFree(pStr); return E_FAIL; + } + + RegDeleteKeyW(hClass, pStr); + CoTaskMemFree(pStr); do { @@ -71,6 +86,24 @@ DllUnregisterServer(void) return hr; } +VOID +RegisterBDAComponent( + HKEY hFilter, + LPCWSTR ComponentClsid, + LPCWSTR ComponentName) +{ + HKEY hComp; + + // create network provider filter key + if (RegCreateKeyExW(hFilter, ComponentClsid, 0, NULL, 0, KEY_WRITE, NULL, &hComp, NULL) == ERROR_SUCCESS) + { + // store class id + RegSetValueExW(hComp, L"CLSID", 0, REG_SZ, (const BYTE*)ComponentClsid, (wcslen(ComponentClsid)+1) * sizeof(WCHAR)); + RegSetValueExW(hComp, L"FriendlyName", 0, REG_SZ, (const BYTE*)ComponentName, (wcslen(ComponentName)+1) * sizeof(WCHAR)); + RegCloseKey(hComp); + } +} + extern "C" KSDDKAPI HRESULT @@ -80,12 +113,50 @@ DllRegisterServer(void) ULONG Index = 0; LPOLESTR pStr; HRESULT hr = S_OK; - HKEY hClass, hKey, hSubKey; + HKEY hClass, hKey, hSubKey, hProvider, hInstance, hFilter; static LPCWSTR ModuleName = L"msdvbnp.ax"; static LPCWSTR ThreadingModel = L"Both"; + hr = StringFromCLSID(KSCATEGORY_BDA_NETWORK_PROVIDER, &pStr); + if (FAILED(hr)) + return hr; + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_WRITE, &hClass) != ERROR_SUCCESS) + { + CoTaskMemFree(pStr); return E_FAIL; + } + + if (RegCreateKeyExW(hClass, pStr, 0, NULL, 0, KEY_WRITE, NULL, &hProvider, NULL) != ERROR_SUCCESS) + { + RegCloseKey(hClass); + CoTaskMemFree(pStr); + return E_FAIL; + } + + CoTaskMemFree(pStr); + + if (RegCreateKeyExW(hProvider, L"Instance", 0, NULL, 0, KEY_WRITE, NULL, &hInstance, NULL) != ERROR_SUCCESS) + { + RegCloseKey(hClass); + return E_FAIL; + } + RegCloseKey(hProvider); + + /* open active movie filter category key */ + if (RegCreateKeyExW(hClass, L"{da4e3da0-d07d-11d0-bd50-00a0c911ce86}\\Instance", 0, NULL, 0, KEY_WRITE, NULL, &hFilter, NULL) != ERROR_SUCCESS) + { + RegCloseKey(hClass); + RegCloseKey(hInstance); + return E_FAIL; + } + + RegisterBDAComponent(hFilter, L"{71985F4A-1CA1-11d3-9CC8-00C04F7971E0}", L"BDA Playback Filter"); + RegisterBDAComponent(hFilter, L"{71985F4B-1CA1-11D3-9CC8-00C04F7971E0}", L"BDA Network Providers"); + RegisterBDAComponent(hFilter, L"{71985F48-1CA1-11d3-9CC8-00C04F7971E0}", L"BDA Source Filter"); + RegisterBDAComponent(hFilter, L"{A2E3074F-6C3D-11D3-B653-00C04F79498E}", L"BDA Transport Information Renderers"); + RegisterBDAComponent(hFilter, L"{FD0A5AF4-B41D-11d2-9C95-00C04F7971E0}", L"BDA Receiver Component"); + RegCloseKey(hKey); do { @@ -104,11 +175,23 @@ DllRegisterServer(void) RegCloseKey(hKey); } + if (RegCreateKeyExW(hInstance, InterfaceTable[Index].ProviderName, 0, 0, 0, KEY_WRITE, NULL, &hKey, 0) == ERROR_SUCCESS) + { + //FIXME filterdata + RegSetValueExW(hKey, L"FriendlyName", 0, REG_SZ, (const BYTE*)InterfaceTable[Index].ProviderName, (wcslen(InterfaceTable[Index].ProviderName) + 1) * sizeof(WCHAR)); + RegSetValueExW(hKey, L"CLSID", 0, REG_SZ, (const BYTE*)pStr, (wcslen(pStr)+1) * sizeof(WCHAR)); + RegCloseKey(hKey); + } + + + + CoTaskMemFree(pStr); Index++; }while(InterfaceTable[Index].lpfnCI != 0); RegCloseKey(hClass); + RegCloseKey(hInstance); return hr; } diff --git a/dll/directx/msdvbnp/precomp.h b/dll/directx/msdvbnp/precomp.h index c9abe7ac000..828cfb47202 100644 --- a/dll/directx/msdvbnp/precomp.h +++ b/dll/directx/msdvbnp/precomp.h @@ -28,6 +28,7 @@ typedef struct { const GUID* riid; LPFNCREATEINSTANCE lpfnCI; + LPCWSTR ProviderName; } INTERFACE_TABLE; /* classfactory.cpp */ diff --git a/dll/directx/qedit/samplegrabber.c b/dll/directx/qedit/samplegrabber.c index 1875c51c49e..78a7306e10e 100644 --- a/dll/directx/qedit/samplegrabber.c +++ b/dll/directx/qedit/samplegrabber.c @@ -854,7 +854,7 @@ SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber *iface, LONG *bufSi static HRESULT WINAPI SampleGrabber_ISampleGrabber_GetCurrentSample(ISampleGrabber *iface, IMediaSample **sample) { - /* MS doesn't implement it either, noone should call it */ + /* MS doesn't implement it either, no one should call it */ WARN("(%p): not implemented\n", sample); return E_NOTIMPL; } @@ -1264,7 +1264,7 @@ SampleGrabber_IPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **mtypes) TRACE("(%p)->(%p)\n", This, mtypes); if (!mtypes) return E_POINTER; - *mtypes = mediaenum_create(This->sg->pin_in.pair ? &This->sg->mtype : (const AM_MEDIA_TYPE *)NULL); + *mtypes = mediaenum_create(This->sg->pin_in.pair ? &This->sg->mtype : NULL); return *mtypes ? S_OK : E_OUTOFMEMORY; } diff --git a/dll/directx/quartz/avidec.c b/dll/directx/quartz/avidec.c index 68b1908d6e6..8469bbc9f29 100644 --- a/dll/directx/quartz/avidec.c +++ b/dll/directx/quartz/avidec.c @@ -203,7 +203,7 @@ static HRESULT AVIDec_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) bmi = &format2->bmiHeader; else goto failed; - TRACE("Fourcc: %s\n", debugstr_an((char *)&pmt->subtype.Data1, 4)); + TRACE("Fourcc: %s\n", debugstr_an((const char *)&pmt->subtype.Data1, 4)); This->hvid = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, bmi, NULL, ICMODE_DECOMPRESS); if (This->hvid) diff --git a/dll/directx/quartz/avisplit.c b/dll/directx/quartz/avisplit.c index faa844b4848..42ec2ae2b34 100644 --- a/dll/directx/quartz/avisplit.c +++ b/dll/directx/quartz/avisplit.c @@ -692,7 +692,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE amt.formattype = FORMAT_WaveFormatEx; break; default: - FIXME("fccType %.4s not handled yet\n", (char *)&pStrHdr->fccType); + FIXME("fccType %.4s not handled yet\n", (const char *)&pStrHdr->fccType); amt.formattype = FORMAT_None; } amt.majortype = MEDIATYPE_Video; @@ -793,7 +793,7 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE TRACE("bIndexSubType: %hd\n", pIndex->bIndexSubType); TRACE("bIndexType: %hd\n", pIndex->bIndexType); TRACE("nEntriesInUse: %u\n", pIndex->nEntriesInUse); - TRACE("dwChunkId: %.4s\n", (char *)&pIndex->dwChunkId); + TRACE("dwChunkId: %.4s\n", (const char *)&pIndex->dwChunkId); if (pIndex->dwReserved[0]) TRACE("dwReserved[0]: %u\n", pIndex->dwReserved[0]); if (pIndex->dwReserved[2]) diff --git a/dll/win32/activeds/activeds.spec b/dll/win32/activeds/activeds.spec index 63625d5d022..2b458342493 100644 --- a/dll/win32/activeds/activeds.spec +++ b/dll/win32/activeds/activeds.spec @@ -6,7 +6,7 @@ 8 stub ADsBuildVarArrayInt 9 stdcall ADsOpenObject(wstr wstr wstr long ptr ptr) 12 stub ADsSetLastError -13 stub ADsGetLastError +13 stdcall ADsGetLastError(ptr ptr long ptr long) 14 stub AllocADsMem 15 stdcall FreeADsMem(ptr) 16 stub ReallocADsMem diff --git a/dll/win32/activeds/activeds_main.c b/dll/win32/activeds/activeds_main.c index 9c03ac16d68..2fa4ec73d80 100644 --- a/dll/win32/activeds/activeds_main.c +++ b/dll/win32/activeds/activeds_main.c @@ -94,6 +94,15 @@ HRESULT WINAPI ADsOpenObject(LPCWSTR lpszPathName, LPCWSTR lpszUserName, LPCWSTR return E_NOTIMPL; } +/***************************************************** + * ADsGetLastError [ACTIVEDS.13] + */ +HRESULT WINAPI ADsGetLastError(LPDWORD perror, LPWSTR errorbuf, DWORD errorbuflen, LPWSTR namebuf, DWORD namebuflen) +{ + FIXME("(%p,%p,%d,%p,%d)!stub\n", perror, errorbuf, errorbuflen, namebuf, namebuflen); + return E_NOTIMPL; +} + /***************************************************** * FreeADsMem [ACTIVEDS.15] */ diff --git a/dll/win32/actxprxy/actxprxy.rbuild b/dll/win32/actxprxy/actxprxy.rbuild index f5272b585cf..c8b28ca5891 100644 --- a/dll/win32/actxprxy/actxprxy.rbuild +++ b/dll/win32/actxprxy/actxprxy.rbuild @@ -31,7 +31,6 @@ actxprxy_ocmm.idl actxprxy_servprov.idl - actxprxy_urlhist.idl - + actxprxy_urlhist.idl diff --git a/dll/win32/atl/atl_ax.c b/dll/win32/atl/atl_ax.c index 2afc7460328..616713ce62b 100644 --- a/dll/win32/atl/atl_ax.c +++ b/dll/win32/atl/atl_ax.c @@ -950,7 +950,7 @@ HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink); - hRes = CLSIDFromString( (LPOLESTR) lpszName, &controlId ); + hRes = CLSIDFromString( lpszName, &controlId ); if ( FAILED(hRes) ) hRes = CLSIDFromProgID( lpszName, &controlId ); if ( SUCCEEDED( hRes ) ) diff --git a/dll/win32/avifil32/rsrc.rc b/dll/win32/avifil32/rsrc.rc index d86578c5a6b..b13fcb93e42 100644 --- a/dll/win32/avifil32/rsrc.rc +++ b/dll/win32/avifil32/rsrc.rc @@ -1,7 +1,7 @@ /* * Top level resource file for avifil32.dll * - * Copyright 2002 Michael Gnnewig + * Copyright 2002 Michael Günnewig * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,10 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "winver.h" #include "avifile_private.h" LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL diff --git a/dll/win32/cabinet/fdi.c b/dll/win32/cabinet/fdi.c index de64f025bd3..b68ab15acd8 100644 --- a/dll/win32/cabinet/fdi.c +++ b/dll/win32/cabinet/fdi.c @@ -77,7 +77,7 @@ THOSE_ZIP_CONSTS; struct fdi_file { struct fdi_file *next; /* next file in sequence */ - LPCSTR filename; /* output name of file */ + LPSTR filename; /* output name of file */ int fh; /* open file handle or NULL */ cab_ULONG length; /* uncompressed length of file */ cab_ULONG offset; /* uncompressed offset in folder */ @@ -2301,7 +2301,7 @@ static void free_decompression_mem(HFDI hfdi, } while (CAB(firstfile)) { file = CAB(firstfile); - if (file->filename) PFDI_FREE(hfdi, (void *)file->filename); + if (file->filename) PFDI_FREE(hfdi, file->filename); CAB(firstfile) = CAB(firstfile)->next; PFDI_FREE(hfdi, file); } diff --git a/dll/win32/crypt32/base64.c b/dll/win32/crypt32/base64.c index 4a6504a488e..7a23dd9a111 100644 --- a/dll/win32/crypt32/base64.c +++ b/dll/win32/crypt32/base64.c @@ -99,8 +99,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); needed = bytes + pad_bytes + 1; - if (sep) - needed += (needed / 64 + 1) * strlen(sep); + needed += (needed / 64 + 1) * strlen(sep); if (needed > *out_len) { @@ -117,7 +116,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, i = 0; while (div > 0) { - if (sep && i && i % 64 == 0) + if (i && i % 64 == 0) { strcpy(ptr, sep); ptr += strlen(sep); @@ -163,8 +162,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, *ptr++ = '='; break; } - if (sep) - strcpy(ptr, sep); + strcpy(ptr, sep); return ERROR_SUCCESS; } @@ -180,7 +178,7 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, if (dwFlags & CRYPT_STRING_NOCR) sep = lf; else if (dwFlags & CRYPT_STRING_NOCRLF) - sep = NULL; + sep = ""; else sep = crlf; switch (dwFlags & 0x0fffffff) @@ -204,8 +202,6 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, charsNeeded = 0; encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded); - if (sep) - charsNeeded += strlen(sep); if (header) charsNeeded += strlen(header) + strlen(sep); if (trailer) @@ -219,11 +215,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, { strcpy(ptr, header); ptr += strlen(ptr); - if (sep) - { - strcpy(ptr, sep); - ptr += strlen(sep); - } + strcpy(ptr, sep); + ptr += strlen(sep); } encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); ptr += size - 1; @@ -231,11 +224,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, { strcpy(ptr, trailer); ptr += strlen(ptr); - if (sep) - { - strcpy(ptr, sep); - ptr += strlen(sep); - } + strcpy(ptr, sep); + ptr += strlen(sep); } *pcchString = charsNeeded - 1; } @@ -304,8 +294,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); needed = bytes + pad_bytes + 1; - if (sep) - needed += (needed / 64 + 1) * strlenW(sep); + needed += (needed / 64 + 1) * strlenW(sep); if (needed > *out_len) { @@ -322,7 +311,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, i = 0; while (div > 0) { - if (sep && i && i % 64 == 0) + if (i && i % 64 == 0) { strcpyW(ptr, sep); ptr += strlenW(sep); @@ -368,8 +357,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, *ptr++ = '='; break; } - if (sep) - strcpyW(ptr, sep); + strcpyW(ptr, sep); return ERROR_SUCCESS; } @@ -377,7 +365,7 @@ static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, static BOOL BinaryToBase64W(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString) { - static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 }; + static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 }, empty[] = {0}; BOOL ret = TRUE; LPCWSTR header = NULL, trailer = NULL, sep; DWORD charsNeeded; @@ -385,7 +373,7 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, if (dwFlags & CRYPT_STRING_NOCR) sep = lf; else if (dwFlags & CRYPT_STRING_NOCRLF) - sep = NULL; + sep = empty; else sep = crlf; switch (dwFlags & 0x0fffffff) @@ -409,8 +397,6 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, charsNeeded = 0; encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded); - if (sep) - charsNeeded += strlenW(sep); if (header) charsNeeded += strlenW(header) + strlenW(sep); if (trailer) @@ -424,11 +410,8 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, { strcpyW(ptr, header); ptr += strlenW(ptr); - if (sep) - { - strcpyW(ptr, sep); - ptr += strlenW(sep); - } + strcpyW(ptr, sep); + ptr += strlenW(sep); } encodeBase64W(pbBinary, cbBinary, sep, ptr, &size); ptr += size - 1; @@ -436,11 +419,8 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary, { strcpyW(ptr, trailer); ptr += strlenW(ptr); - if (sep) - { - strcpyW(ptr, sep); - ptr += strlenW(sep); - } + strcpyW(ptr, sep); + ptr += strlenW(sep); } *pcchString = charsNeeded - 1; } diff --git a/dll/win32/devmgr/lang/cs-CZ.rc b/dll/win32/devmgr/lang/cs-CZ.rc index 2c29b447a76..aa7a56e21c5 100644 --- a/dll/win32/devmgr/lang/cs-CZ.rc +++ b/dll/win32/devmgr/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/win32/devmgr/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2008-06-24 + * UPDATED: 2010-01-07 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -202,7 +202,7 @@ END IDD_DEVICEDETAILS DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Details" +CAPTION "Detaily" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 @@ -215,7 +215,7 @@ END IDD_DEVICERESOURCES DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Resources" +CAPTION "Prostedky" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 @@ -224,7 +224,7 @@ END IDD_DEVICEPOWER DIALOGEX DISCARDABLE 0, 0, 252, 218 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Power" +CAPTION "Napjen" FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_DEVICON, 7, 7, 20, 20 diff --git a/dll/win32/gdi32/objects/dc.c b/dll/win32/gdi32/objects/dc.c index 2d90f60cdac..34c31148bb3 100644 --- a/dll/win32/gdi32/objects/dc.c +++ b/dll/win32/gdi32/objects/dc.c @@ -1540,7 +1540,7 @@ SelectObject(HDC hDC, PDC_ATTR pDc_Attr; HGDIOBJ hOldObj = NULL; UINT uType; -// PTEB pTeb; + PTEB pTeb; if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) { @@ -1582,7 +1582,6 @@ SelectObject(HDC hDC, case GDI_OBJECT_TYPE_FONT: hOldObj = pDc_Attr->hlfntNew; if (hOldObj == hGdiObj) return hOldObj; -#if 0 pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS; pDc_Attr->ulDirty_ |= DIRTY_CHARSET; pDc_Attr->hlfntNew = hGdiObj; @@ -1604,7 +1603,6 @@ SelectObject(HDC hDC, if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); return hOldObj; } -#endif // default for select object font return NtGdiSelectFont(hDC, hGdiObj); diff --git a/dll/win32/gdi32/objects/region.c b/dll/win32/gdi32/objects/region.c index e1f187ad3d2..3e2b7fe5b65 100644 --- a/dll/win32/gdi32/objects/region.c +++ b/dll/win32/gdi32/objects/region.c @@ -104,7 +104,6 @@ BOOL FASTCALL DeleteRegion( HRGN hRgn ) { -//#if 0 PRGN_ATTR Rgn_Attr; if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) && @@ -128,7 +127,6 @@ DeleteRegion( HRGN hRgn ) } } } -//#endif return NtGdiDeleteObjectApp((HGDIOBJ) hRgn); } @@ -581,8 +579,110 @@ INT WINAPI ExtSelectClipRgn( IN HDC hdc, IN HRGN hrgn, IN INT iMode) { - /* FIXME some part need be done on user mode size */ - return NtGdiExtSelectClipRgn(hdc,hrgn, iMode); + INT Ret; + HRGN NewRgn = NULL; + +#if 0 +// Handle something other than a normal dc object. + if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) + return MFDRV_ExtSelectClipRgn( hdc, ); + else + { + PLDC pLDC = GdiGetLDC(hdc); + if ( pLDC ) + { + if (pLDC->iType != LDC_EMFLDC || EMFDRV_ExtSelectClipRgn( hdc, )) + return NtGdiExtSelectClipRgn(hdc, ); + } + else + SetLastError(ERROR_INVALID_HANDLE); + return ERROR; + } + } +#endif +#if 0 + if ( hrgn ) + { + if ( GetLayout(hdc) & LAYOUT_RTL ) + { + if ( MirrorRgnDC(hdc, hrgn, &NewRgn) ) + { + if ( NewRgn ) hrgn = NewRgn; + } + } + } +#endif + /* Batch handles RGN_COPY only! */ + if (iMode == RGN_COPY) + { +#if 0 + PDC_ATTR pDc_Attr; + PRGN_ATTR pRgn_Attr = NULL; + + /* hrgn can be NULL unless the RGN_COPY mode is specified. */ + if (hrgn) + GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr); + + if ( GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr) && + pDc_Attr ) + { + PGDI_TABLE_ENTRY pEntry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hdc); + PTEB pTeb = NtCurrentTeb(); + + if ( pTeb->Win32ThreadInfo != NULL && + pTeb->GdiTebBatch.HDC == hdc && + !(pDc_Attr->ulDirty_ & DC_DIBSECTION) && + !(pEntry->Flags & GDI_ENTRY_VALIDATE_VIS) ) + { + if (!hrgn || + (hrgn && pRgn_Attr && pRgn_Attr->Flags <= SIMPLEREGION) ) + { + if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSEXTSELCLPRGN)) <= GDIBATCHBUFSIZE) + { + PGDIBSEXTSELCLPRGN pgO = (PGDIBSEXTSELCLPRGN)(&pTeb->GdiTebBatch.Buffer[0] + + pTeb->GdiTebBatch.Offset); + pgO->gbHdr.Cmd = GdiBCExtSelClipRgn; + pgO->gbHdr.Size = sizeof(GDIBSEXTSELCLPRGN); + pgO->fnMode = iMode; + + if ( hrgn && pRgn_Attr ) + { + Ret = pRgn_Attr->Flags; + + if ( pDc_Attr->VisRectRegion.Rect.left >= pRgn_Attr->Rect.right || + pDc_Attr->VisRectRegion.Rect.top >= pRgn_Attr->Rect.bottom || + pDc_Attr->VisRectRegion.Rect.right <= pRgn_Attr->Rect.left || + pDc_Attr->VisRectRegion.Rect.bottom <= pRgn_Attr->Rect.top ) + Ret = NULLREGION; + + pgO->left = pRgn_Attr->Rect.left; + pgO->top = pRgn_Attr->Rect.top; + pgO->right = pRgn_Attr->Rect.right; + pgO->bottom = pRgn_Attr->Rect.bottom; + } + else + { + Ret = pDc_Attr->VisRectRegion.Flags; + pgO->fnMode |= 0x80000000; // Set no hrgn mode. + } + pTeb->GdiTebBatch.Offset += sizeof(GDIBSEXTSELCLPRGN); + pTeb->GdiBatchCount++; + if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); + if ( NewRgn ) DeleteObject(NewRgn); + return Ret; + } + } + } + } +#endif + } + Ret = NtGdiExtSelectClipRgn(hdc, hrgn, iMode); + + if ( NewRgn ) DeleteObject(NewRgn); + + return Ret; } /* diff --git a/dll/win32/kernel32/file/dir.c b/dll/win32/kernel32/file/dir.c index 97c04470e75..848d4f8f543 100644 --- a/dll/win32/kernel32/file/dir.c +++ b/dll/win32/kernel32/file/dir.c @@ -741,7 +741,7 @@ GetShortPathNameW ( } /* check for drive letter */ - if (longpath[1] == ':' ) + if (longpath[0] != '/' && longpath[1] == ':' ) { tmpshortpath[0] = longpath[0]; tmpshortpath[1] = ':'; @@ -772,7 +772,7 @@ GetShortPathNameW ( tmplen = p - (longpath + lp); lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1); /* Check, if the current element is a valid dos name */ - if (tmplen <= 8+1+3+1) + if (tmplen <= 8+1+3) { BOOLEAN spaces; memcpy(ustr_buf, longpath + lp, tmplen * sizeof(WCHAR)); diff --git a/dll/win32/msacm32/msacm32.rbuild b/dll/win32/msacm32/msacm32.rbuild index df9cb0340ef..b6f802ee5bb 100644 --- a/dll/win32/msacm32/msacm32.rbuild +++ b/dll/win32/msacm32/msacm32.rbuild @@ -1,6 +1,6 @@ - + . diff --git a/dll/win32/mscoree/mscoree.spec b/dll/win32/mscoree/mscoree.spec index 9365f189b51..8e25cec2b7d 100644 --- a/dll/win32/mscoree/mscoree.spec +++ b/dll/win32/mscoree/mscoree.spec @@ -7,7 +7,7 @@ @ stub CallFunctionShim @ stub CloseCtrs -@ stub ClrCreateManagedInstance +@ stdcall ClrCreateManagedInstance(wstr ptr ptr) @ stub CoEEShutDownCOM @ stdcall CoInitializeCor(long) @ stub CoInitializeEE diff --git a/dll/win32/mscoree/mscoree_main.c b/dll/win32/mscoree/mscoree_main.c index dcdc91a5cc1..5b20c854c2e 100644 --- a/dll/win32/mscoree/mscoree_main.c +++ b/dll/win32/mscoree/mscoree_main.c @@ -91,9 +91,9 @@ HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor { WCHAR *mono_exe; - FIXME("(%s, %s, %s, %p, %d, %p, %p, %p): semi-stub!\n", debugstr_w(pwszVersion), + FIXME("(%s, %s, %s, %p, %d, %s, %s, %p): semi-stub!\n", debugstr_w(pwszVersion), debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved, - startupFlags, rclsid, riid, ppv); + startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv); if (!(mono_exe = get_mono_exe())) { @@ -144,6 +144,11 @@ __int32 WINAPI _CorExeMain(void) PROCESS_INFORMATION pi; WCHAR *mono_exe, *cmd_line; DWORD size, exit_code; + static const WCHAR WINE_MONO_TRACE[]={'W','I','N','E','_','M','O','N','O','_','T','R','A','C','E',0}; + static const WCHAR trace_switch_start[]={'"','-','-','t','r','a','c','e','=',0}; + static const WCHAR trace_switch_end[]={'"',' ',0}; + int trace_size; + WCHAR trace_setting[256]; if (!(mono_exe = get_mono_exe())) { @@ -151,7 +156,13 @@ __int32 WINAPI _CorExeMain(void) return -1; } + trace_size = GetEnvironmentVariableW(WINE_MONO_TRACE, trace_setting, sizeof(trace_setting)/sizeof(WCHAR)); + size = (lstrlenW(mono_exe) + lstrlenW(GetCommandLineW()) + 1) * sizeof(WCHAR); + + if (trace_size) + size += (trace_size + lstrlenW(trace_switch_start) + lstrlenW(trace_switch_end)) * sizeof(WCHAR); + if (!(cmd_line = HeapAlloc(GetProcessHeap(), 0, size))) { HeapFree(GetProcessHeap(), 0, mono_exe); @@ -160,6 +171,14 @@ __int32 WINAPI _CorExeMain(void) lstrcpyW(cmd_line, mono_exe); HeapFree(GetProcessHeap(), 0, mono_exe); + + if (trace_size) + { + lstrcatW(cmd_line, trace_switch_start); + lstrcatW(cmd_line, trace_setting); + lstrcatW(cmd_line, trace_switch_end); + } + lstrcatW(cmd_line, GetCommandLineW()); TRACE("new command line: %s\n", debugstr_w(cmd_line)); @@ -271,7 +290,7 @@ HRESULT WINAPI CoInitializeCor(DWORD fFlags) HRESULT WINAPI GetAssemblyMDImport(LPCWSTR szFileName, REFIID riid, IUnknown **ppIUnk) { - FIXME("(%p %s, %p, %p): stub\n", szFileName, debugstr_w(szFileName), riid, *ppIUnk); + FIXME("(%p %s, %s, %p): stub\n", szFileName, debugstr_w(szFileName), debugstr_guid(riid), *ppIUnk); return ERROR_CALL_NOT_IMPLEMENTED; } @@ -324,6 +343,12 @@ HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID return E_NOTIMPL; } +STDAPI ClrCreateManagedInstance(LPCWSTR pTypeName, REFIID riid, void **ppObject) +{ + FIXME("(%s,%s,%p)\n", debugstr_w(pTypeName), debugstr_guid(riid), ppObject); + return E_NOTIMPL; +} + BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags) { FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename), inFlags, pOutFlags); @@ -338,7 +363,7 @@ BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerifi HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { - FIXME("(%p, %p, %p): stub\n", rclsid, riid, ppv); + FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); if(!ppv) return E_INVALIDARG; diff --git a/dll/win32/msimtf/activeimmapp.c b/dll/win32/msimtf/activeimmapp.c index 73ce0758c70..d8446267893 100644 --- a/dll/win32/msimtf/activeimmapp.c +++ b/dll/win32/msimtf/activeimmapp.c @@ -655,7 +655,7 @@ static HRESULT WINAPI ActiveIMMApp_Deactivate(IActiveIMMApp* This) static HRESULT WINAPI ActiveIMMApp_OnDefWindowProc(IActiveIMMApp* This, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) { - FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam); + //FIXME("Stub (%p %x %lx %lx)\n",hWnd,Msg,wParam,lParam); return E_FAIL; } diff --git a/dll/win32/netcfgx/lang/cs-CZ.rc b/dll/win32/netcfgx/lang/cs-CZ.rc index 887cb443c8d..5aff39c2e5b 100644 --- a/dll/win32/netcfgx/lang/cs-CZ.rc +++ b/dll/win32/netcfgx/lang/cs-CZ.rc @@ -1,12 +1,17 @@ -LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +/* FILE: dll/win32/netcfgx/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * UPDATED: 2010-03-14 + * THANKS TO: potapnik, who translated part of this file + */ +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT IDD_TCPIP_BASIC_DLG DIALOGEX DISCARDABLE 0, 0, 246, 228 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Obecn nastaven" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Konfigurace IP adres me probhnout automaticky, pokud to Vae s dovoluje. V opanm ppad kontaktujte sprvce st pro sprvn nastaven.", -1, 9, 9, 228, 27 + LTEXT "Konfigurace IP adres me probhnout automaticky, pokud to s dovoluje. V opanm ppad kontaktujte sprvce st pro sprvn nastaven.", -1, 9, 9, 228, 27 CONTROL "Zskat IP adresu automaticky", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 43, 210, 12 GROUPBOX "", -1, 9, 61, 228, 70, BS_GROUPBOX CONTROL "&Pout nsledujc IP adresu:", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON, 14, 59, 105, 12 @@ -28,43 +33,43 @@ END IDD_TCPIP_ALTCF_DLG DIALOGEX DISCARDABLE 0, 0, 246, 228 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION -CAPTION "Alternate Configuration" +CAPTION "Alternativn konfigurace" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "If this computer is used on more than one network, enter the alternate IP settings below", -1, 9, 9, 220, 20 - CONTROL "Au&tomatic private IP address", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 40, 210, 12 + LTEXT "Pokud je tento pota pouvn ve vce ne jedn sti, lze zadat alternativn nastaven ne", -1, 9, 9, 220, 20 + CONTROL "Au&tomatick privtn IP adresa", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 40, 210, 12 GROUPBOX "", -1, 9, 55, 228, 80, BS_GROUPBOX - CONTROL "U&ser configured", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 55, 70, 12 - LTEXT "&IP address:", -1, 14, 75, 135, 8 + CONTROL "&Uivatelsk nastaven", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 14, 55, 70, 12 + LTEXT "&IP adresa:", -1, 14, 75, 135, 8 CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 150, 75, 80, 12 - LTEXT "S&ubnet mask:", -1, 14, 95, 135, 8 + LTEXT "&Maska podst:", -1, 14, 95, 135, 8 CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",WS_TABSTOP, 150, 95, 80, 12 - LTEXT "&Default gateway:", -1, 14, 115, 135, 8 + LTEXT "&Vchoz brna:", -1, 14, 115, 135, 8 CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",WS_TABSTOP, 150, 115, 80, 12 - LTEXT "&Preferred DNS server:", -1, 14, 150, 135, 8 + LTEXT "&Preferovan DNS server:", -1, 14, 150, 135, 8 CONTROL "",IDC_DNS1,"SysIPAddress32",WS_TABSTOP, 150, 150, 80, 12 - LTEXT "&Alternate DNS server:", -1, 14, 165, 180, 8 + LTEXT "&Alternativn DNS server:", -1, 14, 165, 180, 8 CONTROL "",IDC_DNS2,"SysIPAddress32",WS_TABSTOP, 150, 165, 80, 12 END IDD_TCPIP_ADVIP_DLG DIALOGEX DISCARDABLE 0, 0, 247, 247 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION -CAPTION "IP Settings" +CAPTION "IP nastaven" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "IP addresses", -1, 5, 5, 240, 90 + GROUPBOX "IP adresy", -1, 5, 5, 240, 90 CONTROL "", IDC_IPLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 15, 210, 55 - PUSHBUTTON "Add...", IDC_IPADD, 60, 75, 50, 14, WS_TABSTOP - PUSHBUTTON "Edit...", IDC_IPMOD, 120, 75, 50, 14, WS_TABSTOP - PUSHBUTTON "Remove", IDC_IPDEL, 180, 75, 50, 14, WS_TABSTOP - GROUPBOX "Default gateways:", -1, 5, 100, 240, 90 + PUSHBUTTON "Pidat...", IDC_IPADD, 60, 75, 50, 14, WS_TABSTOP + PUSHBUTTON "Upravit...", IDC_IPMOD, 120, 75, 50, 14, WS_TABSTOP + PUSHBUTTON "Odebrat", IDC_IPDEL, 180, 75, 50, 14, WS_TABSTOP + GROUPBOX "Vchoz brny:", -1, 5, 100, 240, 90 CONTROL "", IDC_GWLIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 110, 210, 55 - PUSHBUTTON "Add...", IDC_GWADD, 60, 170, 50, 14, WS_TABSTOP - PUSHBUTTON "Edit...", IDC_GWMOD, 120, 170, 50, 14, WS_TABSTOP - PUSHBUTTON "Remove", IDC_GWDEL, 180, 170, 50, 14, WS_TABSTOP + PUSHBUTTON "Pidat...", IDC_GWADD, 60, 170, 50, 14, WS_TABSTOP + PUSHBUTTON "Upravit...", IDC_GWMOD, 120, 170, 50, 14, WS_TABSTOP + PUSHBUTTON "Odebrat", IDC_GWDEL, 180, 170, 50, 14, WS_TABSTOP GROUPBOX "", -1, 5, 200, 240, 30 - CHECKBOX "Automatic metric", IDC_AUTOMETRIC, 9, 200, 90, 12, BS_AUTOCHECKBOX | WS_TABSTOP - LTEXT "Interface metric:", -1, 15, 215, 90, 12 + CHECKBOX "Automatick metrika", IDC_AUTOMETRIC, 9, 200, 90, 12, BS_AUTOCHECKBOX | WS_TABSTOP + LTEXT "Metrika rozhran:", -1, 15, 215, 90, 12 EDITTEXT IDC_METRIC, 110, 212, 50, 12, WS_TABSTOP | ES_NUMBER END @@ -74,158 +79,158 @@ CAPTION "DNS" FONT 8, "MS Shell Dlg" BEGIN LISTBOX IDC_DNSADDRLIST, 5, 15, 180, 60, LBS_NOTIFY - LTEXT "D&NS server addresses, in order of use:", -1, 5, 5, 180, 12 - PUSHBUTTON "Up", IDC_DNSADDRUP, 190, 30, 50, 14, WS_TABSTOP - PUSHBUTTON "Down", IDC_DNSADDRDOWN, 190, 50, 50, 14, WS_TABSTOP - PUSHBUTTON "&Add...", IDC_DNSADDRADD, 30, 70, 50, 14, WS_TABSTOP - PUSHBUTTON "&Edit...", IDC_DNSADDRMOD, 100, 70, 50, 14, WS_TABSTOP - PUSHBUTTON "Remo&ve", IDC_DNSADDRDEL, 170, 70, 50, 14, WS_TABSTOP - LTEXT "The following three settings are applied to all connections with TCP/IP enabled. For resolution of unqualified names:", -1, 5, 90, 220, 24 - CONTROL "Append &primary and connection specific DNS suffixes", IDC_PRIMSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 110, 160, 12 - CHECKBOX "Append parent suffi&xes of the primary DNS suffix", IDC_TOPPRIMSUFFIX, 15, 125, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP - CONTROL "Append t&hese DNS suffixes(in order):", IDC_SELSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 140, 190, 12 + LTEXT "&Adresy DNS server v poad vyuit:", -1, 5, 5, 180, 12 + PUSHBUTTON "Nahoru", IDC_DNSADDRUP, 190, 30, 50, 14, WS_TABSTOP + PUSHBUTTON "Dol", IDC_DNSADDRDOWN, 190, 50, 50, 14, WS_TABSTOP + PUSHBUTTON "&Pidat...", IDC_DNSADDRADD, 30, 70, 50, 14, WS_TABSTOP + PUSHBUTTON "&Upravit...", IDC_DNSADDRMOD, 100, 70, 50, 14, WS_TABSTOP + PUSHBUTTON "&Odebrat", IDC_DNSADDRDEL, 170, 70, 50, 14, WS_TABSTOP + LTEXT "Nsledujc ti nastaven jsou aplikovna na vechna pipojen s povolenm TCP/IP. Pi rezoluci nekvalifikovanch jmen:", -1, 5, 90, 220, 24 + CONTROL "Pipojit p&rimrn a pipojenm dan DNS ppony", IDC_PRIMSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 110, 160, 12 + CHECKBOX "Pipojit rodiovsk ppony primrn DNS ppony", IDC_TOPPRIMSUFFIX, 15, 125, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CONTROL "Pipojit &tyto DNS ppony (v tomto poad):", IDC_SELSUFFIX, "BUTTON", BS_AUTORADIOBUTTON, 5, 140, 190, 12 LISTBOX IDC_DNSSUFFIXLIST, 5, 155, 180, 60, LBS_NOTIFY - PUSHBUTTON "Up", IDC_DNSSUFFIXUP, 190, 170, 50, 14, WS_TABSTOP - PUSHBUTTON "Down", IDC_DNSSUFFIXDOWN, 190, 190, 50, 14, WS_TABSTOP - PUSHBUTTON "&Add...", IDC_DNSSUFFIXADD, 30, 210, 50, 14, WS_TABSTOP - PUSHBUTTON "&Edit...", IDC_DNSSUFFIXMOD, 100, 210, 50, 14, WS_TABSTOP - PUSHBUTTON "Remo&ve", IDC_DNSSUFFIXDEL, 170, 210, 50, 14, WS_TABSTOP - LTEXT "DNS &suffix for this connection:", -1, 5, 225, 110, 14 + PUSHBUTTON "Nahoru", IDC_DNSSUFFIXUP, 190, 170, 50, 14, WS_TABSTOP + PUSHBUTTON "Dol", IDC_DNSSUFFIXDOWN, 190, 190, 50, 14, WS_TABSTOP + PUSHBUTTON "&Pidat...", IDC_DNSSUFFIXADD, 30, 210, 50, 14, WS_TABSTOP + PUSHBUTTON "&Upravit...", IDC_DNSSUFFIXMOD, 100, 210, 50, 14, WS_TABSTOP + PUSHBUTTON "&Odebrat", IDC_DNSSUFFIXDEL, 170, 210, 50, 14, WS_TABSTOP + LTEXT "DNS ppo&na tohoto pipojen:", -1, 5, 225, 110, 14 EDITTEXT IDC_SUFFIX, 120, 225, 100, 12, WS_TABSTOP - CHECKBOX "&Register this connection's addresses in DNS", IDC_REGSUFFIX, 15, 240, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "&Use this connection's DNS suffix in DNS registration", IDC_USESUFFIX, 15, 255, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "Registrovat &adresy tohoto pipojen v DNS", IDC_REGSUFFIX, 15, 240, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "P&out DNS pponu tohoto pipojen pi DNS registraci", IDC_USESUFFIX, 15, 255, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP END IDD_TCPIP_ADVOPT_DLG DIALOGEX DISCARDABLE 0, 0, 247, 247 STYLE DS_SHELLFONT | WS_CHILD | WS_CAPTION -CAPTION "Options" +CAPTION "Volby" FONT 8, "MS Shell Dlg" BEGIN LISTBOX IDC_OPTLIST, 5, 30, 230, 70 - LTEXT "&Optional settings", -1, 5, 15, 130, 12 - PUSHBUTTON "&Properties", IDC_OPTPROP, 160, 100, 70, 14, WS_TABSTOP - GROUPBOX "Description:", -1, 5, 120, 240, 70 + LTEXT "&Voliteln nastaven", -1, 5, 15, 130, 12 + PUSHBUTTON "&Podrobnosti", IDC_OPTPROP, 160, 100, 70, 14, WS_TABSTOP + GROUPBOX "Popis:", -1, 5, 120, 240, 70 LTEXT "", IDC_OPTDESC, 15, 130, 220, 33 END IDD_TCPIPADDIP_DLG DIALOGEX DISCARDABLE 0, 0, 200, 70 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "TCP/IP Address" +CAPTION "TCP/IP adresa" FONT 8, "MS Shell Dlg" BEGIN CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 100, 15, 80, 12 - LTEXT "IP address:", -1, 5, 15, 70, 12 - LTEXT "Subnet mask:", -1, 5, 30, 70, 12 + LTEXT "IP adresa:", -1, 5, 15, 70, 12 + LTEXT "Maska podst:", -1, 5, 30, 70, 12 CONTROL "",IDC_SUBNETMASK,"SysIPAddress32", WS_TABSTOP, 100, 30, 80, 12 - PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP + PUSHBUTTON "OK", IDC_OK, 50, 50, 50, 14, WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP END IDD_TCPIPGW_DLG DIALOGEX DISCARDABLE 0, 0, 200, 80 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "TCP/IP Gateway Address" +CAPTION "TCP/IP adresa brny" FONT 8, "MS Shell Dlg" BEGIN CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 100, 15, 80, 12 - LTEXT "Gateway:", -1, 5, 15, 70, 12 - CHECKBOX "Automatic metric", IDC_USEMETRIC, 15, 30, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP - LTEXT "&Metric:", IDC_METRICTXT, 5, 45, 45, 12, WS_DISABLED + LTEXT "Brna:", -1, 5, 15, 70, 12 + CHECKBOX "Automatick metrika", IDC_USEMETRIC, 15, 30, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP + LTEXT "&Metrika:", IDC_METRICTXT, 5, 45, 45, 12, WS_DISABLED EDITTEXT IDC_METRIC, 100, 45, 50, 12, WS_TABSTOP | ES_NUMBER | WS_DISABLED PUSHBUTTON "", IDC_OK, 50, 60, 50, 14, WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 110, 60, 50, 14, WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 110, 60, 50, 14, WS_TABSTOP END IDD_TCPIPDNS_DLG DIALOGEX DISCARDABLE 0, 0, 200, 80 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "TCP/IP DNS Server" +CAPTION "TCP/IP DNS server" FONT 8, "MS Shell Dlg" BEGIN CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP, 5, 25, 80, 12 LTEXT "DNS server:", -1, 5, 10, 120, 12 PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP END IDD_TCPIPSUFFIX_DLG DIALOGEX DISCARDABLE 0, 0, 200, 80 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "TCP/IP Domain Suffix" +CAPTION "TCP/IP domnov ppona" FONT 8, "MS Shell Dlg" BEGIN EDITTEXT IDC_SUFFIX, 5, 25, 190, 12, WS_TABSTOP - LTEXT "Domain suffix:", -1, 5, 10, 120, 12 + LTEXT "Domnov ppona:", -1, 5, 10, 120, 12 PUSHBUTTON "", IDC_OK, 50, 50, 50, 14, WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 110, 50, 50, 14, WS_TABSTOP END IDD_TCPIP_FILTER_DLG DIALOGEX DISCARDABLE 0, 0, 305, 220 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "TCP/IP Filtering" +CAPTION "TCP/IP filtrovn" FONT 8, "MS Shell Dlg" BEGIN - CHECKBOX "Enable TCP/IP-Filtering (All adapters)", IDC_USE_FILTER, 15, 5, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "Zapnout filtrovn TCP/IP (vechny adaptry)", IDC_USE_FILTER, 15, 5, 190, 12, BS_AUTOCHECKBOX | WS_TABSTOP GROUPBOX "", -1, 5, 30, 90, 150 - CONTROL "Permit All", IDC_TCP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 30, 70, 12 - CONTROL "Permit Only", IDC_TCP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 44, 70, 12 + CONTROL "Povolit ve", IDC_TCP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 30, 70, 12 + CONTROL "Povolit pouze", IDC_TCP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 15, 44, 70, 12 CONTROL "", IDC_TCP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 11, 62, 72, 75 - PUSHBUTTON "Add", IDC_TCP_ADD, 15, 141, 50, 14, WS_TABSTOP - PUSHBUTTON "Remove", IDC_TCP_DEL, 15, 161, 50, 14, WS_TABSTOP + PUSHBUTTON "Pidat", IDC_TCP_ADD, 15, 141, 50, 14, WS_TABSTOP + PUSHBUTTON "Odebrat", IDC_TCP_DEL, 15, 161, 50, 14, WS_TABSTOP GROUPBOX "", -1, 105, 30, 90, 150 - CONTROL "Permit All", IDC_UDP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 30, 70, 12 - CONTROL "Permit Only", IDC_UDP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 44, 70, 12 + CONTROL "Povolit ve", IDC_UDP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 30, 70, 12 + CONTROL "Povolit pouze", IDC_UDP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 115, 44, 70, 12 CONTROL "", IDC_UDP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 111, 62, 72, 75 - PUSHBUTTON "Add", IDC_UDP_ADD, 115, 141, 50, 14, WS_TABSTOP - PUSHBUTTON "Remove", IDC_UDP_DEL, 115, 161, 50, 14, WS_TABSTOP + PUSHBUTTON "Pidat", IDC_UDP_ADD, 115, 141, 50, 14, WS_TABSTOP + PUSHBUTTON "Odebrat", IDC_UDP_DEL, 115, 161, 50, 14, WS_TABSTOP GROUPBOX "", -1, 205, 30, 90, 150 - CONTROL "Permit All", IDC_IP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 30, 70, 12 - CONTROL "Permit Only", IDC_IP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 44, 70, 12 + CONTROL "Povolit ve", IDC_IP_ALLOW_ALL, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 30, 70, 12 + CONTROL "Povolit pouze", IDC_IP_RESTRICT, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 215, 44, 70, 12 CONTROL "", IDC_IP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 211, 62, 72, 75 - PUSHBUTTON "Add", IDC_IP_ADD, 215, 141, 50, 14, WS_TABSTOP - PUSHBUTTON "Remove", IDC_IP_DEL, 215, 161, 50, 14, WS_TABSTOP + PUSHBUTTON "Pidat", IDC_IP_ADD, 215, 141, 50, 14, WS_TABSTOP + PUSHBUTTON "Odebrat", IDC_IP_DEL, 215, 161, 50, 14, WS_TABSTOP PUSHBUTTON "OK", IDC_OK, 150, 190, 50, 14, WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 210, 190, 50, 14, WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 210, 190, 50, 14, WS_TABSTOP END IDD_TCPIP_PORT_DLG DIALOGEX DISCARDABLE 0, 0, 200, 60 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add Filter" +CAPTION "Pidat filtr" FONT 8, "MS Shell Dlg" BEGIN EDITTEXT IDC_PORT_VAL, 5, 30, 70, 12, WS_TABSTOP | ES_NUMBER LTEXT "", IDC_PORT_DESC, 5, 15, 40, 12 PUSHBUTTON "OK", IDC_OK, 120, 15, 50, 14, WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 120, 30, 50, 14, WS_TABSTOP + PUSHBUTTON "Storno", IDCANCEL, 120, 30, 50, 14, WS_TABSTOP END STRINGTABLE BEGIN - IDS_NET_CONNECT "Network connection" - IDS_NO_IPADDR_SET "The adapter requires at least one IP address. Please enter one." - IDS_NO_SUBMASK_SET "You have entered an address that is missing its subnet mask. Please add a subnet mask." - IDS_TCPFILTERDESC "TCP/IP filtering allows you to control the type of TCP/IP network traffic that reaches your computer." - IDS_TCPFILTER "TCP/IP Filtering" - IDS_IPADDR "IP address" - IDS_SUBMASK "Subnet mask" - IDS_GATEWAY "Gateway" - IDS_METRIC "Metric" - IDS_DHCPACTIVE "DHCP Enabled" - IDS_AUTOMATIC "Automatic" - IDS_NOITEMSEL "You have not selected an item. Select one first." + IDS_NET_CONNECT "Sov pipojen" + IDS_NO_IPADDR_SET "Adaptr vyaduje zadn alespo jedn IP adresy." + IDS_NO_SUBMASK_SET "K zadan adrese je nutn doplnit masku podst." + IDS_TCPFILTERDESC "TCP/IP filtrovn dovoluje kontrolovat typ TCP/IP sovho provozu, kter se dostane k tomuto potai." + IDS_TCPFILTER "TCP/IP filtrovn" + IDS_IPADDR "IP adresa" + IDS_SUBMASK "Maska podst" + IDS_GATEWAY "Brna" + IDS_METRIC "Metrika" + IDS_DHCPACTIVE "DHCP zapnuto" + IDS_AUTOMATIC "Automaticky" + IDS_NOITEMSEL "Nebyla vybrna dn poloka." IDS_TCPIP "ReactOS-TCP/IP" - IDS_ADD "Add" + IDS_ADD "Pidat" IDS_MOD "OK" - IDS_TCP_PORTS "TCP Ports" - IDS_UDP_PORTS "UDP Ports" - IDS_IP_PROTO "IP protocols" - IDS_PORT_RANGE "Port numbers must be greater than 0 and less than 65536. Please enter a number within this range." - IDS_PROT_RANGE "Protocol numbers must be greater than 0 and less than 256. Please enter a number within this range." - IDS_DUP_NUMBER "The number you are trying to add is already in the list. Please enter a different number." - IDS_DISABLE_FILTER "Disabling this global TCP/IP setting will affect all adapters." - IDS_NO_SUFFIX "The current setting of search method requires at least one DNS suffix. Please enter one or change the setting." - IDS_DOMAIN_SUFFIX "Domain suffix is not a valid suffix." - IDS_DNS_SUFFIX "The DNS domain name ""%s"" is not a valid DNS name." - IDS_DUP_SUFFIX "The DNS suffix is already on the list." - IDS_DUP_IPADDR "The IP address is already on the list." - IDS_DUP_GW "The default gateway is already on the list." + IDS_TCP_PORTS "TCP porty" + IDS_UDP_PORTS "UDP porty" + IDS_IP_PROTO "IP protokoly" + IDS_PORT_RANGE "sla port mus bt zadna vy ne 0 a ni ne 65536." + IDS_PROT_RANGE "sla protokol mus bt zadna vy ne 0 a ni ne 256." + IDS_DUP_NUMBER "Pidvan slo se u nachz v seznamu. Je nutn zadat jin slo." + IDS_DISABLE_FILTER "Vypnut tohoto globlnho nastaven TCP/IP ovlivn vechny adaptry." + IDS_NO_SUFFIX "Souasn nastaven metod vyhledvn vyaduje alespo jednu DNS pponu. Je nutn ji zadat nebo zmnit nastaven." + IDS_DOMAIN_SUFFIX "Zadan domnov ppona nen platn." + IDS_DNS_SUFFIX "DNS domnov jmno ""%s"" nen platn." + IDS_DUP_SUFFIX "DNS ppona se u nachz v seznamu." + IDS_DUP_IPADDR "IP adresa se u nachz v seznamu." + IDS_DUP_GW "Vchoz brna se u nachz v seznamu." END diff --git a/dll/win32/netid/lang/cs-CZ.rc b/dll/win32/netid/lang/cs-CZ.rc index 886ad7ac864..41a04f6c041 100644 --- a/dll/win32/netid/lang/cs-CZ.rc +++ b/dll/win32/netid/lang/cs-CZ.rc @@ -1,6 +1,6 @@ /* FILE: dll/win32/netid/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2008-06-26 + * UPDATED: 2010-03-14 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -18,10 +18,9 @@ BEGIN LTEXT "(Implicitn)", IDC_COMPUTERNAME, 98, 68, 144, 11 LTEXT "Pracovn skupina:", IDC_WORKGROUPDOMAIN, 6, 84, 64, 9 LTEXT "(przdn)", IDC_WORKGROUPDOMAIN_NAME, 98, 84, 144, 9 - LTEXT "Pokud chcete pout Prvodce sovou identifikac k pipojen se k domn a vytvoen mstnho uivatele, kliknte na ""Sov ID"".", IDC_STATIC, 6, 113, 172, 24 - //musi zustat jako sitova ID, jinak se nevejde na tlacitko! - PUSHBUTTON "&Sov ID...", IDC_NETWORK_ID, 190, 114, 58, 15 - LTEXT "Pokud chcete pejmenovat tento pota nebo se pipojit k domn, kliknte na ""Zmnit"".", IDC_STATIC, 6, 149, 170, 17 + LTEXT "Kliknutm na ""Sov ID"" lze pout Prvodce sovou identifikac k pipojen se k domn a vytvoen mstnho uivatele.", IDC_STATIC, 6, 113, 172, 24 + PUSHBUTTON "&Sov ID...", IDC_NETWORK_ID, 190, 114, 58, 15 //FIXME nic vic nez "sitova ID" se nevejde na tlacitko! + LTEXT "Kliknutm na ""Zmnit"" lze pejmenovat tento pota nebo se pipojit k domn.", IDC_STATIC, 6, 149, 170, 17 PUSHBUTTON "&Zmnit...",IDC_NETWORK_PROPERTY, 190, 149, 58, 15 LTEXT "Poznmka: Identifikaci tohoto potae mohou zmnit pouze administrtoi.", IDC_STATIC, 6, 179, 300, 9 END @@ -31,7 +30,7 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_CAPTIO CAPTION "Zmna nzvu potae" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "(message goes here)", 1017, 7, 5, 218, 30 + LTEXT "(sem pat zprva)", 1017, 7, 5, 218, 30 LTEXT "&Nzev potae:", -1, 7, 41, 219, 8 EDITTEXT 1002, 7, 53, 218, 14, ES_AUTOHSCROLL | ES_OEMCONVERT LTEXT "pln nzev potae:", 1016, 7, 72, 218, 10 @@ -41,7 +40,7 @@ BEGIN AUTORADIOBUTTON "&Domny:", 1008, 17, 132, 192, 10, WS_GROUP AUTORADIOBUTTON "&Pracovn skupiny:", 1004, 17, 161, 191, 10 EDITTEXT 116, 28, 144, 181, 14, ES_AUTOHSCROLL | WS_GROUP - PUSHBUTTON "Najt moj&i domnu", 1010, 7, 203, 109, 14, NOT WS_VISIBLE | WS_DISABLED + PUSHBUTTON "Najt &moji domnu", 1010, 7, 203, 109, 14, NOT WS_VISIBLE | WS_DISABLED EDITTEXT 1007, 28, 172, 181, 14, ES_UPPERCASE | ES_AUTOHSCROLL | ES_OEMCONVERT DEFPUSHBUTTON "OK", 1, 121, 203, 50, 14, WS_GROUP PUSHBUTTON "Storno", 2, 176, 203, 50, 14 @@ -65,7 +64,7 @@ END STRINGTABLE BEGIN 1 "* Neznm *" - 2 "WORKGROUP" + 2 "SKUPINA" 3 "Pi pokusu o naten informac o lenstv v domn nastala nsledujc chyba:" 4 "Zmna nzvu potae" 5 "Pracovn skupina:" @@ -73,12 +72,12 @@ BEGIN 22 "Vtejte v pracovn skupin %1." 23 "Vtejte v domn %1." 24 "Aby se zmny mohly projevit, mus bt pota restartovn." - 25 "You can change the name and the membership of this computer. Changes may affect access to network resources." + 25 "Lze zmnit nzev a lenstv tohoto potae. Zmny mohou mt vliv na pstup k sovm prostedkm." 1021 "Poznmka: Identifikaci tohoto potae mohou zmnit pouze administrtoi." 1022 "Poznmka: Identifikace potae neme bt zmnna z nsledujcch dvod:" - 1030 "The new computer name ""%s"" contains characters which are not allowed. Characters which are not allowed include ` ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / and ?" + 1030 "Nov nzev potae ""%s"" obsahuje nepovolen znaky. Mezi nepovolen znaky pat ` ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / ?" 3210 "&Detaily >>" 3220 "<< &Detaily" - 4000 "Information" - 4001 "Can't set new a computer name!" + 4000 "Informace" + 4001 "Nelze nastavit nov nzev potae!" END diff --git a/dll/win32/netid/lang/it-IT.rc b/dll/win32/netid/lang/it-IT.rc index 26af2b20588..a85b3795367 100644 --- a/dll/win32/netid/lang/it-IT.rc +++ b/dll/win32/netid/lang/it-IT.rc @@ -67,13 +67,13 @@ BEGIN 6 "Dominio:" 22 "Benvenuto al gruppo di lavoro %1." 23 "Benvenuto al dominio %1." - 24 "Il computer deve essre riavviato per rendere operative queste modifiche." - 25 "You can change the name and the membership of this computer. Changes may affect access to network resources." + 24 "Il computer deve essere riavviato per rendere operative queste modifiche." + 25 "Potete modificare il nome e il dominio di questo computer. Le modifiche potrebbero influenzare l'accesso alle risorse di rete." 1021 "Nota: Solo gli Amministratori possono cambiare l'identificazione di questo computer." 1022 "Nota: L'identificazione di questo computer non pu essere cambiata perch:" - 1030 "The new computer name ""%s"" contains characters which are not allowed. Characters which are not allowed include ` ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / and ?" + 1030 "Il nuovo nome del computer ""%s"" contiene dei caratteri non permessi. I caratteri vietati sono `? ~ ! @ # $ %% ^ & * ( ) = + _ [ ] { } \\ | ; : ' \" , . < > / " 3210 "&Dettagli >>" 3220 "<< &Dettagli" - 4000 "Information" - 4001 "Can't set new a computer name!" + 4000 "Informazioni" + 4001 "Impossibile assegnare il nuovo nome del computer!" END diff --git a/dll/win32/netshell/lang/cs-CZ.rc b/dll/win32/netshell/lang/cs-CZ.rc index db5e3ea00b6..b98ecf7c9b8 100644 --- a/dll/win32/netshell/lang/cs-CZ.rc +++ b/dll/win32/netshell/lang/cs-CZ.rc @@ -16,12 +16,12 @@ BEGIN GROUPBOX "Popis", -1, 9, 153, 230, 46, BS_GROUPBOX LTEXT "Tak tady bude popis komponenty...", IDC_DESCRIPTION, 15, 165, 217, 28, WS_GROUP CHECKBOX "Po pipojen zobrazit ikonu na hlavnm panelu", IDC_SHOWTASKBAR, 9, 206, 230, 12, BS_AUTOCHECKBOX | WS_TABSTOP - CHECKBOX "&Notify me when this connection has limited or no connectivity", IDC_NOTIFYNOCONNECTION, 9, 220, 230, 24, BS_AUTOCHECKBOX | WS_TABSTOP + CHECKBOX "&Upozornit, kdy toto pipojen bude mt omezenou nebo dnou konektivitu", IDC_NOTIFYNOCONNECTION, 9, 220, 230, 24, BS_AUTOCHECKBOX | WS_TABSTOP END IDD_STATUS DIALOGEX DISCARDABLE 0, 0, 200, 280 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "General" +CAPTION "Obecn nastaven" FONT 8, "MS Shell Dlg" BEGIN END @@ -65,62 +65,62 @@ BEGIN RTEXT "000.000.000.000", IDC_DETAILSSUBNET, 122, 48, 80, 8 RTEXT "", IDC_DETAILSGATEWAY, 122, 62, 80, 8 - PUSHBUTTON "&Detaily...", IDC_DETAILS, 22, 76, 62, 14 + PUSHBUTTON "&Podrobnosti...", IDC_DETAILS, 22, 76, 62, 14 END IDD_LAN_NETSTATUSDETAILS DIALOGEX DISCARDABLE 0, 0, 200,200 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "Network Connection Details" +CAPTION "Podrobnosti sovho pipojen" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Network Connection &Details:", -1, 15, 9, 170, 12 + LTEXT "&Podrobnosti sovho pipojen:", -1, 15, 9, 170, 12 CONTROL "", IDC_DETAILS, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, 15, 25, 170, 130 - PUSHBUTTON "&Close", IDC_CLOSE, 125, 165, 62, 14 + PUSHBUTTON "&zavt", IDC_CLOSE, 125, 165, 62, 14 END STRINGTABLE DISCARDABLE BEGIN - IDS_PHYSICAL_ADDRESS "Physical Address" - IDS_IP_ADDRESS "IP Address" - IDS_SUBNET_MASK "Subnet Mask" - IDS_DEF_GATEWAY "Default Gateway" - IDS_DHCP_SERVER "DHCP Server" - IDS_LEASE_OBTAINED "Lease Obtained" - IDS_LEASE_EXPIRES "Lease Expires" - IDS_DNS_SERVERS "DNS Servers" - IDS_WINS_SERVERS "WINS Servers" - IDS_PROPERTY "Property" - IDS_VALUE "Value" - IDS_NETWORKCONNECTION "Network Connection" - IDS_SHV_COLUMN_NAME "Name" - IDS_SHV_COLUMN_TYPE "Type" + IDS_PHYSICAL_ADDRESS "Fyzick adresa" + IDS_IP_ADDRESS "IP Adresa" + IDS_SUBNET_MASK "Maska podst" + IDS_DEF_GATEWAY "Vchoz brna" + IDS_DHCP_SERVER "DHCP server" + IDS_LEASE_OBTAINED "Zapjeno" + IDS_LEASE_EXPIRES "Zapjen vypr" + IDS_DNS_SERVERS "DNS servery" + IDS_WINS_SERVERS "WINS servery" + IDS_PROPERTY "Vlastnost" + IDS_VALUE "Hodnota" + IDS_NETWORKCONNECTION "Sov pipojen" + IDS_SHV_COLUMN_NAME "Nzev" + IDS_SHV_COLUMN_TYPE "Typ" IDS_SHV_COLUMN_STATE "Status" - IDS_SHV_COLUMN_DEVNAME "Device Name" - IDS_SHV_COLUMN_PHONE "Phone # or Host Address" - IDS_SHV_COLUMN_OWNER "Owner" - IDS_TYPE_ETHERNET "LAN or High-Speed Internet" - IDS_STATUS_NON_OPERATIONAL "Disabled" - IDS_STATUS_UNREACHABLE "Not Connected" - IDS_STATUS_DISCONNECTED "Network cable unplugged" - IDS_STATUS_CONNECTING "Acquiring network address" - IDS_STATUS_CONNECTED "Connected" - IDS_STATUS_OPERATIONAL "Connected" + IDS_SHV_COLUMN_DEVNAME "Nzev zazen" + IDS_SHV_COLUMN_PHONE "Telefonn slo nebo adresa hostitele" + IDS_SHV_COLUMN_OWNER "Vlastnk" + IDS_TYPE_ETHERNET "LAN nebo vysokorychlostn internet" + IDS_STATUS_NON_OPERATIONAL "Vypnuto" + IDS_STATUS_UNREACHABLE "Nepipojeno" + IDS_STATUS_DISCONNECTED "Sov kabel byl odpojen" + IDS_STATUS_CONNECTING "Zskvm sovou adresu" + IDS_STATUS_CONNECTED "Pipojeno" + IDS_STATUS_OPERATIONAL "Pipojeno" - IDS_NET_ACTIVATE "Enable" - IDS_NET_DEACTIVATE "Disable" + IDS_NET_ACTIVATE "Zapnout" + IDS_NET_DEACTIVATE "Vypnout" IDS_NET_STATUS "Status" - IDS_NET_REPAIR "Repair" - IDS_NET_CREATELINK "Create Shortcut" - IDS_NET_DELETE "Delete" - IDS_NET_RENAME "Rename" - IDS_NET_PROPERTIES "Properties" + IDS_NET_REPAIR "Opravit" + IDS_NET_CREATELINK "Vytvoit zstupce" + IDS_NET_DELETE "Smazat" + IDS_NET_RENAME "Pejmenovat" + IDS_NET_PROPERTIES "Vlasnosti" IDS_FORMAT_BIT "%u Bit/s" IDS_FORMAT_KBIT "%u KBit/s" IDS_FORMAT_MBIT "%u MBit/s" IDS_FORMAT_GBIT "%u GBit/s" - IDS_DURATION_DAY "%d Day %s" - IDS_DURATION_DAYS "%d Days %s" + IDS_DURATION_DAY "%d Den %s" + IDS_DURATION_DAYS "%d Dn %s" IDS_ASSIGNED_DHCP "Piazeno DHCP" IDS_ASSIGNED_MANUAL "Run nastaveno" END diff --git a/dll/win32/ntmarta/ntmarta.c b/dll/win32/ntmarta/ntmarta.c index e077b0570be..f6e77d4cbef 100644 --- a/dll/win32/ntmarta/ntmarta.c +++ b/dll/win32/ntmarta/ntmarta.c @@ -1236,7 +1236,7 @@ AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries, DWORD ObjectsPresent; BOOL needToClean; PSID pSid1, pSid2; - ULONG i; + ULONG i, j; LSA_HANDLE PolicyHandle = NULL; BOOL bRet; DWORD LastErr; @@ -1295,11 +1295,11 @@ AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries, case REVOKE_ACCESS: case SET_ACCESS: /* Discard all accesses for the trustee... */ - for (i = 0; i < SizeInformation.AceCount; i++) + for (j = 0; j < SizeInformation.AceCount; j++) { - if (!pKeepAce[i]) + if (!pKeepAce[j]) continue; - if (!GetAce(OldAcl, i, (PVOID*)&pAce)) + if (!GetAce(OldAcl, j, (PVOID*)&pAce)) { Ret = GetLastError(); goto Cleanup; @@ -1308,7 +1308,7 @@ AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries, pSid2 = AccpGetAceSid(pAce); if (RtlEqualSid(pSid1, pSid2)) { - pKeepAce[i] = FALSE; + pKeepAce[j] = FALSE; SizeInformation.AclBytesInUse -= pAce->AceSize; } } diff --git a/dll/win32/ole32/compobj.c b/dll/win32/ole32/compobj.c index 12f83146113..0625c0b8949 100644 --- a/dll/win32/ole32/compobj.c +++ b/dll/win32/ole32/compobj.c @@ -1566,7 +1566,7 @@ static HRESULT __CLSIDFromString(LPCWSTR s, CLSID *id) /*****************************************************************************/ -HRESULT WINAPI CLSIDFromString(LPOLESTR idstr, CLSID *id ) +HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id ) { HRESULT ret; diff --git a/dll/win32/setupapi/lang/cs-CZ.rc b/dll/win32/setupapi/lang/cs-CZ.rc index 29573ac581d..c1ee9fd7c09 100644 --- a/dll/win32/setupapi/lang/cs-CZ.rc +++ b/dll/win32/setupapi/lang/cs-CZ.rc @@ -1,23 +1,7 @@ -/* Hey, Emacs, open this file with -*- coding: cp1250 -*- - * - * Czech resources for SETUPAPI - * - * Copyright 2001 Andreas Mohr - * Copyright 2004 David Kredba - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +/* FILE: dll/win32/setupapi/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * THANKS TO: David Kredba + * UPDATED: 2010-01-07 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -39,7 +23,7 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_QUERY_REBOOT_TEXT "Your computer needs to be rebooted to finish installation. Do you want to proceed?" - IDS_QUERY_REBOOT_CAPTION "Reboot" - IDS_INF_FILE "Setup Information" + IDS_QUERY_REBOOT_TEXT "Aby mohla bt instalace dokonena, mus bt pota restartovn. Pokraovat?" + IDS_QUERY_REBOOT_CAPTION "Restartovat" + IDS_INF_FILE "Instalan informace" END diff --git a/dll/win32/shell32/dialogs.c b/dll/win32/shell32/dialogs.c index e5aa28f74e8..fa09de07916 100644 --- a/dll/win32/shell32/dialogs.c +++ b/dll/win32/shell32/dialogs.c @@ -344,7 +344,7 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR else pdir[3] = '\0'; } - if (ShellExecuteA(NULL, "open", psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33) + if (ShellExecuteA(NULL, NULL, psz, NULL, pdir, SW_SHOWNORMAL) < (HINSTANCE)33) { char *pszSysMsg = NULL ; FormatMessageA ( @@ -357,7 +357,7 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR ) ; sprintf (szMsg, "Error: %s", pszSysMsg) ; LocalFree ((HLOCAL)pszSysMsg) ; - MessageBoxA (hwnd, szMsg, "Nix", MB_OK | MB_ICONEXCLAMATION) ; + MessageBoxA (hwnd, szMsg, NULL, MB_OK | MB_ICONEXCLAMATION) ; HeapFree(GetProcessHeap(), 0, psz); HeapFree(GetProcessHeap(), 0, pdir); @@ -612,9 +612,11 @@ int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, D int WINAPI LogoffWindowsDialog(HWND hWndOwner) { - UNIMPLEMENTED; - ExitWindowsEx(EWX_LOGOFF, 0); - return 0; + if (ConfirmDialog(hWndOwner, IDS_LOGOFF_PROMPT, IDS_LOGOFF_TITLE)) + { + ExitWindowsEx(EWX_LOGOFF, 0); + } + return 0; } /************************************************************************* diff --git a/dll/win32/shell32/fprop.c b/dll/win32/shell32/fprop.c index 529854ea494..4d9345c469b 100644 --- a/dll/win32/shell32/fprop.c +++ b/dll/win32/shell32/fprop.c @@ -114,7 +114,7 @@ SH_FileGeneralSetFileType(HWND hwndDlg, WCHAR *filext) { /* the file extension is unknown, so default to string "FileExtension File" */ SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)value); - swprintf(name, value, &filext[1]); + swprintf(name, L"%s %s", &filext[1], value); SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)name); return TRUE; } diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc index fea6d988882..13a9bdb9f44 100644 --- a/dll/win32/shell32/lang/bg-BG.rc +++ b/dll/win32/shell32/lang/bg-BG.rc @@ -357,7 +357,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION " " FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -666,6 +666,8 @@ BEGIN IDS_RESTART_PROMPT " ?" IDS_SHUTDOWN_TITLE "" IDS_SHUTDOWN_PROMPT " ?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" // shell folder path default values IDS_PROGRAMS " \\" @@ -750,6 +752,8 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE " " IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc index df5cb9e4b24..214028e7d8e 100644 --- a/dll/win32/shell32/lang/ca-ES.rc +++ b/dll/win32/shell32/lang/ca-ES.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc index b08beea99f9..1f4fc948540 100644 --- a/dll/win32/shell32/lang/cs-CZ.rc +++ b/dll/win32/shell32/lang/cs-CZ.rc @@ -1,21 +1,7 @@ -/* - * Copyright 1998 Juergen Schmied - * Copyright 2003 Filip Navara - * Copyright 2008 Radek Liska - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +/* FILE: dll/win32/shell32/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * UPDATED: 2010-04-05 + * THANKS TO: navaraf, who translated major part of this file */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -208,18 +194,18 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 10, 3, 30, 30, WS_VISIBLE EDITTEXT 14001, 70, 9, 158, 14, ES_LEFT | ES_READONLY - LTEXT "Type of file:", 14004, 8, 35, 50, 10 - LTEXT "Folder", 14005, 68, 35, 160, 10 - LTEXT "Location:", 14006, 8, 53, 50, 10 + LTEXT "Typ souboru:", 14004, 8, 35, 50, 10 + LTEXT "Sloka", 14005, 68, 35, 160, 10 + LTEXT "Umstn:", 14006, 8, 53, 50, 10 LTEXT "", 14007, 68, 53, 315, 10 - LTEXT "Size:", 14008, 8, 72, 45, 10 + LTEXT "Velikost:", 14008, 8, 72, 45, 10 LTEXT "", 14009, 68, 72, 315, 10 - LTEXT "Contains:", 14010, 8, 93, 45, 10 + LTEXT "Obsahuje:", 14010, 8, 93, 45, 10 LTEXT "", 14011, 68, 93, 160, 10 - LTEXT "Created:", 14014, 8, 118, 45, 10 + LTEXT "Vytvoeno:", 14014, 8, 118, 45, 10 LTEXT "", 14015, 68, 118, 160, 10 - AUTOCHECKBOX "&Read-only", 14021, 45, 150, 67, 10 - AUTOCHECKBOX "&Hidden", 14022, 126, 150, 50, 10 + AUTOCHECKBOX "&Jen pro ten", 14021, 45, 150, 67, 10 + AUTOCHECKBOX "&Skryt", 14022, 126, 150, 50, 10 END SHELL_FILE_GENERAL_DLG DIALOGEX 0, 0, 240, 205 @@ -360,7 +346,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Otevt v..." FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -546,7 +532,7 @@ END FORMAT_DLG DIALOGEX 50, 50, 184, 218 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Format" +CAPTION "Formtovn" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "&Spustit", IDOK, 53, 198, 60, 14 @@ -567,14 +553,14 @@ END CHKDSK_DLG DIALOGEX 50, 50, 194, 120 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Check Disk" +CAPTION "Zkontrolovat disk" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "Start", IDOK, 53, 100, 60, 14 - GROUPBOX "Check disk options", -1, 7, 6, 179, 50 - PUSHBUTTON "Cancel", IDCANCEL, 118, 100, 60, 14 - AUTOCHECKBOX "Automatically fix file system errors", 14000, 16, 15, 155, 10 - AUTOCHECKBOX "&Scan for and attempt recovery of bad sectors", 14001, 16, 30, 165, 10 + GROUPBOX "Monosti kontroly disku", -1, 7, 6, 179, 50 + PUSHBUTTON "Storno", IDCANCEL, 118, 100, 60, 14 + AUTOCHECKBOX "Automaticky opravovat chyby souborovho systmu", 14000, 16, 15, 155, 10 + AUTOCHECKBOX "&Vyhledat a pokusit se obnovit vadn sektory", 14001, 16, 30, 165, 10 CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 60, 170, 8 LTEXT "", 14003, 60, 80, 170, 10 END @@ -607,17 +593,17 @@ BEGIN IDS_SHV_COLUMN9 "Koment" IDS_SHV_COLUMN10 "Vlastnk" IDS_SHV_COLUMN11 "Skupina" - IDS_SHV_COLUMN12 "Filename" - IDS_SHV_COLUMN13 "Category" + IDS_SHV_COLUMN12 "Nzev souboru" + IDS_SHV_COLUMN13 "Kategorie" IDS_SHV_COLUMN_DELFROM "Pvodn umstn" IDS_SHV_COLUMN_DELDATE "Odstranno" IDS_SHV_COLUMN_FONTTYPE "Fonttype" - IDS_SHV_COLUMN_WORKGROUP "Workgroup" - IDS_SHV_NETWORKLOCATION "Network Location" - IDS_SHV_COLUMN_DOCUMENTS "Documents" + IDS_SHV_COLUMN_WORKGROUP "Pracovn skupina" + IDS_SHV_NETWORKLOCATION "Sov umstn" + IDS_SHV_COLUMN_DOCUMENTS "Dokumenty" IDS_SHV_COLUMN_STATUS "Status" - IDS_SHV_COLUMN_COMMENTS "Comments" - IDS_SHV_COLUMN_LOCATION "Location" + IDS_SHV_COLUMN_COMMENTS "Komente" + IDS_SHV_COLUMN_LOCATION "Umstn" IDS_SHV_COLUMN_MODEL "Model" /* special folders */ @@ -625,7 +611,7 @@ BEGIN IDS_MYCOMPUTER "Tento pota" IDS_RECYCLEBIN_FOLDER_NAME "Ko" IDS_CONTROLPANEL "Ovldac panely" - IDS_ADMINISTRATIVETOOLS "Administrative Tools" + IDS_ADMINISTRATIVETOOLS "Nstroje sprvy" /* context menus */ IDS_VIEW_LARGE "&Vedle sebe" @@ -634,15 +620,15 @@ BEGIN IDS_VIEW_DETAILS "&Podrobnosti" IDS_SELECT "Vybrat" IDS_OPEN "Otevt" - IDS_CREATELINK "Vytvoit zstupc&e" + IDS_CREATELINK "Vytvoit zstupc&e" IDS_COPY "&Koprovat" IDS_DELETE "O&dstranit" IDS_PROPERTIES "&Vlastnosti" IDS_CUT "Vyj&mout" - IDS_RESTORE "Restore" - IDS_FORMATDRIVE "Format..." - IDS_RENAME "Rename" - IDS_INSERT "Insert" + IDS_RESTORE "Obnovit" + IDS_FORMATDRIVE "Formtovat..." + IDS_RENAME "Pejmenovat" + IDS_INSERT "Vloit" IDS_CREATEFOLDER_DENIED "Nelze vytvoit novou sloku, protoe pstup byl odepen." IDS_CREATEFOLDER_CAPTION "Chyba pi pokusu vytvoit nov adres" @@ -666,6 +652,8 @@ BEGIN IDS_RESTART_PROMPT "Opravdu chcete restartovat systm?" IDS_SHUTDOWN_TITLE "Vypnout" IDS_SHUTDOWN_PROMPT "Opravdu chcete vypnout pota?" + IDS_LOGOFF_TITLE "Odhlsit se" + IDS_LOGOFF_PROMPT "Opravdu se chcete odhlsit?" /* shell folder path default values */ IDS_PROGRAMS "Nabdka Start\\Programy" @@ -735,19 +723,21 @@ BEGIN IDS_LNK_FILE "Zstupce" IDS_SYS_FILE "Systmov soubor" - IDS_OPEN_VERB "Open" - IDS_RUNAS_VERB "Run as " - IDS_EDIT_VERB "Edit" - IDS_FIND_VERB "Find" - IDS_PRINT_VERB "Print" - IDS_PLAY_VERB "Play" - IDS_PREVIEW_VERB "Preview" + IDS_OPEN_VERB "Otevt" + IDS_RUNAS_VERB "Spustit jako " + IDS_EDIT_VERB "Upravit" + IDS_FIND_VERB "Najt" + IDS_PRINT_VERB "Tisknout" + IDS_PLAY_VERB "Pehrt" + IDS_PREVIEW_VERB "Nhled" - IDS_FILE_FOLDER "%u Files, %u Folders" - IDS_PRINTERS "Printers" - IDS_FONTS "Fonts" - IDS_INSTALLNEWFONT "Install New Font..." + IDS_FILE_FOLDER "%u soubor, %u sloek" + IDS_PRINTERS "Tiskrny" + IDS_FONTS "Fonty" + IDS_INSTALLNEWFONT "Nainstalovat nov font..." - IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" - IDS_COPY_OF "Copy of" + IDS_DEFAULT_CLUSTER_SIZE "Vchoz alokan velikost" + IDS_COPY_OF "Kopie " + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc index 40e1eabce06..9ad423c95e4 100644 --- a/dll/win32/shell32/lang/da-DK.rc +++ b/dll/win32/shell32/lang/da-DK.rc @@ -347,7 +347,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -654,6 +654,8 @@ BEGIN IDS_RESTART_PROMPT "nsker du at Genstarte Systemet?" IDS_SHUTDOWN_TITLE "Luk Ned" IDS_SHUTDOWN_PROMPT "nsker du at Lukke Ned?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programmer" @@ -738,4 +740,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc index db0fa82a369..5610af6fa30 100644 --- a/dll/win32/shell32/lang/de-DE.rc +++ b/dll/win32/shell32/lang/de-DE.rc @@ -296,7 +296,7 @@ BEGIN CONTROL "", 14015, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 20, 140, 200, 20 - LTEXT "Laufwerk %s", 14009, 100, 170, 40, 10 + LTEXT "Laufwerk %s", 14009, 100, 170, 50, 10 PUSHBUTTON "Bereinigen", 14010, 180, 175, 50, 15, WS_TABSTOP CHECKBOX "Laufwerk komprimieren, um Speicherplatz zu sparen", 14011, 15, 205, 180, 10, WS_DISABLED CHECKBOX "Laufwerk fr schnelle Dateisuche indizieren", 14012, 15, 220, 165, 10, WS_DISABLED @@ -361,17 +361,17 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "ffnen mit" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON IDI_SHELL_OPEN_WITH, -1, 8, 12, 21, 20 - LTEXT "Whlen Sie das Programm, das zum ffnen dieser Datei verwendet werden soll:", -1, 44, 12, 211, 10 - LTEXT "Datei: ", 14001, 44, 25, 188, 10 + LTEXT "Whlen Sie das Programm, das zum ffnen dieser Datei verwendet werden soll:", -1, 44, 12, 211, 18 + LTEXT "Datei: ", 14001, 44, 30, 188, 10 GROUPBOX "&Programme", -1, 7, 42, 249, 187 LISTBOX 14002, 16 ,57, 230, 130, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP, WS_EX_STATICEDGE AUTOCHECKBOX "&Dateityp &immer mit dem ausgewhlten Programm ffnen", 14003, 20, 193, 225, 10 - PUSHBUTTON "&Durchsuchen..", 14004, 198, 207, 50, 14 + PUSHBUTTON "&Durchsuchen...", 14004, 188, 207, 60, 14 PUSHBUTTON "OK", 14005, 150, 236, 50, 14 PUSHBUTTON "Abbrechen", 14006, 206, 236, 50, 14 END @@ -669,6 +669,8 @@ BEGIN IDS_RESTART_PROMPT "Mchten Sie das System neu starten?" IDS_SHUTDOWN_TITLE "Herunterfahren" IDS_SHUTDOWN_PROMPT "Mchten Sie das System herunterfahren?" + IDS_LOGOFF_TITLE "Ausloggen" + IDS_LOGOFF_PROMPT "Mchten Sie sich ausloggen?" /* shell folder path default values */ IDS_PROGRAMS "Startmen\\Programme" @@ -753,4 +755,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Standardgre" IDS_COPY_OF "Kopie von" + + IDS_SHLEXEC_NOASSOC "Es ist kein Programm mit diesem Dateityp verknpft." END diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc index 6b35ec3f541..a269d68ed2f 100644 --- a/dll/win32/shell32/lang/el-GR.rc +++ b/dll/win32/shell32/lang/el-GR.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION " " FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -666,6 +666,8 @@ BEGIN IDS_RESTART_PROMPT " ;" IDS_SHUTDOWN_TITLE "" IDS_SHUTDOWN_PROMPT " ;" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -750,4 +752,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc index 38203c24077..5d8f02c9a47 100644 --- a/dll/win32/shell32/lang/en-GB.rc +++ b/dll/win32/shell32/lang/en-GB.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc index 63d38cba154..6e8aef34ee0 100644 --- a/dll/win32/shell32/lang/en-US.rc +++ b/dll/win32/shell32/lang/en-US.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc index 0e20abcf95f..f26e1d4b616 100644 --- a/dll/win32/shell32/lang/es-ES.rc +++ b/dll/win32/shell32/lang/es-ES.rc @@ -361,7 +361,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 284, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Abrir con" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -668,6 +668,8 @@ BEGIN IDS_RESTART_PROMPT "Desea reiniciar el equipo?" IDS_SHUTDOWN_TITLE "Apagar" IDS_SHUTDOWN_PROMPT "Desea apagar el equipo?" + IDS_LOGOFF_TITLE "Cerrar sesin" + IDS_LOGOFF_PROMPT "Desea cerrar la sesin?" /* shell folder path default values */ IDS_PROGRAMS "Men Inicio\\Programas" @@ -752,4 +754,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Tamao asignado por defecto" IDS_COPY_OF "Copia de" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc index 2620c2b4277..6469ce1b7b5 100644 --- a/dll/win32/shell32/lang/fi-FI.rc +++ b/dll/win32/shell32/lang/fi-FI.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Haluatko simuloida Windows:n uudelleenkynnistmist?" IDS_SHUTDOWN_TITLE "Sammuta" IDS_SHUTDOWN_PROMPT "Haluatko lopettaa Wine:n istunnon?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Kynnist\\Ohjelmat" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc index 98cd95fa6f0..3d4932fc081 100644 --- a/dll/win32/shell32/lang/fr-FR.rc +++ b/dll/win32/shell32/lang/fr-FR.rc @@ -362,7 +362,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Ouvrir avec" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -669,6 +669,8 @@ BEGIN IDS_RESTART_PROMPT "Voulez-vous redmarrer votre ordinateur ?" IDS_SHUTDOWN_TITLE "Arrter" IDS_SHUTDOWN_PROMPT "Voulez-vous fermer la session ReactOS ?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Menu Dmarrer\\Programmes" @@ -753,4 +755,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Taille d'allocation par dfaut" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "Aucun programme Windows n'est configur pour ouvrir ce type de fichier." END diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc index 7016d5021a8..e45819a2d47 100644 --- a/dll/win32/shell32/lang/hu-HU.rc +++ b/dll/win32/shell32/lang/hu-HU.rc @@ -361,7 +361,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -668,6 +668,8 @@ BEGIN IDS_RESTART_PROMPT "jra szeretnd indtani a rendszert?" IDS_SHUTDOWN_TITLE "Kikapcsols" IDS_SHUTDOWN_PROMPT "Kiakarod kapcsolni szmtgpt?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -752,4 +754,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc index 986ecfeeb46..8372b351e75 100644 --- a/dll/win32/shell32/lang/it-IT.rc +++ b/dll/win32/shell32/lang/it-IT.rc @@ -359,7 +359,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Apri con" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -434,8 +434,8 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUPWIND CAPTION "Conferma della sovrascrittura dei file" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Si", IDYES, 20, 122, 60, 14 - PUSHBUTTON "Si &tutti", 12807, 85, 122, 60, 14 + DEFPUSHBUTTON "&S", IDYES, 20, 122, 60, 14 + PUSHBUTTON "S &tutti", 12807, 85, 122, 60, 14 PUSHBUTTON "&No", IDNO, 150, 122, 60, 14 PUSHBUTTON "Annulla", IDCANCEL, 215, 122, 60, 14 ICON 146, -1, 11, 10, 21, 20, SS_REALSIZECONTROL @@ -555,13 +555,13 @@ BEGIN LTEXT "&File system", -1, 7, 35, 170, 9 COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 - LTEXT "Dimensione dell'unit di &Allocazione", -1, 7, 64, 170, 9 + LTEXT "Dimensione dell'unit di &allocazione", -1, 7, 64, 170, 9 COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP LTEXT "&Etichetta del Volume", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL - GROUPBOX "Opzioni di &Formattazione", 4610, 7, 121, 170, 49 + GROUPBOX "Opzioni di &formattazione", 4610, 7, 121, 170, 49 AUTOCHECKBOX "Formattazione &rapida", 28674, 16, 135, 155, 10 - AUTOCHECKBOX "Abilita la &Compressione", 28675, 16, 152, 155, 10 + AUTOCHECKBOX "Abilita la &compressione", 28675, 16, 152, 155, 10 END CHKDSK_DLG DIALOGEX 50, 50, 194, 120 @@ -645,7 +645,7 @@ BEGIN IDS_CREATEFOLDER_DENIED "Impossibile creare la cartella: Accesso negato." IDS_CREATEFOLDER_CAPTION "Errore durante la creazione della cartella" - IDS_DELETEITEM_CAPTION "Confermare la cancallazione del file" + IDS_DELETEITEM_CAPTION "Confermare la cancellazione del file" IDS_DELETEFOLDER_CAPTION "Confermare la cancellazione della cartella" IDS_DELETEITEM_TEXT "Sei sicuro di voler cancellare '%1'?" IDS_DELETEMULTIPLE_TEXT "Sei sicuro di voler cancellare questi %1 elementi?" @@ -664,8 +664,10 @@ BEGIN /* message box strings */ IDS_RESTART_TITLE "Riavvia" IDS_RESTART_PROMPT "Volete riavviare il sistema?" - IDS_SHUTDOWN_TITLE "Termina sessione" - IDS_SHUTDOWN_PROMPT "Volete terminare la sessione di ReactOS?" + IDS_SHUTDOWN_TITLE "Arresta sistema" + IDS_SHUTDOWN_PROMPT "Volete arrestare il sistema?" + IDS_LOGOFF_TITLE "Disconnetti" + IDS_LOGOFF_PROMPT "Volete disconnettervi?" /* shell folder path default values */ IDS_PROGRAMS "Menu Avvio\\Programmi" @@ -749,5 +751,7 @@ BEGIN IDS_INSTALLNEWFONT "Installazione nuovi Font..." IDS_DEFAULT_CLUSTER_SIZE "Dimensione predefinita di allocazione" - IDS_COPY_OF "Copy of" + IDS_COPY_OF "Copia di" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc index 47c5bfb9923..c09ba106660 100644 --- a/dll/win32/shell32/lang/ja-JP.rc +++ b/dll/win32/shell32/lang/ja-JP.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "JvO" FONT 9, "MS UI Gothic", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "VXeċN܂?" IDS_SHUTDOWN_TITLE "Vbg_E" IDS_SHUTDOWN_PROMPT "Vbg_E܂?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "X^[g j[\\vO" @@ -749,4 +751,5 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "ftHg AP[V TCY" IDS_COPY_OF "Rs[ `" + END diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc index e9e67b71a4e..98981f74213 100644 --- a/dll/win32/shell32/lang/ko-KR.rc +++ b/dll/win32/shell32/lang/ko-KR.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc index 5ff6c83a59a..1689e2a3bae 100644 --- a/dll/win32/shell32/lang/nl-NL.rc +++ b/dll/win32/shell32/lang/nl-NL.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "Er is geen Windows-programma geconfigureerd om dit soort bestanden te openen." END diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc index 90dc27d3aa6..f02aa64fecd 100644 --- a/dll/win32/shell32/lang/no-NO.rc +++ b/dll/win32/shell32/lang/no-NO.rc @@ -359,7 +359,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "pne med" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -668,6 +668,8 @@ BEGIN IDS_RESTART_PROMPT "Vil du starte datamaskinen p nytt?" IDS_SHUTDOWN_TITLE "Avslutt" IDS_SHUTDOWN_PROMPT "Vil du sl av datamaskinen?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start-meny\\Programmer" @@ -750,6 +752,8 @@ BEGIN IDS_FONTS "Skrifttyper" IDS_INSTALLNEWFONT "Installere nye skrifttyper..." - IDS_DEFAULT_CLUSTER_SIZE "Standard tildelingsstrrelse" + IDS_DEFAULT_CLUSTER_SIZE "Standard tildelingsstrrelse" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "Intet Windows-program er satt opp til pne denne filtypen." END diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc index b6d33a64fd4..c9a4d40a48b 100644 --- a/dll/win32/shell32/lang/pl-PL.rc +++ b/dll/win32/shell32/lang/pl-PL.rc @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * ReactOS shell32 fork translation updated by Caemyr - - * - Olaf Siejka (Jan,Mar,Apr,Jul, Aug 2008) + * - Olaf Siejka (Jan,Mar,Apr,Jul, Aug 2008; Apr, 2010) * Use ReactOS forum PM or IRC to contact me * http://www.reactos.org * IRC: irc.freenode.net #reactos-pl; @@ -365,7 +365,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Otwrz za pomoc" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -672,6 +672,8 @@ BEGIN IDS_RESTART_PROMPT "Czy chcesz zrestartowa system?" IDS_SHUTDOWN_TITLE "Wycz" IDS_SHUTDOWN_PROMPT "Czy chcesz wyczy system?" + IDS_LOGOFF_TITLE "Wyloguj" + IDS_LOGOFF_PROMPT "Czy chcesz si wylogowa z systemu?" /* shell folder path default values */ IDS_PROGRAMS "Menu Start\\Programy" @@ -756,4 +758,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Domylny rozmiar jednostki alokacji" IDS_COPY_OF "Kopia" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc index 048d4c39110..7679014ff37 100644 --- a/dll/win32/shell32/lang/pt-BR.rc +++ b/dll/win32/shell32/lang/pt-BR.rc @@ -360,7 +360,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -667,6 +667,8 @@ BEGIN IDS_RESTART_PROMPT "Voc quer simular a reinicializao do Windows?" IDS_SHUTDOWN_TITLE "Desligar" IDS_SHUTDOWN_PROMPT "Voc quer finalizar a sesso no Wine?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Menu Iniciar\\Programas" @@ -751,4 +753,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "Nici un program Windows nu este configurat sa deschida fi?iere de acest tip." END diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc index c20e670e3a2..2d99ca47e97 100644 --- a/dll/win32/shell32/lang/pt-PT.rc +++ b/dll/win32/shell32/lang/pt-PT.rc @@ -2,6 +2,7 @@ * Copyright 1998 Juergen Schmied * Copyright 2003 Marcelo Duarte * Copyright 2006-2007 Amrico Jos Melo + * Copyright 2010 Manuel D V Silva * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -66,27 +67,27 @@ MENU_SHV_FILE MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "E&xplore", FCIDM_SHVIEW_EXPLORE - MENUITEM "&Open", FCIDM_SHVIEW_OPEN + MENUITEM "E&xplorador", FCIDM_SHVIEW_EXPLORE + MENUITEM "&Abrir", FCIDM_SHVIEW_OPEN MENUITEM SEPARATOR - MENUITEM "C&ut", FCIDM_SHVIEW_CUT - MENUITEM "&Copy", FCIDM_SHVIEW_COPY + MENUITEM "C&ortar", FCIDM_SHVIEW_CUT + MENUITEM "&Copiar", FCIDM_SHVIEW_COPY MENUITEM SEPARATOR - MENUITEM "Create &Link", FCIDM_SHVIEW_CREATELINK - MENUITEM "&Delete", FCIDM_SHVIEW_DELETE - MENUITEM "&Rename", FCIDM_SHVIEW_RENAME + MENUITEM "Criar &Link", FCIDM_SHVIEW_CREATELINK + MENUITEM "&Apagar", FCIDM_SHVIEW_DELETE + MENUITEM "&Renomear", FCIDM_SHVIEW_RENAME MENUITEM SEPARATOR - MENUITEM "&Properties", FCIDM_SHVIEW_PROPERTIES + MENUITEM "&Propriadades", FCIDM_SHVIEW_PROPERTIES END END SHBRSFORFOLDER_MSGBOX DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "Browse for Folder" +CAPTION "Procurar Pastas" FONT 8, "MS Shell Dlg" BEGIN DEFPUSHBUTTON "OK", 1, 60, 175, 60, 15, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", 2, 125, 175, 60, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Cancelar", 2, 125, 175, 60, 15, WS_GROUP | WS_TABSTOP LTEXT "", IDD_TITLE, 4, 4, 180, 12 LTEXT "", IDD_STATUS, 4, 25, 180, 12 CONTROL "", IDD_TREEVIEW, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, 4, 40, 180, 120 @@ -94,28 +95,28 @@ END SHNEWBRSFORFOLDER_MSGBOX DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 15, 40, 218, 196 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU -CAPTION "Browse for Folder" +CAPTION "Procurar Pastas" FONT 8, "MS Shell Dlg" BEGIN LTEXT "", IDD_TITLE, 10, 8, 198, 24 LTEXT "", IDD_STATUS, 10, 25, 198, 12 - LTEXT "Folder:", IDD_FOLDER, 10, 152, 40, 12 + LTEXT "Pasta:", IDD_FOLDER, 10, 152, 40, 12 CONTROL "", IDD_TREEVIEW, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_TABSTOP, 12, 38, 194, 105 EDITTEXT IDD_FOLDERTEXT, 46, 150, 160, 14, WS_BORDER | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Make New Folder", IDD_MAKENEWFOLDER, 12, 174, 77, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Criar Nova Pasta", IDD_MAKENEWFOLDER, 12, 174, 77, 14, WS_GROUP | WS_TABSTOP DEFPUSHBUTTON "OK", IDOK, 102, 174, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 156, 174, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Cancelar", IDCANCEL, 156, 174, 50, 14, WS_GROUP | WS_TABSTOP END SHELL_YESTOALL_MSGBOX DIALOGEX 200, 100, 280, 90 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Message" +CAPTION "Mensagem" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Yes", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Yes to &all", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Cancel", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Sim", IDYES, 34, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Sim para &todos", IDD_YESTOALL, 92, 69, 65, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&No", IDNO, 162, 69, 53, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Cancelar", IDCANCEL, 220, 69, 53, 14, WS_GROUP | WS_TABSTOP ICON "", IDD_ICON, 10, 10, 16, 16 LTEXT "", IDD_MESSAGE, 40, 10, 238, 52, 0 END @@ -127,14 +128,14 @@ FONT 8, "MS Shell Dlg" BEGIN ICON "", IDC_SHELL_ABOUT_ICON, 7, 55, 21, 20 LTEXT "", IDC_SHELL_ABOUT_APPNAME, 35, 55, 200, 10 - LTEXT "Version " KERNEL_VERSION_STR " (" KERNEL_VERSION_BUILD_STR ")", IDC_STATIC, 35, 65, 235, 10 + LTEXT "Verso " KERNEL_VERSION_STR " (" KERNEL_VERSION_BUILD_STR ")", IDC_STATIC, 35, 65, 235, 10 LTEXT REACTOS_DEFAULT_STR_LEGAL_COPYRIGHT, IDC_STATIC, 35, 75, 210, 10 LTEXT "", IDC_SHELL_ABOUT_OTHERSTUFF, 35, 90, 180, 20 - LTEXT "This ReactOS version is registered to:", IDC_STATIC, 35, 115, 180, 10 + LTEXT "Esta verso do ReactOS registado a:", IDC_STATIC, 35, 115, 180, 10 LTEXT "", IDC_SHELL_ABOUT_REG_USERNAME, 45, 125, 180, 10 LTEXT "", IDC_SHELL_ABOUT_REG_ORGNAME, 45, 135, 180, 10 LTEXT "", IDC_STATIC, 35, 147, 235, 1, SS_ETCHEDHORZ - LTEXT "Installed physical memory:", IDC_STATIC, 35, 152, 130, 10 + LTEXT "Memria fsica instalada:", IDC_STATIC, 35, 152, 130, 10 LTEXT "", IDC_SHELL_ABOUT_PHYSMEM, 167, 152, 88, 10 DEFPUSHBUTTON "OK", IDOK, 220, 178, 50, 14 @@ -155,7 +156,7 @@ CAPTION "" FONT 8, "MS Shell Dlg" BEGIN ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE - LTEXT "Digite o nome do programa, pasta, documento, ou endereo Internet, que o Wine ir abr-lo.", 12289, 36, 11, 182, 18 + LTEXT "Digite o nome do programa, pasta, documento, ou endereo Internet, que o ReactOS ir abr-lo.", 12289, 36, 11, 182, 18 LTEXT "&Abrir:", 12305, 7, 39, 24, 10 CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100 DEFPUSHBUTTON "OK", IDOK, 62, 63, 50, 14, WS_TABSTOP @@ -165,156 +166,156 @@ END SHELL_GENERAL_SHORTCUT_DLG DIALOGEX 0, 0, 235, 215 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Shortcut" +CAPTION "Atalho" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 10, 4, 30, 30, WS_VISIBLE - LTEXT "Target type:", 14004, 8, 38, 64, 10 + LTEXT "Tipo de destino:", 14004, 8, 38, 64, 10 LTEXT "", 14005, 78, 38, 142, 10 - LTEXT "Target location:", 14006, 8, 58, 64, 10 + LTEXT "Localizao do destino:", 14006, 8, 58, 64, 10 LTEXT "", 14007, 79, 58, 141, 10 - LTEXT "Target:", 14008, 8, 77, 45, 10 + LTEXT "Destino:", 14008, 8, 77, 45, 10 EDITTEXT 14009, 79, 75, 150, 14, ES_AUTOHSCROLL - LTEXT "&Start in:", 14010, 8, 96, 57, 10 + LTEXT "&Iniciar em:", 14010, 8, 96, 57, 10 EDITTEXT 14011, 79, 94, 150, 14, ES_AUTOHSCROLL - LTEXT "Shortcut &key:", 14014, 8, 115, 57, 10 + LTEXT "&Tecla de Atalho:", 14014, 8, 115, 57, 10 EDITTEXT 14015, 79, 112, 150, 14, ES_LEFT - LTEXT "Run:", 14016, 8, 134, 57, 10 + LTEXT "Executar:", 14016, 8, 134, 57, 10 EDITTEXT 14017, 79, 131, 150, 14, ES_AUTOHSCROLL - LTEXT "C&omment:", 14018, 8, 152, 57, 10 + LTEXT "C&omemntrio:", 14018, 8, 152, 57, 10 EDITTEXT 14019, 79, 149, 150, 14, ES_AUTOHSCROLL - PUSHBUTTON "&Find Target...", 14020, 9, 172, 70, 14, ES_LEFT - PUSHBUTTON "&Change Icon...", 14021, 84, 172, 70, 14, ES_LEFT - PUSHBUTTON "A&dvanced...", 14022, 159, 172, 70, 14, ES_LEFT + PUSHBUTTON "&Localizar Destino...", 14020, 9, 172, 70, 14, ES_LEFT + PUSHBUTTON "&Trocar Icon...", 14021, 84, 172, 70, 14, ES_LEFT + PUSHBUTTON "A&vanado...", 14022, 159, 172, 70, 14, ES_LEFT END SHELL_EXTENDED_SHORTCUT_DLG DIALOGEX 0, 0, 230, 150 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "Extended Properties" +CAPTION "Propriedades Avanadas" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - LTEXT "Choose the advanced properties you want for this shortcut.", -1, 5, 30, 210, 10 - CHECKBOX "Run with different credentials", 14000, 25, 50, 150, 10 - LTEXT "This option can allow you to run the this shortcut as another user, or continue as yourself while protecting your computer and data from unauthorized program activity.", -1, 50, 60, 175, 40 - CHECKBOX "Run in seperate memory space", 14001, 25, 100, 90, 10, WS_DISABLED + LTEXT "Escolha as propriedades avanadas que quer para este atalho.", -1, 5, 30, 210, 10 + CHECKBOX "Executar com diferentes credenciais", 14000, 25, 50, 150, 10 + LTEXT "Esta opo permite executar este atalho como outro utilizador, ou continue com a sua conta enquanto protege o seu computador e dados contra actividade de programas no autorizados.", -1, 50, 60, 175, 40 + CHECKBOX "Executar num espao de memria separada", 14001, 25, 100, 90, 10, WS_DISABLED PUSHBUTTON "OK", 1, 63, 124, 50, 15, WS_VISIBLE - PUSHBUTTON "Abort", 2, 120, 124, 50, 15, WS_VISIBLE + PUSHBUTTON "Abortar", 2, 120, 124, 50, 15, WS_VISIBLE END SHELL_FOLDER_GENERAL_DLG DIALOGEX 0, 0, 240, 205 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "General" +CAPTION "Geral" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 10, 3, 30, 30, WS_VISIBLE EDITTEXT 14001, 70, 9, 158, 14, ES_LEFT | ES_READONLY - LTEXT "Type of file:", 14004, 8, 35, 50, 10 - LTEXT "Folder", 14005, 68, 35, 160, 10 - LTEXT "Location:", 14006, 8, 53, 50, 10 + LTEXT "Tipo de ficheiro:", 14004, 8, 35, 50, 10 + LTEXT "Pasta", 14005, 68, 35, 160, 10 + LTEXT "Localizao:", 14006, 8, 53, 50, 10 LTEXT "", 14007, 68, 53, 315, 10 - LTEXT "Size:", 14008, 8, 72, 45, 10 + LTEXT "Tamanho:", 14008, 8, 72, 45, 10 LTEXT "", 14009, 68, 72, 315, 10 - LTEXT "Contains:", 14010, 8, 93, 45, 10 + LTEXT "Contm:", 14010, 8, 93, 45, 10 LTEXT "", 14011, 68, 93, 160, 10 - LTEXT "Created:", 14014, 8, 118, 45, 10 + LTEXT "Criado:", 14014, 8, 118, 45, 10 LTEXT "", 14015, 68, 118, 160, 10 - AUTOCHECKBOX "&Read-only", 14021, 45, 150, 67, 10 - AUTOCHECKBOX "&Hidden", 14022, 126, 150, 50, 10 + AUTOCHECKBOX "&Smente de Leitura", 14021, 45, 150, 67, 10 + AUTOCHECKBOX "&Escondido", 14022, 126, 150, 50, 10 END SHELL_FILE_GENERAL_DLG DIALOGEX 0, 0, 240, 205 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "General" +CAPTION "geral" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON "", 14000, 10, 3, 30, 30, WS_VISIBLE EDITTEXT 14001, 70, 9, 158, 14, ES_LEFT | ES_READONLY - LTEXT "Type of file:", 14004, 8, 35, 50, 10 - LTEXT "File", 14005, 68, 35, 160, 10 - LTEXT "Opens with:", 14006, 8, 53, 50, 10 + LTEXT "Tipo de Ficheiro:", 14004, 8, 35, 50, 10 + LTEXT "Ficheiro", 14005, 68, 35, 160, 10 + LTEXT "Abre com::", 14006, 8, 53, 50, 10 LTEXT "", 14007, 68, 53, 160, 10 - LTEXT "Location:", 14008, 8, 72, 45, 10 + LTEXT "Localizao:", 14008, 8, 72, 45, 10 LTEXT "", 14009, 68, 72, 315, 10 - LTEXT "Size:", 14010, 8, 93, 45, 10 + LTEXT "Tamanho:", 14010, 8, 93, 45, 10 LTEXT "", 14011, 68, 93, 160, 10 - LTEXT "Created:", 14014, 8, 118, 45, 10 + LTEXT "Criado:", 14014, 8, 118, 45, 10 LTEXT "", 14015, 68, 118, 160, 10 - LTEXT "Modified:", 14016, 8, 140, 45, 10 + LTEXT "Modificado:", 14016, 8, 140, 45, 10 LTEXT "", 14017, 68, 140, 160, 10 - LTEXT "Accessed:", 14018, 8, 160, 45, 10 + LTEXT "Acedido:", 14018, 8, 160, 45, 10 LTEXT "", 14019, 68, 160, 160, 10 - LTEXT "Attributes:", 14020, 8, 189, 45, 10 - CHECKBOX "&Read-only", 14021, 58, 189, 67, 10 - CHECKBOX "&Hidden", 14022, 126, 189, 50, 10 - CHECKBOX "&Archive", 14023, 181, 189, 49, 10 + LTEXT "propriedades:", 14020, 8, 189, 45, 10 + CHECKBOX "&Somente de Leitura", 14021, 58, 189, 67, 10 + CHECKBOX "&Oculto", 14022, 126, 189, 50, 10 + CHECKBOX "&Arquivo", 14023, 181, 189, 49, 10 END SHELL_FILE_VERSION_DLG DIALOGEX 0, 0, 235, 215 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Version" +CAPTION "Verso" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - LTEXT "File version: ", 14000, 10, 10, 55, 10 + LTEXT "Verso do Ficheiro: ", 14000, 10, 10, 55, 10 LTEXT "", 14001, 77, 10, 152, 10 - LTEXT "Description: ", 14002, 10, 27, 45, 10 + LTEXT "Descrio: ", 14002, 10, 27, 45, 10 LTEXT "", 14003, 77, 27, 152, 10 LTEXT "Copyright: ", 14004, 10, 46, 66, 10 LTEXT "", 14005, 77, 46, 152, 10 - GROUPBOX "Other version information: ", 14006, 6, 70, 222, 115 - LTEXT "Item name: ", 14007, 13, 82, 50, 10 - LTEXT "Value: ", 14008, 112, 82, 45, 10 + GROUPBOX "Outras informaes da verso: ", 14006, 6, 70, 222, 115 + LTEXT "Nome do Item: ", 14007, 13, 82, 50, 10 + LTEXT "Valor: ", 14008, 112, 82, 45, 10 LISTBOX 14009, 12, 94, 94, 83, LBS_STANDARD | WS_TABSTOP | LBS_NOTIFY EDITTEXT 14010, 112, 93, 109, 83, ES_LEFT | WS_BORDER | WS_VSCROLL | WS_GROUP | ES_MULTILINE | ES_READONLY END DRIVE_GENERAL_DLG DIALOGEX 0, 0, 240, 230 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "General" +CAPTION "Geral" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN EDITTEXT 14000, 40, 20, 190, 14, ES_LEFT|WS_BORDER|WS_GROUP - LTEXT "Type:", -1, 15, 55, 40, 10 + LTEXT "Tipo:", -1, 15, 55, 40, 10 LTEXT "", 14001, 110, 55, 100, 10 - LTEXT "File system:", -1, 15, 70, 100, 10 + LTEXT "Sistema de Ficheiros:", -1, 15, 70, 100, 10 LTEXT "", 14002, 110, 70, 100, 10 CONTROL "", 14013, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 5, 90, 10, 10 - LTEXT "Used space:", -1, 25, 90, 120, 10 + LTEXT "Espao utilizado:", -1, 25, 90, 120, 10 LTEXT "", 14003, 110, 90, 120, 10 LTEXT "", 14004, 200, 90, 40, 10 CONTROL "", 14014, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 5, 105, 10, 10 - LTEXT "Free space:", -1, 25, 105, 70, 10 + LTEXT "Espao livre:", -1, 25, 105, 70, 10 LTEXT "", 14005, 110, 105, 120, 10 LTEXT "", 14006, 200, 105, 40, 10 - LTEXT "Capacity:", -1, 25, 125, 80, 10 + LTEXT "Capacidade:", -1, 25, 125, 80, 10 LTEXT "", 14007, 110, 125, 120, 10 LTEXT "", 14008, 200, 125, 40, 10 CONTROL "", 14015, "Static", SS_NOTIFY | SS_SUNKEN | SS_OWNERDRAW, 20, 140, 200, 20 - LTEXT "Drive %s", 14009, 100, 170, 40, 10 - PUSHBUTTON "Disk Cleanup", 14010, 180, 175, 50, 15, WS_TABSTOP - CHECKBOX "Compress drive to save disk space", 14011, 15, 205, 180, 10, WS_DISABLED - CHECKBOX "Allow Indexing Service to index this disk for fast file searching", 14012, 15, 220, 200, 10, WS_DISABLED + LTEXT "Disco %s", 14009, 100, 170, 40, 10 + PUSHBUTTON "Limpeza do Disco", 14010, 180, 175, 50, 15, WS_TABSTOP + CHECKBOX "Comprimir unidade para libertar espao no disco", 14011, 15, 205, 180, 10, WS_DISABLED + CHECKBOX "permitir indexar este disco para acelerar a procura de ficheiros", 14012, 15, 220, 200, 10, WS_DISABLED END DRIVE_EXTRA_DLG DIALOGEX 0, 0, 240, 230 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Tools" +CAPTION "Ferramentas" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "Error-checking", -1, 5, 5, 230, 60 - LTEXT "This option will check the volume for\nerrors.", -1, 40, 25, 160, 20 - PUSHBUTTON "Check Now...", 14000, 130, 45, 90, 15, WS_TABSTOP - GROUPBOX "Defragmentation", -1, 5, 65, 230, 60 - LTEXT "This option will defragment files on the volume", -1, 40, 85, 160, 20 - PUSHBUTTON "Defragment Now...", 14001, 130, 105, 90, 15, WS_TABSTOP - GROUPBOX "Backup", -1, 5, 130, 230, 60 - LTEXT "This option will back up files on the volume.", -1, 40, 150, 160, 20 - PUSHBUTTON "Backup Now...", 14002, 130, 170, 90, 15, WS_TABSTOP + GROUPBOX "Verificar por erros...", -1, 5, 5, 230, 60 + LTEXT "Esta opo vai verificar o volume por erros.", -1, 40, 25, 160, 20 + PUSHBUTTON "Verificar agora...", 14000, 130, 45, 90, 15, WS_TABSTOP + GROUPBOX "Desfragmentao", -1, 5, 65, 230, 60 + LTEXT "Esta opo vai desfragmentar os ficheiros no volume", -1, 40, 85, 160, 20 + PUSHBUTTON "Defragmentar Agora...", 14001, 130, 105, 90, 15, WS_TABSTOP + GROUPBOX "Cpia de segurana", -1, 5, 130, 230, 60 + LTEXT "Esta opo vai criar os ficheiros do volume.", -1, 40, 150, 160, 20 + PUSHBUTTON "Executar Cpia de Segurana...", 14002, 130, 170, 90, 15, WS_TABSTOP END DRIVE_HARDWARE_DLG DIALOGEX 0, 0, 240, 230 @@ -326,151 +327,151 @@ END RUN_AS_DIALOG DIALOGEX 0, 0, 240, 190 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Run As" +CAPTION "Executar Como..." FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - LTEXT "Which user account do you want to use to run this program?", -1, 10, 20, 220, 20 - CHECKBOX "Current User %s", 14000, 10, 45, 150, 10 - LTEXT "Protect my computer and data from unauthorized program activity", -1, 25, 57, 200, 10, WS_DISABLED - CHECKBOX "This option can prevent computer viruses from harming your computer or personal data, but selecting it might cause the program to function improperly.", 14001, 25, 68, 200, 30, WS_DISABLED | BS_MULTILINE - CHECKBOX "The following user:", 14002, 10, 100, 90, 10 - LTEXT "User name:", -1, 20, 118, 54, 10 + LTEXT "Que conta de utilizador quer utilizar para executar este programa?", -1, 10, 20, 220, 20 + CHECKBOX "Utilizador actual %s", 14000, 10, 45, 150, 10 + LTEXT "Proteger o meu computador e dados de actividade de programas no autoridados.", -1, 25, 57, 200, 10, WS_DISABLED + CHECKBOX "Esta opo pode prevenir a aco de virus no computador,mas seleccionando-a pode levar a que alguns programas funcionem incorrectamente.", 14001, 25, 68, 200, 30, WS_DISABLED | BS_MULTILINE + CHECKBOX "O seguinte utilizador:", 14002, 10, 100, 90, 10 + LTEXT "Nome do utilizador:", -1, 20, 118, 54, 10 COMBOBOX 14003, 75, 115, 100, 15, CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP PUSHBUTTON "...", 14004, 180, 115, 30, 14, WS_TABSTOP - LTEXT "Password:", -1, 20, 143, 53, 10 + LTEXT "Palavra-passe:", -1, 20, 143, 53, 10 EDITTEXT 14005, 74, 140, 100, 14, ES_LEFT | WS_BORDER | WS_GROUP PUSHBUTTON "...", 14006, 180, 140, 30, 14, WS_TABSTOP PUSHBUTTON "OK", 14007, 57, 170, 60, 14, WS_TABSTOP - PUSHBUTTON "Cancel", 14008, 122, 170, 60, 14, WS_TABSTOP + PUSHBUTTON "Cancelar", 14008, 122, 170, 60, 14, WS_TABSTOP END BITBUCKET_PROPERTIES_DLG DIALOGEX 0, 0, 240, 190 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Recycle Bin Properties" +CAPTION "propriedades da Reciclagem" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN CONTROL "", 14000, "SysListView32", LVS_REPORT | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 10, 10, 220, 50 - GROUPBOX "Settings for selected location", -1, 10, 72, 220, 70 - RADIOBUTTON "&Custom size:", 14001, 20, 90, 80, 10, WS_TABSTOP + GROUPBOX "propriedades para as localizaes seleccionadas", -1, 10, 72, 220, 70 + RADIOBUTTON "&Tamanho personalizado:", 14001, 20, 90, 80, 10, WS_TABSTOP EDITTEXT 14002, 106, 87, 50, 14, WS_TABSTOP | ES_NUMBER - LTEXT "M&aximum size(MB):", -1, 20, 105, 70, 10 - RADIOBUTTON "Do not move files to the &Recycle Bin. Remove files immediately when deleted.", 14003, 20, 117, 170, 20, BS_MULTILINE | WS_TABSTOP - AUTOCHECKBOX "&Display delete confirmation dialog", 14004, 20, 155, 140, 10, WS_TABSTOP + LTEXT "Tamanho M&ximo(MB):", -1, 20, 105, 70, 10 + RADIOBUTTON "No mover os ficheiros para a &Reciclagem. Apag-los definitivamente.", 14003, 20, 117, 170, 20, BS_MULTILINE | WS_TABSTOP + AUTOCHECKBOX "&Mostrar ecrn de confirmao de eliminao", 14004, 20, 155, 140, 10, WS_TABSTOP END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "Open With" +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION +CAPTION "Abre com..." FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN ICON IDI_SHELL_OPEN_WITH, -1, 8, 12, 21, 20 - LTEXT "Choose the program you want to use to open this file:", -1, 44, 12, 211, 10 - LTEXT "File: ", 14001, 44, 25, 188, 10 - GROUPBOX "&Programs", -1, 7, 42, 249, 187 + LTEXT "Escolha o programa que quer utilizar para abrir este ficheiro:", -1, 44, 12, 211, 10 + LTEXT "Ficheiro: ", 14001, 44, 25, 188, 10 + GROUPBOX "&Programas", -1, 7, 42, 249, 187 LISTBOX 14002, 16 ,57, 230, 130, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP, WS_EX_STATICEDGE - AUTOCHECKBOX "&Always use the selected program to open this kind of file", 14003, 20, 193, 225, 10 - PUSHBUTTON "&Browse...", 14004, 198, 207, 50, 14 + AUTOCHECKBOX "&Utilizar sempre o programa seleccionado para abrir este tipo de ficheiros", 14003, 20, 193, 225, 10 + PUSHBUTTON "&Seleccione...", 14004, 198, 207, 50, 14 PUSHBUTTON "OK", 14005, 150, 236, 50, 14 - PUSHBUTTON "Cancel", 14006, 206, 236, 50, 14 + PUSHBUTTON "Cancelar", 14006, 206, 236, 50, 14 END FOLDER_OPTIONS_GENERAL_DLG DIALOGEX 0, 0, 264, 256 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "General" +CAPTION "Geral" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - GROUPBOX "Tasks", -1, 7, 10, 249, 45 + GROUPBOX "Tarefas", -1, 7, 10, 249, 45 ICON "", 30109, 14, 25, 21, 20, SS_REALSIZECONTROL - AUTORADIOBUTTON "Show common tasks in &folders", 14001, 40, 25, 120, 10, WS_TABSTOP | WS_GROUP - AUTORADIOBUTTON "Use ReactOS class&ic folders", 14002, 40, 37, 120, 10, WS_TABSTOP | WS_GROUP - GROUPBOX "Browse folders", -1, 7, 60, 249, 45, WS_TABSTOP + AUTORADIOBUTTON "Mostrar tarefas comuns nas &pastas", 14001, 40, 25, 120, 10, WS_TABSTOP | WS_GROUP + AUTORADIOBUTTON "Utilizar pastas class&icas ReactOS", 14002, 40, 37, 120, 10, WS_TABSTOP | WS_GROUP + GROUPBOX "Procurar pastas", -1, 7, 60, 249, 45, WS_TABSTOP ICON "", 30110, 14, 70, 21, 20, SS_REALSIZECONTROL - AUTORADIOBUTTON "Open each folder in the sa&me window", 14004, 40, 70, 140, 10, WS_TABSTOP | WS_GROUP - AUTORADIOBUTTON "Open each folder in its own &window", 14005, 40, 82, 140, 10, WS_TABSTOP | WS_GROUP - GROUPBOX "Click items as follows", -1, 7, 110, 249, 60 + AUTORADIOBUTTON "Abrir cada pasta na &mesma janela", 14004, 40, 70, 140, 10, WS_TABSTOP | WS_GROUP + AUTORADIOBUTTON "Abrir cada pasta na sua &janela", 14005, 40, 82, 140, 10, WS_TABSTOP | WS_GROUP + GROUPBOX "Seleccione a seguinte opo", -1, 7, 110, 249, 60 ICON "", 30111, 14, 120, 21, 20, SS_REALSIZECONTROL - AUTORADIOBUTTON "&Single-click to open an item (point to select)", 14007, 40, 120, 170, 10, WS_TABSTOP | WS_GROUP - AUTORADIOBUTTON "Underline icon titles consistent with my &browser", 14008, 50, 132, 170, 10, WS_TABSTOP | WS_GROUP - AUTORADIOBUTTON "Underline icon titles only when I &point at them", 14009, 50, 144, 170, 10, WS_TABSTOP | WS_GROUP - AUTORADIOBUTTON "&Double-click to open an item (single-click to select)", 14010, 40, 156, 170, 10, WS_TABSTOP | WS_GROUP - PUSHBUTTON "&Restore Defaults", 14011, 180, 180, 60, 14, WS_TABSTOP + AUTORADIOBUTTON "&Click simples para abrir um item", 14007, 40, 120, 170, 10, WS_TABSTOP | WS_GROUP + AUTORADIOBUTTON "Sublinhar os ttulos dos cones mantendo o aspecto do &browser", 14008, 50, 132, 170, 10, WS_TABSTOP | WS_GROUP + AUTORADIOBUTTON "Sublinhar os ttulos dos cones apenas quando &aponto para eles", 14009, 50, 144, 170, 10, WS_TABSTOP | WS_GROUP + AUTORADIOBUTTON "&Duplo-click para abrir um item (um click para seleccionar)", 14010, 40, 156, 170, 10, WS_TABSTOP | WS_GROUP + PUSHBUTTON "&Restaurar valores por defeito", 14011, 180, 180, 60, 14, WS_TABSTOP END FOLDER_OPTIONS_VIEW_DLG DIALOGEX 0, 0, 264, 256 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "View" +CAPTION "Ver" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN -GROUPBOX "Folder views", -1, 7, 10, 249, 60 +GROUPBOX "Vistas das Pastas", -1, 7, 10, 249, 60 //ICON -LTEXT "You can apply the view(such as Details or Tiles) that\nyou are using for this folder to all folders.", -1, 60, 20, 180, 20 -PUSHBUTTON "Apply to A&ll Folders", 14001, 60, 50, 80, 14, WS_TABSTOP -PUSHBUTTON "&Reset All Folders", 14002, 150, 50, 80, 14, WS_TABSTOP -LTEXT "Advanced settings:", -1, 7, 80, 100, 10 +LTEXT "Pode aplicar a vista (como detalhes ou ttulos) que\nest a usar para esta pasta para todas as pastas.", -1, 60, 20, 180, 20 +PUSHBUTTON "Applicar a T&odas as Pastas", 14001, 60, 50, 80, 14, WS_TABSTOP +PUSHBUTTON "&Reiniciar todas as Pastas", 14002, 150, 50, 80, 14, WS_TABSTOP +LTEXT "Definies avanadas:", -1, 7, 80, 100, 10 CONTROL "", 14003, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 7, 90, 249, 120 -PUSHBUTTON "Restore &Defaults", 14004, 180, 210, 80, 14, WS_TABSTOP +PUSHBUTTON "Restaurar valores por &Defeito", 14004, 180, 210, 80, 14, WS_TABSTOP END FOLDER_OPTIONS_FILETYPES_DLG DIALOGEX 0, 0, 264, 256 STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION -CAPTION "File Types" +CAPTION "Tipos de Ficheiros" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN -LTEXT "Registered file &types:", -1, 7, 10, 70, 10 +LTEXT "&Tipos de ficheiros registados:", -1, 7, 10, 70, 10 CONTROL "", 14000, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 7, 20, 249, 80 -PUSHBUTTON "&New", 14001, 120, 110, 50, 14, WS_TABSTOP -PUSHBUTTON "&Delete", 14002, 180, 110, 50, 14, WS_TABSTOP -GROUPBOX "Details for '%s' extension", 14003, 7, 130, 249, 70 -LTEXT "Opens with:", -1, 12, 140, 40, 10 +PUSHBUTTON "&Novo", 14001, 120, 110, 50, 14, WS_TABSTOP +PUSHBUTTON "&Apagar", 14002, 180, 110, 50, 14, WS_TABSTOP +GROUPBOX "Detalhes para '%s' extenso", 14003, 7, 130, 249, 70 +LTEXT "Abre com:", -1, 12, 140, 40, 10 //ICON -LTEXT "Appname", 14005, 100, 140, 40, 10 -PUSHBUTTON "&Change...", 14006, 180, 140, 50, 14, WS_TABSTOP -LTEXT "Files with extension '%s' are of type '%s'. To\nchange settings that affect all '%s' files, click\nAdvanced.", 14007, 12, 155, 160, 30 -PUSHBUTTON "Ad&vanced", 14008, 180, 175, 50, 14, WS_TABSTOP +LTEXT "Appnome", 14005, 100, 140, 40, 10 +PUSHBUTTON "&Mudar...", 14006, 180, 140, 50, 14, WS_TABSTOP +LTEXT "Ficheiros com extenso '%s' so do tipo '%s'. Para\nmudar definies que afectam todos '%s' ficheiros, click\nAvanado.", 14007, 12, 155, 160, 30 +PUSHBUTTON "A&vanado", 14008, 180, 175, 50, 14, WS_TABSTOP END CONFIRM_FILE_REPLACE_DLG DIALOGEX 0, 0, 282, 143 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Confirm File Replace" +CAPTION "Confirmar Substituio de Ficheiros" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Yes", IDYES, 20, 122, 60, 14 - PUSHBUTTON "Yes to &All", 12807, 85, 122, 60, 14 - PUSHBUTTON "&No", IDNO, 150, 122, 60, 14 - PUSHBUTTON "Cancel", IDCANCEL, 215, 122, 60, 14 + DEFPUSHBUTTON "&Sim", IDYES, 20, 122, 60, 14 + PUSHBUTTON "Sim para &Todos", 12807, 85, 122, 60, 14 + PUSHBUTTON "&No", IDNO, 150, 122, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 215, 122, 60, 14 ICON 146, -1, 11, 10, 21, 20, SS_REALSIZECONTROL - LTEXT "This folder already contains a file named '%2'.", 12291, 44, 10, 231, 22, SS_NOPREFIX - LTEXT "This folder already contains a read-only file named '%2'.", 12292, 41, 10, 222, 22, SS_NOPREFIX - LTEXT "This folder already contains a system file named '%2'.", 12293, 41, 10, 222, 22, SS_NOPREFIX - LTEXT "Would you like to replace the existing file", -1, 44, 35, 228, 10, SS_NOPREFIX - LTEXT "(unknown date and size)", 12302, 79, 51, 198, 20, SS_NOPREFIX + LTEXT "Esta pasta j contm um ficheiro com o nome '%2'.", 12291, 44, 10, 231, 22, SS_NOPREFIX + LTEXT "Esta pasta j contm um ficheiro smente de leitura com o nome '%2'.", 12292, 41, 10, 222, 22, SS_NOPREFIX + LTEXT "Esta pasta j contm um ficheiro de sistema com o nome '%2'.", 12293, 41, 10, 222, 22, SS_NOPREFIX + LTEXT "pretende substituir o ficheiro existente", -1, 44, 35, 228, 10, SS_NOPREFIX + LTEXT "(data e tamanho desconhecido)", 12302, 79, 51, 198, 20, SS_NOPREFIX ICON "", 12300, 50, 49, 21, 20, SS_REALSIZECONTROL - LTEXT "with this one?", -1, 44, 75, 228, 10, SS_NOPREFIX - LTEXT "(unknown date and size)", 12303, 79, 91, 198, 20, SS_NOPREFIX + LTEXT "por este?", -1, 44, 75, 228, 10, SS_NOPREFIX + LTEXT "(data e tamanho desconhecido)", 12303, 79, 91, 198, 20, SS_NOPREFIX ICON "", 12301, 50, 89, 21, 20, SS_REALSIZECONTROL END LOGOFF_DLG DIALOGEX 0, 0, 190, 60 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION -CAPTION "Log Off ReactOS" +CAPTION "Terminar sesso ReactOS" FONT 8, "MS Shell Dlg" BEGIN ICON 45, 14344, 10, 10, 21, 20, SS_REALSIZECONTROL - LTEXT "Are you sure you want to log off?", -1, 43, 11, 140, 22 - DEFPUSHBUTTON "&Log Off", IDOK, 57, 40, 60, 14 - PUSHBUTTON "Cancel", IDCANCEL, 122, 40, 60, 14 + LTEXT "Tem a certeza que quer terminar a sesso?", -1, 43, 11, 140, 22 + DEFPUSHBUTTON "&Terminar a sesso", IDOK, 57, 40, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 122, 40, 60, 14 END DISCONNECT_DLG DIALOGEX 0, 0, 190, 60 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION -CAPTION "Disconnect ReactOS" +CAPTION "Encerrar ReactOS" FONT 8, "MS Shell Dlg" BEGIN ICON 49, 14346, 10, 10, 21, 20, SS_REALSIZECONTROL - LTEXT "Are you sure you want to disconnect?", -1, 49, 12, 137, 23 - DEFPUSHBUTTON "&Disconnect", IDOK, 57, 40, 60, 14 - PUSHBUTTON "Cancel", IDCANCEL, 123, 40, 60, 14 + LTEXT "Tem a certeza que quer encerrar?", -1, 49, 12, 137, 23 + DEFPUSHBUTTON "&Encerrar", IDOK, 57, 40, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 123, 40, 60, 14 END AUTOPLAY1_DLG DIALOGEX 0, 0, 227, 218 @@ -478,42 +479,42 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUPWINDOW | WS_VISIBLE | WS_CLIPSIBLIN CAPTION "AutoPlay" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "&Select a content type, then choose an action for ReactOS to perform automatically when that type is used in this device:", 1000, 7, 7, 215, 20 + LTEXT "&Seleccione o tipo de contedo, depois escolha uma aco para o RactOS executar automticamente quando este tipo for usado neste dispositivo:", 1000, 7, 7, 215, 20 CONTROL "", 1001, "COMBOBOXEX32", WS_TABSTOP | 0x00000043, 7, 27, 212, 200 - GROUPBOX "Actions", -1, 7, 45, 212, 146 - AUTORADIOBUTTON "Select an action to &perform:", 1005, 14, 54, 202, 10, WS_GROUP + GROUPBOX "Aces", -1, 7, 45, 212, 146 + AUTORADIOBUTTON "Seleccione uma aco para &executar:", 1005, 14, 54, 202, 10, WS_GROUP CONTROL "LIST2", 1002, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 22, 66, 192, 107 - AUTORADIOBUTTON "Prompt me each time to &choose an action", 1006, 14, 177, 202, 10 - PUSHBUTTON "&Restore Defaults", 1008, 108, 197, 110, 14, WS_DISABLED + AUTORADIOBUTTON "pergunte-me sempre para escolher uma &aco", 1006, 14, 177, 202, 10 + PUSHBUTTON "&Restaurar valores por defeito", 1008, 108, 197, 110, 14, WS_DISABLED END MIXED_CONTENT1_DLG DIALOGEX 0, 0, 227, 207 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION -CAPTION "Mixed Content" +CAPTION "Contedos mistos" FONT 8, "MS Shell Dlg" BEGIN ICON "", 1000, 5, 7, 21, 20 - LTEXT "This disk or device contains more than one type of content.", 1001, 32, 7, 191, 20 - LTEXT "What do you want ReactOS to do?", 1002, 32, 31, 188, 8 + LTEXT "Este disco ou dispositivo contm mais de um tipo de contedo.", 1001, 32, 7, 191, 20 + LTEXT "O que pretende que o ReactOS faa?", 1002, 32, 31, 188, 8 CONTROL "", 1003, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 32, 43, 188, 139 DEFPUSHBUTTON "OK", IDOK, 96, 186, 60, 14 - PUSHBUTTON "Cancel", IDCANCEL, 160, 186, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 160, 186, 60, 14 END MIXED_CONTENT2_DLG DIALOGEX 0, 0, 227, 206 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION -CAPTION "Mixed Content" +CAPTION "Contedo misto" FONT 8, "MS Shell Dlg" BEGIN ICON "", 1000, 5, 7, 21, 20 - LTEXT "ReactOS can perform the same action each time you insert a disk or connect a device with this kind of file:", 1001, 30, 7, 193, 20 + LTEXT "ReactOS pode executar a mesma aco de cada vez que inserir um disco ou um dispositivo com este tipo de ficheiro:", 1001, 30, 7, 193, 20 ICON "", 1005, 32, 27, 11, 10, SS_REALSIZECONTROL EDITTEXT 1006, 49, 28, 177, 14, ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "What do you want ReactOS to do?", 1002, 32, 41, 190, 8 + LTEXT "O que pretende que o ReactOS faa?", 1002, 32, 41, 190, 8 CONTROL "", 1003, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 32, 55, 188, 112 - AUTOCHECKBOX "Always do the selected action.", 1004, 32, 171, 190, 10 + AUTOCHECKBOX "Executar sempre a aco seleccionada.", 1004, 32, 171, 190, 10 DEFPUSHBUTTON "OK", IDOK, 96, 185, 60, 14 - PUSHBUTTON "Cancel", IDCANCEL, 160, 185, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 160, 185, 60, 14 END AUTOPLAY2_DLG DIALOGEX 0, 0, 227, 181 @@ -522,75 +523,75 @@ CAPTION "Autoplay" FONT 8, "MS Shell Dlg" BEGIN ICON "", 1000, 5, 7, 21, 20 - LTEXT "ReactOS can perform the same action each time you connect this device.", 1001, 32, 7, 190, 22 - LTEXT "&What do you want ReactOS to do?", 1002, 32, 31, 190, 8 + LTEXT "ReactOS pode executar sempre mesma aco de cada vez que inserir um disco ou um dispositivo.", 1001, 32, 7, 190, 22 + LTEXT "&O que pretende que o ReactOS faa?", 1002, 32, 31, 190, 8 CONTROL "", 1003, "SYSLISTVIEW32", WS_BORDER | WS_TABSTOP | 0x0000C04D, 32, 43, 187, 96 - AUTOCHECKBOX "&Always perform the selected action", 1004, 32, 143, 190, 8 + AUTOCHECKBOX "&Executar sempre a aco seleccionada", 1004, 32, 143, 190, 8 DEFPUSHBUTTON "OK", IDOK, 94, 160, 60, 14 - PUSHBUTTON "Cancel", IDCANCEL, 159, 160, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 159, 160, 60, 14 END SHUTDOWN_DLG DIALOGEX 0, 0, 211, 103 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION -CAPTION "Shut Down ReactOS" +CAPTION "Encerrar ReactOS" FONT 8, "MS Shell Dlg" BEGIN ICON 8240, -1, 6, 6, 21, 20, SS_REALSIZECONTROL | WS_GROUP - LTEXT "What do you want the computer to do?", -1, 39, 7, 167, 10 + LTEXT "O que pretende aue o computador faa?", -1, 39, 7, 167, 10 COMBOBOX 8224, 39, 20, 165, 200, CBS_DROPDOWNLIST | WS_VSCROLL - LTEXT "Maintains your session, keeping the computer running on low power with data still in memory. The computer wakes up when you press a key or move the mouse.", 8225, 39, 40, 167, 37 + LTEXT "Manter a sesso, deixando o computador a correr em baixa energia. O computador arranca quando tocar numa tecla ou mover o rato.", 8225, 39, 40, 167, 37 DEFPUSHBUTTON "OK", 1, 7, 82, 60, 14, WS_GROUP - PUSHBUTTON "Cancel", IDCANCEL, 75, 82, 60, 14 - PUSHBUTTON "&Help", IDHELP, 144, 82, 60, 14 + PUSHBUTTON "Cancelar", IDCANCEL, 75, 82, 60, 14 + PUSHBUTTON "&Ajuda", IDHELP, 144, 82, 60, 14 END FORMAT_DLG DIALOGEX 50, 50, 184, 218 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Format" +CAPTION "Formatar" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "&Start", IDOK, 53, 198, 60, 14 - PUSHBUTTON "&Close", IDCANCEL, 118, 198, 60, 14 - LTEXT "Ca&pacity:", -1, 7, 6, 169, 9 + DEFPUSHBUTTON "&Iniciar", IDOK, 53, 198, 60, 14 + PUSHBUTTON "&Fechar", IDCANCEL, 118, 198, 60, 14 + LTEXT "Ca&pacidade:", -1, 7, 6, 169, 9 COMBOBOX 28673, 7, 17, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP - LTEXT "&File system", -1, 7, 35, 170, 9 + LTEXT "&Sistema de Ficheiros", -1, 7, 35, 170, 9 COMBOBOX 28677, 7, 46, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP CONTROL "", 28678, "MSCTLS_PROGRESS32", 0, 7, 181, 170, 8 - LTEXT "&Allocation unit size", -1, 7, 64, 170, 9 + LTEXT "&Tamanho da unidade de alocao", -1, 7, 64, 170, 9 COMBOBOX 28680, 7, 75, 170, 200, CBS_DROPDOWNLIST | WS_VSCROLL | NOT WS_TABSTOP - LTEXT "Volume &label", -1, 7, 93, 170, 9 + LTEXT "&Nome do Volume ", -1, 7, 93, 170, 9 EDITTEXT 28679, 7, 103, 170, 13, ES_AUTOHSCROLL - GROUPBOX "Format &options", 4610, 7, 121, 170, 49 - AUTOCHECKBOX "&Quick Format", 28674, 16, 135, 155, 10 - AUTOCHECKBOX "&Enable Compression", 28675, 16, 152, 155, 10 + GROUPBOX "&Opes", 4610, 7, 121, 170, 49 + AUTOCHECKBOX "Formatao &Rpida", 28674, 16, 135, 155, 10 + AUTOCHECKBOX "&Permitir Compresso", 28675, 16, 152, 155, 10 END CHKDSK_DLG DIALOGEX 50, 50, 194, 120 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Check Disk" +CAPTION "Verificar Disco" FONT 8, "MS Shell Dlg" BEGIN - DEFPUSHBUTTON "Start", IDOK, 53, 100, 60, 14 - GROUPBOX "Check disk options", -1, 7, 6, 179, 50 - PUSHBUTTON "Cancel", IDCANCEL, 118, 100, 60, 14 - AUTOCHECKBOX "Automatically fix file system errors", 14000, 16, 15, 155, 10 - AUTOCHECKBOX "&Scan for and attempt recovery of bad sectors", 14001, 16, 30, 165, 10 + DEFPUSHBUTTON "Iniciar", IDOK, 53, 100, 60, 14 + GROUPBOX "Opes verificao do disco", -1, 7, 6, 179, 50 + PUSHBUTTON "Cancelar", IDCANCEL, 118, 100, 60, 14 + AUTOCHECKBOX "Reparar automticamente erros nos ficheiros do sistema", 14000, 16, 15, 155, 10 + AUTOCHECKBOX "&Procurar e tentar reparar sectores danificados", 14001, 16, 30, 165, 10 CONTROL "", 14002, "MSCTLS_PROGRESS32", 16, 7, 60, 170, 8 LTEXT "", 14003, 60, 80, 170, 10 END IDD_PICK_ICON_DIALOG DIALOGEX 0, 0, 237, 204 STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION -CAPTION "Change Icon" +CAPTION "Trocar Icone" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LTEXT "Filename:", -1, 7, 14, 208, 10 - PUSHBUTTON "Browse...",IDC_BUTTON_PATH, 148, 24,67,14 + LTEXT "Nome do ficheiro:", -1, 7, 14, 208, 10 + PUSHBUTTON "procurar...",IDC_BUTTON_PATH, 148, 24,67,14 EDITTEXT IDC_EDIT_PATH, 6, 24, 135, 15, ES_AUTOHSCROLL LTEXT "Icons:", -1, 7, 47, 208, 10 LISTBOX IDC_PICKICON_LIST,7,57,208,119,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_MULTICOLUMN | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,WS_EX_STATICEDGE DEFPUSHBUTTON "OK",IDOK, 107, 181,50, 14 - PUSHBUTTON "Cancel",IDCANCEL, 167, 181, 50, 14 + PUSHBUTTON "Cancelar",IDCANCEL, 167, 181, 50, 14 END STRINGTABLE DISCARDABLE @@ -600,32 +601,32 @@ BEGIN IDS_SHV_COLUMN2 "Tamanho" IDS_SHV_COLUMN3 "Tipo" IDS_SHV_COLUMN4 "Modificado" - IDS_SHV_COLUMN5 "Atributos" + IDS_SHV_COLUMN5 "propriedades" IDS_SHV_COLUMN6 "Tamanho" IDS_SHV_COLUMN7 "Disponvel" IDS_SHV_COLUMN8 "Nome" IDS_SHV_COLUMN9 "Comentrios" IDS_SHV_COLUMN10 "Dono" IDS_SHV_COLUMN11 "Grupo" - IDS_SHV_COLUMN12 "Filename" - IDS_SHV_COLUMN13 "Category" - IDS_SHV_COLUMN_DELFROM "Original location" - IDS_SHV_COLUMN_DELDATE "Date deleted" - IDS_SHV_COLUMN_FONTTYPE "Fonttype" - IDS_SHV_COLUMN_WORKGROUP "Workgroup" - IDS_SHV_NETWORKLOCATION "Network Location" - IDS_SHV_COLUMN_DOCUMENTS "Documents" - IDS_SHV_COLUMN_STATUS "Status" - IDS_SHV_COLUMN_COMMENTS "Comments" - IDS_SHV_COLUMN_LOCATION "Location" - IDS_SHV_COLUMN_MODEL "Model" + IDS_SHV_COLUMN12 "Nome do ficheiro" + IDS_SHV_COLUMN13 "Categoria" + IDS_SHV_COLUMN_DELFROM "Localizao original" + IDS_SHV_COLUMN_DELDATE "Data da eliminao" + IDS_SHV_COLUMN_FONTTYPE "Tipo de letra" + IDS_SHV_COLUMN_WORKGROUP "Grupo de trabalho" + IDS_SHV_NETWORKLOCATION "localizaes na rede" + IDS_SHV_COLUMN_DOCUMENTS "Documentos" + IDS_SHV_COLUMN_STATUS "Estado" + IDS_SHV_COLUMN_COMMENTS "Commentrios" + IDS_SHV_COLUMN_LOCATION "Localizao" + IDS_SHV_COLUMN_MODEL "Modelo" /* special folders */ IDS_DESKTOP "Ambiente de trabalho" IDS_MYCOMPUTER "O Meu Computador" - IDS_RECYCLEBIN_FOLDER_NAME "Trash" - IDS_CONTROLPANEL "Control Panel" - IDS_ADMINISTRATIVETOOLS "Administrative Tools" + IDS_RECYCLEBIN_FOLDER_NAME "Reciclagem" + IDS_CONTROLPANEL "Painel de Controlo" + IDS_ADMINISTRATIVETOOLS "Ferramentas Administrativas" /* context menus */ IDS_VIEW_LARGE "cones &grandes" @@ -634,15 +635,15 @@ BEGIN IDS_VIEW_DETAILS "&Detalhes" IDS_SELECT "Seleccionar" IDS_OPEN "Abrir" - IDS_CREATELINK "Create &Link" - IDS_COPY "Copy" - IDS_DELETE "Delete" - IDS_PROPERTIES "Properties" - IDS_CUT "Cut" - IDS_RESTORE "Restore" - IDS_FORMATDRIVE "Format..." - IDS_RENAME "Rename" - IDS_INSERT "Insert" + IDS_CREATELINK "Criar &Atalho" + IDS_COPY "Copiar" + IDS_DELETE "Apagar" + IDS_PROPERTIES "Propriedades" + IDS_CUT "Cortar" + IDS_RESTORE "Restaurar" + IDS_FORMATDRIVE "Formatar..." + IDS_RENAME "Renaomear" + IDS_INSERT "Inserir" IDS_CREATEFOLDER_DENIED "No possvel criar nova pasta: Permisso negada." IDS_CREATEFOLDER_CAPTION "Erro durante a criao da nova pasta" @@ -650,23 +651,25 @@ BEGIN IDS_DELETEFOLDER_CAPTION "Confirmar excluso da pasta" IDS_DELETEITEM_TEXT "Tem certeza que deseja excluir '%1'?" IDS_DELETEMULTIPLE_TEXT "Tem certeza que deseja excluir estes %1 itens?" - IDS_DELETESELECTED_TEXT "Are you sure you want to delete the selected item(s)?" - IDS_TRASHITEM_TEXT "Are you sure that you want to send '%1' to the Trash?" - IDS_TRASHFOLDER_TEXT "Are you sure that you want to send '%1' and all its content to the Trash?" - IDS_TRASHMULTIPLE_TEXT "Are you sure that you want to send these %1 items to the Trash?" - IDS_CANTTRASH_TEXT "The item '%1' can't be sent to Trash. Do you want to delete it instead?" - IDS_OVERWRITEFILE_TEXT "This folder already contains a file called '%1'.\n\nDo you want to replace it?" + IDS_DELETESELECTED_TEXT "Tem a certeza que quer eliminar os item(s) seleccionado(s)?" + IDS_TRASHITEM_TEXT "Tem a certeza que quer enviar '%1' para a reciclagem?" + IDS_TRASHFOLDER_TEXT "Tem a certeza que quer enviar '%1' e todo o seu contedo para a reciclagem?" + IDS_TRASHMULTIPLE_TEXT "Tem a certeza que quer enviar este '%1' item para a reciclagem?" + IDS_CANTTRASH_TEXT "O item '%1' no pode ser enviado para a reciclagem. Em vez disso pretende elimin-lo?" + IDS_OVERWRITEFILE_TEXT "Esta pasta j contm um ficheiro com o nome '%1'.\n\npretende substitu-lo?" IDS_OVERWRITEFILE_CAPTION "Confirmar substituio de ficheiro" - IDS_OVERWRITEFOLDER_TEXT "This folder already contains a folder named '%1'.\n\n"\ - "If the files in the destination folder have the same names as files in the\n"\ - "selected folder they will be replaced. Do you still want to move or copy\n"\ - "the folder?" + IDS_OVERWRITEFOLDER_TEXT "Esta pasta j contm uma pasta com o nome '%1'.\n\n"\ + "Se os ficheiros na pasta de destino tiverem o mesmo nome dos ficheiros na\n"\ + "pasta seleccionada, sero substitudos. Ainda assim pretende mover ou copiar\n"\ + "a pasta?" /* message box strings */ IDS_RESTART_TITLE "Reiniciar" IDS_RESTART_PROMPT "Deseja simular a reinicializao do Windows?" IDS_SHUTDOWN_TITLE "Desligar" - IDS_SHUTDOWN_PROMPT "Deseja finalizar esta sesso do Wine?" + IDS_SHUTDOWN_PROMPT "Deseja finalizar esta sesso do ReactOS?" + IDS_LOGOFF_TITLE "Terminar a sesso" + IDS_LOGOFF_PROMPT "Pretende terminar a sesso?" /* shell folder path default values */ IDS_PROGRAMS "Menu Iniciar\\Programas" @@ -679,12 +682,12 @@ BEGIN IDS_MYMUSIC "As Minhas Msicas" IDS_MYVIDEO "Os Meus Vdeos" IDS_DESKTOPDIRECTORY "Ambiente de Trabalho" - IDS_NETHOOD "NetHood" + IDS_NETHOOD "Visinhana na rede" IDS_TEMPLATES "Modelos" - IDS_APPDATA "Application Data" + IDS_APPDATA "Dados de Aplicao" IDS_PRINTHOOD "PrintHood" - IDS_LOCAL_APPDATA "Definies locais\\Application Data" - IDS_INTERNET_CACHE "Definies locais\\Temporary Internet Files" + IDS_LOCAL_APPDATA "Definies locais\\Dados de Aplicao" + IDS_INTERNET_CACHE "Definies locais\\Ficheiros Temporrios da Internet" IDS_COOKIES "Cookies" IDS_HISTORY "Definies locais\\Histrico" IDS_PROGRAM_FILES "Programas" @@ -695,60 +698,62 @@ BEGIN IDS_COMMON_MUSIC "Os Meus Documentos\\As Minhas Msicas" IDS_COMMON_PICTURES "Os Meus Documentos\\As Minhas Imagens" IDS_COMMON_VIDEO "Os Meus Documentos\\Os Meus Vdeos" - IDS_CDBURN_AREA "Definies locais\\Application Data\\Microsoft\\CD Burning" - IDS_NETWORKPLACE "My Network Places" + IDS_CDBURN_AREA "Definies locais\\Dados de Aplicao\\Microsoft\\CD Burning" + IDS_NETWORKPLACE "Os Meus Locais da Rede" - IDS_NEWFOLDER "New Folder" + IDS_NEWFOLDER "Nova Pasta" - IDS_DRIVE_FIXED "Local Disk" + IDS_DRIVE_FIXED "Disco Local" IDS_DRIVE_CDROM "CDROM" - IDS_DRIVE_NETWORK "Network Disk" + IDS_DRIVE_NETWORK "Disco de Rede" - IDS_OPEN_WITH "Open With" - IDS_OPEN_WITH_CHOOSE "Choose Program..." + IDS_OPEN_WITH "Abre com..." + IDS_OPEN_WITH_CHOOSE "Escolha Programa..." - IDS_SHELL_ABOUT_AUTHORS "&Authors" - IDS_SHELL_ABOUT_BACK "< &Back" + IDS_SHELL_ABOUT_AUTHORS "&Autores" + IDS_SHELL_ABOUT_BACK "< &Trs" FCIDM_SHVIEW_NEW "Novo" FCIDM_SHVIEW_NEWFOLDER "&Pasta" FCIDM_SHVIEW_NEWLINK "&Atalho" - IDS_FOLDER_OPTIONS "Folder Options" - IDS_RECYCLEBIN_LOCATION "Recycle Bin Location" - IDS_RECYCLEBIN_DISKSPACE "Space Available" - IDS_EMPTY_BITBUCKET "Empty Recycle Bin" - IDS_PICK_ICON_TITLE "Choose Icon" - IDS_PICK_ICON_FILTER "Icon Files(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" - IDS_OPEN_WITH_FILTER "Executable Files\0*.exe\0" - IDS_DIRECTORY "Folder" - IDS_VIRTUAL_DRIVER "Virtual Device Driver" + IDS_FOLDER_OPTIONS "Opes das Pastas" + IDS_RECYCLEBIN_LOCATION "Localizao da Reciclagem" + IDS_RECYCLEBIN_DISKSPACE "Espao Disponvel" + IDS_EMPTY_BITBUCKET "Esvaziar Reciclagem" + IDS_PICK_ICON_TITLE "Escolha cone" + IDS_PICK_ICON_FILTER "Ficheiros de cones(*.ico, *.icl, *.exe, *.dll)\0*.ico;*.icl;*.exe;*.dll\0" + IDS_OPEN_WITH_FILTER "Ficheiros Executveis\0*.exe\0" + IDS_DIRECTORY "Pasta" + IDS_VIRTUAL_DRIVER "Driver de Dispositivo Virtual" IDS_BAT_FILE "ReactOS Batch File" IDS_CMD_FILE "ReactOS Command Script" - IDS_COM_FILE "Dos Application" - IDS_CPL_FILE "Control Panel Item" + IDS_COM_FILE "Aplicao Dos" + IDS_CPL_FILE "Item do Painel de Controle" IDS_CUR_FILE "Cursor" - IDS_DLL_FILE "Application Extension" - IDS_DRV_FILE "Device Driver" - IDS_EXE_FILE "Application" - IDS_FON_FILE "Font file" - IDS_TTF_FILE "TrueType Font file" - IDS_HLP_FILE "Help File" - IDS_INI_FILE "Configuration Settings" - IDS_LNK_FILE "Shortcut" - IDS_SYS_FILE "System file" + IDS_DLL_FILE "Extenso da Aplicao" + IDS_DRV_FILE "Driver do Dispositivo" + IDS_EXE_FILE "Aplicao" + IDS_FON_FILE "Ficheiro de tipo de letra" + IDS_TTF_FILE "Tipo de letra TrueType" + IDS_HLP_FILE "Ficheiro de Ajuda" + IDS_INI_FILE "Definies" + IDS_LNK_FILE "Atalho" + IDS_SYS_FILE "Ficheiro de Sistema" - IDS_OPEN_VERB "Open" - IDS_RUNAS_VERB "Run as " - IDS_EDIT_VERB "Edit" - IDS_FIND_VERB "Find" - IDS_PRINT_VERB "Print" - IDS_PLAY_VERB "Play" - IDS_PREVIEW_VERB "Preview" + IDS_OPEN_VERB "Abrir" + IDS_RUNAS_VERB "Executar como " + IDS_EDIT_VERB "Editar" + IDS_FIND_VERB "Procurar" + IDS_PRINT_VERB "Imprimir" + IDS_PLAY_VERB "Reproduzir" + IDS_PREVIEW_VERB "Previzualizar" - IDS_FILE_FOLDER "%u Files, %u Folders" - IDS_PRINTERS "Printers" - IDS_FONTS "Fonts" - IDS_INSTALLNEWFONT "Install New Font..." + IDS_FILE_FOLDER "%u Ficheiros, %u Pastas" + IDS_PRINTERS "Impressoras" + IDS_FONTS "Tipos de Letras" + IDS_INSTALLNEWFONT "Instalar novo tipo de letra..." - IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" - IDS_COPY_OF "Copy of" + IDS_DEFAULT_CLUSTER_SIZE "Tamanho da unidade de atribuio" + IDS_COPY_OF "Cpia de" + + IDS_SHLEXEC_NOASSOC "No existe um programa Windows configurado para abrir este tipo de ficheiro." END diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc index 656bc410bc9..fb24c2ba437 100644 --- a/dll/win32/shell32/lang/ro-RO.rc +++ b/dll/win32/shell32/lang/ro-RO.rc @@ -361,7 +361,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -668,6 +668,8 @@ BEGIN IDS_RESTART_PROMPT "Vreți să reporniți sistemul?" IDS_SHUTDOWN_TITLE "Închidere" IDS_SHUTDOWN_PROMPT "Vreți să închideți computerul?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Meniu Start\\Programe" @@ -751,6 +753,8 @@ BEGIN IDS_INSTALLNEWFONT "Instalare font nou..." IDS_DEFAULT_CLUSTER_SIZE "Mărime de alocare implicită" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END #pragma code_page(default) diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc index 7d6e1e1e06e..daf4f2ce16b 100644 --- a/dll/win32/shell32/lang/ru-RU.rc +++ b/dll/win32/shell32/lang/ru-RU.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION " " FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -664,6 +664,8 @@ BEGIN IDS_RESTART_PROMPT " ReactOS?" IDS_SHUTDOWN_TITLE " " IDS_SHUTDOWN_PROMPT " ReactOS?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS " \\" @@ -748,4 +750,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE " " IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc index 2ec58ec12ae..897564b799a 100644 --- a/dll/win32/shell32/lang/sk-SK.rc +++ b/dll/win32/shell32/lang/sk-SK.rc @@ -364,7 +364,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Otvori v programe" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -671,6 +671,8 @@ BEGIN IDS_RESTART_PROMPT "Naozaj chcete retartova systm?" IDS_SHUTDOWN_TITLE "Vypn" IDS_SHUTDOWN_PROMPT "Naozaj chcete vypn pota?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Ponuka tart\\Programy" @@ -755,4 +757,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Predvolen alokan vekos" //Default allocation size IDS_COPY_OF "Kpia" //Copy of + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc index 876be4b4927..9789ec3841c 100644 --- a/dll/win32/shell32/lang/sl-SI.rc +++ b/dll/win32/shell32/lang/sl-SI.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "Noben Okenski program ni nastavljen, da bi odpiral ta tip datotek." END diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc index e7a520f5ba4..4ddd5c36520 100644 --- a/dll/win32/shell32/lang/sv-SE.rc +++ b/dll/win32/shell32/lang/sv-SE.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc index 49a154c3408..633936f625a 100644 --- a/dll/win32/shell32/lang/tr-TR.rc +++ b/dll/win32/shell32/lang/tr-TR.rc @@ -358,7 +358,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -665,6 +665,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Oturumu Kapat" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programlar" @@ -749,4 +751,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc index 3846965c696..807a7c9afa3 100644 --- a/dll/win32/shell32/lang/uk-UA.rc +++ b/dll/win32/shell32/lang/uk-UA.rc @@ -359,7 +359,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION " " FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -666,6 +666,8 @@ BEGIN IDS_RESTART_PROMPT " ?" IDS_SHUTDOWN_TITLE "" IDS_SHUTDOWN_PROMPT " '?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -750,4 +752,6 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE " " IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc index 5180db558cd..aa54e3eecb6 100644 --- a/dll/win32/shell32/lang/zh-CN.rc +++ b/dll/win32/shell32/lang/zh-CN.rc @@ -347,7 +347,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -654,6 +654,8 @@ BEGIN IDS_RESTART_PROMPT "Ƿϵͳ?" IDS_SHUTDOWN_TITLE "ػ" IDS_SHUTDOWN_PROMPT "Ƿرϵͳ?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -737,5 +739,7 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc index fc76bf15798..fcf7abf9f7b 100644 --- a/dll/win32/shell32/lang/zh-TW.rc +++ b/dll/win32/shell32/lang/zh-TW.rc @@ -359,7 +359,7 @@ BEGIN END OPEN_WITH_PROGRAMM_DLG DIALOGEX 0, 0, 264, 256 -STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUPWINDOW | WS_CAPTION CAPTION "Open With" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -666,6 +666,8 @@ BEGIN IDS_RESTART_PROMPT "Do you want to restart the system?" IDS_SHUTDOWN_TITLE "Shutdown" IDS_SHUTDOWN_PROMPT "Do you want to shutdown?" + IDS_LOGOFF_TITLE "Log Off" + IDS_LOGOFF_PROMPT "Do you want to log off?" /* shell folder path default values */ IDS_PROGRAMS "Start Menu\\Programs" @@ -750,6 +752,8 @@ BEGIN IDS_DEFAULT_CLUSTER_SIZE "Default allocation size" IDS_COPY_OF "Copy of" + + IDS_SHLEXEC_NOASSOC "There is no Windows program configured to open this type of file." END #pragma code_page(default) diff --git a/dll/win32/shell32/she_ocmenu.c b/dll/win32/shell32/she_ocmenu.c index dc66376cdea..1b6adec94aa 100644 --- a/dll/win32/shell32/she_ocmenu.c +++ b/dll/win32/shell32/she_ocmenu.c @@ -719,12 +719,12 @@ static INT_PTR CALLBACK OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wPar if (lpdis->itemID == index) { - /* paint focused item with blue background */ + /* paint focused item with standard background colour */ HBRUSH hBrush; - hBrush = CreateSolidBrush(RGB(0, 0, 255)); + hBrush = CreateSolidBrush(RGB(46, 104, 160)); FillRect(lpdis->hDC, &lpdis->rcItem, hBrush); DeleteObject(hBrush); - preBkColor = SetBkColor(lpdis->hDC, RGB(255, 255, 255)); + preBkColor = SetBkColor(lpdis->hDC, RGB(46, 104, 160)); } else { @@ -756,6 +756,10 @@ static INT_PTR CALLBACK OpenWithProgrammDlg(HWND hwndDlg, UINT uMsg, WPARAM wPar break; } break; + case WM_CLOSE: + FreeListItems(hwndDlg); + EndDialog(hwndDlg, 0); + return TRUE; default: break; } diff --git a/dll/win32/shell32/shfldr_cpanel.c b/dll/win32/shell32/shfldr_cpanel.c index 57e3701d88f..bf8b632f8eb 100644 --- a/dll/win32/shell32/shfldr_cpanel.c +++ b/dll/win32/shell32/shfldr_cpanel.c @@ -1298,8 +1298,8 @@ static HRESULT WINAPI ICPanel_IContextMenu2_InvokeCommand( sei.hwnd = lpcmi->hwnd; sei.nShow = SW_SHOWNORMAL; sei.lpVerb = L"open"; - ShellExecuteExW(&sei); - if (sei.hInstApp <= (HINSTANCE)32) + + if (ShellExecuteExW(&sei) == FALSE) return E_FAIL; } else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_CREATELINK)) //FIXME diff --git a/dll/win32/shell32/shfldr_fonts.c b/dll/win32/shell32/shfldr_fonts.c index d4f87b68b6e..4ec244f00ab 100644 --- a/dll/win32/shell32/shfldr_fonts.c +++ b/dll/win32/shell32/shfldr_fonts.c @@ -979,8 +979,7 @@ static HRESULT WINAPI ISF_Fonts_IContextMenu2_InvokeCommand( pfont = _ILGetFontStruct(This->apidl); sei.lpFile = pfont->szName + pfont->offsFile; - ShellExecuteExW(&sei); - if (sei.hInstApp <= (HINSTANCE)32) + if (ShellExecuteExW(&sei) == FALSE) return E_FAIL; } else if (lpcmi->lpVerb == MAKEINTRESOURCEA(4)) diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h index e28efb0e240..981e17ff9ce 100644 --- a/dll/win32/shell32/shresdef.h +++ b/dll/win32/shell32/shresdef.h @@ -90,6 +90,9 @@ #define IDS_FONTS 76 #define IDS_PRINTERS 77 +#define IDS_LOGOFF_TITLE 78 +#define IDS_LOGOFF_PROMPT 79 + #define IDS_CREATEFOLDER_DENIED 128 #define IDS_CREATEFOLDER_CAPTION 129 #define IDS_DELETEITEM_CAPTION 130 diff --git a/dll/win32/shell32/shv_def_cmenu.c b/dll/win32/shell32/shv_def_cmenu.c index 71c25a7d407..08c9c3c9c74 100644 --- a/dll/win32/shell32/shv_def_cmenu.c +++ b/dll/win32/shell32/shv_def_cmenu.c @@ -48,7 +48,7 @@ static LPIDefaultContextMenuImpl __inline impl_from_IContextMenu( IContextMenu2 } VOID INewItem_SetCurrentShellFolder(IShellFolder * psfParent); // HACK - +WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls); static HRESULT @@ -1297,12 +1297,12 @@ DoDelete( HRESULT hr; STRRET strTemp; WCHAR szPath[MAX_PATH]; + LPWSTR wszPath, wszPos; SHFILEOPSTRUCTW op; int ret; LPSHELLBROWSER lpSB; HWND hwnd; - hr = IShellFolder2_GetDisplayNameOf(This->dcm.psf, This->dcm.apidl[0], SHGDN_FORPARSING, &strTemp); if(hr != S_OK) { @@ -1316,20 +1316,26 @@ DoDelete( ERR("StrRetToBufW failed with %x\n", hr); return hr; } - /* FIXME - * implement deletion with multiple files - */ + + /* Only keep the base path */ + wszPos = strrchrW(szPath, '\\'); + if (wszPos != NULL) + { + *(wszPos + 1) = '\0'; + } + + wszPath = build_paths_list(szPath, This->dcm.cidl, This->dcm.apidl); ZeroMemory(&op, sizeof(op)); op.hwnd = GetActiveWindow(); op.wFunc = FO_DELETE; - op.pFrom = szPath; + op.pFrom = wszPath; op.fFlags = FOF_ALLOWUNDO; ret = SHFileOperationW(&op); if (ret) { - TRACE("SHFileOperation failed with %0x%x", GetLastError()); + ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(wszPath)); return S_OK; } @@ -1348,6 +1354,7 @@ DoDelete( } NotifyShellViewWindow(lpcmi, TRUE); + HeapFree(GetProcessHeap(), 0, wszPath); return S_OK; } diff --git a/dll/win32/syssetup/lang/it-IT.rc b/dll/win32/syssetup/lang/it-IT.rc index ba3f9988707..bc76a2eaca5 100644 --- a/dll/win32/syssetup/lang/it-IT.rc +++ b/dll/win32/syssetup/lang/it-IT.rc @@ -213,7 +213,7 @@ BEGIN IDS_GAMES "Giochi" IDS_CMT_SOLITAIRE "Solitario" IDS_CMT_WINEMINE "Campo minato" - IDS_CMT_SPIDER "Spider Solitaire" + IDS_CMT_SPIDER "Spider" END STRINGTABLE @@ -235,7 +235,7 @@ BEGIN IDS_SYS_ENTERTAINMENT "Divertimento" IDS_CMT_MPLAY32 "Esegui Multimedia Player" IDS_CMT_SNDVOL32 "Esegui Controllo Volume" - IDS_CMT_SNDREC32 "Launch Sound Recorder" + IDS_CMT_SNDREC32 "Esegui il Registratore di suonoi" END STRINGTABLE @@ -255,7 +255,7 @@ STRINGTABLE BEGIN IDS_SHORT_CMD "Prompt dei comandi.lnk" IDS_SHORT_EXPLORER "ReactOS Explorer.lnk" - IDS_SHORT_DOWNLOADER "ReactOS Applications Manager.lnk" + IDS_SHORT_DOWNLOADER "ReactOS gestione applicazioni.lnk" IDS_SHORT_SERVICE "Service Manager.lnk" IDS_SHORT_DEVICE "Device Manager.lnk" IDS_SHORT_MPLAY32 "Multimedia Player.lnk" @@ -271,12 +271,12 @@ BEGIN IDS_SHORT_RDESKTOP "Remote Desktop.lnk" IDS_SHORT_KBSWITCH "Layout di tastiera.lnk" IDS_SHORT_EVENTVIEW "Visualizzatore Eventi.lnk" - IDS_SHORT_MSCONFIG "Configuratione del sistema.lnk" + IDS_SHORT_MSCONFIG "Configurazione del sistema.lnk" IDS_SHORT_SNDVOL32 "Controllo Volume.lnk" IDS_SHORT_SNDREC32 "Audiorecorder.lnk" IDS_SHORT_DXDIAG "ReactX Diagnostica.lnk" IDS_SHORT_PAINT "Paint.lnk" - IDS_SHORT_SPIDER "Spider Solitaire.lnk" + IDS_SHORT_SPIDER "Spider.lnk" END STRINGTABLE diff --git a/dll/win32/user32/misc/stubs.c b/dll/win32/user32/misc/stubs.c index b053f389da9..06608d8c6ff 100644 --- a/dll/win32/user32/misc/stubs.c +++ b/dll/win32/user32/misc/stubs.c @@ -170,11 +170,11 @@ UserRealizePalette ( HDC hDC ) static HPEN SysColorPens[COLOR_MENUBAR + 1]; static HBRUSH SysColorBrushes[COLOR_MENUBAR + 1]; -DWORD +DWORD_PTR WINAPI SetSysColorsTemp(const COLORREF *pPens, const HBRUSH *pBrushes, - DWORD n) + DWORD_PTR n) { DWORD i; @@ -183,7 +183,7 @@ SetSysColorsTemp(const COLORREF *pPens, /* allocate our structure to remember old colors */ LPVOID pOldCol = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD)+n*sizeof(HPEN)+n*sizeof(HBRUSH)); LPVOID p = pOldCol; - *(DWORD *)p = n; p = (char*)p + sizeof(DWORD); + *(DWORD_PTR *)p = n; p = (char*)p + sizeof(DWORD); memcpy(p, SysColorPens, n*sizeof(HPEN)); p = (char*)p + n*sizeof(HPEN); memcpy(p, SysColorBrushes, n*sizeof(HBRUSH)); p = (char*)p + n*sizeof(HBRUSH); @@ -193,7 +193,7 @@ SetSysColorsTemp(const COLORREF *pPens, SysColorBrushes[i] = pBrushes[i]; } - return (DWORD) pOldCol; /* FIXME: pointer truncation */ + return (DWORD_PTR) pOldCol; } if (!pPens && !pBrushes) /* "restore" call */ { diff --git a/dll/win32/userenv/lang/cs-CZ.rc b/dll/win32/userenv/lang/cs-CZ.rc index a582d533aab..4067447b058 100644 --- a/dll/win32/userenv/lang/cs-CZ.rc +++ b/dll/win32/userenv/lang/cs-CZ.rc @@ -1,20 +1,6 @@ -/* - * Copyright (C) 2004 Eric Kohl - * 2008 Radek Liska - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +/* FILE: dll/win32/devmgr/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * UPDATED: 2010-01-07 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -36,7 +22,7 @@ BEGIN IDS_TEMPLATES "ablony" IDS_RECENT "Posledn dokumenty" IDS_SENDTO "SendTo" - IDS_PRINTHOOD "okoln tiskrny" + IDS_PRINTHOOD "Okoln tiskrny" IDS_NETHOOD "Okoln s" IDS_LOCALSETTINGS "Local Settings" IDS_LOCALAPPDATA "Local Settings\\Data Aplikac" diff --git a/dll/win32/userenv/setup.c b/dll/win32/userenv/setup.c index 796325c7b0c..ca422dd5e9f 100644 --- a/dll/win32/userenv/setup.c +++ b/dll/win32/userenv/setup.c @@ -674,10 +674,6 @@ InitializeProfiles(VOID) } } - SetEnvironmentVariableW(L"ProgramFiles", szProfilesPath); - SetEnvironmentVariableW(L"CommonProgramFiles", szCommonFilesDirPath); - - DPRINT("Success\n"); return TRUE; diff --git a/drivers/bus/acpi/acpi.rbuild b/drivers/bus/acpi/acpi.rbuild index c3e5b7dac90..334cdfc7024 100644 --- a/drivers/bus/acpi/acpi.rbuild +++ b/drivers/bus/acpi/acpi.rbuild @@ -10,7 +10,7 @@ - + @@ -36,3 +36,4 @@ buspdo.c main.c + diff --git a/drivers/bus/directory.rbuild b/drivers/bus/directory.rbuild index 11a8fbe3852..fc752ff4e18 100644 --- a/drivers/bus/directory.rbuild +++ b/drivers/bus/directory.rbuild @@ -13,4 +13,7 @@ + + + diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c new file mode 100644 index 00000000000..51a0f4bccaf --- /dev/null +++ b/drivers/bus/isapnp/fdo.c @@ -0,0 +1,141 @@ +/* + * PROJECT: ReactOS ISA PnP Bus driver + * FILE: fdo.c + * PURPOSE: FDO-specific code + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ +#include + +#define NDEBUG +#include + +NTSTATUS +NTAPI +IsaFdoStartDevice( + IN PISAPNP_FDO_EXTENSION FdoExt, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + NTSTATUS Status; + KIRQL OldIrql; + + KeAcquireSpinLock(&FdoExt->Lock, &OldIrql); + + Status = IsaHwDetectReadDataPort(FdoExt); + if (!NT_SUCCESS(Status)) + { + KeReleaseSpinLock(&FdoExt->Lock, OldIrql); + return Status; + } + + FdoExt->Common.State = dsStarted; + + KeReleaseSpinLock(&FdoExt->Lock, OldIrql); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaFdoQueryDeviceRelations( + IN PISAPNP_FDO_EXTENSION FdoExt, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + NTSTATUS Status; + PLIST_ENTRY CurrentEntry; + PISAPNP_LOGICAL_DEVICE IsaDevice; + PDEVICE_RELATIONS DeviceRelations; + KIRQL OldIrql; + ULONG i = 0; + + if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) + return Irp->IoStatus.Status; + + KeAcquireSpinLock(&FdoExt->Lock, &OldIrql); + + Status = IsaHwFillDeviceList(FdoExt); + if (!NT_SUCCESS(Status)) + { + KeReleaseSpinLock(&FdoExt->Lock, OldIrql); + return Status; + } + + DeviceRelations = ExAllocatePool(NonPagedPool, + sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * (FdoExt->DeviceCount - 1)); + if (!DeviceRelations) + { + KeReleaseSpinLock(&FdoExt->Lock, OldIrql); + return STATUS_INSUFFICIENT_RESOURCES; + } + + CurrentEntry = FdoExt->DeviceListHead.Flink; + while (CurrentEntry != &FdoExt->DeviceListHead) + { + IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, ListEntry); + + DeviceRelations->Objects[i++] = IsaDevice->Common.Self; + + ObReferenceObject(IsaDevice->Common.Self); + + CurrentEntry = CurrentEntry->Flink; + } + + DeviceRelations->Count = FdoExt->DeviceCount; + + KeReleaseSpinLock(&FdoExt->Lock, OldIrql); + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaFdoPnp( + IN PISAPNP_FDO_EXTENSION FdoExt, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + NTSTATUS Status = Irp->IoStatus.Status; + + switch (IrpSp->MinorFunction) + { + case IRP_MN_START_DEVICE: + Status = IsaForwardIrpSynchronous(FdoExt, Irp); + + if (NT_SUCCESS(Status)) + Status = IsaFdoStartDevice(FdoExt, Irp, IrpSp); + + Irp->IoStatus.Status = Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + + case IRP_MN_STOP_DEVICE: + FdoExt->Common.State = dsStopped; + + Status = STATUS_SUCCESS; + break; + + case IRP_MN_QUERY_DEVICE_RELATIONS: + Status = IsaFdoQueryDeviceRelations(FdoExt, Irp, IrpSp); + + Irp->IoStatus.Status = Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + + case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: + DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); + break; + + default: + DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction); + break; + } + + IoSkipCurrentIrpStackLocation(Irp); + + return IoCallDriver(FdoExt->Ldo, Irp); +} diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c new file mode 100644 index 00000000000..99e5d44aa33 --- /dev/null +++ b/drivers/bus/isapnp/hardware.c @@ -0,0 +1,579 @@ +/* + * PROJECT: ReactOS ISA PnP Bus driver + * FILE: hardware.c + * PURPOSE: Hardware support code + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ +#include +#include + +#define NDEBUG +#include + +static +inline +VOID +WriteAddress(USHORT Address) +{ + WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS, Address); +} + +static +inline +VOID +WriteData(USHORT Data) +{ + WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_DATA, Data); +} + +static +inline +UCHAR +ReadData(PUCHAR ReadDataPort) +{ + return READ_PORT_UCHAR(ReadDataPort); +} + +static +inline +VOID +WriteByte(USHORT Address, USHORT Value) +{ + WriteAddress(Address); + WriteData(Value); +} + +static +inline +UCHAR +ReadByte(PUCHAR ReadDataPort, USHORT Address) +{ + WriteAddress(Address); + return ReadData(ReadDataPort); +} + +static +inline +USHORT +ReadWord(PUCHAR ReadDataPort, USHORT Address) +{ + return ((ReadByte(ReadDataPort, Address) << 8) | + (ReadByte(ReadDataPort, Address + 1))); +} + +static +inline +VOID +SetReadDataPort(PUCHAR ReadDataPort) +{ + WriteByte(ISAPNP_READPORT, ((ULONG_PTR)ReadDataPort >> 2)); +} + +static +inline +VOID +EnterIsolationState(VOID) +{ + WriteAddress(ISAPNP_SERIALISOLATION); +} + +static +inline +VOID +WaitForKey(VOID) +{ + WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY); +} + +static +inline +VOID +ResetCsn(VOID) +{ + WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN); +} + +static +inline +VOID +Wake(USHORT Csn) +{ + WriteByte(ISAPNP_WAKE, Csn); +} + +static +inline +USHORT +ReadResourceData(PUCHAR ReadDataPort) +{ + return ReadByte(ReadDataPort, ISAPNP_RESOURCEDATA); +} + +static +inline +USHORT +ReadStatus(PUCHAR ReadDataPort) +{ + return ReadByte(ReadDataPort, ISAPNP_STATUS); +} + +static +inline +VOID +WriteCsn(USHORT Csn) +{ + WriteByte(ISAPNP_CARDSELECTNUMBER, Csn); +} + +static +inline +VOID +WriteLogicalDeviceNumber(USHORT LogDev) +{ + WriteByte(ISAPNP_LOGICALDEVICENUMBER, LogDev); +} + +static +inline +VOID +ActivateDevice(USHORT LogDev) +{ + WriteLogicalDeviceNumber(LogDev); + WriteByte(ISAPNP_ACTIVATE, 1); +} + +static +inline +VOID +DeactivateDevice(USHORT LogDev) +{ + WriteLogicalDeviceNumber(LogDev); + WriteByte(ISAPNP_ACTIVATE, 0); +} + +static +inline +USHORT +ReadIoBase(PUCHAR ReadDataPort, USHORT Index) +{ + return ReadWord(ReadDataPort, ISAPNP_IOBASE(Index)); +} + +static +inline +USHORT +ReadIrqNo(PUCHAR ReadDataPort, USHORT Index) +{ + return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index)); +} + +static +inline +VOID +HwDelay(VOID) +{ + KeStallExecutionProcessor(1000); +} + +static +inline +USHORT +NextLFSR(USHORT Lfsr, USHORT InputBit) +{ + ULONG NextLfsr = Lfsr >> 1; + + NextLfsr |= (((Lfsr ^ NextLfsr) ^ InputBit)) << 7; + + return NextLfsr; +} + +static +VOID +SendKey(VOID) +{ + USHORT i, Lfsr; + + HwDelay(); + WriteAddress(0x00); + WriteAddress(0x00); + + Lfsr = ISAPNP_LFSR_SEED; + for (i = 0; i < 32; i++) + { + WriteAddress(Lfsr); + Lfsr = NextLFSR(Lfsr, 0); + } +} + +static +USHORT +PeekByte(PUCHAR ReadDataPort) +{ + USHORT i; + + for (i = 0; i < 20; i++) + { + if (ReadStatus(ReadDataPort) & 0x01) + return ReadResourceData(ReadDataPort); + + HwDelay(); + } + + return 0xFF; +} + +static +VOID +Peek(PUCHAR ReadDataPort, PVOID Buffer, ULONG Length) +{ + USHORT i, byte; + + for (i = 0; i < Length; i++) + { + byte = PeekByte(ReadDataPort); + if (Buffer) + *((PUCHAR)Buffer + i) = byte; + } +} + +static +USHORT +IsaPnpChecksum(PISAPNP_IDENTIFIER Identifier) +{ + USHORT i,j, Lfsr, Byte; + + Lfsr = ISAPNP_LFSR_SEED; + for (i = 0; i < 8; i++) + { + Byte = *(((PUCHAR)Identifier) + i); + for (j = 0; j < 8; j++) + { + Lfsr = NextLFSR(Lfsr, Byte); + Byte >>= 1; + } + } + + return Lfsr; +} + +static +BOOLEAN +FindTag(PUCHAR ReadDataPort, USHORT WantedTag, PVOID Buffer, ULONG Length) +{ + USHORT Tag, TagLen; + + do + { + Tag = PeekByte(ReadDataPort); + if (ISAPNP_IS_SMALL_TAG(Tag)) + { + TagLen = ISAPNP_SMALL_TAG_LEN(Tag); + Tag = ISAPNP_SMALL_TAG_NAME(Tag); + } + else + { + TagLen = PeekByte(ReadDataPort) + (PeekByte(ReadDataPort) << 8); + Tag = ISAPNP_LARGE_TAG_NAME(Tag); + } + + if (Tag == WantedTag) + { + if (Length > TagLen) + Length = TagLen; + + Peek(ReadDataPort, Buffer, Length); + + return TRUE; + } + else + { + Peek(ReadDataPort, NULL, Length); + } + } while (Tag != ISAPNP_TAG_END); + + return FALSE; +} + +static +BOOLEAN +FindLogDevId(PUCHAR ReadDataPort, USHORT LogDev, PISAPNP_LOGDEVID LogDeviceId) +{ + USHORT i; + + for (i = 0; i <= LogDev; i++) + { + if (!FindTag(ReadDataPort, ISAPNP_TAG_LOGDEVID, LogDeviceId, sizeof(*LogDeviceId))) + return FALSE; + } + + return TRUE; +} + +static +INT +TryIsolate(PUCHAR ReadDataPort) +{ + ISAPNP_IDENTIFIER Identifier; + USHORT i, j; + BOOLEAN Seen55aa, SeenLife; + INT Csn = 0; + USHORT Byte, Data; + + DPRINT("Setting read data port: 0x%x\n", ReadDataPort); + + WaitForKey(); + SendKey(); + + ResetCsn(); + HwDelay(); + HwDelay(); + + WaitForKey(); + SendKey(); + Wake(0x00); + + SetReadDataPort(ReadDataPort); + HwDelay(); + + while (TRUE) + { + EnterIsolationState(); + HwDelay(); + + RtlZeroMemory(&Identifier, sizeof(Identifier)); + + Seen55aa = SeenLife = FALSE; + for (i = 0; i < 9; i++) + { + Byte = 0; + for (j = 0; j < 8; j++) + { + Data = ReadData(ReadDataPort); + HwDelay(); + Data = ((Data << 8) | ReadData(ReadDataPort)); + HwDelay(); + Byte >>= 1; + + if (Data != 0xFFFF) + { + SeenLife = TRUE; + if (Data == 0x55AA) + { + Byte |= 0x80; + Seen55aa = TRUE; + } + } + } + *(((PUCHAR)&Identifier) + i) = Byte; + } + + if (!Seen55aa) + { + if (Csn) + { + DPRINT("Found no more cards\n"); + } + else + { + if (SeenLife) + { + DPRINT("Saw life but no cards, trying new read port\n"); + Csn = -1; + } + else + { + DPRINT("Saw no sign of life, abandoning isolation\n"); + } + } + break; + } + + if (Identifier.Checksum != IsaPnpChecksum(&Identifier)) + { + DPRINT("Bad checksum, trying next read data port\n"); + Csn = -1; + break; + } + + Csn++; + + WriteCsn(Csn); + HwDelay(); + + Wake(0x00); + HwDelay(); + } + + WaitForKey(); + + if (Csn > 0) + { + DPRINT("Found %d cards at read port 0x%x\n", Csn, ReadDataPort); + } + + return Csn; +} + +static +PUCHAR +Isolate(VOID) +{ + PUCHAR ReadPort; + + for (ReadPort = (PUCHAR)ISAPNP_READ_PORT_START; + (ULONG_PTR)ReadPort <= ISAPNP_READ_PORT_MAX; + ReadPort += ISAPNP_READ_PORT_STEP) + { + /* Avoid the NE2000 probe space */ + if ((ULONG_PTR)ReadPort >= 0x280 && + (ULONG_PTR)ReadPort <= 0x380) + continue; + + if (TryIsolate(ReadPort) > 0) + return ReadPort; + } + + return 0; +} + +VOID +DeviceActivation(PISAPNP_LOGICAL_DEVICE IsaDevice, + BOOLEAN Activate) +{ + WaitForKey(); + SendKey(); + Wake(IsaDevice->CSN); + + if (Activate) + ActivateDevice(IsaDevice->LDN); + else + DeactivateDevice(IsaDevice->LDN); + + HwDelay(); + + WaitForKey(); +} + +NTSTATUS +ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt) +{ + PISAPNP_LOGICAL_DEVICE LogDevice; + ISAPNP_IDENTIFIER Identifier; + ISAPNP_LOGDEVID LogDevId; + USHORT Csn; + USHORT LogDev; + PDEVICE_OBJECT Pdo; + NTSTATUS Status; + + ASSERT(FdoExt->ReadDataPort); + + for (Csn = 1; Csn <= 0xFF; Csn++) + { + for (LogDev = 0; LogDev <= 0xFF; LogDev++) + { + Status = IoCreateDevice(FdoExt->Common.Self->DriverObject, + sizeof(ISAPNP_LOGICAL_DEVICE), + NULL, + FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &Pdo); + if (!NT_SUCCESS(Status)) + return Status; + + Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; + + LogDevice = Pdo->DeviceExtension; + + RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE)); + + LogDevice->Common.Self = Pdo; + LogDevice->Common.IsFdo = FALSE; + LogDevice->Common.State = dsStopped; + + LogDevice->CSN = Csn; + LogDevice->LDN = LogDev; + + WaitForKey(); + SendKey(); + Wake(Csn); + + Peek(FdoExt->ReadDataPort, &Identifier, sizeof(Identifier)); + + if (Identifier.VendorId & 0x80) + { + IoDeleteDevice(LogDevice->Common.Self); + return STATUS_SUCCESS; + } + + if (!FindLogDevId(FdoExt->ReadDataPort, LogDev, &LogDevId)) + break; + + WriteLogicalDeviceNumber(LogDev); + + LogDevice->VendorId = LogDevId.VendorId; + LogDevice->ProdId = LogDevId.ProdId; + LogDevice->IoAddr = ReadIoBase(FdoExt->ReadDataPort, 0); + LogDevice->IrqNo = ReadIrqNo(FdoExt->ReadDataPort, 0); + + DPRINT1("Detected ISA PnP device - VID: 0x%x PID: 0x%x IoBase: 0x%x IRQ:0x%x\n", + LogDevice->VendorId, LogDevice->ProdId, LogDevice->IoAddr, LogDevice->IrqNo); + + WaitForKey(); + + Pdo->Flags &= ~DO_DEVICE_INITIALIZING; + + InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry); + FdoExt->DeviceCount++; + } + } + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaHwDetectReadDataPort( + IN PISAPNP_FDO_EXTENSION FdoExt) +{ + FdoExt->ReadDataPort = Isolate(); + if (!FdoExt->ReadDataPort) + { + DPRINT1("No read data port found\n"); + return STATUS_UNSUCCESSFUL; + } + + DPRINT1("Detected read data port at 0x%x\n", FdoExt->ReadDataPort); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaHwActivateDevice( + IN PISAPNP_LOGICAL_DEVICE LogicalDevice) +{ + DeviceActivation(LogicalDevice, + TRUE); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaHwDeactivateDevice( + IN PISAPNP_LOGICAL_DEVICE LogicalDevice) +{ + DeviceActivation(LogicalDevice, + FALSE); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaHwFillDeviceList( + IN PISAPNP_FDO_EXTENSION FdoExt) +{ + return ProbeIsaPnpBus(FdoExt); +} diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 37262c3aa87..594b5a90541 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -1,1729 +1,183 @@ -/* $Id$ - * +/* * PROJECT: ReactOS ISA PnP Bus driver * FILE: isapnp.c * PURPOSE: Driver entry - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) - * NOTE: Parts adapted from linux ISA PnP driver - * UPDATE HISTORY: - * 01-05-2001 CSH Created + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) */ #include -#ifndef NDEBUG #define NDEBUG -#endif #include - -#ifdef ALLOC_PRAGMA - -// Make the initialization routines discardable, so that they -// don't waste space - -#pragma alloc_text(init, DriverEntry) - - -#endif /* ALLOC_PRAGMA */ - - -PUCHAR IsaPnPReadPort; - - -#define UCHAR2USHORT(v0, v1) \ - ((v1 << 8) | v0) - -#define UCHAR2ULONG(v0, v1, v2, v3) \ - ((UCHAR2USHORT(v2, v3) << 16) | UCHAR2USHORT(v0, v1)) - - -#ifndef NDEBUG - -struct -{ - PCH Name; -} SmallTags[] = { - {"Unknown Small Tag"}, - {"ISAPNP_SRIN_VERSION"}, - {"ISAPNP_SRIN_LDEVICE_ID"}, - {"ISAPNP_SRIN_CDEVICE_ID"}, - {"ISAPNP_SRIN_IRQ_FORMAT"}, - {"ISAPNP_SRIN_DMA_FORMAT"}, - {"ISAPNP_SRIN_START_DFUNCTION"}, - {"ISAPNP_SRIN_END_DFUNCTION"}, - {"ISAPNP_SRIN_IO_DESCRIPTOR"}, - {"ISAPNP_SRIN_FL_IO_DESCRIPOTOR"}, - {"Reserved Small Tag"}, - {"Reserved Small Tag"}, - {"Reserved Small Tag"}, - {"Reserved Small Tag"}, - {"ISAPNP_SRIN_VENDOR_DEFINED"}, - {"ISAPNP_SRIN_END_TAG"} -}; - -struct -{ - PCH Name; -} LargeTags[] = { - {"Unknown Large Tag"}, - {"ISAPNP_LRIN_MEMORY_RANGE"}, - {"ISAPNP_LRIN_ID_STRING_ANSI"}, - {"ISAPNP_LRIN_ID_STRING_UNICODE"}, - {"ISAPNP_LRIN_VENDOR_DEFINED"}, - {"ISAPNP_LRIN_MEMORY_RANGE32"}, - {"ISAPNP_LRIN_FL_MEMORY_RANGE32"} -}; - -PCSZ TagName(ULONG Tag, BOOLEAN Small) -{ - if (Small && (Tag <= ISAPNP_SRIN_END_TAG)) { - return SmallTags[Tag].Name; - } else if (Tag <= ISAPNP_LRIN_FL_MEMORY_RANGE32){ - return LargeTags[Tag].Name; - } - - return NULL; -} - -#endif - -static __inline VOID WriteData(UCHAR Value) -{ - WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_PORT, Value); -} - -static __inline VOID WriteAddress(UCHAR Value) -{ - WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS_PORT, Value); - KeStallExecutionProcessor(20); -} - -static __inline UCHAR ReadData(VOID) -{ - return READ_PORT_UCHAR(IsaPnPReadPort); -} - -static UCHAR ReadUchar(UCHAR Index) -{ - WriteAddress(Index); - return ReadData(); -} - -#if 0 -static USHORT ReadUshort(UCHAR Index) -{ - USHORT Value; - - Value = ReadUchar(Index); - Value = (Value << 8) + ReadUchar(Index + 1); - return Value; -} - -static ULONG ReadUlong(UCHAR Index) -{ - ULONG Value; - - Value = ReadUchar(Index); - Value = (Value << 8) + ReadUchar(Index + 1); - Value = (Value << 8) + ReadUchar(Index + 2); - Value = (Value << 8) + ReadUchar(Index + 3); - return Value; -} -#endif - -static VOID WriteUchar(UCHAR Index, UCHAR Value) -{ - WriteAddress(Index); - WriteData(Value); -} - -#if 0 -static VOID WriteUshort(UCHAR Index, USHORT Value) -{ - WriteUchar(Index, Value >> 8); - WriteUchar(Index + 1, Value); -} - -static VOID WriteUlong(UCHAR Index, ULONG Value) -{ - WriteUchar(Index, Value >> 24); - WriteUchar(Index + 1, Value >> 16); - WriteUchar(Index + 2, Value >> 8); - WriteUchar(Index + 3, Value); -} -#endif - -static __inline VOID SetReadDataPort(ULONG_PTR Port) -{ - IsaPnPReadPort = (PUCHAR)Port; - WriteUchar(0x00, (UCHAR) (Port >> 2)); - KeStallExecutionProcessor(100); -} - -static VOID SendKey(VOID) -{ - ULONG i; - UCHAR msb; - UCHAR code; - - /* FIXME: Is there something better? */ - KeStallExecutionProcessor(1000); - WriteAddress(0x00); - WriteAddress(0x00); - - code = 0x6a; - WriteAddress(code); - for (i = 1; i < 32; i++) { - msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7; - code = (code >> 1) | msb; - WriteAddress(code); - } -} - -/* Place all PnP cards in wait-for-key state */ -static VOID SendWait(VOID) -{ - WriteUchar(0x02, 0x02); -} - -static VOID SendWake(UCHAR csn) -{ - WriteUchar(ISAPNP_CARD_WAKECSN, csn); -} - -#if 0 -static VOID SelectLogicalDevice(UCHAR LogicalDevice) -{ - WriteUchar(ISAPNP_CARD_LOG_DEVICE_NUM, LogicalDevice); -} - -static VOID ActivateLogicalDevice(UCHAR LogicalDevice) -{ - SelectLogicalDevice(LogicalDevice); - WriteUchar(ISAPNP_CONTROL_ACTIVATE, 0x1); - KeStallExecutionProcessor(250); -} - -static VOID DeactivateLogicalDevice(UCHAR LogicalDevice) -{ - SelectLogicalDevice(LogicalDevice); - WriteUchar(ISAPNP_CONTROL_ACTIVATE, 0x0); - KeStallExecutionProcessor(500); -} -#endif - -#define READ_DATA_PORT_STEP 32 /* Minimum is 4 */ - -static ULONG_PTR FindNextReadPort(VOID) -{ - ULONG_PTR Port; - - - - Port = (ULONG_PTR)IsaPnPReadPort; - - while (TRUE) { - - Port += READ_DATA_PORT_STEP; - - - - if (Port > ISAPNP_MAX_READ_PORT) - - { - - return 0; - - } - - - - /* - - * We cannot use NE2000 probe spaces for - - * ISAPnP or we will lock up machines - - */ - - if ((Port < 0x280) || (Port > 0x380)) - - { - - return Port; - - } - - } - -} - -static BOOLEAN IsolateReadDataPortSelect(VOID) -{ - ULONG_PTR Port; - - SendWait(); - SendKey(); - - /* Control: reset CSN and conditionally everything else too */ - WriteUchar(0x02, 0x05); - KeStallExecutionProcessor(2000); - - SendWait(); - SendKey(); - SendWake(0x00); - - Port = FindNextReadPort(); - if (Port == 0) { - SendWait(); - return FALSE; - } - - SetReadDataPort(Port); - KeStallExecutionProcessor(1000); - WriteAddress(0x01); - KeStallExecutionProcessor(1000); - return TRUE; -} - -/* - * Isolate (assign uniqued CSN) to all ISA PnP devices - */ -static ULONG IsolatePnPCards(VOID) -{ - UCHAR checksum = 0x6a; - UCHAR chksum = 0x00; - UCHAR bit = 0x00; - ULONG data; - ULONG csn = 0; - ULONG i; - ULONG iteration = 1; - - DPRINT("Called\n"); - - IsaPnPReadPort = (PUCHAR)(ISAPNP_MIN_READ_PORT - READ_DATA_PORT_STEP); - if (!IsolateReadDataPortSelect()) { - DPRINT("Could not set read data port\n"); - return 0; - } - - while (TRUE) { - for (i = 1; i <= 64; i++) { - data = ReadData() << 8; - KeStallExecutionProcessor(250); - data = data | ReadData(); - KeStallExecutionProcessor(250); - if (data == 0x55aa) - bit = 0x01; - checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1); - bit = 0x00; - } - for (i = 65; i <= 72; i++) { - data = ReadData() << 8; - KeStallExecutionProcessor(250); - data = data | ReadData(); - KeStallExecutionProcessor(250); - if (data == 0x55aa) - chksum |= (1 << (i - 65)); - } - if ((checksum != 0x00) && (checksum == chksum)) { - csn++; - - WriteUchar(0x06, (UCHAR) csn); - KeStallExecutionProcessor(250); - iteration++; - SendWake(0x00); - SetReadDataPort((ULONG_PTR)IsaPnPReadPort); - KeStallExecutionProcessor(1000); - WriteAddress(0x01); - KeStallExecutionProcessor(1000); - goto next; - } - if (iteration == 1) { - if (!IsolateReadDataPortSelect()) { - DPRINT("Could not set read data port\n"); - return 0; - } - } else if (iteration > 1) { - break; - } -next: - checksum = 0x6a; - chksum = 0x00; - bit = 0x00; - } - SendWait(); - return csn; -} - - -static VOID Peek(PUCHAR Data, ULONG Count) -{ - ULONG i, j; - UCHAR d = 0; - - for (i = 1; i <= Count; i++) { - for (j = 0; j < 20; j++) { - d = ReadUchar(0x05); - if (d & 0x1) - break; - KeStallExecutionProcessor(100); - } - if (!(d & 0x1)) { - if (Data != NULL) - *Data++ = 0xff; - continue; - } - d = ReadUchar(0x04); /* PRESDI */ - if (Data != NULL) - *Data++ = d; - } -} - - -/* - * Skip specified number of bytes from stream - */ -static VOID Skip(ULONG Count) -{ - Peek(NULL, Count); -} - - -/* - * Read one tag from stream - */ -static BOOLEAN ReadTag(PUCHAR Type, - PUSHORT Size, - PBOOLEAN Small) -{ - UCHAR tag, tmp[2]; - - Peek(&tag, 1); - if (tag == 0) { - /* Invalid tag */ - DPRINT("Invalid tag with value 0\n"); -#ifndef NDEBUG - for (;;); -#endif - return FALSE; - } - - if (tag & ISAPNP_RESOURCE_ITEM_TYPE) { - /* Large resource item */ - *Type = (tag & 0x7f); - Peek(tmp, 2); - *Size = UCHAR2USHORT(tmp[0], tmp[1]); - *Small = FALSE; -#ifndef NDEBUG - if (*Type > ISAPNP_LRIN_FL_MEMORY_RANGE32) { - DPRINT("Invalid large tag with value 0x%X\n", *Type); - for (;;); - } -#endif - } else { - /* Small resource item */ - *Type = (tag >> 3) & 0x0f; - *Size = tag & 0x07; - *Small = TRUE; -#ifndef NDEBUG - if (*Type > ISAPNP_SRIN_END_TAG) { - DPRINT("Invalid small tag with value 0x%X\n", *Type); - for (;;); - } -#endif - } -#if 0 - DPRINT("Tag = 0x%X, Type = 0x%X, Size = %d (%s)\n", - tag, *Type, *Size, TagName(*Type, *Small)); -#endif - /* Probably invalid data */ - if ((*Type == 0xff) && (*Size == 0xffff)) { - DPRINT("Invalid data (Type 0x%X Size 0x%X)\n", *Type, *Size); - for (;;); - return FALSE; - } - - return TRUE; -} - - -/* - * Parse ANSI name for ISA PnP logical device - */ -static NTSTATUS ParseAnsiName(PUNICODE_STRING Name, PUSHORT Size) -{ - ANSI_STRING AnsiString; - UCHAR Buffer[256]; - USHORT size1; - - size1 = (*Size >= sizeof(Buffer)) ? (sizeof(Buffer) - 1) : *Size; - - Peek(Buffer, size1); - Buffer[size1] = '\0'; - *Size -= size1; - - /* Clean whitespace from end of string */ - while ((size1 > 0) && (Buffer[--size1] == ' ')) - Buffer[size1] = '\0'; - - DPRINT("ANSI name: %s\n", Buffer); - - RtlInitAnsiString(&AnsiString, (PCSZ)&Buffer); - return RtlAnsiStringToUnicodeString(Name, &AnsiString, TRUE); -} - - -/* - * Add a resource list to the - * resource lists of a logical device - */ -static NTSTATUS AddResourceList( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Priority, - PISAPNP_CONFIGURATION_LIST *NewList) -{ - PISAPNP_CONFIGURATION_LIST List; - - DPRINT("Adding resource list for logical device %d on card %d (Priority %d)\n", - LogicalDevice->Number, - LogicalDevice->Card->CardId, - Priority); - - List = (PISAPNP_CONFIGURATION_LIST) - ExAllocatePoolWithTag(PagedPool, sizeof(ISAPNP_CONFIGURATION_LIST), TAG_ISAPNP); - if (!List) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlZeroMemory(List, sizeof(ISAPNP_CONFIGURATION_LIST)); - - List->Priority = Priority; - - InitializeListHead(&List->ListHead); - - InsertTailList(&LogicalDevice->Configuration, &List->ListEntry); - - *NewList = List; - - return STATUS_SUCCESS; -} - - -/* - * Add a resource entry to the - * resource list of a logical device - */ -static NTSTATUS AddResourceDescriptor( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Priority, - ULONG Option, - PISAPNP_DESCRIPTOR *Descriptor) -{ - PLIST_ENTRY CurrentEntry; - PISAPNP_CONFIGURATION_LIST List; - PISAPNP_DESCRIPTOR d; - NTSTATUS Status; - - DPRINT("Adding resource descriptor for logical device %d on card %d (%d of %d)\n", - LogicalDevice->Number, - LogicalDevice->Card->CardId, - LogicalDevice->CurrentDescriptorCount, - LogicalDevice->DescriptorCount); - - d = (PISAPNP_DESCRIPTOR) - ExAllocatePoolWithTag(PagedPool, sizeof(ISAPNP_DESCRIPTOR), TAG_ISAPNP); - if (!d) - return STATUS_NO_MEMORY; - - RtlZeroMemory(d, sizeof(ISAPNP_DESCRIPTOR)); - - d->Descriptor.Option = (UCHAR) Option; - - *Descriptor = d; - - CurrentEntry = LogicalDevice->Configuration.Flink; - while (CurrentEntry != &LogicalDevice->Configuration) { - List = CONTAINING_RECORD( - CurrentEntry, ISAPNP_CONFIGURATION_LIST, ListEntry); - - if (List->Priority == Priority) { - - LogicalDevice->ConfigurationSize += sizeof(IO_RESOURCE_DESCRIPTOR); - InsertTailList(&List->ListHead, &d->ListEntry); - LogicalDevice->CurrentDescriptorCount++; - if (LogicalDevice->DescriptorCount < - LogicalDevice->CurrentDescriptorCount) { - LogicalDevice->DescriptorCount = - LogicalDevice->CurrentDescriptorCount; - } - - return STATUS_SUCCESS; - } - CurrentEntry = CurrentEntry->Flink; - } - - Status = AddResourceList(LogicalDevice, Priority, &List); - if (NT_SUCCESS(Status)) { - LogicalDevice->ConfigurationSize += sizeof(IO_RESOURCE_LIST); - LogicalDevice->CurrentDescriptorCount = 0; - InsertTailList(&List->ListHead, &d->ListEntry); - } - - return Status; -} - - -/* - * Add IRQ resource to resources list - */ -static NTSTATUS AddIrqResource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[3]; - ULONG irq, i, last = 0; - BOOLEAN found; - NTSTATUS Status; - - Peek(tmp, Size); - - irq = UCHAR2USHORT(tmp[0], tmp[0]); - - DPRINT("IRQ bitmask: 0x%X\n", irq); - - found = FALSE; - for (i = 0; i < 16; i++) { - if (!found && (irq & (1 << i))) { - last = i; - found = TRUE; - } - - if ((found && !(irq & (1 << i))) || (irq & (1 << i) && (i == 15))) { - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypeInterrupt; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Interrupt.MinimumVector = last; - - if ((irq & (1 << i)) && (i == 15)) - Descriptor->Descriptor.u.Interrupt.MaximumVector = i; - else - Descriptor->Descriptor.u.Interrupt.MaximumVector = i - 1; - - DPRINT("Found IRQ range %d - %d for logical device %d on card %d\n", - Descriptor->Descriptor.u.Interrupt.MinimumVector, - Descriptor->Descriptor.u.Interrupt.MaximumVector, - LogicalDevice->Number, - LogicalDevice->Card->CardId); - - found = FALSE; - } - } - - return STATUS_SUCCESS; -} - -/* - * Add DMA resource to resources list - */ -static NTSTATUS AddDmaResource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[2]; - ULONG dma, flags, i, last = 0; - BOOLEAN found; - NTSTATUS Status; - - Peek(tmp, Size); - - dma = tmp[0]; - flags = tmp[1]; - - DPRINT("DMA bitmask: 0x%X\n", dma); - - found = FALSE; - for (i = 0; i < 8; i++) { - if (!found && (dma & (1 << i))) { - last = i; - found = TRUE; - } - - if ((found && !(dma & (1 << i))) || (dma & (1 << i) && (i == 15))) { - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypeDma; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Dma.MinimumChannel = last; - - if ((dma & (1 << i)) && (i == 15)) - Descriptor->Descriptor.u.Dma.MaximumChannel = i; - else - Descriptor->Descriptor.u.Dma.MaximumChannel = i - 1; - - /* FIXME: Parse flags */ - - DPRINT("Found DMA range %d - %d for logical device %d on card %d\n", - Descriptor->Descriptor.u.Dma.MinimumChannel, - Descriptor->Descriptor.u.Dma.MaximumChannel, - LogicalDevice->Number, - LogicalDevice->Card->CardId); - - found = FALSE; - } - } - - return STATUS_SUCCESS; -} - -/* - * Add port resource to resources list - */ -static NTSTATUS AddIOPortResource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ -#if 0 - DPRINT("I/O port: size 0x%X\n", Size); - Skip(Size); -#else - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[7]; - NTSTATUS Status; - - Peek(tmp, Size); - - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypePort; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Port.Length = tmp[6]; - /* FIXME: Parse flags */ - Descriptor->Descriptor.u.Port.Alignment = 0; - Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]); - Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[4], tmp[4]); - - DPRINT("Found I/O port range 0x%X - 0x%X for logical device %d on card %d\n", - Descriptor->Descriptor.u.Port.MinimumAddress, - Descriptor->Descriptor.u.Port.MaximumAddress, - LogicalDevice->Number, - LogicalDevice->Card->CardId); -#endif - return STATUS_SUCCESS; -} - -/* - * Add fixed port resource to resources list - */ -static NTSTATUS AddFixedIOPortResource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ -#if 0 - DPRINT("Fixed I/O port: size 0x%X\n", Size); - Skip(Size); -#else - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[3]; - NTSTATUS Status; - - Peek(tmp, Size); - - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypePort; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Port.Length = tmp[2]; - Descriptor->Descriptor.u.Port.Alignment = 0; - Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]); - Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]); - - DPRINT("Found fixed I/O port range 0x%X - 0x%X for logical device %d on card %d\n", - Descriptor->Descriptor.u.Port.MinimumAddress, - Descriptor->Descriptor.u.Port.MaximumAddress, - LogicalDevice->Number, - LogicalDevice->Card->CardId); -#endif - return STATUS_SUCCESS; -} - -/* - * Add memory resource to resources list - */ -static NTSTATUS AddMemoryResource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ -#if 0 - DPRINT("Memory range: size 0x%X\n", Size); - Skip(Size); -#else - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[9]; - NTSTATUS Status; - - Peek(tmp, Size); - - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypeMemory; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Memory.Length = UCHAR2USHORT(tmp[7], tmp[8]) << 8; - Descriptor->Descriptor.u.Memory.Alignment = UCHAR2USHORT(tmp[5], tmp[6]); - Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]) << 8; - Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[3], tmp[4]) << 8; - - DPRINT("Found memory range 0x%X - 0x%X for logical device %d on card %d\n", - Descriptor->Descriptor.u.Memory.MinimumAddress, - Descriptor->Descriptor.u.Memory.MaximumAddress, - LogicalDevice->Number, - LogicalDevice->Card->CardId); -#endif - return STATUS_SUCCESS; -} - -/* - * Add 32-bit memory resource to resources list - */ -static NTSTATUS AddMemory32Resource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ -#if 0 - DPRINT("Memory32 range: size 0x%X\n", Size); - Skip(Size); -#else - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[17]; - NTSTATUS Status; - - Peek(tmp, Size); - - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypeMemory; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Memory.Length = - UCHAR2ULONG(tmp[13], tmp[14], tmp[15], tmp[16]); - Descriptor->Descriptor.u.Memory.Alignment = - UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]); - Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart = - UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]); - Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart = - UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]); - - DPRINT("Found memory32 range 0x%X - 0x%X for logical device %d on card %d\n", - Descriptor->Descriptor.u.Memory.MinimumAddress, - Descriptor->Descriptor.u.Memory.MaximumAddress, - LogicalDevice->Number, - LogicalDevice->Card->CardId); -#endif - return STATUS_SUCCESS; -} - -/* - * Add 32-bit fixed memory resource to resources list - */ -static NTSTATUS AddFixedMemory32Resource( - PISAPNP_LOGICAL_DEVICE LogicalDevice, - ULONG Size, - ULONG Priority, - ULONG Option) -{ -#if 0 - DPRINT("Memory32 range: size 0x%X\n", Size); - Skip(Size); -#else - PISAPNP_DESCRIPTOR Descriptor; - UCHAR tmp[17]; - NTSTATUS Status; - - Peek(tmp, Size); - - Status = AddResourceDescriptor(LogicalDevice, - Priority, Option, &Descriptor); - if (!NT_SUCCESS(Status)) - return Status; - Descriptor->Descriptor.Type = CmResourceTypeMemory; - Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive; - Descriptor->Descriptor.u.Memory.Length = - UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]); - Descriptor->Descriptor.u.Memory.Alignment = - UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]); - Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart = - UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]); - Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart = - UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]); - - DPRINT("Found fixed memory32 range 0x%X - 0x%X for logical device %d on card %d\n", - Descriptor->Descriptor.u.Memory.MinimumAddress, - Descriptor->Descriptor.u.Memory.MaximumAddress, - LogicalDevice->Number, - LogicalDevice->Card->CardId); -#endif - return STATUS_SUCCESS; -} - - -/* - * Parse logical device tag - */ -static PISAPNP_LOGICAL_DEVICE ParseLogicalDevice( - PISAPNP_DEVICE_EXTENSION DeviceExtension, - PISAPNP_CARD Card, - ULONG Size, - USHORT Number) -{ - UCHAR tmp[6]; - PISAPNP_LOGICAL_DEVICE LogicalDevice; - - DPRINT("Card %d Number %d\n", Card->CardId, Number); - - Peek(tmp, Size); - - LogicalDevice = (PISAPNP_LOGICAL_DEVICE)ExAllocatePoolWithTag( - PagedPool, sizeof(ISAPNP_LOGICAL_DEVICE), TAG_ISAPNP); - if (!LogicalDevice) - return NULL; - - RtlZeroMemory(LogicalDevice, sizeof(ISAPNP_LOGICAL_DEVICE)); - - LogicalDevice->Number = Number; - LogicalDevice->VendorId = UCHAR2USHORT(tmp[0], tmp[1]); - LogicalDevice->DeviceId = UCHAR2USHORT(tmp[2], tmp[3]); - LogicalDevice->Regs = tmp[4]; - LogicalDevice->Card = Card; - if (Size > 5) - LogicalDevice->Regs |= tmp[5] << 8; - - InitializeListHead(&LogicalDevice->Configuration); - - ExInterlockedInsertTailList(&Card->LogicalDevices, - &LogicalDevice->CardListEntry, - &Card->LogicalDevicesLock); - - ExInterlockedInsertTailList(&DeviceExtension->DeviceListHead, - &LogicalDevice->DeviceListEntry, - &DeviceExtension->GlobalListLock); - - DeviceExtension->DeviceListCount++; - - return LogicalDevice; -} - - -/* - * Parse resource map for logical device - */ -static BOOLEAN CreateLogicalDevice(PISAPNP_DEVICE_EXTENSION DeviceExtension, - PISAPNP_CARD Card, USHORT Size) -{ - ULONG number = 0, skip = 0, compat = 0; - UCHAR type, tmp[17]; - PISAPNP_LOGICAL_DEVICE LogicalDevice; - BOOLEAN Small; - ULONG Priority = 0; - ULONG Option = IO_RESOURCE_REQUIRED; - - DPRINT("Card %d Size %d\n", Card->CardId, Size); - - LogicalDevice = ParseLogicalDevice(DeviceExtension, Card, Size, (USHORT) number++); - if (!LogicalDevice) - return FALSE; - - while (TRUE) { - if (!ReadTag(&type, &Size, &Small)) - return FALSE; - - if (skip && !(Small && ((type == ISAPNP_SRIN_LDEVICE_ID) - || (type == ISAPNP_SRIN_END_TAG)))) - goto skip; - - if (Small) { - switch (type) { - case ISAPNP_SRIN_LDEVICE_ID: - if ((Size >= 5) && (Size <= 6)) { - LogicalDevice = ParseLogicalDevice( - DeviceExtension, Card, Size, (USHORT)number++); - if (!LogicalDevice) - return FALSE; - Size = 0; - skip = 0; - } else { - skip = 1; - } - Priority = 0; - Option = IO_RESOURCE_REQUIRED; - compat = 0; - break; - - case ISAPNP_SRIN_CDEVICE_ID: - if ((Size == 4) && (compat < MAX_COMPATIBLE_ID)) { - Peek(tmp, 4); - LogicalDevice->CVendorId[compat] = UCHAR2USHORT(tmp[0], tmp[1]); - LogicalDevice->CDeviceId[compat] = UCHAR2USHORT(tmp[2], tmp[3]); - compat++; - Size = 0; - } - break; - - case ISAPNP_SRIN_IRQ_FORMAT: - if ((Size < 2) || (Size > 3)) - goto skip; - AddIrqResource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - case ISAPNP_SRIN_DMA_FORMAT: - if (Size != 2) - goto skip; - AddDmaResource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - case ISAPNP_SRIN_START_DFUNCTION: - if (Size > 1) - goto skip; - - if (Size > 0) { - Peek(tmp, Size); - Priority = tmp[0]; - Size = 0; - /* FIXME: Maybe use IO_RESOURCE_PREFERRED for some */ - Option = IO_RESOURCE_ALTERNATIVE; - } else { - Priority = 0; - Option = IO_RESOURCE_ALTERNATIVE; - } - - DPRINT(" Start priority %d \n", Priority); - - LogicalDevice->CurrentDescriptorCount = 0; - - break; - - case ISAPNP_SRIN_END_DFUNCTION: - - DPRINT(" End priority %d \n", Priority); - - if (Size != 0) - goto skip; - Priority = 0; - Option = IO_RESOURCE_REQUIRED; - LogicalDevice->CurrentDescriptorCount = 0; - break; - - case ISAPNP_SRIN_IO_DESCRIPTOR: - if (Size != 7) - goto skip; - AddIOPortResource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - case ISAPNP_SRIN_FL_IO_DESCRIPOTOR: - if (Size != 3) - goto skip; - AddFixedIOPortResource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - case ISAPNP_SRIN_VENDOR_DEFINED: - break; - - case ISAPNP_SRIN_END_TAG: - if (Size > 0) - Skip(Size); - return FALSE; - - default: - DPRINT("Ignoring small tag of type 0x%X for logical device %d on card %d\n", - type, LogicalDevice->Number, Card->CardId); - } - } else { - switch (type) { - case ISAPNP_LRIN_MEMORY_RANGE: - if (Size != 9) - goto skip; - AddMemoryResource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - case ISAPNP_LRIN_ID_STRING_ANSI: - ParseAnsiName(&LogicalDevice->Name, &Size); - break; - - case ISAPNP_LRIN_ID_STRING_UNICODE: - break; - - case ISAPNP_LRIN_VENDOR_DEFINED: - break; - - case ISAPNP_LRIN_MEMORY_RANGE32: - if (Size != 17) - goto skip; - AddMemory32Resource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - case ISAPNP_LRIN_FL_MEMORY_RANGE32: - if (Size != 17) - goto skip; - AddFixedMemory32Resource(LogicalDevice, Size, Priority, Option); - Size = 0; - break; - - default: - DPRINT("Ignoring large tag of type 0x%X for logical device %d on card %d\n", - type, LogicalDevice->Number, Card->CardId); - } - } -skip: - if (Size > 0) - Skip(Size); - } - - return TRUE; -} - - -/* - * Parse resource map for ISA PnP card - */ -static BOOLEAN ParseResourceMap(PISAPNP_DEVICE_EXTENSION DeviceExtension, - PISAPNP_CARD Card) -{ - UCHAR type, tmp[17]; - USHORT size; - BOOLEAN Small; - - DPRINT("Card %d\n", Card->CardId); - - while (TRUE) { - if (!ReadTag(&type, &size, &Small)) - return FALSE; - - if (Small) { - switch (type) { - case ISAPNP_SRIN_VERSION: - if (size != 2) - goto skip; - Peek(tmp, 2); - Card->PNPVersion = tmp[0]; - Card->ProductVersion = tmp[1]; - size = 0; - break; - - case ISAPNP_SRIN_LDEVICE_ID: - if ((size >= 5) && (size <= 6)) { - if (!CreateLogicalDevice(DeviceExtension, Card, size)) - return FALSE; - size = 0; - } - break; - - case ISAPNP_SRIN_CDEVICE_ID: - /* FIXME: Parse compatible IDs */ - break; - - case ISAPNP_SRIN_END_TAG: - if (size > 0) - Skip(size); - return TRUE; - - default: - DPRINT("Ignoring small tag Type 0x%X for Card %d\n", type, Card->CardId); - } - } else { - switch (type) { - case ISAPNP_LRIN_ID_STRING_ANSI: - ParseAnsiName(&Card->Name, &size); - break; - - default: - DPRINT("Ignoring large tag Type 0x%X for Card %d\n", - type, Card->CardId); - } - } -skip: - if (size > 0) - Skip(size); - } - - return TRUE; -} - - -/* - * Compute ISA PnP checksum for first eight bytes - */ -static UCHAR Checksum(PUCHAR data) -{ - ULONG i, j; - UCHAR checksum = 0x6a, bit, b; - - for (i = 0; i < 8; i++) { - b = data[i]; - for (j = 0; j < 8; j++) { - bit = 0; - if (b & (1 << j)) - bit = 1; - checksum = ((((checksum ^ (checksum >> 1)) & - 0x01) ^ bit) << 7) | (checksum >> 1); - } - } - return checksum; -} - - -/* - * Build a resource list for a logical ISA PnP device - */ -static NTSTATUS BuildResourceList(PISAPNP_LOGICAL_DEVICE LogicalDevice, - PIO_RESOURCE_LIST DestinationList, - ULONG Priority) -{ - PLIST_ENTRY CurrentEntry, Entry; - PISAPNP_CONFIGURATION_LIST List; - PISAPNP_DESCRIPTOR Descriptor; - ULONG i; - - if (IsListEmpty(&LogicalDevice->Configuration)) - return STATUS_NOT_FOUND; - - CurrentEntry = LogicalDevice->Configuration.Flink; - while (CurrentEntry != &LogicalDevice->Configuration) { - List = CONTAINING_RECORD( - CurrentEntry, ISAPNP_CONFIGURATION_LIST, ListEntry); - - if (List->Priority == Priority) { - - DPRINT("Logical device %d DestinationList %p\n", - LogicalDevice->Number, - DestinationList); - - DestinationList->Version = 1; - DestinationList->Revision = 1; - DestinationList->Count = LogicalDevice->DescriptorCount; - - i = 0; - Entry = List->ListHead.Flink; - while (Entry != &List->ListHead) { - Descriptor = CONTAINING_RECORD( - Entry, ISAPNP_DESCRIPTOR, ListEntry); - - DPRINT("Logical device %d Destination %p(%d)\n", - LogicalDevice->Number, - &DestinationList->Descriptors[i], - i); - - RtlCopyMemory(&DestinationList->Descriptors[i], - &Descriptor->Descriptor, - sizeof(IO_RESOURCE_DESCRIPTOR)); - - i++; - - Entry = Entry->Flink; - } - - RemoveEntryList(&List->ListEntry); - - ExFreePool(List); - - return STATUS_SUCCESS; - } - - CurrentEntry = CurrentEntry->Flink; - } - - return STATUS_UNSUCCESSFUL; -} - - -/* - * Build resource lists for a logical ISA PnP device - */ -static NTSTATUS BuildResourceLists(PISAPNP_LOGICAL_DEVICE LogicalDevice) -{ - ULONG ListSize; - ULONG Priority; - ULONG SingleListSize; - PIO_RESOURCE_LIST p; - NTSTATUS Status; - - ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) - - sizeof(IO_RESOURCE_LIST) - + LogicalDevice->ConfigurationSize; - - DPRINT("Logical device %d ListSize 0x%X ConfigurationSize 0x%X DescriptorCount %d\n", - LogicalDevice->Number, ListSize, - LogicalDevice->ConfigurationSize, - LogicalDevice->DescriptorCount); - - LogicalDevice->ResourceLists = - (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePoolWithTag( - PagedPool, ListSize, TAG_ISAPNP); - if (!LogicalDevice->ResourceLists) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlZeroMemory(LogicalDevice->ResourceLists, ListSize); - - SingleListSize = sizeof(IO_RESOURCE_LIST) + - (LogicalDevice->DescriptorCount - 1) * - sizeof(IO_RESOURCE_DESCRIPTOR); - - DPRINT("SingleListSize %d\n", SingleListSize); - - Priority = 0; - p = &LogicalDevice->ResourceLists->List[0]; - do { - Status = BuildResourceList(LogicalDevice, p, Priority); - if (NT_SUCCESS(Status)) { - p = (PIO_RESOURCE_LIST)((ULONG_PTR)p + SingleListSize); - Priority++; - } - } while (Status != STATUS_NOT_FOUND); - - LogicalDevice->ResourceLists->ListSize = ListSize; - LogicalDevice->ResourceLists->AlternativeLists = Priority + 1; - - return STATUS_SUCCESS; -} - - -/* - * Build resource lists for a ISA PnP card - */ -static NTSTATUS BuildResourceListsForCard(PISAPNP_CARD Card) -{ - PISAPNP_LOGICAL_DEVICE LogicalDevice; - PLIST_ENTRY CurrentEntry; - NTSTATUS Status; - - CurrentEntry = Card->LogicalDevices.Flink; - while (CurrentEntry != &Card->LogicalDevices) { - LogicalDevice = CONTAINING_RECORD( - CurrentEntry, ISAPNP_LOGICAL_DEVICE, CardListEntry); - Status = BuildResourceLists(LogicalDevice); - if (!NT_SUCCESS(Status)) - return Status; - CurrentEntry = CurrentEntry->Flink; - } - - return STATUS_SUCCESS; -} - - -/* - * Build resource lists for all present ISA PnP cards - */ -static NTSTATUS BuildResourceListsForAll( - PISAPNP_DEVICE_EXTENSION DeviceExtension) -{ - PLIST_ENTRY CurrentEntry; - PISAPNP_CARD Card; - NTSTATUS Status; - - CurrentEntry = DeviceExtension->CardListHead.Flink; - while (CurrentEntry != &DeviceExtension->CardListHead) { - Card = CONTAINING_RECORD( - CurrentEntry, ISAPNP_CARD, ListEntry); - Status = BuildResourceListsForCard(Card); - if (!NT_SUCCESS(Status)) - return Status; - CurrentEntry = CurrentEntry->Flink; - } - - return STATUS_SUCCESS; -} - - -/* - * Build device list for all present ISA PnP cards - */ -static NTSTATUS BuildDeviceList(PISAPNP_DEVICE_EXTENSION DeviceExtension) -{ - ULONG csn; - UCHAR header[9], checksum; - PISAPNP_CARD Card; - - DPRINT("Called\n"); - - SendWait(); - SendKey(); - for (csn = 1; csn <= 10; csn++) { - SendWake((UCHAR)csn); - Peek(header, 9); - checksum = Checksum(header); - - if (checksum == 0x00 || checksum != header[8]) /* Invalid CSN */ - continue; - - DPRINT("VENDOR: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - header[0], header[1], header[2], header[3], - header[4], header[5], header[6], header[7], header[8]); - - Card = (PISAPNP_CARD)ExAllocatePoolWithTag( - PagedPool, sizeof(ISAPNP_CARD), TAG_ISAPNP); - if (!Card) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlZeroMemory(Card, sizeof(ISAPNP_CARD)); - - Card->CardId = (USHORT) csn; - Card->VendorId = (header[1] << 8) | header[0]; - Card->DeviceId = (header[3] << 8) | header[2]; - Card->Serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4]; - - InitializeListHead(&Card->LogicalDevices); - KeInitializeSpinLock(&Card->LogicalDevicesLock); - - ParseResourceMap(DeviceExtension, Card); - - ExInterlockedInsertTailList(&DeviceExtension->CardListHead, - &Card->ListEntry, - &DeviceExtension->GlobalListLock); - } - - return STATUS_SUCCESS; -} - - -static NTSTATUS -ISAPNPQueryBusRelations( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PISAPNP_DEVICE_EXTENSION DeviceExtension; - PISAPNP_LOGICAL_DEVICE LogicalDevice; - PDEVICE_RELATIONS Relations; - PLIST_ENTRY CurrentEntry; - NTSTATUS Status = STATUS_SUCCESS; - ULONG Size; - ULONG i; - - DPRINT("Called\n"); - - DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (Irp->IoStatus.Information) { - /* FIXME: Another bus driver has already created a DEVICE_RELATIONS - structure so we must merge this structure with our own */ - } - - Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) * - (DeviceExtension->DeviceListCount - 1); - Relations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(PagedPool, Size, TAG_ISAPNP); - if (!Relations) - return STATUS_INSUFFICIENT_RESOURCES; - - Relations->Count = DeviceExtension->DeviceListCount; - - i = 0; - CurrentEntry = DeviceExtension->DeviceListHead.Flink; - while (CurrentEntry != &DeviceExtension->DeviceListHead) { - LogicalDevice = CONTAINING_RECORD( - CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceListEntry); - - if (!LogicalDevice->Pdo) { - /* Create a physical device object for the - device as it does not already have one */ - Status = IoCreateDevice(DeviceObject->DriverObject, 0, - NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &LogicalDevice->Pdo); - if (!NT_SUCCESS(Status)) { - DPRINT("IoCreateDevice() failed with status 0x%X\n", Status); - ExFreePool(Relations); - return Status; - } - - LogicalDevice->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; - } - - /* Reference the physical device object. The PnP manager - will dereference it again when it is no longer needed */ - ObReferenceObject(LogicalDevice->Pdo); - - Relations->Objects[i] = LogicalDevice->Pdo; - - i++; - - CurrentEntry = CurrentEntry->Flink; - } - - Irp->IoStatus.Information = (ULONG_PTR)Relations; - - return Status; -} - - -static NTSTATUS -ISAPNPQueryDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PISAPNP_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; - - DPRINT("Called\n"); - - DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (DeviceExtension->State == dsStopped) - return STATUS_UNSUCCESSFUL; - - switch (IrpSp->Parameters.QueryDeviceRelations.Type) { - case BusRelations: - Status = ISAPNPQueryBusRelations(DeviceObject, Irp, IrpSp); - break; - - default: - Status = STATUS_NOT_IMPLEMENTED; - } - - return Status; -} - - -static NTSTATUS -ISAPNPStartDevice( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PISAPNP_DEVICE_EXTENSION DeviceExtension; - NTSTATUS Status; - ULONG NumCards; - - DPRINT("Called\n"); - - DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (DeviceExtension->State == dsStarted) - return STATUS_SUCCESS; - - NumCards = IsolatePnPCards(); - - DPRINT("Number of ISA PnP cards found: %d\n", NumCards); - - Status = BuildDeviceList(DeviceExtension); - if (!NT_SUCCESS(Status)) { - DPRINT("BuildDeviceList() failed with status 0x%X\n", Status); - return Status; - } - - Status = BuildResourceListsForAll(DeviceExtension); - if (!NT_SUCCESS(Status)) { - DPRINT("BuildResourceListsForAll() failed with status 0x%X\n", Status); - return Status; - } - - DeviceExtension->State = dsStarted; - - return STATUS_SUCCESS; -} - - -static NTSTATUS -ISAPNPStopDevice( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - PIO_STACK_LOCATION IrpSp) -{ - PISAPNP_DEVICE_EXTENSION DeviceExtension; - - DPRINT("Called\n"); - - DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - - if (DeviceExtension->State != dsStopped) { - /* FIXME: Stop device */ - DeviceExtension->State = dsStopped; - } - - return STATUS_SUCCESS; -} - - -static DRIVER_DISPATCH ISAPNPDispatchOpenClose; -static NTSTATUS +static +NTSTATUS NTAPI -ISAPNPDispatchOpenClose( +ForwardIrpCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + if (Irp->PendingReturned) + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS +NTAPI +IsaForwardIrpSynchronous( + IN PISAPNP_FDO_EXTENSION FdoExt, + IN PIRP Irp) +{ + KEVENT Event; + NTSTATUS Status; + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + IoCopyCurrentIrpStackLocationToNext(Irp); + + IoSetCompletionRoutine(Irp, ForwardIrpCompletion, &Event, TRUE, TRUE, TRUE); + + Status = IoCallDriver(FdoExt->Ldo, Irp); + if (Status == STATUS_PENDING) + { + Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + if (NT_SUCCESS(Status)) + Status = Irp->IoStatus.Status; + } + + return Status; +} + + +static +NTSTATUS +NTAPI +IsaCreateClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("Called\n"); - Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = FILE_OPENED; + + DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } -static DRIVER_DISPATCH ISAPNPDispatchReadWrite; -static NTSTATUS +static +NTSTATUS NTAPI -ISAPNPDispatchReadWrite( - IN PDEVICE_OBJECT PhysicalDeviceObject, +IsaIoctl( + IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("Called\n"); + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; + DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); + + switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) + { + default: + DPRINT1("Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); + Status = STATUS_NOT_SUPPORTED; + break; + } + + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; + return Status; } -static DRIVER_DISPATCH ISAPNPDispatchDeviceControl; -static NTSTATUS +static +NTSTATUS NTAPI -ISAPNPDispatchDeviceControl( +IsaReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - - DPRINT("Called\n"); + DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; - IrpSp = IoGetCurrentIrpStackLocation(Irp); - switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { - default: - DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; - break; - } + IoCompleteRequest(Irp, IO_NO_INCREMENT); - if (Status != STATUS_PENDING) { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - DPRINT("Leaving. Status 0x%X\n", Status); - - return Status; + return STATUS_NOT_SUPPORTED; } -static DRIVER_DISPATCH ISAPNPControl; -static NTSTATUS +static +NTSTATUS NTAPI -ISAPNPControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - - DPRINT("Called\n"); - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - switch (IrpSp->MinorFunction) { - case IRP_MN_QUERY_DEVICE_RELATIONS: - Status = ISAPNPQueryDeviceRelations(DeviceObject, Irp, IrpSp); - break; - - case IRP_MN_START_DEVICE: - Status = ISAPNPStartDevice(DeviceObject, Irp, IrpSp); - break; - - case IRP_MN_STOP_DEVICE: - Status = ISAPNPStopDevice(DeviceObject, Irp, IrpSp); - break; - - case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: - /* Nothing to do here */ - DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); - Status = Irp->IoStatus.Status; - break; - - default: - DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; - break; - } - - if (Status != STATUS_PENDING) { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - DPRINT("Leaving. Status 0x%X\n", Status); - - return Status; -} - - -static NTSTATUS -NTAPI -ISAPNPAddDevice( +IsaAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { - PISAPNP_DEVICE_EXTENSION DeviceExtension; PDEVICE_OBJECT Fdo; + PISAPNP_FDO_EXTENSION FdoExt; NTSTATUS Status; - DPRINT("Called\n"); + DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject); - Status = IoCreateDevice(DriverObject, sizeof(ISAPNP_DEVICE_EXTENSION), - NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo); - if (!NT_SUCCESS(Status)) { - DPRINT("IoCreateDevice() failed with status 0x%X\n", Status); - return Status; + Status = IoCreateDevice(DriverObject, + sizeof(*FdoExt), + NULL, + FILE_DEVICE_BUS_EXTENDER, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &Fdo); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create FDO (0x%x)\n", Status); + return Status; } - DeviceExtension = (PISAPNP_DEVICE_EXTENSION)Fdo->DeviceExtension; + FdoExt = Fdo->DeviceExtension; + RtlZeroMemory(FdoExt, sizeof(*FdoExt)); - DeviceExtension->Pdo = PhysicalDeviceObject; + FdoExt->Common.Self = Fdo; + FdoExt->Common.IsFdo = TRUE; + FdoExt->Common.State = dsStopped; + FdoExt->Pdo = PhysicalDeviceObject; + FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, + PhysicalDeviceObject); - DeviceExtension->Ldo = - IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject); - - InitializeListHead(&DeviceExtension->CardListHead); - InitializeListHead(&DeviceExtension->DeviceListHead); - DeviceExtension->DeviceListCount = 0; - KeInitializeSpinLock(&DeviceExtension->GlobalListLock); - - DeviceExtension->State = dsStopped; + InitializeListHead(&FdoExt->DeviceListHead); + KeInitializeSpinLock(&FdoExt->Lock); Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - DPRINT("Done AddDevice\n"); - return STATUS_SUCCESS; } +static +NTSTATUS +NTAPI +IsaPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension; + + DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); + + if (DevExt->IsFdo) + { + return IsaFdoPnp((PISAPNP_FDO_EXTENSION)DevExt, + Irp, + IrpSp); + } + else + { + return IsaPdoPnp((PISAPNP_LOGICAL_DEVICE)DevExt, + Irp, + IrpSp); + } +} NTSTATUS NTAPI @@ -1731,15 +185,15 @@ DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { - DbgPrint("ISA Plug and Play Bus Driver\n"); + DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath); - DriverObject->MajorFunction[IRP_MJ_CREATE] = ISAPNPDispatchOpenClose; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = ISAPNPDispatchOpenClose; - DriverObject->MajorFunction[IRP_MJ_READ] = ISAPNPDispatchReadWrite; - DriverObject->MajorFunction[IRP_MJ_WRITE] = ISAPNPDispatchReadWrite; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ISAPNPDispatchDeviceControl; - DriverObject->MajorFunction[IRP_MJ_PNP] = ISAPNPControl; - DriverObject->DriverExtension->AddDevice = ISAPNPAddDevice; + DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaCreateClose; + DriverObject->MajorFunction[IRP_MJ_READ] = IsaReadWrite; + DriverObject->MajorFunction[IRP_MJ_WRITE] = IsaReadWrite; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaIoctl; + DriverObject->MajorFunction[IRP_MJ_PNP] = IsaPnp; + DriverObject->DriverExtension->AddDevice = IsaAddDevice; return STATUS_SUCCESS; } diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h index 59697b9848e..85fcb7887f4 100644 --- a/drivers/bus/isapnp/isapnp.h +++ b/drivers/bus/isapnp/isapnp.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #ifdef __cplusplus extern "C" { @@ -8,331 +8,88 @@ extern "C" { #define TAG_ISAPNP 'PNPI' -#define IO_RESOURCE_REQUIRED 0x00 //ROS Extension - -#define ISAPNP_ADDRESS_PORT 0x0279 // ADDRESS (W) -#define ISAPNP_WRITE_PORT 0x0A79 // WRITE_DATA (W) -#define ISAPNP_MIN_READ_PORT 0x0203 // READ_DATA (R) -#define ISAPNP_MAX_READ_PORT 0x03FF // READ_DATA (R) - -// Card control registers -#define ISAPNP_CARD_READ_DATA_PORT 0x00 // Set READ_DATA port -#define ISAPNP_CARD_ISOLATION 0x01 // Isolation -#define ISAPNP_CARD_CONFIG_COTROL 0x02 // Configuration control -#define ISAPNP_CARD_WAKECSN 0x03 // Wake[CSN] -#define ISAPNP_CARD_RESOUCE_DATA 0x04 // Resource data port -#define ISAPNP_CARD_STATUS 0x05 // Status port -#define ISAPNP_CARD_CSN 0x06 // Card Select Number port -#define ISAPNP_CARD_LOG_DEVICE_NUM 0x07 // Logical Device Number -#define ISAPNP_CARD_RESERVED 0x08 // Card level reserved -#define ISAPNP_CARD_VENDOR_DEFINED 0x20 // Vendor defined - -// Logical device control registers -#define ISAPNP_CONTROL_ACTIVATE 0x30 // Activate logical device -#define ISAPNP_CONTROL_IO_RANGE_CHECK 0x31 // I/O range conflict check -#define ISAPNP_CONTROL_LDC_RESERVED 0x32 // Logical Device Control reserved -#define ISAPNP_CONTROL_LDCV_RESERVED 0x38 // Logical Device Control Vendor reserved - -// Logical device configuration registers -#define ISAPNP_CONFIG_MEMORY_BASE2 0x00 // Memory base address bits 23-16 -#define ISAPNP_CONFIG_MEMORY_BASE1 0x01 // Memory base address bits 15-8 -#define ISAPNP_CONFIG_MEMORY_CONTROL 0x02 // Memory control -#define ISAPNP_CONFIG_MEMORY_LIMIT2 0x03 // Memory limit bits 23-16 -#define ISAPNP_CONFIG_MEMORY_LIMIT1 0x04 // Memory limit bits 15-8 - -#define ISAPNP_CONFIG_MEMORY_DESC0 0x40 // Memory descriptor 0 -#define ISAPNP_CONFIG_MEMORY_DESC1 0x48 // Memory descriptor 1 -#define ISAPNP_CONFIG_MEMORY_DESC2 0x50 // Memory descriptor 2 -#define ISAPNP_CONFIG_MEMORY_DESC3 0x58 // Memory descriptor 3 - -#define ISAPNP_CONFIG_MEMORY32_BASE3 0x00 // 32-bit memory base address bits 31-24 -#define ISAPNP_CONFIG_MEMORY32_BASE2 0x01 // 32-bit memory base address bits 23-16 -#define ISAPNP_CONFIG_MEMORY32_BASE1 0x01 // 32-bit memory base address bits 15-8 -#define ISAPNP_CONFIG_MEMORY32_CONTROL 0x02 // 32-bit memory control -#define ISAPNP_CONFIG_MEMORY32_LIMIT3 0x03 // 32-bit memory limit bits 31-24 -#define ISAPNP_CONFIG_MEMORY32_LIMIT2 0x04 // 32-bit memory limit bits 23-16 -#define ISAPNP_CONFIG_MEMORY32_LIMIT1 0x05 // 32-bit memory limit bits 15-8 - -#define ISAPNP_CONFIG_MEMORY32_DESC0 0x76 // 32-bit memory descriptor 0 -#define ISAPNP_CONFIG_MEMORY32_DESC1 0x80 // 32-bit memory descriptor 1 -#define ISAPNP_CONFIG_MEMORY32_DESC2 0x90 // 32-bit memory descriptor 2 -#define ISAPNP_CONFIG_MEMORY32_DESC3 0xA0 // 32-bit memory descriptor 3 - -#define ISAPNP_CONFIG_IO_BASE1 0x00 // I/O port base address bits 15-8 -#define ISAPNP_CONFIG_IO_BASE0 0x01 // I/O port base address bits 7-0 - -#define ISAPNP_CONFIG_IO_DESC0 0x60 // I/O port descriptor 0 -#define ISAPNP_CONFIG_IO_DESC1 0x62 // I/O port descriptor 1 -#define ISAPNP_CONFIG_IO_DESC2 0x64 // I/O port descriptor 2 -#define ISAPNP_CONFIG_IO_DESC3 0x66 // I/O port descriptor 3 -#define ISAPNP_CONFIG_IO_DESC4 0x68 // I/O port descriptor 4 -#define ISAPNP_CONFIG_IO_DESC5 0x6A // I/O port descriptor 5 -#define ISAPNP_CONFIG_IO_DESC6 0x6C // I/O port descriptor 6 -#define ISAPNP_CONFIG_IO_DESC7 0x6E // I/O port descriptor 7 - -#define ISAPNP_CONFIG_IRQ_LEVEL0 0x70 // Interupt level for descriptor 0 -#define ISAPNP_CONFIG_IRQ_TYPE0 0x71 // Type level for descriptor 0 -#define ISAPNP_CONFIG_IRQ_LEVEL1 0x72 // Interupt level for descriptor 1 -#define ISAPNP_CONFIG_IRQ_TYPE1 0x73 // Type level for descriptor 1 - -#define ISAPNP_CONFIG_DMA_CHANNEL0 0x74 // DMA channel for descriptor 0 -#define ISAPNP_CONFIG_DMA_CHANNEL1 0x75 // DMA channel for descriptor 1 - - -typedef struct _PNPISA_SERIAL_ID -{ - UCHAR VendorId[4]; // Vendor Identifier - UCHAR SerialId[4]; // Serial number - UCHAR Checksum; // Checksum -} PNPISA_SERIAL_ID, *PPNPISA_SERIAL_ID; - - -#define ISAPNP_RES_PRIORITY_PREFERRED 0 -#define ISAPNP_RES_PRIORITY_ACCEPTABLE 1 -#define ISAPNP_RES_PRIORITY_FUNCTIONAL 2 -#define ISAPNP_RES_PRIORITY_INVALID 65535 - - -#define ISAPNP_RESOURCE_ITEM_TYPE 0x80 // 0 = small, 1 = large - -// Small Resource Item Names (SRINs) -#define ISAPNP_SRIN_VERSION 0x1 // PnP version number -#define ISAPNP_SRIN_LDEVICE_ID 0x2 // Logical device id -#define ISAPNP_SRIN_CDEVICE_ID 0x3 // Compatible device id -#define ISAPNP_SRIN_IRQ_FORMAT 0x4 // IRQ format -#define ISAPNP_SRIN_DMA_FORMAT 0x5 // DMA format -#define ISAPNP_SRIN_START_DFUNCTION 0x6 // Start dependant function -#define ISAPNP_SRIN_END_DFUNCTION 0x7 // End dependant function -#define ISAPNP_SRIN_IO_DESCRIPTOR 0x8 // I/O port descriptor -#define ISAPNP_SRIN_FL_IO_DESCRIPOTOR 0x9 // Fixed location I/O port descriptor -#define ISAPNP_SRIN_VENDOR_DEFINED 0xE // Vendor defined -#define ISAPNP_SRIN_END_TAG 0xF // End tag - -typedef struct _ISAPNP_SRI_VERSION -{ - UCHAR Header; - UCHAR Version; // Packed BCD format version number - UCHAR VendorVersion; // Vendor specific version number -} ISAPNP_SRI_VERSION, *PISAPNP_SRI_VERSION; - -typedef struct _ISAPNP_SRI_LDEVICE_ID -{ - UCHAR Header; - USHORT DeviceId; // Logical device id - USHORT VendorId; // Manufacturer id - UCHAR Flags; // Flags -} ISAPNP_SRI_LDEVICE_ID, *PISAPNP_SRI_LDEVICE_ID; - -typedef struct _ISAPNP_SRI_CDEVICE_ID -{ - UCHAR Header; - USHORT DeviceId; // Logical device id - USHORT VendorId; // Manufacturer id -} ISAPNP_SRI_CDEVICE_ID, *PISAPNP_SRI_CDEVICE_ID; - -typedef struct _ISAPNP_SRI_IRQ_FORMAT -{ - UCHAR Header; - USHORT Mask; // IRQ mask (bit 0 = irq 0, etc.) - UCHAR Information; // IRQ information -} ISAPNP_SRI_IRQ_FORMAT, *PISAPNP_SRI_IRQ_FORMAT; - -typedef struct _ISAPNP_SRI_DMA_FORMAT -{ - UCHAR Header; - USHORT Mask; // DMA channel mask (bit 0 = channel 0, etc.) - UCHAR Information; // DMA information -} ISAPNP_SRI_DMA_FORMAT, *PISAPNP_SRI_DMA_FORMAT; - -typedef struct _ISAPNP_SRI_START_DFUNCTION -{ - UCHAR Header; -} ISAPNP_SRI_START_DFUNCTION, *PISAPNP_SRI_START_DFUNCTION; - -typedef struct _ISAPNP_SRI_END_DFUNCTION -{ - UCHAR Header; -} ISAPNP_SRI_END_DFUNCTION, *PISAPNP_SRI_END_DFUNCTION; - -typedef struct _ISAPNP_SRI_IO_DESCRIPTOR -{ - UCHAR Header; - UCHAR Information; // Information - USHORT RangeMinBase; // Minimum base address - USHORT RangeMaxBase; // Maximum base address - UCHAR Alignment; // Base alignment - UCHAR RangeLength; // Length of range -} ISAPNP_SRI_IO_DESCRIPTOR, *PISAPNP_SRI_IO_DESCRIPTOR; - -typedef struct _ISAPNP_SRI_FL_IO_DESCRIPTOR -{ - UCHAR Header; - USHORT RangeBase; // Range base address - UCHAR RangeLength; // Length of range -} ISAPNP_SRI_FL_IO_DESCRIPTOR, *PISAPNP_SRI_FL_IO_DESCRIPTOR; - -typedef struct _PISAPNP_SRI_VENDOR_DEFINED -{ - UCHAR Header; - UCHAR Reserved[0]; // Vendor defined -} ISAPNP_SRI_VENDOR_DEFINED, *PISAPNP_SRI_VENDOR_DEFINED; - -typedef struct _ISAPNP_SRI_END_TAG -{ - UCHAR Header; - UCHAR Checksum; // Checksum -} ISAPNP_SRI_END_TAG, *PISAPNP_SRI_END_TAG; - - -typedef struct _ISAPNP_LRI -{ - UCHAR Header; - USHORT Length; // Length of data items -} ISAPNP_LRI, *PISAPNP_LRI; - -// Large Resource Item Names (LRINs) -#define ISAPNP_LRIN_MEMORY_RANGE 0x1 // Memory range descriptor -#define ISAPNP_LRIN_ID_STRING_ANSI 0x2 // Identifier string (ANSI) -#define ISAPNP_LRIN_ID_STRING_UNICODE 0x3 // Identifier string (UNICODE) -#define ISAPNP_LRIN_VENDOR_DEFINED 0x4 // Vendor defined -#define ISAPNP_LRIN_MEMORY_RANGE32 0x5 // 32-bit memory range descriptor -#define ISAPNP_LRIN_FL_MEMORY_RANGE32 0x6 // 32-bit fixed location memory range descriptor - -typedef struct _ISAPNP_LRI_MEMORY_RANGE -{ - UCHAR Header; - USHORT Length; // Length of data items - UCHAR Information; // Information - USHORT RangeMinBase; // Minimum base address - USHORT RangeMaxBase; // Maximum base address - USHORT Alignment; // Base alignment - USHORT RangeLength; // Length of range -} ISAPNP_LRI_MEMORY_RANGE, *PISAPNP_LRI_MEMORY_RANGE; - -typedef struct _ISAPNP_LRI_ID_STRING_ANSI -{ - UCHAR Header; - USHORT Length; // Length of data items - UCHAR String[0]; // Identifier string -} ISAPNP_LRI_ID_STRING_ANSI, *PISAPNP_LRI_ID_STRING_ANSI; - -typedef struct _ISAPNP_LRI_ID_STRING_UNICODE -{ - UCHAR Header; - USHORT Length; // Length of data items - USHORT CountryId; // Country identifier - USHORT String[0]; // Identifier string -} ISAPNP_LRI_ID_STRING_UNICODE, *PISAPNP_LRI_ID_STRING_UNICODE; - -typedef struct _PISAPNP_LRI_VENDOR_DEFINED -{ - UCHAR Header; - USHORT Length; // Length of data items - UCHAR Reserved[0]; // Vendor defined -} ISAPNP_LRI_VENDOR_DEFINED, *PISAPNP_LRI_VENDOR_DEFINED; - -typedef struct _ISAPNP_LRI_MEMORY_RANGE32 -{ - UCHAR Header; - USHORT Length; // Length of data items - UCHAR Information; // Information - ULONG RangeMinBase; // Minimum base address - ULONG RangeMaxBase; // Maximum base address - ULONG Alignment; // Base alignment - ULONG RangeLength; // Length of range -} ISAPNP_LRI_MEMORY_RANGE32, *PISAPNP_LRI_MEMORY_RANGE32; - -typedef struct _ISAPNP_LRI_FL_MEMORY_RANGE32 -{ - UCHAR Header; - USHORT Length; // Length of data items - UCHAR Information; // Information - ULONG RangeMinBase; // Minimum base address - ULONG RangeMaxBase; // Maximum base address - ULONG RangeLength; // Length of range -} ISAPNP_LRI_FL_MEMORY_RANGE32, *PISAPNP_LRI_FL_MEMORY_RANGE32; - -typedef struct _ISAPNP_CARD -{ - LIST_ENTRY ListEntry; - USHORT CardId; - USHORT VendorId; - USHORT DeviceId; - ULONG Serial; - UCHAR PNPVersion; - UCHAR ProductVersion; - UNICODE_STRING Name; - LIST_ENTRY LogicalDevices; - KSPIN_LOCK LogicalDevicesLock; -} ISAPNP_CARD, *PISAPNP_CARD; - - -typedef struct _ISAPNP_DESCRIPTOR -{ - LIST_ENTRY ListEntry; - IO_RESOURCE_DESCRIPTOR Descriptor; -} ISAPNP_DESCRIPTOR, *PISAPNP_DESCRIPTOR; - -typedef struct _ISAPNP_CONFIGURATION_LIST -{ - LIST_ENTRY ListEntry; - ULONG Priority; - LIST_ENTRY ListHead; -} ISAPNP_CONFIGURATION_LIST, *PISAPNP_CONFIGURATION_LIST; - - -#define MAX_COMPATIBLE_ID 32 - -typedef struct _ISAPNP_LOGICAL_DEVICE -{ - LIST_ENTRY CardListEntry; - LIST_ENTRY DeviceListEntry; - USHORT Number; - USHORT VendorId; - USHORT DeviceId; - USHORT CVendorId[MAX_COMPATIBLE_ID]; - USHORT CDeviceId[MAX_COMPATIBLE_ID]; - USHORT Regs; - PISAPNP_CARD Card; - UNICODE_STRING Name; - PDEVICE_OBJECT Pdo; - PIO_RESOURCE_REQUIREMENTS_LIST ResourceLists; - LIST_ENTRY Configuration; - ULONG ConfigurationSize; - ULONG DescriptorCount; - ULONG CurrentDescriptorCount; -} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE; - - typedef enum { dsStopped, dsStarted } ISAPNP_DEVICE_STATE; -typedef struct _ISAPNP_DEVICE_EXTENSION -{ - // Physical Device Object - PDEVICE_OBJECT Pdo; - // Lower device object - PDEVICE_OBJECT Ldo; - // List of ISA PnP cards managed by this driver - LIST_ENTRY CardListHead; - // List of devices managed by this driver - LIST_ENTRY DeviceListHead; - // Number of devices managed by this driver - ULONG DeviceListCount; - // Spinlock for the linked lists - KSPIN_LOCK GlobalListLock; - // Current state of the driver +typedef struct _ISAPNP_COMMON_EXTENSION { + PDEVICE_OBJECT Self; + BOOLEAN IsFdo; ISAPNP_DEVICE_STATE State; -} ISAPNP_DEVICE_EXTENSION, *PISAPNP_DEVICE_EXTENSION; +} ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION; +typedef struct _ISAPNP_FDO_EXTENSION { + ISAPNP_COMMON_EXTENSION Common; + PDEVICE_OBJECT Ldo; + PDEVICE_OBJECT Pdo; + LIST_ENTRY DeviceListHead; + ULONG DeviceCount; + PUCHAR ReadDataPort; + KSPIN_LOCK Lock; +} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION; + +typedef struct _ISAPNP_LOGICAL_DEVICE { + ISAPNP_COMMON_EXTENSION Common; + USHORT VendorId; + USHORT ProdId; + USHORT IoAddr; + UCHAR IrqNo; + UCHAR CSN; + UCHAR LDN; + LIST_ENTRY ListEntry; +} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE; + +/* isapnp.c */ NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); +NTSTATUS +NTAPI +IsaForwardIrpSynchronous( + IN PISAPNP_FDO_EXTENSION FdoExt, + IN PIRP Irp); + +/* fdo.c */ +NTSTATUS +NTAPI +IsaFdoPnp( + IN PISAPNP_FDO_EXTENSION FdoExt, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp); + +/* pdo.c */ +NTSTATUS +NTAPI +IsaPdoPnp( + IN PISAPNP_LOGICAL_DEVICE LogDev, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp); + +/* hardware.c */ +NTSTATUS +NTAPI +IsaHwDetectReadDataPort( + IN PISAPNP_FDO_EXTENSION FdoExt); + +NTSTATUS +NTAPI +IsaHwFillDeviceList( + IN PISAPNP_FDO_EXTENSION FdoExt); + +NTSTATUS +NTAPI +IsaHwDeactivateDevice( + IN PISAPNP_LOGICAL_DEVICE LogicalDevice); + +NTSTATUS +NTAPI +IsaHwActivateDevice( + IN PISAPNP_LOGICAL_DEVICE LogicalDevice); + #ifdef __cplusplus } #endif diff --git a/drivers/bus/isapnp/isapnp.rbuild b/drivers/bus/isapnp/isapnp.rbuild index b0b7919d927..bc8a96acaf7 100644 --- a/drivers/bus/isapnp/isapnp.rbuild +++ b/drivers/bus/isapnp/isapnp.rbuild @@ -1,9 +1,13 @@ + . ntoskrnl hal isapnp.c + pdo.c + fdo.c + hardware.c isapnp.rc diff --git a/drivers/bus/isapnp/isapnphw.h b/drivers/bus/isapnp/isapnphw.h new file mode 100644 index 00000000000..aec87191fe5 --- /dev/null +++ b/drivers/bus/isapnp/isapnphw.h @@ -0,0 +1,106 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define ISAPNP_ADDRESS 0x279 +#define ISAPNP_WRITE_DATA 0xA79 + +#define ISAPNP_READ_PORT_MIN 0x203 +#define ISAPNP_READ_PORT_START 0x213 +#define ISAPNP_READ_PORT_MAX 0x3FF +#define ISAPNP_READ_PORT_STEP 0x10 + +#define ISAPNP_CSN_MIN 0x01 +#define ISAPNP_CSN_MAX 0x0F + +#define ISAPNP_READPORT 0x00 +#define ISAPNP_SERIALISOLATION 0x01 +#define ISAPNP_CONFIGCONTROL 0x02 +#define ISAPNP_WAKE 0x03 +#define ISAPNP_RESOURCEDATA 0x04 +#define ISAPNP_STATUS 0x05 +#define ISAPNP_CARDSELECTNUMBER 0x06 +#define ISAPNP_LOGICALDEVICENUMBER 0x07 + +#define ISAPNP_ACTIVATE 0x30 +#define ISAPNP_IORANGECHECK 0x31 + +#define ISAPNP_IOBASE(n) (0x60 + ((n)*2)) +#define ISAPNP_IRQNO(n) (0x70 + ((n)*2)) +#define ISAPNP_IRQTYPE(n) (0x71 + ((n) * 2)) + +#define ISAPNP_CONFIG_RESET (1 << 0) +#define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1) +#define ISAPNP_CONFIG_RESET_CSN (1 << 2) + +#define ISAPNP_LFSR_SEED 0x6A + +#define ISAPNP_IS_SMALL_TAG(t) (!((t) & 0x80)) +#define ISAPNP_SMALL_TAG_NAME(t) (((t) >> 3) & 0xF) +#define ISAPNP_SMALL_TAG_LEN(t) (((t) & 0x7)) +#define ISAPNP_TAG_PNPVERNO 0x01 +#define ISAPNP_TAG_LOGDEVID 0x02 +#define ISAPNP_TAG_COMPATDEVID 0x03 +#define ISAPNP_TAG_IRQ 0x04 +#define ISAPNP_TAG_DMA 0x05 +#define ISAPNP_TAG_STARTDEP 0x06 +#define ISAPNP_TAG_ENDDEP 0x07 +#define ISAPNP_TAG_IOPORT 0x08 +#define ISAPNP_TAG_FIXEDIO 0x09 +#define ISAPNP_TAG_RSVDSHORTA 0x0A +#define ISAPNP_TAG_RSVDSHORTB 0x0B +#define ISAPNP_TAG_RSVDSHORTC 0x0C +#define ISAPNP_TAG_RSVDSHORTD 0x0D +#define ISAPNP_TAG_VENDORSHORT 0x0E +#define ISAPNP_TAG_END 0x0F + +#define ISAPNP_IS_LARGE_TAG(t) (((t) & 0x80)) +#define ISAPNP_LARGE_TAG_NAME(t) (t) +#define ISAPNP_TAG_MEMRANGE 0x81 +#define ISAPNP_TAG_ANSISTR 0x82 +#define ISAPNP_TAG_UNICODESTR 0x83 +#define ISAPNP_TAG_VENDORLONG 0x84 +#define ISAPNP_TAG_MEM32RANGE 0x85 +#define ISAPNP_TAG_FIXEDMEM32RANGE 0x86 +#define ISAPNP_TAG_RSVDLONG0 0xF0 +#define ISAPNP_TAG_RSVDLONG1 0xF1 +#define ISAPNP_TAG_RSVDLONG2 0xF2 +#define ISAPNP_TAG_RSVDLONG3 0xF3 +#define ISAPNP_TAG_RSVDLONG4 0xF4 +#define ISAPNP_TAG_RSVDLONG5 0xF5 +#define ISAPNP_TAG_RSVDLONG6 0xF6 +#define ISAPNP_TAG_RSVDLONG7 0xF7 +#define ISAPNP_TAG_RSVDLONG8 0xF8 +#define ISAPNP_TAG_RSVDLONG9 0xF9 +#define ISAPNP_TAG_RSVDLONGA 0xFA +#define ISAPNP_TAG_RSVDLONGB 0xFB +#define ISAPNP_TAG_RSVDLONGC 0xFC +#define ISAPNP_TAG_RSVDLONGD 0xFD +#define ISAPNP_TAG_RSVDLONGE 0xFE +#define ISAPNP_TAG_RSVDLONGF 0xFF +#define ISAPNP_TAG_PSEUDO_NEWBOARD 0x100 + +typedef struct _ISAPNP_IDENTIFIER { + USHORT VendorId; + USHORT ProdId; + ULONG Serial; + UCHAR Checksum; +} ISAPNP_IDENTIFIER, *PISAPNP_IDENTIFIER; + +typedef struct _ISAPNP_LOGDEVID { + USHORT VendorId; + USHORT ProdId; + USHORT Flags; +} ISAPNP_LOGDEVID, *PISAPNP_LOGDEVID; + +typedef struct _ISAPNP_DEVICEID { + CHAR* Name; + USHORT VendorId; + USHORT ProdId; +} ISAPNP_DEVICEID, *PISAPNP_DEVICEID; + +#ifdef __cplusplus +} +#endif diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c new file mode 100644 index 00000000000..0292f20f0f4 --- /dev/null +++ b/drivers/bus/isapnp/pdo.c @@ -0,0 +1,83 @@ +/* + * PROJECT: ReactOS ISA PnP Bus driver + * FILE: pdo.c + * PURPOSE: PDO-specific code + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ +#include + +#define NDEBUG +#include + +NTSTATUS +NTAPI +IsaPdoQueryDeviceRelations( + IN PISAPNP_LOGICAL_DEVICE LogDev, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + PDEVICE_RELATIONS DeviceRelations; + + if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + return Irp->IoStatus.Status; + + DeviceRelations = ExAllocatePool(PagedPool, sizeof(*DeviceRelations)); + if (!DeviceRelations) + return STATUS_INSUFFICIENT_RESOURCES; + + DeviceRelations->Count = 1; + DeviceRelations->Objects[0] = LogDev->Common.Self; + ObReferenceObject(LogDev->Common.Self); + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IsaPdoPnp( + IN PISAPNP_LOGICAL_DEVICE LogDev, + IN PIRP Irp, + IN PIO_STACK_LOCATION IrpSp) +{ + NTSTATUS Status = Irp->IoStatus.Status; + + switch (IrpSp->MinorFunction) + { + case IRP_MN_START_DEVICE: + Status = IsaHwActivateDevice(LogDev); + + if (NT_SUCCESS(Status)) + LogDev->Common.State = dsStarted; + break; + + case IRP_MN_STOP_DEVICE: + Status = IsaHwDeactivateDevice(LogDev); + + if (NT_SUCCESS(Status)) + LogDev->Common.State = dsStopped; + break; + + case IRP_MN_QUERY_DEVICE_RELATIONS: + Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp); + break; + + case IRP_MN_QUERY_RESOURCES: + DPRINT1("IRP_MN_QUERY_RESOURCES is UNIMPLEMENTED!\n"); + break; + + case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: + DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS is UNIMPLEMENTED!\n"); + break; + + default: + DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction); + break; + } + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} diff --git a/drivers/bus/pci/pdo.c b/drivers/bus/pci/pdo.c index f19e45c1f4c..266b95d6a97 100644 --- a/drivers/bus/pci/pdo.c +++ b/drivers/bus/pci/pdo.c @@ -775,7 +775,7 @@ PdoQueryResources( Descriptor->ShareDisposition = CmResourceShareShared; Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine; - Descriptor->u.Interrupt.Vector = 0; + Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine; Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF; } } @@ -1186,6 +1186,52 @@ PdoQueryInterface( return Status; } +static NTSTATUS +PdoStartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PCM_RESOURCE_LIST RawResList = IrpSp->Parameters.StartDevice.AllocatedResources; + PCM_FULL_RESOURCE_DESCRIPTOR RawFullDesc; + PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDesc; + ULONG i, ii; + PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + UCHAR Irq; + + if (!RawResList) + return STATUS_SUCCESS; + + /* TODO: Assign the other resources we get to the card */ + + for (i = 0; i < RawResList->Count; i++) + { + RawFullDesc = &RawResList->List[i]; + + for (ii = 0; ii < RawFullDesc->PartialResourceList.Count; ii++) + { + RawPartialDesc = &RawFullDesc->PartialResourceList.PartialDescriptors[ii]; + + if (RawPartialDesc->Type == CmResourceTypeInterrupt) + { + DPRINT1("Assigning IRQ %x to PCI device (%x, %x)\n", + RawPartialDesc->u.Interrupt.Vector, + DeviceExtension->PciDevice->SlotNumber.u.AsULONG, + DeviceExtension->PciDevice->BusNumber); + + Irq = (UCHAR)RawPartialDesc->u.Interrupt.Vector; + HalSetBusDataByOffset(PCIConfiguration, + DeviceExtension->PciDevice->BusNumber, + DeviceExtension->PciDevice->SlotNumber.u.AsULONG, + &Irq, + 0x3c /* PCI_INTERRUPT_LINE */, + sizeof(UCHAR)); + } + } + } + + return STATUS_SUCCESS; +} static NTSTATUS PdoReadConfig( @@ -1247,6 +1293,33 @@ PdoWriteConfig( return STATUS_SUCCESS; } +static NTSTATUS +PdoQueryDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PDEVICE_RELATIONS DeviceRelations; + + /* We only support TargetDeviceRelation for child PDOs */ + if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + return Irp->IoStatus.Status; + + /* We can do this because we only return 1 PDO for TargetDeviceRelation */ + DeviceRelations = ExAllocatePool(PagedPool, sizeof(*DeviceRelations)); + if (!DeviceRelations) + return STATUS_INSUFFICIENT_RESOURCES; + + DeviceRelations->Count = 1; + DeviceRelations->Objects[0] = DeviceObject; + + /* The PnP manager will remove this when it is done with the PDO */ + ObReferenceObject(DeviceObject); + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +} static NTSTATUS PdoSetPower( @@ -1319,8 +1392,7 @@ PdoPnpControl( break; case IRP_MN_QUERY_DEVICE_RELATIONS: - /* FIXME: Possibly handle for RemovalRelations */ - DPRINT("Unimplemented IRP_MN_QUERY_DEVICE_RELATIONS received\n"); + Status = PdoQueryDeviceRelations(DeviceObject, Irp, IrpSp); break; case IRP_MN_QUERY_DEVICE_TEXT: @@ -1352,6 +1424,9 @@ PdoPnpControl( break; case IRP_MN_START_DEVICE: + Status = PdoStartDevice(DeviceObject, Irp, IrpSp); + break; + case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_STOP_DEVICE: diff --git a/drivers/bus/pcmcia/fdo.c b/drivers/bus/pcmcia/fdo.c new file mode 100644 index 00000000000..348fd1cf9ea --- /dev/null +++ b/drivers/bus/pcmcia/fdo.c @@ -0,0 +1,25 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel + * FILE: drivers/bus/pcmcia/fdo.c + * PURPOSE: PCMCIA Bus Driver + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +//#define NDEBUG +#include + +NTSTATUS +NTAPI +PcmciaFdoPlugPlay(PPCMCIA_FDO_EXTENSION FdoExt, + PIRP Irp) +{ + UNIMPLEMENTED + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_NOT_SUPPORTED; +} + diff --git a/drivers/bus/pcmcia/pcmcia.c b/drivers/bus/pcmcia/pcmcia.c new file mode 100644 index 00000000000..54d23da7f50 --- /dev/null +++ b/drivers/bus/pcmcia/pcmcia.c @@ -0,0 +1,242 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel + * FILE: drivers/bus/pcmcia/pcmcia.c + * PURPOSE: PCMCIA Bus Driver + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +//#define NDEBUG +#include + +BOOLEAN IoctlEnabled; + +NTSTATUS +NTAPI +PcmciaCreateClose(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + DPRINT("PCMCIA: Create/Close\n"); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PcmciaDeviceControl(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status; + + DPRINT("PCMCIA: DeviceIoControl\n"); + + Irp->IoStatus.Information = 0; + + switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) + { + default: + DPRINT1("PCMCIA: Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); + Status = STATUS_NOT_SUPPORTED; + } + + Irp->IoStatus.Status = Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +VOID +NTAPI +PcmciaUnload(PDRIVER_OBJECT DriverObject) +{ + DPRINT("PCMCIA: Unload\n"); +} + +NTSTATUS +NTAPI +PcmciaPlugPlay(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension; + + DPRINT("PCMCIA: PnP\n"); + if (Common->IsFDO) + { + return PcmciaFdoPlugPlay((PPCMCIA_FDO_EXTENSION)Common, + Irp); + } + else + { + return PcmciaPdoPlugPlay((PPCMCIA_PDO_EXTENSION)Common, + Irp); + } +} + +NTSTATUS +NTAPI +PcmciaPower(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status; + + switch (IrpSp->MinorFunction) + { + case IRP_MN_QUERY_POWER: + /* I don't see any reason that we should care */ + DPRINT("PCMCIA: IRP_MN_QUERY_POWER\n"); + Status = STATUS_SUCCESS; + break; + + case IRP_MN_POWER_SEQUENCE: + DPRINT("PCMCIA: IRP_MN_POWER_SEQUENCE\n"); + RtlCopyMemory(IrpSp->Parameters.PowerSequence.PowerSequence, + &Common->PowerSequence, + sizeof(POWER_SEQUENCE)); + Status = STATUS_SUCCESS; + break; + + case IRP_MN_WAIT_WAKE: + /* Not really sure about this */ + DPRINT("PCMCIA: IRP_MN_WAIT_WAKE\n"); + Status = STATUS_NOT_SUPPORTED; + break; + + case IRP_MN_SET_POWER: + DPRINT("PCMCIA: IRP_MN_SET_POWER\n"); + if (IrpSp->Parameters.Power.Type == SystemPowerState) + { + Common->SystemPowerState = IrpSp->Parameters.Power.State.SystemState; + + Status = STATUS_SUCCESS; + } + else + { + Common->DevicePowerState = IrpSp->Parameters.Power.State.DeviceState; + + /* Update the POWER_SEQUENCE struct */ + if (Common->DevicePowerState <= PowerDeviceD1) + Common->PowerSequence.SequenceD1++; + + if (Common->DevicePowerState <= PowerDeviceD2) + Common->PowerSequence.SequenceD2++; + + if (Common->DevicePowerState <= PowerDeviceD3) + Common->PowerSequence.SequenceD3++; + + /* Start the underlying device if we are handling this for a PDO */ + if (!Common->IsFDO) + Status = PcmciaPdoSetPowerState((PPCMCIA_PDO_EXTENSION)Common); + else + Status = STATUS_SUCCESS; + } + + /* Report that we changed state to the Power Manager */ + PoSetPowerState(DeviceObject, IrpSp->Parameters.Power.Type, IrpSp->Parameters.Power.State); + break; + + default: + DPRINT1("PCMCIA: Invalid MN code in MJ_POWER handler %x\n", IrpSp->MinorFunction); + ASSERT(FALSE); + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +NTSTATUS +NTAPI +PcmciaAddDevice(PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT PhysicalDeviceObject) +{ + PPCMCIA_FDO_EXTENSION FdoExt; + PDEVICE_OBJECT Fdo; + NTSTATUS Status; + + DPRINT("PCMCIA: AddDevice\n"); + + Status = IoCreateDevice(DriverObject, + sizeof(*FdoExt), + NULL, + FILE_DEVICE_BUS_EXTENDER, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &Fdo); + if (!NT_SUCCESS(Status)) return Status; + + FdoExt = Fdo->DeviceExtension; + + RtlZeroMemory(FdoExt, sizeof(*FdoExt)); + + InitializeListHead(&FdoExt->ChildDeviceList); + KeInitializeSpinLock(&FdoExt->Lock); + + FdoExt->Common.Self = Fdo; + FdoExt->Common.IsFDO = TRUE; + FdoExt->Common.State = dsStopped; + + FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, + PhysicalDeviceObject); + + Fdo->Flags &= ~DO_DEVICE_INITIALIZING; + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +DriverEntry(PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + NTSTATUS Status; + + DPRINT1("PCMCIA: DriverEntry\n"); + + DriverObject->MajorFunction[IRP_MJ_CREATE] = PcmciaCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = PcmciaCreateClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PcmciaDeviceControl; + DriverObject->MajorFunction[IRP_MJ_PNP] = PcmciaPlugPlay; + DriverObject->MajorFunction[IRP_MJ_POWER] = PcmciaPower; + + DriverObject->DriverExtension->AddDevice = PcmciaAddDevice; + DriverObject->DriverUnload = PcmciaUnload; + + RtlZeroMemory(QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 2); + + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].Name = L"IoctlInterface"; + QueryTable[0].EntryContext = &IoctlEnabled; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, + L"Pcmcia\\Parameters", + QueryTable, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Key not present so assume disabled */ + IoctlEnabled = FALSE; + } + + DPRINT("PCMCIA: Ioctl interface %s\n", + (IoctlEnabled ? "enabled" : "disabled")); + + return STATUS_SUCCESS; +} diff --git a/drivers/bus/pcmcia/pcmcia.h b/drivers/bus/pcmcia/pcmcia.h new file mode 100644 index 00000000000..32dd5f28a06 --- /dev/null +++ b/drivers/bus/pcmcia/pcmcia.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +typedef enum { + dsStopped, + dsStarted, + dsPaused, + dsRemoved, + dsSurpriseRemoved +} PCMCIA_DEVICE_STATE; + +typedef struct _PCMCIA_COMMON_EXTENSION { + PDEVICE_OBJECT Self; + BOOLEAN IsFDO; + POWER_SEQUENCE PowerSequence; + PCMCIA_DEVICE_STATE State; + DEVICE_POWER_STATE DevicePowerState; + SYSTEM_POWER_STATE SystemPowerState; +} PCMCIA_COMMON_EXTENSION, *PPCMCIA_COMMON_EXTENSION; + +typedef struct _PCMCIA_PDO_EXTENSION { + PCMCIA_COMMON_EXTENSION Common; +} PCMCIA_PDO_EXTENSION, *PPCMCIA_PDO_EXTENSION; + +typedef struct _PCMCIA_FDO_EXTENSION { + PCMCIA_COMMON_EXTENSION Common; + PDEVICE_OBJECT Ldo; + LIST_ENTRY ChildDeviceList; + KSPIN_LOCK Lock; +} PCMCIA_FDO_EXTENSION, *PPCMCIA_FDO_EXTENSION; + +/* pdo.c */ +NTSTATUS +NTAPI +PcmciaPdoPlugPlay(PPCMCIA_PDO_EXTENSION PdoExt, + PIRP Irp); + +NTSTATUS +NTAPI +PcmciaPdoSetPowerState(PPCMCIA_PDO_EXTENSION PdoExt); + +/* fdo.c */ +NTSTATUS +NTAPI +PcmciaFdoPlugPlay(PPCMCIA_FDO_EXTENSION FdoExt, + PIRP Irp); + diff --git a/drivers/bus/pcmcia/pcmcia.rbuild b/drivers/bus/pcmcia/pcmcia.rbuild new file mode 100644 index 00000000000..2d33ce5dcd6 --- /dev/null +++ b/drivers/bus/pcmcia/pcmcia.rbuild @@ -0,0 +1,12 @@ + + + + + . + ntoskrnl + hal + fdo.c + pcmcia.c + pdo.c + pcmcia.rc + diff --git a/drivers/bus/pcmcia/pcmcia.rc b/drivers/bus/pcmcia/pcmcia.rc new file mode 100644 index 00000000000..13958160676 --- /dev/null +++ b/drivers/bus/pcmcia/pcmcia.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "PCMCIA Bus Driver\0" +#define REACTOS_STR_INTERNAL_NAME "pcmcia\0" +#define REACTOS_STR_ORIGINAL_FILENAME "pcmcia.sys\0" +#include diff --git a/drivers/bus/pcmcia/pdo.c b/drivers/bus/pcmcia/pdo.c new file mode 100644 index 00000000000..0e4d16886ee --- /dev/null +++ b/drivers/bus/pcmcia/pdo.c @@ -0,0 +1,34 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel + * FILE: drivers/bus/pcmcia/pdo.c + * PURPOSE: PCMCIA Bus Driver + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +//#define NDEBUG +#include + +NTSTATUS +NTAPI +PcmciaPdoPlugPlay(PPCMCIA_PDO_EXTENSION PdoExt, + PIRP Irp) +{ + UNIMPLEMENTED + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +NTAPI +PcmciaPdoSetPowerState(PPCMCIA_PDO_EXTENSION PdoExt) +{ + UNIMPLEMENTED + + return STATUS_SUCCESS; +} + diff --git a/drivers/ksfilter/ks/allocators.c b/drivers/ksfilter/ks/allocators.c index 3040a041837..5a4970f1b58 100644 --- a/drivers/ksfilter/ks/allocators.c +++ b/drivers/ksfilter/ks/allocators.c @@ -251,7 +251,7 @@ IKsAllocator_fnDeviceIoControl( } } - /* unhandeled request */ + /* unhandled request */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; IoCompleteRequest(Irp, IO_NO_INCREMENT); diff --git a/drivers/ksfilter/ks/api.c b/drivers/ksfilter/ks/api.c index ef83f9dbedf..2067de57648 100644 --- a/drivers/ksfilter/ks/api.c +++ b/drivers/ksfilter/ks/api.c @@ -94,6 +94,8 @@ KsReleaseDeviceSecurityLock( { PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; + DPRINT("KsReleaseDevice\n"); + ExReleaseResourceLite(&Header->SecurityLock); KeLeaveCriticalRegion(); } @@ -1589,7 +1591,7 @@ KsAcquireControl( /* sanity check */ ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); - KeWaitForSingleObject(&BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL); + KeWaitForSingleObject(BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL); } @@ -1606,7 +1608,7 @@ KsReleaseControl( /* sanity check */ ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); - KeReleaseMutex(&BasicHeader->ControlMutex, FALSE); + KeReleaseMutex(BasicHeader->ControlMutex, FALSE); } @@ -1623,11 +1625,11 @@ KsAcquireDevice( IKsDevice *KsDevice; PKSIDEVICE_HEADER DeviceHeader; - + DPRINT("KsAcquireDevice\n"); DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); /* get device interface*/ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* acquire device mutex */ KsDevice->lpVtbl->AcquireDevice(KsDevice); @@ -1645,7 +1647,7 @@ KsReleaseDevice( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); /* get device interface*/ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* release device mutex */ KsDevice->lpVtbl->ReleaseDevice(KsDevice); @@ -1668,7 +1670,7 @@ KsTerminateDevice( DeviceHeader = DeviceExtension->DeviceHeader; /* get device interface*/ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* now free device header */ KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); @@ -1958,7 +1960,7 @@ KsDeviceGetBusData( } /* - @unimplemented + @implemented */ KSDDKAPI void @@ -1969,7 +1971,12 @@ KsDeviceRegisterAdapterObject( IN ULONG MaxMappingsByteCount, IN ULONG MappingTableStride) { - UNIMPLEMENTED + PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); + + DeviceHeader->AdapterObject = AdapterObject; + DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount; + DeviceHeader->MappingTableStride = MappingTableStride; + } /* @@ -1982,6 +1989,7 @@ KsGetBusEnumIdentifier( IN PIRP Irp) { UNIMPLEMENTED + return STATUS_UNSUCCESSFUL; } @@ -2094,8 +2102,15 @@ KspCountMethodSets( if (!AutomationTableB) return AutomationTableA->MethodSetsCount; - /* sanity check */ - ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize); + + DPRINT("AutomationTableA MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableA->MethodItemSize, AutomationTableA->MethodSetsCount); + DPRINT("AutomationTableB MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableB->MethodItemSize, AutomationTableB->MethodSetsCount); + + if (AutomationTableA->MethodItemSize && AutomationTableB->MethodItemSize) + { + /* sanity check */ + ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize); + } /* now iterate all property sets and compare their guids */ Count = AutomationTableA->MethodSetsCount; @@ -2136,8 +2151,14 @@ KspCountEventSets( if (!AutomationTableB) return AutomationTableA->EventSetsCount; - /* sanity check */ - ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize); + DPRINT("AutomationTableA EventItemSize %lu EventSetsCount %lu\n", AutomationTableA->EventItemSize, AutomationTableA->EventSetsCount); + DPRINT("AutomationTableB EventItemSize %lu EventSetsCount %lu\n", AutomationTableB->EventItemSize, AutomationTableB->EventSetsCount); + + if (AutomationTableA->EventItemSize && AutomationTableB->EventItemSize) + { + /* sanity check */ + ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize); + } /* now iterate all Event sets and compare their guids */ Count = AutomationTableA->EventSetsCount; @@ -2180,6 +2201,8 @@ KspCountPropertySets( return AutomationTableA->PropertySetsCount; /* sanity check */ + DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount); + DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount); ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize); /* now iterate all property sets and compare their guids */ @@ -2219,18 +2242,18 @@ KspCopyMethodSets( if (!AutomationTableA) { /* copy of property set */ - RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, Table->MethodItemSize * AutomationTableB->MethodSetsCount); + RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableB->MethodSetsCount); return STATUS_SUCCESS; } else if (!AutomationTableB) { /* copy of property set */ - RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount); + RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount); return STATUS_SUCCESS; } /* first copy all property items from dominant table */ - RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount); + RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount); /* set counter */ Count = AutomationTableA->MethodSetsCount; @@ -2253,7 +2276,7 @@ KspCopyMethodSets( if (!bFound) { /* copy new property item set */ - RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], Table->MethodItemSize); + RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], sizeof(KSMETHOD_SET)); Count++; } } @@ -2274,18 +2297,18 @@ KspCopyPropertySets( if (!AutomationTableA) { /* copy of property set */ - RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, Table->PropertyItemSize * AutomationTableB->PropertySetsCount); + RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableB->PropertySetsCount); return STATUS_SUCCESS; } else if (!AutomationTableB) { /* copy of property set */ - RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount); + RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount); return STATUS_SUCCESS; } /* first copy all property items from dominant table */ - RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount); + RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount); /* set counter */ Count = AutomationTableA->PropertySetsCount; @@ -2308,7 +2331,7 @@ KspCopyPropertySets( if (!bFound) { /* copy new property item set */ - RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], Table->PropertyItemSize); + RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], sizeof(KSPROPERTY_SET)); Count++; } } @@ -2328,18 +2351,18 @@ KspCopyEventSets( if (!AutomationTableA) { /* copy of Event set */ - RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, Table->EventItemSize * AutomationTableB->EventSetsCount); + RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, sizeof(KSEVENT_SET) * AutomationTableB->EventSetsCount); return STATUS_SUCCESS; } else if (!AutomationTableB) { /* copy of Event set */ - RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount); + RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount); return STATUS_SUCCESS; } /* first copy all Event items from dominant table */ - RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount); + RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount); /* set counter */ Count = AutomationTableA->EventSetsCount; @@ -2362,7 +2385,7 @@ KspCopyEventSets( if (!bFound) { /* copy new Event item set */ - RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], Table->EventItemSize); + RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], sizeof(KSEVENT_SET)); Count++; } } @@ -2426,7 +2449,7 @@ KsMergeAutomationTables( } /* now allocate the property sets */ - Table->PropertySets = AllocateItem(NonPagedPool, Table->PropertyItemSize * Table->PropertySetsCount); + Table->PropertySets = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * Table->PropertySetsCount); if (!Table->PropertySets) { @@ -2469,7 +2492,7 @@ KsMergeAutomationTables( } /* now allocate the property sets */ - Table->MethodSets = AllocateItem(NonPagedPool, Table->MethodItemSize * Table->MethodSetsCount); + Table->MethodSets = AllocateItem(NonPagedPool, sizeof(KSMETHOD_SET) * Table->MethodSetsCount); if (!Table->MethodSets) { @@ -2512,7 +2535,7 @@ KsMergeAutomationTables( } /* now allocate the property sets */ - Table->EventSets = AllocateItem(NonPagedPool, Table->EventItemSize * Table->EventSetsCount); + Table->EventSets = AllocateItem(NonPagedPool, sizeof(KSEVENT_SET) * Table->EventSetsCount); if (!Table->EventSets) { @@ -2683,8 +2706,26 @@ KsRegisterAggregatedClientUnknown( IN PVOID Object, IN PUNKNOWN ClientUnknown) { - UNIMPLEMENTED - return NULL; + PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); + + /* sanity check */ + ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || + BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); + + if (BasicHeader->ClientAggregate) + { + /* release existing aggregate */ + BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate); + } + + /* increment reference count */ + ClientUnknown->lpVtbl->AddRef(ClientUnknown); + + /* store client aggregate */ + BasicHeader->ClientAggregate = ClientUnknown; + + /* return objects outer unknown */ + return BasicHeader->OuterUnknown; } /* diff --git a/drivers/ksfilter/ks/bag.c b/drivers/ksfilter/ks/bag.c index 1b7eec9bc5e..87f7a2bbef0 100644 --- a/drivers/ksfilter/ks/bag.c +++ b/drivers/ksfilter/ks/bag.c @@ -41,7 +41,7 @@ KsAllocateObjectBag( return STATUS_INSUFFICIENT_RESOURCES; /* get device interface */ - KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; /* initialize object bag */ return KsDevice->lpVtbl->InitializeObjectBag(KsDevice, Bag, NULL); @@ -89,6 +89,8 @@ KsAddItemToObjectBag( PKSIOBJECT_BAG Bag; PKSIOBJECT_BAG_ENTRY BagEntry; + DPRINT("KsAddItemToObjectBag\n"); + /* get real object bag */ Bag = (PKSIOBJECT_BAG)ObjectBag; @@ -363,6 +365,8 @@ _KsEdit( PVOID Item; NTSTATUS Status; + DPRINT("_KsEdit\n"); + /* get real object bag */ Bag = (PKSIOBJECT_BAG)ObjectBag; diff --git a/drivers/ksfilter/ks/clocks.c b/drivers/ksfilter/ks/clocks.c index 39611935076..05064be740a 100644 --- a/drivers/ksfilter/ks/clocks.c +++ b/drivers/ksfilter/ks/clocks.c @@ -21,20 +21,235 @@ typedef struct PFNKSSETTIMER SetTimer; PFNKSCANCELTIMER CancelTimer; PFNKSCORRELATEDTIME CorrelatedTime; - KSRESOLUTION* Resolution; + LONGLONG Granularity; + LONGLONG Error; ULONG Flags; }KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK; typedef struct { - IKsClock *lpVtbl; LONG ref; PKSCLOCK_CREATE ClockCreate; PKSIDEFAULTCLOCK DefaultClock; PKSIOBJECT_HEADER ObjectHeader; }KSICLOCK, *PKSICLOCK; +NTSTATUS NTAPI ClockPropertyTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyCorrelatedTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyResolution(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI ClockPropertyFunctionTable(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + +DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable, ClockPropertyTime, ClockPropertyPhysicalTime, ClockPropertyCorrelatedTime, ClockPropertyCorrelatedPhysicalTime, ClockPropertyResolution, ClockPropertyState, ClockPropertyFunctionTable); + +KSPROPERTY_SET ClockPropertySet[] = +{ + { + &KSPROPSETID_Clock, + sizeof(ClockPropertyTable) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&ClockPropertyTable, + 0, + NULL + } +}; + +LONGLONG +FASTCALL +ClockGetPhysicalTime( + IN PFILE_OBJECT FileObject) +{ + UNIMPLEMENTED + return 0; +} + +LONGLONG +FASTCALL +ClockGetCorrelatedTime( + IN PFILE_OBJECT FileObject, + OUT PLONGLONG SystemTime) +{ + UNIMPLEMENTED + return 0; +} + +LONGLONG +FASTCALL +ClockGetTime( + IN PFILE_OBJECT FileObject) +{ + UNIMPLEMENTED + return 0; +} + +LONGLONG +FASTCALL +ClockGetCorrelatedPhysicalTime( + IN PFILE_OBJECT FileObject, + OUT PLONGLONG SystemTime) +{ + UNIMPLEMENTED + return 0; +} + +NTSTATUS +NTAPI +ClockPropertyTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PLONGLONG Time = (PLONGLONG)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyTime\n"); + + *Time = ClockGetTime(IoStack->FileObject); + + Irp->IoStatus.Information = sizeof(LONGLONG); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyPhysicalTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PLONGLONG Time = (PLONGLONG)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyPhysicalTime\n"); + + *Time = ClockGetPhysicalTime(IoStack->FileObject); + + Irp->IoStatus.Information = sizeof(LONGLONG); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyCorrelatedTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyCorrelatedTime\n"); + + Time->Time = ClockGetCorrelatedTime(IoStack->FileObject, &Time->SystemTime); + + Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyCorrelatedPhysicalTime( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data; + PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("ClockPropertyCorrelatedPhysicalTime\n"); + + Time->Time = ClockGetCorrelatedPhysicalTime(IoStack->FileObject, &Time->SystemTime); + + Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyResolution( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSICLOCK Clock; + PKSIOBJECT_HEADER ObjectHeader; + PIO_STACK_LOCATION IoStack; + PKSRESOLUTION Resolution = (PKSRESOLUTION)Data; + + DPRINT("ClockPropertyResolution\n"); + + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* sanity check */ + ASSERT(ObjectHeader); + + /* locate ks pin implemention from KSPIN offset */ + Clock = (PKSICLOCK)ObjectHeader->ObjectType; + + Resolution->Error = Clock->DefaultClock->Error; + Resolution->Granularity = Clock->DefaultClock->Granularity; + + Irp->IoStatus.Information = sizeof(KSRESOLUTION); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyState( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSICLOCK Clock; + PKSIOBJECT_HEADER ObjectHeader; + PKSSTATE State = (PKSSTATE)Data; + PIO_STACK_LOCATION IoStack; + + DPRINT("ClockPropertyState\n"); + + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* sanity check */ + ASSERT(ObjectHeader); + + /* locate ks pin implemention from KSPIN offset */ + Clock = (PKSICLOCK)ObjectHeader->ObjectType; + + *State = Clock->DefaultClock->State; + Irp->IoStatus.Information = sizeof(KSSTATE); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +ClockPropertyFunctionTable( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PKSCLOCK_FUNCTIONTABLE Table = (PKSCLOCK_FUNCTIONTABLE)Data; + + DPRINT("ClockPropertyFunctionTable\n"); + + Table->GetCorrelatedPhysicalTime = ClockGetCorrelatedPhysicalTime; + Table->GetCorrelatedTime = ClockGetCorrelatedTime; + Table->GetPhysicalTime = ClockGetPhysicalTime; + Table->GetTime = ClockGetTime; + + return STATUS_SUCCESS; +} + /* @implemented @@ -96,12 +311,37 @@ IKsClock_DispatchDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED + PIO_STACK_LOCATION IoStack; + UNICODE_STRING GuidString; + PKSPROPERTY Property; + NTSTATUS Status; - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + DPRINT("IKsClock_DispatchDeviceIoControl\n"); + + /* get current io stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* FIXME support events */ + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY); + + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY)); + + /* call property handler */ + Status = KsPropertyHandler(Irp, 1, ClockPropertySet); + + /* get property from input buffer */ + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT("IKsClock_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information); + RtlFreeUnicodeString(&GuidString); + + + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; } NTSTATUS @@ -112,14 +352,12 @@ IKsClock_DispatchClose( { UNIMPLEMENTED - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + return STATUS_SUCCESS; } - - static KSDISPATCH_TABLE DispatchTable = { IKsClock_DispatchDeviceIoControl, @@ -147,7 +385,6 @@ KsCreateDefaultClock( NTSTATUS Status; PKSCLOCK_CREATE ClockCreate; PKSICLOCK Clock; - PKSOBJECT_CREATE_ITEM CreateItem; Status = KsValidateClockCreateRequest(Irp, &ClockCreate); if (!NT_SUCCESS(Status)) @@ -171,7 +408,7 @@ KsCreateDefaultClock( /* initialize clock */ /* FIXME IKsClock */ - Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl; + Clock->ObjectHeader->ObjectType = (PVOID)Clock; Clock->ref = 1; Clock->ClockCreate = ClockCreate; Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock; @@ -179,9 +416,6 @@ KsCreateDefaultClock( /* increment reference count */ InterlockedIncrement(&Clock->DefaultClock->ReferenceCount); - /* get create item */ - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - return Status; } @@ -230,9 +464,21 @@ KsAllocateDefaultClockEx( Clock->SetTimer = SetTimer; Clock->CancelTimer = CancelTimer; Clock->CorrelatedTime = CorrelatedTime; - Clock->Resolution = (PKSRESOLUTION)Resolution; Clock->Flags = Flags; + if (Resolution) + { + if (SetTimer) + { + Clock->Error = Resolution->Error; + } + + if (CorrelatedTime) + { + Clock->Granularity = Resolution->Granularity; + } + } + *DefaultClock = (PKSDEFAULTCLOCK)Clock; return STATUS_SUCCESS; } diff --git a/drivers/ksfilter/ks/connectivity.c b/drivers/ksfilter/ks/connectivity.c index 7c9b8226de2..bcc55cc6f1f 100644 --- a/drivers/ksfilter/ks/connectivity.c +++ b/drivers/ksfilter/ks/connectivity.c @@ -23,6 +23,7 @@ KSPIN_MEDIUM StandardPinMedium = 0 }; +const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}}; /* @implemented @@ -53,16 +54,12 @@ KsCreatePin( ConnectionHandle); } -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS -NTAPI -KsValidateConnectRequest( - IN PIRP Irp, - IN ULONG DescriptorsCount, - IN KSPIN_DESCRIPTOR* Descriptor, +KspValidateConnectRequest( + IN PIRP Irp, + IN ULONG DescriptorsCount, + IN PVOID Descriptors, + IN ULONG DescriptorSize, OUT PKSPIN_CONNECT* Connect) { PKSPIN_CONNECT ConnectDetails; @@ -73,6 +70,7 @@ KsValidateConnectRequest( ULONG Index; ULONG Count; BOOLEAN Found; + PKSPIN_DESCRIPTOR Descriptor; /* did the caller miss the connect parameter */ if (!Connect) @@ -95,12 +93,24 @@ KsValidateConnectRequest( if (ConnectDetails->PinId >= DescriptorsCount) return STATUS_INVALID_PARAMETER; + if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) + { + /* standard pin descriptor */ + Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId); + } + else + { + /* extended / variable pin descriptor */ + Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor; + } + + /* does the pin have interface details filled in */ - if (Descriptor[ConnectDetails->PinId].InterfacesCount && Descriptor[ConnectDetails->PinId].Interfaces) + if (Descriptor->InterfacesCount && Descriptor->Interfaces) { /* use provided pin interface count */ - Count = Descriptor[ConnectDetails->PinId].InterfacesCount; - Interface = (PKSPIN_INTERFACE)Descriptor[ConnectDetails->PinId].Interfaces; + Count = Descriptor->InterfacesCount; + Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces; } else { @@ -114,6 +124,13 @@ KsValidateConnectRequest( Index = 0; do { + UNICODE_STRING GuidString, GuidString2; + RtlStringFromGUID(&Interface[Index].Set, &GuidString); + RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2); + + DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id); + DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id); + if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) && Interface[Index].Id == ConnectDetails->Interface.Id) { @@ -132,11 +149,11 @@ KsValidateConnectRequest( } /* does the pin have medium details filled in */ - if (Descriptor[ConnectDetails->PinId].MediumsCount && Descriptor[ConnectDetails->PinId].Mediums) + if (Descriptor->MediumsCount && Descriptor->Mediums) { /* use provided pin interface count */ - Count = Descriptor[ConnectDetails->PinId].MediumsCount; - Medium = (PKSPIN_MEDIUM)Descriptor[ConnectDetails->PinId].Mediums; + Count = Descriptor->MediumsCount; + Medium = (PKSPIN_MEDIUM)Descriptor->Mediums; } else { @@ -150,6 +167,14 @@ KsValidateConnectRequest( Index = 0; do { + UNICODE_STRING GuidString, GuidString2; + RtlStringFromGUID(&Medium[Index].Set, &GuidString); + RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2); + + DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id); + DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id); + + if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) && Medium[Index].Id == ConnectDetails->Medium.Id) { @@ -157,6 +182,9 @@ KsValidateConnectRequest( Found = TRUE; break; } + + + /* iterate to next medium */ Index++; }while(Index < Count); @@ -174,6 +202,20 @@ KsValidateConnectRequest( return STATUS_SUCCESS; } +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsValidateConnectRequest( + IN PIRP Irp, + IN ULONG DescriptorsCount, + IN KSPIN_DESCRIPTOR* Descriptor, + OUT PKSPIN_CONNECT* Connect) +{ + return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect); +} NTSTATUS KspReadMediaCategory( @@ -265,18 +307,16 @@ KspReadMediaCategory( return Status; } -/* - @implemented -*/ KSDDKAPI NTSTATUS NTAPI -KsPinPropertyHandler( +KspPinPropertyHandler( IN PIRP Irp, IN PKSPROPERTY Property, IN OUT PVOID Data, IN ULONG DescriptorsCount, - IN const KSPIN_DESCRIPTOR* Descriptor) + IN const KSPIN_DESCRIPTOR* Descriptors, + IN ULONG DescriptorSize) { KSP_PIN * Pin; KSMULTIPLE_ITEM * Item; @@ -286,12 +326,38 @@ KsPinPropertyHandler( PKSDATARANGE_AUDIO *WaveFormatOut; PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn; PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; + const KSPIN_DESCRIPTOR *Descriptor; NTSTATUS Status = STATUS_NOT_SUPPORTED; + ULONG Count; + const PKSDATARANGE* DataRanges; IoStack = IoGetCurrentIrpStackLocation(Irp); Buffer = Irp->UserBuffer; - DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id); + //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id); + + /* convert to PKSP_PIN */ + Pin = (KSP_PIN*)Property; + + if (Property->Id != KSPROPERTY_PIN_CTYPES) + { + if (Pin->PinId >= DescriptorsCount) + { + /* invalid parameter */ + return STATUS_INVALID_PARAMETER; + } + } + + if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) + { + /* it is simple pin descriptor */ + Descriptor = &Descriptors[Pin->PinId]; + } + else + { + /* get offset to pin descriptor */ + Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor); + } switch(Property->Id) { @@ -301,13 +367,7 @@ KsPinPropertyHandler( Status = STATUS_SUCCESS; break; case KSPROPERTY_PIN_DATAFLOW: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } + Size = sizeof(KSPIN_DATAFLOW); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) { @@ -316,23 +376,31 @@ KsPinPropertyHandler( break; } - *((KSPIN_DATAFLOW*)Buffer) = Descriptor[Pin->PinId].DataFlow; + *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow; Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW); Status = STATUS_SUCCESS; break; case KSPROPERTY_PIN_DATARANGES: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } + case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: + Size = sizeof(KSMULTIPLE_ITEM); - for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++) + DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount); + + if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0) { - Size += Descriptor[Pin->PinId].DataRanges[Index]->FormatSize; + DataRanges = Descriptor->DataRanges; + Count = Descriptor->DataRangesCount; + } + else + { + DataRanges = Descriptor->ConstrainedDataRanges; + Count = Descriptor->ConstrainedDataRangesCount; + } + + for (Index = 0; Index < Count; Index++) + { + Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7); } if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) @@ -354,16 +422,9 @@ KsPinPropertyHandler( break; } - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSMULTIPLE_ITEM)) - { - /* buffer too small */ - Status = STATUS_BUFFER_TOO_SMALL; - break; - } - /* store descriptor size */ Item->Size = Size; - Item->Count = Descriptor[Pin->PinId].DataRangesCount; + Item->Count = Count; if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM)) { @@ -374,28 +435,40 @@ KsPinPropertyHandler( /* now copy all dataranges */ Data = (PUCHAR)(Item +1); - for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++) + + /* alignment assert */ + ASSERT(((ULONG_PTR)Data & 0x7) == 0); + + for (Index = 0; Index < Count; Index++) { - RtlMoveMemory(Data, Descriptor[Pin->PinId].DataRanges[Index], Descriptor[Pin->PinId].DataRanges[Index]->FormatSize); - Data = ((PUCHAR)Data + Descriptor[Pin->PinId].DataRanges[Index]->FormatSize); + UNICODE_STRING GuidString; + /* convert the guid to string */ + RtlStringFromGUID(&DataRanges[Index]->MajorFormat, &GuidString); + DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&DataRanges[Index]->SubFormat, &GuidString); + DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index, + DataRanges[Index]->FormatSize, DataRanges[Index]->Flags, DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT)); + + RtlMoveMemory(Data, DataRanges[Index], DataRanges[Index]->FormatSize); + Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize); + /* alignment assert */ + ASSERT(((ULONG_PTR)Data & 0x7) == 0); + Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7); } Status = STATUS_SUCCESS; Irp->IoStatus.Information = Size; break; case KSPROPERTY_PIN_INTERFACES: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } - if (Descriptor[Pin->PinId].Interfaces) + if (Descriptor->Interfaces) { /* use mediums provided by driver */ - return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Interfaces); + return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces); } else { @@ -405,18 +478,11 @@ KsPinPropertyHandler( break; case KSPROPERTY_PIN_MEDIUMS: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } - if (Descriptor[Pin->PinId].MediumsCount) + if (Descriptor->MediumsCount) { /* use mediums provided by driver */ - return KsHandleSizedListQuery(Irp, Descriptor[Pin->PinId].MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor[Pin->PinId].Mediums); + return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums); } else { @@ -426,13 +492,6 @@ KsPinPropertyHandler( break; case KSPROPERTY_PIN_COMMUNICATION: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } Size = sizeof(KSPIN_COMMUNICATION); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) @@ -442,19 +501,13 @@ KsPinPropertyHandler( break; } - *((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication; + *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication; + Status = STATUS_SUCCESS; Irp->IoStatus.Information = Size; break; case KSPROPERTY_PIN_CATEGORY: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } Size = sizeof(GUID); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) @@ -463,9 +516,9 @@ KsPinPropertyHandler( Status = STATUS_BUFFER_TOO_SMALL; break; } - if (Descriptor[Pin->PinId].Category) + if (Descriptor->Category) { - RtlMoveMemory(Buffer, Descriptor[Pin->PinId].Category, sizeof(GUID)); + RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID)); } Status = STATUS_SUCCESS; @@ -473,29 +526,20 @@ KsPinPropertyHandler( break; case KSPROPERTY_PIN_NAME: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } - - if (!Descriptor[Pin->PinId].Name) + if (!Descriptor->Name) { Irp->IoStatus.Information = 0; Status = STATUS_SUCCESS; break; } - Status = KspReadMediaCategory((LPGUID)Descriptor[Pin->PinId].Name, &KeyInfo); + Status = KspReadMediaCategory((LPGUID)Descriptor->Name, &KeyInfo); if (!NT_SUCCESS(Status)) { Irp->IoStatus.Information = 0; break; } - Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR); if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength) @@ -510,13 +554,6 @@ KsPinPropertyHandler( ExFreePool(KeyInfo); break; case KSPROPERTY_PIN_PROPOSEDATAFORMAT: - Pin = (KSP_PIN*)Property; - if (Pin->PinId >= DescriptorsCount) - { - Status = STATUS_INVALID_PARAMETER; - Irp->IoStatus.Information = 0; - break; - } Size = sizeof(KSDATAFORMAT); if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) { @@ -533,14 +570,14 @@ KsPinPropertyHandler( } WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer; - if (!Descriptor[Pin->PinId].DataRanges || !Descriptor[Pin->PinId].DataRangesCount) + if (!Descriptor->DataRanges || !Descriptor->DataRangesCount) { Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; break; } - WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor[Pin->PinId].DataRanges; - for(Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++) + WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges; + for(Index = 0; Index < Descriptor->DataRangesCount; Index++) { if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO)) { @@ -577,6 +614,22 @@ KsPinPropertyHandler( return Status; } +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsPinPropertyHandler( + IN PIRP Irp, + IN PKSPROPERTY Property, + IN OUT PVOID Data, + IN ULONG DescriptorsCount, + IN const KSPIN_DESCRIPTOR* Descriptor) +{ + return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR)); +} + /* @unimplemented */ diff --git a/drivers/ksfilter/ks/device.c b/drivers/ksfilter/ks/device.c index 345689f49b8..432548c6d91 100644 --- a/drivers/ksfilter/ks/device.c +++ b/drivers/ksfilter/ks/device.c @@ -16,15 +16,29 @@ IKsDevice_fnQueryInterface( REFIID refiid, PVOID* Output) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + NTSTATUS Status; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtblIKsDevice; + *Output = &This->BasicHeader.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } + if (This->BasicHeader.ClientAggregate) + { + /* using client aggregate */ + Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsDevice_fnQueryInterface no interface\n"); return STATUS_NOT_SUPPORTED; } @@ -33,7 +47,7 @@ NTAPI IKsDevice_fnAddRef( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -43,7 +57,7 @@ NTAPI IKsDevice_fnRelease( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); InterlockedDecrement(&This->ref); @@ -57,7 +71,7 @@ NTAPI IKsDevice_fnGetStruct( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return &This->KsDevice; } @@ -69,7 +83,7 @@ IKsDevice_fnInitializeObjectBag( IN PKSIOBJECT_BAG Bag, IN PRKMUTEX Mutex) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); if (!Mutex) { @@ -93,7 +107,7 @@ NTAPI IKsDevice_fnAcquireDevice( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL); } @@ -103,7 +117,7 @@ NTAPI IKsDevice_fnReleaseDevice( IN IKsDevice * iface) { - PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); return KeReleaseMutex(&This->DeviceMutex, FALSE); } @@ -112,14 +126,17 @@ NTSTATUS NTAPI IKsDevice_fnGetAdapterObject( IN IKsDevice * iface, - IN PADAPTER_OBJECT Object, - IN PULONG Unknown1, - IN PULONG Unknown2) + IN PADAPTER_OBJECT * Object, + IN PULONG MaxMappingsByteCount, + IN PULONG MappingTableStride) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + *Object = This->AdapterObject; + *MaxMappingsByteCount = This->MaxMappingsByteCount; + *MappingTableStride = This->MappingTableStride; + + return STATUS_SUCCESS; } @@ -130,7 +147,7 @@ IKsDevice_fnAddPowerEntry( IN struct KSPOWER_ENTRY * Entry, IN IKsPowerNotify* Notify) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -142,7 +159,7 @@ IKsDevice_fnRemovePowerEntry( IN IKsDevice * iface, IN struct KSPOWER_ENTRY * Entry) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -158,7 +175,7 @@ IKsDevice_fnPinStateChange( IN KSSTATE OldState, IN KSSTATE NewState) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -169,15 +186,24 @@ NTSTATUS NTAPI IKsDevice_fnArbitrateAdapterChannel( IN IKsDevice * iface, - IN ULONG ControlCode, - IN IO_ALLOCATION_ACTION Action, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); + NTSTATUS Status; - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql()); + /* sanity check */ + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(This->AdapterObject); + + /* allocate adapter channel */ + Status = IoAllocateAdapterChannel(This->AdapterObject, This->KsDevice.FunctionalDeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context); + + /* done */ + return Status; } NTSTATUS @@ -186,7 +212,7 @@ IKsDevice_fnCheckIoCapability( IN IKsDevice * iface, IN ULONG Unknown) { - //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; @@ -492,7 +518,7 @@ IKsDevice_Pnp( } case IRP_MN_QUERY_INTERFACE: { - Status = STATUS_SUCCESS; + Status = STATUS_UNSUCCESSFUL; /* check for pnp notification support */ if (Dispatch) { @@ -508,6 +534,7 @@ IKsDevice_Pnp( if (NT_SUCCESS(Status)) { /* driver supports a private interface */ + DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n"); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; @@ -517,7 +544,6 @@ IKsDevice_Pnp( Status = KspForwardIrpSynchronous(DeviceObject, Irp); DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status); - Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; @@ -557,8 +583,12 @@ IKsDevice_Pnp( } default: DPRINT1("unhandled function %u\n", IoStack->MinorFunction); + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_SUPPORTED; + return Status; } } @@ -601,7 +631,7 @@ IKsDevice_Create( DeviceHeader = DeviceExtension->DeviceHeader; /* acquire list lock */ - IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); /* sanity check */ ASSERT(IoStack->FileObject); @@ -640,7 +670,7 @@ IKsDevice_Create( } /* acquire list lock */ - IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); if (Status != STATUS_PENDING) { @@ -686,6 +716,23 @@ KsInitializeDevice( DPRINT("DeviceHeader %p\n", DeviceExtension->DeviceHeader); + if (Descriptor && Descriptor->Dispatch) + { + DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add); + DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start); + DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart); + DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop); + DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop); + DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop); + DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove); + DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove); + DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove); + DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities); + DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval); + DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower); + DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower); + DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface); + } /* check for success */ if (!NT_SUCCESS(Status)) @@ -695,7 +742,7 @@ KsInitializeDevice( } /* initialize IKsDevice interface */ - Header->lpVtblIKsDevice = &vt_IKsDevice; + Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice; Header->ref = 1; /* allocate object bag */ @@ -779,7 +826,7 @@ KsReferenceSoftwareBusObject( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { @@ -803,7 +850,7 @@ KsReferenceBusObject( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { @@ -828,7 +875,7 @@ KsDereferenceBusObject( PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { @@ -852,7 +899,7 @@ KsDereferenceSoftwareBusObject( DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header); /* get device interface */ - Device = (IKsDevice*)DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; if (Device) { diff --git a/drivers/ksfilter/ks/deviceinterface.c b/drivers/ksfilter/ks/deviceinterface.c index cd0ffe274bb..c1fdff8470b 100644 --- a/drivers/ksfilter/ks/deviceinterface.c +++ b/drivers/ksfilter/ks/deviceinterface.c @@ -90,6 +90,10 @@ KspRegisterDeviceInterfaces( /* return result */ return Status; } + + /* copy device class */ + RtlMoveMemory(&SymEntry->DeviceInterfaceClass, &Categories[Index], sizeof(CLSID)); + /* insert symbolic link entry */ InsertTailList(SymbolicLinkList, &SymEntry->Entry); } diff --git a/drivers/ksfilter/ks/driver.c b/drivers/ksfilter/ks/driver.c index 409977d63d5..c0195a4a97f 100644 --- a/drivers/ksfilter/ks/driver.c +++ b/drivers/ksfilter/ks/driver.c @@ -39,10 +39,19 @@ KsGetDevice( { PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); - DPRINT("KsGetDevice %p BasicHeader %p Type %x\n", Object, BasicHeader, BasicHeader->Type); + DPRINT("KsGetDevice Type %lu KsDevice %p\n", BasicHeader->Type, BasicHeader->KsDevice); - ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == BasicHeader->Type); + ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); ASSERT(BasicHeader->KsDevice); + ASSERT(BasicHeader->KsDevice->Descriptor); + ASSERT(BasicHeader->KsDevice->Bag); + ASSERT(BasicHeader->KsDevice->Context); + ASSERT(BasicHeader->KsDevice->FunctionalDeviceObject); + ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject); + ASSERT(BasicHeader->KsDevice->NextDeviceObject); + ASSERT(BasicHeader->KsDevice->Started); + ASSERT(BasicHeader->KsDevice->SystemPowerState == PowerSystemWorking); + ASSERT(BasicHeader->KsDevice->DevicePowerState == PowerDeviceD0); return BasicHeader->KsDevice; } @@ -152,6 +161,8 @@ KsInitializeDriver( PKS_DRIVER_EXTENSION DriverObjectExtension; NTSTATUS Status = STATUS_SUCCESS; + DPRINT("KsInitializeDriver\n"); + if (Descriptor) { Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)KsInitializeDriver, sizeof(KS_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension); diff --git a/drivers/ksfilter/ks/filter.c b/drivers/ksfilter/ks/filter.c index 5d06ca2f49d..5f4a74b9b64 100644 --- a/drivers/ksfilter/ks/filter.c +++ b/drivers/ksfilter/ks/filter.c @@ -14,18 +14,15 @@ typedef struct KSBASIC_HEADER Header; KSFILTER Filter; - IKsFilterVtbl *lpVtbl; IKsControlVtbl *lpVtblKsControl; IKsFilterFactory * FilterFactory; LONG ref; PKSIOBJECT_HEADER ObjectHeader; KSTOPOLOGY Topology; - KSPIN_DESCRIPTOR_EX * PinDescriptorsEx; - KSPIN_DESCRIPTOR * PinDescriptors; - ULONG PinDescriptorCount; PKSFILTERFACTORY Factory; PFILE_OBJECT FileObject; + KMUTEX ControlMutex; KMUTEX ProcessingMutex; @@ -34,7 +31,7 @@ typedef struct ULONG *PinInstanceCount; PKSPIN * FirstPin; - KSPROCESSPIN_INDEXENTRY ProcessPinIndex; + PKSPROCESSPIN_INDEXENTRY ProcessPinIndex; }IKsFilterImpl; @@ -43,9 +40,17 @@ const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; +VOID +IKsFilter_RemoveFilterFromFilterFactory( + IKsFilterImpl * This, + PKSFILTERFACTORY FilterFactory); -DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler); -DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler); +NTSTATUS NTAPI FilterTopologyPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI FilterPinPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + + +DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, FilterTopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, FilterPinPropertyHandler, FilterPinPropertyHandler, FilterPinPropertyHandler); KSPROPERTY_SET FilterPropertySet[] = { @@ -76,7 +81,7 @@ IKsControl_fnQueryInterface( if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtbl; + *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } @@ -179,12 +184,13 @@ IKsFilter_fnQueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + NTSTATUS Status; + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || IsEqualGUIDAligned(refiid, &IID_IKsFilter)) { - *Output = &This->lpVtbl; + *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } @@ -195,7 +201,20 @@ IKsFilter_fnQueryInterface( return STATUS_SUCCESS; } - return STATUS_UNSUCCESSFUL; + if (This->Header.ClientAggregate) + { + /* using client aggregate */ + Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsFilter_fnQueryInterface no interface\n"); + return STATUS_NOT_SUPPORTED; } ULONG @@ -203,7 +222,7 @@ NTAPI IKsFilter_fnAddRef( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -213,7 +232,7 @@ NTAPI IKsFilter_fnRelease( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); InterlockedDecrement(&This->ref); @@ -232,7 +251,7 @@ NTAPI IKsFilter_fnGetStruct( IKsFilter * iface) { - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); return &This->Filter; } @@ -289,23 +308,25 @@ IKsFilter_fnAddProcessPin( IN PKSPROCESSPIN ProcessPin) { NTSTATUS Status; - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); /* first acquire processing mutex */ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); - /* edit process pin descriptor */ - Status = _KsEdit(This->Filter.Bag, - (PVOID*)&This->ProcessPinIndex.Pins, - (This->ProcessPinIndex.Count + 1) * sizeof(PKSPROCESSPIN), - (This->ProcessPinIndex.Count) * sizeof(PKSPROCESSPIN), + /* sanity check */ + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > ProcessPin->Pin->Id); + + /* allocate new process pin array */ + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex[ProcessPin->Pin->Id].Pins, + (This->Filter.Descriptor->PinDescriptorsCount + 1) * sizeof(PKSPROCESSPIN), + This->Filter.Descriptor->PinDescriptorsCount * sizeof(PKSPROCESSPIN), 0); if (NT_SUCCESS(Status)) { - /* add new process pin */ - This->ProcessPinIndex.Pins[This->ProcessPinIndex.Count] = ProcessPin; - This->ProcessPinIndex.Count++; + /* store process pin */ + This->ProcessPinIndex[ProcessPin->Pin->Id].Pins[This->ProcessPinIndex[ProcessPin->Pin->Id].Count] = ProcessPin; + This->ProcessPinIndex[ProcessPin->Pin->Id].Count++; } /* release process mutex */ @@ -321,25 +342,39 @@ IKsFilter_fnRemoveProcessPin( IN PKSPROCESSPIN ProcessPin) { ULONG Index; - IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + ULONG Count; + PKSPROCESSPIN * Pins; + + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); /* first acquire processing mutex */ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL); - /* iterate through process pin index array and search for the process pin to be removed */ - for(Index = 0; Index < This->ProcessPinIndex.Count; Index++) + /* sanity check */ + ASSERT(ProcessPin->Pin); + ASSERT(ProcessPin->Pin->Id); + + Count = This->ProcessPinIndex[ProcessPin->Pin->Id].Count; + Pins = This->ProcessPinIndex[ProcessPin->Pin->Id].Pins; + + /* search for current process pin */ + for(Index = 0; Index < Count; Index++) { - if (This->ProcessPinIndex.Pins[Index] == ProcessPin) + if (Pins[Index] == ProcessPin) { - /* found process pin */ - if (Index + 1 < This->ProcessPinIndex.Count) - { - /* erase entry */ - RtlMoveMemory(&This->ProcessPinIndex.Pins[Index], &This->ProcessPinIndex.Pins[Index+1], This->ProcessPinIndex.Count - Index - 1); - } - /* decrement process pin count */ - This->ProcessPinIndex.Count--; + RtlMoveMemory(&Pins[Index], &Pins[Index + 1], (Count - (Index + 1)) * sizeof(PKSPROCESSPIN)); + break; } + + } + + /* decrement pin count */ + This->ProcessPinIndex[ProcessPin->Pin->Id].Count--; + + if (!This->ProcessPinIndex[ProcessPin->Pin->Id].Count) + { + /* clear entry object bag will delete it */ + This->ProcessPinIndex[ProcessPin->Pin->Id].Pins = NULL; } /* release process mutex */ @@ -394,8 +429,9 @@ NTAPI IKsFilter_fnGetProcessDispatch( IKsFilter * iface) { - UNIMPLEMENTED - return NULL; + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, Header.OuterUnknown); + + return This->ProcessPinIndex; } static IKsFilterVtbl vt_IKsFilter = @@ -472,13 +508,13 @@ IKsFilter_DispatchClose( return Status; /* get our real implementation */ - This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl); + This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); /* does the driver support notifications */ - if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close) + if (This->Filter.Descriptor && This->Filter.Descriptor->Dispatch && This->Filter.Descriptor->Dispatch->Close) { /* call driver's filter close function */ - Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp); + Status = This->Filter.Descriptor->Dispatch->Close(&This->Filter, Irp); } if (NT_SUCCESS(Status) && Status != STATUS_PENDING) @@ -488,8 +524,8 @@ IKsFilter_DispatchClose( /* complete irp */ IoCompleteRequest(Irp, IO_NO_INCREMENT); - /* FIXME remove our instance from the filter factory */ - ASSERT(0); + /* remove our instance from the filter factory */ + IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory); /* free object header */ KsFreeObjectHeader(This->ObjectHeader); @@ -517,7 +553,7 @@ KspHandlePropertyInstances( KSPIN_CINSTANCES * Instances; KSP_PIN * Pin = (KSP_PIN*)Request; - if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) + if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) { /* no filter / pin descriptor */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -525,12 +561,12 @@ KspHandlePropertyInstances( } /* ignore custom structs for now */ - ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - ASSERT(This->PinDescriptorCount > Pin->PinId); + ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); Instances = (KSPIN_CINSTANCES*)Data; /* max instance count */ - Instances->PossibleCount = This->PinDescriptorsEx[Pin->PinId].InstancesPossible; + Instances->PossibleCount = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesPossible; /* current instance count */ Instances->CurrentCount = This->PinInstanceCount[Pin->PinId]; @@ -549,7 +585,7 @@ KspHandleNecessaryPropertyInstances( PULONG Result; KSP_PIN * Pin = (KSP_PIN*)Request; - if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) + if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) { /* no filter / pin descriptor */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -557,11 +593,11 @@ KspHandleNecessaryPropertyInstances( } /* ignore custom structs for now */ - ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - ASSERT(This->PinDescriptorCount > Pin->PinId); + ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); Result = (PULONG)Data; - *Result = This->PinDescriptorsEx[Pin->PinId].InstancesNecessary; + *Result = This->Filter.Descriptor->PinDescriptors[Pin->PinId].InstancesNecessary; IoStatus->Information = sizeof(ULONG); IoStatus->Status = STATUS_SUCCESS; @@ -581,13 +617,23 @@ KspHandleDataIntersection( PKSDATARANGE DataRange; NTSTATUS Status = STATUS_NO_MATCH; ULONG Index, Length; + PIO_STACK_LOCATION IoStack; KSP_PIN * Pin = (KSP_PIN*)Request; + /* get stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* sanity check */ + ASSERT(DataLength == IoStack->Parameters.DeviceIoControl.OutputBufferLength); + /* Access parameters */ MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); DataRange = (PKSDATARANGE)(MultipleItem + 1); - if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) + /* FIXME make sure its 64 bit aligned */ + ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); + + if (!This->Filter.Descriptor || !This->Filter.Descriptor->PinDescriptorsCount) { /* no filter / pin descriptor */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -595,12 +641,12 @@ KspHandleDataIntersection( } /* ignore custom structs for now */ - ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - ASSERT(This->PinDescriptorCount > Pin->PinId); + ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Filter.Descriptor->PinDescriptorsCount > Pin->PinId); - if (This->PinDescriptorsEx[Pin->PinId].IntersectHandler == NULL || - This->PinDescriptors[Pin->PinId].DataRanges == NULL || - This->PinDescriptors[Pin->PinId].DataRangesCount == 0) + if (This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL || + This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL || + This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0) { /* no driver supported intersect handler / no provided data ranges */ IoStatus->Status = STATUS_NOT_IMPLEMENTED; @@ -609,31 +655,65 @@ KspHandleDataIntersection( for(Index = 0; Index < MultipleItem->Count; Index++) { - /* Call miniport's properitary handler */ - Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(NULL, /* context */ - Irp, - Pin, - DataRange, - (PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges, - DataLength, - Data, - &Length); + UNICODE_STRING MajorFormat, SubFormat, Specifier; + /* convert the guid to string */ + RtlStringFromGUID(&DataRange->MajorFormat, &MajorFormat); + RtlStringFromGUID(&DataRange->SubFormat, &SubFormat); + RtlStringFromGUID(&DataRange->Specifier, &Specifier); - if (Status == STATUS_SUCCESS) + DPRINT("KspHandleDataIntersection Index %lu PinId %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index, Pin->PinId, MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer, + DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment, DataRange->Flags, DataRange->Reserved, DataLength); + + /* FIXME implement KsPinDataIntersectionEx */ + /* Call miniport's properitary handler */ + Status = This->Filter.Descriptor->PinDescriptors[Pin->PinId].IntersectHandler(&This->Filter, + Irp, + Pin, + DataRange, + This->Filter.Descriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */ + DataLength, + Data, + &Length); + DPRINT("KspHandleDataIntersection Status %lx\n", Status); + + if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { + ASSERT(Length); IoStatus->Information = Length; break; } - DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); - } + DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); + /* FIXME make sure its 64 bit aligned */ + ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); + } IoStatus->Status = Status; return Status; } NTSTATUS NTAPI -KspPinPropertyHandler( +FilterTopologyPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + IKsFilterImpl * This; + + /* get filter implementation */ + This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + /* sanity check */ + ASSERT(This); + + return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology); + +} + + +NTSTATUS +NTAPI +FilterPinPropertyHandler( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) @@ -645,6 +725,9 @@ KspPinPropertyHandler( /* get filter implementation */ This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + /* sanity check */ + ASSERT(This); + /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -658,8 +741,8 @@ KspPinPropertyHandler( case KSPROPERTY_PIN_COMMUNICATION: case KSPROPERTY_PIN_CATEGORY: case KSPROPERTY_PIN_NAME: - case KSPROPERTY_PIN_PROPOSEDATAFORMAT: - Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors); + case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: + Status = KspPinPropertyHandler(Irp, Request, Data, This->Filter.Descriptor->PinDescriptorsCount, (const KSPIN_DESCRIPTOR*)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize); break; case KSPROPERTY_PIN_GLOBALCINSTANCES: Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE); @@ -674,16 +757,11 @@ KspPinPropertyHandler( case KSPROPERTY_PIN_DATAINTERSECTION: Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This); break; - case KSPROPERTY_PIN_PHYSICALCONNECTION: - case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: - UNIMPLEMENTED - Status = STATUS_NOT_IMPLEMENTED; - break; default: UNIMPLEMENTED - Status = STATUS_UNSUCCESSFUL; + Status = STATUS_NOT_FOUND; } - DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status); + //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n", This->PinDescriptorCount, Request->Id, Status); return Status; @@ -700,6 +778,9 @@ IKsFilter_DispatchDeviceIoControl( IKsFilterImpl * This; NTSTATUS Status; PKSFILTER FilterInstance; + UNICODE_STRING GuidString; + PKSPROPERTY Property; + ULONG SetCount = 0; /* obtain filter from object header */ Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); @@ -707,45 +788,96 @@ IKsFilter_DispatchDeviceIoControl( return Status; /* get our real implementation */ - This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl); + This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Header.OuterUnknown); /* current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); - if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) + /* get property from input buffer */ + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + /* get filter instance */ + FilterInstance = Filter->lpVtbl->GetStruct(Filter); + + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); + ASSERT(FilterInstance); + ASSERT(FilterInstance->Descriptor); + ASSERT(FilterInstance->Descriptor->AutomationTable); + + /* acquire control mutex */ + KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) { - UNIMPLEMENTED; + const KSMETHOD_SET *MethodSet = NULL; + ULONG MethodItemSize = 0; - /* release filter interface */ - Filter->lpVtbl->Release(Filter); - - /* complete and forget irp */ - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; - } - - /* call property handler supported by ks */ - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; - Status = KspPropertyHandler(Irp, 2, FilterPropertySet, NULL, sizeof(KSPROPERTY_ITEM)); - - if (Status == STATUS_NOT_FOUND) - { - /* get filter instance */ - FilterInstance = Filter->lpVtbl->GetStruct(Filter); - - /* check if the driver supports property sets */ - if (FilterInstance->Descriptor->AutomationTable && FilterInstance->Descriptor->AutomationTable->PropertySetsCount) + /* check if the driver supports method sets */ + if (FilterInstance->Descriptor->AutomationTable->MethodSetsCount) { - /* call driver's filter property handler */ - Status = KspPropertyHandler(Irp, - FilterInstance->Descriptor->AutomationTable->PropertySetsCount, - FilterInstance->Descriptor->AutomationTable->PropertySets, - NULL, - FilterInstance->Descriptor->AutomationTable->PropertyItemSize); + SetCount = FilterInstance->Descriptor->AutomationTable->MethodSetsCount; + MethodSet = FilterInstance->Descriptor->AutomationTable->MethodSets; + MethodItemSize = FilterInstance->Descriptor->AutomationTable->MethodItemSize; + } + + /* call method set handler */ + Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize); + } + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + { + const KSPROPERTY_SET *PropertySet = NULL; + ULONG PropertyItemSize = 0; + + /* check if the driver supports method sets */ + if (FilterInstance->Descriptor->AutomationTable->PropertySetsCount) + { + SetCount = FilterInstance->Descriptor->AutomationTable->PropertySetsCount; + PropertySet = FilterInstance->Descriptor->AutomationTable->PropertySets; + PropertyItemSize = FilterInstance->Descriptor->AutomationTable->PropertyItemSize; + } + + /* needed for our property handlers */ + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; + + /* call property handler */ + Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize); + } + else + { + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT || + IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) + { + /* call enable event handlers */ + Status = KspEnableEvent(Irp, + FilterInstance->Descriptor->AutomationTable->EventSetsCount, + (PKSEVENT_SET)FilterInstance->Descriptor->AutomationTable->EventSets, + &This->Header.EventList, + KSEVENTS_SPINLOCK, + (PVOID)&This->Header.EventListLock, + NULL, + FilterInstance->Descriptor->AutomationTable->EventItemSize); + } + else + { + /* disable event handler */ + Status = KsDisableEvent(Irp, &This->Header.EventList, KSEVENTS_SPINLOCK, &This->Header.EventListLock); } } + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information); + RtlFreeUnicodeString(&GuidString); + + /* release filter */ + Filter->lpVtbl->Release(Filter); + + /* release control mutex */ + KeReleaseMutex(This->Header.ControlMutex, FALSE); + if (Status != STATUS_PENDING) { Irp->IoStatus.Status = Status; @@ -782,9 +914,7 @@ IKsFilter_CreateDescriptors( /* initialize pin descriptors */ This->FirstPin = NULL; This->PinInstanceCount = NULL; - This->PinDescriptors = NULL; - This->PinDescriptorsEx = NULL; - This->PinDescriptorCount = 0; + This->ProcessPinIndex = NULL; /* initialize topology descriptor */ This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount; @@ -803,8 +933,8 @@ IKsFilter_CreateDescriptors( ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); /* store pin descriptors ex */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, - sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount, 0); + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, + FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { @@ -812,17 +942,7 @@ IKsFilter_CreateDescriptors( return Status; } - /* store pin descriptors */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, - sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount, 0); - - if (!NT_SUCCESS(Status)) - { - DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); - return Status; - } - - /* store pin instance count ex */ + /* store pin instance count */ Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinInstanceCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount, 0); @@ -842,18 +962,33 @@ IKsFilter_CreateDescriptors( return Status; } - - /* add new pin factory */ - RtlMoveMemory(This->PinDescriptorsEx, FilterDescriptor->PinDescriptors, sizeof(KSPIN_DESCRIPTOR_EX) * FilterDescriptor->PinDescriptorsCount); + RtlMoveMemory((PVOID)This->Filter.Descriptor->PinDescriptors, FilterDescriptor->PinDescriptors, FilterDescriptor->PinDescriptorSize * FilterDescriptor->PinDescriptorsCount); - for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++) + /* allocate process pin index */ + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, + sizeof(KSPROCESSPIN_INDEXENTRY) * FilterDescriptor->PinDescriptorsCount, 0); + + if (!NT_SUCCESS(Status)) { - RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR)); + DPRINT("IKsFilter_CreateDescriptors _KsEdit failed %lx\n", Status); + return Status; } - /* store new pin descriptor count */ - This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount; + } + + + if (FilterDescriptor->ConnectionsCount) + { + /* modify connections array */ + Status = _KsEdit(This->Filter.Bag, + (PVOID*)&This->Filter.Descriptor->Connections, + FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), + FilterDescriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), + 0); + + This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; + This->Topology.TopologyConnectionsCount = ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount = FilterDescriptor->ConnectionsCount; } if (FilterDescriptor->NodeDescriptorsCount) @@ -905,6 +1040,7 @@ IKsFilter_CopyFilterDescriptor( const KSFILTER_DESCRIPTOR* FilterDescriptor) { NTSTATUS Status; + KSAUTOMATION_TABLE AutomationTable; This->Filter.Descriptor = AllocateItem(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR)); if (!This->Filter.Descriptor) @@ -921,27 +1057,39 @@ IKsFilter_CopyFilterDescriptor( /* copy filter descriptor fields */ RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor, sizeof(KSFILTER_DESCRIPTOR)); + /* zero automation table */ + RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE)); + + /* setup filter property sets */ + AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM); + AutomationTable.PropertySetsCount = 2; + AutomationTable.PropertySets = FilterPropertySet; + + /* merge filter automation table */ + Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable, This->Filter.Bag); + return Status; } -NTSTATUS +VOID IKsFilter_AddPin( - IKsFilter * Filter, + PKSFILTER Filter, PKSPIN Pin) { PKSPIN NextPin, CurPin; PKSBASIC_HEADER BasicHeader; - IKsFilterImpl * This = (IKsFilterImpl*)Filter; + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); /* sanity check */ - ASSERT(Pin->Id < This->PinDescriptorCount); + ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); if (This->FirstPin[Pin->Id] == NULL) { /* welcome first pin */ This->FirstPin[Pin->Id] = Pin; - return STATUS_SUCCESS; + This->PinInstanceCount[Pin->Id]++; + return; } /* get first pin */ @@ -963,8 +1111,58 @@ IKsFilter_AddPin( /* store pin */ BasicHeader->Next.Pin = Pin; +} - return STATUS_SUCCESS; +VOID +IKsFilter_RemovePin( + PKSFILTER Filter, + PKSPIN Pin) +{ + PKSPIN NextPin, CurPin, LastPin; + PKSBASIC_HEADER BasicHeader; + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); + + /* sanity check */ + ASSERT(Pin->Id < This->Filter.Descriptor->PinDescriptorsCount); + + /* get first pin */ + CurPin = This->FirstPin[Pin->Id]; + + LastPin = NULL; + do + { + /* get next instantiated pin */ + NextPin = KsPinGetNextSiblingPin(CurPin); + + if (CurPin == Pin) + { + if (LastPin) + { + /* get basic header of last pin */ + BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastPin - sizeof(KSBASIC_HEADER)); + + BasicHeader->Next.Pin = NextPin; + } + else + { + /* erase last pin */ + This->FirstPin[Pin->Id] = NextPin; + } + /* decrement pin instance count */ + This->PinInstanceCount[Pin->Id]--; + return; + } + + if (!NextPin) + break; + + LastPin = CurPin; + NextPin = CurPin; + + }while(NextPin != NULL); + + /* pin not found */ + ASSERT(0); } @@ -991,45 +1189,39 @@ IKsFilter_DispatchCreatePin( ASSERT(This->Header.Type == KsObjectTypeFilter); /* acquire control mutex */ - KeWaitForSingleObject(&This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); + KeWaitForSingleObject(This->Header.ControlMutex, Executive, KernelMode, FALSE, NULL); /* now validate the connect request */ - Status = KsValidateConnectRequest(Irp, This->PinDescriptorCount, This->PinDescriptors, &Connect); + Status = KspValidateConnectRequest(Irp, This->Filter.Descriptor->PinDescriptorsCount, (PVOID)This->Filter.Descriptor->PinDescriptors, This->Filter.Descriptor->PinDescriptorSize, &Connect); DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest %lx\n", Status); if (NT_SUCCESS(Status)) { /* sanity check */ - ASSERT(Connect->PinId < This->PinDescriptorCount); + ASSERT(Connect->PinId < This->Filter.Descriptor->PinDescriptorsCount); DPRINT("IKsFilter_DispatchCreatePin KsValidateConnectRequest PinId %lu CurrentInstanceCount %lu MaxPossible %lu\n", Connect->PinId, This->PinInstanceCount[Connect->PinId], - This->PinDescriptorsEx[Connect->PinId].InstancesPossible); + This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible); - if (This->PinInstanceCount[Connect->PinId] < This->PinDescriptorsEx[Connect->PinId].InstancesPossible) + if (This->PinInstanceCount[Connect->PinId] < This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible) { /* create the pin */ - Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->lpVtbl, Connect, &This->PinDescriptorsEx[Connect->PinId]); + Status = KspCreatePin(DeviceObject, Irp, This->Header.KsDevice, This->FilterFactory, (IKsFilter*)&This->Header.OuterUnknown, Connect, (KSPIN_DESCRIPTOR_EX*)&This->Filter.Descriptor->PinDescriptors[Connect->PinId]); DPRINT("IKsFilter_DispatchCreatePin KspCreatePin %lx\n", Status); - - if (NT_SUCCESS(Status)) - { - /* successfully created pin, increment pin instance count */ - This->PinInstanceCount[Connect->PinId]++; - } } else { /* maximum instance count reached, bye-bye */ Status = STATUS_UNSUCCESSFUL; - DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->PinDescriptorsEx[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]); + DPRINT("IKsFilter_DispatchCreatePin MaxInstance %lu CurInstance %lu %lx\n", This->Filter.Descriptor->PinDescriptors[Connect->PinId].InstancesPossible, This->PinInstanceCount[Connect->PinId]); } } /* release control mutex */ - KeReleaseMutex(&This->Header.ControlMutex, FALSE); + KeReleaseMutex(This->Header.ControlMutex, FALSE); if (Status != STATUS_PENDING) { @@ -1098,12 +1290,72 @@ IKsFilter_AttachFilterToFilterFactory( /* found last entry */ break; } - }while(FilterFactory); + }while(TRUE); /* attach filter factory */ BasicHeader->Next.Filter = &This->Filter; } +VOID +IKsFilter_RemoveFilterFromFilterFactory( + IKsFilterImpl * This, + PKSFILTERFACTORY FilterFactory) +{ + PKSBASIC_HEADER BasicHeader; + PKSFILTER Filter, LastFilter; + + /* get filter factory basic header */ + BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER)); + + /* sanity check */ + ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory); + ASSERT(BasicHeader->FirstChild.Filter != NULL); + + + /* set to first entry */ + Filter = BasicHeader->FirstChild.Filter; + LastFilter = NULL; + + do + { + if (Filter == &This->Filter) + { + if (LastFilter) + { + /* get basic header */ + BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastFilter - sizeof(KSBASIC_HEADER)); + /* remove filter instance */ + BasicHeader->Next.Filter = This->Header.Next.Filter; + break; + } + else + { + /* remove filter instance */ + BasicHeader->FirstChild.Filter = This->Header.Next.Filter; + break; + } + } + + /* get basic header */ + BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER)); + /* sanity check */ + ASSERT(BasicHeader->Type == KsObjectTypeFilter); + + LastFilter = Filter; + if (BasicHeader->Next.Filter) + { + /* iterate to next filter factory */ + Filter = BasicHeader->Next.Filter; + } + else + { + /* filter is not in list */ + ASSERT(0); + break; + } + }while(TRUE); +} + NTSTATUS NTAPI KspCreateFilter( @@ -1148,7 +1400,7 @@ KspCreateFilter( DPRINT("KspCreateFilter OutOfMemory\n"); return STATUS_INSUFFICIENT_RESOURCES; } - KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->Filter.Bag, NULL); /* copy filter descriptor */ @@ -1176,6 +1428,8 @@ KspCreateFilter( return STATUS_INSUFFICIENT_RESOURCES; } + DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags); + /* initialize pin create item */ CreateItem[0].Create = IKsFilter_DispatchCreatePin; CreateItem[0].Context = (PVOID)This; @@ -1190,10 +1444,9 @@ KspCreateFilter( /* initialize filter instance */ This->ref = 1; - This->lpVtbl = &vt_IKsFilter; + This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter; This->lpVtblKsControl = &vt_IKsControl; - This->Filter.Descriptor = Factory->FilterDescriptor; This->Factory = Factory; This->FilterFactory = iface; This->FileObject = IoStack->FileObject; @@ -1202,7 +1455,8 @@ KspCreateFilter( This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface); This->Header.Type = KsObjectTypeFilter; - KeInitializeMutex(&This->Header.ControlMutex, 0); + This->Header.ControlMutex = &This->ControlMutex; + KeInitializeMutex(This->Header.ControlMutex, 0); InitializeListHead(&This->Header.EventList); KeInitializeSpinLock(&This->Header.EventListLock); @@ -1224,8 +1478,9 @@ KspCreateFilter( if (Factory->FilterDescriptor->Dispatch->Create) { /* now let driver initialize the filter instance */ - DPRINT("Before instantiating filter Filter %p This %p KSBASIC_HEADER %u\n", &This->Filter, This, sizeof(KSBASIC_HEADER)); + ASSERT(This->Header.KsDevice); + ASSERT(This->Header.KsDevice->Started); Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp); if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) @@ -1253,14 +1508,14 @@ KspCreateFilter( /* initialize object header extra fields */ This->ObjectHeader->Type = KsObjectTypeFilter; - This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; + This->ObjectHeader->Unknown = (PUNKNOWN)&This->Header.OuterUnknown; This->ObjectHeader->ObjectType = (PVOID)&This->Filter; /* attach filter to filter factory */ IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory); /* completed initialization */ - DPRINT("KspCreateFilter done %lx\n", Status); + DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice); return Status; } @@ -1292,6 +1547,7 @@ KsFilterReleaseProcessingMutex( KeReleaseMutex(&This->ProcessingMutex, FALSE); } + /* @implemented */ @@ -1304,40 +1560,42 @@ KsFilterAddTopologyConnections ( IN const KSTOPOLOGY_CONNECTION *const NewTopologyConnections) { ULONG Count; - KSTOPOLOGY_CONNECTION * Connections; + NTSTATUS Status; IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); + DPRINT("KsFilterAddTopologyConnections\n"); + + ASSERT(This->Filter.Descriptor); Count = This->Filter.Descriptor->ConnectionsCount + NewConnectionsCount; - /* allocate array */ - Connections = AllocateItem(NonPagedPool, Count * sizeof(KSTOPOLOGY_CONNECTION)); - if (!Connections) - return STATUS_INSUFFICIENT_RESOURCES; + + /* modify connections array */ + Status = _KsEdit(This->Filter.Bag, + (PVOID*)&This->Filter.Descriptor->Connections, + Count * sizeof(KSTOPOLOGY_CONNECTION), + This->Filter.Descriptor->ConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION), + 0); + + if (!NT_SUCCESS(Status)) + { + /* failed */ + DPRINT("KsFilterAddTopologyConnections KsEdit failed with %lx\n", Status); + return Status; + } /* FIXME verify connections */ - if (This->Filter.Descriptor->ConnectionsCount) - { - /* copy old connections */ - RtlMoveMemory(Connections, This->Filter.Descriptor->Connections, sizeof(KSTOPOLOGY_CONNECTION) * This->Filter.Descriptor->ConnectionsCount); - } + /* copy new connections */ + RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections[This->Filter.Descriptor->ConnectionsCount], + NewTopologyConnections, + NewConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION)); - /* add new connections */ - RtlMoveMemory((PVOID)(Connections + This->Filter.Descriptor->ConnectionsCount), NewTopologyConnections, NewConnectionsCount); + /* update topology */ + This->Topology.TopologyConnectionsCount += NewConnectionsCount; + ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->ConnectionsCount += NewConnectionsCount; + This->Topology.TopologyConnections = This->Filter.Descriptor->Connections; - /* add the new connections */ - RtlMoveMemory((PVOID)&This->Filter.Descriptor->ConnectionsCount, &Count, sizeof(ULONG)); /* brain-dead gcc hack */ - - /* free old connections array */ - if (This->Filter.Descriptor->ConnectionsCount) - { - FreeItem((PVOID)This->Filter.Descriptor->Connections); - } - - /* brain-dead gcc hack */ - RtlMoveMemory((PVOID)&This->Filter.Descriptor->Connections, Connections, sizeof(KSTOPOLOGY_CONNECTION*)); - - return STATUS_SUCCESS; + return Status; } /* @@ -1386,13 +1644,13 @@ KsFilterCreatePinFactory ( DPRINT("KsFilterCreatePinFactory\n"); /* calculate new count */ - Count = This->PinDescriptorCount + 1; + Count = This->Filter.Descriptor->PinDescriptorsCount + 1; /* sanity check */ ASSERT(This->Filter.Descriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); - /* allocate pin descriptors ex array */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptorsEx, Count * sizeof(KSPIN_DESCRIPTOR_EX), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR_EX), 0); + /* modify pin descriptors ex array */ + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->Filter.Descriptor->PinDescriptors, Count * This->Filter.Descriptor->PinDescriptorSize, This->Filter.Descriptor->PinDescriptorsCount * This->Filter.Descriptor->PinDescriptorSize, 0); if (!NT_SUCCESS(Status)) { /* failed */ @@ -1400,8 +1658,8 @@ KsFilterCreatePinFactory ( return Status; } - /* allocate pin descriptors array */ - Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->PinDescriptors, Count * sizeof(KSPIN_DESCRIPTOR), This->PinDescriptorCount * sizeof(KSPIN_DESCRIPTOR), 0); + /* modify pin instance count array */ + Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->Filter.Descriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { /* failed */ @@ -1409,18 +1667,8 @@ KsFilterCreatePinFactory ( return Status; } - - /* allocate pin instance count array */ - Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->PinInstanceCount, sizeof(ULONG) * Count, sizeof(ULONG) * This->PinDescriptorCount, 0); - if (!NT_SUCCESS(Status)) - { - /* failed */ - DPRINT("KsFilterCreatePinFactory _KsEdit failed with %lx\n", Status); - return Status; - } - - /* allocate first pin array */ - Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->PinDescriptorCount, 0); + /* modify first pin array */ + Status = _KsEdit(This->Filter.Bag,(PVOID*)&This->FirstPin, sizeof(PKSPIN) * Count, sizeof(PKSPIN) * This->Filter.Descriptor->PinDescriptorsCount, 0); if (!NT_SUCCESS(Status)) { /* failed */ @@ -1429,14 +1677,23 @@ KsFilterCreatePinFactory ( } /* add new pin factory */ - RtlMoveMemory(&This->PinDescriptorsEx[This->PinDescriptorCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); - RtlMoveMemory(&This->PinDescriptors[This->PinDescriptorCount], &InPinDescriptor->PinDescriptor, sizeof(KSPIN_DESCRIPTOR)); + RtlMoveMemory((PVOID)&This->Filter.Descriptor->PinDescriptors[This->Filter.Descriptor->PinDescriptorsCount], InPinDescriptor, sizeof(KSPIN_DESCRIPTOR_EX)); + + /* allocate process pin index */ + Status = _KsEdit(This->Filter.Bag, (PVOID*)&This->ProcessPinIndex, sizeof(KSPROCESSPIN_INDEXENTRY) * Count, + sizeof(KSPROCESSPIN_INDEXENTRY) * This->Filter.Descriptor->PinDescriptorsCount, 0); + + if (!NT_SUCCESS(Status)) + { + DPRINT("KsFilterCreatePinFactory _KsEdit failed %lx\n", Status); + return Status; + } /* store new pin id */ - *PinID = This->PinDescriptorCount; + *PinID = This->Filter.Descriptor->PinDescriptorsCount; /* increment pin descriptor count */ - This->PinDescriptorCount++; + ((PKSFILTER_DESCRIPTOR)This->Filter.Descriptor)->PinDescriptorsCount++; DPRINT("KsFilterCreatePinFactory done\n"); @@ -1469,7 +1726,7 @@ KsFilterGetChildPinCount( { IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); - if (PinId >= This->PinDescriptorCount) + if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) { /* index is out of bounds */ return 0; @@ -1490,7 +1747,7 @@ KsFilterGetFirstChildPin( { IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter); - if (PinId >= This->PinDescriptorCount) + if (PinId >= This->Filter.Descriptor->PinDescriptorsCount) { /* index is out of bounds */ return NULL; @@ -1529,6 +1786,8 @@ KsGetFilterFromIrp( PIO_STACK_LOCATION IoStack; PKSIOBJECT_HEADER ObjectHeader; + DPRINT("KsGetFilterFromIrp\n"); + /* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); diff --git a/drivers/ksfilter/ks/filterfactory.c b/drivers/ksfilter/ks/filterfactory.c index a16b2900069..e60bfc41e81 100644 --- a/drivers/ksfilter/ks/filterfactory.c +++ b/drivers/ksfilter/ks/filterfactory.c @@ -14,13 +14,14 @@ typedef struct KSBASIC_HEADER Header; KSFILTERFACTORY FilterFactory; - IKsFilterFactoryVtbl *lpVtbl; LONG ref; PKSIDEVICE_HEADER DeviceHeader; PFNKSFILTERFACTORYPOWER SleepCallback; PFNKSFILTERFACTORYPOWER WakeCallback; LIST_ENTRY SymbolicLinkList; + KMUTEX ControlMutex; + }IKsFilterFactoryImpl; VOID @@ -57,7 +58,7 @@ IKsFilterFactory_Create( Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory); /* get interface */ - iface = (IKsFilterFactory*)&Factory->lpVtbl; + iface = (IKsFilterFactory*)&Factory->Header.OuterUnknown; /* create a filter instance */ Status = KspCreateFilter(DeviceObject, Irp, iface); @@ -82,15 +83,31 @@ IKsFilterFactory_fnQueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + NTSTATUS Status; + + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtbl; + *Output = &This->Header.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } - return STATUS_UNSUCCESSFUL; + + if (This->Header.ClientAggregate) + { + /* using client aggregate */ + Status = This->Header.ClientAggregate->lpVtbl->QueryInterface(This->Header.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsFilterFactory_fnQueryInterface no interface\n"); + return STATUS_NOT_SUPPORTED; } ULONG @@ -98,7 +115,7 @@ NTAPI IKsFilterFactory_fnAddRef( IKsFilterFactory * iface) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -108,7 +125,7 @@ NTAPI IKsFilterFactory_fnRelease( IKsFilterFactory * iface) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); InterlockedDecrement(&This->ref); @@ -134,7 +151,7 @@ NTAPI IKsFilterFactory_fnGetStruct( IKsFilterFactory * iface) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); return &This->FilterFactory; } @@ -145,7 +162,7 @@ IKsFilterFactory_fnSetDeviceClassesState( IKsFilterFactory * iface, IN BOOLEAN Enable) { - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable); } @@ -211,7 +228,7 @@ IKsFilterFactory_fnInitialize( BOOL FreeString = FALSE; IKsDevice * KsDevice; - IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, Header.OuterUnknown); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -225,17 +242,16 @@ IKsFilterFactory_fnInitialize( This->Header.Parent.KsDevice = &DeviceExtension->DeviceHeader->KsDevice; This->DeviceHeader = DeviceExtension->DeviceHeader; + /* initialize filter factory control mutex */ + This->Header.ControlMutex = &This->ControlMutex; + KeInitializeMutex(This->Header.ControlMutex, 0); + /* unused fields */ - KeInitializeMutex(&This->Header.ControlMutex, 0); InitializeListHead(&This->Header.EventList); KeInitializeSpinLock(&This->Header.EventListLock); - InitializeListHead(&This->SymbolicLinkList); - /* initialize filter factory control mutex */ - KeInitializeMutex(&This->Header.ControlMutex, 0); - /* does the device use a reference string */ if (RefString || !Descriptor->ReferenceGuid) { @@ -305,7 +321,7 @@ IKsFilterFactory_fnInitialize( if (This->FilterFactory.Bag) { /* initialize object bag */ - KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; KsDevice->lpVtbl->InitializeObjectBag(KsDevice, (PKSIOBJECT_BAG)This->FilterFactory.Bag, NULL); } } @@ -356,10 +372,10 @@ KspCreateFilterFactory( /* initialize struct */ This->ref = 1; - This->lpVtbl = &vt_IKsFilterFactoryVtbl; + This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilterFactoryVtbl; /* map to com object */ - Filter = (IKsFilterFactory*)&This->lpVtbl; + Filter = (IKsFilterFactory*)&This->Header.OuterUnknown; /* initialize filter */ Status = Filter->lpVtbl->Initialize(Filter, DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory); @@ -411,7 +427,7 @@ KsFilterFactorySetDeviceClassesState( IKsFilterFactory * Factory; IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory); - Factory = (IKsFilterFactory*)&This->lpVtbl; + Factory = (IKsFilterFactory*)&This->Header.OuterUnknown; return Factory->lpVtbl->SetDeviceClassesState(Factory, NewState); } @@ -468,19 +484,261 @@ KsFilterFactoryAddCreateItem( return KsAllocateObjectCreateItem((KSDEVICE_HEADER)Factory->DeviceHeader, &CreateItem, TRUE, IKsFilterFactory_ItemFreeCb); } +ULONG +KspCacheAddData( + PKSPCACHE_DESCRIPTOR Descriptor, + LPCVOID Data, + ULONG Length) +{ + ULONG Index; + + for(Index = 0; Index < Descriptor->DataOffset; Index++) + { + if (RtlCompareMemory(Descriptor->DataCache, Data, Length) == Length) + { + if (Index + Length > Descriptor->DataOffset) + { + /* adjust used space */ + Descriptor->DataOffset = Index + Length; + /* return absolute offset */ + return Descriptor->DataLength + Index; + } + } + } + + /* sanity check */ + ASSERT(Descriptor->DataOffset + Length < Descriptor->DataLength); + + /* copy to data blob */ + RtlMoveMemory((Descriptor->DataCache + Descriptor->DataOffset), Data, Length); + + /* backup offset */ + Index = Descriptor->DataOffset; + + /* adjust used space */ + Descriptor->DataOffset += Length; + + /* return absolute offset */ + return Descriptor->DataLength + Index; +} + /* @implemented */ KSDDKAPI NTSTATUS NTAPI -KsFilterFactoryUpdateCacheData ( +KsFilterFactoryUpdateCacheData( IN PKSFILTERFACTORY FilterFactory, IN const KSFILTER_DESCRIPTOR* FilterDescriptor OPTIONAL) { - UNIMPLEMENTED + KSPCACHE_DESCRIPTOR Descriptor; + PKSPCACHE_FILTER_HEADER FilterHeader; + UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData"); + PKSPCACHE_PIN_HEADER PinHeader; + ULONG Index, SubIndex; + PLIST_ENTRY Entry; + PSYMBOLIC_LINK_ENTRY SymEntry; + BOOLEAN Found; + HKEY hKey; + NTSTATUS Status = STATUS_SUCCESS; + + IKsFilterFactoryImpl * Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory); + DPRINT("KsFilterFactoryUpdateCacheData %p\n", FilterDescriptor); - return STATUS_SUCCESS; + if (!FilterDescriptor) + FilterDescriptor = Factory->FilterFactory.FilterDescriptor; + + ASSERT(FilterDescriptor); + + /* initialize cache descriptor */ + RtlZeroMemory(&Descriptor, sizeof(KSPCACHE_DESCRIPTOR)); + + /* calculate filter data size */ + Descriptor.FilterLength = sizeof(KSPCACHE_FILTER_HEADER); + + /* FIXME support variable size pin descriptors */ + ASSERT(FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + + for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++) + { + /* add filter descriptor */ + Descriptor.FilterLength += sizeof(KSPCACHE_PIN_HEADER); + + if (FilterDescriptor->PinDescriptors[Index].PinDescriptor.Category) + { + /* add extra ULONG for offset to category */ + Descriptor.FilterLength += sizeof(ULONG); + + /* add size for clsid */ + Descriptor.DataLength += sizeof(CLSID); + } + + /* add space for formats */ + Descriptor.FilterLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount * sizeof(KSPCACHE_DATARANGE); + + /* add space for MajorFormat / MinorFormat */ + Descriptor.DataLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount * sizeof(CLSID) * 2; + + /* add space for mediums */ + Descriptor.FilterLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount * sizeof(ULONG); + + /* add space for the data */ + Descriptor.DataLength += FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount * sizeof(KSPCACHE_MEDIUM); + } + + /* now allocate the space */ + Descriptor.FilterData = (PUCHAR)AllocateItem(NonPagedPool, Descriptor.DataLength + Descriptor.FilterLength); + if (!Descriptor.FilterData) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize data cache */ + Descriptor.DataCache = (PUCHAR)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterLength); + + /* setup filter header */ + FilterHeader = (PKSPCACHE_FILTER_HEADER)Descriptor.FilterData; + + FilterHeader->dwVersion = 2; + FilterHeader->dwMerit = MERIT_DO_NOT_USE; + FilterHeader->dwUnused = 0; + FilterHeader->dwPins = FilterDescriptor->PinDescriptorsCount; + + Descriptor.FilterOffset = sizeof(KSPCACHE_FILTER_HEADER); + + /* write pin headers */ + for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++) + { + /* get offset to pin */ + PinHeader = (PKSPCACHE_PIN_HEADER)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterOffset); + + /* write pin header */ + PinHeader->Signature = 0x33697030 + Index; + PinHeader->Flags = 0; + PinHeader->Instances = FilterDescriptor->PinDescriptors[Index].InstancesPossible; + if (PinHeader->Instances > 1) + PinHeader->Flags |= REG_PINFLAG_B_MANY; + + + PinHeader->MediaTypes = FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount; + PinHeader->Mediums = FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount; + PinHeader->Category = (FilterDescriptor->PinDescriptors[Index].PinDescriptor.Category ? TRUE : FALSE); + + Descriptor.FilterOffset += sizeof(KSPCACHE_PIN_HEADER); + + if (PinHeader->Category) + { + /* get category offset */ + PULONG Category = (PULONG)(PinHeader + 1); + + /* write category offset */ + *Category = KspCacheAddData(&Descriptor, FilterDescriptor->PinDescriptors[Index].PinDescriptor.Category, sizeof(CLSID)); + + /* adjust offset */ + Descriptor.FilterOffset += sizeof(ULONG); + } + + /* add dataranges */ + for(SubIndex = 0; SubIndex < FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRangesCount; SubIndex++) + { + /* get datarange offset */ + PKSPCACHE_DATARANGE DataRange = (PKSPCACHE_DATARANGE)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterOffset); + + /* initialize data range */ + DataRange->Signature = 0x33797430 + SubIndex; + DataRange->dwUnused = 0; + DataRange->OffsetMajor = KspCacheAddData(&Descriptor, &FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRanges[SubIndex]->MajorFormat, sizeof(CLSID)); + DataRange->OffsetMinor = KspCacheAddData(&Descriptor, &FilterDescriptor->PinDescriptors[Index].PinDescriptor.DataRanges[SubIndex]->SubFormat, sizeof(CLSID)); + + /* adjust offset */ + Descriptor.FilterOffset += sizeof(KSPCACHE_DATARANGE); + } + + /* add mediums */ + for(SubIndex = 0; SubIndex < FilterDescriptor->PinDescriptors[Index].PinDescriptor.MediumsCount; SubIndex++) + { + KSPCACHE_MEDIUM Medium; + PULONG MediumOffset; + + /* get pin medium offset */ + MediumOffset = (PULONG)((ULONG_PTR)Descriptor.FilterData + Descriptor.FilterOffset); + + /* copy medium guid */ + RtlMoveMemory(&Medium.Medium, &FilterDescriptor->PinDescriptors[Index].PinDescriptor.Mediums[SubIndex].Set, sizeof(GUID)); + Medium.dw1 = FilterDescriptor->PinDescriptors[Index].PinDescriptor.Mediums[SubIndex].Id; /* FIXME verify */ + Medium.dw2 = 0; + + *MediumOffset = KspCacheAddData(&Descriptor, &Medium, sizeof(KSPCACHE_MEDIUM)); + + /* adjust offset */ + Descriptor.FilterOffset += sizeof(ULONG); + } + } + + /* sanity checks */ + ASSERT(Descriptor.FilterOffset == Descriptor.FilterLength); + ASSERT(Descriptor.DataOffset <= Descriptor.DataLength); + + + /* now go through all entries and update 'FilterData' key */ + for(Index = 0; Index < FilterDescriptor->CategoriesCount; Index++) + { + /* get first entry */ + Entry = Factory->SymbolicLinkList.Flink; + + /* set status to not found */ + Found = FALSE; + /* loop list until the the current category is found */ + while(Entry != &Factory->SymbolicLinkList) + { + /* fetch symbolic link entry */ + SymEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLIC_LINK_ENTRY, Entry); + + if (IsEqualGUIDAligned(&SymEntry->DeviceInterfaceClass, &FilterDescriptor->Categories[Index])) + { + /* found category */ + Found = TRUE; + break; + } + + /* move to next entry */ + Entry = Entry->Flink; + } + + if (!Found) + { + /* filter category is not present */ + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* now open device interface */ + Status = IoOpenDeviceInterfaceRegistryKey(&SymEntry->SymbolicLink, KEY_WRITE, &hKey); + if (!NT_SUCCESS(Status)) + { + /* failed to open interface key */ + break; + } + + /* update filterdata key */ + Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Descriptor.FilterData, Descriptor.FilterLength + Descriptor.DataOffset); + + /* close filterdata key */ + ZwClose(hKey); + + if (!NT_SUCCESS(Status)) + { + /* failed to set key value */ + break; + } + } + /* free filter data */ + FreeItem(Descriptor.FilterData); + + /* done */ + return Status; } diff --git a/drivers/ksfilter/ks/irp.c b/drivers/ksfilter/ks/irp.c index e50490aad58..0c6036e2059 100644 --- a/drivers/ksfilter/ks/irp.c +++ b/drivers/ksfilter/ks/irp.c @@ -1360,7 +1360,7 @@ KsRemoveIrpFromCancelableQueue( PLIST_ENTRY CurEntry; KIRQL OldIrql; - DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation); + //DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation); /* check parameters */ if (!QueueHead || !SpinLock) @@ -1719,10 +1719,24 @@ FindMatchingCreateItem( { PLIST_ENTRY Entry; PCREATE_ITEM_ENTRY CreateItemEntry; + UNICODE_STRING RefString; + +#ifndef MS_KSUSER /* remove '\' slash */ Buffer++; BufferSize -= sizeof(WCHAR); +#endif + + if (!wcschr(Buffer, L'\\')) + { + RtlInitUnicodeString(&RefString, Buffer); + } + else + { + RefString.Buffer = Buffer; + RefString.Length = RefString.MaximumLength = ((ULONG_PTR)wcschr(Buffer, L'\\') - (ULONG_PTR)Buffer); + } /* point to first entry */ Entry = ListHead->Flink; @@ -1751,9 +1765,9 @@ FindMatchingCreateItem( ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer); - DPRINT("CreateItem %S Length %u Request %S %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer, + DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer, CreateItemEntry->CreateItem->ObjectClass.Length, - Buffer, + &RefString, BufferSize); if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize) @@ -1764,7 +1778,7 @@ FindMatchingCreateItem( } /* now check if the object class is the same */ - if (RtlCompareMemory(CreateItemEntry->CreateItem->ObjectClass.Buffer, Buffer, CreateItemEntry->CreateItem->ObjectClass.Length) == CreateItemEntry->CreateItem->ObjectClass.Length) + if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE)) { /* found matching create item */ *OutCreateItem = CreateItemEntry; @@ -1992,7 +2006,7 @@ KsDispatchIrp( PKSIDEVICE_HEADER DeviceHeader; PDEVICE_EXTENSION DeviceExtension; - DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp); + //DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -2008,7 +2022,7 @@ KsDispatchIrp( if (IoStack->MajorFunction == IRP_MJ_CREATE) { /* check internal type */ - if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ { /* AVStream client */ return IKsDevice_Create(DeviceObject, Irp); @@ -2040,7 +2054,7 @@ KsDispatchIrp( if (IoStack->MajorFunction == IRP_MJ_POWER) { /* check internal type */ - if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ { /* AVStream client */ return IKsDevice_Power(DeviceObject, Irp); @@ -2054,7 +2068,7 @@ KsDispatchIrp( else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */ { /* check internal type */ - if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ { /* AVStream client */ return IKsDevice_Pnp(DeviceObject, Irp); diff --git a/drivers/ksfilter/ks/ksfunc.h b/drivers/ksfilter/ks/ksfunc.h index 8d0836af7d7..636c616bcb2 100644 --- a/drivers/ksfilter/ks/ksfunc.h +++ b/drivers/ksfilter/ks/ksfunc.h @@ -84,19 +84,17 @@ VOID FreeItem( IN PVOID Item); -NTSTATUS -NTAPI -KspTopologyPropertyHandler( - IN PIRP Irp, - IN PKSIDENTIFIER Request, - IN OUT PVOID Data); - +KSDDKAPI NTSTATUS NTAPI KspPinPropertyHandler( - IN PIRP Irp, - IN PKSIDENTIFIER Request, - IN OUT PVOID Data); + IN PIRP Irp, + IN PKSPROPERTY Property, + IN OUT PVOID Data, + IN ULONG DescriptorsCount, + IN const KSPIN_DESCRIPTOR* Descriptors, + IN ULONG DescriptorSize); + NTSTATUS FindMatchingCreateItem( @@ -122,11 +120,6 @@ KspCreatePin( IN PKSPIN_CONNECT Connect, IN KSPIN_DESCRIPTOR_EX* Descriptor); -NTSTATUS -IKsFilter_AddPin( - IKsFilter * Filter, - PKSPIN Pin); - NTSTATUS KspAddCreateItemToList( OUT PLIST_ENTRY ListHead, @@ -156,3 +149,40 @@ KspSetFilterFactoriesState( IN PKSIDEVICE_HEADER DeviceHeader, IN BOOLEAN NewState); +NTSTATUS +NTAPI +KspMethodHandlerWithAllocator( + IN PIRP Irp, + IN ULONG MethodSetsCount, + IN const KSMETHOD_SET *MethodSet, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG MethodItemSize OPTIONAL); + +VOID +IKsFilter_AddPin( + PKSFILTER Filter, + PKSPIN Pin); + +VOID +IKsFilter_RemovePin( + PKSFILTER Filter, + PKSPIN Pin); + +NTSTATUS +KspEnableEvent( + IN PIRP Irp, + IN ULONG EventSetsCount, + IN PKSEVENT_SET EventSet, + IN OUT PLIST_ENTRY EventsList OPTIONAL, + IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, + IN PVOID EventsLock OPTIONAL, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG EventItemSize OPTIONAL); + +NTSTATUS +KspValidateConnectRequest( + IN PIRP Irp, + IN ULONG DescriptorsCount, + IN PVOID Descriptors, + IN ULONG DescriptorSize, + OUT PKSPIN_CONNECT* Connect); diff --git a/drivers/ksfilter/ks/ksiface.h b/drivers/ksfilter/ks/ksiface.h index ffea3ed8a7c..ad95fc9a922 100644 --- a/drivers/ksfilter/ks/ksiface.h +++ b/drivers/ksfilter/ks/ksiface.h @@ -282,9 +282,9 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown) STDMETHOD_(NTSTATUS,ReleaseDevice)(THIS) PURE; STDMETHOD_(NTSTATUS, GetAdapterObject)(THIS_ - IN PADAPTER_OBJECT Object, - IN PULONG Unknown1, - IN PULONG Unknown2) PURE; + IN PADAPTER_OBJECT * Object, + IN PULONG MaxMappingsByteCount, + IN PULONG MappingTableStride) PURE; STDMETHOD_(NTSTATUS, AddPowerEntry)(THIS_ IN struct KSPOWER_ENTRY * Entry, @@ -300,8 +300,8 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown) IN KSSTATE NewState)PURE; STDMETHOD_(NTSTATUS, ArbitrateAdapterChannel)(THIS_ - IN ULONG ControlCode, - IN IO_ALLOCATION_ACTION Action, + IN ULONG NumberOfMapRegisters, + IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context)PURE; STDMETHOD_(NTSTATUS, CheckIoCapability)(THIS_ diff --git a/drivers/ksfilter/ks/kstypes.h b/drivers/ksfilter/ks/kstypes.h index 4bdc04c0bcb..0e64312e095 100644 --- a/drivers/ksfilter/ks/kstypes.h +++ b/drivers/ksfilter/ks/kstypes.h @@ -58,9 +58,11 @@ typedef struct { KSOBJECTTYPE Type; PKSDEVICE KsDevice; - KMUTEX ControlMutex; + PRKMUTEX ControlMutex; LIST_ENTRY EventList; KSPIN_LOCK EventListLock; + PUNKNOWN ClientAggregate; + PUNKNOWN OuterUnknown; union { PKSDEVICE KsDevice; @@ -87,7 +89,6 @@ typedef struct { KSBASIC_HEADER BasicHeader; KSDEVICE KsDevice; - IKsDeviceVtbl *lpVtblIKsDevice; LONG ref; ERESOURCE SecurityLock; @@ -108,6 +109,10 @@ typedef struct LIST_ENTRY PowerDispatchList; LIST_ENTRY ObjectBags; + PADAPTER_OBJECT AdapterObject; + ULONG MaxMappingsByteCount; + ULONG MappingTableStride; + }KSIDEVICE_HEADER, *PKSIDEVICE_HEADER; typedef struct @@ -120,6 +125,7 @@ typedef struct { LIST_ENTRY Entry; UNICODE_STRING SymbolicLink; + CLSID DeviceInterfaceClass; }SYMBOLIC_LINK_ENTRY, *PSYMBOLIC_LINK_ENTRY; typedef struct @@ -157,3 +163,51 @@ typedef struct WCHAR BusIdentifier[1]; }BUS_ENUM_DEVICE_EXTENSION, *PBUS_ENUM_DEVICE_EXTENSION; + +typedef struct +{ + PUCHAR FilterData; + ULONG FilterLength; + ULONG FilterOffset; + + PUCHAR DataCache; + ULONG DataLength; + ULONG DataOffset; + +}KSPCACHE_DESCRIPTOR, *PKSPCACHE_DESCRIPTOR; + +typedef struct +{ + DWORD dwVersion; + DWORD dwMerit; + DWORD dwPins; + DWORD dwUnused; +}KSPCACHE_FILTER_HEADER, *PKSPCACHE_FILTER_HEADER; + +typedef struct +{ + ULONG Signature; + ULONG Flags; + ULONG Instances; + ULONG MediaTypes; + ULONG Mediums; + DWORD Category; +}KSPCACHE_PIN_HEADER, *PKSPCACHE_PIN_HEADER; + + +typedef struct +{ + ULONG Signature; + ULONG dwUnused; + ULONG OffsetMajor; + ULONG OffsetMinor; +}KSPCACHE_DATARANGE, *PKSPCACHE_DATARANGE; + + +typedef struct +{ + CLSID Medium; + ULONG dw1; + ULONG dw2; +}KSPCACHE_MEDIUM; + diff --git a/drivers/ksfilter/ks/methods.c b/drivers/ksfilter/ks/methods.c index 512371a6a29..6263ce0b7bb 100644 --- a/drivers/ksfilter/ks/methods.c +++ b/drivers/ksfilter/ks/methods.c @@ -8,8 +8,183 @@ #include "priv.h" +NTSTATUS +FindMethodHandler( + IN PIO_STATUS_BLOCK IoStatus, + IN const KSMETHOD_SET* MethodSet, + IN ULONG MethodSetCount, + IN PKSMETHOD Method, + IN ULONG InputBufferLength, + IN ULONG OutputBufferLength, + OUT PVOID OutputBuffer, + OUT PFNKSHANDLER *MethodHandler, + OUT PKSMETHOD_SET * Set) +{ + ULONG Index, ItemIndex; + + for(Index = 0; Index < MethodSetCount; Index++) + { + ASSERT(MethodSet[Index].Set); + + if (IsEqualGUIDAligned(&Method->Set, MethodSet[Index].Set)) + { + for(ItemIndex = 0; ItemIndex < MethodSet[Index].MethodsCount; ItemIndex++) + { + if (MethodSet[Index].MethodItem[ItemIndex].MethodId == Method->Id) + { + if (MethodSet[Index].MethodItem[ItemIndex].MinMethod > InputBufferLength) + { + /* too small input buffer */ + IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinMethod; + return STATUS_INVALID_PARAMETER; + } + + if (MethodSet[Index].MethodItem[ItemIndex].MinData > OutputBufferLength) + { + /* too small output buffer */ + IoStatus->Information = MethodSet[Index].MethodItem[ItemIndex].MinData; + return STATUS_MORE_ENTRIES; + } + if (Method->Flags & KSMETHOD_TYPE_BASICSUPPORT) + { + PULONG Flags; + PKSPROPERTY_DESCRIPTION Description; + + if (sizeof(ULONG) > OutputBufferLength) + { + /* too small buffer */ + return STATUS_INVALID_PARAMETER; + } + + /* get output buffer */ + Flags = (PULONG)OutputBuffer; + + /* set flags flags */ + *Flags = MethodSet[Index].MethodItem[ItemIndex].Flags; + + IoStatus->Information = sizeof(ULONG); + + if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) + { + /* get output buffer */ + Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer; + + /* store result */ + Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); + Description->PropTypeSet.Set = KSPROPTYPESETID_General; + Description->PropTypeSet.Id = 0; + Description->PropTypeSet.Flags = 0; + Description->MembersListCount = 0; + Description->Reserved = 0; + + IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION); + } + return STATUS_SUCCESS; + } + *MethodHandler = MethodSet[Index].MethodItem[ItemIndex].MethodHandler; + *Set = (PKSMETHOD_SET)&MethodSet[Index]; + return STATUS_SUCCESS; + } + } + } + } + return STATUS_NOT_FOUND; +} + +NTSTATUS +NTAPI +KspMethodHandlerWithAllocator( + IN PIRP Irp, + IN ULONG MethodSetsCount, + IN const KSMETHOD_SET *MethodSet, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG MethodItemSize OPTIONAL) +{ + PKSMETHOD Method; + PKSMETHOD_SET Set; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + PFNKSHANDLER MethodHandler = NULL; + ULONG Index; + LPGUID Guid; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* check if inputbuffer at least holds KSMETHOD item */ + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSMETHOD)) + { + /* invalid parameter */ + Irp->IoStatus.Information = sizeof(KSPROPERTY); + return STATUS_INVALID_BUFFER_SIZE; + } + + /* FIXME probe the input / output buffer if from user mode */ + + /* get input property request */ + Method = (PKSMETHOD)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + +// DPRINT("KspMethodHandlerWithAllocator Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); + + /* sanity check */ + ASSERT(MethodItemSize == 0 || MethodItemSize == sizeof(KSMETHOD_ITEM)); + + /* find the method handler */ + Status = FindMethodHandler(&Irp->IoStatus, MethodSet, MethodSetsCount, Method, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &MethodHandler, &Set); + + if (NT_SUCCESS(Status) && MethodHandler) + { + /* call method handler */ + KSMETHOD_SET_IRP_STORAGE(Irp) = Set; + Status = MethodHandler(Irp, Method, Irp->UserBuffer); + + if (Status == STATUS_BUFFER_TOO_SMALL) + { + /* output buffer is too small */ + if (Allocator) + { + /* allocate the requested amount */ + Status = Allocator(Irp, Irp->IoStatus.Information, FALSE); + + /* check if the block was allocated */ + if (!NT_SUCCESS(Status)) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* re-call method handler */ + Status = MethodHandler(Irp, Method, Irp->UserBuffer); + } + } + } + else if (IsEqualGUIDAligned(&Method->Set, &GUID_NULL) && Method->Id == 0 && Method->Flags == KSMETHOD_TYPE_SETSUPPORT) + { + // store output size + Irp->IoStatus.Information = sizeof(GUID) * MethodSetsCount; + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * MethodSetsCount) + { + // buffer too small + return STATUS_MORE_ENTRIES; + } + + // get output buffer + Guid = (LPGUID)Irp->UserBuffer; + + // copy property guids from property sets + for(Index = 0; Index < MethodSetsCount; Index++) + { + RtlMoveMemory(&Guid[Index], MethodSet[Index].Set, sizeof(GUID)); + } + return STATUS_SUCCESS; + } + + /* done */ + return Status; +} + /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -19,12 +194,11 @@ KsMethodHandler( IN ULONG MethodSetsCount, IN PKSMETHOD_SET MethodSet) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, NULL, 0); } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -36,12 +210,39 @@ KsMethodHandlerWithAllocator( IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG MethodItemSize OPTIONAL) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, Allocator, MethodItemSize); } + +NTSTATUS +FindFastMethodHandler( + IN ULONG FastIoCount, + IN const KSFASTMETHOD_ITEM * FastIoTable, + IN PKSMETHOD MethodId, + OUT PFNKSFASTHANDLER * FastPropertyHandler) +{ + ULONG Index; + + /* iterate through all items */ + for(Index = 0; Index < FastIoCount; Index++) + { + if (MethodId->Id == FastIoTable[Index].MethodId) + { + if (FastIoTable[Index].MethodSupported) + { + *FastPropertyHandler = FastIoTable[Index].MethodHandler; + return STATUS_SUCCESS; + } + } + + } + /* no fast property handler found */ + return STATUS_NOT_FOUND; +} + + /* - @unimplemented + @implemented */ KSDDKAPI BOOLEAN @@ -56,6 +257,68 @@ KsFastMethodHandler( IN ULONG MethodSetsCount, IN const KSMETHOD_SET* MethodSet) { - UNIMPLEMENTED; + KSMETHOD MethodRequest; + KPROCESSOR_MODE Mode; + NTSTATUS Status = STATUS_SUCCESS; + ULONG Index; + PFNKSFASTHANDLER FastMethodHandler; + + if (MethodLength < sizeof(KSPROPERTY)) + { + /* invalid request */ + return FALSE; + } + + /* get previous mode */ + Mode = ExGetPreviousMode(); + + if (Mode == KernelMode) + { + /* just copy it */ + RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); + } + else + { + /* need to probe the buffer */ + _SEH2_TRY + { + ProbeForRead(Method, sizeof(KSPROPERTY), sizeof(UCHAR)); + RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + }_SEH2_END; + + if (!NT_SUCCESS(Status)) + return FALSE; + } + + /* are there any property sets provided */ + if (MethodSetsCount) + { + /* iterate through all property sets count */ + Index = 0; + do + { + /* does the property id match */ + if (IsEqualGUIDAligned(MethodSet[Index].Set, &MethodRequest.Set)) + { + /* try to find a fast property handler */ + Status = FindFastMethodHandler(MethodSet[Index].FastIoCount, MethodSet[Index].FastIoTable, &MethodRequest, &FastMethodHandler); + + if (NT_SUCCESS(Status)) + { + /* call fast property handler */ + ASSERT(MethodLength == sizeof(KSMETHOD)); /* FIXME check if property length is bigger -> copy params */ + ASSERT(Mode == KernelMode); /* FIXME need to probe usermode output buffer */ + return FastMethodHandler(FileObject, &MethodRequest, sizeof(KSMETHOD), Data, DataLength, IoStatus); + } + } + /* move to next item */ + Index++; + }while(Index < MethodSetsCount); + } return FALSE; } diff --git a/drivers/ksfilter/ks/misc.c b/drivers/ksfilter/ks/misc.c index cc3d2cc9cca..dc814eae01e 100644 --- a/drivers/ksfilter/ks/misc.c +++ b/drivers/ksfilter/ks/misc.c @@ -175,16 +175,21 @@ KsGetObjectTypeFromIrp( } /* - @unimplemented + @implemented */ PUNKNOWN NTAPI KsGetOuterUnknown( IN PVOID Object) { - UNIMPLEMENTED - return NULL; + PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); + /* sanity check */ + ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || + BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); + + /* return objects outer unknown */ + return BasicHeader->OuterUnknown; } /* diff --git a/drivers/ksfilter/ks/pin.c b/drivers/ksfilter/ks/pin.c index 5d1ee77a6df..019e5ce6023 100644 --- a/drivers/ksfilter/ks/pin.c +++ b/drivers/ksfilter/ks/pin.c @@ -11,13 +11,17 @@ typedef struct _KSISTREAM_POINTER { - KSSTREAM_POINTER StreamPointer; PFNKSSTREAMPOINTER Callback; PIRP Irp; KTIMER Timer; KDPC TimerDpc; struct _KSISTREAM_POINTER *Next; - + PKSPIN Pin; + PVOID Data; + ULONG Offset; + ULONG Length; + KSSTREAM_POINTER StreamPointer; + KSPIN_LOCK Lock; }KSISTREAM_POINTER, *PKSISTREAM_POINTER; typedef struct @@ -28,9 +32,9 @@ typedef struct KSPROCESSPIN ProcessPin; LIST_ENTRY Entry; - IKsPinVtbl *lpVtbl; - LONG ref; + + IKsFilter * Filter; KMUTEX ProcessingMutex; PFILE_OBJECT FileObject; @@ -39,10 +43,11 @@ typedef struct LIST_ENTRY IrpList; KSPIN_LOCK IrpListLock; + volatile LONG IrpCount; PKSISTREAM_POINTER ClonedStreamPointer; - PKSISTREAM_POINTER LeadingEdgeStreamPointer; - PKSISTREAM_POINTER TrailingStreamPointer; + KSISTREAM_POINTER LeadingEdgeStreamPointer; + KSISTREAM_POINTER TrailingStreamPointer; PFNKSPINPOWER Sleep; PFNKSPINPOWER Wake; @@ -50,8 +55,425 @@ typedef struct PFNKSPINFRAMERETURN FrameReturn; PFNKSPINIRPCOMPLETION IrpCompletion; + KSCLOCK_FUNCTIONTABLE ClockTable; + PFILE_OBJECT ClockFileObject; + IKsReferenceClockVtbl * lpVtblReferenceClock; + PKSDEFAULTCLOCK DefaultClock; + + PKSWORKER PinWorker; + WORK_QUEUE_ITEM PinWorkQueueItem; + KEVENT FrameComplete; + ULONG FrameSize; + ULONG NumFrames; + PDMA_ADAPTER Dma; + ULONG MapRegisters; + }IKsPinImpl; +NTSTATUS NTAPI IKsPin_PinStatePropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI IKsPin_PinDataFormatPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI IKsPin_PinAllocatorFramingPropertyHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI IKsPin_PinStreamAllocator(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI IKsPin_PinMasterClock(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI IKsPin_PinPipeId(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + + + +DEFINE_KSPROPERTY_CONNECTIONSET(PinConnectionSet, IKsPin_PinStatePropertyHandler, IKsPin_PinDataFormatPropertyHandler, IKsPin_PinAllocatorFramingPropertyHandler); +DEFINE_KSPROPERTY_STREAMSET(PinStreamSet, IKsPin_PinStreamAllocator, IKsPin_PinMasterClock, IKsPin_PinPipeId); + +//TODO +// KSPROPSETID_Connection +// KSPROPERTY_CONNECTION_ACQUIREORDERING +// KSPROPSETID_StreamInterface +// KSPROPERTY_STREAMINTERFACE_HEADERSIZE + +KSPROPERTY_SET PinPropertySet[] = +{ + { + &KSPROPSETID_Connection, + sizeof(PinConnectionSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinConnectionSet, + 0, + NULL + }, + { + &KSPROPSETID_Stream, + sizeof(PinStreamSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinStreamSet, + 0, + NULL + } +}; + +const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Stream = {0x65aaba60L, 0x98ae, 0x11cf, {0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}}; +const GUID KSPROPSETID_Clock = {0xDF12A4C0L, 0xAC17, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + +NTSTATUS +NTAPI +IKsPin_PinStreamAllocator( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsPin_PinMasterClock( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + IKsPinImpl * This; + NTSTATUS Status = STATUS_SUCCESS; + PHANDLE Handle; + PFILE_OBJECT FileObject; + KPROCESSOR_MODE Mode; + KSPROPERTY Property; + ULONG BytesReturned; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("IKsPin_PinMasterClock\n"); + + /* sanity check */ + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext2); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* sanity check */ + ASSERT(ObjectHeader); + + /* locate ks pin implemention from KSPIN offset */ + This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); + + /* sanity check */ + ASSERT(This); + + Handle = (PHANDLE)Data; + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + if (This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE && + This->Pin.Descriptor->Dispatch && + (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK)) + { + *Handle = NULL; + Status = STATUS_SUCCESS; + } + else + { + /* no clock available */ + Status = STATUS_UNSUCCESSFUL; + } + } + else if (Request->Flags & KSPROPERTY_TYPE_SET) + { + if (This->Pin.ClientState != KSSTATE_STOP) + { + /* can only set in stopped state */ + Status = STATUS_INVALID_DEVICE_STATE; + } + else + { + if (*Handle) + { + Mode = ExGetPreviousMode(); + + Status = ObReferenceObjectByHandle(*Handle, SYNCHRONIZE | DIRECTORY_QUERY, IoFileObjectType, Mode, (PVOID*)&FileObject, NULL); + + DPRINT("IKsPin_PinMasterClock ObReferenceObjectByHandle %lx\n", Status); + if (NT_SUCCESS(Status)) + { + Property.Set = KSPROPSETID_Clock; + Property.Id = KSPROPERTY_CLOCK_FUNCTIONTABLE; + Property.Flags = KSPROPERTY_TYPE_GET; + + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE), &BytesReturned); + + DPRINT("IKsPin_PinMasterClock KSPROPERTY_CLOCK_FUNCTIONTABLE %lx\n", Status); + + if (NT_SUCCESS(Status)) + { + This->ClockFileObject = FileObject; + } + else + { + ObDereferenceObject(FileObject); + } + } + } + else + { + /* zeroing clock handle */ + RtlZeroMemory(&This->ClockTable, sizeof(KSCLOCK_FUNCTIONTABLE)); + Status = STATUS_SUCCESS; + if (This->ClockFileObject) + { + FileObject = This->ClockFileObject; + This->ClockFileObject = NULL; + + ObDereferenceObject(This->ClockFileObject); + } + } + } + } + + DPRINT("IKsPin_PinMasterClock Status %lx\n", Status); + return Status; +} + + + +NTSTATUS +NTAPI +IKsPin_PinPipeId( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +NTAPI +IKsPin_PinStatePropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + IKsPinImpl * This; + NTSTATUS Status = STATUS_SUCCESS; + KSSTATE OldState; + PKSSTATE NewState; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("IKsPin_PinStatePropertyHandler\n"); + + /* sanity check */ + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext2); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* locate ks pin implemention from KSPIN offset */ + This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); + + /* acquire control mutex */ + KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); + + /* grab state */ + NewState = (PKSSTATE)Data; + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + *NewState = This->Pin.DeviceState; + Irp->IoStatus.Information = sizeof(KSSTATE); + } + else if (Request->Flags & KSPROPERTY_TYPE_SET) + { + if (This->Pin.Descriptor->Dispatch->SetDeviceState) + { + /* backup old state */ + OldState = This->Pin.ClientState; + + /* set new state */ + This->Pin.ClientState = *NewState; + This->Pin.DeviceState = KSSTATE_RUN; + + /* check if it supported */ + Status = This->Pin.Descriptor->Dispatch->SetDeviceState(&This->Pin, *NewState, OldState); + + DPRINT("IKsPin_PinStatePropertyHandler NewState %lu Result %lx\n", *NewState, Status); + + if (!NT_SUCCESS(Status)) + { + /* revert to old state */ + This->Pin.ClientState = OldState; + This->Pin.DeviceState = OldState; + DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx Result %lx\n", *NewState, Status); + DbgBreakPoint(); + } + else + { + /* update device state */ + This->Pin.DeviceState = *NewState; + } + } + else + { + /* just set new state */ + This->Pin.DeviceState = *NewState; + This->Pin.ClientState = *NewState; + } + } + + /* release processing mutex */ + KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); + + DPRINT("IKsPin_PinStatePropertyHandler Status %lx\n", Status); + return Status; +} + +NTSTATUS +NTAPI +IKsPin_PinAllocatorFramingPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + IKsPinImpl * This; + ULONG Size; + NTSTATUS Status = STATUS_SUCCESS; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* sanity check */ + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext2); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* locate ks pin implemention from KSPIN offset */ + This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); + + /* setting allocator flags is not supported */ + ASSERT(!(Request->Flags & KSPROPERTY_TYPE_SET)); + + /* acquire control mutex */ + KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); + + if (This->Pin.Descriptor->AllocatorFraming) + { + /* calculate size */ + Size = FIELD_OFFSET(KSALLOCATOR_FRAMING_EX, FramingItem[0]) + This->Pin.Descriptor->AllocatorFraming->CountItems * sizeof(KS_FRAMING_ITEM); + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) + { + /* no buffer */ + Status = STATUS_BUFFER_OVERFLOW; + } + else if (Size > IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* buffer too small */ + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + /* copy buffer */ + RtlMoveMemory(Data, This->Pin.Descriptor->AllocatorFraming, Size); + } + + /* store size */ + Irp->IoStatus.Information = Size; + } + else + { + /* no allocator framing details */ + Status = STATUS_NOT_FOUND; + } + + /* release processing mutex */ + KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); + + DPRINT("IKsPin_PinAllocatorFramingPropertyHandler Status %lx\n", Status); + + return Status; +} + +NTSTATUS +NTAPI +IKsPin_PinDataFormatPropertyHandler( + IN PIRP Irp, + IN PKSPROPERTY Request, + IN OUT PVOID Data) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + IKsPinImpl * This; + NTSTATUS Status = STATUS_SUCCESS; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("IKsPin_PinDataFormatPropertyHandler\n"); + + /* sanity check */ + ASSERT(IoStack->FileObject); + ASSERT(IoStack->FileObject->FsContext2); + + /* get the object header */ + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; + + /* locate ks pin implemention from KSPIN offset */ + This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); + + /* acquire control mutex */ + KeWaitForSingleObject(This->BasicHeader.ControlMutex, Executive, KernelMode, FALSE, NULL); + + if (Request->Flags & KSPROPERTY_TYPE_GET) + { + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < This->Pin.ConnectionFormat->FormatSize) + { + /* buffer too small */ + Irp->IoStatus.Information = This->Pin.ConnectionFormat->FormatSize; + Status = STATUS_BUFFER_TOO_SMALL; + } + else + { + /* copy format */ + RtlMoveMemory(Data, This->Pin.ConnectionFormat, This->Pin.ConnectionFormat->FormatSize); + } + } + else if (Request->Flags & KSPROPERTY_TYPE_SET) + { + /* set format */ + if (This->Pin.Descriptor->Flags & KSPIN_FLAG_FIXED_FORMAT) + { + /* format cannot be changed */ + Status = STATUS_INVALID_DEVICE_REQUEST; + } + else + { + /* FIXME check if the format is supported */ + Status = _KsEdit(This->Pin.Bag, (PVOID*)&This->Pin.ConnectionFormat, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This->Pin.ConnectionFormat->FormatSize, 0); + + if (NT_SUCCESS(Status)) + { + /* store new format */ + RtlMoveMemory(This->Pin.ConnectionFormat, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength); + } + } + } + + /* release processing mutex */ + KeReleaseMutex(This->BasicHeader.ControlMutex, FALSE); + + DPRINT("IKsPin_PinDataFormatPropertyHandler Status %lx\n", Status); + + return Status; +} + NTSTATUS NTAPI IKsPin_fnQueryInterface( @@ -59,15 +481,31 @@ IKsPin_fnQueryInterface( IN REFIID refiid, OUT PVOID* Output) { - IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + NTSTATUS Status; + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { - *Output = &This->lpVtbl; + *Output = &This->BasicHeader.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; } - return STATUS_UNSUCCESSFUL; + + + if (This->BasicHeader.ClientAggregate) + { + /* using client aggregate */ + Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); + + if (NT_SUCCESS(Status)) + { + /* client aggregate supports interface */ + return Status; + } + } + + DPRINT("IKsPin_fnQueryInterface no interface\n"); + return STATUS_NOT_SUPPORTED; } ULONG @@ -75,7 +513,7 @@ NTAPI IKsPin_fnAddRef( IKsPin * iface) { - IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); return InterlockedIncrement(&This->ref); } @@ -85,7 +523,7 @@ NTAPI IKsPin_fnRelease( IKsPin * iface) { - IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtbl); + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, BasicHeader.OuterUnknown); InterlockedDecrement(&This->ref); @@ -270,6 +708,219 @@ static IKsPinVtbl vt_IKsPin = //============================================================== +NTSTATUS +NTAPI +IKsReferenceClock_fnQueryInterface( + IKsReferenceClock * iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + return IKsPin_fnQueryInterface((IKsPin*)&This->BasicHeader.OuterUnknown, refiid, Output); +} + +ULONG +NTAPI +IKsReferenceClock_fnAddRef( + IKsReferenceClock * iface) +{ + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + return IKsPin_fnAddRef((IKsPin*)&This->BasicHeader.OuterUnknown); +} + +ULONG +NTAPI +IKsReferenceClock_fnRelease( + IKsReferenceClock * iface) +{ + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + return IKsPin_fnRelease((IKsPin*)&This->BasicHeader.OuterUnknown); +} + +LONGLONG +NTAPI +IKsReferenceClock_fnGetTime( + IKsReferenceClock * iface) +{ + LONGLONG Result; + + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + + DPRINT1("IKsReferenceClock_fnGetTime\n"); + + if (!This->ClockFileObject || !This->ClockTable.GetTime) + { + Result = 0; + } + else + { + Result = This->ClockTable.GetTime(This->ClockFileObject); + } + + return Result; +} + +LONGLONG +NTAPI +IKsReferenceClock_fnGetPhysicalTime( + IKsReferenceClock * iface) +{ + LONGLONG Result; + + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n"); + + + if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime) + { + Result = 0; + } + else + { + Result = This->ClockTable.GetPhysicalTime(This->ClockFileObject); + } + + return Result; +} + + +LONGLONG +NTAPI +IKsReferenceClock_fnGetCorrelatedTime( + IKsReferenceClock * iface, + OUT PLONGLONG SystemTime) +{ + LONGLONG Result; + + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n"); + + if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime) + { + Result = 0; + } + else + { + Result = This->ClockTable.GetCorrelatedTime(This->ClockFileObject, SystemTime); + } + + return Result; +} + + +LONGLONG +NTAPI +IKsReferenceClock_fnGetCorrelatedPhysicalTime( + IKsReferenceClock * iface, + OUT PLONGLONG SystemTime) +{ + LONGLONG Result; + + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n"); + + if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime) + { + Result = 0; + } + else + { + Result = This->ClockTable.GetCorrelatedPhysicalTime(This->ClockFileObject, SystemTime); + } + + return Result; +} + +NTSTATUS +NTAPI +IKsReferenceClock_fnGetResolution( + IKsReferenceClock * iface, + OUT PKSRESOLUTION Resolution) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetResolution\n"); + + if (!This->ClockFileObject) + { + Resolution->Error = 0; + Resolution->Granularity = 1; + DPRINT1("IKsReferenceClock_fnGetResolution Using HACK\n"); + return STATUS_SUCCESS; + } + + + if (!This->ClockFileObject) + return STATUS_DEVICE_NOT_READY; + + + Property.Set = KSPROPSETID_Clock; + Property.Id = KSPROPERTY_CLOCK_RESOLUTION; + Property.Flags = KSPROPERTY_TYPE_GET; + + return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), Resolution, sizeof(KSRESOLUTION), &BytesReturned); + +} + +NTSTATUS +NTAPI +IKsReferenceClock_fnGetState( + IKsReferenceClock * iface, + OUT PKSSTATE State) +{ + KSPROPERTY Property; + ULONG BytesReturned; + + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl, lpVtblReferenceClock); + + DPRINT1("IKsReferenceClock_fnGetState\n"); + + if (!This->ClockFileObject) + { + *State = This->Pin.ClientState; + DPRINT1("IKsReferenceClock_fnGetState Using HACK\n"); + return STATUS_SUCCESS; + } + + + if (!This->ClockFileObject) + return STATUS_DEVICE_NOT_READY; + + + Property.Set = KSPROPSETID_Clock; + Property.Id = KSPROPERTY_CLOCK_RESOLUTION; + Property.Flags = KSPROPERTY_TYPE_GET; + + return KsSynchronousIoControlDevice(This->ClockFileObject, KernelMode, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), State, sizeof(KSSTATE), &BytesReturned); +} + +static IKsReferenceClockVtbl vt_ReferenceClock = +{ + IKsReferenceClock_fnQueryInterface, + IKsReferenceClock_fnAddRef, + IKsReferenceClock_fnRelease, + IKsReferenceClock_fnGetTime, + IKsReferenceClock_fnGetPhysicalTime, + IKsReferenceClock_fnGetCorrelatedTime, + IKsReferenceClock_fnGetCorrelatedPhysicalTime, + IKsReferenceClock_fnGetResolution, + IKsReferenceClock_fnGetState +}; + + +//============================================================== + + /* @implemented */ @@ -340,6 +991,7 @@ KsPinAttemptProcessing( IN BOOLEAN Asynchronous) { DPRINT("KsPinAttemptProcessing\n"); + DbgBreakPoint(); UNIMPLEMENTED } @@ -448,17 +1100,26 @@ KsPinGetParentFilter( } /* - @unimplemented + @implemented */ NTSTATUS NTAPI - KsPinGetReferenceClockInterface( +KsPinGetReferenceClockInterface( IN PKSPIN Pin, OUT PIKSREFERENCECLOCK* Interface) { - UNIMPLEMENTED - DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p\n", Pin, Interface); - return STATUS_UNSUCCESSFUL; + NTSTATUS Status = STATUS_DEVICE_NOT_READY; + IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + if (This->ClockFileObject) + { + /* clock is available */ + *Interface = (PIKSREFERENCECLOCK)&This->lpVtblReferenceClock; + Status = STATUS_SUCCESS; + } + + DPRINT("KsPinGetReferenceClockInterface Pin %p Interface %p Status %x\n", Pin, Interface, Status); + return Status; } /* @@ -547,15 +1208,26 @@ KsGetPinFromIrp( IN PIRP Irp) { PKSIOBJECT_HEADER ObjectHeader; + PKSPIN Pin; + PKSBASIC_HEADER Header; PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp); DPRINT("KsGetPinFromIrp\n"); /* get object header */ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2; - /* return object type */ - return (PKSPIN)ObjectHeader->ObjectType; + if (!ObjectHeader) + return NULL; + + Pin = (PKSPIN)ObjectHeader->ObjectType; + Header = (PKSBASIC_HEADER)((ULONG_PTR)Pin - sizeof(KSBASIC_HEADER)); + + /* sanity check */ + ASSERT(Header->Type == KsObjectTypePin); + + /* return object type */ + return Pin; } @@ -617,6 +1289,85 @@ KsProcessPinUpdate( return FALSE; } +NTSTATUS +IKsPin_PrepareStreamHeader( + IN IKsPinImpl * This, + IN PKSISTREAM_POINTER StreamPointer) +{ + PKSSTREAM_HEADER Header; + ULONG Length; + + /* grab new irp */ + StreamPointer->Irp = KsRemoveIrpFromCancelableQueue(&This->IrpList, &This->IrpListLock, KsListEntryHead, KsAcquireAndRemoveOnlySingleItem); + if (!StreamPointer->Irp) + { + /* run out of mappings */ + DPRINT("OutOfMappings\n"); + return STATUS_DEVICE_NOT_READY; + } + + InterlockedDecrement(&This->IrpCount); + KsDecrementCountedWorker(This->PinWorker); + + /* get stream header */ + if (StreamPointer->Irp->RequestorMode == UserMode) + Header = (PKSSTREAM_HEADER)StreamPointer->Irp->AssociatedIrp.SystemBuffer; + else + Header = (PKSSTREAM_HEADER)StreamPointer->Irp->UserBuffer; + + /* initialize stream pointer */ + StreamPointer->Callback = NULL; + StreamPointer->Length = max(Header->DataUsed, Header->FrameExtent); + StreamPointer->Next = NULL; + StreamPointer->Offset = 0; + StreamPointer->Pin = &This->Pin; + StreamPointer->Data = Header->Data; + + StreamPointer->StreamPointer.Context = NULL; + StreamPointer->StreamPointer.Pin = &This->Pin; + StreamPointer->StreamPointer.StreamHeader = Header; + + if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) + StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetIn; + else + StreamPointer->StreamPointer.Offset = &StreamPointer->StreamPointer.OffsetOut; + + StreamPointer->StreamPointer.Offset->Alignment = 0; + StreamPointer->StreamPointer.Offset->Count = 0; + StreamPointer->StreamPointer.Offset->Data = NULL; + StreamPointer->StreamPointer.Offset->Remaining = 0; + + ASSERT(StreamPointer->StreamPointer.Offset->Remaining == 0); + + //StreamPointer->Offset += StreamPointer->StreamPointer.Offset->Count; + + ASSERT(StreamPointer->Length > StreamPointer->Offset); + ASSERT(StreamPointer->StreamPointer.StreamHeader); + ASSERT(This->FrameSize); + + /* calculate length */ + /* TODO split into frames */ + Length = StreamPointer->Length; + + /* FIXME */ + ASSERT(Length); + + StreamPointer->StreamPointer.Offset->Alignment = 0; + StreamPointer->StreamPointer.Context = NULL; + StreamPointer->StreamPointer.Pin = &This->Pin; + StreamPointer->StreamPointer.Offset->Count = Length; + StreamPointer->StreamPointer.Offset->Remaining = Length; + StreamPointer->StreamPointer.Offset->Data = (PVOID)((ULONG_PTR)StreamPointer->Data + StreamPointer->Offset); + StreamPointer->StreamPointer.StreamHeader->FrameExtent = Length; + if (StreamPointer->StreamPointer.StreamHeader->DataUsed) + StreamPointer->StreamPointer.StreamHeader->DataUsed = Length; + + StreamPointer->StreamPointer.StreamHeader->Data = StreamPointer->StreamPointer.Offset->Data; + + return STATUS_SUCCESS; +} + + /* @unimplemented */ @@ -627,9 +1378,31 @@ KsPinGetLeadingEdgeStreamPointer( IN PKSPIN Pin, IN KSSTREAM_POINTER_STATE State) { - UNIMPLEMENTED - DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x\n", Pin, State); - return NULL; + IKsPinImpl * This; + NTSTATUS Status; + + This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + DPRINT("KsPinGetLeadingEdgeStreamPointer Pin %p State %x Count %lu Remaining %lu\n", Pin, State, + This->LeadingEdgeStreamPointer.Length, + This->LeadingEdgeStreamPointer.Offset); + + /* sanity check */ + ASSERT(State == KSSTREAM_POINTER_STATE_LOCKED); + + if (State == KSSTREAM_POINTER_STATE_LOCKED) + { + if (!This->LeadingEdgeStreamPointer.Irp || This->LeadingEdgeStreamPointer.StreamPointer.Offset->Remaining == 0) + { + Status = IKsPin_PrepareStreamHeader(This, &This->LeadingEdgeStreamPointer); + if (!NT_SUCCESS(Status)) + return NULL; + } + + DPRINT("KsPinGetLeadingEdgeStreamPointer NewOffset %lu TotalLength %lu\n", This->LeadingEdgeStreamPointer.Offset, This->LeadingEdgeStreamPointer.Length); + } + + return &This->LeadingEdgeStreamPointer.StreamPointer; } /* @@ -683,8 +1456,11 @@ KsStreamPointerUnlock( IN PKSSTREAM_POINTER StreamPointer, IN BOOLEAN Eject) { - UNIMPLEMENTED - DPRINT("KsStreamPointerUnlock\n"); + PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); + + DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer, Eject); + + Pointer->Irp = NULL; } /* @@ -699,8 +1475,8 @@ KsStreamPointerAdvanceOffsetsAndUnlock( IN ULONG OutUsed, IN BOOLEAN Eject) { - DPRINT("KsStreamPointerAdvanceOffsets\n"); - + DPRINT("KsStreamPointerAdvanceOffsets InUsed %lu OutUsed %lu Eject %lu\n", InUsed, OutUsed, Eject); + DbgBreakPoint(); UNIMPLEMENTED } @@ -715,10 +1491,10 @@ KsStreamPointerDelete( { IKsPinImpl * This; PKSISTREAM_POINTER Cur, Last; - PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer; - - DPRINT("KsStreamPointerDelete\n"); + PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); + DPRINT("KsStreamPointerDelete %p\n", Pointer); +DbgBreakPoint(); This = (IKsPinImpl*)CONTAINING_RECORD(Pointer->StreamPointer.Pin, IKsPinImpl, Pin); /* point to first stream pointer */ @@ -753,7 +1529,7 @@ KsStreamPointerDelete( } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -764,13 +1540,79 @@ KsStreamPointerClone( IN ULONG ContextSize, OUT PKSSTREAM_POINTER* CloneStreamPointer) { - UNIMPLEMENTED - DPRINT("KsStreamPointerClone\n"); - return STATUS_NOT_IMPLEMENTED; + IKsPinImpl * This; + PKSISTREAM_POINTER CurFrame; + PKSISTREAM_POINTER NewFrame; + ULONG RefCount; + NTSTATUS Status; + ULONG Size; + + DPRINT("KsStreamPointerClone StreamPointer %p CancelCallback %p ContextSize %p CloneStreamPointer %p\n", StreamPointer, CancelCallback, ContextSize, CloneStreamPointer); + + /* get stream pointer */ + CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); + + /* calculate context size */ + Size = sizeof(KSISTREAM_POINTER) + ContextSize; + + /* allocate new stream pointer */ + NewFrame = (PKSISTREAM_POINTER)ExAllocatePool(NonPagedPool, Size); + + if (!NewFrame) + return STATUS_INSUFFICIENT_RESOURCES; + + /* get current irp stack location */ + RefCount = (ULONG)CurFrame->Irp->Tail.Overlay.DriverContext[0]; + + /* increment reference count */ + RefCount++; + CurFrame->Irp->Tail.Overlay.DriverContext[0] = (PVOID)RefCount; + + /* copy stream pointer */ + RtlMoveMemory(NewFrame, CurFrame, sizeof(KSISTREAM_POINTER)); + + /* locate pin */ + This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin); + + /* prepare stream header in case required */ + if (CurFrame->StreamPointer.Offset->Remaining == 0) + { + Status = IKsPin_PrepareStreamHeader(This, NewFrame); + if (!NT_SUCCESS(Status)) + { + FreeItem(NewFrame); + return STATUS_DEVICE_NOT_READY; + } + } + + if (ContextSize) + NewFrame->StreamPointer.Context = (NewFrame + 1); + + + if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) + NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetIn; + else + NewFrame->StreamPointer.Offset = &NewFrame->StreamPointer.OffsetOut; + + + + NewFrame->StreamPointer.Pin = &This->Pin; + + ASSERT(NewFrame->StreamPointer.Pin); + ASSERT(NewFrame->StreamPointer.Context); + ASSERT(NewFrame->StreamPointer.Offset); + ASSERT(NewFrame->StreamPointer.StreamHeader); + + /* store result */ + *CloneStreamPointer = &NewFrame->StreamPointer; + + DPRINT("KsStreamPointerClone CloneStreamPointer %p\n", *CloneStreamPointer); + + return STATUS_SUCCESS; } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -781,8 +1623,52 @@ KsStreamPointerAdvanceOffsets( IN ULONG OutUsed, IN BOOLEAN Eject) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PKSISTREAM_POINTER CurFrame; + IKsPinImpl * This; + NTSTATUS Status; + + DPRINT("KsStreamPointerAdvanceOffsets StreamPointer %p InUsed %lu OutUsed %lu Eject %lu\n", StreamPointer, InUsed, OutUsed, Eject); + + /* get stream pointer */ + CurFrame = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); + + /* locate pin */ + This = (IKsPinImpl*)CONTAINING_RECORD(CurFrame->Pin, IKsPinImpl, Pin); + + /* TODO */ + ASSERT(InUsed == 0); + ASSERT(Eject == 0); + ASSERT(OutUsed); + + DPRINT("KsStreamPointerAdvanceOffsets Offset %lu Length %lu NewOffset %lu Remaining %lu LeadingEdge %p DataUsed %lu\n", CurFrame->Offset, CurFrame->Length, CurFrame->Offset + OutUsed, +CurFrame->StreamPointer.OffsetOut.Remaining, &This->LeadingEdgeStreamPointer.StreamPointer, CurFrame->StreamPointer.StreamHeader->DataUsed); +DbgBreakPoint(); + + if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) + { + ASSERT(CurFrame->StreamPointer.OffsetIn.Remaining >= InUsed); + CurFrame->StreamPointer.OffsetIn.Remaining -= InUsed; + CurFrame->StreamPointer.OffsetIn.Data = (PVOID)((ULONG_PTR)CurFrame->StreamPointer.OffsetIn.Data + InUsed); + } + else + { + if (!CurFrame->StreamPointer.OffsetOut.Remaining) + { + Status = IKsPin_PrepareStreamHeader(This, CurFrame); + if (!NT_SUCCESS(Status)) + { + return STATUS_DEVICE_NOT_READY; + } + } + else + { + ASSERT(CurFrame->StreamPointer.OffsetOut.Remaining >= OutUsed); + CurFrame->StreamPointer.OffsetOut.Remaining -= OutUsed; + CurFrame->StreamPointer.OffsetOut.Data = (PVOID)((ULONG_PTR)CurFrame->StreamPointer.OffsetOut.Data + OutUsed); + } + } + + return STATUS_SUCCESS; } /* @@ -795,6 +1681,7 @@ KsStreamPointerAdvance( IN PKSSTREAM_POINTER StreamPointer) { UNIMPLEMENTED + DbgBreakPoint(); return STATUS_NOT_IMPLEMENTED; } @@ -838,7 +1725,10 @@ KsStreamPointerScheduleTimeout( IN ULONGLONG Interval) { LARGE_INTEGER DueTime; - PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer; + PKSISTREAM_POINTER Pointer; + + /* get stream pointer */ + Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); /* setup timer callback */ Pointer->Callback = Callback; @@ -860,7 +1750,10 @@ NTAPI KsStreamPointerCancelTimeout( IN PKSSTREAM_POINTER StreamPointer) { - PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer; + PKSISTREAM_POINTER Pointer; + + /* get stream pointer */ + Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); KeCancelTimer(&Pointer->Timer); @@ -880,6 +1773,10 @@ KsPinGetFirstCloneStreamPointer( DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin); This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + if (!This->ClonedStreamPointer) + return NULL; + /* return first cloned stream pointer */ return &This->ClonedStreamPointer->StreamPointer; } @@ -893,9 +1790,12 @@ NTAPI KsStreamPointerGetNextClone( IN PKSSTREAM_POINTER StreamPointer) { - PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)StreamPointer; + PKSISTREAM_POINTER Pointer; DPRINT("KsStreamPointerGetNextClone\n"); +DbgBreakPoint(); + /* get stream pointer */ + Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER, StreamPointer); /* is there a another cloned stream pointer */ if (!Pointer->Next) @@ -905,67 +1805,174 @@ KsStreamPointerGetNextClone( return &Pointer->Next->StreamPointer; } +VOID +NTAPI +IKsPin_PinCentricWorker( + IN PVOID Parameter) +{ + NTSTATUS Status; + IKsPinImpl * This = (IKsPinImpl*)Parameter; + + DPRINT("IKsPin_PinCentricWorker\n"); + + /* sanity checks */ + ASSERT(This); + ASSERT(This->Pin.Descriptor); + ASSERT(This->Pin.Descriptor->Dispatch); + ASSERT(This->Pin.Descriptor->Dispatch->Process); + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING)); + ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_GENERATE_MAPPINGS)); + + do + { + DPRINT("IKsPin_PinCentricWorker calling Pin Process Routine\n"); + + Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin); + DPRINT("IKsPin_PinCentricWorker Status %lx, Offset %lu Length %lu\n", Status, + This->LeadingEdgeStreamPointer.Offset, + This->LeadingEdgeStreamPointer.Length); + break; + + }while(This->IrpCount); +} + + NTSTATUS -IKsPin_DispatchKsProperty( +NTAPI +IKsPin_DispatchKsStream( PDEVICE_OBJECT DeviceObject, PIRP Irp, IKsPinImpl * This) { - NTSTATUS Status; - PKSPROPERTY Property; + PKSPROCESSPIN_INDEXENTRY ProcessPinIndex; + PKSSTREAM_HEADER Header; + ULONG NumHeaders; + PKSFILTER Filter; PIO_STACK_LOCATION IoStack; - UNICODE_STRING GuidString; - ULONG PropertySetsCount = 0, PropertyItemSize = 0; - const KSPROPERTY_SET* PropertySets = NULL; + NTSTATUS Status = STATUS_SUCCESS; - /* sanity check */ - ASSERT(This->Pin.Descriptor); + DPRINT("IKsPin_DispatchKsStream\n"); - /* get current irp stack */ + /* FIXME handle reset states */ + ASSERT(This->Pin.ResetState == KSRESET_END); + + /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); + /* probe stream pointer */ + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) + Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, This->Pin.StreamHeaderSize); + else + Status = KsProbeStreamIrp(Irp, KSSTREAM_READ | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_SYSTEMADDRESS, This->Pin.StreamHeaderSize); - if (This->Pin.Descriptor->AutomationTable) + if (!NT_SUCCESS(Status)) { - /* use available driver property sets */ - PropertySetsCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount; - PropertySets = This->Pin.Descriptor->AutomationTable->PropertySets; - PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize; - } + DPRINT1("KsProbeStreamIrp failed with %x\n", Status); - - /* try driver provided property sets */ - Status = KspPropertyHandler(Irp, - PropertySetsCount, - PropertySets, - NULL, - PropertyItemSize); - - DPRINT("IKsPin_DispatchKsProperty PropertySetCount %lu Status %lu\n", PropertySetsCount, Status); - - if (Status != STATUS_NOT_FOUND) - { - /* property was handled by driver */ - if (Status != STATUS_PENDING) - { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } - /* property was not handled */ - Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + if (Irp->RequestorMode == UserMode) + Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + else + Header = (PKSSTREAM_HEADER)Irp->UserBuffer; - RtlStringFromGUID(&Property->Set, &GuidString); - DPRINT("IKsPin_DispatchKsProperty Unhandled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - RtlFreeUnicodeString(&GuidString); + if (!Header) + { + DPRINT("NoHeader Canceling Irp %p\n", Irp); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } - Irp->IoStatus.Status = STATUS_NOT_FOUND; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* calculate num headers */ + NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength / Header->Size; - return STATUS_NOT_FOUND; + /* assume headers of same length */ + ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength % Header->Size == 0); + /* FIXME support multiple stream headers */ + ASSERT(NumHeaders == 1); + + if (Irp->RequestorMode == UserMode) + { + /* prepare header */ + ASSERT(Irp->MdlAddress); + Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + + if (!Header->Data) + { + DPRINT("NoHeader->Data Canceling Irp %p\n", Irp); + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + } + + + + if (This->Pin.Descriptor->Dispatch->Process) + { + /* it is a pin centric avstream */ + + /* mark irp as pending */ + IoMarkIrpPending(Irp); + + /* add irp to cancelable queue */ + KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */); + + /* sanity checks */ + ASSERT(!(This->Pin.Descriptor->Flags & KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING)); + ASSERT(This->PinWorker); + + InterlockedIncrement(&This->IrpCount); + + DPRINT("IKsPin_DispatchKsStream IrpCount %lu\n", This->IrpCount); + + /* start the processing loop */ + KsIncrementCountedWorker(This->PinWorker); + + Status = STATUS_PENDING; + } + else + { + /* filter-centric avstream */ + ASSERT(This->Filter); + + ProcessPinIndex = This->Filter->lpVtbl->GetProcessDispatch(This->Filter); + Filter = This->Filter->lpVtbl->GetStruct(This->Filter); + + ASSERT(ProcessPinIndex); + ASSERT(Filter); + ASSERT(Filter->Descriptor); + ASSERT(Filter->Descriptor->Dispatch); + + if (!Filter->Descriptor->Dispatch->Process) + { + /* invalid device request */ + DPRINT("Filter Centric Processing No Process Routine\n"); + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + /* mark irp as pending */ + IoMarkIrpPending(Irp); + + /* add irp to cancelable queue */ + KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */); + + Status = Filter->Descriptor->Dispatch->Process(Filter, ProcessPinIndex); + + DPRINT("IKsPin_DispatchKsStream FilterCentric: Status %lx \n", Status); + + } + + return Status; } NTSTATUS @@ -977,7 +1984,10 @@ IKsPin_DispatchDeviceIoControl( PIO_STACK_LOCATION IoStack; PKSIOBJECT_HEADER ObjectHeader; IKsPinImpl * This; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; + UNICODE_STRING GuidString; + PKSPROPERTY Property; + ULONG SetCount = 0; /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -992,43 +2002,99 @@ IKsPin_DispatchDeviceIoControl( /* locate ks pin implemention from KSPIN offset */ This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); - if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) + /* current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM || + IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM) { - /* handle ks properties */ - return IKsPin_DispatchKsProperty(DeviceObject, Irp, This); + /* handle ks stream packets */ + return IKsPin_DispatchKsStream(DeviceObject, Irp, This); } + /* get property from input buffer */ + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_WRITE_STREAM && IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_READ_STREAM) + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSIDENTIFIER)); + ASSERT(This->Pin.Descriptor->AutomationTable); + + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_METHOD) { - UNIMPLEMENTED; - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + const KSMETHOD_SET *MethodSet = NULL; + ULONG MethodItemSize = 0; + + /* check if the driver supports method sets */ + if (This->Pin.Descriptor->AutomationTable->MethodSetsCount) + { + SetCount = This->Pin.Descriptor->AutomationTable->MethodSetsCount; + MethodSet = This->Pin.Descriptor->AutomationTable->MethodSets; + MethodItemSize = This->Pin.Descriptor->AutomationTable->MethodItemSize; + } + + /* call method set handler */ + Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL, MethodItemSize); } - - /* mark irp as pending */ - IoMarkIrpPending(Irp); - - /* add irp to cancelable queue */ - KsAddIrpToCancelableQueue(&This->IrpList, &This->IrpListLock, Irp, KsListEntryTail, NULL /* FIXME */); - - if (This->Pin.Descriptor->Dispatch->Process) + else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { - /* it is a pin centric avstream */ - Status = This->Pin.Descriptor->Dispatch->Process(&This->Pin); + const KSPROPERTY_SET *PropertySet = NULL; + ULONG PropertyItemSize = 0; - /* TODO */ + /* check if the driver supports method sets */ + if (This->Pin.Descriptor->AutomationTable->PropertySetsCount) + { + SetCount = This->Pin.Descriptor->AutomationTable->PropertySetsCount; + PropertySet = This->Pin.Descriptor->AutomationTable->PropertySets; + PropertyItemSize = This->Pin.Descriptor->AutomationTable->PropertyItemSize; + } + + /* needed for our property handlers */ + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This; + + /* call property handler */ + Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize); } else { - /* TODO - * filter-centric avstream - */ - UNIMPLEMENTED + /* sanity check */ + ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT || + IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) + { + /* call enable event handlers */ + Status = KspEnableEvent(Irp, + This->Pin.Descriptor->AutomationTable->EventSetsCount, + (PKSEVENT_SET)This->Pin.Descriptor->AutomationTable->EventSets, + &This->BasicHeader.EventList, + KSEVENTS_SPINLOCK, + (PVOID)&This->BasicHeader.EventListLock, + NULL, + This->Pin.Descriptor->AutomationTable->EventItemSize); + } + else + { + /* disable event handler */ + Status = KsDisableEvent(Irp, &This->BasicHeader.EventList, KSEVENTS_SPINLOCK, &This->BasicHeader.EventListLock); + } } + RtlStringFromGUID(&Property->Set, &GuidString); + DPRINT("IKsPin_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information); + RtlFreeUnicodeString(&GuidString); + + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + /* done */ return Status; } @@ -1056,9 +2122,6 @@ IKsPin_Close( /* locate ks pin implemention fro KSPIN offset */ This = (IKsPinImpl*)CONTAINING_RECORD(ObjectHeader->ObjectType, IKsPinImpl, Pin); - /* acquire filter control mutex */ - KsFilterAcquireControl(This->BasicHeader.Parent.KsFilter); - if (This->Pin.Descriptor->Dispatch->Close) { /* call pin close routine */ @@ -1072,7 +2135,8 @@ IKsPin_Close( return Status; } - /* FIXME remove pin from filter pin list and decrement reference count */ + /* remove pin from filter pin list and decrement reference count */ + IKsFilter_RemovePin(This->Filter->lpVtbl->GetStruct(This->Filter), &This->Pin); if (Status != STATUS_PENDING) { @@ -1104,11 +2168,80 @@ IKsPin_DispatchCreateClock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; + PKSPIN Pin; + NTSTATUS Status = STATUS_SUCCESS; + IKsPinImpl * This; + KSRESOLUTION Resolution; + PKSRESOLUTION pResolution = NULL; + PKSOBJECT_CREATE_ITEM CreateItem; - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + DPRINT("IKsPin_DispatchCreateClock\n"); + + /* get the create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + + /* sanity check */ + ASSERT(CreateItem); + + /* get the pin object */ + Pin = (PKSPIN)CreateItem->Context; + + /* sanity check */ + ASSERT(Pin); + + /* locate ks pin implemention fro KSPIN offset */ + This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin); + + /* sanity check */ + ASSERT(This->BasicHeader.Type == KsObjectTypePin); + ASSERT(This->BasicHeader.ControlMutex); + + /* acquire control mutex */ + KsAcquireControl(Pin); + + if ((This->Pin.Descriptor->PinDescriptor.Communication != KSPIN_COMMUNICATION_NONE && + This->Pin.Descriptor->Dispatch) || + (This->Pin.Descriptor->Flags & KSPIN_FLAG_IMPLEMENT_CLOCK)) + { + if (!This->DefaultClock) + { + if (This->Pin.Descriptor->Dispatch && This->Pin.Descriptor->Dispatch->Clock) + { + if (This->Pin.Descriptor->Dispatch->Clock->Resolution) + { + This->Pin.Descriptor->Dispatch->Clock->Resolution(&This->Pin, &Resolution); + pResolution = &Resolution; + } + + Status = KsAllocateDefaultClockEx(&This->DefaultClock, + (PVOID)&This->Pin, + (PFNKSSETTIMER)This->Pin.Descriptor->Dispatch->Clock->SetTimer, + (PFNKSCANCELTIMER)This->Pin.Descriptor->Dispatch->Clock->CancelTimer, + (PFNKSCORRELATEDTIME)This->Pin.Descriptor->Dispatch->Clock->CorrelatedTime, + pResolution, + 0); + } + else + { + Status = KsAllocateDefaultClockEx(&This->DefaultClock, (PVOID)&This->Pin, NULL, NULL, NULL, NULL, 0); + } + } + + if (NT_SUCCESS(Status)) + { + Status = KsCreateDefaultClock(Irp, This->DefaultClock); + } + } + + DPRINT("IKsPin_DispatchCreateClock %lx\n", Status); + + /* release control mutex */ + KsReleaseControl(Pin); + + /* done */ + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_NOT_IMPLEMENTED; + return Status; } NTSTATUS @@ -1141,7 +2274,7 @@ static KSDISPATCH_TABLE PinDispatchTable = NTSTATUS KspCreatePin( IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, + IN PIRP Irp, IN PKSDEVICE KsDevice, IN IKsFilterFactory * FilterFactory, IN IKsFilter* Filter, @@ -1155,11 +2288,86 @@ KspCreatePin( PKSOBJECT_CREATE_ITEM CreateItem; NTSTATUS Status; PKSDATAFORMAT DataFormat; + PKSBASIC_HEADER BasicHeader; + ULONG Index; + ULONG FrameSize = 0; + ULONG NumFrames = 0; + KSAUTOMATION_TABLE AutomationTable; /* sanity checks */ ASSERT(Descriptor->Dispatch); - DPRINT("KspCreatePin\n"); + DPRINT("KspCreatePin PinId %lu Flags %x\n", Connect->PinId, Descriptor->Flags); + +//Output Pin: KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY +//Input Pin: KSPIN_FLAG_FIXED_FORMAT|KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT|KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING + + DPRINT("KspCreatePin Dataflow %lu\n", Descriptor->PinDescriptor.DataFlow); + DPRINT("KspCreatePin Communication %lu\n", Descriptor->PinDescriptor.Communication); + if (Descriptor->AllocatorFraming) + { + DPRINT("KspCreatePin CountItems %lu\n", Descriptor->AllocatorFraming->CountItems); + DPRINT("KspCreatePin PinFlags %lx\n", Descriptor->AllocatorFraming->PinFlags); + DPRINT("KspCreatePin OutputCompression RatioNumerator %lu RatioDenominator %lu RatioConstantMargin %lu\n", Descriptor->AllocatorFraming->OutputCompression.RatioNumerator, + Descriptor->AllocatorFraming->OutputCompression.RatioDenominator, Descriptor->AllocatorFraming->OutputCompression.RatioConstantMargin); + DPRINT("KspCreatePin PinWeight %lx\n", Descriptor->AllocatorFraming->PinWeight); + + for(Index = 0; Index < Descriptor->AllocatorFraming->CountItems; Index++) + { + DPRINT("KspCreatePin Index %lu MemoryFlags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].MemoryFlags); + DPRINT("KspCreatePin Index %lu BusFlags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].BusFlags); + DPRINT("KspCreatePin Index %lu Flags %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].Flags); + DPRINT("KspCreatePin Index %lu Frames %lu\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].Frames); + DPRINT("KspCreatePin Index %lu FileAlignment %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].FileAlignment); + DPRINT("KspCreatePin Index %lu MemoryTypeWeight %lx\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].MemoryTypeWeight); + DPRINT("KspCreatePin Index %lu PhysicalRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu\n", Index, Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.MinFrameSize, + Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.MaxFrameSize, + Descriptor->AllocatorFraming->FramingItem[Index].PhysicalRange.Stepping); + + DPRINT("KspCreatePin Index %lu FramingRange MinFrameSize %lu MaxFrameSize %lu Stepping %lu InPlaceWeight %lu NotInPlaceWeight %lu\n", + Index, + Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MinFrameSize, + Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MaxFrameSize, + Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.Stepping, + Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.InPlaceWeight, + Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.NotInPlaceWeight); + + FrameSize = Descriptor->AllocatorFraming->FramingItem[Index].FramingRange.Range.MaxFrameSize; + NumFrames = Descriptor->AllocatorFraming->FramingItem[Index].Frames; + } + } + + for (Index = 0; Index < Descriptor->PinDescriptor.DataRangesCount; Index++) + { + UNICODE_STRING GuidString; + /* convert the guid to string */ + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->MajorFormat, &GuidString); + DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &GuidString); + DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer); + RtlStringFromGUID(&Descriptor->PinDescriptor.DataRanges[Index]->Specifier, &GuidString); + DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index, + Descriptor->PinDescriptor.DataRanges[Index]->FormatSize, Descriptor->PinDescriptor.DataRanges[Index]->Flags, Descriptor->PinDescriptor.DataRanges[Index]->SampleSize, Descriptor->PinDescriptor.DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT)); + + if (IsEqualGUIDAligned(&Descriptor->PinDescriptor.DataRanges[Index]->SubFormat, &KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT)) + { + PKS_DATARANGE_BDA_TRANSPORT Transport = (PKS_DATARANGE_BDA_TRANSPORT)&Descriptor->PinDescriptor.DataRanges[Index]; + DPRINT("KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT AvgTimePerFrame %I64u ulcbPhyiscalFrame %lu ulcbPhyiscalFrameAlignment %lu ulcbPhyiscalPacket %lu\n", Transport->BdaTransportInfo.AvgTimePerFrame, Transport->BdaTransportInfo.ulcbPhyiscalFrame, + Transport->BdaTransportInfo.ulcbPhyiscalFrameAlignment, Transport->BdaTransportInfo.ulcbPhyiscalPacket); + } + } + if (!FrameSize) + { + /* default to 50 * 188 (MPEG2 TS packet size) */ + FrameSize = 9400; + } + + if (!NumFrames) + { + NumFrames = 8; + } /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -1168,7 +2376,7 @@ KspCreatePin( DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get ks device interface */ - Device = (IKsDevice*)&DeviceExtension->DeviceHeader->lpVtblIKsDevice; + Device = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown; /* first allocate pin ctx */ This = AllocateItem(NonPagedPool, sizeof(IKsPinImpl)); @@ -1192,19 +2400,31 @@ KspCreatePin( This->BasicHeader.KsDevice = KsDevice; This->BasicHeader.Type = KsObjectTypePin; This->BasicHeader.Parent.KsFilter = Filter->lpVtbl->GetStruct(Filter); - KeInitializeMutex(&This->BasicHeader.ControlMutex, 0); + This->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsPin; + InitializeListHead(&This->BasicHeader.EventList); + KeInitializeSpinLock(&This->BasicHeader.EventListLock); + + ASSERT(This->BasicHeader.Parent.KsFilter); + + BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)This->BasicHeader.Parent.KsFilter - sizeof(KSBASIC_HEADER)); + + This->BasicHeader.ControlMutex = BasicHeader->ControlMutex; + ASSERT(This->BasicHeader.ControlMutex); + InitializeListHead(&This->BasicHeader.EventList); KeInitializeSpinLock(&This->BasicHeader.EventListLock); /* initialize pin */ - This->lpVtbl = &vt_IKsPin; + This->FrameSize = FrameSize; + This->NumFrames = NumFrames; + This->lpVtblReferenceClock = &vt_ReferenceClock; This->ref = 1; This->FileObject = IoStack->FileObject; + This->Filter = Filter; KeInitializeMutex(&This->ProcessingMutex, 0); InitializeListHead(&This->IrpList); KeInitializeSpinLock(&This->IrpListLock); - /* allocate object bag */ This->Pin.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); if (!This->Pin.Bag) @@ -1216,13 +2436,45 @@ KspCreatePin( } /* initialize object bag */ - Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, &This->BasicHeader.ControlMutex); /* is using control mutex right? */ + Device->lpVtbl->InitializeObjectBag(Device, This->Pin.Bag, NULL); + + /* allocate pin descriptor */ + This->Pin.Descriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR_EX)); + if (!This->Pin.Descriptor) + { + /* not enough memory */ + KsFreeObjectBag(This->Pin.Bag); + FreeItem(This); + FreeItem(CreateItem); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* copy pin descriptor */ + RtlMoveMemory((PVOID)This->Pin.Descriptor, Descriptor, sizeof(KSPIN_DESCRIPTOR_EX)); + + /* initialize automation table */ + RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE)); + + AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM); + AutomationTable.PropertySets = PinPropertySet; + AutomationTable.PropertySetsCount = sizeof(PinPropertySet) / sizeof(KSPROPERTY_SET); + + /* merge in pin property sets */ + Status = KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Pin.Descriptor->AutomationTable, (PKSAUTOMATION_TABLE)Descriptor->AutomationTable, &AutomationTable, This->Pin.Bag); + + if (!NT_SUCCESS(Status)) + { + /* not enough memory */ + KsFreeObjectBag(This->Pin.Bag); + FreeItem(This); + FreeItem(CreateItem); + return Status; + } /* get format */ DataFormat = (PKSDATAFORMAT)(Connect + 1); - /* initialize ks pin descriptor */ - This->Pin.Descriptor = Descriptor; + /* initialize pin descriptor */ This->Pin.Context = NULL; This->Pin.Id = Connect->PinId; This->Pin.Communication = Descriptor->PinDescriptor.Communication; @@ -1253,19 +2505,19 @@ KspCreatePin( This->Pin.ClientState = KSSTATE_STOP; /* intialize allocator create item */ - CreateItem[0].Context = (PVOID)This; + CreateItem[0].Context = (PVOID)&This->Pin; CreateItem[0].Create = IKsPin_DispatchCreateAllocator; CreateItem[0].Flags = KSCREATE_ITEM_FREEONSTOP; RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Allocator); /* intialize clock create item */ - CreateItem[1].Context = (PVOID)This; + CreateItem[1].Context = (PVOID)&This->Pin; CreateItem[1].Create = IKsPin_DispatchCreateClock; CreateItem[1].Flags = KSCREATE_ITEM_FREEONSTOP; RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Clock); /* intialize topology node create item */ - CreateItem[2].Context = (PVOID)This; + CreateItem[2].Context = (PVOID)&This->Pin; CreateItem[2].Create = IKsPin_DispatchCreateNode; CreateItem[2].Flags = KSCREATE_ITEM_FREEONSTOP; RtlInitUnicodeString(&CreateItem[2].ObjectClass, KSSTRING_TopologyNode); @@ -1286,18 +2538,24 @@ KspCreatePin( /* add extra info to object header */ This->ObjectHeader->Type = KsObjectTypePin; - This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; + This->ObjectHeader->Unknown = (PUNKNOWN)&This->BasicHeader.OuterUnknown; This->ObjectHeader->ObjectType = (PVOID)&This->Pin; - /* setup process pin */ - This->ProcessPin.Pin = &This->Pin; - This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)This->LeadingEdgeStreamPointer; - if (!Descriptor->Dispatch || !Descriptor->Dispatch->Process) { /* the pin is part of filter-centric processing filter * add process pin to filter */ + This->ProcessPin.BytesAvailable = 0; + This->ProcessPin.BytesUsed = 0; + This->ProcessPin.CopySource = NULL; + This->ProcessPin.Data = NULL; + This->ProcessPin.DelegateBranch = NULL; + This->ProcessPin.Flags = 0; + This->ProcessPin.InPlaceCounterpart = NULL; + This->ProcessPin.Pin = &This->Pin; + This->ProcessPin.StreamPointer = (PKSSTREAM_POINTER)&This->LeadingEdgeStreamPointer.StreamPointer; + This->ProcessPin.Terminate = FALSE; Status = Filter->lpVtbl->AddProcessPin(Filter, &This->ProcessPin); DPRINT("KspCreatePin AddProcessPin %lx\n", Status); @@ -1307,13 +2565,51 @@ KspCreatePin( /* failed to add process pin */ KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); KsFreeObjectHeader(&This->ObjectHeader); - + FreeItem(This); + FreeItem(CreateItem); /* return failure code */ return Status; } } + else if (Descriptor->Dispatch && Descriptor->Dispatch->Process) + { + /* pin centric processing filter */ + + /* initialize work item */ + ExInitializeWorkItem(&This->PinWorkQueueItem, IKsPin_PinCentricWorker, (PVOID)This); + + /* allocate counted work item */ + Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->PinWorkQueueItem, &This->PinWorker); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to register Worker %lx\n", Status); + KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); + KsFreeObjectHeader(&This->ObjectHeader); + FreeItem(This); + FreeItem(CreateItem); + return Status; + } + + if (This->Pin.Descriptor->PinDescriptor.DataFlow == KSPIN_DATAFLOW_IN) + This->LeadingEdgeStreamPointer.StreamPointer.Offset = &This->LeadingEdgeStreamPointer.StreamPointer.OffsetIn; + else + This->LeadingEdgeStreamPointer.StreamPointer.Offset = &This->LeadingEdgeStreamPointer.StreamPointer.OffsetOut; + + + KeInitializeEvent(&This->FrameComplete, NotificationEvent, FALSE); + + } /* FIXME add pin instance to filter instance */ + IKsFilter_AddPin(Filter->lpVtbl->GetStruct(Filter), &This->Pin); + + if (Descriptor->Dispatch && Descriptor->Dispatch->SetDataFormat) + { + Status = Descriptor->Dispatch->SetDataFormat(&This->Pin, NULL, NULL, This->Pin.ConnectionFormat, NULL); + DPRINT("KspCreatePin SetDataFormat %lx\n", Status); + } + /* does the driver have a pin dispatch */ if (Descriptor->Dispatch && Descriptor->Dispatch->Create) @@ -1323,11 +2619,13 @@ KspCreatePin( DPRINT("KspCreatePin DispatchCreate %lx\n", Status); } - DPRINT("KspCreatePin Status %lx\n", Status); + + DPRINT("KspCreatePin Status %lx KsDevice %p\n", Status, KsDevice); if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) { /* failed to create pin, release resources */ + IKsFilter_RemovePin(Filter->lpVtbl->GetStruct(Filter), &This->Pin); KsFreeObjectHeader((KSOBJECT_HEADER)This->ObjectHeader); KsFreeObjectBag((KSOBJECT_BAG)This->Pin.Bag); FreeItem(This); diff --git a/drivers/ksfilter/ks/priv.h b/drivers/ksfilter/ks/priv.h index cc0b8f95fef..75b514158cc 100644 --- a/drivers/ksfilter/ks/priv.h +++ b/drivers/ksfilter/ks/priv.h @@ -5,6 +5,7 @@ #include #include #define NDEBUG +//#define YDEBUG #include #include #include @@ -16,8 +17,12 @@ #include "kstypes.h" #include "ksiface.h" +#include "ksmedia.h" +#include "bdamedia.h" #define TAG_DEVICE_HEADER 'KSDH' +#define REG_PINFLAG_B_MANY 0x4 /* strmif.h */ +#define MERIT_DO_NOT_USE 0x200000 /* dshow.h */ #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ @@ -35,3 +40,24 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\ DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\ } + +#define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\ + PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\ + DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(PropAllocatorFraming)\ +} + + +#define DEFINE_KSPROPERTY_STREAMSET(PinSet,\ + PropStreamAllocator, PropMasterClock, PropPipeId)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(PropStreamAllocator, PropStreamAllocator),\ + DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(PropMasterClock, PropMasterClock),\ + DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(PropPipeId, PropPipeId)\ +} + + + + diff --git a/drivers/ksfilter/ks/property.c b/drivers/ksfilter/ks/property.c index a2e759ca07a..b1a17e3ed09 100644 --- a/drivers/ksfilter/ks/property.c +++ b/drivers/ksfilter/ks/property.c @@ -137,7 +137,7 @@ KspPropertyHandler( /* get input property request */ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); +// DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); /* sanity check */ ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM)); diff --git a/drivers/ksfilter/ks/topology.c b/drivers/ksfilter/ks/topology.c index 87eb1e97c98..cc4a88880e7 100644 --- a/drivers/ksfilter/ks/topology.c +++ b/drivers/ksfilter/ks/topology.c @@ -270,13 +270,3 @@ KsTopologyPropertyHandler( return Status; } -NTSTATUS -NTAPI -KspTopologyPropertyHandler( - IN PIRP Irp, - IN PKSIDENTIFIER Request, - IN OUT PVOID Data) -{ - - return STATUS_NOT_IMPLEMENTED; -} diff --git a/drivers/multimedia/bdasup/precomp.h b/drivers/multimedia/bdasup/precomp.h index db581728221..45a603ddecd 100644 --- a/drivers/multimedia/bdasup/precomp.h +++ b/drivers/multimedia/bdasup/precomp.h @@ -3,6 +3,9 @@ #include #include #include +#define NOBITMAP +#include +#include #include #include #include diff --git a/drivers/network/ndis/ndis.def b/drivers/network/ndis/ndis.def deleted file mode 100644 index 5eba1a29842..00000000000 --- a/drivers/network/ndis/ndis.def +++ /dev/null @@ -1,298 +0,0 @@ -; NDIS Kernel Module - ReactOS Operating System - -LIBRARY NDIS.SYS - -EXPORTS -ArcFilterDprIndicateReceive@16 -ArcFilterDprIndicateReceiveComplete@4 -EthFilterDprIndicateReceive@32 -EthFilterDprIndicateReceiveComplete@4 -FddiFilterDprIndicateReceive@36 -FddiFilterDprIndicateReceiveComplete@4 -NDIS_BUFFER_TO_SPAN_PAGES@4 -NdisAcquireReadWriteLock@12 -NdisAcquireSpinLock@4 -NdisAdjustBufferLength@8 -NdisAllocateBuffer@20 -NdisAllocateBufferPool@12 -NdisAllocateDmaChannel@20 -NdisAllocateFromBlockPool@4 -NdisAllocateMemory@20 -NdisAllocateMemoryWithTag@12 -NdisAllocatePacket@12 -NdisAllocatePacketPool@16 -NdisAllocatePacketPoolEx@20 -NdisAllocateSharedMemory@20 -NdisAllocateSpinLock@4 -NdisAnsiStringToUnicodeString@8 -NdisBufferLength@4 -NdisBufferVirtualAddress@4 -NdisCancelSendPackets@8 -NdisCancelTimer@8 -NdisClAddParty@16 -NdisClCloseAddressFamily@4 -NdisClCloseCall@16 -NdisClDeregisterSap@4 -NdisClDropParty@12 -NdisClGetProtocolVcContextFromTapiCallId@12 -NdisClIncomingCallComplete@12 -NdisClMakeCall@16 -NdisClModifyCallQoS@8 -NdisClOpenAddressFamily@24 -NdisClRegisterSap@16 -NdisCloseAdapter@8 -NdisCloseConfiguration@4 -NdisCloseFile@4 -NdisCmActivateVc@8 -NdisCmAddPartyComplete@16 -NdisCmCloseAddressFamilyComplete@8 -NdisCmCloseCallComplete@12 -NdisCmDeactivateVc@4 -NdisCmDeregisterSapComplete@8 -NdisCmDispatchCallConnected@4 -NdisCmDispatchIncomingCall@12 -NdisCmDispatchIncomingCallQoSChange@8 -NdisCmDispatchIncomingCloseCall@16 -NdisCmDispatchIncomingDropParty@16 -NdisCmDropPartyComplete@8 -NdisCmMakeCallComplete@20 -NdisCmModifyCallQoSComplete@12 -NdisCmOpenAddressFamilyComplete@12 -NdisCmRegisterAddressFamily@16 -NdisCmRegisterSapComplete@12 -NdisCoAssignInstanceName@12 -NdisCoCreateVc@16 -NdisCoDeleteVc@4 -NdisCoGetTapiCallId@8 -NdisCoRequest@20 -NdisCoRequestComplete@20 -NdisCoSendPackets@12 -NdisCompareAnsiString@12 -NdisCompareUnicodeString@12 -NdisCompleteBindAdapter@12 -NdisCompleteCloseAdapter@8 -NdisCompleteDmaTransfer@24 -NdisCompleteOpenAdapter@12 -NdisCompletePnPEvent@12 -NdisCompleteQueryStatistics@12 -NdisCompleteUnbindAdapter@8 -NdisConvertStringToAtmAddress@12 -NdisCopyBuffer@24 -NdisCopyFromPacketToPacket@24 -NdisCopyFromPacketToPacketSafe@28 -NdisCreateBlockPool@16 -NdisDeregisterAdapter@4 -NdisDeregisterAdapterShutdownHandler@4 -NdisDeregisterMac@8 -NdisDeregisterProtocol@8 -NdisDeregisterTdiCallBack@0 -NdisDestroyBlockPool@4 -NdisDprAcquireSpinLock@4 -NdisDprAllocatePacket@12 -NdisDprAllocatePacketNonInterlocked@12 -NdisDprFreePacket@4 -NdisDprFreePacketNonInterlocked@4 -NdisDprReleaseSpinLock@4 -NdisEqualString@12 -NdisFreeBuffer@4 -NdisFreeBufferPool@4 -NdisFreeDmaChannel@4 -NdisFreeToBlockPool@4 -NdisFreeMemory@12 -NdisFreePacket@4 -NdisFreePacketPool@4 -NdisFreeSharedMemory@24 -NdisFreeSpinLock@4 -NdisGeneratePartialCancelId@0 -NdisGetBufferPhysicalArraySize@8 -NdisGetCurrentProcessorCounts@12 -NdisGetCurrentProcessorCpuUsage@4 -NdisGetCurrentSystemTime@4 -NdisGetDriverHandle@8 -NdisGetFirstBufferFromPacket@20 -NdisGetFirstBufferFromPacketSafe@24 -NdisGetPacketCancelId@4 -NdisGetPoolFromPacket@4 -NdisGetReceivedPacket@8 -NdisGetRoutineAddress@4 -NdisGetSharedDataAlignment@0 -NdisGetSystemUpTime@4 -NdisGetVersion@0 -NdisIMAssociateMiniport@8 -NdisIMCancelInitializeDeviceInstance@8 -NdisIMCopySendCompletePerPacketInfo@8 -NdisIMCopySendPerPacketInfo@8 -NdisIMDeInitializeDeviceInstance@4 -NdisIMDeregisterLayeredMiniport@4 -NdisIMGetBindingContext@4 -NdisIMGetCurrentPacketStack@8 -NdisIMGetDeviceContext@4 -NdisIMInitializeDeviceInstance@8 -NdisIMInitializeDeviceInstanceEx@12 -NdisIMNotifyPnPEvent@8 -NdisImmediateReadPciSlotInformation@20 -NdisImmediateReadPortUchar@12 -NdisImmediateReadPortUlong@12 -NdisImmediateReadPortUshort@12 -NdisImmediateReadSharedMemory@16 -NdisImmediateWritePciSlotInformation@20 -NdisImmediateWritePortUchar@12 -NdisImmediateWritePortUlong@12 -NdisImmediateWritePortUshort@12 -NdisImmediateWriteSharedMemory@16 -NdisIMQueueMiniportCallback@12 -NdisIMRegisterLayeredMiniport@16 -NdisIMRevertBack@8 -NdisIMSwitchToMiniport@8 -NdisInitAnsiString@8 -NdisInitializeEvent@4 -NdisInitializeReadWriteLock@4 -NdisInitializeString@8 -NdisInitializeTimer@12 -NdisInitializeWrapper@16 -NdisInitUnicodeString@8 -NdisInterlockedAddLargeInteger@16 -NdisInterlockedAddUlong@12 -NdisInterlockedDecrement@4 -NdisInterlockedIncrement@4 -NdisInterlockedInsertHeadList@12 -NdisInterlockedInsertTailList@12 -NdisInterlockedPopEntrySList@8 -NdisInterlockedPushEntrySList@12 -NdisInterlockedRemoveHeadList@8 -NdisMAllocateMapRegisters@20 -NdisMAllocateSharedMemory@20 -NdisMAllocateSharedMemoryAsync@16 -NdisMapFile@12 -NdisMapIoSpace@24 -;NdisMatchPdoWithPacket ? -NdisMCancelTimer@8 -NdisMCloseLog@4 -NdisMCmActivateVc@8 -NdisMCmCreateVc@16 -NdisMCmDeactivateVc@4 -NdisMCmDeleteVc@4 -NdisMCmRegisterAddressFamily@16 -NdisMCmRequest@16 -NdisMCoActivateVcComplete@12 -NdisMCoDeactivateVcComplete@8 -NdisMCoIndicateReceivePacket@12 -NdisMCoIndicateStatus@20 -NdisMCompleteBufferPhysicalMapping@12 -NdisMCoReceiveComplete@4 -NdisMCoRequestComplete@12 -NdisMCoSendComplete@12 -NdisMCreateLog@12 -NdisMDeregisterAdapterShutdownHandler@4 -NdisMDeregisterDevice@4 -NdisMDeregisterDmaChannel@4 -NdisMDeregisterInterrupt@4 -NdisMDeregisterIoPortRange@16 -NdisMFlushLog@4 -NdisMFreeMapRegisters@4 -NdisMFreeSharedMemory@24 -NdisMGetDeviceProperty@24 -NdisMGetDmaAlignment@4 -NdisMIndicateStatus@16 -NdisMIndicateStatusComplete@4 -NdisMInitializeScatterGatherDma@12 -NdisMInitializeTimer@16 -NdisMMapIoSpace@20 -NdisMPciAssignResources@12 -NdisMPromoteMiniport@4 -NdisMQueryAdapterInstanceName@8 -NdisMQueryAdapterResources@16 -NdisMQueryInformationComplete@8 -NdisMReadDmaCounter@4 -NdisMRegisterAdapterShutdownHandler@12 -NdisMRegisterDevice@24 -NdisMRegisterDmaChannel@24 -NdisMRegisterInterrupt@28 -NdisMRegisterIoPortRange@16 -NdisMRegisterMiniport@12 -NdisMRegisterUnloadHandler@8 -NdisMRemoveMiniport@4 -NdisMResetComplete@12 -NdisMSendComplete@12 -NdisMSendResourcesAvailable@4 -NdisMSetAttributes@16 -NdisMSetAttributesEx@20 -NdisMSetInformationComplete@8 -NdisMSetMiniportSecondary@8 -NdisMSetPeriodicTimer@8 -NdisMSetTimer@8 -NdisMSleep@4 -NdisMStartBufferPhysicalMapping@24 -NdisMSynchronizeWithInterrupt@12 -NdisMTransferDataComplete@16 -NdisMUnmapIoSpace@12 -NdisMWanIndicateReceive@20 -NdisMWanIndicateReceiveComplete@4 -NdisMWanSendComplete@12 -NdisMWriteLogData@12 -NdisOpenAdapter@44 -NdisOpenConfiguration@12 -NdisOpenConfigurationKeyByIndex@20 -NdisOpenConfigurationKeyByName@16 -NdisOpenFile@24 -NdisOpenProtocolConfiguration@12 -NdisOverrideBusNumber@12 -NdisPacketPoolUsage@4 -NdisPacketSize@4 -NdisPciAssignResources@20 -NdisQueryAdapterInstanceName@8 -NdisQueryBindInstanceName@8 -NdisQueryBuffer@12 -NdisQueryBufferOffset@12 -NdisQueryBufferSafe@16 -NdisQueryMapRegisterCount@8 -NdisQueryPendingIOCount@8 -NdisReadConfiguration@20 -NdisReadEisaSlotInformation@16 -NdisReadEisaSlotInformationEx@20 -NdisReadMcaPosInformation@16 -NdisReadNetworkAddress@16 -NdisReadPciSlotInformation@20 -NdisReadPcmciaAttributeMemory@16 -NdisReEnumerateProtocolBindings@4 -NdisRegisterAdapter@24 -NdisRegisterAdapterShutdownHandler@12 -NdisRegisterProtocol@16 -NdisRegisterTdiCallBack@8 -NdisReleaseAdapterResources@4 -NdisReleaseReadWriteLock@8 -NdisReleaseSpinLock@4 -NdisRequest@12 -NdisReset@8 -NdisResetEvent@4 -NdisReturnPackets@8 -NdisSend@12 -NdisSendPackets@12 -NdisSetEvent@4 -NdisSetPacketCancelId@8 -NdisSetPacketPoolProtocolId@8 -NdisSetPacketStatus@16 -NdisSetProtocolFilter@32 -NdisSetTimer@8 -NdisSetTimerEx@12 -NdisSetupDmaTransfer@24 -NdisSystemProcessorCount@0 -NdisTerminateWrapper@8 -NdisTransferData@28 -NdisUnchainBufferAtBack@8 -NdisUnchainBufferAtFront@8 -NdisUnicodeStringToAnsiString@8 -NdisUnmapFile@4 -NdisUpcaseUnicodeString@8 -NdisUpdateSharedMemory@20 -NdisWaitEvent@8 -NdisWriteConfiguration@16 -NdisWriteErrorLogEntry -NdisWriteEventLogEntry@28 -NdisWritePciSlotInformation@20 -NdisWritePcmciaAttributeMemory@16 -TrFilterDprIndicateReceive@28 -TrFilterDprIndicateReceiveComplete@4 -NdisScheduleWorkItem@4 - -; EOF diff --git a/drivers/network/ndis/ndis.rbuild b/drivers/network/ndis/ndis.rbuild index 39eab407a43..38dadeff652 100644 --- a/drivers/network/ndis/ndis.rbuild +++ b/drivers/network/ndis/ndis.rbuild @@ -1,7 +1,7 @@ - + include diff --git a/drivers/network/ndis/ndis.spec b/drivers/network/ndis/ndis.spec new file mode 100644 index 00000000000..bd3eaea56b9 --- /dev/null +++ b/drivers/network/ndis/ndis.spec @@ -0,0 +1,292 @@ + + @ stdcall ArcFilterDprIndicateReceive(ptr ptr ptr long) + @ stdcall ArcFilterDprIndicateReceiveComplete(ptr) + @ stdcall EthFilterDprIndicateReceive(ptr ptr ptr ptr long ptr long long) + @ stdcall EthFilterDprIndicateReceiveComplete(ptr) + @ stdcall FddiFilterDprIndicateReceive(ptr ptr ptr long ptr long ptr long long) + @ stdcall FddiFilterDprIndicateReceiveComplete(ptr) + @ stdcall NDIS_BUFFER_TO_SPAN_PAGES(ptr) + @ stdcall NdisAcquireReadWriteLock(ptr long ptr) + @ stdcall NdisAcquireSpinLock(ptr) + @ stdcall NdisAdjustBufferLength(ptr long) + @ stdcall NdisAllocateBuffer(ptr ptr ptr ptr long) + @ stdcall NdisAllocateBufferPool(ptr ptr long) + @ stdcall NdisAllocateDmaChannel(ptr ptr ptr ptr long) + @ stdcall NdisAllocateMemory(ptr long long double) + @ stdcall NdisAllocateFromBlockPool(ptr) + @ stdcall NdisAllocateMemoryWithTag(ptr long long) + @ stdcall NdisAllocatePacket(ptr ptr ptr) + @ stdcall NdisAllocatePacketPool(ptr ptr long long) + @ stdcall NdisAllocatePacketPoolEx(ptr ptr long long long) + @ stdcall NdisAllocateSharedMemory(ptr long long ptr ptr) + @ stdcall NdisAllocateSpinLock(ptr) + @ stdcall NdisAnsiStringToUnicodeString(ptr ptr) + @ stdcall NdisBufferLength(ptr) + @ stdcall NdisBufferVirtualAddress(ptr) + @ stdcall NdisCancelSendPackets(ptr ptr) + @ stdcall NdisCancelTimer(ptr ptr) + @ stdcall NdisClAddParty(ptr ptr ptr ptr) + @ stdcall NdisClCloseAddressFamily(ptr) + @ stdcall NdisClCloseCall(ptr ptr ptr long) + @ stdcall NdisClDeregisterSap(ptr) + @ stdcall NdisClDropParty(ptr ptr long) + @ stdcall NdisClGetProtocolVcContextFromTapiCallId(double ptr) + @ stdcall NdisClIncomingCallComplete(long ptr ptr) + @ stdcall NdisClMakeCall(ptr ptr ptr ptr) + @ stdcall NdisClModifyCallQoS(ptr ptr) + @ stdcall NdisClOpenAddressFamily(ptr ptr ptr ptr long ptr) + @ stdcall NdisClRegisterSap(ptr ptr ptr ptr) + @ stdcall NdisCloseAdapter(ptr ptr) + @ stdcall NdisCloseConfiguration(ptr) + @ stdcall NdisCloseFile(ptr) + @ stdcall NdisCmActivateVc(ptr ptr) + @ stdcall NdisCmAddPartyComplete(long ptr ptr ptr) + @ stdcall NdisCmCloseAddressFamilyComplete(long ptr) + @ stdcall NdisCmCloseCallComplete(long ptr ptr) + @ stdcall NdisCmDeactivateVc(ptr) + @ stdcall NdisCmDeregisterSapComplete(long ptr) + @ stdcall NdisCmDispatchCallConnected(ptr) + @ stdcall NdisCmDispatchIncomingCall(ptr ptr ptr) + @ stdcall NdisCmDispatchIncomingCallQoSChange(ptr ptr) + @ stdcall NdisCmDispatchIncomingCloseCall(long ptr ptr long) + @ stdcall NdisCmDispatchIncomingDropParty(ptr ptr ptr long) + @ stdcall NdisCmDropPartyComplete(long ptr) + @ stdcall NdisCmMakeCallComplete(long ptr ptr ptr ptr) + @ stdcall NdisCmModifyCallQoSComplete(long ptr ptr) + @ stdcall NdisCmOpenAddressFamilyComplete(long ptr ptr) + @ stdcall NdisCmRegisterAddressFamily(ptr ptr ptr long) + @ stdcall NdisCmRegisterSapComplete(long ptr ptr) + @ stdcall NdisCoAssignInstanceName(ptr ptr ptr) + @ stdcall NdisCoCreateVc(ptr ptr ptr ptr) + @ stdcall NdisCoDeleteVc(ptr) + @ stdcall NdisCoGetTapiCallId(ptr ptr) + @ stdcall NdisCoRequest(ptr ptr ptr ptr ptr) + @ stdcall NdisCoRequestComplete(long ptr ptr ptr ptr) + @ stdcall NdisCoSendPackets(ptr ptr long) + @ stdcall NdisCompareAnsiString(ptr ptr long) + @ stdcall NdisCompareUnicodeString(ptr ptr long) + @ stdcall NdisCompleteBindAdapter(ptr long long) + @ stdcall NdisCompleteCloseAdapter(ptr long) + @ stdcall NdisCompleteDmaTransfer(ptr ptr ptr long long long) + @ stdcall NdisCompleteOpenAdapter(ptr long long) + @ stdcall NdisCompletePnPEvent(long ptr ptr) + @ stdcall NdisCompleteQueryStatistics(ptr ptr long) + @ stdcall NdisCompleteUnbindAdapter(ptr long) + @ stdcall NdisConvertStringToAtmAddress(ptr ptr ptr) + @ stdcall NdisCopyBuffer(ptr ptr ptr ptr long long) + @ stdcall NdisCopyFromPacketToPacket(ptr long long ptr long ptr) + @ stdcall NdisCopyFromPacketToPacketSafe(ptr long long ptr long ptr long) + @ stdcall NdisCreateBlockPool(long long long ptr) + @ stdcall NdisDeregisterAdapter(ptr) + @ stdcall NdisDeregisterAdapterShutdownHandler(ptr) + @ stdcall NdisDeregisterMac(ptr ptr) + @ stdcall NdisDeregisterProtocol(ptr ptr) + @ stdcall NdisDeregisterTdiCallBack() + @ stdcall NdisDestroyBlockPool(ptr) + @ stdcall NdisDprAcquireSpinLock(ptr) + @ stdcall NdisDprAllocatePacket(ptr ptr ptr) + @ stdcall NdisDprAllocatePacketNonInterlocked(ptr ptr ptr) + @ stdcall NdisDprFreePacket(ptr) + @ stdcall NdisDprFreePacketNonInterlocked(ptr) + @ stdcall NdisDprReleaseSpinLock(ptr) + @ stdcall NdisEqualString(ptr ptr long) + @ stdcall NdisFreeBuffer(ptr) + @ stdcall NdisFreeBufferPool(ptr) + @ stdcall NdisFreeDmaChannel(ptr) + @ stdcall NdisFreeToBlockPool(ptr) + @ stdcall NdisFreeMemory(ptr long long) + @ stdcall NdisFreePacket(ptr) + @ stdcall NdisFreePacketPool(ptr) + @ stdcall NdisFreeSharedMemory(ptr long long ptr double) + @ stdcall NdisFreeSpinLock(ptr) + @ stdcall NdisGeneratePartialCancelId() + @ stdcall NdisGetBufferPhysicalArraySize(ptr ptr) + @ stdcall NdisGetCurrentProcessorCounts(ptr ptr ptr) + @ stdcall NdisGetCurrentProcessorCpuUsage(ptr) + @ stdcall NdisGetCurrentSystemTime(ptr) + @ stdcall NdisGetDriverHandle(ptr ptr) + @ stdcall NdisGetFirstBufferFromPacket(ptr ptr ptr ptr ptr) + @ stdcall NdisGetFirstBufferFromPacketSafe(ptr ptr ptr ptr ptr long) + @ stdcall NdisGetPacketCancelId(ptr) + @ stdcall NdisGetPoolFromPacket(ptr) + @ stdcall NdisGetReceivedPacket(ptr ptr) + @ stdcall NdisGetRoutineAddress(ptr) + @ stdcall NdisGetSharedDataAlignment() + @ stdcall NdisGetSystemUpTime(ptr) + @ stdcall NdisGetVersion() + @ stdcall NdisIMAssociateMiniport(ptr ptr) + @ stdcall NdisIMCancelInitializeDeviceInstance(ptr ptr) + @ stdcall NdisIMCopySendCompletePerPacketInfo(ptr ptr) + @ stdcall NdisIMCopySendPerPacketInfo(ptr ptr) + @ stdcall NdisIMDeInitializeDeviceInstance(ptr) + @ stdcall NdisIMDeregisterLayeredMiniport(ptr) + @ stdcall NdisIMGetBindingContext(ptr) + @ stdcall NdisIMGetCurrentPacketStack(ptr ptr) + @ stdcall NdisIMGetDeviceContext(ptr) + @ stdcall NdisIMInitializeDeviceInstance(ptr ptr) + @ stdcall NdisIMInitializeDeviceInstanceEx(ptr ptr ptr) + @ stdcall NdisIMNotifyPnPEvent(ptr ptr) + @ stdcall NdisImmediateReadPciSlotInformation(ptr long long ptr long) + @ stdcall NdisImmediateReadPortUchar(ptr long ptr) + @ stdcall NdisImmediateReadPortUlong(ptr long ptr) + @ stdcall NdisImmediateReadPortUshort(ptr long ptr) + @ stdcall NdisImmediateReadSharedMemory(ptr long ptr long) + @ stdcall NdisImmediateWritePciSlotInformation(ptr long long ptr long) + @ stdcall NdisImmediateWritePortUchar(ptr long long) + @ stdcall NdisImmediateWritePortUlong(ptr long long) + @ stdcall NdisImmediateWritePortUshort(ptr long long) + @ stdcall NdisImmediateWriteSharedMemory(ptr long ptr long) + @ stdcall NdisIMQueueMiniportCallback(ptr ptr ptr) + @ stdcall NdisIMRegisterLayeredMiniport(ptr ptr long ptr) + @ stdcall NdisIMRevertBack(ptr ptr) + @ stdcall NdisIMSwitchToMiniport(ptr ptr) + @ stdcall NdisInitAnsiString(ptr ptr) + @ stdcall NdisInitializeEvent(ptr) + @ stdcall NdisInitializeReadWriteLock(ptr) + @ stdcall NdisInitializeString(ptr ptr) + @ stdcall NdisInitializeTimer(ptr ptr ptr) + @ stdcall NdisInitializeWrapper(ptr ptr ptr ptr) + @ stdcall NdisInitUnicodeString(ptr ptr) + @ stdcall NdisInterlockedAddLargeInteger(ptr double ptr) + @ stdcall NdisInterlockedAddUlong(ptr long ptr) + @ stdcall NdisInterlockedDecrement(ptr) + @ stdcall NdisInterlockedIncrement(ptr) + @ stdcall NdisInterlockedInsertHeadList(ptr ptr ptr) + @ stdcall NdisInterlockedInsertTailList(ptr ptr ptr) + @ stdcall NdisInterlockedPopEntrySList(ptr ptr) + @ stdcall NdisInterlockedPushEntrySList(ptr ptr ptr) + @ stdcall NdisInterlockedRemoveHeadList(ptr ptr) + @ stdcall NdisMAllocateMapRegisters(ptr long long long long) + @ stdcall NdisMAllocateSharedMemory(ptr long long ptr ptr) + @ stdcall NdisMAllocateSharedMemoryAsync(ptr long long ptr) + @ stdcall NdisMapFile(ptr ptr ptr) + @ stdcall NdisMapIoSpace(ptr ptr ptr double long) +# @ stdcall NdisMatchPdoWithPacket ? + @ stdcall NdisMCancelTimer(ptr ptr) + @ stdcall NdisMCloseLog(ptr) + @ stdcall NdisMCmActivateVc(ptr ptr) + @ stdcall NdisMCmCreateVc(ptr ptr ptr ptr) + @ stdcall NdisMCmDeactivateVc(ptr) + @ stdcall NdisMCmDeleteVc(ptr) + @ stdcall NdisMCmRegisterAddressFamily(ptr ptr ptr long) + @ stdcall NdisMCmRequest(ptr ptr ptr ptr) + @ stdcall NdisMCoActivateVcComplete(long ptr ptr) + @ stdcall NdisMCoDeactivateVcComplete(long ptr) + @ stdcall NdisMCoIndicateReceivePacket(ptr ptr long) + @ stdcall NdisMCoIndicateStatus(ptr ptr long ptr long) + @ stdcall NdisMCompleteBufferPhysicalMapping(ptr ptr long) + @ stdcall NdisMCoReceiveComplete(ptr) + @ stdcall NdisMCoRequestComplete(long ptr ptr) + @ stdcall NdisMCoSendComplete(ptr ptr ptr) + @ stdcall NdisMCreateLog(ptr long ptr) + @ stdcall NdisMDeregisterAdapterShutdownHandler(ptr) + @ stdcall NdisMDeregisterDevice(ptr) + @ stdcall NdisMDeregisterDmaChannel(ptr) + @ stdcall NdisMDeregisterInterrupt(ptr) + @ stdcall NdisMDeregisterIoPortRange(ptr long long ptr) + @ stdcall NdisMFlushLog(ptr) + @ stdcall NdisMFreeMapRegisters(ptr) + @ stdcall NdisMFreeSharedMemory(ptr long long ptr double) + @ stdcall NdisMGetDeviceProperty(ptr ptr ptr ptr ptr ptr) + @ stdcall NdisMGetDmaAlignment(ptr) + @ stdcall NdisMIndicateStatus(ptr long ptr long) + @ stdcall NdisMIndicateStatusComplete(ptr) + @ stdcall NdisMInitializeScatterGatherDma(ptr long long) + @ stdcall NdisMInitializeTimer(ptr ptr ptr ptr) + @ stdcall NdisMMapIoSpace(ptr ptr double long) + @ stdcall NdisMPciAssignResources(ptr long ptr) + @ stdcall NdisMPromoteMiniport(ptr) + @ stdcall NdisMQueryAdapterInstanceName(ptr ptr) + @ stdcall NdisMQueryAdapterResources(ptr ptr ptr ptr) + @ stdcall NdisMQueryInformationComplete(ptr long) + @ stdcall NdisMReadDmaCounter(ptr) + @ stdcall NdisMRegisterAdapterShutdownHandler(ptr ptr ptr) + @ stdcall NdisMRegisterDevice(ptr ptr ptr ptr ptr ptr) + @ stdcall NdisMRegisterDmaChannel(ptr ptr long long ptr long) + @ stdcall NdisMRegisterInterrupt(ptr ptr long long long long long) + @ stdcall NdisMRegisterIoPortRange(ptr ptr long long) + @ stdcall NdisMRegisterMiniport(ptr ptr long) + @ stdcall NdisMRegisterUnloadHandler(ptr ptr) + @ stdcall NdisMRemoveMiniport(ptr) + @ stdcall NdisMResetComplete(ptr long long) + @ stdcall NdisMSendComplete(ptr ptr long) + @ stdcall NdisMSendResourcesAvailable(ptr) + @ stdcall NdisMSetAttributes(ptr ptr long long) + @ stdcall NdisMSetAttributesEx(ptr ptr long long long) + @ stdcall NdisMSetInformationComplete(ptr long) + @ stdcall NdisMSetMiniportSecondary(ptr ptr) + @ stdcall NdisMSetPeriodicTimer(ptr long) + @ stdcall NdisMSetTimer(ptr long) + @ stdcall NdisMSleep(long) + @ stdcall NdisMStartBufferPhysicalMapping(ptr ptr long long ptr ptr) + @ stdcall NdisMSynchronizeWithInterrupt(ptr ptr ptr) + @ stdcall NdisMTransferDataComplete(ptr ptr long long) + @ stdcall NdisMUnmapIoSpace(ptr ptr long) + @ stdcall NdisMWanIndicateReceive(ptr ptr ptr ptr long) + @ stdcall NdisMWanIndicateReceiveComplete(ptr) + @ stdcall NdisMWanSendComplete(ptr ptr long) + @ stdcall NdisMWriteLogData(ptr ptr long) + @ stdcall NdisOpenAdapter(ptr ptr ptr ptr ptr long ptr ptr ptr long ptr) + @ stdcall NdisOpenConfiguration(ptr ptr ptr) + @ stdcall NdisOpenConfigurationKeyByIndex(ptr ptr long ptr ptr) + @ stdcall NdisOpenConfigurationKeyByName(ptr ptr ptr ptr) + @ stdcall NdisOpenFile(ptr ptr ptr ptr double) + @ stdcall NdisOpenProtocolConfiguration(ptr ptr ptr) + @ stdcall NdisOverrideBusNumber(ptr ptr long) + @ stdcall NdisPacketPoolUsage(ptr) + @ stdcall NdisPacketSize(long) + @ stdcall NdisPciAssignResources(ptr ptr ptr long ptr) + @ stdcall NdisQueryAdapterInstanceName(ptr ptr) + @ stdcall NdisQueryBindInstanceName(ptr ptr) + @ stdcall NdisQueryBuffer(ptr ptr ptr) + @ stdcall NdisQueryBufferOffset(ptr ptr ptr) + @ stdcall NdisQueryBufferSafe(ptr ptr ptr long) + @ stdcall NdisQueryMapRegisterCount(long ptr) + @ stdcall NdisQueryPendingIOCount(ptr ptr) + @ stdcall NdisReadConfiguration(ptr ptr ptr ptr long) + @ stdcall NdisReadEisaSlotInformation(ptr ptr ptr ptr) + @ stdcall NdisReadEisaSlotInformationEx(ptr ptr ptr ptr ptr) + @ stdcall NdisReadMcaPosInformation(ptr ptr ptr ptr) + @ stdcall NdisReadNetworkAddress(ptr ptr ptr ptr) + @ stdcall NdisReadPciSlotInformation(ptr long long ptr long) + @ stdcall NdisReadPcmciaAttributeMemory(ptr long ptr long) + @ stdcall NdisReEnumerateProtocolBindings(ptr) + @ stdcall NdisRegisterAdapter(ptr ptr ptr ptr ptr ptr) + @ stdcall NdisRegisterAdapterShutdownHandler(ptr ptr ptr) + @ stdcall NdisRegisterProtocol(ptr ptr ptr long) + @ stdcall NdisRegisterTdiCallBack(ptr ptr) + @ stdcall NdisReleaseAdapterResources(ptr) + @ stdcall NdisReleaseReadWriteLock(ptr ptr) + @ stdcall NdisReleaseSpinLock(ptr) + @ stdcall NdisRequest(ptr ptr ptr) + @ stdcall NdisReset(ptr ptr) + @ stdcall NdisResetEvent(ptr) + @ stdcall NdisReturnPackets(ptr long) + @ stdcall NdisSend(ptr ptr ptr) + @ stdcall NdisSendPackets(ptr ptr long) + @ stdcall NdisSetEvent(ptr) + @ stdcall NdisSetPacketCancelId(ptr ptr) + @ stdcall NdisSetPacketPoolProtocolId(ptr long) + @ stdcall NdisSetPacketStatus(ptr long ptr long) + @ stdcall NdisSetProtocolFilter(ptr ptr ptr ptr long long long ptr) + @ stdcall NdisSetTimer(ptr long) + @ stdcall NdisSetTimerEx(ptr long ptr) + @ stdcall NdisSetupDmaTransfer(ptr ptr ptr long long long) + @ stdcall NdisSystemProcessorCount() + @ stdcall NdisTerminateWrapper(ptr ptr) + @ stdcall NdisTransferData(ptr ptr ptr long long ptr ptr) + @ stdcall NdisUnchainBufferAtBack(ptr ptr) + @ stdcall NdisUnchainBufferAtFront(ptr ptr) + @ stdcall NdisUnicodeStringToAnsiString(ptr ptr) + @ stdcall NdisUnmapFile(ptr) + @ stdcall NdisUpcaseUnicodeString(ptr ptr) + @ stdcall NdisUpdateSharedMemory(ptr long ptr double) + @ stdcall NdisWaitEvent(ptr long) + @ stdcall NdisWriteConfiguration(ptr ptr ptr ptr) + @ cdecl NdisWriteErrorLogEntry(ptr long long) + @ stdcall NdisWriteEventLogEntry(ptr long long long ptr long ptr) + @ stdcall NdisWritePciSlotInformation(ptr long long ptr long) + @ stdcall NdisWritePcmciaAttributeMemory(ptr long ptr long) + @ stdcall TrFilterDprIndicateReceive(ptr ptr ptr long ptr long long) + @ stdcall TrFilterDprIndicateReceiveComplete(ptr) + @ stdcall NdisScheduleWorkItem(ptr) diff --git a/drivers/network/tdi/misc/tdi.def b/drivers/network/tdi/misc/tdi.def deleted file mode 100644 index 4f10551a4e6..00000000000 --- a/drivers/network/tdi/misc/tdi.def +++ /dev/null @@ -1,47 +0,0 @@ -; $Id$ -; -; TDI.SYS Kernel Module - ReactOS Operating System -; -LIBRARY TDI.SYS - -EXPORTS -CTEAllocateString@8 -CTEBlock@4 -CTEInitEvent@8 -CTEInitString@8 -CTEInitTimer@4 -CTEInitialize@0 -CTELogEvent@28 -CTEScheduleEvent@8 -CTESignal@8 -CTEStartTimer@16 -CTESystemUpTime@0 -TdiBuildNetbiosAddress@12 -TdiBuildNetbiosAddressEa@12 -TdiCopyBufferToMdl@24 -TdiCopyMdlToBuffer@24 -TdiDefaultChainedRcvDatagramHandler@40 -TdiDefaultChainedRcvExpeditedHandler@28 -TdiDefaultChainedReceiveHandler@28 -TdiDefaultConnectHandler@36 -TdiDefaultDisconnectHandler@28 -TdiDefaultErrorHandler@8 -TdiDefaultRcvDatagramHandler@44 -TdiDefaultRcvExpeditedHandler@32 -TdiDefaultReceiveHandler@32 -TdiDefaultSendPossibleHandler@12 -TdiDeregisterAddressChangeHandler@4 -TdiDeregisterDeviceObject@4 -TdiDeregisterNetAddress@4 -TdiDeregisterNotificationHandler@4 -TdiInitialize@4 -TdiMapBuffer@4 -TdiMapUserRequest@12 -TdiOpenNetbiosAddress@16 -TdiRegisterAddressChangeHandler@12 -TdiRegisterDeviceObject@8 -TdiRegisterNetAddress@8 -TdiRegisterNotificationHandler@12 -TdiReturnChainedReceives@8 -TdiUnmapBuffer@4 -; EOF diff --git a/drivers/network/tdi/misc/tdi.spec b/drivers/network/tdi/misc/tdi.spec new file mode 100644 index 00000000000..a1810644793 --- /dev/null +++ b/drivers/network/tdi/misc/tdi.spec @@ -0,0 +1,39 @@ + @ stdcall CTEAllocateString(long long) + @ stdcall CTEBlock(long) + @ stdcall CTEInitEvent(long long) + @ stdcall CTEInitString(long long) + @ stdcall CTEInitTimer(long) + @ stdcall CTEInitialize() + @ stdcall CTELogEvent(long long long long long long long) + @ stdcall CTEScheduleEvent(long long) + @ stdcall CTESignal(long long) + @ stdcall CTEStartTimer(long long long long) + @ stdcall CTESystemUpTime() + @ stdcall TdiBuildNetbiosAddress(str long ptr) + @ stdcall TdiBuildNetbiosAddressEa(str long str) + @ stdcall TdiCopyBufferToMdl(ptr long long ptr long ptr) + @ stdcall TdiCopyMdlToBuffer(ptr long long ptr long ptr) + @ stdcall TdiDefaultChainedRcvDatagramHandler(ptr long ptr long ptr long long long ptr ptr) + @ stdcall TdiDefaultChainedRcvExpeditedHandler(ptr ptr long long long ptr ptr) + @ stdcall TdiDefaultChainedReceiveHandler(ptr ptr long long long ptr ptr) + @ stdcall TdiDefaultConnectHandler(ptr long ptr long ptr long ptr ptr ptr) + @ stdcall TdiDefaultDisconnectHandler(ptr ptr long ptr long ptr long) + @ stdcall TdiDefaultErrorHandler(ptr long) + @ stdcall TdiDefaultRcvDatagramHandler(ptr long ptr long ptr long long long ptr ptr ptr) + @ stdcall TdiDefaultRcvExpeditedHandler(ptr ptr long long long ptr ptr ptr) + @ stdcall TdiDefaultReceiveHandler(ptr ptr long long long ptr ptr ptr) + @ stdcall TdiDefaultSendPossibleHandler(ptr ptr long) + @ stdcall TdiDeregisterAddressChangeHandler(ptr) + @ stdcall TdiDeregisterDeviceObject(ptr) + @ stdcall TdiDeregisterNetAddress(ptr) + @ stdcall TdiDeregisterNotificationHandler(ptr) + @ stdcall TdiInitialize(ptr) + @ stdcall TdiMapBuffer(ptr) + @ stdcall TdiMapUserRequest(ptr ptr ptr) + @ stdcall TdiOpenNetbiosAddress(long long long long) + @ stdcall TdiRegisterAddressChangeHandler(long long long) + @ stdcall TdiRegisterDeviceObject(long long) + @ stdcall TdiRegisterNetAddress(long long) + @ stdcall TdiRegisterNotificationHandler(long long long) + @ stdcall TdiReturnChainedReceives(ptr long) + @ stdcall TdiUnmapBuffer(ptr) diff --git a/drivers/network/tdi/tdi.rbuild b/drivers/network/tdi/tdi.rbuild index 3a7b059938f..1c658fa50f2 100644 --- a/drivers/network/tdi/tdi.rbuild +++ b/drivers/network/tdi/tdi.rbuild @@ -1,7 +1,7 @@ - + ntoskrnl hal diff --git a/drivers/storage/class/cdrom/cdrom.c b/drivers/storage/class/cdrom/cdrom.c index e5a51493139..ef462658d7e 100644 --- a/drivers/storage/class/cdrom/cdrom.c +++ b/drivers/storage/class/cdrom/cdrom.c @@ -5127,7 +5127,7 @@ Return Value: // The data buffer must be aligned. // - srb->DataBuffer = (PVOID) (((ULONG) (context + 1) + (alignment - 1)) & + srb->DataBuffer = (PVOID) (((ULONG_PTR) (context + 1) + (alignment - 1)) & ~(alignment - 1)); @@ -5877,7 +5877,7 @@ Return Value: irpStack = IoGetCurrentIrpStackLocation(irp); if (irpStack->Parameters.Others.Argument3) { - ULONG count; + ULONG_PTR count; // // Decrement the countdown timer and put the IRP back in the list. @@ -6497,7 +6497,7 @@ Return Value: PIO_STACK_LOCATION irpStack; NTSTATUS status; BOOLEAN retry; - ULONG retryCount; + ULONG_PTR retryCount; ULONG lastSector; PIRP originalIrp; PCDROM_DATA cddata; diff --git a/drivers/storage/class/ramdisk/ramdisk.c b/drivers/storage/class/ramdisk/ramdisk.c index 1ebe19664c8..6a353bc264e 100644 --- a/drivers/storage/class/ramdisk/ramdisk.c +++ b/drivers/storage/class/ramdisk/ramdisk.c @@ -2422,18 +2422,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, 0, &PhysicalDeviceObject); if (NT_SUCCESS(Status)) - { - // - // ReactOS Fix - // The ReactOS Plug and Play Manager is broken and does not create - // the required keys when reporting a detected device. - // We hack around this ourselves. - // - RtlCreateUnicodeString(&((PEXTENDED_DEVOBJ_EXTENSION) - PhysicalDeviceObject->DeviceObjectExtension) - ->DeviceNode->InstancePath, - L"Root\\UNKNOWN\\0000"); - + { // // Create the device object // diff --git a/drivers/storage/ide/uniata/id_ata.cpp b/drivers/storage/ide/uniata/id_ata.cpp index 1cace8bd488..fb2bb028e87 100644 --- a/drivers/storage/ide/uniata/id_ata.cpp +++ b/drivers/storage/ide/uniata/id_ata.cpp @@ -537,10 +537,10 @@ WaitOnBaseBusy( { ULONG i; UCHAR Status; - for (i=0; i<200; i++) { + for (i=0; i<20000; i++) { GetBaseStatus(chan, Status); if (Status & IDE_STATUS_BUSY) { - AtapiStallExecution(10); + AtapiStallExecution(150); continue; } else { break; @@ -640,11 +640,11 @@ WaitForDrq( for (i=0; i<1000; i++) { GetStatus(chan, Status); if (Status & IDE_STATUS_BUSY) { - AtapiStallExecution(10); + AtapiStallExecution(100); } else if (Status & IDE_STATUS_DRQ) { break; } else { - AtapiStallExecution(10); + AtapiStallExecution(200); } } return Status; @@ -661,11 +661,11 @@ WaitShortForDrq( for (i=0; i<2; i++) { GetStatus(chan, Status); if (Status & IDE_STATUS_BUSY) { - AtapiStallExecution(10); + AtapiStallExecution(100); } else if (Status & IDE_STATUS_DRQ) { break; } else { - AtapiStallExecution(10); + AtapiStallExecution(100); } } return Status; diff --git a/drivers/usb/usbehci/common.c b/drivers/usb/usbehci/common.c index 79ecbadf25f..7ed7421d8d8 100644 --- a/drivers/usb/usbehci/common.c +++ b/drivers/usb/usbehci/common.c @@ -11,8 +11,6 @@ #include "usbehci.h" #include #include -#define NDEBUG -#include /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/ diff --git a/drivers/usb/usbehci/fdo.c b/drivers/usb/usbehci/fdo.c index b1ec5503cb6..c42ebfd1f56 100644 --- a/drivers/usb/usbehci/fdo.c +++ b/drivers/usb/usbehci/fdo.c @@ -11,26 +11,6 @@ #include "usbehci.h" #include -//#include "ntstrsafe.h" - -VOID NTAPI -DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context) -{ - PWORKITEM_DATA WorkItemData; - PPDO_DEVICE_EXTENSION PdoDeviceExtension; - - WorkItemData = (PWORKITEM_DATA)Context; - PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension; - - if (PdoDeviceExtension->CallbackRoutine) - PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext); - else - DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n"); - - IoFreeWorkItem(WorkItemData->IoWorkItem); - ExFreePool(WorkItemData); -} - VOID NTAPI EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2) { @@ -60,7 +40,6 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO /* Check for port change on this port */ if (tmp & 0x02) { - PWORKITEM_DATA WorkItemData = NULL; /* Connect or Disconnect? */ if (tmp & 0x01) { @@ -83,11 +62,11 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO DPRINT1("Releasing ownership to companion host controller!\n"); /* Release ownership to companion host controller */ WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), 0x4000); + continue; } } KeStallExecutionProcessor(30); - DPRINT("port tmp %x\n", tmp); /* As per USB 2.0 Specs, 9.1.2. Reset the port and clear the status change */ tmp |= 0x100 | 0x02; @@ -100,17 +79,12 @@ EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVO tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i))); - GetDeviceDescriptor(FdoDeviceExtension, 0, 0, FALSE); PdoDeviceExtension->ChildDeviceCount++; - PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE; - WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEM_DATA)); - if (!WorkItemData) ASSERT(FALSE); - WorkItemData->IoWorkItem = IoAllocateWorkItem(PdoDeviceExtension->DeviceObject); - WorkItemData->PdoDeviceExtension = PdoDeviceExtension; - IoQueueWorkItem(WorkItemData->IoWorkItem, - (PIO_WORKITEM_ROUTINE)DeviceArrivalWorkItem, - DelayedWorkQueue, - WorkItemData); + PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT; + PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_CONNECT; + + PdoDeviceExtension->HaltQueue = FALSE; + KeSetEvent(&PdoDeviceExtension->QueueDrainedEvent, 0, FALSE); } else { @@ -545,6 +519,7 @@ StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PART StartEhci(DeviceObject); FdoDeviceExtension->DeviceState = DEVICESTARTED; + return STATUS_SUCCESS; } @@ -610,6 +585,10 @@ FdoQueryBusRelations( InitializeListHead(&PdoDeviceExtension->IrpQueue); KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock); + KeInitializeEvent(&PdoDeviceExtension->QueueDrainedEvent, SynchronizationEvent, TRUE); + + ExInitializeFastMutex(&PdoDeviceExtension->ListLock); + Pdo->Flags &= ~DO_DEVICE_INITIALIZING; DeviceExtension->Pdo = Pdo; @@ -814,7 +793,6 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo) IoDetachDevice(FdoDeviceExtension->LowerDevice); IoDeleteSymbolicLink(&SymLinkName); IoDeleteDevice(Fdo); - return STATUS_UNSUCCESSFUL; } @@ -840,11 +818,14 @@ AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo) if (!NT_SUCCESS(Status)) { DPRINT1("Unable to register device interface!\n"); + ASSERT(FALSE); } else { Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE); DPRINT1("SetInterfaceState %x\n", Status); + if (!NT_SUCCESS(Status)) + ASSERT(FALSE); } Fdo->Flags &= ~DO_DEVICE_INITIALIZING; diff --git a/drivers/usb/usbehci/irp.c b/drivers/usb/usbehci/irp.c index 06d7c50ab08..99a601d8ebc 100644 --- a/drivers/usb/usbehci/irp.c +++ b/drivers/usb/usbehci/irp.c @@ -62,26 +62,26 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql); - while(!IsListEmpty(&DeviceExtension->IrpQueue)) + while (!IsListEmpty(&DeviceExtension->IrpQueue)) { NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue); Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry); if (!Irp) break; - Stack = IoGetCurrentIrpStackLocation(Irp); ASSERT(Stack); Urb = (PURB) Stack->Parameters.Others.Argument1; + ASSERT(Urb); Information = 0; Status = STATUS_SUCCESS; - DPRINT1("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer); - DPRINT1("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); - DPRINT1("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle); + DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer); + DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); + DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle); UsbDevice = Urb->UrbHeader.UsbdDeviceHandle; /* UsbdDeviceHandle of 0 is root hub */ @@ -97,14 +97,15 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) { case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: { - DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n"); - DPRINT1("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); - DPRINT1("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer); - DPRINT1("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle); - DPRINT1("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->EndPointDescriptor); - DPRINT1("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags); - + DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n"); + DPRINT("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + DPRINT("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer); + DPRINT("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle); + DPRINT("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor); + DPRINT("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags); + ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength); + if (UsbDevice == DeviceExtension->UsbDevices[0]) { if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK)) @@ -112,10 +113,13 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) LONG i; for (i = 0; i < 8; i++) { + if (i == 0){ + DPRINT("PortStatus %x\n", DeviceExtension->Ports[i].PortStatus); + DPRINT("PortChange %x\n", DeviceExtension->Ports[i].PortChange);} if (DeviceExtension->Ports[i].PortChange) { DPRINT1("Inform hub driver that port %d has changed\n", i+1); - ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << (i + 1); + ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7); } } } @@ -123,8 +127,11 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) { Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER; Status = STATUS_UNSUCCESSFUL; + DPRINT1("Invalid transfer flags for SCE\n"); } } + else + DPRINT1("Interrupt Transfer not for hub\n"); break; } case URB_FUNCTION_GET_STATUS_FROM_DEVICE: @@ -132,9 +139,9 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) DPRINT("Get Status from Device\n"); DPRINT("Index : %d\n", Urb->UrbControlGetStatusRequest.Index); - /* Copied from pvdrivers */ if (Urb->UrbControlGetStatusRequest.Index == 0) { + ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL); *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE; } else @@ -156,7 +163,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) { Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); } - + ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL); RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &UsbDevice->DeviceDescriptor, Urb->UrbControlDescriptorRequest.TransferBufferLength); @@ -164,19 +171,40 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) } case USB_CONFIGURATION_DESCRIPTOR_TYPE: { - DPRINT1("USB CONFIG DESC\n"); - ULONG FullDescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR) + - sizeof(USB_INTERFACE_DESCRIPTOR) + - sizeof(USB_ENDPOINT_DESCRIPTOR); + PUCHAR BufPtr; + LONG i, j; - if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= FullDescriptorLength) + DPRINT1("USB CONFIG DESC\n"); + + if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength) { - Urb->UrbControlDescriptorRequest.TransferBufferLength = FullDescriptorLength; + Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength; + } + else + { + DPRINT1("Buffer to small!!!\n"); + //ASSERT(FALSE); + } + + ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); + BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer; + + /* Copy the Configuration Descriptor */ + RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); + BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR); + for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++) + { + /* Copy the Interface Descriptor */ + RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR)); + BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR); + for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++) + { + /* Copy the EndPoint Descriptor */ + RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); + BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR); + } } - RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, - &UsbDevice->ConfigurationDescriptor, - Urb->UrbControlDescriptorRequest.TransferBufferLength); break; } case USB_STRING_DESCRIPTOR_TYPE: @@ -213,7 +241,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) DPRINT(" MaxPower = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower); - Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ConfigurationDescriptor; + Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor; DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle); InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; @@ -229,10 +257,10 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) DPRINT(" Reserved = %02x\n", (ULONG)InterfaceInfo->Reserved); DPRINT(" InterfaceHandle = %p\n", InterfaceInfo->InterfaceHandle); DPRINT(" NumberOfPipes = %d\n", InterfaceInfo->NumberOfPipes); - InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->InterfaceDescriptor; - InterfaceInfo->Class = UsbDevice->InterfaceDescriptor.bInterfaceClass; - InterfaceInfo->SubClass = UsbDevice->InterfaceDescriptor.bInterfaceSubClass; - InterfaceInfo->Protocol = UsbDevice->InterfaceDescriptor.bInterfaceProtocol; + InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor; + InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass; + InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass; + InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol; InterfaceInfo->Reserved = 0; for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++) @@ -245,11 +273,11 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) DPRINT(" PipeHandle = %x\n", InterfaceInfo->Pipes[pCount].PipeHandle); DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumTransferSize); DPRINT(" PipeFlags = %08x\n", InterfaceInfo->Pipes[pCount].PipeFlags); - InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->EndPointDescriptor.wMaxPacketSize; - InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->EndPointDescriptor.bEndpointAddress; - InterfaceInfo->Pipes[pCount].Interval = UsbDevice->EndPointDescriptor.bInterval; + InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.wMaxPacketSize; + InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bEndpointAddress; + InterfaceInfo->Pipes[pCount].Interval = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bInterval; InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt; - InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->EndPointDescriptor; + InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor; if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0) InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096; /* InterfaceInfo->Pipes[j].PipeFlags = 0; */ @@ -315,9 +343,12 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) break; } case USB_DEVICE_CLASS_RESERVED: + DPRINT1("Reserved!!!\n"); case USB_DEVICE_CLASS_HUB: { + PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer; + ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); /* FIXME: Handle more than root hub? */ if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR)) { @@ -328,7 +359,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) /* FIXME: Handle this correctly */ UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); UsbHubDescr->bDescriptorType = 0x29; - return; + break; } DPRINT1("USB_DEVICE_CLASS_HUB request\n"); UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR); @@ -355,6 +386,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) if (Urb->UrbControlVendorClassRequest.Index == 1) { + ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0; } break; @@ -374,7 +406,7 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) case USB_REQUEST_GET_STATUS: { DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index); - + ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0); ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus; ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange; break; @@ -425,7 +457,6 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) case USB_REQUEST_SET_ADDRESS: { DPRINT1("USB_REQUEST_SET_ADDRESS\n"); - ASSERT(FALSE); break; } case USB_REQUEST_GET_DESCRIPTOR: @@ -466,7 +497,6 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) default: { DPRINT1("Unknown Function Class Unknown request\n"); - ASSERT(FALSE); break; } } @@ -476,13 +506,10 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) { DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function); Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION; - ASSERT(FALSE); } } - KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); - Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Information; @@ -493,10 +520,16 @@ CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension) Urb->UrbHeader.UsbdFlags = 0; } + KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); IoCompleteRequest(Irp, IO_NO_INCREMENT); KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql); + + if (DeviceExtension->HaltQueue) + break; } KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql); + if (!DeviceExtension->HaltQueue) + KeSetEvent(&DeviceExtension->QueueDrainedEvent, 0, FALSE); } diff --git a/drivers/usb/usbehci/pdo.c b/drivers/usb/usbehci/pdo.c index 6a0d735e851..cf84911afa7 100644 --- a/drivers/usb/usbehci/pdo.c +++ b/drivers/usb/usbehci/pdo.c @@ -8,11 +8,12 @@ */ #define INITGUID -#define NDEBUG #include "usbehci.h" -#include +#include +#include #include "usbiffn.h" +#include #include #include @@ -51,8 +52,11 @@ const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] = 6: Self-powered, 5: Remote wakeup, 4..0: reserved */ - 0x00, /* MaxPower; */ + 0x00 /* MaxPower; */ +}; +const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] = +{ /* one interface */ 0x09, /* bLength: Interface; */ 0x04, /* bDescriptorType; Interface */ @@ -62,8 +66,11 @@ const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] = 0x09, /* bInterfaceClass; HUB_CLASSCODE */ 0x01, /* bInterfaceSubClass; */ 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface; */ + 0x00 /* iInterface; */ +}; +const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] = +{ /* one endpoint (status change endpoint) */ 0x07, /* bLength; */ 0x05, /* bDescriptorType; Endpoint */ @@ -78,40 +85,26 @@ VOID NTAPI UrbWorkerThread(PVOID Context) { PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Context; + NTSTATUS Status; + LARGE_INTEGER DueTime; + PVOID PollEvents[] = { (PVOID) &PdoDeviceExtension->QueueDrainedEvent, (PVOID) &PdoDeviceExtension->Timer }; - while (PdoDeviceExtension->HaltUrbHandling == FALSE) + DueTime.QuadPart = 0; + KeInitializeTimerEx(&PdoDeviceExtension->Timer, SynchronizationTimer); + KeSetTimerEx(&PdoDeviceExtension->Timer, DueTime, 100, NULL); + + while (TRUE) { + Status = KeWaitForMultipleObjects(2, PollEvents, WaitAll, Executive, KernelMode, FALSE, NULL, NULL); + + if (!PdoDeviceExtension->HaltQueue) + KeResetEvent(&PdoDeviceExtension->QueueDrainedEvent); CompletePendingURBRequest(PdoDeviceExtension); - KeStallExecutionProcessor(10); } + DPRINT1("Thread terminated\n"); } -/* FIXME: Do something better */ -PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub) -{ - PUSB_DEVICE UsbDevicePointer = NULL; - UsbDevicePointer = ExAllocatePool(NonPagedPool, sizeof(USB_DEVICE)); - if (!UsbDevicePointer) - { - DPRINT1("Out of memory\n"); - return NULL; - } - - if ((Hub) && (!Parent)) - { - DPRINT1("This is the root hub\n"); - } - - UsbDevicePointer->Address = DeviceNumber; - UsbDevicePointer->Port = Port; - UsbDevicePointer->ParentDevice = Parent; - - UsbDevicePointer->IsHub = Hub; - - return UsbDevicePointer; -} - NTSTATUS NTAPI PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -137,7 +130,6 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) Urb = (PURB) Stack->Parameters.Others.Argument1; DPRINT("Header Length %d\n", Urb->UrbHeader.Length); DPRINT("Header Function %d\n", Urb->UrbHeader.Function); - /* Queue all request for now, kernel thread will complete them */ QueueURBRequest(PdoDeviceExtension, Irp); Information = 0; @@ -153,6 +145,8 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) case IOCTL_INTERNAL_USB_ENABLE_PORT: { DPRINT1("IOCTL_INTERNAL_USB_ENABLE_PORT\n"); + Information = 0; + Status = STATUS_SUCCESS; break; } case IOCTL_INTERNAL_USB_GET_BUS_INFO: @@ -176,21 +170,27 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) if (Stack->Parameters.Others.Argument1) { /* Return the root hubs devicehandle */ + DPRINT1("Returning RootHub Handle %x\n", PdoDeviceExtension->UsbDevices[0]); *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0]; + Status = STATUS_SUCCESS; } else Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } case IOCTL_INTERNAL_USB_GET_HUB_COUNT: { DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT); + ASSERT(Stack->Parameters.Others.Argument1 != NULL); if (Stack->Parameters.Others.Argument1) { /* FIXME: Determine the number of hubs between the usb device and root hub */ - /* For now return 1, the root hub */ - *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)1; + DPRINT1("RootHubCount %x\n", *(PULONG)Stack->Parameters.Others.Argument1); + *(PULONG)Stack->Parameters.Others.Argument1 = 0; } + Status = STATUS_SUCCESS; break; } case IOCTL_INTERNAL_USB_GET_HUB_NAME: @@ -220,7 +220,7 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) if (Stack->Parameters.Others.Argument1) *(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo; if (Stack->Parameters.Others.Argument2) - *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDevice(FdoDeviceExtension->DeviceObject); + *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject); Information = 0; Status = STATUS_SUCCESS; @@ -228,7 +228,18 @@ PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) } case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: { + PUSB_IDLE_CALLBACK_INFO CallBackInfo; DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n"); + /* FIXME: Set Callback for safe power down */ + CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer; + DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback); + DPRINT1("IdleContext %x\n", CallBackInfo->IdleContext); + + PdoDeviceExtension->IdleCallback = CallBackInfo->IdleCallback; + PdoDeviceExtension->IdleContext = CallBackInfo->IdleContext; + + Information = 0; + Status = STATUS_SUCCESS; break; } default: @@ -275,6 +286,7 @@ PdoQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG_PTR* Information) SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR); SourceString.Buffer = Buffer; break; + } case BusQueryCompatibleIDs: { @@ -375,13 +387,45 @@ PdoDispatchPnp( RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId; RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId; - RtlCopyMemory(&RootHubDevice->ConfigurationDescriptor, + /* FIXME: Do something better below */ + + RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool, + sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations, + USB_POOL_TAG); + + RootHubDevice->Configs[0] = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ROOTHUB2_CONFIGURATION_DESCRIPTOR[5], + USB_POOL_TAG); + + RootHubDevice->Configs[0]->Interfaces[0] = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB_INTERFACE) + sizeof(PVOID) * ROOTHUB2_INTERFACE_DESCRIPTOR[3], + USB_POOL_TAG); + + RootHubDevice->Configs[0]->Interfaces[0]->EndPoints[0] = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB_ENDPOINT), + USB_POOL_TAG); + + RootHubDevice->ActiveConfig = RootHubDevice->Configs[0]; + RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0]; + + RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor, ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR)); + RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->InterfaceDescriptor, + ROOTHUB2_INTERFACE_DESCRIPTOR, + sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR)); + + RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->EndPoints[0]->EndPointDescriptor, + ROOTHUB2_ENDPOINT_DESCRIPTOR, + sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR)); + RootHubDevice->DeviceSpeed = UsbHighSpeed; + RootHubDevice->DeviceType = Usb20Device; + PdoDeviceExtension->UsbDevices[0] = RootHubDevice; /* Create a thread to handle the URB's */ + Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle, THREAD_ALL_ACCESS, NULL, @@ -397,14 +441,16 @@ PdoDispatchPnp( if (!NT_SUCCESS(Status)) { DPRINT1("Failed to register interface\n"); + ASSERT(FALSE); } else { Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE); DPRINT1("Set interface state %x\n", Status); + if (!NT_SUCCESS(Status)) + ASSERT(FALSE); } - Status = STATUS_SUCCESS; break; } @@ -420,7 +466,19 @@ PdoDispatchPnp( break; } case BusRelations: + { + PPDO_DEVICE_EXTENSION PdoDeviceExtension; + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + DPRINT1("BusRelations!!!!!\n"); + + /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager + has resent this IRP and type, so leave the next SCE request pending until a new device arrives. + Is there a better way to do this */ + ExAcquireFastMutex(&PdoDeviceExtension->ListLock); + PdoDeviceExtension->HaltQueue = TRUE; + ExReleaseFastMutex(&PdoDeviceExtension->ListLock); + } case RemovalRelations: case EjectionRelations: { @@ -500,62 +558,101 @@ PdoDispatchPnp( { DPRINT1("Failed to create string from GUID!\n"); } - DPRINT1("Interface GUID requested %wZ\n", &GuidString); - DPRINT1("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size); - DPRINT1("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version); + DPRINT("Interface GUID requested %wZ\n", &GuidString); + DPRINT("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size); + DPRINT("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version); + + /* Assume success */ Status = STATUS_SUCCESS; Information = 0; - /* FIXME: Check the actual Guid */ - if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V2) && (Stack->Parameters.QueryInterface.Version == 2)) - { - InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface; - InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2); - InterfaceDI->Version = 2; - InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject; - InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference; - InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference; - InterfaceDI->GetUSBDIVersion = GetUSBDIVersion; - InterfaceDI->QueryBusTime = QueryBusTime; - InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb; - InterfaceDI->QueryBusInformation = QueryBusInformation; - InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed; - InterfaceDI->EnumLogEntry = EnumLogEntry; - } - /* FIXME: Check the actual Guid */ - else if (Stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_HUB_V5) && - (Stack->Parameters.QueryInterface.Version == 5)) + if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID)) { InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface; - InterfaceHub->Version = 5; - InterfaceHub->Size = sizeof(USB_BUS_INTERFACE_HUB_V5); - InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject; - InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference; - InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference; - InterfaceHub->CreateUsbDevice = CreateUsbDevice; - InterfaceHub->InitializeUsbDevice = InitializeUsbDevice; - InterfaceHub->GetUsbDescriptors = GetUsbDescriptors; - InterfaceHub->RemoveUsbDevice = RemoveUsbDevice; - InterfaceHub->RestoreUsbDevice = RestoreUsbDevice; - InterfaceHub->GetPortHackFlags = GetPortHackFlags; - InterfaceHub->QueryDeviceInformation = QueryDeviceInformation; - InterfaceHub->GetControllerInformation = GetControllerInformation; - InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend; - InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation; - InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName; - InterfaceHub->GetDeviceBusContext = GetDeviceBusContext; - InterfaceHub->Initialize20Hub = Initialize20Hub; - InterfaceHub->RootHubInitNotification = RootHubInitNotification; - InterfaceHub->FlushTransfers = FlushTransfers; - InterfaceHub->SetDeviceHandleData = SetDeviceHandleData; + InterfaceHub->Version = Stack->Parameters.QueryInterface.Version; + if (Stack->Parameters.QueryInterface.Version >= 0) + { + InterfaceHub->Size = Stack->Parameters.QueryInterface.Size; + InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject; + InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference; + InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference; + } + if (Stack->Parameters.QueryInterface.Version >= 1) + { + InterfaceHub->CreateUsbDevice = CreateUsbDevice; + InterfaceHub->InitializeUsbDevice = InitializeUsbDevice; + InterfaceHub->GetUsbDescriptors = GetUsbDescriptors; + InterfaceHub->RemoveUsbDevice = RemoveUsbDevice; + InterfaceHub->RestoreUsbDevice = RestoreUsbDevice; + InterfaceHub->GetPortHackFlags = GetPortHackFlags; + InterfaceHub->QueryDeviceInformation = QueryDeviceInformation; + } + if (Stack->Parameters.QueryInterface.Version >= 2) + { + InterfaceHub->GetControllerInformation = GetControllerInformation; + InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend; + InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation; + InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName; + InterfaceHub->GetDeviceBusContext = GetDeviceBusContext; + InterfaceHub->Initialize20Hub = Initialize20Hub; + + } + if (Stack->Parameters.QueryInterface.Version >= 3) + { + InterfaceHub->RootHubInitNotification = RootHubInitNotification; + } + if (Stack->Parameters.QueryInterface.Version >= 4) + { + InterfaceHub->FlushTransfers = FlushTransfers; + } + if (Stack->Parameters.QueryInterface.Version >= 5) + { + InterfaceHub->SetDeviceHandleData = SetDeviceHandleData; + } + if (Stack->Parameters.QueryInterface.Version >= 6) + { + DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n"); + } + break; } - else + + if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID)) { - DPRINT1("Not Supported\n"); - Status = Irp->IoStatus.Status; - Information = Irp->IoStatus.Information; + InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface; + InterfaceDI->Version = Stack->Parameters.QueryInterface.Version; + if (Stack->Parameters.QueryInterface.Version >= 0) + { + //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2); + InterfaceDI->Size = Stack->Parameters.QueryInterface.Size; + InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject; + InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference; + InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference; + InterfaceDI->GetUSBDIVersion = GetUSBDIVersion; + InterfaceDI->QueryBusTime = QueryBusTime; + InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb; + InterfaceDI->QueryBusInformation = QueryBusInformation; + } + if (Stack->Parameters.QueryInterface.Version >= 1) + { + InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed; + } + if (Stack->Parameters.QueryInterface.Version >= 2) + { + InterfaceDI->EnumLogEntry = EnumLogEntry; + } + + if (Stack->Parameters.QueryInterface.Version >= 3) + { + DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n"); + } + break; } + + DPRINT1("GUID Not Supported\n"); + Status = Irp->IoStatus.Status; + Information = Irp->IoStatus.Information; + break; } case IRP_MN_QUERY_BUS_INFORMATION: @@ -593,4 +690,3 @@ PdoDispatchPnp( IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } - diff --git a/drivers/usb/usbehci/urbreq.c b/drivers/usb/usbehci/urbreq.c index d9a85ba1338..cbd18452757 100644 --- a/drivers/usb/usbehci/urbreq.c +++ b/drivers/usb/usbehci/urbreq.c @@ -15,7 +15,7 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead, PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD1, PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD2, PQUEUE_TRANSFER_DESCRIPTOR *CtrlTD3, - PEHCI_SETUP_FORMAT *CtrlSetup, + PUSB_DEFAULT_PIPE_SETUP_PACKET *CtrlSetup, PVOID *CtrlData, ULONG Size) { @@ -67,15 +67,15 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead, *CtrlTD3 = (PQUEUE_TRANSFER_DESCRIPTOR) (((ULONG)(*CtrlTD2) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0x1F) & ~0x1F); /* Must be Page aligned */ - *CtrlSetup = (PEHCI_SETUP_FORMAT) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF) & ~0xFFF); - *CtrlData = (PUSB_DEVICE_DESCRIPTOR) (( (ULONG)(*CtrlSetup) + sizeof(EHCI_SETUP_FORMAT) + 0xFFF) & ~0xFFF); + *CtrlSetup = (PUSB_DEFAULT_PIPE_SETUP_PACKET) (( (ULONG)(*CtrlTD3) + sizeof(QUEUE_TRANSFER_DESCRIPTOR) + 0xFFF) & ~0xFFF); + *CtrlData = (PVOID) (( (ULONG)(*CtrlSetup) + sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) + 0xFFF) & ~0xFFF); (*CtrlTD1)->NextPointer = TERMINATE_POINTER; (*CtrlTD1)->AlternateNextPointer = TERMINATE_POINTER; (*CtrlTD1)->BufferPointer[0] = (ULONG)MmGetPhysicalAddress((PVOID) (*CtrlSetup)).LowPart; (*CtrlTD1)->Token.Bits.DataToggle = FALSE; (*CtrlTD1)->Token.Bits.InterruptOnComplete = FALSE; - (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(EHCI_SETUP_FORMAT); + (*CtrlTD1)->Token.Bits.TotalBytesToTransfer = sizeof(USB_DEFAULT_PIPE_SETUP_PACKET); (*CtrlTD1)->Token.Bits.ErrorCounter = 0x03; (*CtrlTD1)->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN; (*CtrlTD1)->Token.Bits.Active = TRUE; @@ -105,46 +105,48 @@ IntializeHeadQueueForStandardRequest(PQUEUE_HEAD QueueHead, } BOOLEAN -GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub) +ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength) { - PEHCI_SETUP_FORMAT CtrlSetup = NULL; - PUSB_DEVICE_DESCRIPTOR CtrlData = NULL; + PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup = NULL; + PVOID CtrlData = NULL; PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL; PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL; PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL; + PQUEUE_HEAD QueueHead; PEHCI_USBCMD_CONTENT UsbCmd; PEHCI_USBSTS_CONTEXT UsbSts; LONG Base; LONG tmp; + DPRINT1("ExecuteControlRequest: Buffer %x, Length %x\n", Buffer, BufferLength); + Base = (ULONG) DeviceExtension->ResourceMemory; /* Set up the QUEUE HEAD in memory */ QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr); + /* Initialize the memory pointers */ IntializeHeadQueueForStandardRequest(QueueHead, &CtrlTD1, &CtrlTD2, &CtrlTD3, &CtrlSetup, (PVOID)&CtrlData, - sizeof(USB_DEVICE_DESCRIPTOR)); + BufferLength); - /* FIXME: Use defines and handle other than Device Desciptors */ - if (Hub) - { - CtrlSetup->bmRequestType = 0x80; - CtrlSetup->wValue = 0x0600; - } - else - { - CtrlSetup->bmRequestType = 0x80; - CtrlSetup->wValue = 0x0100; - } - CtrlSetup->bRequest = 0x06; - CtrlSetup->wIndex = 0; - CtrlSetup->wLength = sizeof(USB_DEVICE_DESCRIPTOR); + CtrlSetup->bmRequestType._BM.Recipient = SetupPacket->bmRequestType._BM.Recipient; + CtrlSetup->bmRequestType._BM.Type = SetupPacket->bmRequestType._BM.Type; + CtrlSetup->bmRequestType._BM.Dir = SetupPacket->bmRequestType._BM.Dir; + CtrlSetup->bRequest = SetupPacket->bRequest; + CtrlSetup->wValue.LowByte = SetupPacket->wValue.LowByte; + CtrlSetup->wValue.HiByte = SetupPacket->wValue.HiByte; + CtrlSetup->wIndex.W = SetupPacket->wIndex.W; + CtrlSetup->wLength = SetupPacket->wLength; + + + QueueHead->EndPointCapabilities1.DeviceAddress = Address; + //QueueHead->EndPointCapabilities2.PortNumber = Port; tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; @@ -190,136 +192,15 @@ GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEV break; } - if (OutBuffer != NULL) + if (CtrlSetup->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST) { - OutBuffer->bLength = CtrlData->bLength; - OutBuffer->bDescriptorType = CtrlData->bDescriptorType; - OutBuffer->bcdUSB = CtrlData->bcdUSB; - OutBuffer->bDeviceClass = CtrlData->bDeviceClass; - OutBuffer->bDeviceSubClass = CtrlData->bDeviceSubClass; - OutBuffer->bDeviceProtocol = CtrlData->bDeviceProtocol; - OutBuffer->bMaxPacketSize0 = CtrlData->bMaxPacketSize0; - OutBuffer->idVendor = CtrlData->idVendor; - OutBuffer->idProduct = CtrlData->idProduct; - OutBuffer->bcdDevice = CtrlData->bcdDevice; - OutBuffer->iManufacturer = CtrlData->iManufacturer; - OutBuffer->iProduct = CtrlData->iProduct; - OutBuffer->iSerialNumber = CtrlData->iSerialNumber; - OutBuffer->bNumConfigurations = CtrlData->bNumConfigurations; - } - - DPRINT1("bLength %d\n", CtrlData->bLength); - DPRINT1("bDescriptorType %x\n", CtrlData->bDescriptorType); - DPRINT1("bcdUSB %x\n", CtrlData->bcdUSB); - DPRINT1("CtrlData->bDeviceClass %x\n", CtrlData->bDeviceClass); - DPRINT1("CtrlData->bDeviceSubClass %x\n", CtrlData->bDeviceSubClass); - DPRINT1("CtrlData->bDeviceProtocal %x\n", CtrlData->bDeviceProtocol); - DPRINT1("CtrlData->bMaxPacketSize %x\n", CtrlData->bMaxPacketSize0); - DPRINT1("CtrlData->idVendor %x\n", CtrlData->idVendor); - DPRINT1("CtrlData->idProduct %x\n", CtrlData->idProduct); - DPRINT1("CtrlData->bcdDevice %x\n", CtrlData->bcdDevice); - DPRINT1("CtrlData->iManufacturer %x\n", CtrlData->iManufacturer); - DPRINT1("CtrlData->iProduct %x\n", CtrlData->iProduct); - DPRINT1("CtrlData->iSerialNumber %x\n", CtrlData->iSerialNumber); - DPRINT1("CtrlData->bNumConfigurations %x\n", CtrlData->bNumConfigurations); - - /* Temporary: Remove */ - if (CtrlData->bLength > 0) - { - /* We got valid data, try for strings */ - UCHAR Manufacturer = CtrlData->iManufacturer; - UCHAR Product = CtrlData->iProduct; - UCHAR SerialNumber = CtrlData->iSerialNumber; - - GetDeviceStringDescriptor(DeviceExtension, Manufacturer); - GetDeviceStringDescriptor(DeviceExtension, Product); - GetDeviceStringDescriptor(DeviceExtension, SerialNumber); - } - - return TRUE; -} - -BOOLEAN -GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index) -{ - PEHCI_SETUP_FORMAT CtrlSetup = NULL; - PSTRING_DESCRIPTOR CtrlData = NULL; - PQUEUE_TRANSFER_DESCRIPTOR CtrlTD1 = NULL; - PQUEUE_TRANSFER_DESCRIPTOR CtrlTD2 = NULL; - PQUEUE_TRANSFER_DESCRIPTOR CtrlTD3 = NULL; - PQUEUE_HEAD QueueHead; - PEHCI_USBCMD_CONTENT UsbCmd; - PEHCI_USBSTS_CONTEXT UsbSts; - LONG Base; - LONG tmp; - - Base = (ULONG) DeviceExtension->ResourceMemory; - - /* Set up the QUEUE HEAD in memory */ - QueueHead = (PQUEUE_HEAD) ((ULONG)DeviceExtension->AsyncListQueueHeadPtr); - - IntializeHeadQueueForStandardRequest(QueueHead, - &CtrlTD1, - &CtrlTD2, - &CtrlTD3, - &CtrlSetup, - (PVOID)&CtrlData, - sizeof(STRING_DESCRIPTOR) + 256); - - /* FIXME: Use defines and handle other than Device Desciptors */ - CtrlSetup->bmRequestType = 0x80; - CtrlSetup->bRequest = 0x06; - CtrlSetup->wValue = 0x0300 | Index; - CtrlSetup->wIndex = 0; - /* 256 pulled from thin air */ - CtrlSetup->wLength = sizeof(STRING_DESCRIPTOR) + 256; - - tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - UsbCmd->Run = FALSE; - WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD), tmp); - - /* Wait for the controller to halt */ - for (;;) - { - KeStallExecutionProcessor(10); - tmp = READ_REGISTER_ULONG((PULONG)(Base + EHCI_USBSTS)); - UsbSts = (PEHCI_USBSTS_CONTEXT)&tmp; - DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(Base + EHCI_USBSTS))); - if (UsbSts->HCHalted) + if ((Buffer) && (BufferLength)) { - break; + RtlCopyMemory(Buffer, CtrlData, BufferLength); } + else + DPRINT1("Unable to copy data to buffer\n"); } - /* Set to TRUE on interrupt for async completion */ - DeviceExtension->AsyncComplete = FALSE; - QueueHead->QETDPointer = (ULONG) MmGetPhysicalAddress((PVOID)(CtrlTD1)).LowPart; - - tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - UsbCmd->AsyncEnable = TRUE; - - WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp); - - tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD)); - UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp; - - /* Interrupt on Async completion */ - UsbCmd->DoorBell = TRUE; - UsbCmd->Run = TRUE; - WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp); - - for (;;) - { - KeStallExecutionProcessor(10); - DPRINT("Waiting for completion!\n"); - if (DeviceExtension->AsyncComplete == TRUE) - break; - } - - DPRINT1("String %S\n", &CtrlData->bString); - return TRUE; } - diff --git a/drivers/usb/usbehci/usbehci.c b/drivers/usb/usbehci/usbehci.c index 15540694bf1..0f35a318f02 100644 --- a/drivers/usb/usbehci/usbehci.c +++ b/drivers/usb/usbehci/usbehci.c @@ -9,11 +9,6 @@ /* DEFINES *******************************************************************/ #include "usbehci.h" -#define NDEBUG - -/* INCLUDES *******************************************************************/ -#include - static NTSTATUS NTAPI IrpStub(PDEVICE_OBJECT DeviceObject, PIRP Irp) diff --git a/drivers/usb/usbehci/usbehci.h b/drivers/usb/usbehci/usbehci.h index 13bfabb3657..56f03b5b491 100644 --- a/drivers/usb/usbehci/usbehci.h +++ b/drivers/usb/usbehci/usbehci.h @@ -5,10 +5,12 @@ #include #define NDEBUG #include -#include "usbiffn.h" +#include #include #include +#define USB_POOL_TAG (ULONG)'UsbR' + #define DEVICEINTIALIZED 0x01 #define DEVICESTARTED 0x02 #define DEVICEBUSY 0x04 @@ -196,21 +198,46 @@ typedef struct _EHCI_SETUP_FORMAT typedef struct _STRING_DESCRIPTOR { - UCHAR bLength; /* Size of this descriptor in bytes */ + UCHAR bLength; /* Size of this descriptor in bytes */ UCHAR bDescriptorType; /* STRING Descriptor Type */ - UCHAR bString[0]; /* UNICODE encoded string */ + UCHAR bString[0]; /* UNICODE encoded string */ } STRING_DESCRIPTOR, *PSTRING_DESCRIPTOR; +typedef struct _USB_ENDPOINT +{ + ULONG Flags; + LIST_ENTRY UrbList; + struct _USB_INTERFACE *Interface; + USB_ENDPOINT_DESCRIPTOR EndPointDescriptor; +} USB_ENDPOINT, *PUSB_ENDPOINT; + +typedef struct _USB_INTERFACE +{ + struct _USB_CONFIGURATION *Config; + USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + USB_ENDPOINT *EndPoints[]; +} USB_INTERFACE, *PUSB_INTERFACE; + +typedef struct _USB_CONFIGURATION +{ + struct _USB_DEVICE *Device; + USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; + USB_INTERFACE *Interfaces[]; +} USB_CONFIGURATION, *PUSB_CONFIGURATION; + typedef struct _USB_DEVICE { UCHAR Address; ULONG Port; PVOID ParentDevice; BOOLEAN IsHub; + USB_DEVICE_SPEED DeviceSpeed; + USB_DEVICE_TYPE DeviceType; USB_DEVICE_DESCRIPTOR DeviceDescriptor; - USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; - USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; - USB_ENDPOINT_DESCRIPTOR EndPointDescriptor; + USB_CONFIGURATION *ActiveConfig; + USB_INTERFACE *ActiveInterface; + USB_CONFIGURATION **Configs; + } USB_DEVICE, *PUSB_DEVICE; /* USBCMD register 32 bits */ @@ -380,11 +407,16 @@ typedef struct _PDO_DEVICE_EXTENSION PIRP CurrentIrp; HANDLE ThreadHandle; ULONG ChildDeviceCount; - BOOLEAN HaltUrbHandling; + BOOLEAN HaltQueue; PVOID CallbackContext; - PRH_INIT_CALLBACK CallbackRoutine; + RH_INIT_CALLBACK *CallbackRoutine; + USB_IDLE_CALLBACK IdleCallback; + PVOID IdleContext; ULONG NumberOfPorts; EHCIPORTS Ports[32]; + KTIMER Timer; + KEVENT QueueDrainedEvent; + FAST_MUTEX ListLock; } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; typedef struct _WORKITEM_DATA @@ -432,10 +464,7 @@ NTSTATUS NTAPI PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp); BOOLEAN -GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index, PUSB_DEVICE_DESCRIPTOR OutBuffer, BOOLEAN Hub); - -BOOLEAN -GetDeviceStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, UCHAR Index); +ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength); VOID QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp); diff --git a/drivers/usb/usbehci/usbiffn.c b/drivers/usb/usbehci/usbiffn.c index 47fefb610b3..4dd98f4212d 100644 --- a/drivers/usb/usbehci/usbiffn.c +++ b/drivers/usb/usbehci/usbiffn.c @@ -7,11 +7,57 @@ * Michael Martin */ -/* usbbusif.h and hubbusif.h need to be imported */ #include "usbehci.h" -#include "usbiffn.h" -#define NDEBUG -#include +#include +#include + +PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub) +{ + PUSB_DEVICE UsbDevicePointer = NULL; + UsbDevicePointer = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG); + + if (!UsbDevicePointer) + { + DPRINT1("Out of memory\n"); + return NULL; + } + + RtlZeroMemory(UsbDevicePointer, sizeof(USB_DEVICE)); + + if ((Hub) && (!Parent)) + { + DPRINT1("This is the root hub\n"); + } + + UsbDevicePointer->Address = DeviceNumber; + UsbDevicePointer->Port = Port; + UsbDevicePointer->ParentDevice = Parent; + + UsbDevicePointer->IsHub = Hub; + + return UsbDevicePointer; +} + +BOOLEAN +IsHandleValid(PVOID BusContext, + PUSB_DEVICE_HANDLE DeviceHandle) +{ + PPDO_DEVICE_EXTENSION PdoDeviceExtension; + LONG i; + + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) BusContext; + + if (!DeviceHandle) + return FALSE; + + for (i = 0; i < 128; i++) + { + if (PdoDeviceExtension->UsbDevices[i] == DeviceHandle) + return TRUE; + } + + return FALSE; +} VOID USB_BUSIFFN @@ -36,15 +82,157 @@ CreateUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, USHORT PortStatus, USHORT PortNumber) { - DPRINT1("CreateUsbDevice called\n"); + PPDO_DEVICE_EXTENSION PdoDeviceExtension; + PUSB_DEVICE UsbDevice; + LONG i = 0; + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; + DPRINT1("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber); + + UsbDevice = InternalCreateUsbDevice(PdoDeviceExtension->ChildDeviceCount, PortNumber, HubDeviceHandle, FALSE); + + /* Add it to the list */ + while (TRUE) + { + if (PdoDeviceExtension->UsbDevices[i] == NULL) + { + PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice; + PdoDeviceExtension->UsbDevices[i]->Address = i + 1; + PdoDeviceExtension->UsbDevices[i]->Port = PortNumber; + break; + } + i++; + } + + /* Return it */ + *NewDevice = UsbDevice; return STATUS_SUCCESS; } +/* Called when SCE reports a change */ +/* FIXME: Do something better for memory */ NTSTATUS USB_BUSIFFN InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle) { - DPRINT1("InitializeUsbDevice called\n"); + PPDO_DEVICE_EXTENSION PdoDeviceExtension; + PFDO_DEVICE_EXTENSION FdoDeviceExtension; + USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; + PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc; + PUSB_INTERFACE_DESCRIPTOR InterfaceDesc; + PUSB_ENDPOINT_DESCRIPTOR EndpointDesc; + PUSB_DEVICE UsbDevice; + BOOLEAN ResultOk; + PVOID Buffer; + PUCHAR Ptr; + LONG i, j, k; + + DPRINT1("InitializeUsbDevice called, device %x\n", DeviceHandle); + PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; + FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension; + UsbDevice = (PUSB_DEVICE) DeviceHandle; + + Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, USB_POOL_TAG); + + if (!Buffer) + { + DPRINT1("Out of memory\n"); + return STATUS_NO_MEMORY; + } + + Ptr = Buffer; + /* Set the device address */ + CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; + CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; + CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_HOST_TO_DEVICE; + CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS; + CtrlSetup.wValue.W = UsbDevice->Address; + CtrlSetup.wIndex.W = 0; + CtrlSetup.wLength = 0; + + ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, 0, NULL, 0); + + /* Get the Device Descriptor */ + CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; + CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; + CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; + CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; + CtrlSetup.wValue.LowByte = 0; + CtrlSetup.wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; + CtrlSetup.wIndex.W = 0; + CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR); + + ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, + &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + + DPRINT1("bLength %x\n", UsbDevice->DeviceDescriptor.bLength); + DPRINT1("bDescriptorType %x\n", UsbDevice->DeviceDescriptor.bDescriptorType); + DPRINT1("bNumDescriptors %x\n", UsbDevice->DeviceDescriptor.bNumConfigurations); + + if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0) + return STATUS_DEVICE_DATA_ERROR; + + UsbDevice->Configs = ExAllocatePoolWithTag(NonPagedPool, + sizeof(PVOID) * UsbDevice->DeviceDescriptor.bNumConfigurations, + USB_POOL_TAG); + + if (!UsbDevice->Configs) + { + DPRINT1("Out of memory\n"); + return STATUS_NO_MEMORY; + } + + for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++) + { + /* Get the Device Configuration Descriptor */ + CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; + CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD; + CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST; + CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR; + CtrlSetup.wValue.LowByte = 0; + CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; + CtrlSetup.wIndex.W = 0; + CtrlSetup.wLength = PAGE_SIZE; + + ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port, Buffer, PAGE_SIZE); + + ConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)Ptr; + + ASSERT(ConfigDesc->wTotalLength <= PAGE_SIZE); + + UsbDevice->Configs[i] = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ConfigDesc->bNumInterfaces, + USB_POOL_TAG); + UsbDevice->Configs[i]->Device = UsbDevice; + RtlCopyMemory(&UsbDevice->Configs[0]->ConfigurationDescriptor, + ConfigDesc, sizeof(USB_CONFIGURATION_DESCRIPTOR)); + Ptr += ConfigDesc->bLength; + + for (j = 0; j < ConfigDesc->bNumInterfaces; j++) + { + InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) Ptr; + UsbDevice->Configs[i]->Interfaces[j] = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB_INTERFACE) + sizeof(PVOID) * InterfaceDesc->bNumEndpoints, + USB_POOL_TAG); + RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor, + InterfaceDesc, + sizeof(USB_INTERFACE_DESCRIPTOR)); + + Ptr += InterfaceDesc->bLength; + + for (k = 0; k < InterfaceDesc->bNumEndpoints; k++) + { + EndpointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Ptr; + UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT), USB_POOL_TAG); + RtlCopyMemory(&UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]->EndPointDescriptor, + EndpointDesc, sizeof(USB_ENDPOINT_DESCRIPTOR)); + } + + } + } + + UsbDevice->ActiveConfig = UsbDevice->Configs[0]; + UsbDevice->ActiveInterface = UsbDevice->Configs[0]->Interfaces[0]; + return STATUS_SUCCESS; } @@ -54,10 +242,25 @@ GetUsbDescriptors(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, PUCHAR DeviceDescriptorBuffer, PULONG DeviceDescriptorBufferLength, - PUCHAR ConfigurationBuffer, + PUCHAR ConfigDescriptorBuffer, PULONG ConfigDescriptorBufferLength) { - DPRINT1("GetUsbDescriptor called\n"); + PUSB_DEVICE UsbDevice; + DPRINT1("GetUsbDescriptor %x, %d, %x, %d\n", DeviceDescriptorBuffer, DeviceDescriptorBufferLength, ConfigDescriptorBuffer, ConfigDescriptorBufferLength); + + UsbDevice = (PUSB_DEVICE) DeviceHandle; + + if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength)) + { + RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + *DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); + } + if ((ConfigDescriptorBuffer) && (ConfigDescriptorBufferLength)) + { + RtlCopyMemory(ConfigDescriptorBuffer, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); + *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); + } + return STATUS_SUCCESS; } @@ -74,7 +277,7 @@ USB_BUSIFFN RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle) { DPRINT1("RestoreUsbDevice called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } NTSTATUS @@ -82,7 +285,7 @@ USB_BUSIFFN GetPortHackFlags(PVOID BusContext, PULONG Flags) { DPRINT1("GetPortHackFlags called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } NTSTATUS @@ -93,7 +296,51 @@ QueryDeviceInformation(PVOID BusContext, ULONG DeviceInformationBufferLength, PULONG LengthReturned) { - DPRINT1("QueryDeviceInformation called\n"); + PUSB_DEVICE_INFORMATION_0 DeviceInfo = DeviceInformationBuffer; + PUSB_DEVICE UsbDevice = (PUSB_DEVICE) DeviceHandle; + ULONG SizeNeeded; + LONG i; + + DPRINT1("QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, DeviceInformationBufferLength, LengthReturned); + + /* Search for a valid usb device in this BusContext */ + if (!IsHandleValid(BusContext, DeviceHandle)) + { + DPRINT1("Not a valid DeviceHandle\n"); + return STATUS_INVALID_PARAMETER; + } + + SizeNeeded = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints]); + *LengthReturned = SizeNeeded; + + DeviceInfo->ActualLength = SizeNeeded; + + if (DeviceInformationBufferLength < SizeNeeded) + { + DPRINT1("Buffer to small\n"); + return STATUS_BUFFER_TOO_SMALL; + } + + if (DeviceInfo->InformationLevel != 0) + { + DPRINT1("Invalid Param\n"); + return STATUS_INVALID_PARAMETER; + } + + DeviceInfo->PortNumber = UsbDevice->Port; + DeviceInfo->HubAddress = 1; + DeviceInfo->DeviceAddress = UsbDevice->Address; + DeviceInfo->DeviceSpeed = UsbDevice->DeviceSpeed; + DeviceInfo->DeviceType = UsbDevice->DeviceType; + DeviceInfo->CurrentConfigurationValue = UsbDevice->ActiveConfig->ConfigurationDescriptor.bConfigurationValue; + DeviceInfo->NumberOfOpenPipes = UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; + + RtlCopyMemory(&DeviceInfo->DeviceDescriptor, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + + for (i = 0; i < UsbDevice->ActiveInterface->InterfaceDescriptor.bNumEndpoints; i++) + { + RtlCopyMemory(&DeviceInfo->PipeList[i].EndpointDescriptor, &UsbDevice->ActiveInterface->EndPoints[i]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR)); + } return STATUS_SUCCESS; } @@ -104,7 +351,30 @@ GetControllerInformation(PVOID BusContext, ULONG ControllerInformationBufferLength, PULONG LengthReturned) { + PUSB_CONTROLLER_INFORMATION_0 ControllerInfo; + DPRINT1("GetControllerInformation called\n"); + + ControllerInfo = ControllerInformationBuffer; + + if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0)) + { + DPRINT1("Buffer to small\n"); + return STATUS_BUFFER_TOO_SMALL; + } + + if (ControllerInfo->InformationLevel != 0) + { + DPRINT1("InformationLevel other than 0 not supported\n"); + return STATUS_NOT_SUPPORTED; + } + + ControllerInfo->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0); + ControllerInfo->SelectiveSuspendEnabled = FALSE; + ControllerInfo->IsHighSpeedController = TRUE; + + *LengthReturned = ControllerInfo->ActualLength; + return STATUS_SUCCESS; } @@ -113,7 +383,7 @@ USB_BUSIFFN ControllerSelectiveSuspend(PVOID BusContext, BOOLEAN Enable) { DPRINT1("ControllerSelectiveSuspend called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } NTSTATUS @@ -129,7 +399,7 @@ GetExtendedHubInformation(PVOID BusContext, PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; PFDO_DEVICE_EXTENSION FdoDeviceExntension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension; LONG i; - + DPRINT1("GetExtendedHubInformation\n"); /* Set the default return value */ *LengthReturned = 0; /* Caller must have set InformationLevel to 0 */ @@ -162,6 +432,12 @@ GetRootHubSymbolicName(PVOID BusContext, PULONG HubSymNameActualLength) { DPRINT1("GetRootHubSymbolicName called\n"); + + if (HubSymNameBufferLength < 16) + return STATUS_UNSUCCESSFUL; + RtlCopyMemory(HubSymNameBuffer, L"ROOT_HUB", HubSymNameBufferLength); + *HubSymNameActualLength = 16; + return STATUS_SUCCESS; } @@ -177,7 +453,11 @@ NTSTATUS USB_BUSIFFN Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount) { - DPRINT1("Initialize20Hub called\n"); + DPRINT1("Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle); + + /* FIXME: */ + /* Create the Irp Queue for SCE */ + /* Should queue be created for each device or each enpoint??? */ return STATUS_SUCCESS; } @@ -191,6 +471,17 @@ RootHubInitNotification(PVOID BusContext, PVOID CallbackContext, PRH_INIT_CALLBA PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension; PdoDeviceExtension->CallbackContext = CallbackContext; PdoDeviceExtension->CallbackRoutine = CallbackRoutine; + if (PdoDeviceExtension->CallbackRoutine) + { + DPRINT1("Called Callbackrountine\n"); + PdoDeviceExtension->CallbackRoutine(PdoDeviceExtension->CallbackContext); + DPRINT1("Done Callbackrountine\n"); + } + else + { + DPRINT1("PdoDeviceExtension->CallbackRoutine is NULL!\n"); + } + return STATUS_SUCCESS; } @@ -211,12 +502,12 @@ SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevi /* USB_BUS_INTERFACE_USBDI_V2 Functions */ -NTSTATUS +VOID USB_BUSIFFN GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites) { DPRINT1("GetUSBDIVersion called\n"); - return STATUS_SUCCESS; + return; } NTSTATUS @@ -224,7 +515,7 @@ USB_BUSIFFN QueryBusTime(PVOID BusContext, PULONG CurrentFrame) { DPRINT1("QueryBusTime called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } NTSTATUS @@ -232,7 +523,7 @@ USB_BUSIFFN SubmitIsoOutUrb(PVOID BusContext, PURB Urb) { DPRINT1("SubmitIsoOutUrb called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } NTSTATUS @@ -244,7 +535,7 @@ QueryBusInformation(PVOID BusContext, PULONG BusInformationActualLength) { DPRINT1("QueryBusInformation called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } BOOLEAN @@ -260,6 +551,5 @@ USB_BUSIFFN EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2) { DPRINT1("EnumLogEntry called\n"); - return STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } - diff --git a/drivers/usb/usbehci/usbiffn.h b/drivers/usb/usbehci/usbiffn.h index e9c2de469be..eff48f0eac7 100644 --- a/drivers/usb/usbehci/usbiffn.h +++ b/drivers/usb/usbehci/usbiffn.h @@ -1,77 +1,12 @@ #pragma once -#define USB_BUSIFFN __stdcall #include #include #include +#include -/* usbbusif.h and hubbusif.h need to be imported */ -typedef PVOID PUSB_DEVICE_HANDLE; - -typedef -VOID -USB_BUSIFFN -RH_INIT_CALLBACK (PVOID CallBackContext); - -typedef RH_INIT_CALLBACK *PRH_INIT_CALLBACK; - -typedef struct _USB_EXTPORT_INFORMATION_0 -{ - ULONG PhysicalPortNumber; - ULONG PortLabelNumber; - USHORT VidOverride; - USHORT PidOverride; - ULONG PortAttributes; -} USB_EXTPORT_INFORMATION_0, *PUSB_EXTPORT_INFORMATION; - -typedef struct _USB_EXTHUB_INFORMATION_0 -{ - ULONG InformationLevel; - ULONG NumberOfPorts; - USB_EXTPORT_INFORMATION_0 Port[255]; -} USB_EXTHUB_INFORMATION_0, *PUSB_EXTHUB_INFORMATION_0; - -typedef struct _USB_BUS_INTERFACE_USBDI_V2 -{ - USHORT Size; - USHORT Version; - PVOID BusContext; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - - PVOID GetUSBDIVersion; - PVOID QueryBusTime; - PVOID SubmitIsoOutUrb; - PVOID QueryBusInformation; - PVOID IsDeviceHighSpeed; - PVOID EnumLogEntry; -} USB_BUS_INTERFACE_USBDI_V2, *PUSB_BUS_INTERFACE_USBDI_V2; - -typedef struct _USB_BUS_INTERFACE_HUB_V5 -{ - USHORT Size; - USHORT Version; - PVOID BusContext; - PINTERFACE_REFERENCE InterfaceReference; - PINTERFACE_DEREFERENCE InterfaceDereference; - - PVOID CreateUsbDevice; - PVOID InitializeUsbDevice; - PVOID GetUsbDescriptors; - PVOID RemoveUsbDevice; - PVOID RestoreUsbDevice; - PVOID GetPortHackFlags; - PVOID QueryDeviceInformation; - PVOID GetControllerInformation; - PVOID ControllerSelectiveSuspend; - PVOID GetExtendedHubInformation; - PVOID GetRootHubSymbolicName; - PVOID GetDeviceBusContext; - PVOID Initialize20Hub; - PVOID RootHubInitNotification; - PVOID FlushTransfers; - PVOID SetDeviceHandleData; -} USB_BUS_INTERFACE_HUB_V5, *PUSB_BUS_INTERFACE_HUB_V5; +PVOID +InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub); VOID USB_BUSIFFN @@ -98,7 +33,7 @@ GetUsbDescriptors(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, PUCHAR DeviceDescriptorBuffer, PULONG DeviceDescriptorBufferLength, - PUCHAR ConfigurationBuffer, + PUCHAR ConfigDescriptorBuffer, PULONG ConfigDescriptorBufferLength); NTSTATUS @@ -167,7 +102,7 @@ VOID USB_BUSIFFN SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo); -NTSTATUS +VOID USB_BUSIFFN GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites); diff --git a/hal/halx86/directory.rbuild b/hal/halx86/directory.rbuild index 7cea4c006fa..9c8c482a2c7 100644 --- a/hal/halx86/directory.rbuild +++ b/hal/halx86/directory.rbuild @@ -3,14 +3,15 @@ - - - + + + + - + diff --git a/hal/halx86/generic/acpi/halpnpdd.c b/hal/halx86/generic/acpi/halpnpdd.c index ca85188bcaf..8617b20f1fc 100644 --- a/hal/halx86/generic/acpi/halpnpdd.c +++ b/hal/halx86/generic/acpi/halpnpdd.c @@ -848,9 +848,6 @@ HalpDriverEntry(IN PDRIVER_OBJECT DriverObject, /* Now add us */ if (NT_SUCCESS(Status)) Status = HalpAddDevice(DriverObject, TargetDevice); - - /* Force re-enumeration??? */ - IoInvalidateDeviceRelations(TargetDevice, 0); /* Return to kernel */ return Status; diff --git a/hal/halx86/generic/halinit.c b/hal/halx86/generic/halinit.c index 4309ac1a16e..db54eb59d63 100644 --- a/hal/halx86/generic/halinit.c +++ b/hal/halx86/generic/halinit.c @@ -145,33 +145,31 @@ HalpMapPhysicalMemory64(IN PHYSICAL_ADDRESS PhysicalAddress, /* Start at the current HAL heap base */ BaseAddress = HalpHeapStart; + VirtualAddress = BaseAddress; /* Loop until we have all the pages required */ while (UsedPages < PageCount) { - /* Begin a new loop cycle */ - UsedPages = 0; - VirtualAddress = BaseAddress; - /* If this overflows past the HAL heap, it means there's no space */ - if (BaseAddress == NULL) return NULL; + if (VirtualAddress == NULL) return NULL; - /* Loop until we have all the pages required in a single run */ - while (UsedPages < PageCount) + /* Get the PTE for this address */ + PointerPte = HalAddressToPte(VirtualAddress); + + /* Go to the next page */ + VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); + + /* Check if the page is available */ + if (PointerPte->Valid) { - /* Get the PTE for this address and check if it's available */ - PointerPte = HalAddressToPte(VirtualAddress); - if (*(PULONG)PointerPte) - { - /* PTE has data, skip it and start with a new base address */ - BaseAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); - break; - } - - /* PTE is available, keep going on this run */ - VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE); - UsedPages++; + /* PTE has data, skip it and start with a new base address */ + BaseAddress = VirtualAddress; + UsedPages = 0; + continue; } + + /* PTE is available, keep going on this run */ + UsedPages++; } /* Take the base address of the page plus the actual offset in the address */ diff --git a/hal/halx86/hal_generic.rbuild b/hal/halx86/hal_generic.rbuild index 166bb930404..8dd5f7bc57d 100644 --- a/hal/halx86/hal_generic.rbuild +++ b/hal/halx86/hal_generic.rbuild @@ -16,7 +16,6 @@ sysbus.c beep.c - bios.c cmos.c display.c dma.c @@ -29,6 +28,7 @@ timer.c usage.c + bios.c portio.c systimer.S @@ -36,9 +36,16 @@ + + . x86bios.c + halinit.c + irq.S + misc.c + apic.c systimer.S + usage.c @@ -46,47 +53,4 @@ hal.h - - - include - include - - - - - - - bushndlr.c - isabus.c - halbus.c - pcibus.c - pcidata.c - sysbus.c - - beep.c - bios.c - cmos.c - dma.c - display.c - drive.c - misc.c - profil.c - reboot.c - spinlock.c - sysinfo.c - timer.c - usage.c - - - portio.c - systimer.S - - - - - halinit_up.c - pic.c - processor.c - - diff --git a/hal/halx86/hal_mini.rbuild b/hal/halx86/hal_mini.rbuild new file mode 100644 index 00000000000..a7baed44639 --- /dev/null +++ b/hal/halx86/hal_mini.rbuild @@ -0,0 +1,44 @@ + + + + + include + include + + + + + + + bushndlr.c + isabus.c + halbus.c + pcibus.c + pcidata.c + sysbus.c + + beep.c + bios.c + cmos.c + dma.c + display.c + drive.c + misc.c + profil.c + reboot.c + spinlock.c + sysinfo.c + timer.c + usage.c + + portio.c + systimer.S + + + + halinit_up.c + pic.c + processor.c + + + diff --git a/hal/halx86/halamd64.rbuild b/hal/halx86/halamd64.rbuild index 0b60f7615dc..ad96c0f1cf9 100644 --- a/hal/halx86/halamd64.rbuild +++ b/hal/halx86/halamd64.rbuild @@ -12,17 +12,25 @@ hal_generic hal_generic_acpi - hal_generic_up ntoskrnl - + x86emu - + + spinlock.c + + + + processor.c + + + + mps.S - + diff --git a/include/ddk/hubbusif.h b/include/ddk/hubbusif.h index e03f19edbb8..cf97c5cf64f 100644 --- a/include/ddk/hubbusif.h +++ b/include/ddk/hubbusif.h @@ -1,8 +1,14 @@ #pragma once +#define _HUBBUSIF_ + +#include "usbdi.h" + #if (NTDDI_VERSION >= NTDDI_WINXP) +#if !defined(_USBBUSIF_) typedef PVOID PUSB_DEVICE_HANDLE; +#endif typedef struct _ROOTHUB_PDO_EXTENSION { ULONG Signature; diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index 73aa6d6f780..5c03ef71b8e 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -3283,13 +3283,14 @@ ExFreeToZone( #define ExIsResourceAcquired ExIsResourceAcquiredSharedLite #define ExReleaseResourceForThread ExReleaseResourceForThreadLite +#ifdef _X86_ + typedef enum _INTERLOCKED_RESULT { ResultNegative = RESULT_NEGATIVE, ResultZero = RESULT_ZERO, ResultPositive = RESULT_POSITIVE } INTERLOCKED_RESULT; -#ifdef _X86_ NTKERNELAPI INTERLOCKED_RESULT FASTCALL diff --git a/include/ddk/usbbusif.h b/include/ddk/usbbusif.h index 0483738b18a..3d1c1f3a337 100644 --- a/include/ddk/usbbusif.h +++ b/include/ddk/usbbusif.h @@ -1,12 +1,16 @@ #pragma once +#define _USBBUSIF_ + #ifndef USB_BUSIFFN #define USB_BUSIFFN __stdcall #endif #if (NTDDI_VERSION >= NTDDI_WINXP) +#if !defined(_USBBUSIF_) typedef PVOID PUSB_DEVICE_HANDLE; +#endif typedef NTSTATUS (USB_BUSIFFN *PUSB_BUSIFFN_SUBMIT_ISO_OUT_URB) ( diff --git a/include/dxsdk/bdamedia.h b/include/dxsdk/bdamedia.h index 3cf12d5617b..f090af5b4c2 100644 --- a/include/dxsdk/bdamedia.h +++ b/include/dxsdk/bdamedia.h @@ -317,6 +317,20 @@ typedef enum { }KSPROPERTY_BDA_SIGNAL_STATS; +typedef struct tagBDA_TRANSPORT_INFO { + ULONG ulcbPhyiscalPacket; + ULONG ulcbPhyiscalFrame; + ULONG ulcbPhyiscalFrameAlignment; + REFERENCE_TIME AvgTimePerFrame; + +} BDA_TRANSPORT_INFO, *PBDA_TRANSPORT_INFO; + +typedef struct tagKS_DATARANGE_BDA_TRANSPORT +{ + KSDATARANGE DataRange; + BDA_TRANSPORT_INFO BdaTransportInfo; +} KS_DATARANGE_BDA_TRANSPORT, *PKS_DATARANGE_BDA_TRANSPORT; + /* ------------------------------------------------------------ BDA Stream Format GUIDs */ diff --git a/include/ndk/amd64/ketypes.h b/include/ndk/amd64/ketypes.h index b57242055d4..8e4d4215514 100644 --- a/include/ndk/amd64/ketypes.h +++ b/include/ndk/amd64/ketypes.h @@ -58,12 +58,14 @@ Author: // #define RPL_MASK 0x0003 #define MODE_MASK 0x0001 -#define KGDT_64_R0_CODE 0x0010 -#define KGDT_64_R0_SS 0x0018 -#define KGDT_64_DATA 0x0028 // 2b -#define KGDT_64_R3_CODE 0x0030 // 33 -#define KGDT_TSS 0x0040 -#define KGDT_32_R3_TEB 0x0050 // 53 +#define KGDT64_NULL 0x0000 +#define KGDT64_R0_CODE 0x0010 +#define KGDT64_R0_DATA 0x0018 +#define KGDT64_R3_CMCODE 0x0020 +#define KGDT64_R3_DATA 0x0028 +#define KGDT64_R3_CODE 0x0030 +#define KGDT64_SYS_TSS 0x0040 +#define KGDT64_R3_CMTEB 0x0050 // diff --git a/include/psdk/ks.h b/include/psdk/ks.h index f728bfb0f78..2290d7cf4e2 100644 --- a/include/psdk/ks.h +++ b/include/psdk/ks.h @@ -744,6 +744,99 @@ typedef enum KSPROPERTY_STREAM_PIPE_ID } KSPROPERTY_STREAM; +#define DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_ALLOCATOR,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(HANDLE),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_QUALITY(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_QUALITY,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSQUALITY_MANAGER),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_DEGRADATION(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_DEGRADATION,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + 0,\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_MASTERCLOCK,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(HANDLE),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_TIMEFORMAT(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_TIMEFORMAT,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(GUID),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONTIME(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_PRESENTATIONTIME,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(KSTIME),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONEXTENT(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_PRESENTATIONEXTENT,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_FRAMETIME(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_FRAMETIME,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSFRAMETIME),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_RATECAPABILITY(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_RATECAPABILITY,\ + (Handler),\ + sizeof(KSRATE_CAPABILITY),\ + sizeof(KSRATE),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_RATE(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_RATE,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(KSRATE),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(GetHandler, SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_STREAM_PIPE_ID,\ + (GetHandler),\ + sizeof(KSPROPERTY),\ + sizeof(HANDLE),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) /* =============================================================== StreamAllocator @@ -1926,6 +2019,76 @@ typedef struct } KSCLOCK_FUNCTIONTABLE, *PKSCLOCK_FUNCTIONTABLE; +#define DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_TIME,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_PHYSICALTIME,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(LONGLONG),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_CORRELATEDTIME,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSCORRELATED_TIME),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSCORRELATED_TIME),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_RESOLUTION,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSRESOLUTION),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_STATE,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSSTATE),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(Handler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_CLOCK_FUNCTIONTABLE,\ + (Handler),\ + sizeof(KSPROPERTY),\ + sizeof(KSCLOCK_FUNCTIONTABLE),\ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_CLOCKSET(ClockSet,\ + PropTime, PropPhysicalTime,\ + PropCorrelatedTime, PropCorrelatedPhysicalTime,\ + PropResolution, PropState, PropFunctionTable)\ +DEFINE_KSPROPERTY_TABLE(ClockSet) {\ + DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(PropTime),\ + DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(PropPhysicalTime),\ + DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(PropCorrelatedTime),\ + DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(PropCorrelatedPhysicalTime),\ + DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(PropResolution),\ + DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(PropState),\ + DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(PropFunctionTable)\ +} + /* =============================================================== Objects ??? SORT ME! */ diff --git a/include/psdk/ksmedia.h b/include/psdk/ksmedia.h index da909168afc..a1b1c0c314e 100644 --- a/include/psdk/ksmedia.h +++ b/include/psdk/ksmedia.h @@ -14,6 +14,8 @@ KS CATEGORIES */ +typedef LONGLONG REFERENCE_TIME; + #define EXTRACT_WAVEFORMATEX_ID(Guid)\ (USHORT)((Guid)->Data1) diff --git a/include/psdk/ntdef.h b/include/psdk/ntdef.h index fdc365085b2..18107cdcbcc 100644 --- a/include/psdk/ntdef.h +++ b/include/psdk/ntdef.h @@ -565,6 +565,9 @@ typedef struct _PROCESSOR_NUMBER { UCHAR Reserved; } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER; +struct _CONTEXT; +struct _EXCEPTION_RECORD; + typedef EXCEPTION_DISPOSITION (NTAPI *PEXCEPTION_ROUTINE)( IN struct _EXCEPTION_RECORD *ExceptionRecord, diff --git a/include/psdk/objbase.h b/include/psdk/objbase.h index 57da913bf51..e9295de6cf3 100644 --- a/include/psdk/objbase.h +++ b/include/psdk/objbase.h @@ -225,10 +225,9 @@ #define THIS void #define interface struct -#define DECLARE_INTERFACE(iface) interface iface -#define DECLARE_INTERFACE_(iface,ibase) interface iface : public ibase -#define DECLARE_INTERFACE_IID(iface, iid) interface DECLSPEC_UUID(iid) iface -#define DECLARE_INTERFACE_IID_(iface, baseiface, iid) interface DECLSPEC_UUID(iid) iface : public baseiface +#define DECLARE_INTERFACE(iface) interface DECLSPEC_NOVTABLE iface +#define DECLARE_INTERFACE_(iface,ibase) interface DECLSPEC_NOVTABLE iface : public ibase +#define DECLARE_INTERFACE_IID_(iface, ibase, iid) interface DECLSPEC_UUID(iid) DECLSPEC_NOVTABLE iface : public ibase #define BEGIN_INTERFACE #define END_INTERFACE @@ -268,6 +267,7 @@ struct iface##Vtbl #endif #define DECLARE_INTERFACE_(iface,ibase) DECLARE_INTERFACE(iface) +#define DECLARE_INTERFACE_IID_(iface, ibase, iid) DECLARE_INTERFACE_(iface, ibase) #define BEGIN_INTERFACE #define END_INTERFACE @@ -431,7 +431,7 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags,DWORD dwTimeout,ULONG cHan * GUID API */ HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR*); -HRESULT WINAPI CLSIDFromString(LPOLESTR, CLSID *); +HRESULT WINAPI CLSIDFromString(LPCOLESTR, LPCLSID); HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid); HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID); diff --git a/include/psdk/wingdi.h b/include/psdk/wingdi.h index edfbae652f3..cad35c7d659 100644 --- a/include/psdk/wingdi.h +++ b/include/psdk/wingdi.h @@ -3050,7 +3050,9 @@ UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE,UINT,LPPALETTEENTRY); UINT WINAPI GetEnhMetaFilePixelFormat(HENHMETAFILE,UINT,PIXELFORMATDESCRIPTOR*); DWORD WINAPI GetFontData(HDC,DWORD,DWORD,PVOID,DWORD); DWORD WINAPI GetFontLanguageInfo(HDC); +#if (_WIN32_WINNT >= 0x0500) DWORD WINAPI GetFontUnicodeRanges(HDC,LPGLYPHSET); +#endif DWORD WINAPI GetGlyphIndicesA(HDC,LPCSTR,INT,LPWORD,DWORD); DWORD WINAPI GetGlyphIndicesW(HDC,LPCWSTR,INT,LPWORD,DWORD); DWORD WINAPI GetGlyphOutlineA(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,PVOID,const MAT2*); diff --git a/include/psdk/winnt.h b/include/psdk/winnt.h index a2e0852de40..ef2037d5569 100644 --- a/include/psdk/winnt.h +++ b/include/psdk/winnt.h @@ -63,6 +63,14 @@ extern "C" { #define UNALIGNED #endif +#ifndef DECLSPEC_NOVTABLE +# if defined(_MSC_VER) && (_MSC_VER >= 1100) && defined(__cplusplus) +# define DECLSPEC_NOVTABLE __declspec(novtable) +# else +# define DECLSPEC_NOVTABLE +# endif +#endif + #ifndef DECLSPEC_ADDRSAFE #if (_MSC_VER >= 1200) && (defined(_M_ALPHA) || defined(_M_AXP64)) #define DECLSPEC_ADDRSAFE __declspec(address_safe) diff --git a/include/psdk/winuser.h b/include/psdk/winuser.h index 36807bbdaf5..fbae7314d97 100644 --- a/include/psdk/winuser.h +++ b/include/psdk/winuser.h @@ -4442,7 +4442,7 @@ int WINAPI SetScrollInfo(HWND,int,LPCSCROLLINFO,BOOL); int WINAPI SetScrollPos(HWND,int,int,BOOL); BOOL WINAPI SetScrollRange(HWND,int,int,int,BOOL); BOOL WINAPI SetSysColors(int,const INT *,const COLORREF *); -DWORD WINAPI SetSysColorsTemp(const COLORREF *, const HBRUSH *, DWORD); +DWORD_PTR WINAPI SetSysColorsTemp(const COLORREF *, const HBRUSH *, DWORD_PTR); #define SetSysModalWindow(h) (NULL) BOOL WINAPI SetSystemCursor(HCURSOR,DWORD); BOOL WINAPI SetSystemMenu(HWND,HMENU); diff --git a/include/reactos/arm/armddk.h b/include/reactos/arm/armddk.h index 68262c2b9d7..82e6d9fdd72 100644 --- a/include/reactos/arm/armddk.h +++ b/include/reactos/arm/armddk.h @@ -54,13 +54,16 @@ extern ULONG_PTR MmUserProbeAddress; // #define MAXIMUM_VECTOR 16 +#define KERNEL_STACK_SIZE 12288 +#define KERNEL_LARGE_STACK_SIZE 61440 +#define KERNEL_LARGE_STACK_COMMIT 12288 // // Used to contain PFNs and PFN counts // -typedef ULONG PFN_COUNT; -typedef ULONG PFN_NUMBER, *PPFN_NUMBER; -typedef LONG SPFN_NUMBER, *PSPFN_NUMBER; +//typedef ULONG PFN_COUNT; +//typedef ULONG PFN_NUMBER, *PPFN_NUMBER; +//typedef LONG SPFN_NUMBER, *PSPFN_NUMBER; // // Stub @@ -124,11 +127,25 @@ typedef struct _CONTEXT { #ifdef _WINNT_H #define KIRQL ULONG #endif + +typedef struct _NT_TIB_KPCR { + struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; + PVOID StackBase; + PVOID StackLimit; + PVOID SubSystemTib; + _ANONYMOUS_UNION union { + PVOID FiberData; + ULONG Version; + } DUMMYUNIONNAME; + PVOID ArbitraryUserPointer; + struct _NT_TIB_KPCR *Self; +} NT_TIB_KPCR,*PNT_TIB_KPCR; + typedef struct _KPCR { union { - NT_TIB NtTib; + NT_TIB_KPCR NtTib; struct { struct _EXCEPTION_REGISTRATION_RECORD *Used_ExceptionList; // Unused @@ -167,6 +184,11 @@ struct _TEB* NtCurrentTeb(VOID) return (struct _TEB*)USERPCR->Used_Self; } +NTSYSAPI +PKTHREAD +NTAPI +KeGetCurrentThread(VOID); + #ifndef _WINNT_H // // IRQL Support on ARM is similar to MIPS/ALPHA diff --git a/include/reactos/asm.h b/include/reactos/asm.h index 30afca482a0..f60a37c79ef 100644 --- a/include/reactos/asm.h +++ b/include/reactos/asm.h @@ -73,7 +73,7 @@ ENDM .altmacro /* Hex numbers need to be in 0x1AB format */ -#define HEX(x) 0x##x +#define HEX(y) 0x##y /* Macro values need to be marked */ #define VAL(x) \x diff --git a/include/reactos/win32k/ntgdityp.h b/include/reactos/win32k/ntgdityp.h index 2e710ca6bdf..1aedf765dbc 100644 --- a/include/reactos/win32k/ntgdityp.h +++ b/include/reactos/win32k/ntgdityp.h @@ -523,10 +523,7 @@ typedef struct _GDIBSEXTSELCLPRGN { GDIBATCHHDR gbHdr; int fnMode; - LONG right; - LONG bottom; - LONG left; - LONG top; + RECTL; } GDIBSEXTSELCLPRGN, *PGDIBSEXTSELCLPRGN; // // Use with GdiBCSelObj, GdiBCDelObj and GdiBCDelRgn. diff --git a/include/xdk/exfuncs.h b/include/xdk/exfuncs.h index a04b7aeed62..3f02d3df6e5 100644 --- a/include/xdk/exfuncs.h +++ b/include/xdk/exfuncs.h @@ -299,13 +299,14 @@ ExFreeToZone( #define ExIsResourceAcquired ExIsResourceAcquiredSharedLite #define ExReleaseResourceForThread ExReleaseResourceForThreadLite +#ifdef _X86_ + typedef enum _INTERLOCKED_RESULT { ResultNegative = RESULT_NEGATIVE, ResultZero = RESULT_ZERO, ResultPositive = RESULT_POSITIVE } INTERLOCKED_RESULT; -#ifdef _X86_ NTKERNELAPI INTERLOCKED_RESULT FASTCALL @@ -324,6 +325,7 @@ FASTCALL Exfi386InterlockedExchangeUlong( IN PULONG Target, IN ULONG Value); + #endif $endif (_NTDDK_) diff --git a/lib/cmlib/cmlib.h b/lib/cmlib/cmlib.h index fae049507d2..c6823b06a47 100644 --- a/lib/cmlib/cmlib.h +++ b/lib/cmlib/cmlib.h @@ -198,6 +198,22 @@ typedef struct _CMHIVE #endif +typedef struct _HV_HIVE_CELL_PAIR +{ + PHHIVE Hive; + HCELL_INDEX Cell; +} HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR; + +#define STATIC_CELL_PAIR_COUNT 4 +typedef struct _HV_TRACK_CELL_REF +{ + USHORT Count; + USHORT Max; + PHV_HIVE_CELL_PAIR CellArray; + HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT]; + USHORT StaticCount; +} HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF; + extern ULONG CmlibTraceLevel; /* @@ -272,6 +288,12 @@ HvIsCellDirty( IN HCELL_INDEX Cell ); +BOOLEAN +CMAPI +HvHiveWillShrink( + IN PHHIVE RegistryHive +); + BOOLEAN CMAPI HvSyncHive( PHHIVE RegistryHive); @@ -288,6 +310,21 @@ CmCreateRootNode( VOID CMAPI CmPrepareHive( PHHIVE RegistryHive); + + +BOOLEAN +CMAPI +HvTrackCellRef( + PHV_TRACK_CELL_REF CellRef, + PHHIVE Hive, + HCELL_INDEX Cell +); + +VOID +CMAPI +HvReleaseFreeCellRefArray( + PHV_TRACK_CELL_REF CellRef +); /* * Private functions. diff --git a/lib/cmlib/hivecell.c b/lib/cmlib/hivecell.c index 994ca98170d..815165182a5 100644 --- a/lib/cmlib/hivecell.c +++ b/lib/cmlib/hivecell.c @@ -113,7 +113,7 @@ HvMarkCellDirty( __FUNCTION__, RegistryHive, CellIndex, HoldingLock); if ((CellIndex & HCELL_TYPE_MASK) >> HCELL_TYPE_SHIFT != Stable) - return FALSE; + return TRUE; CellBlock = (CellIndex & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; CellLastBlock = ((CellIndex + HV_BLOCK_SIZE - 1) & HCELL_BLOCK_MASK) >> HCELL_BLOCK_SHIFT; @@ -525,3 +525,56 @@ HvFreeCell( if (CellType == Stable) HvMarkCellDirty(RegistryHive, CellIndex, FALSE); } + +BOOLEAN +CMAPI +HvTrackCellRef(PHV_TRACK_CELL_REF CellRef, + PHHIVE Hive, + HCELL_INDEX Cell) +{ + /* Sanity checks */ + ASSERT(CellRef); + ASSERT(Hive ); + ASSERT(Cell != HCELL_NIL); + + /* Less than 4? */ + if (CellRef->StaticCount < STATIC_CELL_PAIR_COUNT) + { + /* Add reference */ + CellRef->StaticArray[CellRef->StaticCount].Hive = Hive; + CellRef->StaticArray[CellRef->StaticCount].Cell = Cell; + CellRef->StaticCount++; + return TRUE; + } + + /* FIXME: TODO */ + DPRINT1("ERROR: Too many references\n"); + while (TRUE); + return FALSE; +} + +VOID +CMAPI +HvReleaseFreeCellRefArray(PHV_TRACK_CELL_REF CellRef) +{ + ULONG i; + ASSERT(CellRef); + + /* Any references? */ + if (CellRef->StaticCount > 0) + { + /* Sanity check */ + ASSERT(CellRef->StaticCount <= STATIC_CELL_PAIR_COUNT); + + /* Loop them */ + for (i = 0; i < CellRef->StaticCount;i++) + { + /* Release them */ + HvReleaseCell(CellRef->StaticArray[i].Hive, + CellRef->StaticArray[i].Cell); + } + + /* Free again */ + CellRef->StaticCount = 0; + } +} \ No newline at end of file diff --git a/lib/cmlib/hivewrt.c b/lib/cmlib/hivewrt.c index 5cc20cfe503..7ecadff2062 100644 --- a/lib/cmlib/hivewrt.c +++ b/lib/cmlib/hivewrt.c @@ -265,6 +265,14 @@ HvSyncHive( return TRUE; } +BOOLEAN +CMAPI +HvHiveWillShrink(IN PHHIVE RegistryHive) +{ + /* No shrinking yet */ + return FALSE; +} + BOOLEAN CMAPI HvWriteHive( PHHIVE RegistryHive) diff --git a/lib/drivers/sound/mmixer/wave.c b/lib/drivers/sound/mmixer/wave.c index a8b2675cac9..0ba0aae41b9 100644 --- a/lib/drivers/sound/mmixer/wave.c +++ b/lib/drivers/sound/mmixer/wave.c @@ -360,6 +360,17 @@ MMixerInitializeWaveInfo( WaveInfo->DeviceId = MixerData->DeviceId; WaveInfo->PinId = PinId; + + /* copy device name */ + if (bWaveIn) + { + wcscpy(WaveInfo->u.InCaps.szPname, DeviceName); + } + else + { + wcscpy(WaveInfo->u.OutCaps.szPname, DeviceName); + } + /* FIXME determine manufacturer / product id */ if (bWaveIn) { @@ -410,6 +421,8 @@ MMixerInitializeWaveInfo( MixerContext->Free(MultipleItem); + + if (bWaveIn) { InsertTailList(&MixerList->WaveInList, &WaveInfo->Entry); diff --git a/lib/rtl/sprintf.c b/lib/rtl/sprintf.c index 42aca6c3511..52f46f8a3d3 100644 --- a/lib/rtl/sprintf.c +++ b/lib/rtl/sprintf.c @@ -27,33 +27,40 @@ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */ -typedef union { - struct { - unsigned int mantissal:32; - unsigned int mantissah:20; - unsigned int exponent:11; - unsigned int sign:1; - }; - long long AsLongLong; +typedef struct { + unsigned int mantissal:32; + unsigned int mantissah:20; + unsigned int exponent:11; + unsigned int sign:1; } double_t; -/* We depend on this being true */ -C_ASSERT(sizeof(double_t) == sizeof(double)); - static __inline int -_isinf(double_t x) +_isinf(double __x) { - return ( x.exponent == 0x7ff && ( x.mantissah == 0 && x.mantissal == 0 )); + union + { + double* __x; + double_t* x; + } x; + + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 )); } static __inline int -_isnan(double_t x) +_isnan(double __x) { - return ( x.exponent == 0x7ff && ( x.mantissah != 0 || x.mantissal != 0 )); + union + { + double* __x; + double_t* x; + } x; + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 )); } @@ -173,13 +180,14 @@ number(char * buf, char * end, long long num, int base, int size, int precision, } static char * -numberf(char * buf, char * end, double_t num, int base, int size, int precision, int type) +numberf(char * buf, char * end, double num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits; const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz"; const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int i; + long long x; /* FIXME the float version of number is direcly copy of number @@ -193,9 +201,9 @@ numberf(char * buf, char * end, double_t num, int base, int size, int precision, c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { - if (num.sign) { + if (num < 0) { sign = '-'; - num.sign = 0; + num = -num; size--; } else if (type & PLUS) { sign = '+'; @@ -212,11 +220,15 @@ numberf(char * buf, char * end, double_t num, int base, int size, int precision, size--; } i = 0; - if (num.AsLongLong == 0) + if (num == 0) tmp[i++] = '0'; - else while (num.AsLongLong != 0) + else while (num != 0) { - tmp[i++] = digits[do_div(&num.AsLongLong,base)]; + x = num; + tmp[i++] = digits[do_div(&x,base)]; +#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4 + num=x; +#endif } if (i > precision) precision = i; @@ -377,7 +389,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) { int len; unsigned long long num; - double_t _double; + double _double; int base; char *str, *end; @@ -591,7 +603,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) case 'f': case 'g': case 'G': - _double = va_arg(args, double_t); + _double = (double)va_arg(args, double); if ( _isnan(_double) ) { s = "Nan"; len = 3; @@ -622,7 +634,7 @@ int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args) } else { if ( precision == -1 ) precision = 6; - str = numberf(str, end, _double, base, field_width, precision, flags); + str = numberf(str, end, (int)_double, base, field_width, precision, flags); } continue; diff --git a/lib/rtl/swprintf.c b/lib/rtl/swprintf.c index 3d6488b92b6..64d7d65397a 100644 --- a/lib/rtl/swprintf.c +++ b/lib/rtl/swprintf.c @@ -27,33 +27,40 @@ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ #define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */ -typedef union { - struct { - unsigned int mantissal:32; - unsigned int mantissah:20; - unsigned int exponent:11; - unsigned int sign:1; - }; - long long AsLongLong; +typedef struct { + unsigned int mantissal:32; + unsigned int mantissah:20; + unsigned int exponent:11; + unsigned int sign:1; } double_t; -/* We depend on this being true */ -C_ASSERT(sizeof(double_t) == sizeof(double)); - static __inline int -_isinf(double_t x) +_isinf(double __x) { - return ( x.exponent == 0x7ff && ( x.mantissah == 0 && x.mantissal == 0 )); + union + { + double* __x; + double_t* x; + } x; + + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 )); } static __inline int -_isnan(double_t x) +_isnan(double __x) { - return ( x.exponent == 0x7ff && ( x.mantissah != 0 || x.mantissal != 0 )); + union + { + double* __x; + double_t* x; + } x; + x.__x = &__x; + return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 )); } @@ -172,13 +179,14 @@ number(wchar_t * buf, wchar_t * end, long long num, int base, int size, int prec } static wchar_t * -numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int precision, int type) +numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precision, int type) { wchar_t c, sign, tmp[66]; const wchar_t *digits; const wchar_t *small_digits = L"0123456789abcdefghijklmnopqrstuvwxyz"; const wchar_t *large_digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int i; + long long x; /* FIXME the float version of number is direcly copy of number @@ -193,9 +201,9 @@ numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int prec c = (type & ZEROPAD) ? L'0' : L' '; sign = 0; if (type & SIGN) { - if (num.sign) { + if (num < 0) { sign = L'-'; - num.sign = 0; + num = -num; size--; } else if (type & PLUS) { sign = L'+'; @@ -212,11 +220,15 @@ numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int prec size--; } i = 0; - if (num.AsLongLong == 0) + if (num == 0) tmp[i++] = L'0'; - else while (num.AsLongLong != 0) + else while (num != 0) { - tmp[i++] = digits[do_div(&num.AsLongLong,base)]; + x = num; + tmp[i++] = digits[do_div(&x,base)]; +#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4 + num = x; +#endif } if (i > precision) precision = i; @@ -382,7 +394,7 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar const char *s; const wchar_t *sw; const wchar_t *ss; - double_t _double; + double _double; int flags; /* flags to number() */ @@ -588,7 +600,7 @@ int __cdecl _vsnwprintf(wchar_t *buf, size_t cnt, const wchar_t *fmt, va_list ar case 'f': case 'g': case 'G': - _double = va_arg(args, double_t); + _double = (double)va_arg(args, double); if ( _isnan(_double) ) { ss = L"Nan"; diff --git a/media/inf/cpu.inf b/media/inf/cpu.inf index bc2517dcaa0..087ab209a62 100644 Binary files a/media/inf/cpu.inf and b/media/inf/cpu.inf differ diff --git a/media/inf/fdc.inf b/media/inf/fdc.inf index 0da85d2785a..445f38e096b 100644 Binary files a/media/inf/fdc.inf and b/media/inf/fdc.inf differ diff --git a/media/inf/hdc.inf b/media/inf/hdc.inf index 0ad794cce9e..78983c57d44 100644 Binary files a/media/inf/hdc.inf and b/media/inf/hdc.inf differ diff --git a/media/inf/machine.inf b/media/inf/machine.inf index ecc90375e8d..0ac8b68bef8 100644 Binary files a/media/inf/machine.inf and b/media/inf/machine.inf differ diff --git a/ntoskrnl/config/cmapi.c b/ntoskrnl/config/cmapi.c index 85f2ed9fe14..538c3e5b560 100644 --- a/ntoskrnl/config/cmapi.c +++ b/ntoskrnl/config/cmapi.c @@ -14,6 +14,67 @@ /* FUNCTIONS *****************************************************************/ +BOOLEAN +NTAPI +CmpIsHiveAlreadyLoaded(IN HANDLE KeyHandle, + IN POBJECT_ATTRIBUTES SourceFile, + OUT PCMHIVE *CmHive) +{ + NTSTATUS Status; + PCM_KEY_BODY KeyBody; + PCMHIVE Hive; + BOOLEAN Loaded = FALSE; + PAGED_CODE(); + + /* Sanity check */ + CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK(); + + /* Reference the handle */ + Status = ObReferenceObjectByHandle(KeyHandle, + 0, + CmpKeyObjectType, + KernelMode, + (PVOID)&KeyBody, + NULL); + if (!NT_SUCCESS(Status)) return Loaded; + + /* Don't touch deleted KCBs */ + if (KeyBody->KeyControlBlock->Delete) return Loaded; + + Hive = CONTAINING_RECORD(KeyBody->KeyControlBlock->KeyHive, CMHIVE, Hive); + + /* Must be the root key */ + if (!(KeyBody->KeyControlBlock->Flags & KEY_HIVE_ENTRY) || + !(Hive->FileUserName.Buffer)) + { + /* It isn't */ + ObDereferenceObject(KeyBody); + return Loaded; + } + + /* Now compare the name of the file */ + if (!RtlCompareUnicodeString(&Hive->FileUserName, + SourceFile->ObjectName, + TRUE)) + { + /* Same file found */ + Loaded = TRUE; + *CmHive = Hive; + + /* If the hive is frozen, not sure what to do */ + if (Hive->Frozen) + { + /* FIXME: TODO */ + DPRINT1("ERROR: Hive is frozen\n"); + while (TRUE); + } + } + + /* Dereference and return result */ + ObDereferenceObject(KeyBody); + return Loaded; + } + BOOLEAN NTAPI CmpDoFlushAll(IN BOOLEAN ForceFlush) @@ -39,16 +100,35 @@ CmpDoFlushAll(IN BOOLEAN ForceFlush) if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH)) { /* Acquire the flusher lock */ - ExAcquirePushLockExclusive((PVOID)&Hive->FlusherLock); + CmpLockHiveFlusherExclusive(Hive); + + /* Check for illegal state */ + if ((ForceFlush) && (Hive->UseCount)) + { + /* Registry needs to be locked down */ + CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK(); + DPRINT1("FIXME: Hive is damaged and needs fixup\n"); + while (TRUE); + } + + /* Only sync if we are forced to or if it won't cause a hive shrink */ + if ((ForceFlush) || (!HvHiveWillShrink(&Hive->Hive))) + { + /* Do the sync */ + Status = HvSyncHive(&Hive->Hive); - /* Do the sync */ - Status = HvSyncHive(&Hive->Hive); - - /* If something failed - set the flag and continue looping*/ - if (!NT_SUCCESS(Status)) Result = FALSE; + /* If something failed - set the flag and continue looping */ + if (!NT_SUCCESS(Status)) Result = FALSE; + } + else + { + /* We won't flush if the hive might shrink */ + Result = FALSE; + CmpForceForceFlush = TRUE; + } /* Release the flusher lock */ - ExReleasePushLock((PVOID)&Hive->FlusherLock); + CmpUnlockHiveFlusher(Hive); } /* Try the next entry */ @@ -81,10 +161,14 @@ CmpSetValueKeyNew(IN PHHIVE Hive, { /* Then make sure it's valid and dirty it */ ASSERT(Parent->ValueList.List != HCELL_NIL); - HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE); + if (!HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) + { + /* Fail if we're out of space for log changes */ + return STATUS_NO_LOG_SPACE; + } } - /* Allocate avalue cell */ + /* Allocate a value cell */ ValueCell = HvAllocateCell(Hive, FIELD_OFFSET(CM_KEY_VALUE, Name) + CmpNameSize(Hive, ValueName), @@ -102,16 +186,33 @@ CmpSetValueKeyNew(IN PHHIVE Hive, /* Set it up and copy the name */ CellData->u.KeyValue.Signature = CM_KEY_VALUE_SIGNATURE; - CellData->u.KeyValue.Flags = 0; - CellData->u.KeyValue.Type = Type; - CellData->u.KeyValue.NameLength = CmpCopyName(Hive, - CellData->u.KeyValue.Name, - ValueName); + _SEH2_TRY + { + /* This can crash since the name is coming from user-mode */ + CellData->u.KeyValue.NameLength = CmpCopyName(Hive, + CellData->u.KeyValue.Name, + ValueName); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail */ + DPRINT1("Invalid user data!\n"); + HvFreeCell(Hive, ValueCell); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* Check for compressed name */ if (CellData->u.KeyValue.NameLength < ValueName->Length) { /* This is a compressed name */ CellData->u.KeyValue.Flags = VALUE_COMP_NAME; } + else + { + /* No flags to set */ + CellData->u.KeyValue.Flags = 0; + } /* Check if this is a normal key */ if (DataSize > CM_KEY_VALUE_SMALL) @@ -140,6 +241,9 @@ CmpSetValueKeyNew(IN PHHIVE Hive, CellData->u.KeyValue.DataLength = DataSize + CM_KEY_VALUE_SPECIAL_SIZE; CellData->u.KeyValue.Data = SmallData; } + + /* Set the type now */ + CellData->u.KeyValue.Type = Type; /* Add this value cell to the child list */ Status = CmpAddValueToList(Hive, @@ -149,7 +253,12 @@ CmpSetValueKeyNew(IN PHHIVE Hive, &Parent->ValueList); /* If we failed, free the entire cell, including the data */ - if (!NT_SUCCESS(Status)) CmpFreeValue(Hive, ValueCell); + if (!NT_SUCCESS(Status)) + { + /* Overwrite the status with a known one */ + CmpFreeValue(Hive, ValueCell); + Status = STATUS_INSUFFICIENT_RESOURCES; + } /* Return Status */ return Status; @@ -170,9 +279,12 @@ CmpSetValueKeyExisting(IN PHHIVE Hive, PCELL_DATA CellData; ULONG Length; BOOLEAN WasSmall, IsSmall; + + /* Registry writes must be blocked */ + CMP_ASSERT_FLUSH_LOCK(Hive); /* Mark the old child cell dirty */ - HvMarkCellDirty(Hive, OldChild, FALSE); + if (!HvMarkCellDirty(Hive, OldChild, FALSE)) return STATUS_NO_LOG_SPACE; /* See if this is a small or normal key */ WasSmall = CmpIsKeyValueSmall(&Length, Value->DataLength); @@ -185,7 +297,7 @@ CmpSetValueKeyExisting(IN PHHIVE Hive, ASSERT_VALUE_BIG(Hive, DataSize); /* Mark the old value dirty */ - CmpMarkValueDataDirty(Hive, Value); + if (!CmpMarkValueDataDirty(Hive, Value)) return STATUS_NO_LOG_SPACE; /* Check if we have a small key */ if (IsSmall) @@ -203,662 +315,58 @@ CmpSetValueKeyExisting(IN PHHIVE Hive, Value->Type = Type; return STATUS_SUCCESS; } - else + + /* We have a normal key. Was the old cell also normal and had data? */ + if (!(WasSmall) && (Length > 0)) { - /* We have a normal key. Was the old cell also normal and had data? */ - if (!(WasSmall) && (Length > 0)) + /* Get the current data cell and actual data inside it */ + DataCell = Value->Data; + ASSERT(DataCell != HCELL_NIL); + CellData = HvGetCell(Hive, DataCell); + if (!CellData) return STATUS_INSUFFICIENT_RESOURCES; + + /* Immediately release the cell */ + HvReleaseCell(Hive, DataCell); + + /* Make sure that the data cell actually has a size */ + ASSERT(HvGetCellSize(Hive, CellData) > 0); + + /* Check if the previous data cell could fit our new data */ + if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData))) { - /* Get the current data cell and actual data inside it */ - DataCell = Value->Data; - ASSERT(DataCell != HCELL_NIL); - CellData = HvGetCell(Hive, DataCell); - if (!CellData) return STATUS_INSUFFICIENT_RESOURCES; - - /* Immediately release the cell */ - HvReleaseCell(Hive, DataCell); - - /* Make sure that the data cell actually has a size */ - ASSERT(HvGetCellSize(Hive, CellData) > 0); - - /* Check if the previous data cell could fit our new data */ - if (DataSize <= (ULONG)(HvGetCellSize(Hive, CellData))) - { - /* Re-use it then */ - NewCell = DataCell; - } - else - { - /* Otherwise, re-allocate the current data cell */ - NewCell = HvReallocateCell(Hive, DataCell, DataSize); - if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; - } + /* Re-use it then */ + NewCell = DataCell; } else { - /* This was a small key, or a key with no data, allocate a cell */ - NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL); + /* Otherwise, re-allocate the current data cell */ + NewCell = HvReallocateCell(Hive, DataCell, DataSize); if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; } - - /* Now get the actual data for our data cell */ - CellData = HvGetCell(Hive, NewCell); - if (!CellData) ASSERT(FALSE); - - /* Release it immediately */ - HvReleaseCell(Hive, NewCell); - - /* Copy our data into the data cell's buffer, and set up the value */ - RtlCopyMemory(CellData, Data, DataSize); - Value->Data = NewCell; - Value->DataLength = DataSize; - Value->Type = Type; - - /* Return success */ - ASSERT(HvIsCellDirty(Hive, NewCell)); - return STATUS_SUCCESS; - } -} - -NTSTATUS -NTAPI -CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, - IN PUNICODE_STRING ValueName, - IN ULONG Type, - IN PVOID Data, - IN ULONG DataLength) -{ - PHHIVE Hive; - PCM_KEY_NODE Parent; - PCM_KEY_VALUE Value = NULL; - HCELL_INDEX CurrentChild, Cell; - NTSTATUS Status; - BOOLEAN Found, Result; - ULONG Count, ChildIndex, SmallData, Storage; - VALUE_SEARCH_RETURN_TYPE SearchResult; - - /* Acquire hive lock */ - CmpLockRegistry(); - CmpAcquireKcbLockShared(Kcb); - - /* Sanity check */ - ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL); - - /* Don't touch deleted KCBs */ -DoAgain: - if (Kcb->Delete) - { - /* Fail */ - Status = STATUS_KEY_DELETED; - goto Quickie; - } - - /* Don't let anyone mess with symlinks */ - if ((Kcb->Flags & KEY_SYM_LINK) && - ((Type != REG_LINK) || - !(ValueName) || - !(RtlEqualUnicodeString(&CmSymbolicLinkValueName, ValueName, TRUE)))) - { - /* Invalid modification of a symlink key */ - Status = STATUS_ACCESS_DENIED; - goto Quickie; - } - - /* Search for the value */ - SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb, - ValueName, - Type, - Data, - DataLength); - if (SearchResult == SearchNeedExclusiveLock) - { - /* Try again with the exclusive lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } - else if (SearchResult == SearchSuccess) - { - /* We don't actually need to do anything! */ - Status = STATUS_SUCCESS; - goto Quickie; - } - - /* We need the exclusive KCB lock now */ - if (!(CmpIsKcbLockedExclusive(Kcb)) && !(CmpTryToConvertKcbSharedToExclusive(Kcb))) - { - /* Acquire exclusive lock */ - CmpConvertKcbSharedToExclusive(Kcb); - } - - /* Get pointer to key cell */ - Hive = Kcb->KeyHive; - Cell = Kcb->KeyCell; - - /* Prepare to scan the key node */ - Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); - Count = Parent->ValueList.Count; - Found = FALSE; - if (Count > 0) - { - /* Try to find the existing name */ - Result = CmpFindNameInList(Hive, - &Parent->ValueList, - ValueName, - &ChildIndex, - &CurrentChild); - if (!Result) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Check if we found something */ - if (CurrentChild != HCELL_NIL) - { - /* Get its value */ - Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild); - if (!Value) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Remember that we found it */ - Found = TRUE; - } } else { - /* No child list, we'll need to add it */ - ChildIndex = 0; - } - - /* The KCB must be locked exclusive at this point */ - ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) || - (CmpTestRegistryLockExclusive() == TRUE)); - - /* Mark the cell dirty */ - HvMarkCellDirty(Hive, Cell, FALSE); - - /* Get the storage type */ - Storage = HvGetCellType(Cell); - - /* Check if this is small data */ - SmallData = 0; - if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0)) - { - /* Copy it */ - RtlCopyMemory(&SmallData, Data, DataLength); + /* This was a small key, or a key with no data, allocate a cell */ + NewCell = HvAllocateCell(Hive, DataSize, StorageType, HCELL_NIL); + if (NewCell == HCELL_NIL) return STATUS_INSUFFICIENT_RESOURCES; } - /* Check if we didn't find a matching key */ - if (!Found) - { - /* Call the internal routine */ - Status = CmpSetValueKeyNew(Hive, - Parent, - ValueName, - ChildIndex, - Type, - Data, - DataLength, - Storage, - SmallData); - } - else - { - /* Call the internal routine */ - Status = CmpSetValueKeyExisting(Hive, - CurrentChild, - Value, - Type, - Data, - DataLength, - Storage, - SmallData); - } + /* Now get the actual data for our data cell */ + CellData = HvGetCell(Hive, NewCell); + if (!CellData) ASSERT(FALSE); - /* Check for success */ - if (NT_SUCCESS(Status)) - { - /* Check if the maximum value name length changed */ - ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen); - if (Parent->MaxValueNameLen < ValueName->Length) - { - /* Set the new values */ - Parent->MaxValueNameLen = ValueName->Length; - Kcb->KcbMaxValueNameLen = ValueName->Length; - } - - /* Check if the maximum data length changed */ - ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen); - if (Parent->MaxValueDataLen < DataLength) - { - /* Update it */ - Parent->MaxValueDataLen = DataLength; - Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen; - } - - /* Save the write time */ - KeQuerySystemTime(&Parent->LastWriteTime); - KeQuerySystemTime(&Kcb->KcbLastWriteTime); - - /* Check if the cell is cached */ - if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))) - { - /* Shouldn't happen */ - ASSERT(FALSE); - } - else - { - /* Cleanup the value cache */ - CmpCleanUpKcbValueCache(Kcb); + /* Release it immediately */ + HvReleaseCell(Hive, NewCell); - /* Sanity checks */ - ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))); - ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)); - - /* Set the value cache */ - Kcb->ValueCache.Count = Parent->ValueList.Count; - Kcb->ValueCache.ValueList = Parent->ValueList.List; - } - } - -Quickie: - /* Release the locks */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return Status; -} + /* Copy our data into the data cell's buffer, and set up the value */ + RtlCopyMemory(CellData, Data, DataSize); + Value->Data = NewCell; + Value->DataLength = DataSize; + Value->Type = Type; -NTSTATUS -NTAPI -CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, - IN UNICODE_STRING ValueName) -{ - NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND; - PHHIVE Hive; - PCM_KEY_NODE Parent; - HCELL_INDEX ChildCell, Cell; - PCHILD_LIST ChildList; - PCM_KEY_VALUE Value = NULL; - ULONG ChildIndex; - BOOLEAN Result; - - /* Acquire hive lock */ - CmpLockRegistry(); - - /* Lock KCB exclusively */ - CmpAcquireKcbLockExclusive(Kcb); - - /* Don't touch deleted keys */ - if (Kcb->Delete) - { - /* Undo everything */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return STATUS_KEY_DELETED; - } - - /* Get the hive and the cell index */ - Hive = Kcb->KeyHive; - Cell = Kcb->KeyCell; - - /* Get the parent key node */ - Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Get the value list and check if it has any entries */ - ChildList = &Parent->ValueList; - if (ChildList->Count) - { - /* Try to find this value */ - Result = CmpFindNameInList(Hive, - ChildList, - &ValueName, - &ChildIndex, - &ChildCell); - if (!Result) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Value not found, return error */ - if (ChildCell == HCELL_NIL) goto Quickie; - - /* We found the value, mark all relevant cells dirty */ - HvMarkCellDirty(Hive, Cell, FALSE); - HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE); - HvMarkCellDirty(Hive, ChildCell, FALSE); - - /* Get the key value */ - Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell); - if (!Value) ASSERT(FALSE); - - /* Mark it and all related data as dirty */ - CmpMarkValueDataDirty(Hive, Value); - - /* Ssanity checks */ - ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List)); - ASSERT(HvIsCellDirty(Hive, ChildCell)); - - /* Remove the value from the child list */ - Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList); - if(!NT_SUCCESS(Status)) goto Quickie; - - /* Remove the value and its data itself */ - if (!CmpFreeValue(Hive, ChildCell)) - { - /* Failed to free the value, fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Set the last write time */ - KeQuerySystemTime(&Parent->LastWriteTime); - KeQuerySystemTime(&Kcb->KcbLastWriteTime); - - /* Sanity check */ - ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen); - ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen); - ASSERT(HvIsCellDirty(Hive, Cell)); - - /* Check if the value list is empty now */ - if (!Parent->ValueList.Count) - { - /* Then clear key node data */ - Parent->MaxValueNameLen = 0; - Parent->MaxValueDataLen = 0; - Kcb->KcbMaxValueNameLen = 0; - Kcb->KcbMaxValueDataLen = 0; - } - - /* Cleanup the value cache */ - CmpCleanUpKcbValueCache(Kcb); - - /* Sanity checks */ - ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))); - ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)); - - /* Set the value cache */ - Kcb->ValueCache.Count = ChildList->Count; - Kcb->ValueCache.ValueList = ChildList->List; - - /* Change default Status to success */ - Status = STATUS_SUCCESS; - } - -Quickie: - /* Release the parent cell, if any */ - if (Parent) HvReleaseCell(Hive, Cell); - - /* Check if we had a value */ - if (Value) - { - /* Release the child cell */ - ASSERT(ChildCell != HCELL_NIL); - HvReleaseCell(Hive, ChildCell); - } - - /* Release locks */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return Status; -} - -NTSTATUS -NTAPI -CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, - IN UNICODE_STRING ValueName, - IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, - IN PVOID KeyValueInformation, - IN ULONG Length, - IN PULONG ResultLength) -{ - NTSTATUS Status; - PCM_KEY_VALUE ValueData; - ULONG Index; - BOOLEAN ValueCached = FALSE; - PCM_CACHED_VALUE *CachedValue; - HCELL_INDEX CellToRelease; - VALUE_SEARCH_RETURN_TYPE Result; - PHHIVE Hive; - PAGED_CODE(); - - /* Acquire hive lock */ - CmpLockRegistry(); - - /* Lock the KCB shared */ - CmpAcquireKcbLockShared(Kcb); - - /* Don't touch deleted keys */ -DoAgain: - if (Kcb->Delete) - { - /* Undo everything */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return STATUS_KEY_DELETED; - } - - /* We don't deal with this yet */ - if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) - { - /* Shouldn't happen */ - ASSERT(FALSE); - } - - /* Get the hive */ - Hive = Kcb->KeyHive; - - /* Find the key value */ - Result = CmpFindValueByNameFromCache(Kcb, - &ValueName, - &CachedValue, - &Index, - &ValueData, - &ValueCached, - &CellToRelease); - if (Result == SearchNeedExclusiveLock) - { - /* Check if we need an exclusive lock */ - ASSERT(CellToRelease == HCELL_NIL); - ASSERT(ValueData == NULL); - - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } - - if (Result == SearchSuccess) - { - /* Sanity check */ - ASSERT(ValueData != NULL); - - /* Query the information requested */ - Result = CmpQueryKeyValueData(Kcb, - CachedValue, - ValueData, - ValueCached, - KeyValueInformationClass, - KeyValueInformation, - Length, - ResultLength, - &Status); - if (Result == SearchNeedExclusiveLock) - { - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } - } - else - { - /* Failed to find the value */ - Status = STATUS_OBJECT_NAME_NOT_FOUND; - } - - /* If we have a cell to release, do so */ - if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease); - - /* Release locks */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return Status; -} - -NTSTATUS -NTAPI -CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, - IN ULONG Index, - IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, - IN PVOID KeyValueInformation, - IN ULONG Length, - IN PULONG ResultLength) -{ - NTSTATUS Status; - PHHIVE Hive; - PCM_KEY_NODE Parent; - HCELL_INDEX CellToRelease = HCELL_NIL, CellToRelease2 = HCELL_NIL; - VALUE_SEARCH_RETURN_TYPE Result; - BOOLEAN IndexIsCached, ValueIsCached = FALSE; - PCELL_DATA CellData; - PCM_CACHED_VALUE *CachedValue; - PCM_KEY_VALUE ValueData = NULL; - PAGED_CODE(); - - /* Acquire hive lock */ - CmpLockRegistry(); - - /* Lock the KCB shared */ - CmpAcquireKcbLockShared(Kcb); - - /* Don't touch deleted keys */ -DoAgain: - if (Kcb->Delete) - { - /* Undo everything */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return STATUS_KEY_DELETED; - } - - /* Get the hive and parent */ - Hive = Kcb->KeyHive; - Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Make sure the index is valid */ - //if (Index >= Kcb->ValueCache.Count) - if (Index >= Parent->ValueList.Count) - { - /* Release the cell and fail */ - HvReleaseCell(Hive, Kcb->KeyCell); - Status = STATUS_NO_MORE_ENTRIES; - goto Quickie; - } - - /* We don't deal with this yet */ - if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) - { - /* Shouldn't happen */ - ASSERT(FALSE); - } - - /* Find the value list */ - Result = CmpGetValueListFromCache(Kcb, - &CellData, - &IndexIsCached, - &CellToRelease); - if (Result == SearchNeedExclusiveLock) - { - /* Check if we need an exclusive lock */ - ASSERT(CellToRelease == HCELL_NIL); - ASSERT(ValueData == NULL); - - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } - else if (Result != SearchSuccess) - { - /* Sanity check */ - ASSERT(CellData == NULL); - - /* Release the cell and fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Now get the key value */ - Result = CmpGetValueKeyFromCache(Kcb, - CellData, - Index, - &CachedValue, - &ValueData, - IndexIsCached, - &ValueIsCached, - &CellToRelease2); - if (Result == SearchNeedExclusiveLock) - { - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } - else if (Result != SearchSuccess) - { - /* Sanity check */ - ASSERT(ValueData == NULL); - - /* Release the cells and fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - - /* Query the information requested */ - Result = CmpQueryKeyValueData(Kcb, - CachedValue, - ValueData, - ValueIsCached, - KeyValueInformationClass, - KeyValueInformation, - Length, - ResultLength, - &Status); - if (Result == SearchNeedExclusiveLock) - { - /* Try with exclusive KCB lock */ - CmpConvertKcbSharedToExclusive(Kcb); - goto DoAgain; - } - -Quickie: - /* If we have a cell to release, do so */ - if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease); - - /* Release the parent cell */ - HvReleaseCell(Hive, Kcb->KeyCell); - - /* If we have a cell to release, do so */ - if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2); - - /* Release locks */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return Status; + /* Return success */ + ASSERT(HvIsCellDirty(Hive, NewCell)); + return STATUS_SUCCESS; } NTSTATUS @@ -1076,6 +584,725 @@ CmpQueryKeyData(IN PHHIVE Hive, return Status; } +NTSTATUS +NTAPI +CmSetValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, + IN PUNICODE_STRING ValueName, + IN ULONG Type, + IN PVOID Data, + IN ULONG DataLength) +{ + PHHIVE Hive = NULL; + PCM_KEY_NODE Parent; + PCM_KEY_VALUE Value = NULL; + HCELL_INDEX CurrentChild, Cell; + NTSTATUS Status; + BOOLEAN Found, Result; + ULONG Count, ChildIndex, SmallData, Storage; + VALUE_SEARCH_RETURN_TYPE SearchResult; + BOOLEAN FirstTry = TRUE, FlusherLocked = FALSE; + HCELL_INDEX ParentCell = HCELL_NIL, ChildCell = HCELL_NIL; + + /* Acquire hive and KCB lock */ + CmpLockRegistry(); + CmpAcquireKcbLockShared(Kcb); + + /* Sanity check */ + ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL); + + /* Don't touch deleted KCBs */ +DoAgain: + if (Kcb->Delete) + { + /* Fail */ + Status = STATUS_KEY_DELETED; + goto Quickie; + } + + /* Don't let anyone mess with symlinks */ + if ((Kcb->Flags & KEY_SYM_LINK) && + ((Type != REG_LINK) || + !(ValueName) || + !(RtlEqualUnicodeString(&CmSymbolicLinkValueName, ValueName, TRUE)))) + { + /* Invalid modification of a symlink key */ + Status = STATUS_ACCESS_DENIED; + goto Quickie; + } + + /* Check if this is the first attempt */ + if (FirstTry) + { + /* Search for the value in the cache */ + SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb, + ValueName, + Type, + Data, + DataLength); + if (SearchResult == SearchNeedExclusiveLock) + { + /* Try again with the exclusive lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + else if (SearchResult == SearchSuccess) + { + /* We don't actually need to do anything! */ + Status = STATUS_SUCCESS; + goto Quickie; + } + + /* We need the exclusive KCB lock now */ + if (!(CmpIsKcbLockedExclusive(Kcb)) && + !(CmpTryToConvertKcbSharedToExclusive(Kcb))) + { + /* Acquire exclusive lock */ + CmpConvertKcbSharedToExclusive(Kcb); + } + + /* Cache lookup failed, so don't try it next time */ + FirstTry = FALSE; + + /* Now grab the flush lock since the key will be modified */ + ASSERT(FlusherLocked == FALSE); + CmpLockHiveFlusherShared((PCMHIVE)Kcb->KeyHive); + FlusherLocked = TRUE; + goto DoAgain; + } + else + { + /* Get pointer to key cell */ + Hive = Kcb->KeyHive; + Cell = Kcb->KeyCell; + + /* Get the parent */ + Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); + ASSERT(Parent); + ParentCell = Cell; + + /* Prepare to scan the key node */ + Count = Parent->ValueList.Count; + Found = FALSE; + if (Count > 0) + { + /* Try to find the existing name */ + Result = CmpFindNameInList(Hive, + &Parent->ValueList, + ValueName, + &ChildIndex, + &CurrentChild); + if (!Result) + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Check if we found something */ + if (CurrentChild != HCELL_NIL) + { + /* Release existing child */ + if (ChildCell != HCELL_NIL) + { + HvReleaseCell(Hive, ChildCell); + ChildCell = HCELL_NIL; + } + + /* Get its value */ + Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild); + if (!Value) + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Remember that we found it */ + ChildCell = CurrentChild; + Found = TRUE; + } + } + else + { + /* No child list, we'll need to add it */ + ChildIndex = 0; + } + } + + /* Should only get here on the second pass */ + ASSERT(FirstTry == FALSE); + + /* The KCB must be locked exclusive at this point */ + CMP_ASSERT_KCB_LOCK(Kcb); + + /* Mark the cell dirty */ + if (!HvMarkCellDirty(Hive, Cell, FALSE)) + { + /* Not enough log space, fail */ + Status = STATUS_NO_LOG_SPACE; + goto Quickie; + } + + /* Get the storage type */ + Storage = HvGetCellType(Cell); + + /* Check if this is small data */ + SmallData = 0; + if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0)) + { + /* Need SEH because user data may be invalid */ + _SEH2_TRY + { + /* Copy it */ + RtlCopyMemory(&SmallData, Data, DataLength); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return failure code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(goto Quickie); + } + _SEH2_END; + } + + /* Check if we didn't find a matching key */ + if (!Found) + { + /* Call the internal routine */ + Status = CmpSetValueKeyNew(Hive, + Parent, + ValueName, + ChildIndex, + Type, + Data, + DataLength, + Storage, + SmallData); + } + else + { + /* Call the internal routine */ + Status = CmpSetValueKeyExisting(Hive, + CurrentChild, + Value, + Type, + Data, + DataLength, + Storage, + SmallData); + } + + /* Check for success */ + if (NT_SUCCESS(Status)) + { + /* Check if the maximum value name length changed */ + ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen); + if (Parent->MaxValueNameLen < ValueName->Length) + { + /* Set the new values */ + Parent->MaxValueNameLen = ValueName->Length; + Kcb->KcbMaxValueNameLen = ValueName->Length; + } + + /* Check if the maximum data length changed */ + ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen); + if (Parent->MaxValueDataLen < DataLength) + { + /* Update it */ + Parent->MaxValueDataLen = DataLength; + Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen; + } + + /* Save the write time */ + KeQuerySystemTime(&Parent->LastWriteTime); + Kcb->KcbLastWriteTime = Parent->LastWriteTime; + + /* Check if the cell is cached */ + if ((Found) && (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))) + { + /* Shouldn't happen */ + ASSERT(FALSE); + } + else + { + /* Cleanup the value cache */ + CmpCleanUpKcbValueCache(Kcb); + + /* Sanity checks */ + ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))); + ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)); + + /* Set the value cache */ + Kcb->ValueCache.Count = Parent->ValueList.Count; + Kcb->ValueCache.ValueList = Parent->ValueList.List; + } + + /* Notify registered callbacks */ + CmpReportNotify(Kcb, + Hive, + Kcb->KeyCell, + REG_NOTIFY_CHANGE_LAST_SET); + } + + /* Release the cells */ +Quickie: + if ((ParentCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ParentCell); + if ((ChildCell != HCELL_NIL) && (Hive)) HvReleaseCell(Hive, ChildCell); + + /* Release the locks */ + if (FlusherLocked) CmpUnlockHiveFlusher((PCMHIVE)Hive); + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return Status; +} + +NTSTATUS +NTAPI +CmDeleteValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, + IN UNICODE_STRING ValueName) +{ + NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND; + PHHIVE Hive; + PCM_KEY_NODE Parent; + HCELL_INDEX ChildCell, Cell; + PCHILD_LIST ChildList; + PCM_KEY_VALUE Value = NULL; + ULONG ChildIndex; + BOOLEAN Result; + + /* Acquire hive lock */ + CmpLockRegistry(); + + /* Lock KCB exclusively */ + CmpAcquireKcbLockExclusive(Kcb); + + /* Don't touch deleted keys */ + if (Kcb->Delete) + { + /* Undo everything */ + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return STATUS_KEY_DELETED; + } + + /* Get the hive and the cell index */ + Hive = Kcb->KeyHive; + Cell = Kcb->KeyCell; + + /* Lock flushes */ + CmpLockHiveFlusherShared((PCMHIVE)Hive); + + /* Get the parent key node */ + Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell); + ASSERT(Parent); + + /* Get the value list and check if it has any entries */ + ChildList = &Parent->ValueList; + if (ChildList->Count) + { + /* Try to find this value */ + Result = CmpFindNameInList(Hive, + ChildList, + &ValueName, + &ChildIndex, + &ChildCell); + if (!Result) + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Value not found, return error */ + if (ChildCell == HCELL_NIL) goto Quickie; + + /* We found the value, mark all relevant cells dirty */ + if (!((HvMarkCellDirty(Hive, Cell, FALSE)) && + (HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) && + (HvMarkCellDirty(Hive, ChildCell, FALSE)))) + { + /* Not enough log space, fail */ + Status = STATUS_NO_LOG_SPACE; + goto Quickie; + } + + /* Get the key value */ + Value = (PCM_KEY_VALUE)HvGetCell(Hive,ChildCell); + ASSERT(Value); + + /* Mark it and all related data as dirty */ + if (!CmpMarkValueDataDirty(Hive, Value)) + { + /* Not enough log space, fail */ + Status = STATUS_NO_LOG_SPACE; + goto Quickie; + } + + /* Ssanity checks */ + ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List)); + ASSERT(HvIsCellDirty(Hive, ChildCell)); + + /* Remove the value from the child list */ + Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList); + if (!NT_SUCCESS(Status)) + { + /* Set known error */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Remove the value and its data itself */ + if (!CmpFreeValue(Hive, ChildCell)) + { + /* Failed to free the value, fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Set the last write time */ + KeQuerySystemTime(&Parent->LastWriteTime); + Kcb->KcbLastWriteTime = Parent->LastWriteTime; + + /* Sanity check */ + ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen); + ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen); + ASSERT(HvIsCellDirty(Hive, Cell)); + + /* Check if the value list is empty now */ + if (!Parent->ValueList.Count) + { + /* Then clear key node data */ + Parent->MaxValueNameLen = 0; + Parent->MaxValueDataLen = 0; + Kcb->KcbMaxValueNameLen = 0; + Kcb->KcbMaxValueDataLen = 0; + } + + /* Cleanup the value cache */ + CmpCleanUpKcbValueCache(Kcb); + + /* Sanity checks */ + ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))); + ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)); + + /* Set the value cache */ + Kcb->ValueCache.Count = ChildList->Count; + Kcb->ValueCache.ValueList = ChildList->List; + + /* Notify registered callbacks */ + CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_LAST_SET); + + /* Change default Status to success */ + Status = STATUS_SUCCESS; + } + +Quickie: + /* Release the parent cell, if any */ + if (Parent) HvReleaseCell(Hive, Cell); + + /* Check if we had a value */ + if (Value) + { + /* Release the child cell */ + ASSERT(ChildCell != HCELL_NIL); + HvReleaseCell(Hive, ChildCell); + } + + /* Release locks */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return Status; +} + +NTSTATUS +NTAPI +CmQueryValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, + IN UNICODE_STRING ValueName, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + IN PVOID KeyValueInformation, + IN ULONG Length, + IN PULONG ResultLength) +{ + NTSTATUS Status; + PCM_KEY_VALUE ValueData; + ULONG Index; + BOOLEAN ValueCached = FALSE; + PCM_CACHED_VALUE *CachedValue; + HCELL_INDEX CellToRelease; + VALUE_SEARCH_RETURN_TYPE Result; + PHHIVE Hive; + PAGED_CODE(); + + /* Acquire hive lock */ + CmpLockRegistry(); + + /* Lock the KCB shared */ + CmpAcquireKcbLockShared(Kcb); + + /* Don't touch deleted keys */ +DoAgain: + if (Kcb->Delete) + { + /* Undo everything */ + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return STATUS_KEY_DELETED; + } + + /* We don't deal with this yet */ + if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) + { + /* Shouldn't happen */ + ASSERT(FALSE); + } + + /* Get the hive */ + Hive = Kcb->KeyHive; + + /* Find the key value */ + Result = CmpFindValueByNameFromCache(Kcb, + &ValueName, + &CachedValue, + &Index, + &ValueData, + &ValueCached, + &CellToRelease); + if (Result == SearchNeedExclusiveLock) + { + /* Check if we need an exclusive lock */ + ASSERT(CellToRelease == HCELL_NIL); + ASSERT(ValueData == NULL); + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + + if (Result == SearchSuccess) + { + /* Sanity check */ + ASSERT(ValueData != NULL); + + /* User data, protect against exceptions */ + _SEH2_TRY + { + /* Query the information requested */ + Result = CmpQueryKeyValueData(Kcb, + CachedValue, + ValueData, + ValueCached, + KeyValueInformationClass, + KeyValueInformation, + Length, + ResultLength, + &Status); + if (Result == SearchNeedExclusiveLock) + { + /* Release the value cell */ + if (CellToRelease != HCELL_NIL) + { + HvReleaseCell(Hive, CellToRelease); + CellToRelease = HCELL_NIL; + } + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + else + { + /* Failed to find the value */ + Status = STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* If we have a cell to release, do so */ + if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease); + + /* Release locks */ + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return Status; +} + +NTSTATUS +NTAPI +CmEnumerateValueKey(IN PCM_KEY_CONTROL_BLOCK Kcb, + IN ULONG Index, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + IN PVOID KeyValueInformation, + IN ULONG Length, + IN PULONG ResultLength) +{ + NTSTATUS Status; + PHHIVE Hive; + PCM_KEY_NODE Parent; + HCELL_INDEX CellToRelease = HCELL_NIL, CellToRelease2 = HCELL_NIL; + VALUE_SEARCH_RETURN_TYPE Result; + BOOLEAN IndexIsCached, ValueIsCached = FALSE; + PCELL_DATA CellData; + PCM_CACHED_VALUE *CachedValue; + PCM_KEY_VALUE ValueData = NULL; + PAGED_CODE(); + + /* Acquire hive lock */ + CmpLockRegistry(); + + /* Lock the KCB shared */ + CmpAcquireKcbLockShared(Kcb); + + /* Don't touch deleted keys */ +DoAgain: + if (Kcb->Delete) + { + /* Undo everything */ + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return STATUS_KEY_DELETED; + } + + /* Get the hive and parent */ + Hive = Kcb->KeyHive; + Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); + ASSERT(Parent); + + /* FIXME: Lack of cache? */ + if (Kcb->ValueCache.Count != Parent->ValueList.Count) + { + DPRINT1("HACK: Overriding value cache count\n"); + Kcb->ValueCache.Count = Parent->ValueList.Count; + } + + /* Make sure the index is valid */ + if (Index >= Kcb->ValueCache.Count) + { + /* Release the cell and fail */ + HvReleaseCell(Hive, Kcb->KeyCell); + Status = STATUS_NO_MORE_ENTRIES; + goto Quickie; + } + + /* We don't deal with this yet */ + if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) + { + /* Shouldn't happen */ + ASSERT(FALSE); + } + + /* Find the value list */ + Result = CmpGetValueListFromCache(Kcb, + &CellData, + &IndexIsCached, + &CellToRelease); + if (Result == SearchNeedExclusiveLock) + { + /* Check if we need an exclusive lock */ + ASSERT(CellToRelease == HCELL_NIL); + HvReleaseCell(Hive, Kcb->KeyCell); + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + else if (Result != SearchSuccess) + { + /* Sanity check */ + ASSERT(CellData == NULL); + + /* Release the cell and fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Now get the key value */ + Result = CmpGetValueKeyFromCache(Kcb, + CellData, + Index, + &CachedValue, + &ValueData, + IndexIsCached, + &ValueIsCached, + &CellToRelease2); + if (Result == SearchNeedExclusiveLock) + { + /* Cleanup state */ + ASSERT(CellToRelease2 == HCELL_NIL); + if (CellToRelease) + { + HvReleaseCell(Hive, CellToRelease); + CellToRelease = HCELL_NIL; + } + HvReleaseCell(Hive, Kcb->KeyCell); + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + else if (Result != SearchSuccess) + { + /* Sanity check */ + ASSERT(ValueData == NULL); + + /* Release the cells and fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* User data, need SEH */ + _SEH2_TRY + { + /* Query the information requested */ + Result = CmpQueryKeyValueData(Kcb, + CachedValue, + ValueData, + ValueIsCached, + KeyValueInformationClass, + KeyValueInformation, + Length, + ResultLength, + &Status); + if (Result == SearchNeedExclusiveLock) + { + /* Cleanup state */ + if (CellToRelease2) HvReleaseCell(Hive, CellToRelease2); + HvReleaseCell(Hive, Kcb->KeyCell); + if (CellToRelease) HvReleaseCell(Hive, CellToRelease); + + /* Try with exclusive KCB lock */ + CmpConvertKcbSharedToExclusive(Kcb); + goto DoAgain; + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + +Quickie: + /* If we have a cell to release, do so */ + if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease); + + /* Release the parent cell */ + HvReleaseCell(Hive, Kcb->KeyCell); + + /* If we have a cell to release, do so */ + if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2); + + /* Release locks */ + CmpReleaseKcbLock(Kcb); + CmpUnlockRegistry(); + return Status; +} + NTSTATUS NTAPI CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb, @@ -1087,6 +1314,7 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb, NTSTATUS Status; PHHIVE Hive; PCM_KEY_NODE Parent; + HV_TRACK_CELL_REF CellReferences = {0}; /* Acquire hive lock */ CmpLockRegistry(); @@ -1094,16 +1322,6 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb, /* Lock KCB shared */ CmpAcquireKcbLockShared(Kcb); - /* Get the hive and parent */ - Hive = Kcb->KeyHive; - Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } - /* Don't touch deleted keys */ if (Kcb->Delete) { @@ -1120,13 +1338,27 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb, case KeyBasicInformation: case KeyNodeInformation: - /* Call the internal API */ - Status = CmpQueryKeyData(Hive, - Parent, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); + /* Get the hive and parent */ + Hive = Kcb->KeyHive; + Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); + ASSERT(Parent); + + /* Track cell references */ + if (!HvTrackCellRef(&CellReferences, Hive, Kcb->KeyCell)) + { + /* Not enough memory to track references */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + /* Call the internal API */ + Status = CmpQueryKeyData(Hive, + Parent, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + } break; /* Unsupported classes for now */ @@ -1149,6 +1381,9 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb, } Quickie: + /* Release references */ + HvReleaseFreeCellRefArray(&CellReferences); + /* Release locks */ CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); @@ -1168,6 +1403,7 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb, PHHIVE Hive; PCM_KEY_NODE Parent, Child; HCELL_INDEX ChildCell; + HV_TRACK_CELL_REF CellReferences = {0}; /* Acquire hive lock */ CmpLockRegistry(); @@ -1179,20 +1415,14 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb, if (Kcb->Delete) { /* Undo everything */ - CmpReleaseKcbLock(Kcb); - CmpUnlockRegistry(); - return STATUS_KEY_DELETED; + Status = STATUS_KEY_DELETED; + goto Quickie; } /* Get the hive and parent */ Hive = Kcb->KeyHive; Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell); - if (!Parent) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } + ASSERT(Parent); /* Get the child cell */ ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index); @@ -1210,22 +1440,39 @@ CmEnumerateKey(IN PCM_KEY_CONTROL_BLOCK Kcb, /* Now get the actual child node */ Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell); - if (!Child) + ASSERT(Child); + + /* Track references */ + if (!HvTrackCellRef(&CellReferences, Hive, ChildCell)) { - /* Fail */ + /* Can't allocate memory for tracking */ Status = STATUS_INSUFFICIENT_RESOURCES; goto Quickie; } - /* Query the data requested */ - Status = CmpQueryKeyData(Hive, - Child, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); + /* Data can be user-mode, use SEH */ + _SEH2_TRY + { + /* Query the data requested */ + Status = CmpQueryKeyData(Hive, + Child, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Fail with exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(goto Quickie); + } + _SEH2_END; Quickie: + /* Release references */ + HvReleaseFreeCellRefArray(&CellReferences); + /* Release locks */ CmpReleaseKcbLock(Kcb); CmpUnlockRegistry(); @@ -1271,14 +1518,12 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody) Hive = Kcb->KeyHive; Cell = Kcb->KeyCell; + /* Lock flushes */ + CmpLockHiveFlusherShared((PCMHIVE)Hive); + /* Get the key node */ Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell); - if (!Node) - { - /* Fail */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto Quickie; - } + ASSERT(Node); /* Sanity check */ ASSERT(Node->Flags == Kcb->Flags); @@ -1287,11 +1532,17 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody) if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) && !(Node->Flags & KEY_NO_DELETE)) { + /* Send notification to registered callbacks */ + CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_NAME); + /* Get the parent and free the cell */ ParentCell = Node->Parent; Status = CmpFreeKeyByCell(Hive, Cell, TRUE); if (NT_SUCCESS(Status)) { + /* Flush any notifications */ + CmpFlushNotifiesOnKeyBodyList(Kcb, FALSE); + /* Clean up information we have on the subkey */ CmpCleanUpSubKeyInfo(Kcb->ParentKcb); @@ -1327,10 +1578,12 @@ CmDeleteKey(IN PCM_KEY_BODY KeyBody) Status = STATUS_CANNOT_DELETE; } -Quickie: /* Release the cell */ HvReleaseCell(Hive, Cell); - + + /* Release flush lock */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); + /* Release the KCB locks */ Quickie2: CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey); @@ -1364,12 +1617,36 @@ CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb, } else { + /* Don't touch the hive */ + CmpLockHiveFlusherExclusive(CmHive); + ASSERT(CmHive->ViewLock); + KeAcquireGuardedMutex(CmHive->ViewLock); + CmHive->ViewLockOwner = KeGetCurrentThread(); + + /* Will the hive shrink? */ + if (HvHiveWillShrink(Hive)) + { + /* I don't believe the current Hv does shrinking */ + ASSERT(FALSE); + } + else + { + /* Now we can release views */ + ASSERT(CmHive->ViewLock); + CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK_OR_LOADING(CmHive); + ASSERT(KeGetCurrentThread() == CmHive->ViewLockOwner); + KeReleaseGuardedMutex(CmHive->ViewLock); + } + /* Flush only this hive */ if (!HvSyncHive(Hive)) { /* Fail */ Status = STATUS_REGISTRY_IO_FAILED; } + + /* Release the flush lock */ + CmpUnlockHiveFlusher((PCMHIVE)Hive); } /* Return the status */ @@ -1387,8 +1664,9 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey, SECURITY_CLIENT_CONTEXT ClientSecurityContext; HANDLE KeyHandle; BOOLEAN Allocate = TRUE; - PCMHIVE CmHive; + PCMHIVE CmHive, LoadedHive; NTSTATUS Status; + CM_PARSE_CONTEXT ParseContext; /* Check if we have a trust key */ if (KeyBody) @@ -1415,9 +1693,21 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey, } /* Open the target key */ +#if 0 Status = ZwOpenKey(&KeyHandle, KEY_READ, TargetKey); +#else + RtlZeroMemory(&ParseContext, sizeof(ParseContext)); + ParseContext.CreateOperation = FALSE; + Status = ObOpenObjectByName(TargetKey, + CmpKeyObjectType, + KernelMode, + NULL, + KEY_READ, + &ParseContext, + &KeyHandle); +#endif if (!NT_SUCCESS(Status)) KeyHandle = NULL; - + /* Open the hive */ Status = CmpCmdHiveOpen(SourceFile, &ClientSecurityContext, @@ -1437,21 +1727,29 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey, /* Lock the registry */ CmpLockRegistryExclusive(); - /* FIXME: Check if we are already loaded */ - + /* Check if we are already loaded */ + if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive)) + { + /* That's okay then */ + ASSERT(LoadedHive); + Status = STATUS_SUCCESS; + } + /* Release the registry */ CmpUnlockRegistry(); } /* Close the key handle if we had one */ if (KeyHandle) ZwClose(KeyHandle); - DPRINT1("Failed: %lx\n", Status); return Status; } /* Lock the registry shared */ CmpLockRegistry(); + /* Lock loading */ + ExAcquirePushLockExclusive(&CmpLoadHiveLock); + /* Lock the hive to this thread */ CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING; CmHive->CreatorOwner = KeGetCurrentThread(); @@ -1467,23 +1765,37 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey, TargetKey->SecurityDescriptor); if (NT_SUCCESS(Status)) { - /* FIXME: Add to HiveList key */ + /* Add to HiveList key */ + CmpAddToHiveFileList(CmHive); /* Sync the hive if necessary */ if (Allocate) { - /* Sync it */ + /* Sync it under the flusher lock */ + CmpLockHiveFlusherExclusive(CmHive); HvSyncHive(&CmHive->Hive); + CmpUnlockHiveFlusher(CmHive); } /* Release the hive */ CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING; CmHive->CreatorOwner = NULL; + + /* Allow loads */ + ExReleasePushLock(&CmpLoadHiveLock); } else { /* FIXME: TODO */ - + ASSERT(FALSE); + } + + /* Is this first profile load? */ + if (!(CmpProfileLoaded) && !(CmpWasSetupBoot)) + { + /* User is now logged on, set quotas */ + CmpProfileLoaded = TRUE; + CmpSetGlobalQuotaAllowed(); } /* Unlock the registry */ diff --git a/ntoskrnl/config/cmboot.c b/ntoskrnl/config/cmboot.c index f1dcc347a20..50c6815866f 100644 --- a/ntoskrnl/config/cmboot.c +++ b/ntoskrnl/config/cmboot.c @@ -1,20 +1,19 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: ntoskrnl/config/cmboot.c * PURPOSE: Configuration Manager - Boot Initialization - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * PROGRAMMERS: ReactOS Portable Systems Group + * Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include "ntoskrnl.h" #define NDEBUG #include "debug.h" - -/* GLOBALS *******************************************************************/ - -/* FUNCTIONS *****************************************************************/ + +/* FUNCTIONS ******************************************************************/ HCELL_INDEX NTAPI @@ -124,3 +123,559 @@ CmpFindControlSet(IN PHHIVE SystemHive, /* Return the CCS Cell */ return ControlSetCell; } + +ULONG +NTAPI +CmpFindTagIndex(IN PHHIVE Hive, + IN HCELL_INDEX TagCell, + IN HCELL_INDEX GroupOrderCell, + IN PUNICODE_STRING GroupName) +{ + PCM_KEY_VALUE TagValue, Value; + HCELL_INDEX OrderCell; + PULONG TagOrder, DriverTag; + ULONG CurrentTag, Length; + PCM_KEY_NODE Node; + BOOLEAN BufferAllocated; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Get the tag */ + Value = HvGetCell(Hive, TagCell); + ASSERT(Value); + DriverTag = (PULONG)CmpValueToData(Hive, Value, &Length); + ASSERT(DriverTag); + + /* Get the order array */ + Node = HvGetCell(Hive, GroupOrderCell); + ASSERT(Node); + OrderCell = CmpFindValueByName(Hive, Node, GroupName); + if (OrderCell == HCELL_NIL) return -2; + + /* And read it */ + TagValue = HvGetCell(Hive, OrderCell); + CmpGetValueData(Hive, TagValue, &Length, (PVOID*)&TagOrder, &BufferAllocated, &OrderCell); + ASSERT(TagOrder); + + /* Parse each tag */ + for (CurrentTag = 1; CurrentTag <= TagOrder[0]; CurrentTag++) + { + /* Find a match */ + if (TagOrder[CurrentTag] == *DriverTag) + { + /* Found it -- return the tag */ + if (BufferAllocated) ExFreePool(TagOrder); + return CurrentTag; + } + } + + /* No matches, so assume next to last ordering */ + if (BufferAllocated) ExFreePool(TagOrder); + return -2; +} + +BOOLEAN +NTAPI +CmpAddDriverToList(IN PHHIVE Hive, + IN HCELL_INDEX DriverCell, + IN HCELL_INDEX GroupOrderCell, + IN PUNICODE_STRING RegistryPath, + IN PLIST_ENTRY BootDriverListHead) +{ + PBOOT_DRIVER_NODE DriverNode; + PBOOT_DRIVER_LIST_ENTRY DriverEntry; + PCM_KEY_NODE Node; + ULONG NameLength, Length; + HCELL_INDEX ValueCell, TagCell; + PCM_KEY_VALUE Value; + PUNICODE_STRING FileName, RegistryString; + UNICODE_STRING UnicodeString; + PULONG ErrorControl; + PWCHAR Buffer; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Allocate a driver node and initialize it */ + DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM); + if (!DriverNode) return FALSE; + DriverEntry = &DriverNode->ListEntry; + DriverEntry->RegistryPath.Buffer = NULL; + DriverEntry->FilePath.Buffer = NULL; + + /* Get the driver cell */ + Node = HvGetCell(Hive, DriverCell); + ASSERT(Node); + + /* Get the name from the cell */ + DriverNode->Name.Length = Node->Flags & KEY_COMP_NAME ? + CmpCompressedNameSize(Node->Name, Node->NameLength) : + Node->NameLength; + DriverNode->Name.MaximumLength = DriverNode->Name.Length; + NameLength = DriverNode->Name.Length; + + /* Now allocate the buffer for it and copy the name */ + DriverNode->Name.Buffer = CmpAllocate(NameLength, FALSE, TAG_CM); + if (!DriverNode->Name.Buffer) return FALSE; + if (Node->Flags & KEY_COMP_NAME) + { + /* Compressed name */ + CmpCopyCompressedName(DriverNode->Name.Buffer, + DriverNode->Name.Length, + Node->Name, + Node->NameLength); + } + else + { + /* Normal name */ + RtlCopyMemory(DriverNode->Name.Buffer, Node->Name, Node->NameLength); + } + + /* Now find the image path */ + RtlInitUnicodeString(&UnicodeString, L"ImagePath"); + ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (ValueCell == HCELL_NIL) + { + /* Couldn't find it, so assume the drivers path */ + Length = sizeof(L"System32\\Drivers\\") + NameLength + sizeof(L".sys"); + + /* Allocate the path name */ + FileName = &DriverEntry->FilePath; + FileName->Length = 0; + FileName->MaximumLength = Length; + FileName->Buffer = CmpAllocate(Length, FALSE,TAG_CM); + if (!FileName->Buffer) return FALSE; + + /* Write the path name */ + RtlAppendUnicodeToString(FileName, L"System32\\Drivers\\"); + RtlAppendUnicodeStringToString(FileName, &DriverNode->Name); + RtlAppendUnicodeToString(FileName, L".sys"); + } + else + { + /* Path name exists, so grab it */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + + /* Allocate and setup the path name */ + FileName = &DriverEntry->FilePath; + Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length); + FileName->MaximumLength = FileName->Length = Length; + FileName->Buffer = CmpAllocate(Length, FALSE, TAG_CM); + + /* Transfer the data */ + if (!(FileName->Buffer) || !(Buffer)) return FALSE; + RtlCopyMemory(FileName->Buffer, Buffer, Length); + } + + /* Now build the registry path */ + RegistryString = &DriverEntry->RegistryPath; + RegistryString->Length = 0; + RegistryString->MaximumLength = RegistryPath->Length + NameLength; + RegistryString->Buffer = CmpAllocate(RegistryString->MaximumLength, FALSE, TAG_CM); + if (!RegistryString->Buffer) return FALSE; + + /* Add the driver name to it */ + RtlAppendUnicodeStringToString(RegistryString, RegistryPath); + RtlAppendUnicodeStringToString(RegistryString, &DriverNode->Name); + + /* The entry is done, add it */ + InsertHeadList(BootDriverListHead, &DriverEntry->Link); + + /* Now find error control settings */ + RtlInitUnicodeString(&UnicodeString, L"ErrorControl"); + ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (ValueCell == HCELL_NIL) + { + /* Couldn't find it, so assume default */ + DriverNode->ErrorControl = NormalError; + } + else + { + /* Otherwise, read whatever the data says */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + ErrorControl = (PULONG)CmpValueToData(Hive, Value, &Length); + ASSERT(ErrorControl); + DriverNode->ErrorControl = *ErrorControl; + } + + /* Next, get the group cell */ + RtlInitUnicodeString(&UnicodeString, L"group"); + ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (ValueCell == HCELL_NIL) + { + /* Couldn't find, so set an empty string */ + RtlInitEmptyUnicodeString(&DriverNode->Group, NULL, 0); + } + else + { + /* Found it, read the group value */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + + /* Copy it into the node */ + DriverNode->Group.Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length); + if (!DriverNode->Group.Buffer) return FALSE; + DriverNode->Group.Length = Length - sizeof(UNICODE_NULL); + DriverNode->Group.MaximumLength = DriverNode->Group.Length; + } + + /* Finally, find the tag */ + RtlInitUnicodeString(&UnicodeString, L"Tag"); + TagCell = CmpFindValueByName(Hive, Node, &UnicodeString); + if (TagCell == HCELL_NIL) + { + /* No tag, so load last */ + DriverNode->Tag = -1; + } + else + { + /* Otherwise, decode it based on tag order */ + DriverNode->Tag = CmpFindTagIndex(Hive, + TagCell, + GroupOrderCell, + &DriverNode->Group); + } + + /* All done! */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpIsLoadType(IN PHHIVE Hive, + IN HCELL_INDEX Cell, + IN SERVICE_LOAD_TYPE LoadType) +{ + PCM_KEY_NODE Node; + HCELL_INDEX ValueCell; + UNICODE_STRING ValueString = RTL_CONSTANT_STRING(L"Start"); + PCM_KEY_VALUE Value; + ULONG Length; + PLONG Data; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Open the start cell */ + Node = HvGetCell(Hive, Cell); + ASSERT(Node); + ValueCell = CmpFindValueByName(Hive, Node, &ValueString); + if (ValueCell == HCELL_NIL) return FALSE; + + /* Read the start value */ + Value = HvGetCell(Hive, ValueCell); + ASSERT(Value); + Data = (PLONG)CmpValueToData(Hive, Value, &Length); + ASSERT(Data); + + /* Return if the type matches */ + return (*Data == LoadType); +} + +BOOLEAN +NTAPI +CmpFindDrivers(IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN SERVICE_LOAD_TYPE LoadType, + IN PWCHAR BootFileSystem OPTIONAL, + IN PLIST_ENTRY DriverListHead) +{ + HCELL_INDEX ServicesCell, ControlCell, GroupOrderCell, DriverCell; + UNICODE_STRING Name; + ULONG i; + WCHAR Buffer[128]; + UNICODE_STRING UnicodeString, KeyPath; + PBOOT_DRIVER_NODE FsNode; + PCM_KEY_NODE ControlNode, ServicesNode, Node; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Open the control set key */ + ControlNode = HvGetCell(Hive, ControlSet); + ASSERT(ControlNode); + + /* Get services cell */ + RtlInitUnicodeString(&Name, L"Services"); + ServicesCell = CmpFindSubKeyByName(Hive, ControlNode, &Name); + if (ServicesCell == HCELL_NIL) return FALSE; + + /* Open services key */ + ServicesNode = HvGetCell(Hive, ServicesCell); + ASSERT(ServicesNode); + + /* Get control cell */ + RtlInitUnicodeString(&Name, L"Control"); + ControlCell = CmpFindSubKeyByName(Hive, ControlNode, &Name); + if (ControlCell == HCELL_NIL) return FALSE; + + /* Get the group order cell and read it */ + RtlInitUnicodeString(&Name, L"GroupOrderList"); + Node = HvGetCell(Hive, ControlCell); + ASSERT(Node); + GroupOrderCell = CmpFindSubKeyByName(Hive, Node, &Name); + if (GroupOrderCell == HCELL_NIL) return FALSE; + + /* Build the root registry path */ + RtlInitEmptyUnicodeString(&KeyPath, Buffer, sizeof(Buffer)); + RtlAppendUnicodeToString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); + + /* Find the first subkey (ie: the first driver or service) */ + i = 0; + DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, i); + while (DriverCell != HCELL_NIL) + { + /* Make sure it's a driver of this start type */ + if (CmpIsLoadType(Hive, DriverCell, LoadType)) + { + /* Add it to the list */ + CmpAddDriverToList(Hive, + DriverCell, + GroupOrderCell, + &KeyPath, + DriverListHead); + + } + + /* Try the next subkey */ + DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, ++i); + } + + /* Check if we have a boot file system */ + if (BootFileSystem) + { + /* Find it */ + RtlInitUnicodeString(&UnicodeString, BootFileSystem); + DriverCell = CmpFindSubKeyByName(Hive, ServicesNode, &UnicodeString); + if (DriverCell != HCELL_NIL) + { + /* Always add it to the list */ + CmpAddDriverToList(Hive, + DriverCell, + GroupOrderCell, + &KeyPath, + DriverListHead); + + /* Mark it as critical so it always loads */ + FsNode = CONTAINING_RECORD(DriverListHead->Flink, + BOOT_DRIVER_NODE, + ListEntry.Link); + FsNode->ErrorControl = SERVICE_ERROR_CRITICAL; + } + } + + /* We're done! */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpDoSort(IN PLIST_ENTRY DriverListHead, + IN PUNICODE_STRING OrderList) +{ + PWCHAR Current, End = NULL; + PLIST_ENTRY NextEntry; + UNICODE_STRING GroupName; + PBOOT_DRIVER_NODE CurrentNode; + + /* We're going from end to start, so get to the last group and keep going */ + Current = &OrderList->Buffer[OrderList->Length / sizeof(WCHAR)]; + while (Current > OrderList->Buffer) + { + /* Scan the current string */ + do + { + if (*Current == UNICODE_NULL) End = Current; + } while ((*(--Current - 1) != UNICODE_NULL) && (Current != OrderList->Buffer)); + + /* This is our cleaned up string for this specific group */ + ASSERT(End != NULL); + GroupName.Length = (End - Current) * sizeof(WCHAR); + GroupName.MaximumLength = GroupName.Length; + GroupName.Buffer = Current; + + /* Now loop the driver list */ + NextEntry = DriverListHead->Flink; + while (NextEntry != DriverListHead) + { + /* Get this node */ + CurrentNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* Get the next entry now since we'll do a relink */ + NextEntry = CurrentNode->ListEntry.Link.Flink; + + /* Is there a group name and does it match the current group? */ + if ((CurrentNode->Group.Buffer) && + (RtlEqualUnicodeString(&GroupName, &CurrentNode->Group, TRUE))) + { + /* Remove from this location and re-link in the new one */ + RemoveEntryList(&CurrentNode->ListEntry.Link); + InsertHeadList(DriverListHead, &CurrentNode->ListEntry.Link); + } + } + + /* Move on */ + Current--; + } + + /* All done */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpSortDriverList(IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN PLIST_ENTRY DriverListHead) +{ + HCELL_INDEX Controls, GroupOrder, ListCell; + UNICODE_STRING Name, DependList; + PCM_KEY_VALUE ListNode; + ULONG Length; + PCM_KEY_NODE Node; + ASSERT(Hive->ReleaseCellRoutine == NULL); + + /* Open the control key */ + Node = HvGetCell(Hive, ControlSet); + ASSERT(Node); + RtlInitUnicodeString(&Name, L"Control"); + Controls = CmpFindSubKeyByName(Hive, Node, &Name); + if (Controls == HCELL_NIL) return FALSE; + + /* Open the service group order */ + Node = HvGetCell(Hive, Controls); + ASSERT(Node); + RtlInitUnicodeString(&Name, L"ServiceGroupOrder"); + GroupOrder = CmpFindSubKeyByName(Hive, Node, &Name); + if (GroupOrder == HCELL_NIL) return FALSE; + + /* Open the list key */ + Node = HvGetCell(Hive, GroupOrder); + ASSERT(Node); + RtlInitUnicodeString(&Name, L"list"); + ListCell = CmpFindValueByName(Hive, Node, &Name); + if (ListCell == HCELL_NIL) return FALSE; + + /* Now read the actual list */ + ListNode = HvGetCell(Hive, ListCell); + ASSERT(ListNode); + if (ListNode->Type != REG_MULTI_SZ) return FALSE; + + /* Copy it into a buffer */ + DependList.Buffer = (PWCHAR)CmpValueToData(Hive, ListNode, &Length); + if (!DependList.Buffer) return FALSE; + DependList.Length = DependList.MaximumLength = Length - sizeof(UNICODE_NULL); + + /* And start the recurive sort algorithm */ + return CmpDoSort(DriverListHead, &DependList); +} + +BOOLEAN +NTAPI +CmpOrderGroup(IN PBOOT_DRIVER_NODE StartNode, + IN PBOOT_DRIVER_NODE EndNode) +{ + PBOOT_DRIVER_NODE CurrentNode, PreviousNode; + PLIST_ENTRY ListEntry; + + /* Base case, nothing to do */ + if (StartNode == EndNode) return TRUE; + + /* Loop the nodes */ + CurrentNode = StartNode; + do + { + /* Save this as the previous node */ + PreviousNode = CurrentNode; + + /* And move to the next one */ + ListEntry = CurrentNode->ListEntry.Link.Flink; + CurrentNode = CONTAINING_RECORD(ListEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* Check if the previous driver had a bigger tag */ + if (PreviousNode->Tag > CurrentNode->Tag) + { + /* Check if we need to update the tail */ + if (CurrentNode == EndNode) + { + /* Update the tail */ + ListEntry = CurrentNode->ListEntry.Link.Blink; + EndNode = CONTAINING_RECORD(ListEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + } + + /* Remove this driver since we need to move it */ + RemoveEntryList(&CurrentNode->ListEntry.Link); + + /* Keep looping until we find a driver with a lower tag than ours */ + while ((PreviousNode->Tag > CurrentNode->Tag) && (PreviousNode != StartNode)) + { + /* We'll be re-inserted at this spot */ + ListEntry = PreviousNode->ListEntry.Link.Blink; + PreviousNode = CONTAINING_RECORD(ListEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + } + + /* Do the insert in the new location */ + InsertTailList(&PreviousNode->ListEntry.Link, &CurrentNode->ListEntry.Link); + + /* Update the head, if needed */ + if (PreviousNode == StartNode) StartNode = CurrentNode; + } + } while (CurrentNode != EndNode); + + /* All done */ + return TRUE; +} + +BOOLEAN +NTAPI +CmpResolveDriverDependencies(IN PLIST_ENTRY DriverListHead) +{ + PLIST_ENTRY NextEntry; + PBOOT_DRIVER_NODE StartNode, EndNode, CurrentNode; + + /* Loop the list */ + NextEntry = DriverListHead->Flink; + while (NextEntry != DriverListHead) + { + /* Find the first entry */ + StartNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + do + { + /* Find the last entry */ + EndNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* Get the next entry */ + NextEntry = NextEntry->Flink; + CurrentNode = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_NODE, + ListEntry.Link); + + /* If the next entry is back to the top, break out */ + if (NextEntry == DriverListHead) break; + + /* Otherwise, check if this entry is equal */ + if (!RtlEqualUnicodeString(&StartNode->Group, + &CurrentNode->Group, + TRUE)) + { + /* It is, so we've detected a cycle, break out */ + break; + } + } while (NextEntry != DriverListHead); + + /* Now we have the correct start and end pointers, so do the sort */ + CmpOrderGroup(StartNode, EndNode); + } + + /* We're done */ + return TRUE; +} + +/* EOF */ diff --git a/ntoskrnl/config/cmhvlist.c b/ntoskrnl/config/cmhvlist.c index f4e97814bbd..8fb2636f3dc 100644 --- a/ntoskrnl/config/cmhvlist.c +++ b/ntoskrnl/config/cmhvlist.c @@ -14,4 +14,11 @@ /* FUNCTIONS *****************************************************************/ +NTSTATUS +NTAPI +CmpAddToHiveFileList(IN PCMHIVE Hive) +{ + return STATUS_SUCCESS; +} + /* EOF */ \ No newline at end of file diff --git a/ntoskrnl/config/cminit.c b/ntoskrnl/config/cminit.c index 154ba1530b6..be7efc1660f 100644 --- a/ntoskrnl/config/cminit.c +++ b/ntoskrnl/config/cminit.c @@ -119,12 +119,10 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive, if (!Hive->ViewLock) return STATUS_INSUFFICIENT_RESOURCES; /* Allocate the flush lock */ -#if 0 Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), TAG_CM); if (!Hive->FlusherLock) return STATUS_INSUFFICIENT_RESOURCES; -#endif /* Setup the handles */ Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary; @@ -136,7 +134,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive, Hive->ViewLockOwner = NULL; /* Initialize the flush lock */ - ExInitializePushLock((PULONG_PTR)&Hive->FlusherLock); + ExInitializeResourceLite(Hive->FlusherLock); /* Setup hive locks */ ExInitializePushLock((PULONG_PTR)&Hive->HiveLock); @@ -193,9 +191,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive, { /* Clear allocations and fail */ ExFreePool(Hive->ViewLock); -#if 0 ExFreePool(Hive->FlusherLock); -#endif ExFreePool(Hive); return Status; } @@ -211,9 +207,7 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive, { /* Free all alocations */ ExFreePool(Hive->ViewLock); -#if 0 ExFreePool(Hive->FlusherLock); -#endif ExFreePool(Hive); return STATUS_REGISTRY_CORRUPT; } diff --git a/ntoskrnl/config/cmkcbncb.c b/ntoskrnl/config/cmkcbncb.c index 5e7060d61c4..a26de07cf1b 100644 --- a/ntoskrnl/config/cmkcbncb.c +++ b/ntoskrnl/config/cmkcbncb.c @@ -1135,3 +1135,62 @@ DelistKeyBodyFromKCB(IN PCM_KEY_BODY KeyBody, /* Unlock it it if we did a manual lock */ if (!LockHeld) CmpReleaseKcbLock(KeyBody->KeyControlBlock); } + +VOID +NTAPI +CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb, + IN BOOLEAN LockHeld) +{ + PLIST_ENTRY NextEntry, ListHead; + PCM_KEY_BODY KeyBody; + + /* Sanity check */ + LockHeld ? CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() : CmpIsKcbLockedExclusive(Kcb); + while (TRUE) + { + /* Is the list empty? */ + ListHead = &Kcb->KeyBodyListHead; + if (!IsListEmpty(ListHead)) + { + /* Loop the list */ + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the key body */ + KeyBody = CONTAINING_RECORD(NextEntry, CM_KEY_BODY, KeyBodyList); + ASSERT(KeyBody->Type == '20yk'); + + /* Check for notifications */ + if (KeyBody->NotifyBlock) + { + /* Is the lock held? */ + if (LockHeld) + { + /* Flush it */ + CmpFlushNotify(KeyBody, LockHeld); + ASSERT(KeyBody->NotifyBlock == NULL); + continue; + } + + /* Lock isn't held, so we need to take a reference */ + if (ObReferenceObjectSafe(KeyBody)) + { + /* Now we can flush */ + CmpFlushNotify(KeyBody, LockHeld); + ASSERT(KeyBody->NotifyBlock == NULL); + + /* Release the reference we took */ + ObDereferenceObjectDeferDelete(KeyBody); + continue; + } + } + + /* Try the next entry */ + NextEntry = NextEntry->Flink; + } + } + + /* List has been parsed, exit */ + break; + } +} diff --git a/ntoskrnl/config/cmparse.c b/ntoskrnl/config/cmparse.c index 42d737908a0..82635445dda 100644 --- a/ntoskrnl/config/cmparse.c +++ b/ntoskrnl/config/cmparse.c @@ -414,15 +414,6 @@ CmpDoCreate(IN PHHIVE Hive, LARGE_INTEGER TimeStamp; PCM_KEY_NODE KeyNode; - /* Sanity check */ -#if 0 - ASSERT((CmpIsKcbLockedExclusive(ParentKcb) == TRUE) || - (CmpTestRegistryLockExclusive() == TRUE)); -#endif - - /* Acquire the flusher lock */ - ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock); - /* Check if the parent is being deleted */ if (ParentKcb->Delete) { @@ -555,7 +546,6 @@ CmpDoCreate(IN PHHIVE Hive, Exit: /* Release the flusher lock and return status */ - ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock); return Status; } @@ -747,9 +737,6 @@ CmpCreateLinkNode(IN PHHIVE Hive, LARGE_INTEGER TimeStamp; PCM_KEY_NODE KeyNode; PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb; -#if 0 - CMP_ASSERT_REGISTRY_LOCK(); -#endif /* Link nodes only allowed on the master */ if (Hive != &CmiVolatileHive->Hive) @@ -759,10 +746,6 @@ CmpCreateLinkNode(IN PHHIVE Hive, return STATUS_ACCESS_DENIED; } - /* Acquire the flusher locks */ - ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock); - ExAcquirePushLockShared((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock); - /* Check if the parent is being deleted */ if (ParentKcb->Delete) { @@ -964,8 +947,6 @@ CmpCreateLinkNode(IN PHHIVE Hive, Exit: /* Release the flusher locks and return status */ - ExReleasePushLock((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock); - ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock); return Status; } diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index 0326e88e619..3587efe7326 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -1,12 +1,13 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: ntoskrnl/config/cmsysini.c * PURPOSE: Configuration Manager - System Initialization Code - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * PROGRAMMERS: ReactOS Portable Systems Group + * Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include "ntoskrnl.h" #define NDEBUG @@ -33,7 +34,7 @@ ULONG CmpTraceLevel = 0; extern LONG CmpFlushStarveWriters; extern BOOLEAN CmFirstTime; -/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS ******************************************************************/ VOID NTAPI @@ -1574,6 +1575,162 @@ CmInitSystem1(VOID) return TRUE; } +VOID +NTAPI +CmpFreeDriverList(IN PHHIVE Hive, + IN PLIST_ENTRY DriverList) +{ + PLIST_ENTRY NextEntry, OldEntry; + PBOOT_DRIVER_NODE DriverNode; + PAGED_CODE(); + + /* Parse the current list */ + NextEntry = DriverList->Flink; + while (NextEntry != DriverList) + { + /* Get the driver node */ + DriverNode = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_NODE, ListEntry.Link); + + /* Get the next entry now, since we're going to free it later */ + OldEntry = NextEntry; + NextEntry = NextEntry->Flink; + + /* Was there a name? */ + if (DriverNode->Name.Buffer) + { + /* Free it */ + CmpFree(DriverNode->Name.Buffer, DriverNode->Name.Length); + } + + /* Was there a registry path? */ + if (DriverNode->ListEntry.RegistryPath.Buffer) + { + /* Free it */ + CmpFree(DriverNode->ListEntry.RegistryPath.Buffer, + DriverNode->ListEntry.RegistryPath.MaximumLength); + } + + /* Was there a file path? */ + if (DriverNode->ListEntry.FilePath.Buffer) + { + /* Free it */ + CmpFree(DriverNode->ListEntry.FilePath.Buffer, + DriverNode->ListEntry.FilePath.MaximumLength); + } + + /* Now free the node, and move on */ + CmpFree(OldEntry, sizeof(BOOT_DRIVER_NODE)); + } +} + +PUNICODE_STRING* +NTAPI +CmGetSystemDriverList(VOID) +{ + LIST_ENTRY DriverList; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + PCM_KEY_BODY KeyBody; + PHHIVE Hive; + HCELL_INDEX RootCell, ControlCell; + HANDLE KeyHandle; + UNICODE_STRING KeyName; + PLIST_ENTRY NextEntry; + ULONG i; + PUNICODE_STRING* ServicePath = NULL; + BOOLEAN Success, AutoSelect; + PBOOT_DRIVER_LIST_ENTRY DriverEntry; + PAGED_CODE(); + + /* Initialize the driver list */ + InitializeListHead(&DriverList); + + /* Open the system hive key */ + RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); + if (!NT_SUCCESS(Status)) return NULL; + + /* Reference the key object to get the root hive/cell to access directly */ + Status = ObReferenceObjectByHandle(KeyHandle, + KEY_QUERY_VALUE, + CmpKeyObjectType, + KernelMode, + (PVOID*)&KeyBody, + NULL); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + NtClose(KeyHandle); + return NULL; + } + + /* Do all this under the registry lock */ + CmpLockRegistryExclusive(); + + /* Get the hive and key cell */ + Hive = KeyBody->KeyControlBlock->KeyHive; + RootCell = KeyBody->KeyControlBlock->KeyCell; + + /* Open the current control set key */ + RtlInitUnicodeString(&KeyName, L"Current"); + ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect); + if (ControlCell == HCELL_NIL) goto EndPath; + + /* Find all system drivers */ + Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList); + if (!Success) goto EndPath; + + /* Sort by group/tag */ + if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath; + + /* Remove circular dependencies (cycles) and sort */ + if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath; + + /* Loop the list to count drivers */ + for (i = 0, NextEntry = DriverList.Flink; + NextEntry != &DriverList; + i++, NextEntry = NextEntry->Flink); + + /* Allocate the array */ + ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING)); + if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0); + + /* Loop the driver list */ + for (i = 0, NextEntry = DriverList.Flink; + NextEntry != &DriverList; + i++, NextEntry = NextEntry->Flink) + { + /* Get the entry */ + DriverEntry = CONTAINING_RECORD(NextEntry, BOOT_DRIVER_LIST_ENTRY, Link); + + /* Allocate the path for the caller and duplicate the registry path */ + ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)); + RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &DriverEntry->RegistryPath, + ServicePath[i]); + } + + /* Terminate the list */ + ServicePath[i] = NULL; + +EndPath: + /* Free the driver list if we had one */ + if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList); + + /* Unlock the registry */ + CmpUnlockRegistry(); + + /* Close the key handle and dereference the object, then return the path */ + ObDereferenceObject(KeyBody); + NtClose(KeyHandle); + return ServicePath; +} + VOID NTAPI CmpLockRegistryExclusive(VOID) @@ -1771,3 +1928,5 @@ CmShutdownSystem(VOID) if (!CmFirstTime) CmpShutdownWorkers(); CmpDoFlushAll(TRUE); } + +/* EOF */ diff --git a/ntoskrnl/include/internal/cm.h b/ntoskrnl/include/internal/cm.h index 4880dc08026..62f4010f20b 100644 --- a/ntoskrnl/include/internal/cm.h +++ b/ntoskrnl/include/internal/cm.h @@ -1522,6 +1522,40 @@ CmSetLazyFlushState( IN BOOLEAN Enable ); +// +// Driver List Routines +// +PUNICODE_STRING* +NTAPI +CmGetSystemDriverList( + VOID +); + +BOOLEAN +NTAPI +CmpFindDrivers( + IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN SERVICE_LOAD_TYPE LoadType, + IN PWSTR BootFileSystem OPTIONAL, + IN PLIST_ENTRY DriverListHead +); + + +BOOLEAN +NTAPI +CmpSortDriverList( + IN PHHIVE Hive, + IN HCELL_INDEX ControlSet, + IN PLIST_ENTRY DriverListHead +); + +BOOLEAN +NTAPI +CmpResolveDriverDependencies( + IN PLIST_ENTRY DriverListHead +); + // // Global variables accessible from all of Cm // diff --git a/ntoskrnl/include/internal/i386/intrin_i.h b/ntoskrnl/include/internal/i386/intrin_i.h index a78497b1871..94501841149 100644 --- a/ntoskrnl/include/internal/i386/intrin_i.h +++ b/ntoskrnl/include/internal/i386/intrin_i.h @@ -136,17 +136,27 @@ Ke386FnInit(VOID) FORCEINLINE VOID -Ke386GetGlobalDescriptorTable(OUT PVOID Descriptor) +__sgdt(OUT PVOID Descriptor) { - __asm sgdt [Descriptor]; + __asm + { + mov eax, Descriptor + sgdt [eax] + } } +#define Ke386GetGlobalDescriptorTable __sgdt FORCEINLINE VOID -Ke386SetGlobalDescriptorTable(IN PVOID Descriptor) +__lgdt(IN PVOID Descriptor) { - __asm lgdt [Descriptor]; + __asm + { + mov eax, Descriptor + lgdt [eax] + } } +#define Ke386SetGlobalDescriptorTable __lgdt FORCEINLINE USHORT diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 2519a8134d2..1faff6bfcea 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -395,6 +395,33 @@ typedef struct _LOAD_UNLOAD_PARAMS PDRIVER_OBJECT DriverObject; } LOAD_UNLOAD_PARAMS, *PLOAD_UNLOAD_PARAMS; +// +// Boot Driver List Entry +// +typedef struct _DRIVER_INFORMATION +{ + LIST_ENTRY Link; + PDRIVER_OBJECT DriverObject; + PBOOT_DRIVER_LIST_ENTRY DataTableEntry; + HANDLE ServiceHandle; + USHORT TagPosition; + ULONG Failed; + ULONG Processed; + NTSTATUS Status; +} DRIVER_INFORMATION, *PDRIVER_INFORMATION; + +// +// Boot Driver Node +// +typedef struct _BOOT_DRIVER_NODE +{ + BOOT_DRIVER_LIST_ENTRY ListEntry; + UNICODE_STRING Group; + UNICODE_STRING Name; + ULONG Tag; + ULONG ErrorControl; +} BOOT_DRIVER_NODE, *PBOOT_DRIVER_NODE; + // // List of Bus Type GUIDs // @@ -482,8 +509,17 @@ typedef struct _DEVICETREE_TRAVERSE_CONTEXT // // PNP Routines // -VOID -PnpInit( +NTSTATUS +NTAPI +PipCallDriverAddDevice( + IN PDEVICE_NODE DeviceNode, + IN BOOLEAN LoadDriver, + IN PDRIVER_OBJECT DriverObject +); + +NTSTATUS +NTAPI +IopInitializePlugPlayServices( VOID ); @@ -522,6 +558,12 @@ IopGetSystemPowerDeviceObject( IN PDEVICE_OBJECT *DeviceObject ); +PDEVICE_NODE +NTAPI +PipAllocateDeviceNode( + IN PDEVICE_OBJECT PhysicalDeviceObject +); + NTSTATUS IopCreateDeviceNode( IN PDEVICE_NODE ParentNode, @@ -536,6 +578,15 @@ IopFreeDeviceNode( ); NTSTATUS +NTAPI +IopSynchronousCall( + IN PDEVICE_OBJECT DeviceObject, + IN PIO_STACK_LOCATION IoStackLocation, + OUT PVOID *Information +); + +NTSTATUS +NTAPI IopInitiatePnpIrp( IN PDEVICE_OBJECT DeviceObject, IN PIO_STATUS_BLOCK IoStatusBlock, @@ -600,11 +651,66 @@ IopOpenRegistryKeyEx( NTSTATUS NTAPI -IopGetRegistryValue(IN HANDLE Handle, - IN PWSTR ValueName, - OUT PKEY_VALUE_FULL_INFORMATION *Information); +IopGetRegistryValue( + IN HANDLE Handle, + IN PWSTR ValueName, + OUT PKEY_VALUE_FULL_INFORMATION *Information +); +NTSTATUS +NTAPI +IopCreateRegistryKeyEx( + OUT PHANDLE Handle, + IN HANDLE BaseHandle OPTIONAL, + IN PUNICODE_STRING KeyName, + IN ACCESS_MASK DesiredAccess, + IN ULONG CreateOptions, + OUT PULONG Disposition OPTIONAL +); +// +// PnP Routines +// +NTSTATUS +NTAPI +IopUpdateRootKey( + VOID +); + +NTSTATUS +NTAPI +PiInitCacheGroupInformation( + VOID +); + +USHORT +NTAPI +PpInitGetGroupOrderIndex( + IN HANDLE ServiceHandle +); + +USHORT +NTAPI +PipGetDriverTagPriority( + IN HANDLE ServiceHandle +); + +NTSTATUS +NTAPI +PnpRegMultiSzToUnicodeStrings( + IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation, + OUT PUNICODE_STRING *UnicodeStringList, + OUT PULONG UnicodeStringCount +); + +BOOLEAN +NTAPI +PnpRegSzToString( + IN PWCHAR RegSzData, + IN ULONG RegSzLength, + OUT PUSHORT StringLength OPTIONAL +); + // // Initialization Routines // @@ -630,6 +736,12 @@ IoInitSystem( // // Device/Volume Routines // +VOID +NTAPI +IopReadyDeviceObjects( + IN PDRIVER_OBJECT Driver +); + NTSTATUS FASTCALL IopInitializeDevice( @@ -1051,6 +1163,7 @@ IopStartRamdisk( // extern POBJECT_TYPE IoCompletionType; extern PDEVICE_NODE IopRootDeviceNode; +extern KSPIN_LOCK IopDeviceTreeLock; extern ULONG IopTraceLevel; extern GENERAL_LOOKASIDE IopMdlLookasideList; extern GENERIC_MAPPING IopCompletionMapping; @@ -1060,6 +1173,8 @@ extern HAL_DISPATCH _HalDispatchTable; extern LIST_ENTRY IopErrorLogListHead; extern ULONG IopNumTriageDumpDataBlocks; extern PVOID IopTriageDumpDataBlocks[64]; +extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList; +extern PDRIVER_OBJECT IopRootDriverObject; // // Inlined Functions diff --git a/ntoskrnl/io/iomgr/device.c b/ntoskrnl/io/iomgr/device.c index 7434970734f..b9176ce276b 100644 --- a/ntoskrnl/io/iomgr/device.c +++ b/ntoskrnl/io/iomgr/device.c @@ -25,6 +25,24 @@ extern LIST_ENTRY IopTapeFsListHead; /* PRIVATE FUNCTIONS **********************************************************/ +VOID +NTAPI +IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver) +{ + PAGED_CODE(); + PDEVICE_OBJECT DeviceObject; + + /* Set the driver as initialized */ + Driver->Flags |= DRVO_INITIALIZED; + DeviceObject = Driver->DeviceObject; + while (DeviceObject) + { + /* Set every device as initialized too */ + DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + DeviceObject = DeviceObject->NextDevice; + } +} + VOID NTAPI IopDeleteDevice(IN PVOID ObjectBody) diff --git a/ntoskrnl/io/iomgr/deviface.c b/ntoskrnl/io/iomgr/deviface.c index 2b0789b5a60..114e308c4a8 100644 --- a/ntoskrnl/io/iomgr/deviface.c +++ b/ntoskrnl/io/iomgr/deviface.c @@ -51,31 +51,29 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, OUT PHANDLE DeviceInterfaceKey) { WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH]; - PWCHAR Guid; - UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT L"\\"); + PWCHAR Guid, RefString; UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters"); UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\"); UNICODE_STRING KeyPath, KeyName; UNICODE_STRING MatchableGuid; - HANDLE GuidKey, ChildKey; + UNICODE_STRING GuidString; + HANDLE GuidKey, hInterfaceKey; ULONG Index = 0; PKEY_BASIC_INFORMATION KeyInformation; ULONG KeyInformationLength; - PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; - ULONG KeyValueInformationLength; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; ULONG RequiredLength; - MatchableGuid.Length = 0; - MatchableGuid.Length += swprintf(StrBuff, - L"##?#%ls", - &SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]); - StrBuff[++MatchableGuid.Length] = UNICODE_NULL; + swprintf(StrBuff, L"##?#%s", &SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]); - MatchableGuid.Buffer = StrBuff; - MatchableGuid.MaximumLength = MAX_PATH * sizeof(WCHAR); - MatchableGuid.Length = (MatchableGuid.Length-1) * sizeof(WCHAR); + RefString = wcsstr(StrBuff, L"\\"); + if (RefString) + { + RefString[0] = 0; + } + + RtlInitUnicodeString(&MatchableGuid, StrBuff); Guid = wcsstr(StrBuff, L"{"); if (!Guid) @@ -85,8 +83,11 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, KeyPath.Length = 0; KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR); + GuidString.Buffer = Guid; + GuidString.Length = GuidString.MaximumLength = 38 * sizeof(WCHAR); + RtlAppendUnicodeToString(&KeyPath, BaseKeyString); - RtlAppendUnicodeToString(&KeyPath, Guid); + RtlAppendUnicodeStringToString(&KeyPath, &GuidString); InitializeObjectAttributes(&ObjectAttributes, &KeyPath, @@ -142,73 +143,62 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName, KeyName.Buffer = KeyInformation->Name; if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE)) - continue; - - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - GuidKey, - NULL); - Status = ZwOpenKey(&ChildKey, KEY_QUERY_VALUE, &ObjectAttributes); - ZwClose(GuidKey); - if (!NT_SUCCESS(Status)) - return Status; - - RtlInitUnicodeString(&KeyName, L"DeviceInstance"); - Status = ZwQueryValueKey(ChildKey, - &KeyName, - KeyValuePartialInformation, - NULL, - 0, - &RequiredLength); - if (Status == STATUS_BUFFER_TOO_SMALL) { - KeyValueInformationLength = RequiredLength; - KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength); - if (!KeyValueInformation) - { - ZwClose(ChildKey); - return Status; - } + ExFreePool(KeyInformation); + continue; + } - Status = ZwQueryValueKey(ChildKey, - &KeyName, - KeyValuePartialInformation, - KeyValueInformation, - KeyValueInformationLength, - &RequiredLength); + KeyPath.Length = 0; + RtlAppendUnicodeStringToString(&KeyPath, &KeyName); + RtlAppendUnicodeToString(&KeyPath, L"\\"); + + /* check for presence of a reference string */ + if (RefString) + { + /* append reference string */ + RefString[0] = L'#'; + RtlInitUnicodeString(&KeyName, RefString); } else { - ZwClose(ChildKey); - return STATUS_OBJECT_PATH_NOT_FOUND; + /* no reference string */ + RtlInitUnicodeString(&KeyName, L"#"); } - ZwClose(ChildKey); - - if (!NT_SUCCESS(Status)) - return Status; - - KeyPath.Length = 0; - - KeyName.Length = KeyName.MaximumLength = KeyValueInformation->DataLength; - KeyName.Buffer = (PWCHAR)KeyValueInformation->Data; - - RtlAppendUnicodeStringToString(&KeyPath, &EnumU); RtlAppendUnicodeStringToString(&KeyPath, &KeyName); - RtlAppendUnicodeStringToString(&KeyPath, &DevParamU); + /* initialize reference string attributes */ InitializeObjectAttributes(&ObjectAttributes, &KeyPath, OBJ_CASE_INSENSITIVE, - 0, + GuidKey, NULL); - Status = ZwCreateKey(DeviceInterfaceKey, - DesiredAccess, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - NULL); + + /* now open device interface key */ + Status = ZwOpenKey(&hInterfaceKey, KEY_CREATE_SUB_KEY, &ObjectAttributes); + + if (NT_SUCCESS(Status)) + { + /* check if it provides a DeviceParameters key */ + InitializeObjectAttributes(&ObjectAttributes, &DevParamU, OBJ_CASE_INSENSITIVE, hInterfaceKey, NULL); + + Status = ZwCreateKey(DeviceInterfaceKey, DesiredAccess, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); + + if (NT_SUCCESS(Status)) + { + /* DeviceParameters key present */ + ZwClose(hInterfaceKey); + } + else + { + /* fall back to device interface */ + *DeviceInterfaceKey = hInterfaceKey; + Status = STATUS_SUCCESS; + } + } + + /* close class key */ + ZwClose(GuidKey); + ExFreePool(KeyInformation); return Status; } @@ -671,12 +661,6 @@ IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid, DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status); goto cleanup; } - /* RtlAppendUnicodeStringToString added a NULL at the end of the - * destination string, but didn't increase the Length field. - * Do it for it. - */ - ReturnBuffer.Length += sizeof(WCHAR); - NextReferenceString: ExFreePool(ReferenceBi); ReferenceBi = NULL; @@ -1071,6 +1055,7 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString); } SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0'; + SymbolicLinkName->Length += sizeof(WCHAR); /* Write symbolic link name in registry */ SymbolicLinkName->Buffer[1] = '\\'; diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c index ef1b78969fb..1ab54458526 100644 --- a/ntoskrnl/io/iomgr/driver.c +++ b/ntoskrnl/io/iomgr/driver.c @@ -34,6 +34,9 @@ POBJECT_TYPE IoDriverObjectType = NULL; extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN PnpSystemInit; +USHORT IopGroupIndex; +PLIST_ENTRY IopGroupTable; + /* PRIVATE FUNCTIONS **********************************************************/ NTSTATUS NTAPI @@ -197,6 +200,7 @@ IopDisplayLoadingMessage(PUNICODE_STRING ServiceName) UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS"); if (ExpInTextModeSetup) return; + if (!KeLoaderBlock) return; RtlUpcaseUnicodeString(ServiceName, ServiceName, FALSE); snprintf(TextBuffer, sizeof(TextBuffer), "%s%sSystem32\\Drivers\\%wZ%s\n", @@ -434,7 +438,6 @@ IopInitializeDriverModule( UNICODE_STRING RegistryKey; PDRIVER_INITIALIZE DriverEntry; PDRIVER_OBJECT Driver; - PDEVICE_OBJECT DeviceObject; NTSTATUS Status; DriverEntry = ModuleObject->EntryPoint; @@ -491,14 +494,7 @@ IopInitializeDriverModule( } /* Set the driver as initialized */ - Driver->Flags |= DRVO_INITIALIZED; - DeviceObject = Driver->DeviceObject; - while (DeviceObject) - { - /* Set every device as initialized too */ - DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - DeviceObject = DeviceObject->NextDevice; - } + IopReadyDeviceObjects(Driver); if (PnpSystemInit) IopReinitializeDrivers(); @@ -880,14 +876,17 @@ VOID FASTCALL IopInitializeBootDrivers(VOID) { - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY ListHead, NextEntry, NextEntry2; PLDR_DATA_TABLE_ENTRY LdrEntry; PDEVICE_NODE DeviceNode; PDRIVER_OBJECT DriverObject; LDR_DATA_TABLE_ENTRY ModuleObject; NTSTATUS Status; UNICODE_STRING DriverName; - + ULONG i, Index; + PDRIVER_INFORMATION DriverInfo, DriverInfoTag; + HANDLE KeyHandle; + PBOOT_DRIVER_LIST_ENTRY BootEntry; DPRINT("IopInitializeBootDrivers()\n"); /* Use IopRootDeviceNode for now */ @@ -931,6 +930,19 @@ IopInitializeBootDrivers(VOID) return; } + /* Get highest group order index */ + IopGroupIndex = PpInitGetGroupOrderIndex(NULL); + if (IopGroupIndex == 0xFFFF) ASSERT(FALSE); + + /* Allocate the group table */ + IopGroupTable = ExAllocatePoolWithTag(PagedPool, + IopGroupIndex * sizeof(LIST_ENTRY), + TAG_IO); + if (IopGroupTable == NULL) ASSERT(FALSE); + + /* Initialize the group table lists */ + for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]); + /* Loop the boot modules */ ListHead = &KeLoaderBlock->LoadOrderListHead; NextEntry = ListHead->Flink; @@ -940,19 +952,83 @@ IopInitializeBootDrivers(VOID) LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - - /* - * HACK: Make sure we're loading a driver - * (we should be using BootDriverListHead!) - */ - if (wcsstr(_wcsupr(LdrEntry->BaseDllName.Buffer), L".SYS")) + + /* Check if the DLL needs to be initialized */ + if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL) { - /* Make sure we didn't load this driver already */ - if (!(LdrEntry->Flags & LDRP_ENTRY_INSERTED)) + /* Call its entrypoint */ + MmCallDllInitialize(LdrEntry, NULL); + } + + /* Go to the next driver */ + NextEntry = NextEntry->Flink; + } + + /* Loop the boot drivers */ + ListHead = &KeLoaderBlock->BootDriverListHead; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + /* Get the entry */ + BootEntry = CONTAINING_RECORD(NextEntry, + BOOT_DRIVER_LIST_ENTRY, + Link); + + /* Get the driver loader entry */ + LdrEntry = BootEntry->LdrEntry; + + /* Allocate our internal accounting structure */ + DriverInfo = ExAllocatePoolWithTag(PagedPool, + sizeof(DRIVER_INFORMATION), + TAG_IO); + if (DriverInfo) + { + /* Zero it and initialize it */ + RtlZeroMemory(DriverInfo, sizeof(DRIVER_INFORMATION)); + InitializeListHead(&DriverInfo->Link); + DriverInfo->DataTableEntry = BootEntry; + + /* Open the registry key */ + Status = IopOpenRegistryKeyEx(&KeyHandle, + NULL, + &BootEntry->RegistryPath, + KEY_READ); + if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */ + ((KeLoaderBlock->SetupLdrBlock) && (KeyHandle = (PVOID)1))) { - DPRINT("Initializing bootdriver %wZ\n", &LdrEntry->BaseDllName); - /* Initialize it */ - IopInitializeBuiltinDriver(LdrEntry); + /* Save the handle */ + DriverInfo->ServiceHandle = KeyHandle; + + /* Get the group oder index */ + Index = PpInitGetGroupOrderIndex(KeyHandle); + + /* Get the tag position */ + DriverInfo->TagPosition = PipGetDriverTagPriority(KeyHandle); + + /* Insert it into the list, at the right place */ + ASSERT(Index < IopGroupIndex); + NextEntry2 = IopGroupTable[Index].Flink; + while (NextEntry2 != &IopGroupTable[Index]) + { + /* Get the driver info */ + DriverInfoTag = CONTAINING_RECORD(NextEntry2, + DRIVER_INFORMATION, + Link); + + /* Check if we found the right tag position */ + if (DriverInfoTag->TagPosition > DriverInfo->TagPosition) + { + /* We're done */ + break; + } + + /* Next entry */ + NextEntry2 = NextEntry2->Flink; + } + + /* Insert us right before the next entry */ + NextEntry2 = NextEntry2->Blink; + InsertHeadList(NextEntry2, &DriverInfo->Link); } } @@ -960,10 +1036,65 @@ IopInitializeBootDrivers(VOID) NextEntry = NextEntry->Flink; } + /* Loop each group index */ + for (i = 0; i < IopGroupIndex; i++) + { + /* Loop each group table */ + NextEntry = IopGroupTable[i].Flink; + while (NextEntry != &IopGroupTable[i]) + { + /* Get the entry */ + DriverInfo = CONTAINING_RECORD(NextEntry, + DRIVER_INFORMATION, + Link); + + /* Get the driver loader entry */ + LdrEntry = DriverInfo->DataTableEntry->LdrEntry; + + /* Initialize it */ + IopInitializeBuiltinDriver(LdrEntry); + + /* Next entry */ + NextEntry = NextEntry->Flink; + } + } + /* In old ROS, the loader list became empty after this point. Simulate. */ InitializeListHead(&KeLoaderBlock->LoadOrderListHead); } +VOID +FASTCALL +IopInitializeSystemDrivers(VOID) +{ + PUNICODE_STRING *DriverList, *SavedList; + + /* No system drivers on the boot cd */ + if (KeLoaderBlock->SetupLdrBlock) return; + + /* Get the driver list */ + SavedList = DriverList = CmGetSystemDriverList(); + ASSERT(DriverList); + + /* Loop it */ + while (*DriverList) + { + /* Load the driver */ + ZwLoadDriver(*DriverList); + + /* Free the entry */ + RtlFreeUnicodeString(*DriverList); + ExFreePool(*DriverList); + + /* Next entry */ + InbvIndicateProgress(); + DriverList++; + } + + /* Free the list */ + ExFreePool(SavedList); +} + /* * IopUnloadDriver * @@ -1685,6 +1816,8 @@ IopLoadUnloadDriver(PLOAD_UNLOAD_PARAMS LoadParams) cur--; } + IopDisplayLoadingMessage(&ServiceName); + /* * Get service type. */ diff --git a/ntoskrnl/io/iomgr/drvrlist.c b/ntoskrnl/io/iomgr/drvrlist.c deleted file mode 100644 index e15aab2a2cd..00000000000 --- a/ntoskrnl/io/iomgr/drvrlist.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/io/iomgr/drvrlist.c - * PURPOSE: Driver List support for Grouping, Tagging, Sorting, etc. - * PROGRAMMERS: - */ - -/* INCLUDES *******************************************************************/ - -#include -#define NDEBUG -#include - -typedef struct _SERVICE_GROUP -{ - LIST_ENTRY GroupListEntry; - UNICODE_STRING GroupName; - BOOLEAN ServicesRunning; - ULONG TagCount; - PULONG TagArray; -} SERVICE_GROUP, *PSERVICE_GROUP; - -typedef struct _SERVICE -{ - LIST_ENTRY ServiceListEntry; - UNICODE_STRING ServiceName; - UNICODE_STRING RegistryPath; - UNICODE_STRING ServiceGroup; - UNICODE_STRING ImagePath; - - ULONG Start; - ULONG Type; - ULONG ErrorControl; - ULONG Tag; - -/* BOOLEAN ServiceRunning;*/ // needed ?? -} SERVICE, *PSERVICE; - -#define TAG_RTLREGISTRY 'vrqR' - -/* GLOBALS ********************************************************************/ - -LIST_ENTRY GroupListHead = {NULL, NULL}; -LIST_ENTRY ServiceListHead = {NULL, NULL}; -extern BOOLEAN NoGuiBoot; - -VOID -FASTCALL -INIT_FUNCTION -IopDisplayLoadingMessage(PUNICODE_STRING ServiceName); - -/* PRIVATE FUNCTIONS **********************************************************/ - -static NTSTATUS NTAPI -IopGetGroupOrderList(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) -{ - PSERVICE_GROUP Group; - - DPRINT("IopGetGroupOrderList(%S, %x, 0x%p, %x, 0x%p, 0x%p)\n", - ValueName, ValueType, ValueData, ValueLength, Context, EntryContext); - - if (ValueType == REG_BINARY && - ValueData != NULL && - ValueLength >= sizeof(ULONG) && - ValueLength >= (*(PULONG)ValueData + 1) * sizeof(ULONG)) - { - Group = (PSERVICE_GROUP)Context; - Group->TagCount = ((PULONG)ValueData)[0]; - if (Group->TagCount > 0) - { - if (ValueLength >= (Group->TagCount + 1) * sizeof(ULONG)) - { - Group->TagArray = ExAllocatePool(NonPagedPool, Group->TagCount * sizeof(ULONG)); - if (Group->TagArray == NULL) - { - Group->TagCount = 0; - return STATUS_INSUFFICIENT_RESOURCES; - } - memcpy(Group->TagArray, (PULONG)ValueData + 1, Group->TagCount * sizeof(ULONG)); - } - else - { - Group->TagCount = 0; - return STATUS_UNSUCCESSFUL; - } - } - } - return STATUS_SUCCESS; -} - -static NTSTATUS NTAPI -IopCreateGroupListEntry(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) -{ - PSERVICE_GROUP Group; - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - NTSTATUS Status; - - - if (ValueType == REG_SZ) - { - DPRINT("GroupName: '%S'\n", (PWCHAR)ValueData); - - Group = ExAllocatePool(NonPagedPool, - sizeof(SERVICE_GROUP)); - if (Group == NULL) - { - return(STATUS_INSUFFICIENT_RESOURCES); - } - - RtlZeroMemory(Group, sizeof(SERVICE_GROUP)); - - if (!RtlCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData)) - { - ExFreePool(Group); - return(STATUS_INSUFFICIENT_RESOURCES); - } - - RtlZeroMemory(&QueryTable, sizeof(QueryTable)); - QueryTable[0].Name = (PWSTR)ValueData; - QueryTable[0].QueryRoutine = IopGetGroupOrderList; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, - L"GroupOrderList", - QueryTable, - (PVOID)Group, - NULL); - DPRINT("%x %d %S\n", Status, Group->TagCount, (PWSTR)ValueData); - - InsertTailList(&GroupListHead, - &Group->GroupListEntry); - } - - return(STATUS_SUCCESS); -} - - -static NTSTATUS NTAPI -IopCreateServiceListEntry(PUNICODE_STRING ServiceName) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[7]; - PSERVICE Service; - NTSTATUS Status; - ULONG DefaultTag = MAXULONG; - - DPRINT("ServiceName: '%wZ'\n", ServiceName); - - /* Allocate service entry */ - Service = (PSERVICE)ExAllocatePool(NonPagedPool, sizeof(SERVICE)); - if (Service == NULL) - { - DPRINT1("ExAllocatePool() failed\n"); - return(STATUS_INSUFFICIENT_RESOURCES); - } - RtlZeroMemory(Service, sizeof(SERVICE)); - - /* Get service data */ - RtlZeroMemory(&QueryTable, - sizeof(QueryTable)); - - QueryTable[0].Name = L"Start"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[0].EntryContext = &Service->Start; - - QueryTable[1].Name = L"Type"; - QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[1].EntryContext = &Service->Type; - - QueryTable[2].Name = L"ErrorControl"; - QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[2].EntryContext = &Service->ErrorControl; - - QueryTable[3].Name = L"Group"; - QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[3].EntryContext = &Service->ServiceGroup; - - QueryTable[4].Name = L"ImagePath"; - QueryTable[4].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[4].EntryContext = &Service->ImagePath; - - QueryTable[5].Name = L"Tag"; - QueryTable[5].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[5].EntryContext = &Service->Tag; - QueryTable[5].DefaultData = &DefaultTag; - QueryTable[5].DefaultType = REG_DWORD; - QueryTable[5].DefaultLength = sizeof(DefaultTag); - - Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, - ServiceName->Buffer, - QueryTable, - NULL, - NULL); - if (!NT_SUCCESS(Status) || Service->Start > 1) - { - /* - * If something goes wrong during RtlQueryRegistryValues - * it'll just drop everything on the floor and return, - * so you have to check if the buffers were filled. - * Luckily we zerofilled the Service. - */ - if (Service->ServiceGroup.Buffer) - { - ExFreePoolWithTag(Service->ServiceGroup.Buffer, TAG_RTLREGISTRY); - } - if (Service->ImagePath.Buffer) - { - ExFreePoolWithTag(Service->ImagePath.Buffer, TAG_RTLREGISTRY); - } - ExFreePool(Service); - return(Status); - } - - /* Copy service name */ - Service->ServiceName.Length = ServiceName->Length; - Service->ServiceName.MaximumLength = ServiceName->Length + sizeof(WCHAR); - Service->ServiceName.Buffer = ExAllocatePool(NonPagedPool, - Service->ServiceName.MaximumLength); - RtlCopyMemory(Service->ServiceName.Buffer, - ServiceName->Buffer, - ServiceName->Length); - Service->ServiceName.Buffer[ServiceName->Length / sizeof(WCHAR)] = 0; - - /* Build registry path */ - Service->RegistryPath.MaximumLength = MAX_PATH * sizeof(WCHAR); - Service->RegistryPath.Buffer = ExAllocatePool(NonPagedPool, - MAX_PATH * sizeof(WCHAR)); - wcscpy(Service->RegistryPath.Buffer, - L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); - wcscat(Service->RegistryPath.Buffer, - Service->ServiceName.Buffer); - Service->RegistryPath.Length = wcslen(Service->RegistryPath.Buffer) * sizeof(WCHAR); - - DPRINT("ServiceName: '%wZ'\n", &Service->ServiceName); - DPRINT("RegistryPath: '%wZ'\n", &Service->RegistryPath); - DPRINT("ServiceGroup: '%wZ'\n", &Service->ServiceGroup); - DPRINT("ImagePath: '%wZ'\n", &Service->ImagePath); - DPRINT("Start %lx Type %lx Tag %lx ErrorControl %lx\n", - Service->Start, Service->Type, Service->Tag, Service->ErrorControl); - - /* Append service entry */ - InsertTailList(&ServiceListHead, - &Service->ServiceListEntry); - - return(STATUS_SUCCESS); -} - - -NTSTATUS INIT_FUNCTION -IoCreateDriverList(VOID) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - PKEY_BASIC_INFORMATION KeyInfo = NULL; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services"); - UNICODE_STRING SubKeyName; - HANDLE KeyHandle; - NTSTATUS Status; - ULONG Index; - - ULONG KeyInfoLength = 0; - ULONG ReturnedLength; - - DPRINT("IoCreateDriverList() called\n"); - - /* Initialize basic variables */ - InitializeListHead(&GroupListHead); - InitializeListHead(&ServiceListHead); - - /* Build group order list */ - RtlZeroMemory(&QueryTable, - sizeof(QueryTable)); - - QueryTable[0].Name = L"List"; - QueryTable[0].QueryRoutine = IopCreateGroupListEntry; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, - L"ServiceGroupOrder", - QueryTable, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - return(Status); - - /* Enumerate services and create the service list */ - InitializeObjectAttributes(&ObjectAttributes, - &ServicesKeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwOpenKey(&KeyHandle, - KEY_ENUMERATE_SUB_KEYS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR); - KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength); - if (KeyInfo == NULL) - { - ZwClose(KeyHandle); - return(STATUS_INSUFFICIENT_RESOURCES); - } - - Index = 0; - while (TRUE) - { - Status = ZwEnumerateKey(KeyHandle, - Index, - KeyBasicInformation, - KeyInfo, - KeyInfoLength, - &ReturnedLength); - if (NT_SUCCESS(Status)) - { - if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR)) - { - - SubKeyName.Length = (USHORT)KeyInfo->NameLength; - SubKeyName.MaximumLength = (USHORT)KeyInfo->NameLength + sizeof(WCHAR); - SubKeyName.Buffer = KeyInfo->Name; - SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0; - - DPRINT("KeyName: '%wZ'\n", &SubKeyName); - IopCreateServiceListEntry(&SubKeyName); - } - } - - if (!NT_SUCCESS(Status)) - break; - - Index++; - } - - ExFreePool(KeyInfo); - ZwClose(KeyHandle); - - DPRINT("IoCreateDriverList() done\n"); - - return(STATUS_SUCCESS); -} - -NTSTATUS INIT_FUNCTION -IoDestroyDriverList(VOID) -{ - PSERVICE_GROUP CurrentGroup; - PSERVICE CurrentService; - PLIST_ENTRY NextEntry, TempEntry; - - DPRINT("IoDestroyDriverList() called\n"); - - /* Destroy the Group List */ - for (NextEntry = GroupListHead.Flink, TempEntry = NextEntry->Flink; - NextEntry != &GroupListHead; - NextEntry = TempEntry, TempEntry = NextEntry->Flink) - { - /* Get the entry */ - CurrentGroup = CONTAINING_RECORD(NextEntry, - SERVICE_GROUP, - GroupListEntry); - - /* Remove it from the list */ - RemoveEntryList(&CurrentGroup->GroupListEntry); - - /* Free buffers */ - ExFreePool(CurrentGroup->GroupName.Buffer); - if (CurrentGroup->TagArray) - ExFreePool(CurrentGroup->TagArray); - ExFreePool(CurrentGroup); - } - - /* Destroy the Service List */ - for (NextEntry = ServiceListHead.Flink, TempEntry = NextEntry->Flink; - NextEntry != &ServiceListHead; - NextEntry = TempEntry, TempEntry = NextEntry->Flink) - { - /* Get the entry */ - CurrentService = CONTAINING_RECORD(NextEntry, - SERVICE, - ServiceListEntry); - - /* Remove it from the list */ - RemoveEntryList(&CurrentService->ServiceListEntry); - - /* Free buffers */ - ExFreePool(CurrentService->ServiceName.Buffer); - ExFreePool(CurrentService->RegistryPath.Buffer); - if (CurrentService->ServiceGroup.Buffer) - ExFreePool(CurrentService->ServiceGroup.Buffer); - if (CurrentService->ImagePath.Buffer) - ExFreePool(CurrentService->ImagePath.Buffer); - ExFreePool(CurrentService); - } - - DPRINT("IoDestroyDriverList() done\n"); - - /* Return success */ - return STATUS_SUCCESS; -} - -static INIT_FUNCTION NTSTATUS -IopLoadDriver(PSERVICE Service) -{ - NTSTATUS Status = STATUS_UNSUCCESSFUL; - PUNICODE_STRING ImagePath = &Service->ImagePath; - PWCHAR ImageName; - UNICODE_STRING ImageNameU; - - ImageName = wcsrchr(ImagePath->Buffer, L'\\'); - if (!ImageName) - ImageName = ImagePath->Buffer; - else - ImageName++; - - RtlInitUnicodeString(&ImageNameU, ImageName); - - IopDisplayLoadingMessage(&ImageNameU); - - Status = ZwLoadDriver(&Service->RegistryPath); - IopBootLog(&Service->ImagePath, NT_SUCCESS(Status) ? TRUE : FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopLoadDriver() failed (Status %lx)\n", Status); -#if 0 - if (Service->ErrorControl == 1) - { - /* Log error */ - } - else if (Service->ErrorControl == 2) - { - if (IsLastKnownGood == FALSE) - { - /* Boot last known good configuration */ - } - } - else if (Service->ErrorControl == 3) - { - if (IsLastKnownGood == FALSE) - { - /* Boot last known good configuration */ - } - else - { - /* BSOD! */ - } - } -#endif - } - return Status; -} - -/* - * IopInitializeSystemDrivers - * - * Load drivers marked as system start. - * - * Parameters - * None - * - * Return Value - * None - */ -VOID -FASTCALL -IopInitializeSystemDrivers(VOID) -{ - PSERVICE_GROUP CurrentGroup; - PSERVICE CurrentService; - NTSTATUS Status; - ULONG i; - PLIST_ENTRY NextGroupEntry, NextServiceEntry; - - DPRINT("IopInitializeSystemDrivers()\n"); - - /* Start looping */ - for (NextGroupEntry = GroupListHead.Flink; - NextGroupEntry != &GroupListHead; - NextGroupEntry = NextGroupEntry->Flink) - { - /* Get the entry */ - CurrentGroup = CONTAINING_RECORD(NextGroupEntry, - SERVICE_GROUP, - GroupListEntry); - - DPRINT("Group: %wZ\n", &CurrentGroup->GroupName); - - /* Load all drivers with a valid tag */ - for (i = 0; i < CurrentGroup->TagCount; i++) - { - /* Start looping */ - for (NextServiceEntry = ServiceListHead.Flink; - NextServiceEntry != &ServiceListHead; - NextServiceEntry = NextServiceEntry->Flink) - { - /* Get the entry */ - CurrentService = CONTAINING_RECORD(NextServiceEntry, - SERVICE, - ServiceListEntry); - - if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName, - &CurrentService->ServiceGroup, - TRUE)) && - (CurrentService->Start == SERVICE_SYSTEM_START) && - (CurrentService->Tag == CurrentGroup->TagArray[i])) - - { - DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath); - Status = IopLoadDriver(CurrentService); - InbvIndicateProgress(); - } - } - } - - /* Load all drivers without a tag or with an invalid tag */ - for (NextServiceEntry = ServiceListHead.Flink; - NextServiceEntry != &ServiceListHead; - NextServiceEntry = NextServiceEntry->Flink) - { - /* Get the entry */ - CurrentService = CONTAINING_RECORD(NextServiceEntry, - SERVICE, - ServiceListEntry); - - if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName, - &CurrentService->ServiceGroup, - TRUE)) && - (CurrentService->Start == SERVICE_SYSTEM_START)) - { - for (i = 0; i < CurrentGroup->TagCount; i++) - { - if (CurrentGroup->TagArray[i] == CurrentService->Tag) - { - break; - } - } - - if (i >= CurrentGroup->TagCount) - { - DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath); - Status = IopLoadDriver(CurrentService); - InbvIndicateProgress(); - } - - } - } - } - - DPRINT("IopInitializeSystemDrivers() done\n"); -} diff --git a/ntoskrnl/io/iomgr/iomgr.c b/ntoskrnl/io/iomgr/iomgr.c index cb32297d25c..a0f16bb15a4 100644 --- a/ntoskrnl/io/iomgr/iomgr.c +++ b/ntoskrnl/io/iomgr/iomgr.c @@ -488,10 +488,7 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) if (!IopCreateRootDirectories()) return FALSE; /* Initialize PnP manager */ - PnpInit(); - - /* Create the group driver list */ - IoCreateDriverList(); + IopInitializePlugPlayServices(); /* Load boot start drivers */ IopInitializeBootDrivers(); @@ -530,9 +527,6 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) IopInitializeSystemDrivers(); PnpSystemInit = TRUE; - /* Destroy the group driver list */ - IoDestroyDriverList(); - /* Reinitialize drivers that requested it */ IopReinitializeDrivers(); diff --git a/ntoskrnl/io/pnpmgr/pnpinit.c b/ntoskrnl/io/pnpmgr/pnpinit.c new file mode 100644 index 00000000000..deced326832 --- /dev/null +++ b/ntoskrnl/io/pnpmgr/pnpinit.c @@ -0,0 +1,502 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/io/pnpmgr/pnpinit.c + * PURPOSE: PnP Initialization Code + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +typedef struct _IOPNP_DEVICE_EXTENSION +{ + PWCHAR CompatibleIdList; + ULONG CompatibleIdListSize; +} IOPNP_DEVICE_EXTENSION, *PIOPNP_DEVICE_EXTENSION; + +PUNICODE_STRING PiInitGroupOrderTable; +ULONG PiInitGroupOrderTableCount; +INTERFACE_TYPE PnpDefaultInterfaceType; + +/* FUNCTIONS ******************************************************************/ + +INTERFACE_TYPE +NTAPI +IopDetermineDefaultInterfaceType(VOID) +{ + /* FIXME: ReactOS doesn't support MicroChannel yet */ + return Isa; +} + +NTSTATUS +NTAPI +IopInitializeArbiters(VOID) +{ + /* FIXME: TODO */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PiInitCacheGroupInformation(VOID) +{ + HANDLE KeyHandle; + NTSTATUS Status; + PKEY_VALUE_FULL_INFORMATION KeyValueInformation; + PUNICODE_STRING GroupTable; + ULONG Count; + UNICODE_STRING GroupString = + RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet" + L"\\Control\\ServiceGroupOrder"); + + /* ReactOS HACK for SETUPLDR */ + if (KeLoaderBlock->SetupLdrBlock) + { + /* Bogus data */ + PiInitGroupOrderTableCount = 0; + PiInitGroupOrderTable = (PVOID)0xBABEB00B; + return STATUS_SUCCESS; + } + + /* Open the registry key */ + Status = IopOpenRegistryKeyEx(&KeyHandle, + NULL, + &GroupString, + KEY_READ); + if (NT_SUCCESS(Status)) + { + /* Get the list */ + Status = IopGetRegistryValue(KeyHandle, L"List", &KeyValueInformation); + ZwClose(KeyHandle); + + /* Make sure we got it */ + if (NT_SUCCESS(Status)) + { + /* Make sure it's valid */ + if ((KeyValueInformation->Type == REG_MULTI_SZ) && + (KeyValueInformation->DataLength)) + { + /* Convert it to unicode strings */ + Status = PnpRegMultiSzToUnicodeStrings(KeyValueInformation, + &GroupTable, + &Count); + + /* Cache it for later */ + PiInitGroupOrderTable = GroupTable; + PiInitGroupOrderTableCount = Count; + } + else + { + /* Fail */ + Status = STATUS_UNSUCCESSFUL; + } + + /* Free the information */ + ExFreePool(KeyValueInformation); + } + } + + /* Return status */ + return Status; +} + +USHORT +NTAPI +PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle) +{ + NTSTATUS Status; + PKEY_VALUE_FULL_INFORMATION KeyValueInformation; + ULONG i; + PVOID Buffer; + UNICODE_STRING Group; + PAGED_CODE(); + + /* Make sure we have a cache */ + if (!PiInitGroupOrderTable) return -1; + + /* If we don't have a handle, the rest is easy -- return the count */ + if (!ServiceHandle) return PiInitGroupOrderTableCount + 1; + + /* Otherwise, get the group value */ + Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation); + if (!NT_SUCCESS(Status)) return PiInitGroupOrderTableCount; + + /* Make sure we have a valid string */ + ASSERT(KeyValueInformation->Type == REG_SZ); + ASSERT(KeyValueInformation->DataLength); + + /* Convert to unicode string */ + Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset); + PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length); + Group.MaximumLength = KeyValueInformation->DataLength; + Group.Buffer = Buffer; + + /* Loop the groups */ + for (i = 0; i < PiInitGroupOrderTableCount; i++) + { + /* Try to find a match */ + if (RtlEqualUnicodeString(&Group, &PiInitGroupOrderTable[i], TRUE)) break; + } + + /* We're done */ + ExFreePool(KeyValueInformation); + return i; +} + +USHORT +NTAPI +PipGetDriverTagPriority(IN HANDLE ServiceHandle) +{ + NTSTATUS Status; + HANDLE KeyHandle = NULL; + PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL; + PKEY_VALUE_FULL_INFORMATION KeyValueInformationTag; + PKEY_VALUE_FULL_INFORMATION KeyValueInformationGroupOrderList; + PVOID Buffer; + UNICODE_STRING Group; + PULONG GroupOrder; + ULONG i = -1, Count, Tag = 0; + UNICODE_STRING GroupString = + RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet" + L"\\Control\\ServiceGroupOrder"); + + /* Open the key */ + Status = IopOpenRegistryKeyEx(&KeyHandle, NULL, &GroupString, KEY_READ); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Read the group */ + Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Make sure we have a group */ + if ((KeyValueInformation->Type == REG_SZ) && + (KeyValueInformation->DataLength)) + { + /* Convert to unicode string */ + Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset); + PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length); + Group.MaximumLength = KeyValueInformation->DataLength; + Group.Buffer = Buffer; + } + + /* Now read the tag */ + Status = IopGetRegistryValue(ServiceHandle, L"Tag", &KeyValueInformationTag); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Make sure we have a tag */ + if ((KeyValueInformationTag->Type == REG_DWORD) && + (KeyValueInformationTag->DataLength)) + { + /* Read it */ + Tag = *(PULONG)((ULONG_PTR)KeyValueInformationTag + + KeyValueInformationTag->DataOffset); + } + + /* We can get rid of this now */ + ExFreePool(KeyValueInformationTag); + + /* Now let's read the group's tag order */ + Status = IopGetRegistryValue(KeyHandle, + Group.Buffer, + &KeyValueInformationGroupOrderList); + + /* We can get rid of this now */ +Quickie: + if (KeyValueInformation) ExFreePool(KeyValueInformation); + if (KeyHandle) NtClose(KeyHandle); + if (!NT_SUCCESS(Status)) return -1; + + /* We're on the success path -- validate the tag order*/ + if ((KeyValueInformationGroupOrderList->Type == REG_BINARY) && + (KeyValueInformationGroupOrderList->DataLength)) + { + /* Get the order array */ + GroupOrder = (PULONG)((ULONG_PTR)KeyValueInformationGroupOrderList + + KeyValueInformationGroupOrderList->DataOffset); + + /* Get the count */ + Count = *GroupOrder; + ASSERT(((Count + 1) * sizeof(ULONG)) <= + KeyValueInformationGroupOrderList->DataLength); + + /* Now loop each tag */ + GroupOrder++; + for (i = 1; i <= Count; i++) + { + /* If we found it, we're out */ + if (Tag == *GroupOrder) break; + + /* Try the next one */ + GroupOrder++; + } + } + + /* Last buffer to free */ + ExFreePool(KeyValueInformationGroupOrderList); + return i; +} + +NTSTATUS +NTAPI +PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode, + IN BOOLEAN LoadDriver, + IN PDRIVER_OBJECT DriverObject) +{ + NTSTATUS Status; + HANDLE EnumRootKey, SubKey, ControlKey, ClassKey, PropertiesKey; + UNICODE_STRING ClassGuid, Properties; + UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT); + UNICODE_STRING ControlClass = + RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class"); + PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL; + PWCHAR Buffer; + + /* Open enumeration root key */ + Status = IopOpenRegistryKeyEx(&EnumRootKey, + NULL, + &EnumRoot, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); + return Status; + } + + /* Open instance subkey */ + Status = IopOpenRegistryKeyEx(&SubKey, + EnumRootKey, + &DeviceNode->InstancePath, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); + ZwClose(EnumRootKey); + return Status; + } + + /* Get class GUID */ + Status = IopGetRegistryValue(SubKey, + REGSTR_VAL_CLASSGUID, + &KeyValueInformation); + if (NT_SUCCESS(Status)) + { + /* Convert to unicode string */ + Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset); + PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &ClassGuid.Length); + ClassGuid.MaximumLength = KeyValueInformation->DataLength; + ClassGuid.Buffer = Buffer; + + /* Open the key */ + Status = IopOpenRegistryKeyEx(&ControlKey, + NULL, + &ControlClass, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + /* No class key */ + DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); + ClassKey = NULL; + } + else + { + /* Open the class key */ + Status = IopOpenRegistryKeyEx(&ClassKey, + ControlKey, + &ClassGuid, + KEY_READ); + ZwClose(ControlKey); + if (!NT_SUCCESS(Status)) + { + /* No class key */ + DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); + ClassKey = NULL; + } + } + + /* Check if we made it till here */ + if (ClassKey) + { + /* Get the device properties */ + RtlInitUnicodeString(&Properties, REGSTR_KEY_DEVICE_PROPERTIES); + Status = IopOpenRegistryKeyEx(&PropertiesKey, + ClassKey, + &Properties, + KEY_READ); + if (!NT_SUCCESS(Status)) + { + /* No properties */ + DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); + PropertiesKey = NULL; + } + } + + /* Free the registry data */ + ExFreePool(KeyValueInformation); + } + + /* Do ReactOS-style setup */ + IopAttachFilterDrivers(DeviceNode, TRUE); + Status = IopInitializeDevice(DeviceNode, DriverObject); + if (NT_SUCCESS(Status)) + { + IopAttachFilterDrivers(DeviceNode, FALSE); + Status = IopStartDevice(DeviceNode); + } + + /* Return status */ + return Status; +} + +NTSTATUS +NTAPI +IopInitializePlugPlayServices(VOID) +{ + NTSTATUS Status; + ULONG Disposition; + HANDLE KeyHandle, EnumHandle, ParentHandle, TreeHandle; + UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"); + PDEVICE_OBJECT Pdo; + + /* Initialize locks and such */ + KeInitializeSpinLock(&IopDeviceTreeLock); + + /* Get the default interface */ + PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType(); + + /* Initialize arbiters */ + Status = IopInitializeArbiters(); + if (!NT_SUCCESS(Status)) return Status; + + /* Setup the group cache */ + Status = PiInitCacheGroupInformation(); + if (!NT_SUCCESS(Status)) return Status; + + /* Open the current control set */ + Status = IopOpenRegistryKeyEx(&KeyHandle, + NULL, + &KeyName, + KEY_ALL_ACCESS); + if (!NT_SUCCESS(Status)) return Status; + + /* Create the enum key */ + RtlInitUnicodeString(&KeyName, REGSTR_KEY_ENUM); + Status = IopCreateRegistryKeyEx(&EnumHandle, + KeyHandle, + &KeyName, + KEY_ALL_ACCESS, + REG_OPTION_NON_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if it's a new key */ + if (Disposition == REG_CREATED_NEW_KEY) + { + /* FIXME: DACLs */ + DPRINT1("Need to build DACL\n"); + } + + /* Create the root key */ + ParentHandle = EnumHandle; + RtlInitUnicodeString(&KeyName, REGSTR_KEY_ROOTENUM); + Status = IopCreateRegistryKeyEx(&EnumHandle, + ParentHandle, + &KeyName, + KEY_ALL_ACCESS, + REG_OPTION_NON_VOLATILE, + &Disposition); + NtClose(ParentHandle); + if (!NT_SUCCESS(Status)) return Status; + NtClose(EnumHandle); + + /* Open the root key now */ + RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM"); + Status = IopOpenRegistryKeyEx(&EnumHandle, + NULL, + &KeyName, + KEY_ALL_ACCESS); + if (NT_SUCCESS(Status)) + { + /* Create the root dev node */ + RtlInitUnicodeString(&KeyName, REGSTR_VAL_ROOT_DEVNODE); + Status = IopCreateRegistryKeyEx(&TreeHandle, + EnumHandle, + &KeyName, + KEY_ALL_ACCESS, + REG_OPTION_NON_VOLATILE, + NULL); + NtClose(EnumHandle); + if (NT_SUCCESS(Status)) NtClose(TreeHandle); + } + + /* Create the root driver */ + Status = IoCreateDriver(NULL, PnpRootDriverEntry); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IoCreateDriverObject() failed\n"); + KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); + } + + /* Create the root PDO */ + Status = IoCreateDevice(IopRootDriverObject, + sizeof(IOPNP_DEVICE_EXTENSION), + NULL, + FILE_DEVICE_CONTROLLER, + 0, + FALSE, + &Pdo); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IoCreateDevice() failed\n"); + KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); + } + + /* This is a bus enumerated device */ + Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; + + /* Create the root device node */ + IopRootDeviceNode = PipAllocateDeviceNode(Pdo); + + /* Set flags */ + IopRootDeviceNode->Flags |= DNF_STARTED + DNF_PROCESSED + DNF_ENUMERATED + + DNF_MADEUP + DNF_NO_RESOURCE_REQUIRED + + DNF_ADDED; + + /* Create instance path */ + RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath, + REGSTR_VAL_ROOT_DEVNODE); + + /* Call the add device routine */ + IopRootDriverObject->DriverExtension->AddDevice(IopRootDriverObject, + IopRootDeviceNode->PhysicalDeviceObject); + + /* Initialize PnP-Event notification support */ + Status = IopInitPlugPlayEvents(); + if (!NT_SUCCESS(Status)) return Status; + + /* Report the device to the user-mode pnp manager */ + IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, + &IopRootDeviceNode->InstancePath); + + /* Initialize the Bus Type GUID List */ + PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST)); + RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST)); + ExInitializeFastMutex(&PnpBusTypeGuidList->Lock); + + /* Launch the firmware mapper */ + Status = IopUpdateRootKey(); + if (!NT_SUCCESS(Status)) return Status; + + /* Close the handle to the control set */ + NtClose(KeyHandle); + + /* We made it */ + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 44283968d0c..35c7447dc41 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -29,8 +29,7 @@ extern BOOLEAN PnpSystemInit; /* DATA **********************************************************************/ PDRIVER_OBJECT IopRootDriverObject; -FAST_MUTEX IopBusTypeGuidListLock; -PIO_BUS_TYPE_GUID_LIST IopBusTypeGuidList = NULL; +PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL; #if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, PnpInit) @@ -63,6 +62,7 @@ IopUpdateResourceMapForPnPDevice( NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, + IN ULONG CreateOptions, OUT PHANDLE Handle); PDEVICE_NODE @@ -138,6 +138,114 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, return STATUS_SUCCESS; } +VOID +NTAPI +IopStartDevice2(IN PDEVICE_OBJECT DeviceObject) +{ + IO_STACK_LOCATION Stack; + PDEVICE_NODE DeviceNode; + NTSTATUS Status; + PVOID Dummy; + + /* Get the device node */ + DeviceNode = IopGetDeviceNode(DeviceObject); + + /* Build the I/O stack locaiton */ + RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION)); + Stack.MajorFunction = IRP_MJ_PNP; + Stack.MinorFunction = IRP_MN_START_DEVICE; + + /* Check if we didn't already report the resources */ + // if (!DeviceNode->Flags & DNF_RESOURCE_REPORTED) + { + /* Report them */ + if (DeviceNode->Flags & DNF_RESOURCE_REPORTED) + { + DPRINT1("Warning: Setting resource pointers even though DNF_RESOURCE_REPORTED is set\n"); + } + Stack.Parameters.StartDevice.AllocatedResources = + DeviceNode->ResourceList; + Stack.Parameters.StartDevice.AllocatedResourcesTranslated = + DeviceNode->ResourceListTranslated; + } + + /* I don't think we set this flag yet */ + ASSERT(!(DeviceNode->Flags & DNF_STOPPED)); + + /* Do the call */ + Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy); + if (!NT_SUCCESS(Status)) + { + /* FIXME: TODO */ + DPRINT1("Warning: PnP Start failed\n"); + //ASSERT(FALSE); + return; + } + + /* Otherwise, mark us as started */ + DeviceNode->Flags |= DNF_STARTED; + + /* We now need enumeration */ + DeviceNode->Flags |= DNF_NEED_ENUMERATION_ONLY; +} + +NTSTATUS +NTAPI +IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode) +{ + PDEVICE_OBJECT DeviceObject; + NTSTATUS Status; + PAGED_CODE(); + + /* Sanity check */ + // ASSERT((DeviceNode->Flags & DNF_ADDED)); + if (!(DeviceNode->Flags & DNF_ADDED)) DPRINT1("Warning: Starting a device node without DNF_ADDED\n"); + ASSERT((DeviceNode->Flags & (DNF_RESOURCE_ASSIGNED | + DNF_RESOURCE_REPORTED | + DNF_NO_RESOURCE_REQUIRED | + DNF_NO_RESOURCE_REQUIRED))); + ASSERT((!(DeviceNode->Flags & (DNF_HAS_PROBLEM | + DNF_STARTED | + DNF_START_REQUEST_PENDING)))); + + /* Get the device object */ + DeviceObject = DeviceNode->PhysicalDeviceObject; + + /* Check if we're not started yet */ + //if (!DeviceNode->Flags & DNF_STARTED) + { + /* Start us */ + IopStartDevice2(DeviceObject); + } + + /* Do we need to query IDs? This happens in the case of manual reporting */ + //if (DeviceNode->Flags & DNF_NEED_QUERY_IDS) + //{ + // DPRINT1("Warning: Device node has DNF_NEED_QUERY_IDS\n"); + /* And that case shouldn't happen yet */ + // ASSERT(FALSE); + //} + + /* Make sure we're started, and check if we need enumeration */ + if ((DeviceNode->Flags & DNF_STARTED) && + (DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY)) + { + /* Enumerate us */ + //Status = IopEnumerateDevice(DeviceObject); + IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations); + IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY); + Status = STATUS_SUCCESS; + } + else + { + /* Nothing to do */ + Status = STATUS_SUCCESS; + } + + /* Return */ + return Status; +} + NTSTATUS IopStartDevice( PDEVICE_NODE DeviceNode) @@ -146,7 +254,7 @@ IopStartDevice( IO_STACK_LOCATION Stack; ULONG RequiredLength; NTSTATUS Status; - HANDLE InstanceHandle, ControlHandle; + HANDLE InstanceHandle = INVALID_HANDLE_VALUE, ControlHandle = INVALID_HANDLE_VALUE; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; @@ -161,9 +269,13 @@ IopStartDevice( if (!NT_SUCCESS(Status) && Status != STATUS_NOT_SUPPORTED) { DPRINT("IopInitiatePnpIrp(IRP_MN_FILTER_RESOURCE_REQUIREMENTS) failed\n"); + IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); return Status; } - DeviceNode->ResourceRequirements = (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information; + else if (NT_SUCCESS(Status)) + { + DeviceNode->ResourceRequirements = (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information; + } Status = IopAssignDeviceResources(DeviceNode, &RequiredLength); if (NT_SUCCESS(Status)) @@ -188,45 +300,19 @@ IopStartDevice( } IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); - DPRINT("Sending IRP_MN_START_DEVICE to driver\n"); - Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList; - Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated; - - /* - * Windows NT Drivers receive IRP_MN_START_DEVICE in a critical region and - * actually _depend_ on this!. This is because NT will lock the Device Node - * with an ERESOURCE, which of course requires APCs to be disabled. - */ - KeEnterCriticalRegion(); - - Status = IopInitiatePnpIrp( - DeviceNode->PhysicalDeviceObject, - &IoStatusBlock, - IRP_MN_START_DEVICE, - &Stack); - - KeLeaveCriticalRegion(); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitiatePnpIrp() failed\n"); - } - else - { - if (IopDeviceNodeHasFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY)) - { - DPRINT("Device needs enumeration, invalidating bus relations\n"); - /* Invalidate device relations synchronously - (otherwise there will be dirty read of DeviceNode) */ - IopEnumerateDevice(DeviceNode->PhysicalDeviceObject); - IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY); - } - } + goto ByeBye; - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceHandle); + /* New PnP ABI */ + IopStartAndEnumerateDevice(DeviceNode); + + /* FIX: Should be done in new device instance code */ + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceHandle); if (!NT_SUCCESS(Status)) - return Status; + goto ByeBye; + /* FIX: Should be done in IoXxxPrepareDriverLoading */ + // { RtlInitUnicodeString(&KeyName, L"Control"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, @@ -235,19 +321,31 @@ IopStartDevice( NULL); Status = ZwCreateKey(&ControlHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); if (!NT_SUCCESS(Status)) - { - ZwClose(InstanceHandle); - return Status; - } + goto ByeBye; RtlInitUnicodeString(&KeyName, L"ActiveService"); Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_SZ, DeviceNode->ServiceName.Buffer, DeviceNode->ServiceName.Length); + // } + + /* FIX: Should be done somewhere in resoure code? */ + if (NT_SUCCESS(Status) && DeviceNode->ResourceList) + { + RtlInitUnicodeString(&KeyName, L"AllocConfig"); + Status = ZwSetValueKey(ControlHandle, &KeyName, 0, REG_RESOURCE_LIST, + DeviceNode->ResourceList, CM_RESOURCE_LIST_SIZE(DeviceNode->ResourceList)); + } +ByeBye: if (NT_SUCCESS(Status)) IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); + else + IopDeviceNodeSetFlag(DeviceNode, DNF_START_FAILED); - ZwClose(ControlHandle); - ZwClose(InstanceHandle); + if (ControlHandle != INVALID_HANDLE_VALUE) + ZwClose(ControlHandle); + + if (InstanceHandle != INVALID_HANDLE_VALUE) + ZwClose(InstanceHandle); return Status; } @@ -320,14 +418,14 @@ IopGetBusTypeGuidIndex(LPGUID BusTypeGuid) PVOID NewList; /* Acquire the lock */ - ExAcquireFastMutex(&IopBusTypeGuidListLock); + ExAcquireFastMutex(&PnpBusTypeGuidList->Lock); /* Loop all entries */ - while (i < IopBusTypeGuidList->GuidCount) + while (i < PnpBusTypeGuidList->GuidCount) { /* Try to find a match */ if (RtlCompareMemory(BusTypeGuid, - &IopBusTypeGuidList->Guids[i], + &PnpBusTypeGuidList->Guids[i], sizeof(GUID)) == sizeof(GUID)) { /* Found it */ @@ -338,43 +436,43 @@ IopGetBusTypeGuidIndex(LPGUID BusTypeGuid) } /* Check if we have to grow the list */ - if (IopBusTypeGuidList->GuidCount) + if (PnpBusTypeGuidList->GuidCount) { /* Calculate the new size */ NewSize = sizeof(IO_BUS_TYPE_GUID_LIST) + - (sizeof(GUID) * IopBusTypeGuidList->GuidCount); + (sizeof(GUID) * PnpBusTypeGuidList->GuidCount); /* Allocate the new copy */ NewList = ExAllocatePool(PagedPool, NewSize); if (!NewList) { /* Fail */ - ExFreePool(IopBusTypeGuidList); + ExFreePool(PnpBusTypeGuidList); goto Quickie; } /* Now copy them, decrease the size too */ NewSize -= sizeof(GUID); - RtlCopyMemory(NewList, IopBusTypeGuidList, NewSize); + RtlCopyMemory(NewList, PnpBusTypeGuidList, NewSize); /* Free the old list */ - ExFreePool(IopBusTypeGuidList); + ExFreePool(PnpBusTypeGuidList); /* Use the new buffer */ - IopBusTypeGuidList = NewList; + PnpBusTypeGuidList = NewList; } /* Copy the new GUID */ - RtlCopyMemory(&IopBusTypeGuidList->Guids[IopBusTypeGuidList->GuidCount], + RtlCopyMemory(&PnpBusTypeGuidList->Guids[PnpBusTypeGuidList->GuidCount], BusTypeGuid, sizeof(GUID)); /* The new entry is the index */ - FoundIndex = (USHORT)IopBusTypeGuidList->GuidCount; - IopBusTypeGuidList->GuidCount++; + FoundIndex = (USHORT)PnpBusTypeGuidList->GuidCount; + PnpBusTypeGuidList->GuidCount++; Quickie: - ExReleaseFastMutex(&IopBusTypeGuidListLock); + ExReleaseFastMutex(&PnpBusTypeGuidList->Lock); return FoundIndex; } @@ -404,7 +502,13 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, UNICODE_STRING FullServiceName; UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_"); UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN"); - HANDLE TempHandle; + UNICODE_STRING KeyName, ClassName; + PUNICODE_STRING ServiceName1; + ULONG LegacyValue; +#if 0 + UNICODE_STRING ClassGUID; +#endif + HANDLE InstanceHandle; DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n", ParentNode, PhysicalDeviceObject, ServiceName); @@ -418,11 +522,13 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, RtlZeroMemory(Node, sizeof(DEVICE_NODE)); if (!ServiceName) - ServiceName = &UnknownDeviceName; + ServiceName1 = &UnknownDeviceName; + else + ServiceName1 = ServiceName; if (!PhysicalDeviceObject) { - FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName->Length; + FullServiceName.MaximumLength = LegacyPrefix.Length + ServiceName1->Length; FullServiceName.Length = 0; FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); if (!FullServiceName.Buffer) @@ -432,7 +538,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, } RtlAppendUnicodeStringToString(&FullServiceName, &LegacyPrefix); - RtlAppendUnicodeStringToString(&FullServiceName, ServiceName); + RtlAppendUnicodeStringToString(&FullServiceName, ServiceName1); Status = PnpRootCreateDevice(&FullServiceName, &PhysicalDeviceObject, &Node->InstancePath); if (!NT_SUCCESS(Status)) @@ -443,14 +549,69 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, } /* Create the device key for legacy drivers */ - Status = IopCreateDeviceKeyPath(&Node->InstancePath, &TempHandle); - if (NT_SUCCESS(Status)) - ZwClose(TempHandle); + Status = IopCreateDeviceKeyPath(&Node->InstancePath, REG_OPTION_VOLATILE, &InstanceHandle); + if (!NT_SUCCESS(Status)) + { + ZwClose(InstanceHandle); + ExFreePool(Node); + ExFreePool(FullServiceName.Buffer); + return Status; + } + Node->ServiceName.Buffer = ExAllocatePool(PagedPool, ServiceName1->Length); + if (!Node->ServiceName.Buffer) + { + ZwClose(InstanceHandle); + ExFreePool(Node); + ExFreePool(FullServiceName.Buffer); + return Status; + } + + Node->ServiceName.MaximumLength = ServiceName1->Length; + Node->ServiceName.Length = 0; + + RtlAppendUnicodeStringToString(&Node->ServiceName, ServiceName1); + + if (ServiceName) + { + RtlInitUnicodeString(&KeyName, L"Service"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName->Buffer, ServiceName->Length); + } + + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&KeyName, L"Legacy"); + + LegacyValue = 1; + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_DWORD, &LegacyValue, sizeof(LegacyValue)); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&KeyName, L"Class"); + + RtlInitUnicodeString(&ClassName, L"LegacyDriver"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length); +#if 0 + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString(&KeyName, L"ClassGUID"); + + RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}"); + Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length); + } +#endif + } + } + + ZwClose(InstanceHandle); ExFreePool(FullServiceName.Buffer); + if (!NT_SUCCESS(Status)) + { + ExFreePool(Node); + return Status; + } + /* This is for drivers passed on the command line to ntoskrnl.exe */ - IopDeviceNodeSetFlag(Node, DNF_STARTED); IopDeviceNodeSetFlag(Node, DNF_LEGACY_DRIVER); } @@ -549,69 +710,90 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode) } NTSTATUS -IopInitiatePnpIrp(PDEVICE_OBJECT DeviceObject, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG MinorFunction, - PIO_STACK_LOCATION Stack OPTIONAL) +NTAPI +IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject, + IN PIO_STACK_LOCATION IoStackLocation, + OUT PVOID *Information) { - PDEVICE_OBJECT TopDeviceObject; - PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; - KEVENT Event; - PIRP Irp; - - /* Always call the top of the device stack */ - TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject); - - KeInitializeEvent( - &Event, - NotificationEvent, - FALSE); - - Irp = IoBuildSynchronousFsdRequest( - IRP_MJ_PNP, - TopDeviceObject, - NULL, - 0, - NULL, - &Event, - IoStatusBlock); - - /* PNP IRPs are initialized with a status code of STATUS_NOT_SUPPORTED */ - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - Irp->IoStatus.Information = 0; - - if (MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS) - { - Irp->IoStatus.Information = (ULONG_PTR)Stack->Parameters.FilterResourceRequirements.IoResourceRequirementList; - } - - IrpSp = IoGetNextIrpStackLocation(Irp); - IrpSp->MinorFunction = (UCHAR)MinorFunction; - - if (Stack) - { - RtlCopyMemory(&IrpSp->Parameters, - &Stack->Parameters, - sizeof(Stack->Parameters)); - } - - Status = IoCallDriver(TopDeviceObject, Irp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - Status = IoStatusBlock->Status; - } - - ObDereferenceObject(TopDeviceObject); - - return Status; + PIRP Irp; + PIO_STACK_LOCATION IrpStack; + IO_STATUS_BLOCK IoStatusBlock; + KEVENT Event; + NTSTATUS Status; + PDEVICE_OBJECT TopDeviceObject; + PAGED_CODE(); + + /* Call the top of the device stack */ + TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject); + + /* Allocate an IRP */ + Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE); + if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; + + /* Initialize to failure */ + Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Information = IoStatusBlock.Information = 0; + + /* Initialize the event */ + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + + /* Set them up */ + Irp->UserIosb = &IoStatusBlock; + Irp->UserEvent = &Event; + + /* Queue the IRP */ + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + IoQueueThreadIrp(Irp); + + /* Copy-in the stack */ + IrpStack = IoGetNextIrpStackLocation(Irp); + *IrpStack = *IoStackLocation; + + /* Call the driver */ + Status = IoCallDriver(TopDeviceObject, Irp); + if (Status == STATUS_PENDING) + { + /* Wait for it */ + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = IoStatusBlock.Status; + } + + /* Return the information */ + *Information = (PVOID)IoStatusBlock.Information; + return Status; } +NTSTATUS +NTAPI +IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject, + IN OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG MinorFunction, + IN PIO_STACK_LOCATION Stack OPTIONAL) +{ + IO_STACK_LOCATION IoStackLocation; + + /* Fill out the stack information */ + RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION)); + IoStackLocation.MajorFunction = IRP_MJ_PNP; + IoStackLocation.MinorFunction = MinorFunction; + if (Stack) + { + /* Copy the rest */ + RtlCopyMemory(&IoStackLocation.Parameters, + &Stack->Parameters, + sizeof(Stack->Parameters)); + } + + /* Do the PnP call */ + IoStatusBlock->Status = IopSynchronousCall(DeviceObject, + &IoStackLocation, + (PVOID)&IoStatusBlock->Information); + return IoStatusBlock->Status; +} NTSTATUS IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context) @@ -693,6 +875,7 @@ IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context) NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, + IN ULONG CreateOptions, OUT PHANDLE Handle) { UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT); @@ -743,7 +926,7 @@ IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, &ObjectAttributes, 0, NULL, - 0, + CreateOptions, NULL); /* Close parent key handle, we don't need it anymore */ @@ -1005,137 +1188,183 @@ IopSetDeviceInstanceData(HANDLE InstanceKey, } BOOLEAN -IopCheckForResourceConflict( - IN PCM_RESOURCE_LIST ResourceList1, - IN PCM_RESOURCE_LIST ResourceList2) +IopCheckResourceDescriptor( + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc, + IN PCM_RESOURCE_LIST ResourceList, + IN BOOLEAN Silent, + OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) { - ULONG i1, i2, ii1, ii2; + ULONG i, ii; BOOLEAN Result = FALSE; - for (i1 = 0; i1 < ResourceList1->Count; i1++) + if (ResDesc->ShareDisposition == CmResourceShareShared) + return FALSE; + + for (i = 0; i < ResourceList->Count; i++) { - PCM_PARTIAL_RESOURCE_LIST ResList1 = &ResourceList1->List[i1].PartialResourceList; - for (i2 = 0; i2 < ResourceList2->Count; i2++) + PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList->List[i].PartialResourceList; + for (ii = 0; ii < ResList->Count; ii++) { - PCM_PARTIAL_RESOURCE_LIST ResList2 = &ResourceList2->List[i2].PartialResourceList; - for (ii1 = 0; ii1 < ResList1->Count; ii1++) + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 = &ResList->PartialDescriptors[ii]; + + /* We don't care about shared resources */ + if (ResDesc->ShareDisposition == CmResourceShareShared && + ResDesc2->ShareDisposition == CmResourceShareShared) + continue; + + /* Make sure we're comparing the same types */ + if (ResDesc->Type != ResDesc2->Type) + continue; + + switch (ResDesc->Type) { - PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc1 = &ResList1->PartialDescriptors[ii1]; - - if (ResDesc1->ShareDisposition == CmResourceShareShared) - continue; - - for (ii2 = 0; ii2 < ResList2->Count; ii2++) - { - PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc2 = &ResList2->PartialDescriptors[ii2]; - - /* We don't care about shared resources */ - if (ResDesc2->ShareDisposition == CmResourceShareShared) - continue; - - /* Make sure we're comparing the same types */ - if (ResDesc1->Type != ResDesc2->Type) - continue; - - switch (ResDesc1->Type) - { - case CmResourceTypeMemory: - if ((ResDesc1->u.Memory.Start.QuadPart < ResDesc2->u.Memory.Start.QuadPart && - ResDesc1->u.Memory.Start.QuadPart + ResDesc1->u.Memory.Length > - ResDesc2->u.Memory.Start.QuadPart) || (ResDesc2->u.Memory.Start.QuadPart < - ResDesc1->u.Memory.Start.QuadPart && ResDesc2->u.Memory.Start.QuadPart + - ResDesc2->u.Memory.Length > ResDesc1->u.Memory.Start.QuadPart)) + case CmResourceTypeMemory: + if ((ResDesc->u.Memory.Start.QuadPart < ResDesc2->u.Memory.Start.QuadPart && + ResDesc->u.Memory.Start.QuadPart + ResDesc->u.Memory.Length > + ResDesc2->u.Memory.Start.QuadPart) || (ResDesc2->u.Memory.Start.QuadPart < + ResDesc->u.Memory.Start.QuadPart && ResDesc2->u.Memory.Start.QuadPart + + ResDesc2->u.Memory.Length > ResDesc->u.Memory.Start.QuadPart)) + { + if (!Silent) { DPRINT1("Resource conflict: Memory (0x%x to 0x%x vs. 0x%x to 0x%x)\n", - ResDesc1->u.Memory.Start.QuadPart, ResDesc1->u.Memory.Start.QuadPart + - ResDesc1->u.Memory.Length, ResDesc2->u.Memory.Start.QuadPart, + ResDesc->u.Memory.Start.QuadPart, ResDesc->u.Memory.Start.QuadPart + + ResDesc->u.Memory.Length, ResDesc2->u.Memory.Start.QuadPart, ResDesc2->u.Memory.Start.QuadPart + ResDesc2->u.Memory.Length); - - Result = TRUE; - - goto ByeBye; } - break; - case CmResourceTypePort: - if ((ResDesc1->u.Port.Start.QuadPart < ResDesc2->u.Port.Start.QuadPart && - ResDesc1->u.Port.Start.QuadPart + ResDesc1->u.Port.Length > - ResDesc2->u.Port.Start.QuadPart) || (ResDesc2->u.Port.Start.QuadPart < - ResDesc1->u.Port.Start.QuadPart && ResDesc2->u.Port.Start.QuadPart + - ResDesc2->u.Port.Length > ResDesc1->u.Port.Start.QuadPart)) + Result = TRUE; + + goto ByeBye; + } + break; + + case CmResourceTypePort: + if ((ResDesc->u.Port.Start.QuadPart < ResDesc2->u.Port.Start.QuadPart && + ResDesc->u.Port.Start.QuadPart + ResDesc->u.Port.Length > + ResDesc2->u.Port.Start.QuadPart) || (ResDesc2->u.Port.Start.QuadPart < + ResDesc->u.Port.Start.QuadPart && ResDesc2->u.Port.Start.QuadPart + + ResDesc2->u.Port.Length > ResDesc->u.Port.Start.QuadPart)) + { + if (!Silent) { DPRINT1("Resource conflict: Port (0x%x to 0x%x vs. 0x%x to 0x%x)\n", - ResDesc1->u.Port.Start.QuadPart, ResDesc1->u.Port.Start.QuadPart + - ResDesc1->u.Port.Length, ResDesc2->u.Port.Start.QuadPart, + ResDesc->u.Port.Start.QuadPart, ResDesc->u.Port.Start.QuadPart + + ResDesc->u.Port.Length, ResDesc2->u.Port.Start.QuadPart, ResDesc2->u.Port.Start.QuadPart + ResDesc2->u.Port.Length); - - Result = TRUE; - - goto ByeBye; } - break; - case CmResourceTypeInterrupt: - if (ResDesc1->u.Interrupt.Vector == ResDesc2->u.Interrupt.Vector) + Result = TRUE; + + goto ByeBye; + } + break; + + case CmResourceTypeInterrupt: + if (ResDesc->u.Interrupt.Vector == ResDesc2->u.Interrupt.Vector) + { + if (!Silent) { - DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x 0x%x)\n", - ResDesc1->u.Interrupt.Vector, ResDesc1->u.Interrupt.Level, - ResDesc2->u.Interrupt.Vector, ResDesc2->u.Interrupt.Level); - - Result = TRUE; - - goto ByeBye; + DPRINT1("Resource conflict: IRQ (0x%x 0x%x vs. 0x%x 0x%x)\n", + ResDesc->u.Interrupt.Vector, ResDesc->u.Interrupt.Level, + ResDesc2->u.Interrupt.Vector, ResDesc2->u.Interrupt.Level); } - break; - case CmResourceTypeBusNumber: - if ((ResDesc1->u.BusNumber.Start < ResDesc2->u.BusNumber.Start && - ResDesc1->u.BusNumber.Start + ResDesc1->u.BusNumber.Length > - ResDesc2->u.BusNumber.Start) || (ResDesc2->u.BusNumber.Start < - ResDesc1->u.BusNumber.Start && ResDesc2->u.BusNumber.Start + - ResDesc2->u.BusNumber.Length > ResDesc1->u.BusNumber.Start)) + Result = TRUE; + + goto ByeBye; + } + break; + + case CmResourceTypeBusNumber: + if ((ResDesc->u.BusNumber.Start < ResDesc2->u.BusNumber.Start && + ResDesc->u.BusNumber.Start + ResDesc->u.BusNumber.Length > + ResDesc2->u.BusNumber.Start) || (ResDesc2->u.BusNumber.Start < + ResDesc->u.BusNumber.Start && ResDesc2->u.BusNumber.Start + + ResDesc2->u.BusNumber.Length > ResDesc->u.BusNumber.Start)) + { + if (!Silent) { - DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs. 0x%x to 0x%x)\n", - ResDesc1->u.BusNumber.Start, ResDesc1->u.BusNumber.Start + - ResDesc1->u.BusNumber.Length, ResDesc2->u.BusNumber.Start, + DPRINT1("Resource conflict: Bus number (0x%x to 0x%x vs. 0x%x to 0x%x)\n", + ResDesc->u.BusNumber.Start, ResDesc->u.BusNumber.Start + + ResDesc->u.BusNumber.Length, ResDesc2->u.BusNumber.Start, ResDesc2->u.BusNumber.Start + ResDesc2->u.BusNumber.Length); - - Result = TRUE; - - goto ByeBye; } - break; - case CmResourceTypeDma: - if (ResDesc1->u.Dma.Channel == ResDesc2->u.Dma.Channel) - { + Result = TRUE; + + goto ByeBye; + } + break; + + case CmResourceTypeDma: + if (ResDesc->u.Dma.Channel == ResDesc2->u.Dma.Channel) + { + if (!Silent) + { DPRINT1("Resource conflict: Dma (0x%x 0x%x vs. 0x%x 0x%x)\n", - ResDesc1->u.Dma.Channel, ResDesc1->u.Dma.Port, + ResDesc->u.Dma.Channel, ResDesc->u.Dma.Port, ResDesc2->u.Dma.Channel, ResDesc2->u.Dma.Port); + } - Result = TRUE; + Result = TRUE; - goto ByeBye; - } - break; - } - } + goto ByeBye; + } + break; } } } ByeBye: -#ifdef ENABLE_RESOURCE_CONFLICT_DETECTION + if (Result && ConflictingDescriptor) + { + RtlCopyMemory(ConflictingDescriptor, + ResDesc, + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + } + + return Result; +} + + +BOOLEAN +IopCheckForResourceConflict( + IN PCM_RESOURCE_LIST ResourceList1, + IN PCM_RESOURCE_LIST ResourceList2, + IN BOOLEAN Silent, + OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) +{ + ULONG i, ii; + BOOLEAN Result = FALSE; + + for (i = 0; i < ResourceList1->Count; i++) + { + PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList1->List[i].PartialResourceList; + for (ii = 0; ii < ResList->Count; ii++) + { + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc = &ResList->PartialDescriptors[ii]; + + Result = IopCheckResourceDescriptor(ResDesc, + ResourceList2, + Silent, + ConflictingDescriptor); + if (Result) goto ByeBye; + } + } + + +ByeBye: + return Result; -#else - return FALSE; -#endif } NTSTATUS IopDetectResourceConflict( - IN PCM_RESOURCE_LIST ResourceList) + IN PCM_RESOURCE_LIST ResourceList, + IN BOOLEAN Silent, + OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; @@ -1321,7 +1550,9 @@ IopDetectResourceConflict( ExFreePool(KeyNameInformation); if (IopCheckForResourceConflict(ResourceList, - (PCM_RESOURCE_LIST)KeyValueInformation->Data)) + (PCM_RESOURCE_LIST)KeyValueInformation->Data, + Silent, + ConflictingDescriptor)) { ExFreePool(KeyValueInformation); Status = STATUS_CONFLICTING_ADDRESSES; @@ -1346,19 +1577,311 @@ cleanup: return Status; } - + +BOOLEAN +IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) +{ + CM_RESOURCE_LIST CmList; + NTSTATUS Status; + + CmList.Count = 1; + CmList.List[0].InterfaceType = InterfaceTypeUndefined; + CmList.List[0].BusNumber = 0; + CmList.List[0].PartialResourceList.Version = 1; + CmList.List[0].PartialResourceList.Revision = 1; + CmList.List[0].PartialResourceList.Count = 1; + CmList.List[0].PartialResourceList.PartialDescriptors[0] = *CmDesc; + + Status = IopDetectResourceConflict(&CmList, TRUE, ConflictingDescriptor); + if (Status == STATUS_CONFLICTING_ADDRESSES) + return TRUE; + + return FALSE; +} + +BOOLEAN +IopFindBusNumberResource( + IN PIO_RESOURCE_DESCRIPTOR IoDesc, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc) +{ + ULONG Start; + CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc; + + ASSERT(IoDesc->Type == CmDesc->Type); + ASSERT(IoDesc->Type == CmResourceTypeBusNumber); + + for (Start = IoDesc->u.BusNumber.MinBusNumber; + Start < IoDesc->u.BusNumber.MaxBusNumber; + Start++) + { + CmDesc->u.BusNumber.Length = IoDesc->u.BusNumber.Length; + CmDesc->u.BusNumber.Start = Start; + + if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc)) + { + Start += ConflictingDesc.u.BusNumber.Start + ConflictingDesc.u.BusNumber.Length; + } + else + { + return TRUE; + } + } + + return FALSE; +} + +BOOLEAN +IopFindMemoryResource( + IN PIO_RESOURCE_DESCRIPTOR IoDesc, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc) +{ + ULONGLONG Start; + CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc; + + ASSERT(IoDesc->Type == CmDesc->Type); + ASSERT(IoDesc->Type == CmResourceTypeMemory); + + for (Start = IoDesc->u.Memory.MinimumAddress.QuadPart; + Start < IoDesc->u.Memory.MaximumAddress.QuadPart; + Start++) + { + CmDesc->u.Memory.Length = IoDesc->u.Memory.Length; + CmDesc->u.Memory.Start.QuadPart = Start; + + if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc)) + { + Start += ConflictingDesc.u.Memory.Start.QuadPart + ConflictingDesc.u.Memory.Length; + } + else + { + return TRUE; + } + } + + return FALSE; +} + +BOOLEAN +IopFindPortResource( + IN PIO_RESOURCE_DESCRIPTOR IoDesc, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc) +{ + ULONGLONG Start; + CM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDesc; + + ASSERT(IoDesc->Type == CmDesc->Type); + ASSERT(IoDesc->Type == CmResourceTypePort); + + for (Start = IoDesc->u.Port.MinimumAddress.QuadPart; + Start < IoDesc->u.Port.MaximumAddress.QuadPart; + Start++) + { + CmDesc->u.Port.Length = IoDesc->u.Port.Length; + CmDesc->u.Port.Start.QuadPart = Start; + + if (IopCheckDescriptorForConflict(CmDesc, &ConflictingDesc)) + { + Start += ConflictingDesc.u.Port.Start.QuadPart + ConflictingDesc.u.Port.Length; + } + else + { + return TRUE; + } + } + + return FALSE; +} + +BOOLEAN +IopFindDmaResource( + IN PIO_RESOURCE_DESCRIPTOR IoDesc, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc) +{ + ULONG Channel; + + ASSERT(IoDesc->Type == CmDesc->Type); + ASSERT(IoDesc->Type == CmResourceTypeDma); + + for (Channel = IoDesc->u.Dma.MinimumChannel; + Channel < IoDesc->u.Dma.MaximumChannel; + Channel++) + { + CmDesc->u.Dma.Channel = Channel; + CmDesc->u.Dma.Port = 0; + + if (!IopCheckDescriptorForConflict(CmDesc, NULL)) + return TRUE; + } + + return FALSE; +} + +BOOLEAN +IopFindInterruptResource( + IN PIO_RESOURCE_DESCRIPTOR IoDesc, + OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc) +{ + ULONG Vector; + + ASSERT(IoDesc->Type == CmDesc->Type); + ASSERT(IoDesc->Type == CmResourceTypeInterrupt); + + for (Vector = IoDesc->u.Interrupt.MinimumVector; + Vector < IoDesc->u.Interrupt.MaximumVector; + Vector++) + { + CmDesc->u.Interrupt.Vector = Vector; + CmDesc->u.Interrupt.Level = Vector; + CmDesc->u.Interrupt.Affinity = (KAFFINITY)-1; + + if (!IopCheckDescriptorForConflict(CmDesc, NULL)) + return TRUE; + } + + return FALSE; +} + +NTSTATUS +IopCreateResourceListFromRequirements( + IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, + OUT PCM_RESOURCE_LIST *ResourceList) +{ + ULONG i, ii, Size; + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResDesc; + + Size = FIELD_OFFSET(CM_RESOURCE_LIST, List); + for (i = 0; i < RequirementsList->AlternativeLists; i++) + { + PIO_RESOURCE_LIST ResList = &RequirementsList->List[i]; + Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + + ResList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + } + + *ResourceList = ExAllocatePool(PagedPool, Size); + if (!*ResourceList) + return STATUS_INSUFFICIENT_RESOURCES; + + (*ResourceList)->Count = 1; + (*ResourceList)->List[0].BusNumber = RequirementsList->BusNumber; + (*ResourceList)->List[0].InterfaceType = RequirementsList->InterfaceType; + (*ResourceList)->List[0].PartialResourceList.Version = 1; + (*ResourceList)->List[0].PartialResourceList.Revision = 1; + (*ResourceList)->List[0].PartialResourceList.Count = 0; + + ResDesc = &(*ResourceList)->List[0].PartialResourceList.PartialDescriptors[0]; + + for (i = 0; i < RequirementsList->AlternativeLists; i++) + { + PIO_RESOURCE_LIST ResList = &RequirementsList->List[i]; + for (ii = 0; ii < ResList->Count; ii++) + { + PIO_RESOURCE_DESCRIPTOR ReqDesc = &ResList->Descriptors[ii]; + + /* FIXME: Handle alternate ranges */ + if (ReqDesc->Option == IO_RESOURCE_ALTERNATIVE) + continue; + + ResDesc->Type = ReqDesc->Type; + ResDesc->Flags = ReqDesc->Flags; + ResDesc->ShareDisposition = ReqDesc->ShareDisposition; + + switch (ReqDesc->Type) + { + case CmResourceTypeInterrupt: + if (!IopFindInterruptResource(ReqDesc, ResDesc)) + { + DPRINT1("Failed to find an available interrupt resource (0x%x to 0x%x)\n", + ReqDesc->u.Interrupt.MinimumVector, ReqDesc->u.Interrupt.MaximumVector); + + if (ReqDesc->Option == 0) + { + ExFreePool(*ResourceList); + return STATUS_CONFLICTING_ADDRESSES; + } + } + break; + + case CmResourceTypePort: + if (!IopFindPortResource(ReqDesc, ResDesc)) + { + DPRINT1("Failed to find an available port resource (0x%x to 0x%x length: 0x%x)\n", + ReqDesc->u.Port.MinimumAddress.QuadPart, ReqDesc->u.Port.MaximumAddress.QuadPart, + ReqDesc->u.Port.Length); + + if (ReqDesc->Option == 0) + { + ExFreePool(*ResourceList); + return STATUS_CONFLICTING_ADDRESSES; + } + } + break; + + case CmResourceTypeMemory: + if (!IopFindMemoryResource(ReqDesc, ResDesc)) + { + DPRINT1("Failed to find an available memory resource (0x%x to 0x%x length: 0x%x)\n", + ReqDesc->u.Memory.MinimumAddress.QuadPart, ReqDesc->u.Memory.MaximumAddress.QuadPart, + ReqDesc->u.Memory.Length); + + if (ReqDesc->Option == 0) + { + ExFreePool(*ResourceList); + return STATUS_CONFLICTING_ADDRESSES; + } + } + break; + + case CmResourceTypeBusNumber: + if (!IopFindBusNumberResource(ReqDesc, ResDesc)) + { + DPRINT1("Failed to find an available bus number resource (0x%x to 0x%x length: 0x%x)\n", + ReqDesc->u.BusNumber.MinBusNumber, ReqDesc->u.BusNumber.MaxBusNumber, + ReqDesc->u.BusNumber.Length); + + if (ReqDesc->Option == 0) + { + ExFreePool(*ResourceList); + return STATUS_CONFLICTING_ADDRESSES; + } + } + break; + + case CmResourceTypeDma: + if (!IopFindDmaResource(ReqDesc, ResDesc)) + { + DPRINT1("Failed to find an available dma resource (0x%x to 0x%x)\n", + ReqDesc->u.Dma.MinimumChannel, ReqDesc->u.Dma.MaximumChannel); + + if (ReqDesc->Option == 0) + { + ExFreePool(*ResourceList); + return STATUS_CONFLICTING_ADDRESSES; + } + } + break; + + default: + DPRINT1("Unsupported resource type: %x\n", ReqDesc->Type); + break; + } + + (*ResourceList)->List[0].PartialResourceList.Count++; + ResDesc++; + } + } + + return STATUS_SUCCESS; +} + NTSTATUS IopAssignDeviceResources( IN PDEVICE_NODE DeviceNode, OUT ULONG *pRequiredSize) { - PIO_RESOURCE_LIST ResourceList; - PIO_RESOURCE_DESCRIPTOR ResourceDescriptor; - PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw; PCM_PARTIAL_RESOURCE_LIST pPartialResourceList; - ULONG NumberOfResources = 0; ULONG Size; - ULONG i, j; + ULONG i; + ULONG j; NTSTATUS Status; if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements) @@ -1371,7 +1894,7 @@ IopAssignDeviceResources( /* Fill DeviceNode->ResourceList * FIXME: the PnP arbiter should go there! - * Actually, use the BootResources if provided, else the resource list #0 + * Actually, use the BootResources if provided, else the resource requirements */ if (DeviceNode->BootResources) @@ -1381,8 +1904,8 @@ IopAssignDeviceResources( for (i = 0; i < DeviceNode->BootResources->Count; i++) { pPartialResourceList = &DeviceNode->BootResources->List[i].PartialResourceList; - Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) - + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); for (j = 0; j < pPartialResourceList->Count; j++) { if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific) @@ -1398,161 +1921,38 @@ IopAssignDeviceResources( } RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, Size); - Status = IopDetectResourceConflict(DeviceNode->ResourceList); - if (!NT_SUCCESS(Status)) - goto ByeBye; - - *pRequiredSize = Size; - return STATUS_SUCCESS; - } - - /* Ok, here, we have to use the device requirement list */ - ResourceList = &DeviceNode->ResourceRequirements->List[0]; - if (ResourceList->Version != 1 || ResourceList->Revision != 1) - { - Status = STATUS_REVISION_MISMATCH; - goto ByeBye; - } - - Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); - DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size); - if (!DeviceNode->ResourceList) - { - Status = STATUS_NO_MEMORY; - goto ByeBye; - } - - DeviceNode->ResourceList->Count = 1; - DeviceNode->ResourceList->List[0].InterfaceType = DeviceNode->ResourceRequirements->InterfaceType; - DeviceNode->ResourceList->List[0].BusNumber = DeviceNode->ResourceRequirements->BusNumber; - DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1; - DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1; - - for (i = 0; i < ResourceList->Count; i++) - { - ResourceDescriptor = &ResourceList->Descriptors[i]; - - if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED) + Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL); + if (NT_SUCCESS(Status) || !DeviceNode->ResourceRequirements) { - DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources]; - NumberOfResources++; + if (!NT_SUCCESS(Status) && !DeviceNode->ResourceRequirements) + { + DPRINT1("Using conflicting boot resources because no requirements were supplied!\n"); + } - /* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */ - DescriptorRaw->Type = ResourceDescriptor->Type; - DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition; - DescriptorRaw->Flags = ResourceDescriptor->Flags; - switch (ResourceDescriptor->Type) - { - case CmResourceTypePort: - { - DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress; - DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length; - break; - } - case CmResourceTypeInterrupt: - { - INTERFACE_TYPE BusType; - ULONG SlotNumber; - ULONG ret; - UCHAR Irq; - - DescriptorRaw->u.Interrupt.Level = 0; - DescriptorRaw->u.Interrupt.Vector = ResourceDescriptor->u.Interrupt.MinimumVector; - /* FIXME: HACK: if we have a PCI device, we try - * to keep the IRQ assigned by the BIOS */ - if (NT_SUCCESS(IoGetDeviceProperty( - DeviceNode->PhysicalDeviceObject, - DevicePropertyLegacyBusType, - sizeof(INTERFACE_TYPE), - &BusType, - &ret)) && BusType == PCIBus) - { - /* We have a PCI bus */ - if (NT_SUCCESS(IoGetDeviceProperty( - DeviceNode->PhysicalDeviceObject, - DevicePropertyAddress, - sizeof(ULONG), - &SlotNumber, - &ret)) && SlotNumber > 0) - { - /* We have a good slot number */ - ret = HalGetBusDataByOffset(PCIConfiguration, - DeviceNode->ResourceRequirements->BusNumber, - SlotNumber, - &Irq, - 0x3c /* PCI_INTERRUPT_LINE */, - sizeof(UCHAR)); - if (ret != 0 && ret != 2 - && ResourceDescriptor->u.Interrupt.MinimumVector <= Irq - && ResourceDescriptor->u.Interrupt.MaximumVector >= Irq) - { - /* The device already has an assigned IRQ */ - DescriptorRaw->u.Interrupt.Vector = Irq; - } - else - { - DPRINT1("Trying to assign IRQ 0x%lx to %wZ\n", - DescriptorRaw->u.Interrupt.Vector, - &DeviceNode->InstancePath); - Irq = (UCHAR)DescriptorRaw->u.Interrupt.Vector; - ret = HalSetBusDataByOffset(PCIConfiguration, - DeviceNode->ResourceRequirements->BusNumber, - SlotNumber, - &Irq, - 0x3c /* PCI_INTERRUPT_LINE */, - sizeof(UCHAR)); - if (ret == 0 || ret == 2) - ASSERT(FALSE); - } - } - } - break; - } - case CmResourceTypeMemory: - { - DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress; - DescriptorRaw->u.Memory.Length = ResourceDescriptor->u.Memory.Length; - break; - } - case CmResourceTypeDma: - { - DescriptorRaw->u.Dma.Channel = ResourceDescriptor->u.Dma.MinimumChannel; - DescriptorRaw->u.Dma.Port = 0; /* FIXME */ - DescriptorRaw->u.Dma.Reserved1 = 0; - break; - } - case CmResourceTypeBusNumber: - { - DescriptorRaw->u.BusNumber.Start = ResourceDescriptor->u.BusNumber.MinBusNumber; - DescriptorRaw->u.BusNumber.Length = ResourceDescriptor->u.BusNumber.Length; - DescriptorRaw->u.BusNumber.Reserved = ResourceDescriptor->u.BusNumber.Reserved; - break; - } - /*CmResourceTypeDevicePrivate: - case CmResourceTypePcCardConfig: - case CmResourceTypeMfCardConfig: - { - RtlCopyMemory( - &DescriptorRaw->u.DevicePrivate, - &ResourceDescriptor->u.DevicePrivate, - sizeof(ResourceDescriptor->u.DevicePrivate)); - RtlCopyMemory( - &DescriptorTranslated->u.DevicePrivate, - &ResourceDescriptor->u.DevicePrivate, - sizeof(ResourceDescriptor->u.DevicePrivate)); - break; - }*/ - default: - DPRINT1("IopAssignDeviceResources(): unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type); - NumberOfResources--; - } + *pRequiredSize = Size; + return STATUS_SUCCESS; + } + else + { + DPRINT1("Boot resources for %wZ cause a resource conflict!\n", &DeviceNode->InstancePath); + ExFreePool(DeviceNode->ResourceList); } - } - DeviceNode->ResourceList->List[0].PartialResourceList.Count = NumberOfResources; + Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements, + &DeviceNode->ResourceList); + if (!NT_SUCCESS(Status)) + goto ByeBye; - Status = IopDetectResourceConflict(DeviceNode->ResourceList); + Size = FIELD_OFFSET(CM_RESOURCE_LIST, List); + for (i = 0; i < DeviceNode->ResourceList->Count; i++) + { + pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList; + Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors) + + pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR); + } + + Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL); if (!NT_SUCCESS(Status)) goto ByeBye; @@ -1959,7 +2359,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, /* * Create registry key for the instance id, if it doesn't exist yet */ - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceKey); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to create the instance key! (Status %lx)\n", Status); @@ -2189,7 +2589,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, { DeviceNode->BootResources = (PCM_RESOURCE_LIST)IoStatusBlock.Information; - DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG; + IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG); } else { @@ -2483,14 +2883,8 @@ IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, DPRINT1("%wZ is using parent bus driver (%wZ)\n", &DeviceNode->InstancePath, &ParentDeviceNode->ServiceName); DeviceNode->ServiceName.Length = 0; - DeviceNode->ServiceName.MaximumLength = ParentDeviceNode->ServiceName.MaximumLength; - DeviceNode->ServiceName.Buffer = ExAllocatePool(PagedPool, DeviceNode->ServiceName.MaximumLength); - if (!DeviceNode->ServiceName.Buffer) - return STATUS_SUCCESS; - - RtlCopyUnicodeString(&DeviceNode->ServiceName, &ParentDeviceNode->ServiceName); - - IopDeviceNodeSetFlag(DeviceNode, DNF_LEGACY_DRIVER); + DeviceNode->ServiceName.MaximumLength = 0; + DeviceNode->ServiceName.Buffer = NULL; } else if (ClassGUID.Length != 0) { @@ -2569,10 +2963,23 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, return STATUS_UNSUCCESSFUL; } #endif + if (IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED) || + IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) || + IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED)) + return STATUS_SUCCESS; - if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) && - !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && - !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) + if (DeviceNode->ServiceName.Buffer == NULL) + { + /* We don't need to worry about loading the driver because we're + * being driven in raw mode so our parent must be loaded to get here */ + Status = IopStartDevice(DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n", + &DeviceNode->InstancePath, Status); + } + } + else { PLDR_DATA_TABLE_ENTRY ModuleObject; PDRIVER_OBJECT DriverObject; @@ -2615,24 +3022,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, /* Driver is loaded and initialized at this point */ if (NT_SUCCESS(Status)) { - /* Attach lower level filter drivers. */ - IopAttachFilterDrivers(DeviceNode, TRUE); - /* Initialize the function driver for the device node */ - Status = IopInitializeDevice(DeviceNode, DriverObject); - - if (NT_SUCCESS(Status)) - { - /* Attach upper level filter drivers. */ - IopAttachFilterDrivers(DeviceNode, FALSE); - IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); - - Status = IopStartDevice(DeviceNode); - } - else - { - DPRINT1("IopInitializeDevice(%wZ) failed with status 0x%08x\n", - &DeviceNode->InstancePath, Status); - } + /* Initialize the device, including all filters */ + Status = PipCallDriverAddDevice(DeviceNode, FALSE, DriverObject); } else { @@ -2649,11 +3040,6 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, } } } - else - { - DPRINT("Device %wZ is disabled or already initialized\n", - &DeviceNode->InstancePath); - } return STATUS_SUCCESS; } @@ -2696,7 +3082,6 @@ IopEnumerateDetectedDevices( IN ULONG ParentBootResourcesLength) { UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier"); - UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc"); UNICODE_STRING HardwareIDU = RTL_CONSTANT_STRING(L"HardwareID"); UNICODE_STRING ConfigurationDataU = RTL_CONSTANT_STRING(L"Configuration Data"); UNICODE_STRING BootConfigU = RTL_CONSTANT_STRING(L"BootConfig"); @@ -2743,7 +3128,8 @@ IopEnumerateDetectedDevices( UNICODE_STRING HardwareIdKey; PUNICODE_STRING pHardwareId; ULONG DeviceIndex = 0; - BOOLEAN IsDeviceDesc; + PUCHAR CmResourceList; + ULONG ListCount; if (RelativePath) { @@ -2850,7 +3236,7 @@ IopEnumerateDetectedDevices( BootResourcesLength = pValueInformation->DataLength; else BootResourcesLength = ParentBootResourcesLength - + pValueInformation->DataLength + + pValueInformation->DataLength - Header; BootResources = ExAllocatePool(PagedPool, BootResourcesLength); if (!BootResources) @@ -2858,7 +3244,7 @@ IopEnumerateDetectedDevices( DPRINT("ExAllocatePool() failed\n"); goto nextdevice; } - if (ParentBootResourcesLength == 0) + if (ParentBootResourcesLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) { RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength); } @@ -2970,31 +3356,26 @@ IopEnumerateDetectedDevices( { pHardwareId = &HardwareIdSerial; DeviceIndex = DeviceIndexSerial++; - IsDeviceDesc = TRUE; } else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0) { pHardwareId = &HardwareIdKeyboard; DeviceIndex = DeviceIndexKeyboard++; - IsDeviceDesc = FALSE; } else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0) { pHardwareId = &HardwareIdMouse; DeviceIndex = DeviceIndexMouse++; - IsDeviceDesc = FALSE; } else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierParallel, FALSE) == 0) { pHardwareId = &HardwareIdParallel; DeviceIndex = DeviceIndexParallel++; - IsDeviceDesc = FALSE; } else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierFloppy, FALSE) == 0) { pHardwareId = &HardwareIdFloppy; DeviceIndex = DeviceIndexFloppy++; - IsDeviceDesc = FALSE; } else if (NT_SUCCESS(Status)) { @@ -3003,13 +3384,11 @@ IopEnumerateDetectedDevices( { pHardwareId = &HardwareIdPci; DeviceIndex = DeviceIndexPci++; - IsDeviceDesc = FALSE; } else if (RtlCompareUnicodeString(&ValueName, &IdentifierIsa, FALSE) == 0) { pHardwareId = &HardwareIdIsa; DeviceIndex = DeviceIndexIsa++; - IsDeviceDesc = FALSE; } else { @@ -3061,16 +3440,6 @@ IopEnumerateDetectedDevices( goto nextdevice; } DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey); - if (IsDeviceDesc) - { - Status = ZwSetValueKey(hLevel2Key, &DeviceDescU, 0, REG_SZ, ValueName.Buffer, ValueName.MaximumLength); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); - ZwDeleteKey(hLevel2Key); - goto nextdevice; - } - } Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength); if (!NT_SUCCESS(Status)) { @@ -3094,10 +3463,29 @@ IopEnumerateDetectedDevices( ZwDeleteKey(hLevel2Key); goto nextdevice; } - if (BootResourcesLength > 0) + if (BootResourcesLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) { + CmResourceList = ExAllocatePool(PagedPool, BootResourcesLength + sizeof(ULONG)); + if (!CmResourceList) + { + ZwClose(hLogConf); + ZwDeleteKey(hLevel2Key); + goto nextdevice; + } + + /* Add the list count (1st member of CM_RESOURCE_LIST) */ + ListCount = 1; + RtlCopyMemory(CmResourceList, + &ListCount, + sizeof(ULONG)); + + /* Now add the actual list (2nd member of CM_RESOURCE_LIST) */ + RtlCopyMemory(CmResourceList + sizeof(ULONG), + BootResources, + BootResourcesLength); + /* Save boot resources to 'LogConf\BootConfig' */ - Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_FULL_RESOURCE_DESCRIPTOR, BootResources, BootResourcesLength); + Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_RESOURCE_LIST, CmResourceList, BootResourcesLength + sizeof(ULONG)); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status); @@ -3110,7 +3498,10 @@ IopEnumerateDetectedDevices( nextdevice: if (BootResources && BootResources != ParentBootResources) + { ExFreePool(BootResources); + BootResources = NULL; + } if (hLevel2Key) { ZwClose(hLevel2Key); @@ -3277,7 +3668,8 @@ cleanup: #endif } -static NTSTATUS INIT_FUNCTION +NTSTATUS +NTAPI IopUpdateRootKey(VOID) { UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum"); @@ -3384,6 +3776,131 @@ IopOpenRegistryKeyEx(PHANDLE KeyHandle, return Status; } +NTSTATUS +NTAPI +IopCreateRegistryKeyEx(OUT PHANDLE Handle, + IN HANDLE RootHandle OPTIONAL, + IN PUNICODE_STRING KeyName, + IN ACCESS_MASK DesiredAccess, + IN ULONG CreateOptions, + OUT PULONG Disposition OPTIONAL) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + ULONG KeyDisposition, RootHandleIndex = 0, i = 1, NestedCloseLevel = 0, Length; + HANDLE HandleArray[2]; + BOOLEAN Recursing = TRUE; + PWCHAR pp, p, p1; + UNICODE_STRING KeyString; + NTSTATUS Status = STATUS_SUCCESS; + PAGED_CODE(); + + /* P1 is start, pp is end */ + p1 = KeyName->Buffer; + pp = (PVOID)((ULONG_PTR)p1 + KeyName->Length); + + /* Create the target key */ + InitializeObjectAttributes(&ObjectAttributes, + KeyName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + RootHandle, + NULL); + Status = ZwCreateKey(&HandleArray[i], + DesiredAccess, + &ObjectAttributes, + 0, + NULL, + CreateOptions, + &KeyDisposition); + + /* Now we check if this failed */ + if ((Status == STATUS_OBJECT_NAME_NOT_FOUND) && (RootHandle)) + { + /* Target key failed, so we'll need to create its parent. Setup array */ + HandleArray[0] = NULL; + HandleArray[1] = RootHandle; + + /* Keep recursing for each missing parent */ + while (Recursing) + { + /* And if we're deep enough, close the last handle */ + if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]); + + /* We're setup to ping-pong between the two handle array entries */ + RootHandleIndex = i; + i = (i + 1) & 1; + + /* Clear the one we're attempting to open now */ + HandleArray[i] = NULL; + + /* Process the parent key name */ + for (p = p1; ((p < pp) && (*p != OBJ_NAME_PATH_SEPARATOR)); p++); + Length = (p - p1) * sizeof(WCHAR); + + /* Is there a parent name? */ + if (Length) + { + /* Build the unicode string for it */ + KeyString.Buffer = p1; + KeyString.Length = KeyString.MaximumLength = Length; + + /* Now try opening the parent */ + InitializeObjectAttributes(&ObjectAttributes, + &KeyString, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + HandleArray[RootHandleIndex], + NULL); + Status = ZwCreateKey(&HandleArray[i], + DesiredAccess, + &ObjectAttributes, + 0, + NULL, + CreateOptions, + &KeyDisposition); + if (NT_SUCCESS(Status)) + { + /* It worked, we have one more handle */ + NestedCloseLevel++; + } + else + { + /* Parent key creation failed, abandon loop */ + Recursing = FALSE; + continue; + } + } + else + { + /* We don't have a parent name, probably corrupted key name */ + Status = STATUS_INVALID_PARAMETER; + Recursing = FALSE; + continue; + } + + /* Now see if there's more parents to create */ + p1 = p + 1; + if ((p == pp) || (p1 == pp)) + { + /* We're done, hopefully successfully, so stop */ + Recursing = FALSE; + } + } + + /* Outer loop check for handle nesting that requires closing the top handle */ + if (NestedCloseLevel > 1) ZwClose(HandleArray[RootHandleIndex]); + } + + /* Check if we broke out of the loop due to success */ + if (NT_SUCCESS(Status)) + { + /* Return the target handle (we closed all the parent ones) and disposition */ + *Handle = HandleArray[i]; + if (Disposition) *Disposition = KeyDisposition; + } + + /* Return the success state */ + return Status; +} + NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, @@ -3429,95 +3946,6 @@ IopGetRegistryValue(IN HANDLE Handle, return STATUS_SUCCESS; } -static NTSTATUS INIT_FUNCTION -NTAPI -PnpDriverInitializeEmpty(IN struct _DRIVER_OBJECT *DriverObject, IN PUNICODE_STRING RegistryPath) -{ - return STATUS_SUCCESS; -} - -VOID INIT_FUNCTION -PnpInit(VOID) -{ - PDEVICE_OBJECT Pdo; - NTSTATUS Status; - - DPRINT("PnpInit()\n"); - - KeInitializeSpinLock(&IopDeviceTreeLock); - ExInitializeFastMutex(&IopBusTypeGuidListLock); - - /* Initialize the Bus Type GUID List */ - IopBusTypeGuidList = ExAllocatePool(NonPagedPool, sizeof(IO_BUS_TYPE_GUID_LIST)); - if (!IopBusTypeGuidList) { - DPRINT1("ExAllocatePool() failed\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0); - } - - RtlZeroMemory(IopBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST)); - ExInitializeFastMutex(&IopBusTypeGuidList->Lock); - - /* Initialize PnP-Event notification support */ - Status = IopInitPlugPlayEvents(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopInitPlugPlayEvents() failed\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); - } - - /* - * Create root device node - */ - - Status = IopCreateDriver(NULL, PnpDriverInitializeEmpty, NULL, 0, 0, &IopRootDriverObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IoCreateDriverObject() failed\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); - } - - Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER, - 0, FALSE, &Pdo); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IoCreateDevice() failed\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); - } - - Status = IopCreateDeviceNode(NULL, Pdo, NULL, &IopRootDeviceNode); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Insufficient resources\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); - } - - if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath, - L"HTREE\\ROOT\\0")) - { - DPRINT1("Failed to create the instance path!\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0); - } - - /* Report the device to the user-mode pnp manager */ - IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, - &IopRootDeviceNode->InstancePath); - - IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE; - PnpRootDriverEntry(IopRootDriverObject, NULL); - IopRootDeviceNode->PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; - IopRootDriverObject->DriverExtension->AddDevice( - IopRootDriverObject, - IopRootDeviceNode->PhysicalDeviceObject); - - /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */ - Status = IopUpdateRootKey(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopUpdateRootKey() failed\n"); - KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); - } -} - RTL_GENERIC_COMPARE_RESULTS NTAPI PiCompareInstancePath(IN PRTL_AVL_TABLE Table, @@ -3605,6 +4033,49 @@ PpInitSystem(VOID) } } +LONG IopNumberDeviceNodes; + +PDEVICE_NODE +NTAPI +PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject) +{ + PDEVICE_NODE DeviceNode; + PAGED_CODE(); + + /* Allocate it */ + DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), 'donD'); + if (!DeviceNode) return DeviceNode; + + /* Statistics */ + InterlockedIncrement(&IopNumberDeviceNodes); + + /* Set it up */ + RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE)); + DeviceNode->InterfaceType = InterfaceTypeUndefined; + DeviceNode->BusNumber = -1; + DeviceNode->ChildInterfaceType = InterfaceTypeUndefined; + DeviceNode->ChildBusNumber = -1; + DeviceNode->ChildBusTypeIndex = -1; +// KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent, TRUE); + InitializeListHead(&DeviceNode->DeviceArbiterList); + InitializeListHead(&DeviceNode->DeviceTranslatorList); + InitializeListHead(&DeviceNode->TargetDeviceNotify); + InitializeListHead(&DeviceNode->DockInfo.ListEntry); + InitializeListHead(&DeviceNode->PendedSetInterfaceState); + + /* Check if there is a PDO */ + if (PhysicalDeviceObject) + { + /* Link it and remove the init flag */ + DeviceNode->PhysicalDeviceObject = PhysicalDeviceObject; + ((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = DeviceNode; + PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + } + + /* Return the node */ + return DeviceNode; +} + /* PUBLIC FUNCTIONS **********************************************************/ /* @@ -3645,7 +4116,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, case DevicePropertyBusTypeGuid: /* Sanity check */ if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) && - (DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount)) + (DeviceNode->ChildBusTypeIndex < PnpBusTypeGuidList->GuidCount)) { /* Return the GUID */ *ResultLength = sizeof(GUID); @@ -3658,7 +4129,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, /* Copy the GUID */ RtlCopyMemory(PropertyBuffer, - &(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]), + &(PnpBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]), sizeof(GUID)); return STATUS_SUCCESS; } diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index c75e566b0d4..4995b16fd65 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -15,6 +15,7 @@ NTSTATUS NTAPI IopCreateDeviceKeyPath(IN PCUNICODE_STRING RegistryPath, + IN ULONG CreateOptions, OUT PHANDLE Handle); NTSTATUS @@ -196,7 +197,7 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent); /* Open a handle to the instance path key */ - Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, &InstanceKey); + Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0, &InstanceKey); if (!NT_SUCCESS(Status)) return Status; @@ -265,9 +266,6 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, /* Write the resource information to the registry */ IopSetDeviceInstanceData(InstanceKey, DeviceNode); - /* Close the instance key handle */ - ZwClose(InstanceKey); - /* If the caller didn't get the resources assigned for us, do it now */ if (!ResourceAssigned) { @@ -277,7 +275,19 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, { Status = IopTranslateDeviceResources(DeviceNode, RequiredLength); if (NT_SUCCESS(Status)) + { Status = IopUpdateResourceMapForPnPDevice(DeviceNode); + if (NT_SUCCESS(Status) && DeviceNode->ResourceList) + { + RtlInitUnicodeString(&ValueName, L"AllocConfig"); + Status = ZwSetValueKey(InstanceKey, + &ValueName, + 0, + REG_RESOURCE_LIST, + DeviceNode->ResourceList, + CM_RESOURCE_LIST_SIZE(DeviceNode->ResourceList)); + } + } } IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); @@ -285,10 +295,14 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject, if (!NT_SUCCESS(Status)) { DPRINT("Assigning resources failed: 0x%x\n", Status); + ZwClose(InstanceKey); return Status; } } + /* Close the instance key handle */ + ZwClose(InstanceKey); + /* Report the device's enumeration to umpnpmgr */ IopQueueTargetDeviceEvent(&GUID_DEVICE_ENUMERATED, &DeviceNode->InstancePath); diff --git a/ntoskrnl/io/pnpmgr/pnproot.c b/ntoskrnl/io/pnpmgr/pnproot.c index a5fa2a04f0c..30c612f1fc3 100644 --- a/ntoskrnl/io/pnpmgr/pnproot.c +++ b/ntoskrnl/io/pnpmgr/pnproot.c @@ -33,7 +33,6 @@ typedef struct _PNPROOT_DEVICE UNICODE_STRING DeviceDescription; // Resource requirement list PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList; - ULONG ResourceRequirementsListSize; // Associated resource list PCM_RESOURCE_LIST ResourceList; ULONG ResourceListSize; @@ -140,29 +139,19 @@ PnpRootCreateDevice( WCHAR InstancePath[5]; PPNPROOT_DEVICE Device = NULL; NTSTATUS Status; - ULONG i; UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\"); + ULONG NextInstance; + UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM); + HANDLE EnumHandle, DeviceKeyHandle = INVALID_HANDLE_VALUE; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + OBJECT_ATTRIBUTES ObjectAttributes; DeviceExtension = PnpRootDeviceObject->DeviceExtension; KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock); DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName); - /* Search for a free instance ID */ _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName); - for (i = 0; i < 9999; i++) - { - _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i); - Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device); - if (Status == STATUS_NO_SUCH_DEVICE) - break; - } - if (i == 9999) - { - DPRINT1("Too much legacy devices reported for service '%wZ'\n", ServiceName); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } /* Initialize a PNPROOT_DEVICE structure */ Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT); @@ -178,6 +167,74 @@ PnpRootCreateDevice( Status = STATUS_NO_MEMORY; goto cleanup; } + + Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ); + if (NT_SUCCESS(Status)) + { + InitializeObjectAttributes(&ObjectAttributes, &Device->DeviceID, OBJ_CASE_INSENSITIVE, EnumHandle, NULL); + Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL); + ZwClose(EnumHandle); + } + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open registry key\n"); + goto cleanup; + } + +tryagain: + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + QueryTable[0].Name = L"NextInstance"; + QueryTable[0].EntryContext = &NextInstance; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)DeviceKeyHandle, + QueryTable, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + for (NextInstance = 0; NextInstance <= 9999; NextInstance++) + { + _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance); + Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device); + if (Status == STATUS_NO_SUCH_DEVICE) + break; + } + + if (NextInstance > 9999) + { + DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + } + + _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance); + Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device); + if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999) + { + DPRINT1("NextInstance value is corrupt! (%d)\n", NextInstance); + RtlDeleteRegistryValue(RTL_REGISTRY_HANDLE, + (PWSTR)DeviceKeyHandle, + L"NextInstance"); + goto tryagain; + } + + NextInstance++; + Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, + (PWSTR)DeviceKeyHandle, + L"NextInstance", + REG_DWORD, + &NextInstance, + sizeof(NextInstance)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status); + goto cleanup; + } + if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath)) { Status = STATUS_NO_MEMORY; @@ -244,6 +301,8 @@ cleanup: RtlFreeUnicodeString(&Device->InstanceID); ExFreePoolWithTag(Device, TAG_PNP_ROOT); } + if (DeviceKeyHandle != INVALID_HANDLE_VALUE) + ZwClose(DeviceKeyHandle); return Status; } @@ -677,24 +736,27 @@ PnpRootFdoPnpControl( if (NT_SUCCESS(Status)) DeviceExtension->State = dsStarted; } - break; + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; case IRP_MN_STOP_DEVICE: DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n"); /* Root device cannot be stopped */ - Status = STATUS_NOT_SUPPORTED; - break; + Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; default: DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; break; } if (Status != STATUS_PENDING) { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); } return Status; @@ -707,48 +769,25 @@ PdoQueryDeviceRelations( IN PIO_STACK_LOCATION IrpSp) { PDEVICE_RELATIONS Relations; - DEVICE_RELATION_TYPE RelationType; NTSTATUS Status = Irp->IoStatus.Status; - RelationType = IrpSp->Parameters.QueryDeviceRelations.Type; + if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + return Status; - switch (RelationType) + DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n"); + Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); + if (!Relations) { - /* FIXME: remove */ - case BusRelations: - { - if (IoGetAttachedDevice(DeviceObject) != DeviceObject) - { - /* We're not alone in the stack */ - DPRINT1("PnP is misbehaving ; don't know how to handle IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); - } - break; - } - - case TargetDeviceRelation: - { - DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n"); - Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); - if (!Relations) - { - DPRINT("ExAllocatePoolWithTag() failed\n"); - Status = STATUS_NO_MEMORY; - } - else - { - ObReferenceObject(DeviceObject); - Relations->Count = 1; - Relations->Objects[0] = DeviceObject; - Status = STATUS_SUCCESS; - Irp->IoStatus.Information = (ULONG_PTR)Relations; - } - break; - } - - default: - { - DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / unknown relation type 0x%lx\n", RelationType); - } + DPRINT("ExAllocatePoolWithTag() failed\n"); + Status = STATUS_NO_MEMORY; + } + else + { + ObReferenceObject(DeviceObject); + Relations->Count = 1; + Relations->Objects[0] = DeviceObject; + Status = STATUS_SUCCESS; + Irp->IoStatus.Information = (ULONG_PTR)Relations; } return Status; @@ -786,35 +825,29 @@ PdoQueryResources( DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - if (DeviceExtension->DeviceInfo->ResourceList == NULL) - { - /* Create an empty resource list */ - ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST)); - if (!ResourceList) - return STATUS_NO_MEMORY; - - ResourceList->Count = 0; - - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - else + if (DeviceExtension->DeviceInfo->ResourceList) { /* Copy existing resource requirement list */ ResourceList = ExAllocatePool( PagedPool, - FIELD_OFFSET(CM_RESOURCE_LIST, List) + DeviceExtension->DeviceInfo->ResourceListSize); + DeviceExtension->DeviceInfo->ResourceListSize); if (!ResourceList) return STATUS_NO_MEMORY; - ResourceList->Count = 1; RtlCopyMemory( - &ResourceList->List, + ResourceList, DeviceExtension->DeviceInfo->ResourceList, DeviceExtension->DeviceInfo->ResourceListSize); - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - return STATUS_SUCCESS; + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + + return STATUS_SUCCESS; + } + else + { + /* No resources so just return without changing the status */ + return Irp->IoStatus.Status; + } } static NTSTATUS @@ -825,23 +858,10 @@ PdoQueryResourceRequirements( { PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension; PIO_RESOURCE_REQUIREMENTS_LIST ResourceList; - ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List); DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - if (DeviceExtension->DeviceInfo->ResourceRequirementsList == NULL) - { - /* Create an empty resource list */ - ResourceList = ExAllocatePool(PagedPool, ResourceListSize); - if (!ResourceList) - return STATUS_NO_MEMORY; - - RtlZeroMemory(ResourceList, ResourceListSize); - ResourceList->ListSize = ResourceListSize; - - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - else + if (DeviceExtension->DeviceInfo->ResourceRequirementsList) { /* Copy existing resource requirement list */ ResourceList = ExAllocatePool(PagedPool, DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize); @@ -852,10 +872,16 @@ PdoQueryResourceRequirements( ResourceList, DeviceExtension->DeviceInfo->ResourceRequirementsList, DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize); - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - return STATUS_SUCCESS; + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + + return STATUS_SUCCESS; + } + else + { + /* No resource requirements so just return without changing the status */ + return Irp->IoStatus.Status; + } } static NTSTATUS @@ -1159,6 +1185,8 @@ PnpRootDriverEntry( { DPRINT("PnpRootDriverEntry(%p %wZ)\n", DriverObject, RegistryPath); + IopRootDriverObject = DriverObject; + DriverObject->DriverExtension->AddDevice = PnpRootAddDevice; DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl; diff --git a/ntoskrnl/io/pnpmgr/pnputil.c b/ntoskrnl/io/pnpmgr/pnputil.c new file mode 100644 index 00000000000..f274f3db679 --- /dev/null +++ b/ntoskrnl/io/pnpmgr/pnputil.c @@ -0,0 +1,185 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * FILE: ntoskrnl/io/pnpmgr/pnputil.c + * PURPOSE: PnP Utility Code + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +/* FUNCTIONS ******************************************************************/ + +VOID +NTAPI +PnpFreeUnicodeStringList(IN PUNICODE_STRING UnicodeStringList, + IN ULONG StringCount) +{ + ULONG i; + + /* Go through the list */ + if (UnicodeStringList) + { + /* Go through each string */ + for (i = 0; i < StringCount; i++) + { + /* Check if it exists */ + if (UnicodeStringList[i].Buffer) + { + /* Free it */ + ExFreePool(UnicodeStringList[i].Buffer); + } + } + + /* Free the whole list */ + ExFreePool(UnicodeStringList); + } +} + +NTSTATUS +NTAPI +PnpRegMultiSzToUnicodeStrings(IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation, + OUT PUNICODE_STRING *UnicodeStringList, + OUT PULONG UnicodeStringCount) +{ + PWCHAR p, pp, ps; + ULONG i = 0, n; + ULONG Count = 0; + + /* Validate the key information */ + if (KeyValueInformation->Type != REG_MULTI_SZ) return STATUS_INVALID_PARAMETER; + + /* Set the pointers */ + p = (PWCHAR)((ULONG_PTR)KeyValueInformation + + KeyValueInformation->DataOffset); + pp = (PWCHAR)((ULONG_PTR)p + KeyValueInformation->DataLength); + + /* Loop the data */ + while (p != pp) + { + /* If we find a NULL, that means one string is done */ + if (!*p) + { + /* Add to our string count */ + Count++; + + /* Check for a double-NULL, which means we're done */ + if (((p + 1) == pp) || !(*(p + 1))) break; + } + + /* Go to the next character */ + p++; + } + + /* If we looped the whole list over, we missed increment a string, do it */ + if (p == pp) Count++; + + /* Allocate the list now that we know how big it is */ + *UnicodeStringList = ExAllocatePoolWithTag(PagedPool, + sizeof(UNICODE_STRING) * Count, + 'sUpP'); + if (!(*UnicodeStringList)) return STATUS_INSUFFICIENT_RESOURCES; + + /* Set pointers for second loop */ + ps = p = (PWCHAR)((ULONG_PTR)KeyValueInformation + + KeyValueInformation->DataOffset); + + /* Loop again, to do the copy this time */ + while (p != pp) + { + /* If we find a NULL, that means one string is done */ + if (!*p) + { + /* Check how long this string is */ + n = (ULONG_PTR)p - (ULONG_PTR)ps + sizeof(UNICODE_NULL); + + /* Allocate the buffer */ + (*UnicodeStringList)[i].Buffer = ExAllocatePoolWithTag(PagedPool, + n, + 'sUpP'); + if (!(*UnicodeStringList)[i].Buffer) + { + /* Back out of everything */ + PnpFreeUnicodeStringList(*UnicodeStringList, i); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Copy the string into the buffer */ + RtlCopyMemory((*UnicodeStringList)[i].Buffer, ps, n); + + /* Set the lengths */ + (*UnicodeStringList)[i].MaximumLength = n; + (*UnicodeStringList)[i].Length = n - sizeof(UNICODE_NULL); + + /* One more entry done */ + i++; + + /* Check for a double-NULL, which means we're done */ + if (((p + 1) == pp) || !(*(p + 1))) break; + + /* New string */ + ps = p + 1; + } + + /* New string */ + p++; + } + + /* Check if we've reached the last string */ + if (p == pp) + { + /* Calculate the string length */ + n = (ULONG_PTR)p - (ULONG_PTR)ps; + + /* Allocate the buffer for it */ + (*UnicodeStringList)[i].Buffer = ExAllocatePoolWithTag(PagedPool, + n + + sizeof(UNICODE_NULL), + 'sUpP'); + if (!(*UnicodeStringList)[i].Buffer) + { + /* Back out of everything */ + PnpFreeUnicodeStringList(*UnicodeStringList, i); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Make sure there's an actual string here */ + if (n) RtlCopyMemory((*UnicodeStringList)[i].Buffer, ps, n); + + /* Null-terminate the string ourselves */ + (*UnicodeStringList)[i].Buffer[n / sizeof(WCHAR)] = UNICODE_NULL; + + /* Set the lenghts */ + (*UnicodeStringList)[i].Length = n; + (*UnicodeStringList)[i].MaximumLength = n + sizeof(UNICODE_NULL); + } + + /* And we're done */ + *UnicodeStringCount = Count; + return STATUS_SUCCESS; +} + +BOOLEAN +NTAPI +PnpRegSzToString(IN PWCHAR RegSzData, + IN ULONG RegSzLength, + OUT PUSHORT StringLength OPTIONAL) +{ + PWCHAR p, pp; + + /* Find the end */ + pp = RegSzData + RegSzLength; + for (p = RegSzData; p < pp; p++) if (!*p) break; + + /* Return it */ + if (StringLength) *StringLength = p - RegSzData; + return TRUE; +} + +/* EOF */ diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index 389781cbb04..1ced65de25d 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -40,7 +40,7 @@ /* Make the code cleaner with some definitions for size multiples */ #define _1KB (1024) -#define _1MB (1000 * _1KB) +#define _1MB (1024 * _1KB) /* Size of a PDE directory, and size of a page table */ #define PDE_SIZE (PDE_COUNT * sizeof(MMPDE)) @@ -127,6 +127,12 @@ extern PVOID PoolTrackTable; // END FIXFIX // +typedef struct _MI_LARGE_PAGE_DRIVER_ENTRY +{ + LIST_ENTRY Links; + UNICODE_STRING BaseName; +} MI_LARGE_PAGE_DRIVER_ENTRY, *PMI_LARGE_PAGE_DRIVER_ENTRY; + typedef enum _MMSYSTEM_PTE_POOL_TYPE { SystemPteSpace, @@ -235,6 +241,9 @@ extern PFN_NUMBER MiLowNonPagedPoolThreshold; extern PFN_NUMBER MiHighNonPagedPoolThreshold; extern PFN_NUMBER MmMinimumFreePages; extern PFN_NUMBER MmPlentyFreePages; +extern PFN_NUMBER MiExpansionPoolPagesInitialCharge; +extern PFN_NUMBER MmResidentAvailablePages; +extern PFN_NUMBER MmResidentAvailablePagesAtInit; #define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x]) #define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1]) diff --git a/ntoskrnl/ntoskrnl-generic.rbuild b/ntoskrnl/ntoskrnl-generic.rbuild index a605ee1b147..a349f887312 100644 --- a/ntoskrnl/ntoskrnl-generic.rbuild +++ b/ntoskrnl/ntoskrnl-generic.rbuild @@ -244,7 +244,6 @@ device.c deviface.c driver.c - drvrlist.c error.c file.c iocomp.c @@ -267,10 +266,12 @@ plugplay.c pnpdma.c + pnpinit.c pnpmgr.c pnpnotify.c pnpreport.c pnproot.c + pnputil.c diff --git a/ntoskrnl/ntoskrnl.pspec b/ntoskrnl/ntoskrnl.pspec index 5016dbd2b87..12973661b81 100644 --- a/ntoskrnl/ntoskrnl.pspec +++ b/ntoskrnl/ntoskrnl.pspec @@ -1,5 +1,10 @@ #include #undef i386 +#ifndef __x86_64__ +#define FASTCALL fastcall +#else +#define FASTCALL stdcall +#endif @ stdcall CcCanIWrite(ptr long long long) @ stdcall CcCopyRead(ptr ptr long long ptr ptr) @@ -57,13 +62,13 @@ @ stdcall DbgQueryDebugFilterState(long long) @ stdcall DbgSetDebugFilterState(long long long) @ stdcall -arch=x86_64 ExAcquireFastMutex(ptr) -@ fastcall ExAcquireFastMutexUnsafe(ptr) +@ FASTCALL ExAcquireFastMutexUnsafe(ptr) @ stdcall ExAcquireResourceExclusiveLite(ptr long) @ stdcall ExAcquireResourceSharedLite(ptr long) -@ fastcall ExAcquireRundownProtection(ptr) ExfAcquireRundownProtection -@ fastcall ExAcquireRundownProtectionCacheAware(ptr) ExfAcquireRundownProtectionCacheAware -@ fastcall ExAcquireRundownProtectionCacheAwareEx(ptr long) ExfAcquireRundownProtectionCacheAwareEx -@ fastcall ExAcquireRundownProtectionEx(ptr long) ExfAcquireRundownProtectionEx +@ FASTCALL ExAcquireRundownProtection(ptr) ExfAcquireRundownProtection +@ FASTCALL ExAcquireRundownProtectionCacheAware(ptr) ExfAcquireRundownProtectionCacheAware +@ FASTCALL ExAcquireRundownProtectionCacheAwareEx(ptr long) ExfAcquireRundownProtectionCacheAwareEx +@ FASTCALL ExAcquireRundownProtectionEx(ptr long) ExfAcquireRundownProtectionEx @ stdcall ExAcquireSharedStarveExclusive(ptr long) @ stdcall ExAcquireSharedWaitForExclusive(ptr long) @ stdcall ExAllocateCacheAwareRundownProtection(long long) @@ -80,7 +85,7 @@ @ stdcall ExDeleteResourceLite(ptr) @ extern ExDesktopObjectType @ stdcall ExDisableResourceBoostLite(ptr) -@ fastcall ExEnterCriticalRegionAndAcquireFastMutexUnsafe(ptr) +@ FASTCALL ExEnterCriticalRegionAndAcquireFastMutexUnsafe(ptr) @ stdcall ExEnterCriticalRegionAndAcquireResourceExclusive(ptr) @ stdcall ExEnterCriticalRegionAndAcquireResourceShared(ptr) @ stdcall ExEnterCriticalRegionAndAcquireSharedWaitForExclusive(ptr) @@ -99,33 +104,33 @@ @ stdcall ExInitializeNPagedLookasideList(ptr ptr ptr long long long long) @ stdcall ExInitializePagedLookasideList(ptr ptr ptr long long long long) @ stdcall ExInitializeResourceLite(ptr) -@ fastcall ExInitializeRundownProtection(ptr) ExfInitializeRundownProtection +@ FASTCALL ExInitializeRundownProtection(ptr) ExfInitializeRundownProtection @ stdcall ExInitializeRundownProtectionCacheAware(ptr long) @ stdcall ExInitializeZone(ptr long ptr long) @ stdcall ExInterlockedAddLargeInteger(ptr long long ptr) #ifndef __x86_64__ -@ fastcall ExInterlockedAddLargeStatistic(ptr long) +@ FASTCALL ExInterlockedAddLargeStatistic(ptr long) #endif @ stdcall ExInterlockedAddUlong(ptr long ptr) #ifndef __x86_64__ -@ fastcall ExInterlockedCompareExchange64(ptr ptr ptr ptr) +@ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr) @ stdcall ExInterlockedDecrementLong(ptr ptr) @ stdcall ExInterlockedExchangeUlong(ptr long ptr) #endif @ stdcall ExInterlockedExtendZone(ptr ptr long ptr) #ifndef __x86_64__ -@ fastcall ExInterlockedFlushSList(ptr) +@ FASTCALL ExInterlockedFlushSList(ptr) @ stdcall ExInterlockedIncrementLong(ptr ptr) #endif @ stdcall ExInterlockedInsertHeadList(ptr ptr ptr) @ stdcall ExInterlockedInsertTailList(ptr ptr ptr) @ stdcall ExInterlockedPopEntryList(ptr ptr) #ifndef __x86_64__ -@ fastcall ExInterlockedPopEntrySList(ptr ptr) +@ FASTCALL ExInterlockedPopEntrySList(ptr ptr) #endif @ stdcall ExInterlockedPushEntryList(ptr ptr ptr) #ifndef __x86_64__ -@ fastcall ExInterlockedPushEntrySList(ptr ptr ptr) +@ FASTCALL ExInterlockedPushEntrySList(ptr ptr ptr) #endif @ stdcall ExInterlockedRemoveHeadList(ptr ptr) @ stdcall ExIsProcessorFeaturePresent(long) @@ -141,22 +146,22 @@ @ stdcall ExRaiseException(ptr) RtlRaiseException @ stdcall ExRaiseHardError(long long long ptr long ptr) @ stdcall ExRaiseStatus(long) RtlRaiseStatus -@ fastcall ExReInitializeRundownProtection(ptr) ExfReInitializeRundownProtection -@ fastcall ExReInitializeRundownProtectionCacheAware(ptr) ExfReInitializeRundownProtectionCacheAware +@ FASTCALL ExReInitializeRundownProtection(ptr) ExfReInitializeRundownProtection +@ FASTCALL ExReInitializeRundownProtectionCacheAware(ptr) ExfReInitializeRundownProtectionCacheAware @ stdcall ExRegisterCallback(ptr ptr ptr) @ stdcall ExReinitializeResourceLite(ptr) @ stdcall -arch=x86_64 ExReleaseFastMutex(ptr) -@ fastcall ExReleaseFastMutexUnsafe(ptr) -@ fastcall ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(ptr) -@ fastcall ExReleaseResourceAndLeaveCriticalRegion(ptr) +@ FASTCALL ExReleaseFastMutexUnsafe(ptr) +@ FASTCALL ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(ptr) +@ FASTCALL ExReleaseResourceAndLeaveCriticalRegion(ptr) @ stdcall ExReleaseResourceForThreadLite(ptr long) -@ fastcall ExReleaseResourceLite(ptr) -@ fastcall ExReleaseRundownProtection(ptr) ExfReleaseRundownProtection -@ fastcall ExReleaseRundownProtectionCacheAware(ptr) ExfReleaseRundownProtectionCacheAware -@ fastcall ExReleaseRundownProtectionCacheAwareEx(ptr long) ExfReleaseRundownProtectionCacheAwareEx -@ fastcall ExReleaseRundownProtectionEx(ptr long) ExfReleaseRundownProtectionEx -@ fastcall ExRundownCompleted(ptr) ExfRundownCompleted -@ fastcall ExRundownCompletedCacheAware(ptr) ExfRundownCompletedCacheAware +@ FASTCALL ExReleaseResourceLite(ptr) +@ FASTCALL ExReleaseRundownProtection(ptr) ExfReleaseRundownProtection +@ FASTCALL ExReleaseRundownProtectionCacheAware(ptr) ExfReleaseRundownProtectionCacheAware +@ FASTCALL ExReleaseRundownProtectionCacheAwareEx(ptr long) ExfReleaseRundownProtectionCacheAwareEx +@ FASTCALL ExReleaseRundownProtectionEx(ptr long) ExfReleaseRundownProtectionEx +@ FASTCALL ExRundownCompleted(ptr) ExfRundownCompleted +@ FASTCALL ExRundownCompletedCacheAware(ptr) ExfRundownCompletedCacheAware @ extern ExSemaphoreObjectType _ExSemaphoreObjectType @ stdcall ExSetResourceOwnerPointer(ptr ptr) @ stdcall ExSetTimerResolution(long long) @@ -167,37 +172,37 @@ @ stdcall ExUnregisterCallback(ptr) @ stdcall ExUuidCreate(ptr) @ stdcall ExVerifySuite(long) -@ fastcall ExWaitForRundownProtectionRelease(ptr) ExfWaitForRundownProtectionRelease -@ fastcall ExWaitForRundownProtectionReleaseCacheAware(ptr) ExfWaitForRundownProtectionReleaseCacheAware +@ FASTCALL ExWaitForRundownProtectionRelease(ptr) ExfWaitForRundownProtectionRelease +@ FASTCALL ExWaitForRundownProtectionReleaseCacheAware(ptr) ExfWaitForRundownProtectionReleaseCacheAware @ extern ExWindowStationObjectType -@ fastcall ExfAcquirePushLockExclusive(ptr) -@ fastcall ExfAcquirePushLockShared(ptr) +@ FASTCALL ExfAcquirePushLockExclusive(ptr) +@ FASTCALL ExfAcquirePushLockShared(ptr) #ifndef __x86_64__ -@ fastcall ExfInterlockedAddUlong(ptr long ptr) -@ fastcall ExfInterlockedCompareExchange64(ptr ptr ptr) -@ fastcall ExfInterlockedInsertHeadList(ptr ptr ptr) -@ fastcall ExfInterlockedInsertTailList(ptr ptr ptr) -@ fastcall ExfInterlockedPopEntryList(ptr ptr) -@ fastcall ExfInterlockedPushEntryList(ptr ptr ptr) -@ fastcall ExfInterlockedRemoveHeadList(ptr ptr) +@ FASTCALL ExfInterlockedAddUlong(ptr long ptr) +@ FASTCALL ExfInterlockedCompareExchange64(ptr ptr ptr) +@ FASTCALL ExfInterlockedInsertHeadList(ptr ptr ptr) +@ FASTCALL ExfInterlockedInsertTailList(ptr ptr ptr) +@ FASTCALL ExfInterlockedPopEntryList(ptr ptr) +@ FASTCALL ExfInterlockedPushEntryList(ptr ptr ptr) +@ FASTCALL ExfInterlockedRemoveHeadList(ptr ptr) #endif -@ fastcall ExfReleasePushLock(ptr) -@ fastcall ExfReleasePushLockExclusive(ptr) -@ fastcall ExfReleasePushLockShared(ptr) -@ fastcall ExfTryToWakePushLock(ptr) -@ fastcall ExfUnblockPushLock(ptr ptr) +@ FASTCALL ExfReleasePushLock(ptr) +@ FASTCALL ExfReleasePushLockExclusive(ptr) +@ FASTCALL ExfReleasePushLockShared(ptr) +@ FASTCALL ExfTryToWakePushLock(ptr) +@ FASTCALL ExfUnblockPushLock(ptr ptr) @ stdcall -arch=x86_64 ExpInterlockedFlushSList(ptr) @ stdcall -arch=x86_64 ExpInterlockedPopEntrySList(ptr ptr) @ stdcall -arch=x86_64 ExpInterlockedPushEntrySList(ptr ptr) -@ fastcall -arch=i386 Exfi386InterlockedDecrementLong(ptr) -@ fastcall -arch=i386 Exfi386InterlockedExchangeUlong(ptr long) -@ fastcall -arch=i386 Exfi386InterlockedIncrementLong(ptr) +@ FASTCALL -arch=i386 Exfi386InterlockedDecrementLong(ptr) +@ FASTCALL -arch=i386 Exfi386InterlockedExchangeUlong(ptr long) +@ FASTCALL -arch=i386 Exfi386InterlockedIncrementLong(ptr) @ stdcall -arch=i386 Exi386InterlockedDecrementLong(ptr) @ stdcall -arch=i386 Exi386InterlockedExchangeUlong(ptr long long) @ stdcall -arch=i386 Exi386InterlockedIncrementLong(ptr) -@ fastcall -arch=i386 ExiAcquireFastMutex(ptr) ExAcquireFastMutex -@ fastcall -arch=i386 ExiReleaseFastMutex(ptr) ExReleaseFastMutex -@ fastcall -arch=i386 ExiTryToAcquireFastMutex(ptr) ExTryToAcquireFastMutex +@ FASTCALL -arch=i386 ExiAcquireFastMutex(ptr) ExAcquireFastMutex +@ FASTCALL -arch=i386 ExiReleaseFastMutex(ptr) ExReleaseFastMutex +@ FASTCALL -arch=i386 ExiTryToAcquireFastMutex(ptr) ExTryToAcquireFastMutex @ stdcall FsRtlAcquireFileExclusive(ptr) ;FsRtlAddBaseMcbEntry @ stdcall FsRtlAddLargeMcbEntry(ptr long long long long long long) @@ -318,7 +323,7 @@ @ stdcall FsRtlUninitializeMcb(ptr) @ stdcall FsRtlUninitializeOplock(ptr) @ extern HalDispatchTable _HalDispatchTable -@ fastcall HalExamineMBR(ptr long long ptr) +@ FASTCALL HalExamineMBR(ptr long long ptr) @ extern HalPrivateDispatchTable ;HeadlessDispatch @ stdcall InbvAcquireDisplayOwnership() @@ -335,13 +340,13 @@ @ stdcall InbvSolidColorFill(long long long long long) @ extern InitSafeBootMode #ifndef __x86_64__ -@ fastcall InterlockedCompareExchange(ptr long long) -@ fastcall InterlockedDecrement(ptr) -@ fastcall InterlockedExchange(ptr long) -@ fastcall InterlockedExchangeAdd(ptr long) -@ fastcall InterlockedIncrement(ptr) -@ fastcall InterlockedPopEntrySList(ptr) -@ fastcall InterlockedPushEntrySList(ptr ptr) +@ FASTCALL InterlockedCompareExchange(ptr long long) +@ FASTCALL InterlockedDecrement(ptr) +@ FASTCALL InterlockedExchange(ptr long) +@ FASTCALL InterlockedExchangeAdd(ptr long) +@ FASTCALL InterlockedIncrement(ptr) +@ FASTCALL InterlockedPopEntrySList(ptr) +@ FASTCALL InterlockedPushEntrySList(ptr ptr) #else @ stdcall InitializeSListHead(ptr) RtlInitializeSListHead #endif @@ -356,7 +361,7 @@ @ stdcall IoAllocateIrp(long long) @ stdcall IoAllocateMdl(ptr long long long ptr) @ stdcall IoAllocateWorkItem(ptr) -@ fastcall IoAssignDriveLetters(ptr ptr ptr ptr) +@ FASTCALL IoAssignDriveLetters(ptr ptr ptr ptr) @ stdcall IoAssignResources(ptr ptr ptr ptr ptr ptr) @ stdcall IoAttachDevice(ptr ptr ptr) @ stdcall IoAttachDeviceByPointer(ptr ptr) @@ -437,7 +442,7 @@ @ stdcall IoGetFileObjectGenericMapping() @ stdcall IoGetInitialStack() @ stdcall IoGetLowerDeviceObject(ptr) -@ fastcall IoGetPagingIoPriority(ptr) +@ FASTCALL IoGetPagingIoPriority(ptr) @ stdcall IoGetRelatedDeviceObject(ptr) @ stdcall IoGetRequestorProcess(ptr) @ stdcall IoGetRequestorProcessId(ptr) @@ -469,7 +474,7 @@ @ stdcall IoRaiseInformationalHardError(long ptr ptr) @ stdcall IoReadDiskSignature(ptr long ptr) @ extern IoReadOperationCount -@ fastcall IoReadPartitionTable(ptr long long ptr) +@ FASTCALL IoReadPartitionTable(ptr long long ptr) @ stdcall IoReadPartitionTableEx(ptr ptr) @ extern IoReadTransferCount @ stdcall IoRegisterBootDriverReinitialization(ptr ptr ptr) @@ -500,7 +505,7 @@ @ stdcall IoSetHardErrorOrVerifyDevice(ptr ptr) @ stdcall IoSetInformation(ptr ptr long ptr) @ stdcall IoSetIoCompletion(ptr ptr ptr long ptr long) -@ fastcall IoSetPartitionInformation(ptr long long long) +@ FASTCALL IoSetPartitionInformation(ptr long long long) @ stdcall IoSetPartitionInformationEx(ptr long ptr) @ stdcall IoSetShareAccess(long long ptr ptr) @ stdcall IoSetStartIoAttributes(ptr long long) @@ -543,11 +548,11 @@ @ stdcall IoWMIWriteEvent(ptr) @ stdcall IoWriteErrorLogEntry(ptr) @ extern IoWriteOperationCount -@ fastcall IoWritePartitionTable(ptr long long long ptr) +@ FASTCALL IoWritePartitionTable(ptr long long long ptr) @ stdcall IoWritePartitionTableEx(ptr ptr) @ extern IoWriteTransferCount -@ fastcall IofCallDriver(ptr ptr) -@ fastcall IofCompleteRequest(ptr long) +@ FASTCALL IofCallDriver(ptr ptr) +@ FASTCALL IofCompleteRequest(ptr long) @ stdcall KdChangeOption(long long ptr long ptr ptr) @ extern KdDebuggerEnabled _KdDebuggerEnabled @ extern KdDebuggerNotPresent _KdDebuggerNotPresent @@ -562,13 +567,13 @@ @ stdcall -arch=i386 Ke386IoSetAccessProcess(ptr long) @ stdcall -arch=i386 Ke386QueryIoAccessMap(long ptr) @ stdcall -arch=i386 Ke386SetIoAccessMap(long ptr) -@ fastcall KeAcquireGuardedMutex(ptr) -@ fastcall KeAcquireGuardedMutexUnsafe(ptr) -@ fastcall KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr) -@ fastcall KeAcquireInStackQueuedSpinLockForDpc(ptr ptr) +@ FASTCALL KeAcquireGuardedMutex(ptr) +@ FASTCALL KeAcquireGuardedMutexUnsafe(ptr) +@ FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr) +@ FASTCALL KeAcquireInStackQueuedSpinLockForDpc(ptr ptr) @ stdcall KeAcquireInterruptSpinLock(ptr) @ stdcall KeAcquireSpinLockAtDpcLevel(ptr) -@ fastcall KeAcquireSpinLockForDpc(ptr) +@ FASTCALL KeAcquireSpinLockForDpc(ptr) @ stdcall -arch=x86_64 KeAcquireSpinLockRaiseToDpc(ptr) @ stdcall KeAddSystemServiceTable(ptr ptr long ptr long) @ stdcall KeAreAllApcsDisabled() @@ -612,7 +617,7 @@ @ stdcall KeInitializeDeviceQueue(ptr) @ stdcall KeInitializeDpc(ptr ptr ptr) @ stdcall KeInitializeEvent(ptr long long) -@ fastcall KeInitializeGuardedMutex(ptr) +@ FASTCALL KeInitializeGuardedMutex(ptr) @ stdcall KeInitializeInterrupt(ptr ptr ptr ptr long long long long long long long) @ stdcall KeInitializeMutant(ptr long) @ stdcall KeInitializeMutex(ptr long) @@ -663,10 +668,10 @@ @ stdcall KeRegisterBugCheckCallback(ptr ptr ptr long ptr) @ stdcall KeRegisterBugCheckReasonCallback(ptr ptr ptr ptr) @ stdcall KeRegisterNmiCallback(ptr ptr) -@ fastcall KeReleaseGuardedMutex(ptr) -@ fastcall KeReleaseGuardedMutexUnsafe(ptr) -@ fastcall KeReleaseInStackQueuedSpinLockForDpc(ptr) -@ fastcall KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr) +@ FASTCALL KeReleaseGuardedMutex(ptr) +@ FASTCALL KeReleaseGuardedMutexUnsafe(ptr) +@ FASTCALL KeReleaseInStackQueuedSpinLockForDpc(ptr) +@ FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr) @ stdcall KeReleaseInterruptSpinLock(ptr long) @ stdcall KeReleaseMutant(ptr long long long) @ stdcall KeReleaseMutex(ptr long) @@ -674,7 +679,7 @@ #ifdef __x86_64__ @ stdcall KeReleaseSpinLock(ptr long) #endif -@ fastcall KeReleaseSpinLockForDpc(ptr long) +@ FASTCALL KeReleaseSpinLockForDpc(ptr long) @ stdcall KeReleaseSpinLockFromDpcLevel(ptr) @ stdcall KeRemoveByKeyDeviceQueue(ptr long) @ stdcall KeRemoveByKeyDeviceQueueIfBusy(ptr long) @@ -710,10 +715,10 @@ @ stdcall KeStackAttachProcess(ptr ptr) @ stdcall KeSynchronizeExecution(ptr ptr ptr) @ stdcall KeTerminateThread(long) -@ fastcall KeTestSpinLock(ptr) +@ FASTCALL KeTestSpinLock(ptr) @ extern KeTickCount -@ fastcall KeTryToAcquireGuardedMutex(ptr) -@ fastcall KeTryToAcquireSpinLockAtDpcLevel(ptr) +@ FASTCALL KeTryToAcquireGuardedMutex(ptr) +@ FASTCALL KeTryToAcquireSpinLockAtDpcLevel(ptr) @ stdcall KeUnstackDetachProcess(ptr) @ stdcall KeUpdateRunTime(ptr long) @ fastcall KeUpdateSystemTime(ptr long long) @@ -721,11 +726,11 @@ @ stdcall KeWaitForMultipleObjects(long ptr long long long long ptr ptr) @ stdcall KeWaitForMutexObject(ptr long long long ptr) KeWaitForSingleObject @ stdcall KeWaitForSingleObject(ptr long long long ptr) -@ fastcall KefAcquireSpinLockAtDpcLevel(ptr) -@ fastcall KefReleaseSpinLockFromDpcLevel(ptr) +@ FASTCALL KefAcquireSpinLockAtDpcLevel(ptr) +@ FASTCALL KefReleaseSpinLockFromDpcLevel(ptr) @ stdcall -arch=i386 Kei386EoiHelper() @ fastcall -arch=i386 KiEoiHelper(ptr) /* FIXME: Evaluate decision */ -@ fastcall KiAcquireSpinLock(ptr) +@ FASTCALL KiAcquireSpinLock(ptr) @ extern KiBugCheckData @ stdcall KiCheckForKernelApcDelivery() ;KiCheckForSListAddress @@ -734,7 +739,7 @@ @ stdcall -arch=i386 KiDispatchInterrupt() @ extern KiEnableTimerWatchdog @ stdcall KiIpiServiceRoutine(ptr ptr) -@ fastcall KiReleaseSpinLock(ptr) +@ FASTCALL KiReleaseSpinLock(ptr) @ cdecl KiUnexpectedInterrupt() #ifdef _M_IX86 @ stdcall Kii386SpinOnSpinLock(ptr long) @@ -928,8 +933,8 @@ ;ObSetHandleAttributes@12 @ stdcall ObSetSecurityDescriptorInfo(ptr ptr ptr ptr long ptr) @ stdcall ObSetSecurityObjectByPointer(ptr long ptr) -@ fastcall ObfDereferenceObject(ptr) -@ fastcall ObfReferenceObject(ptr) +@ FASTCALL ObfDereferenceObject(ptr) +@ FASTCALL ObfReferenceObject(ptr) ;PfxFindPrefix ;PfxInitialize ;PfxInsertPrefix @@ -1251,7 +1256,7 @@ @ stdcall RtlOemStringToUnicodeString(ptr ptr long) @ stdcall RtlOemToUnicodeN(wstr long ptr ptr long) @ stdcall RtlPinAtomInAtomTable(ptr ptr) -@ fastcall RtlPrefetchMemoryNonTemporal(ptr long) +@ FASTCALL RtlPrefetchMemoryNonTemporal(ptr long) @ stdcall RtlPrefixString(ptr ptr long) @ stdcall RtlPrefixUnicodeString(ptr ptr long) @ stdcall RtlQueryAtomInAtomTable(ptr ptr ptr ptr ptr ptr) @@ -1298,8 +1303,8 @@ ;RtlTraceDatabaseUnlock ;RtlTraceDatabaseValidate #ifndef __x86_64__ -@ fastcall RtlUlongByteSwap(long) -@ fastcall RtlUlonglongByteSwap(long long) +@ FASTCALL RtlUlongByteSwap(long) +@ FASTCALL RtlUlonglongByteSwap(long long) #endif @ stdcall RtlUnicodeStringToAnsiSize(ptr) RtlxUnicodeStringToAnsiSize @ stdcall RtlUnicodeStringToAnsiString(ptr ptr long) @@ -1324,7 +1329,7 @@ @ stdcall RtlUpperChar(long) @ stdcall RtlUpperString(ptr ptr) #ifndef __x86_64__ -@ fastcall RtlUshortByteSwap(long) +@ FASTCALL RtlUshortByteSwap(long) #endif @ stdcall RtlValidRelativeSecurityDescriptor(ptr long long) @ stdcall RtlValidSecurityDescriptor(ptr) diff --git a/ntoskrnl/se/semgr.c b/ntoskrnl/se/semgr.c index d06fb04bbb6..de374473139 100644 --- a/ntoskrnl/se/semgr.c +++ b/ntoskrnl/se/semgr.c @@ -314,6 +314,31 @@ SepSidInToken(PACCESS_TOKEN _Token, return FALSE; } +static BOOLEAN +SepTokenIsOwner(PACCESS_TOKEN Token, + PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + NTSTATUS Status; + PSID Sid = NULL; + BOOLEAN Defaulted; + + Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, + &Sid, + &Defaulted); + if (!NT_SUCCESS(Status)) + { + DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status); + return FALSE; + } + + if (Sid == NULL) + { + DPRINT1("Owner Sid is NULL\n"); + return FALSE; + } + + return SepSidInToken(Token, Sid); +} VOID NTAPI SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, @@ -352,6 +377,9 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, } } + +#define OLD_ACCESS_CHECK + BOOLEAN NTAPI SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, @@ -364,7 +392,13 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PNTSTATUS AccessStatus) { LUID_AND_ATTRIBUTES Privilege; +#ifdef OLD_ACCESS_CHECK ACCESS_MASK CurrentAccess, AccessMask; +#endif + ACCESS_MASK RemainingAccess; + ACCESS_MASK TempAccess; + ACCESS_MASK TempGrantedAccess = 0; + ACCESS_MASK TempDeniedAccess = 0; PACCESS_TOKEN Token; ULONG i; PACL Dacl; @@ -398,15 +432,45 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, if (PreviouslyGrantedAccess) RtlMapGenericMask(&PreviouslyGrantedAccess, GenericMapping); - - +#ifdef OLD_ACCESS_CHECK CurrentAccess = PreviouslyGrantedAccess; - - +#endif + /* Initialize remaining access rights */ + RemainingAccess = DesiredAccess; Token = SubjectSecurityContext->ClientToken ? SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; + /* Check for system security access */ + if (RemainingAccess & ACCESS_SYSTEM_SECURITY) + { + Privilege.Luid = SeSecurityPrivilege; + Privilege.Attributes = SE_PRIVILEGE_ENABLED; + + /* Fail if we do not the SeSecurityPrivilege */ + if (!SepPrivilegeCheck(Token, + &Privilege, + 1, + PRIVILEGE_SET_ALL_NECESSARY, + AccessMode)) + { + *AccessStatus = STATUS_PRIVILEGE_NOT_HELD; + return FALSE; + } + + /* Adjust access rights */ + RemainingAccess &= ~ACCESS_SYSTEM_SECURITY; + PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY; + + /* Succeed if there are no more rights to grant */ + if (RemainingAccess == 0) + { + *GrantedAccess = PreviouslyGrantedAccess; + *AccessStatus = STATUS_SUCCESS; + return TRUE; + } + } + /* Get the DACL */ Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, &Present, @@ -435,57 +499,54 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, return TRUE; } +#ifdef OLD_ACCESS_CHECK CurrentAccess = PreviouslyGrantedAccess; +#endif /* RULE 2: Check token for 'take ownership' privilege */ - Privilege.Luid = SeTakeOwnershipPrivilege; - Privilege.Attributes = SE_PRIVILEGE_ENABLED; - - if (SepPrivilegeCheck(Token, - &Privilege, - 1, - PRIVILEGE_SET_ALL_NECESSARY, - AccessMode)) + if (DesiredAccess & WRITE_OWNER) { - CurrentAccess |= WRITE_OWNER; - if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == - (CurrentAccess & ~VALID_INHERIT_FLAGS)) + Privilege.Luid = SeTakeOwnershipPrivilege; + Privilege.Attributes = SE_PRIVILEGE_ENABLED; + + if (SepPrivilegeCheck(Token, + &Privilege, + 1, + PRIVILEGE_SET_ALL_NECESSARY, + AccessMode)) { - *GrantedAccess = CurrentAccess; - *AccessStatus = STATUS_SUCCESS; - return TRUE; + /* Adjust access rights */ + RemainingAccess &= ~WRITE_OWNER; + PreviouslyGrantedAccess |= WRITE_OWNER; +#ifdef OLD_ACCESS_CHECK + CurrentAccess |= WRITE_OWNER; +#endif + + /* Succeed if there are no more rights to grant */ + if (RemainingAccess == 0) + { + *GrantedAccess = PreviouslyGrantedAccess; + *AccessStatus = STATUS_SUCCESS; + return TRUE; + } } } /* Deny access if the DACL is empty */ if (Dacl->AceCount == 0) { - *GrantedAccess = 0; - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; - } - - /* RULE 3: Check whether the token is the owner */ - Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, - &Sid, - &Defaulted); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlGetOwnerSecurityDescriptor() failed (Status %lx)\n", Status); - *AccessStatus = Status; - return FALSE; - } - - if (Sid && SepSidInToken(Token, Sid)) - { - CurrentAccess |= (READ_CONTROL | WRITE_DAC); - if ((DesiredAccess & ~VALID_INHERIT_FLAGS) == - (CurrentAccess & ~VALID_INHERIT_FLAGS)) + if (RemainingAccess == MAXIMUM_ALLOWED && PreviouslyGrantedAccess != 0) { - *GrantedAccess = CurrentAccess; + *GrantedAccess = PreviouslyGrantedAccess; *AccessStatus = STATUS_SUCCESS; return TRUE; } + else + { + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } } /* Fail if DACL is absent */ @@ -496,50 +557,134 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, return FALSE; } + /* Determine the MAXIMUM_ALLOWED access rights according to the DACL */ + if (DesiredAccess & MAXIMUM_ALLOWED) + { + CurrentAce = (PACE)(Dacl + 1); + for (i = 0; i < Dacl->AceCount; i++) + { + if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE)) + { + Sid = (PSID)(CurrentAce + 1); + if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) + { + if (SepSidInToken(Token, Sid)) + { + /* Map access rights from the ACE */ + TempAccess = CurrentAce->AccessMask; + RtlMapGenericMask(&TempAccess, GenericMapping); + + /* Deny access rights that have not been granted yet */ + TempDeniedAccess |= (TempAccess & ~TempGrantedAccess); + } + } + else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) + { + if (SepSidInToken(Token, Sid)) + { + /* Map access rights from the ACE */ + TempAccess = CurrentAce->AccessMask; + RtlMapGenericMask(&TempAccess, GenericMapping); + + /* Grant access rights that have not been denied yet */ + TempGrantedAccess |= (TempAccess & ~TempDeniedAccess); + } + } + else + { + DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType); + } + } + + /* Get the next ACE */ + CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); + } + + /* Fail if some rights have not been granted */ + RemainingAccess &= ~(MAXIMUM_ALLOWED | TempGrantedAccess); + if (RemainingAccess != 0) + { + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } + + /* Set granted access right and access status */ + *GrantedAccess = TempGrantedAccess | PreviouslyGrantedAccess; + if (*GrantedAccess != 0) + { + *AccessStatus = STATUS_SUCCESS; + return TRUE; + } + else + { + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } + } + /* RULE 4: Grant rights according to the DACL */ CurrentAce = (PACE)(Dacl + 1); for (i = 0; i < Dacl->AceCount; i++) { - Sid = (PSID)(CurrentAce + 1); - if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) + if (!(CurrentAce->Header.AceFlags & INHERIT_ONLY_ACE)) { - if (SepSidInToken(Token, Sid)) + Sid = (PSID)(CurrentAce + 1); + if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE) { - *GrantedAccess = 0; - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; + if (SepSidInToken(Token, Sid)) + { +#ifdef OLD_ACCESS_CHECK + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; +#else + /* Map access rights from the ACE */ + TempAccess = CurrentAce->AccessMask; + RtlMapGenericMask(&TempAccess, GenericMapping); + + /* Leave if a remaining right must be denied */ + if (RemainingAccess & TempAccess) + break; +#endif + } + } + else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) + { + if (SepSidInToken(Token, Sid)) + { +#ifdef OLD_ACCESS_CHECK + AccessMask = CurrentAce->AccessMask; + RtlMapGenericMask(&AccessMask, GenericMapping); + CurrentAccess |= AccessMask; +#else + /* Map access rights from the ACE */ + TempAccess = CurrentAce->AccessMask; + RtlMapGenericMask(&TempAccess, GenericMapping); + + /* Remove granted rights */ + RemainingAccess &= ~TempAccess; +#endif + } + } + else + { + DPRINT1("Unsupported ACE type 0x%lx\n", CurrentAce->Header.AceType); } } - else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) - { - if (SepSidInToken(Token, Sid)) - { - AccessMask = CurrentAce->AccessMask; - RtlMapGenericMask(&AccessMask, GenericMapping); - CurrentAccess |= AccessMask; - } - } - else - { - DPRINT1("Unknown Ace type 0x%lx\n", CurrentAce->Header.AceType); - } + /* Get the next ACE */ CurrentAce = (PACE)((ULONG_PTR)CurrentAce + CurrentAce->Header.AceSize); } +#ifdef OLD_ACCESS_CHECK DPRINT("CurrentAccess %08lx\n DesiredAccess %08lx\n", CurrentAccess, DesiredAccess); *GrantedAccess = CurrentAccess & DesiredAccess; - if (DesiredAccess & MAXIMUM_ALLOWED) - { - *GrantedAccess = CurrentAccess; - *AccessStatus = STATUS_SUCCESS; - return TRUE; - } - else if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == - (DesiredAccess & ~VALID_INHERIT_FLAGS)) + if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == + (DesiredAccess & ~VALID_INHERIT_FLAGS)) { *AccessStatus = STATUS_SUCCESS; return TRUE; @@ -553,6 +698,33 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, *AccessStatus = STATUS_SUCCESS; return TRUE; } +#else + DPRINT("DesiredAccess %08lx\nPreviouslyGrantedAccess %08lx\nRemainingAccess %08lx\n", + DesiredAccess, PreviouslyGrantedAccess, RemainingAccess); + + /* Fail if some rights have not been granted */ + if (RemainingAccess != 0) + { + *GrantedAccess = 0; + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } + + /* Set granted access rights */ + *GrantedAccess = DesiredAccess | PreviouslyGrantedAccess; + + DPRINT("GrantedAccess %08lx\n", *GrantedAccess); + + /* Fail if no rights have been granted */ + if (*GrantedAccess == 0) + { + *AccessStatus = STATUS_ACCESS_DENIED; + return FALSE; + } + + *AccessStatus = STATUS_SUCCESS; + return TRUE; +#endif } static PSID @@ -649,16 +821,43 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, if (!SubjectContextLocked) SeLockSubjectContext(SubjectSecurityContext); - /* Call the internal function */ - ret = SepAccessCheck(SecurityDescriptor, - SubjectSecurityContext, - DesiredAccess, - PreviouslyGrantedAccess, - Privileges, - GenericMapping, - AccessMode, - GrantedAccess, - AccessStatus); + /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */ + if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED)) + { + PACCESS_TOKEN Token = SubjectSecurityContext->ClientToken ? + SubjectSecurityContext->ClientToken : SubjectSecurityContext->PrimaryToken; + + if (SepTokenIsOwner(Token, + SecurityDescriptor)) + { + if (DesiredAccess & MAXIMUM_ALLOWED) + PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL); + else + PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL)); + + DesiredAccess &= ~(WRITE_DAC | READ_CONTROL); + } + } + + if (DesiredAccess == 0) + { + *GrantedAccess = PreviouslyGrantedAccess; + *AccessStatus = STATUS_SUCCESS; + ret = TRUE; + } + else + { + /* Call the internal function */ + ret = SepAccessCheck(SecurityDescriptor, + SubjectSecurityContext, + DesiredAccess, + PreviouslyGrantedAccess, + Privileges, + GenericMapping, + AccessMode, + GrantedAccess, + AccessStatus); + } /* Release the lock if needed */ if (!SubjectContextLocked) @@ -686,6 +885,7 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = NULL; SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + ACCESS_MASK PreviouslyGrantedAccess = 0; PTOKEN Token; NTSTATUS Status; PAGED_CODE(); @@ -801,16 +1001,38 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, SubjectSecurityContext.ProcessAuditId = NULL; SeLockSubjectContext(&SubjectSecurityContext); - /* Now perform the access check */ - SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor - &SubjectSecurityContext, - DesiredAccess, - 0, - &PrivilegeSet, //FIXME - GenericMapping, - PreviousMode, - GrantedAccess, - AccessStatus); + /* Check if the token is the owner and grant WRITE_DAC and READ_CONTROL rights */ + if (DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED)) + { + if (SepTokenIsOwner(Token, SecurityDescriptor)) // FIXME: use CapturedSecurityDescriptor + { + if (DesiredAccess & MAXIMUM_ALLOWED) + PreviouslyGrantedAccess |= (WRITE_DAC | READ_CONTROL); + else + PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL)); + + DesiredAccess &= ~(WRITE_DAC | READ_CONTROL); + } + } + + if (DesiredAccess == 0) + { + *GrantedAccess = PreviouslyGrantedAccess; + *AccessStatus = STATUS_SUCCESS; + } + else + { + /* Now perform the access check */ + SepAccessCheck(SecurityDescriptor, // FIXME: use CapturedSecurityDescriptor + &SubjectSecurityContext, + DesiredAccess, + PreviouslyGrantedAccess, + &PrivilegeSet, //FIXME + GenericMapping, + PreviousMode, + GrantedAccess, + AccessStatus); + } /* Unlock subject context */ SeUnlockSubjectContext(&SubjectSecurityContext); diff --git a/rosbuild.bat b/rosbuild.bat index 21f814b33a3..c8f5a7ce6c5 100644 --- a/rosbuild.bat +++ b/rosbuild.bat @@ -41,7 +41,7 @@ set "_ROSBE_FULL_PATH_=%_ROSBE_PATH_DIR%%_ROSBE_PATH_%" ::echo RosBE insall path = %_ROSBE_FULL_PATH_% :: Set the path which contains our build tools -set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%i386\bin +set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%Tools :: Add the path to the search path path=%path%;%_ROSBE_BIN_PATH% diff --git a/subsystems/win32/win32k/include/coord.h b/subsystems/win32/win32k/include/coord.h index c241b9eb9b6..83f3a355eaa 100644 --- a/subsystems/win32/win32k/include/coord.h +++ b/subsystems/win32/win32k/include/coord.h @@ -18,4 +18,6 @@ IntGdiModifyWorldTransform(PDC pDc, DWORD Mode); VOID FASTCALL IntMirrorWindowOrg(PDC); -void FASTCALL IntFixIsotropicMapping(PDC dc); +void FASTCALL IntFixIsotropicMapping(PDC); +LONG FASTCALL IntCalcFillOrigin(PDC); +PPOINTL FASTCALL IntptlBrushOrigin(PDC pdc,LONG,LONG); \ No newline at end of file diff --git a/subsystems/win32/win32k/include/dc.h b/subsystems/win32/win32k/include/dc.h index b616bdc0ba6..48b0e921400 100644 --- a/subsystems/win32/win32k/include/dc.h +++ b/subsystems/win32/win32k/include/dc.h @@ -177,6 +177,8 @@ HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC); BOOL FASTCALL IntGdiCleanDC(HDC hDC); VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS); INT FASTCALL IntGdiGetDeviceCaps(PDC,INT); +BOOL FASTCALL MakeInfoDC(PDC,BOOL); +BOOL FASTCALL IntSetDefaultRegion(PDC); extern PPDEVOBJ pPrimarySurface; @@ -228,6 +230,5 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal) pdc->dclevel.ppal = ppal; } -BOOL FASTCALL -IntPrepareDriverIfNeeded(VOID); +BOOL FASTCALL IntPrepareDriverIfNeeded(VOID); extern PDEVOBJ PrimarySurface; diff --git a/subsystems/win32/win32k/include/gdiobj.h b/subsystems/win32/win32k/include/gdiobj.h index 50ed2e6163f..6b9a7fd8aa8 100644 --- a/subsystems/win32/win32k/include/gdiobj.h +++ b/subsystems/win32/win32k/include/gdiobj.h @@ -131,3 +131,6 @@ GDIOBJ_IncrementShareCount(POBJ Object) #endif INT FASTCALL GreGetObjectOwner(HGDIOBJ, GDIOBJTYPE); + +#define GDIOBJ_GetKernelObj(Handle) \ + ((PGDI_TABLE_ENTRY)&GdiHandleTable->Entries[GDI_HANDLE_GET_INDEX(Handle)])->KernelData diff --git a/subsystems/win32/win32k/include/pdevobj.h b/subsystems/win32/win32k/include/pdevobj.h index 4124509fbe5..ca0c3fa0821 100644 --- a/subsystems/win32/win32k/include/pdevobj.h +++ b/subsystems/win32/win32k/include/pdevobj.h @@ -88,8 +88,8 @@ typedef struct _PDEVOBJ // PVOID TypeOneInfo; PVOID pvGammaRamp; /* Gamma ramp pointer. */ // PVOID RemoteTypeOne; -// ULONG ulHorzRes; -// ULONG ulVertRes; + ULONG ulHorzRes; + ULONG ulVertRes; // PFN_DrvSetPointerShape pfnDrvSetPointerShape; // PFN_DrvMovePointer pfnDrvMovePointer; PFN_DrvMovePointer pfnMovePointer; @@ -107,7 +107,7 @@ typedef struct _PDEVOBJ // HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */ // PVOID pDesktopId; PGRAPHICS_DEVICE pGraphicsDevice; -// POINTL ptlOrigion; + POINTL ptlOrigion; PVOID pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */ // DWORD Unknown3; FLONG DxDd_Flags; /* DxDD active status flags. */ @@ -141,4 +141,6 @@ typedef struct _PDEVEDD EDD_DIRECTDRAW_GLOBAL EDDgpl; } PDEVEDD, *PPDEVEDD; +PSIZEL FASTCALL PDEV_sizl(PPDEVOBJ, PSIZEL); + extern ULONG gdwDirectDrawContext; diff --git a/subsystems/win32/win32k/include/surface.h b/subsystems/win32/win32k/include/surface.h index 57a5ec24f85..3fe90540467 100644 --- a/subsystems/win32/win32k/include/surface.h +++ b/subsystems/win32/win32k/include/surface.h @@ -3,6 +3,8 @@ #include "win32.h" #include "gdiobj.h" +#define PDEV_SURFACE 0x80000000 + /* GDI surface object */ typedef struct _SURFACE { diff --git a/subsystems/win32/win32k/ntuser/input.c b/subsystems/win32/win32k/ntuser/input.c index f0790e19a7b..6b02f2d270e 100644 --- a/subsystems/win32/win32k/ntuser/input.c +++ b/subsystems/win32/win32k/ntuser/input.c @@ -713,6 +713,7 @@ KeyboardThreadMain(PVOID StartContext) for (;NumKeys;memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)), NumKeys--) { + PKBL keyboardLayout = NULL; lParam = 0; IntKeyboardUpdateLeds(KeyboardDeviceHandle, @@ -783,29 +784,30 @@ KeyboardThreadMain(PVOID StartContext) } /* Find the target thread whose locale is in effect */ - FocusQueue = IntGetFocusMessageQueue(); + FocusQueue = IntGetFocusMessageQueue(); - /* This might cause us to lose hot keys, which are important - * (ctrl-alt-del secure attention sequence). Not sure if it - * can happen though. - */ - if (!FocusQueue) - continue; + if (FocusQueue) + { + msg.hwnd = FocusQueue->FocusWindow; + + FocusThread = FocusQueue->Thread; + if (FocusThread && FocusThread->Tcb.Win32Thread) + { + keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout; + } + } + if (!keyboardLayout) + { + keyboardLayout = W32kGetDefaultKeyLayout(); + } msg.lParam = lParam; - msg.hwnd = FocusQueue->FocusWindow; - - FocusThread = FocusQueue->Thread; - - if (!(FocusThread && FocusThread->Tcb.Win32Thread && - ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout)) - continue; /* This function uses lParam to fill wParam according to the * keyboard layout in use. */ W32kKeyProcessMessage(&msg, - ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout->KBTables, + keyboardLayout->KBTables, KeyInput.Flags & KEY_E0 ? 0xE0 : (KeyInput.Flags & KEY_E1 ? 0xE1 : 0)); @@ -827,6 +829,11 @@ KeyboardThreadMain(PVOID StartContext) continue; /* Eat key up motion too */ } + if (!FocusQueue) + { + /* There is no focused window to receive a keyboard message */ + continue; + } /* * Post a keyboard message. */ diff --git a/subsystems/win32/win32k/ntuser/keyboard.c b/subsystems/win32/win32k/ntuser/keyboard.c index 0c935a478e0..813137856fc 100644 --- a/subsystems/win32/win32k/ntuser/keyboard.c +++ b/subsystems/win32/win32k/ntuser/keyboard.c @@ -88,12 +88,12 @@ static VOID APIENTRY SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down) gQueueKeyStateTable[vk] ^= KS_LOCK_BIT; } - if (ext && vk == VK_LSHIFT) - vk = VK_RSHIFT; - if (ext && vk == VK_LCONTROL) - vk = VK_RCONTROL; - if (ext && vk == VK_LMENU) - vk = VK_RMENU; + if (vk == VK_SHIFT) + vk = ext ? VK_RSHIFT : VK_LSHIFT; + if (vk == VK_CONTROL) + vk = ext ? VK_RCONTROL : VK_LCONTROL; + if (vk == VK_MENU) + vk = ext ? VK_RMENU : VK_LMENU; if (down) gQueueKeyStateTable[vk] |= KS_DOWN_BIT; diff --git a/subsystems/win32/win32k/objects/brush.c b/subsystems/win32/win32k/objects/brush.c index 6e827fa7bae..f45f6fbcdd4 100644 --- a/subsystems/win32/win32k/objects/brush.c +++ b/subsystems/win32/win32k/objects/brush.c @@ -709,6 +709,7 @@ NtGdiSetBrushOrg(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point) pdcattr->ptlBrushOrigin.x = XOrg; pdcattr->ptlBrushOrigin.y = YOrg; + IntptlBrushOrigin(dc, XOrg, YOrg ); DC_UnlockDc(dc); return TRUE; diff --git a/subsystems/win32/win32k/objects/coord.c b/subsystems/win32/win32k/objects/coord.c index 6b80f1d463e..0ae25bcc10d 100644 --- a/subsystems/win32/win32k/objects/coord.c +++ b/subsystems/win32/win32k/objects/coord.c @@ -1133,6 +1133,16 @@ IntCalcFillOrigin(PDC pdc) return pdc->ptlFillOrigin.y; } +PPOINTL +FASTCALL +IntptlBrushOrigin(PDC pdc, LONG x, LONG y ) +{ + pdc->dclevel.ptlBrushOrigin.x = x; + pdc->dclevel.ptlBrushOrigin.y = y; + IntCalcFillOrigin(pdc); + return &pdc->dclevel.ptlBrushOrigin; +} + VOID APIENTRY GdiSetDCOrg(HDC hDC, LONG Left, LONG Top, PRECTL prc) diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c index 3837b78567d..1fe51886b2a 100644 --- a/subsystems/win32/win32k/objects/dclife.c +++ b/subsystems/win32/win32k/objects/dclife.c @@ -119,6 +119,8 @@ DC_AllocDC(PUNICODE_STRING Driver) pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT); TextIntRealizeFont(pdcattr->hlfntNew,NULL); + NewDC->hlfntCur = pdcattr->hlfntNew; + NewDC->dclevel.plfnt = GDIOBJ_GetKernelObj(pdcattr->hlfntNew); NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE); NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal); @@ -586,8 +588,59 @@ DC_InitDC(HDC DCHandle) NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0); } +BOOL +FASTCALL +MakeInfoDC(PDC pdc, BOOL bSet) +{ + PSURFACE pSurface; + SIZEL sizl; + + /* Can not be a display DC. */ + if (pdc->fs & DC_FLAG_DISPLAY) return FALSE; + if (bSet) + { + if (pdc->fs & DC_FLAG_TEMPINFODC || pdc->dctype == DC_TYPE_DIRECT) + return FALSE; + + pSurface = pdc->dclevel.pSurface; + pdc->fs |= DC_FLAG_TEMPINFODC; + pdc->pSurfInfo = pSurface; + pdc->dctype = DC_TYPE_INFO; + pdc->dclevel.pSurface = NULL; + + PDEV_sizl(pdc->ppdev, &sizl); + + if ( sizl.cx == pdc->dclevel.sizl.cx && + sizl.cy == pdc->dclevel.sizl.cy ) + return TRUE; + + pdc->dclevel.sizl.cx = sizl.cx; + pdc->dclevel.sizl.cy = sizl.cy; + } + else + { + if (!(pdc->fs & DC_FLAG_TEMPINFODC) || pdc->dctype != DC_TYPE_INFO) + return FALSE; + + pSurface = pdc->pSurfInfo; + pdc->fs &= ~DC_FLAG_TEMPINFODC; + pdc->dclevel.pSurface = pSurface; + pdc->dctype = DC_TYPE_DIRECT; + pdc->pSurfInfo = NULL; + + if ( !pSurface || + (pSurface->SurfObj.sizlBitmap.cx == pdc->dclevel.sizl.cx && + pSurface->SurfObj.sizlBitmap.cy == pdc->dclevel.sizl.cy) ) + return TRUE; + + pdc->dclevel.sizl.cx = pSurface->SurfObj.sizlBitmap.cx; + pdc->dclevel.sizl.cy = pSurface->SurfObj.sizlBitmap.cy; + } + return IntSetDefaultRegion(pdc); +} + /* -* @unimplemented +* @implemented */ BOOL APIENTRY @@ -595,7 +648,14 @@ NtGdiMakeInfoDC( IN HDC hdc, IN BOOL bSet) { - UNIMPLEMENTED; + BOOL Ret; + PDC pdc = DC_LockDc(hdc); + if (pdc) + { + Ret = MakeInfoDC(pdc, bSet); + DC_UnlockDc(pdc); + return Ret; + } return FALSE; } @@ -704,34 +764,16 @@ NtGdiCreateCompatibleDC(HDC hDC) BOOL APIENTRY NtGdiDeleteObjectApp(HANDLE DCHandle) -{ - /* Complete all pending operations */ - NtGdiFlushUserBatch(); - - if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE; - - if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC) - return GreDeleteObject((HGDIOBJ) DCHandle); - - if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE; - - if (!GDIOBJ_OwnedByCurrentProcess(DCHandle)) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - - return IntGdiDeleteDC(DCHandle, FALSE); -} - -BOOL -APIENTRY -NewNtGdiDeleteObjectApp(HANDLE DCHandle) { GDIOBJTYPE ObjType; + /* Complete all pending operations */ + NtGdiFlushUserBatch(); + if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE; + if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE; + ObjType = GDI_HANDLE_GET_TYPE(DCHandle) >> GDI_ENTRY_UPPER_SHIFT; if (GreGetObjectOwner( DCHandle, ObjType)) diff --git a/subsystems/win32/win32k/objects/dcutil.c b/subsystems/win32/win32k/objects/dcutil.c index 9721af3147f..a8c28ecb348 100644 --- a/subsystems/win32/win32k/objects/dcutil.c +++ b/subsystems/win32/win32k/objects/dcutil.c @@ -125,6 +125,71 @@ IntIsPrimarySurface(SURFOBJ *SurfObj) } #endif +BOOL +FASTCALL +IntSetDefaultRegion(PDC pdc) +{ + PSURFACE pSurface; + PROSRGNDATA prgn; + RECTL rclWnd, rclClip; + + IntGdiReleaseRaoRgn(pdc); + + rclWnd.left = 0; + rclWnd.top = 0; + rclWnd.right = pdc->dclevel.sizl.cx; + rclWnd.bottom = pdc->dclevel.sizl.cy; + rclClip = rclWnd; + +// EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock); + if (pdc->ppdev->flFlags & PDEV_META_DEVICE) + { + pSurface = pdc->dclevel.pSurface; + if (pSurface && pSurface->flFlags & PDEV_SURFACE) + { + rclClip.left += pdc->ppdev->ptlOrigion.x; + rclClip.top += pdc->ppdev->ptlOrigion.y; + rclClip.right += pdc->ppdev->ptlOrigion.x; + rclClip.bottom += pdc->ppdev->ptlOrigion.y; + } + } +// EngReleaseSemaphore(pdc->ppdev->hsemDevLock); + + prgn = pdc->prgnVis; + + if (prgn && prgn != prgnDefault) + { + REGION_SetRectRgn( prgn, + rclClip.left, + rclClip.top, + rclClip.right , + rclClip.bottom ); + } + else + { + prgn = IntSysCreateRectpRgn( rclClip.left, + rclClip.top, + rclClip.right , + rclClip.bottom ); + pdc->prgnVis = prgn; + } + + if (prgn) + { + pdc->ptlDCOrig.x = 0; + pdc->ptlDCOrig.y = 0; + pdc->erclWindow = rclWnd; + pdc->erclClip = rclClip; + /* Might be an InitDC or DCE....*/ + pdc->ptlFillOrigin.x = pdc->dcattr.VisRectRegion.Rect.right; + pdc->ptlFillOrigin.y = pdc->dcattr.VisRectRegion.Rect.bottom; + return TRUE; + } + + pdc->prgnVis = prgnDefault; + return FALSE; +} + BOOL APIENTRY NtGdiCancelDC(HDC hDC) diff --git a/subsystems/win32/win32k/objects/device.c b/subsystems/win32/win32k/objects/device.c index 40a79562ede..b1158471282 100644 --- a/subsystems/win32/win32k/objects/device.c +++ b/subsystems/win32/win32k/objects/device.c @@ -19,6 +19,22 @@ static KEVENT VideoDriverNeedsPreparation; static KEVENT VideoDriverPrepared; PDC defaultDCstate = NULL; +PSIZEL +FASTCALL +PDEV_sizl(PPDEVOBJ ppdev, PSIZEL psizl) +{ + if (ppdev->flFlags & PDEV_META_DEVICE) + { + psizl->cx = ppdev->ulHorzRes; + psizl->cy = ppdev->ulVertRes; + } + else + { + psizl->cx = ppdev->gdiinfo.ulHorzRes; + psizl->cy = ppdev->gdiinfo.ulVertRes; + } + return psizl; +} NTSTATUS FASTCALL InitDcImpl(VOID) diff --git a/subsystems/win32/win32k/objects/font.c b/subsystems/win32/win32k/objects/font.c index 41a75cdb43f..6127d835f42 100644 --- a/subsystems/win32/win32k/objects/font.c +++ b/subsystems/win32/win32k/objects/font.c @@ -251,6 +251,49 @@ RealizeFontInit(HFONT hFont) return pTextObj; } +HFONT +FASTCALL +GreSelectFont( HDC hDC, HFONT hFont) +{ + PDC pdc; + PDC_ATTR pdcattr; + PTEXTOBJ pOrgFnt, pNewFnt = NULL; + HFONT hOrgFont = NULL; + + if (!hDC || !hFont) return NULL; + + pdc = DC_LockDc(hDC); + if (!pdc) + { + return NULL; + } + + if (NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL))) + { + /* LFONTOBJ use share and locking. */ + pNewFnt = TEXTOBJ_LockText(hFont); + pdcattr = pdc->pdcattr; + pOrgFnt = pdc->dclevel.plfnt; + if (pOrgFnt) + { + hOrgFont = pOrgFnt->BaseObject.hHmgr; + } + else + { + hOrgFont = pdcattr->hlfntNew; + } + pdc->dclevel.plfnt = pNewFnt; + pdc->hlfntCur = hFont; + pdcattr->hlfntNew = hFont; + pdcattr->ulDirty_ |= DIRTY_CHARSET; + pdcattr->ulDirty_ &= ~SLOW_WIDTHS; + } + + if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt); + DC_UnlockDc(pdc); + return hOrgFont; +} + /** Functions ******************************************************************/ INT @@ -933,30 +976,7 @@ NtGdiSelectFont( IN HDC hDC, IN HFONT hFont) { - PDC pDC; - PDC_ATTR pdcattr; - HFONT hOrgFont = NULL; - - if (hDC == NULL || hFont == NULL) return NULL; - - pDC = DC_LockDc(hDC); - if (!pDC) - { - return NULL; - } - - pdcattr = pDC->pdcattr; - - /* FIXME: what if not successful? */ - if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL))) - { - hOrgFont = pdcattr->hlfntNew; - pdcattr->hlfntNew = hFont; - } - - DC_UnlockDc(pDC); - - return hOrgFont; + return GreSelectFont(hDC, hFont); } diff --git a/subsystems/win32/win32k/objects/gdibatch.c b/subsystems/win32/win32k/objects/gdibatch.c index b958ad4835d..ac174e971fb 100644 --- a/subsystems/win32/win32k/objects/gdibatch.c +++ b/subsystems/win32/win32k/objects/gdibatch.c @@ -106,9 +106,10 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) case GdiBCSetBrushOrg: { PGDIBSSETBRHORG pgSBO; - if(!dc) break; + if (!dc) break; pgSBO = (PGDIBSSETBRHORG) pHdr; pdcattr->ptlBrushOrigin = pgSBO->ptlBrushOrigin; + IntptlBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y); break; } case GdiBCExtSelClipRgn: @@ -116,10 +117,34 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) case GdiBCSelObj: { PGDIBSOBJECT pgO; - if(!dc) break; + PTEXTOBJ pOrgFnt, pNewFnt = NULL; + HFONT hOrgFont = NULL; + + if (!dc) break; pgO = (PGDIBSOBJECT) pHdr; - TextIntRealizeFont((HFONT) pgO->hgdiobj, NULL); - pdcattr->ulDirty_ &= ~(DIRTY_CHARSET); + + if (NT_SUCCESS(TextIntRealizeFont((HFONT)pgO->hgdiobj,NULL))) + { + /* LFONTOBJ use share and locking. */ + pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj); + + pOrgFnt = dc->dclevel.plfnt; + if (pOrgFnt) + { + hOrgFont = pOrgFnt->BaseObject.hHmgr; + } + else + { + hOrgFont = pdcattr->hlfntNew; + } + dc->dclevel.plfnt = pNewFnt; + dc->hlfntCur = pgO->hgdiobj; + pdcattr->hlfntNew = pgO->hgdiobj; + pdcattr->ulDirty_ |= DIRTY_CHARSET; + pdcattr->ulDirty_ &= ~SLOW_WIDTHS; + } + if (pNewFnt) TEXTOBJ_UnlockText(pNewFnt); + break; } case GdiBCDelRgn: DPRINT("Delete Region Object!\n");