diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a7c2cad321..e900205c757 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,8 +202,8 @@ else() include/psdk include/dxsdk ${REACTOS_BINARY_DIR}/include - ${REACTOS_BINARY_DIR}/include/dxsdk ${REACTOS_BINARY_DIR}/include/psdk + ${REACTOS_BINARY_DIR}/include/dxsdk ${REACTOS_BINARY_DIR}/include/reactos include/crt include/ddk diff --git a/base/applications/atactl/CMakeLists.txt b/base/applications/atactl/CMakeLists.txt index 05df18381b3..24e85a64138 100644 --- a/base/applications/atactl/CMakeLists.txt +++ b/base/applications/atactl/CMakeLists.txt @@ -1,4 +1,6 @@ + set_cpp() + add_definitions(-DUSER_MODE) include_directories(${REACTOS_SOURCE_DIR}/drivers/storage/ide/uniata) add_executable(atactl atactl.cpp atactl.rc) @@ -9,7 +11,6 @@ if(NOT MSVC) # FIXME: http://www.cmake.org/Bug/view.php?id=12998 #allow_warnings(atactl) set_source_files_properties(atactl.cpp PROPERTIES COMPILE_FLAGS "-Wno-error") - target_link_libraries(atactl gcc) endif() add_cd_file(TARGET atactl DESTINATION reactos/system32 FOR all) diff --git a/base/applications/calc/lang/tr-TR.rc b/base/applications/calc/lang/tr-TR.rc index c7930e9f62a..35ebaa394a2 100644 --- a/base/applications/calc/lang/tr-TR.rc +++ b/base/applications/calc/lang/tr-TR.rc @@ -1,3 +1,7 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT // Dialog @@ -547,7 +551,7 @@ BEGIN IDS_ENERGY_KILOJOULES "Kilojul" IDS_ENERGY_KILOWATT_HOURS "Kilovat-saat" IDS_ENERGY_NUTRITION_CALORIES "Besin kalorisi" - IDS_ENERGY_TH_CALORIES "Termokimyasal kalori" + IDS_ENERGY_TH_CALORIES "Termokimyevî kalori" END // TYPES OF LENGTHS diff --git a/base/applications/charmap/lang/tr-TR.rc b/base/applications/charmap/lang/tr-TR.rc index 60d14bc19bf..df24450d545 100644 --- a/base/applications/charmap/lang/tr-TR.rc +++ b/base/applications/charmap/lang/tr-TR.rc @@ -1,3 +1,7 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDD_CHARMAP DIALOGEX 6, 6, 292, 224 diff --git a/base/applications/dxdiag/lang/tr-TR.rc b/base/applications/dxdiag/lang/tr-TR.rc index a5ac796ebb9..ef36cedf74f 100644 --- a/base/applications/dxdiag/lang/tr-TR.rc +++ b/base/applications/dxdiag/lang/tr-TR.rc @@ -1,6 +1,8 @@ /* - * Çeviri: Arda Tanrıkulu (ardatanrikulu@gmail.com), Erdem Ersoy (erdemersoy@live.com) + * TRANSLATORS: 2012 - Arda Tanrıkulu (ardatanrikulu@gmail.com) + * 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDD_MAIN_DIALOG DIALOGEX DISCARDABLE 0, 0, 478, 280 @@ -153,7 +155,7 @@ FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "ReactInput Aygıtları", -1, 10, 10, 452, 80 CONTROL "", IDC_LIST_DEVICE, "SysListView32", LVS_REPORT | WS_CHILD | WS_BORDER | WS_TABSTOP, 20, 22, 432, 60 - GROUPBOX "Girişle İlgili Aygıtlar", -1, 10, 100, 452, 60 + GROUPBOX "Giriş Aygıtları", -1, 10, 100, 452, 60 CONTROL "", IDC_TREE_PORT, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 20, 112, 432, 40, 0x00000200 GROUPBOX "Notlar", -1, 10, 170, 452, 50 EDITTEXT IDC_RICH_INFO, 20, 182, 432, 30, WS_DISABLED | WS_TABSTOP @@ -175,55 +177,55 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_MAIN_DIALOG "ReactX Tanı Aracı" - IDS_SYSTEM_DIALOG "Dizge" - IDS_DISPLAY_DIALOG "Görüntü" - IDS_SOUND_DIALOG "Ses" - IDS_MUSIC_DIALOG "Mûsiki" - IDS_INPUT_DIALOG "Giriş" - IDS_NETWORK_DIALOG "Ağ" - IDS_HELP_DIALOG "Yardım" - IDS_FORMAT_MB "%I64u MB RAM" - IDS_FORMAT_SWAP "%I64u MB kullanıldı, %I64u MB kullanılabilir" - IDS_FORMAT_UNIPROC "%s (%u CPU)" - IDS_FORMAT_MPPROC "%s (%u CPU)" - IDS_VERSION_UNKNOWN "Bilinmeyen Sürüm" - IDS_DEVICE_STATUS_ATTACHED "Bağlı" - IDS_DEVICE_STATUS_MISSING "Bağlı değil" - IDS_DEVICE_STATUS_UNKNOWN "Bilinmiyor" - IDS_DEVICE_NAME "Aygıt Adı" - IDS_DEVICE_STATUS "Durum" - IDS_DEVICE_CONTROLLER "Denetleyici Kimliği" - IDS_DEVICE_MANUFACTURER "Üretici Kimliği" - IDS_DEVICE_PRODUCT "Ürün Kimliği" - IDS_DEVICE_FORCEFEEDBACK "Güç Geribildirimli Sürücüsü" - IDS_NOT_APPLICABLE "Uygulanamaz" - IDS_OPTION_YES "Evet" - IDS_DIRECTPLAY_COL_NAME1 "Ad" - IDS_DIRECTPLAY_COL_NAME2 "Değer" - IDS_DIRECTPLAY_COL_NAME3 "Kütük" - IDS_DIRECTPLAY_COL_NAME4 "Sürüm" - IDS_DIRECTPLAY8_MODEMSP "ReactPlay8 Çevirge Hizmeti Sağlayıcısı" - IDS_DIRECTPLAY8_SERIALSP "ReactPlay8 Dizi Hizmeti Sağlayıcısı" - IDS_DIRECTPLAY8_IPXSP "ReactPlay8 IPX Hizmeti Sağlayıcısı" - IDS_DIRECTPLAY8_TCPSP "ReactPlay8 TCP/IP Hizmeti Sağlayıcısı" - IDS_DIRECTPLAY_TCPCONN "ReactPlay için Genelağ TCP/IP Bağlantısı" - IDS_DIRECTPLAY_IPXCONN "ReactPlay için IPX Bağlantısı" - IDS_DIRECTPLAY_MODEMCONN "ReactPlay için Çeivrge Bağlantısı" - IDS_DIRECTPLAY_SERIALCONN "ReactPlay için Dizi Bağlantısı" - IDS_REG_SUCCESS "Tamam" - IDS_REG_FAIL "Hata" - IDS_DDTEST_ERROR "Sınama başarısız oldu." - IDS_DDTEST_DESCRIPTION "ReactDraw arayüz sınaması başlatılacak. Sürdürülsün mü?" - IDS_DDPRIMARY_DESCRIPTION "Bu sınama, ReactDraw'ı birincil yüzeye çizmek için kullanacak. Ekrana ak ve kara dikdörtgenler çizilecek. Sürdürülsün mü?" - IDS_DDPRIMARY_RESULT "Ekranda ak ve kara dikdörtgenler gördünüz mü?" - IDS_DDOFFSCREEN_DESCRIPTION "Bu sınama, ReactDraw'ı ekran dışı arabelleğe çizmek için kullanacak. Ekranda devinen bir ak dikdörtgen göreceksiniz. Sürdürülsün mü?" - IDS_DDOFFSCREEN_RESULT "Ekranda devinen bir ak dikdörtgen gördünüz mü?" - IDS_DDFULLSCREEN_DESCRIPTION "Bu sınama, ReactDraw'ı tam ekranda çizmek için kullanacak. Tam ekranda devinen bir ak dikdörtgen göreceksiniz. Sürdürülsün mü?" - IDS_DDFULLSCREEN_RESULT "Tam ekranda devinen bir ak dikdörtgen gördünüz mü?" - IDS_FORMAT_ADAPTER_MEM "%u MB" - IDS_FORMAT_ADAPTER_MODE "%04u x %04u (%u ikillik) (%uHz)" - IDS_OPTION_NO "Hayır" - IDS_D3DTEST_DESCRIPTION "React3D arayüz sınaması başlatılacak. Sürdürülsün mü?" - IDS_D3DTEST_D3Dx "Bu sınama, donanım hızlandırmalı React3D %u arayüzünü kullanacak." + IDS_MAIN_DIALOG "ReactX Tanı Aracı" + IDS_SYSTEM_DIALOG "Dizge" + IDS_DISPLAY_DIALOG "Görüntü" + IDS_SOUND_DIALOG "Ses" + IDS_MUSIC_DIALOG "Mûsiki" + IDS_INPUT_DIALOG "Giriş" + IDS_NETWORK_DIALOG "Ağ" + IDS_HELP_DIALOG "Yardım" + IDS_FORMAT_MB "%I64u MB RAM" + IDS_FORMAT_SWAP "%I64u MB kullanıldı, %I64u MB kullanılabilir" + IDS_FORMAT_UNIPROC "%s (%u CPU)" + IDS_FORMAT_MPPROC "%s (%u CPU)" + IDS_VERSION_UNKNOWN "Bilinmeyen Sürüm" + IDS_DEVICE_STATUS_ATTACHED "Bağlı" + IDS_DEVICE_STATUS_MISSING "Bağlı değil" + IDS_DEVICE_STATUS_UNKNOWN "Bilinmiyor" + IDS_DEVICE_NAME "Aygıt Adı" + IDS_DEVICE_STATUS "Durum" + IDS_DEVICE_CONTROLLER "Denetleyici Kimliği" + IDS_DEVICE_MANUFACTURER "Üretici Kimliği" + IDS_DEVICE_PRODUCT "Ürün Kimliği" + IDS_DEVICE_FORCEFEEDBACK "Güç Dönütlü Sürücüsü" + IDS_NOT_APPLICABLE "Uygulanamaz" + IDS_OPTION_YES "Evet" + IDS_DIRECTPLAY_COL_NAME1 "Ad" + IDS_DIRECTPLAY_COL_NAME2 "Değer" + IDS_DIRECTPLAY_COL_NAME3 "Kütük" + IDS_DIRECTPLAY_COL_NAME4 "Sürüm" + IDS_DIRECTPLAY8_MODEMSP "ReactPlay8 Çevirge Hizmeti Sağlayıcısı" + IDS_DIRECTPLAY8_SERIALSP "ReactPlay8 Dizilik Hizmeti Sağlayıcısı" + IDS_DIRECTPLAY8_IPXSP "ReactPlay8 IPX Hizmeti Sağlayıcısı" + IDS_DIRECTPLAY8_TCPSP "ReactPlay8 TCP/IP Hizmeti Sağlayıcısı" + IDS_DIRECTPLAY_TCPCONN "ReactPlay için Örütbağ TCP/IP Bağlantısı" + IDS_DIRECTPLAY_IPXCONN "ReactPlay için IPX Bağlantısı" + IDS_DIRECTPLAY_MODEMCONN "ReactPlay için Çeivrge Bağlantısı" + IDS_DIRECTPLAY_SERIALCONN "ReactPlay için Dizilik Bağlantı" + IDS_REG_SUCCESS "Tamam" + IDS_REG_FAIL "Hatâ" + IDS_DDTEST_ERROR "Sınama başarısız oldu." + IDS_DDTEST_DESCRIPTION "ReactDraw arayüz sınaması başlatılacak. Sürdürülsün mü?" + IDS_DDPRIMARY_DESCRIPTION "Bu sınama, ReactDraw'ı birincil yüzeye çizmek için kullanacak. Ekrana ak ve kara dikdörtgenler çizilecek. Sürdürülsün mü?" + IDS_DDPRIMARY_RESULT "Ekranda ak ve kara dikdörtgenler gördünüz mü?" + IDS_DDOFFSCREEN_DESCRIPTION "Bu sınama, ReactDraw'ı ekran dışı arabelleğe çizmek için kullanacak. Ekranda devinen bir ak dikdörtgen göreceksiniz. Sürdürülsün mü?" + IDS_DDOFFSCREEN_RESULT "Ekranda devinen bir ak dikdörtgen gördünüz mü?" + IDS_DDFULLSCREEN_DESCRIPTION "Bu sınama, ReactDraw'ı tam ekranda çizmek için kullanacak. Tam ekranda devinen bir ak dikdörtgen göreceksiniz. Sürdürülsün mü?" + IDS_DDFULLSCREEN_RESULT "Tam ekranda devinen bir ak dikdörtgen gördünüz mü?" + IDS_FORMAT_ADAPTER_MEM "%u MB" + IDS_FORMAT_ADAPTER_MODE "%04u x %04u (%u ikillik) (%uHz)" + IDS_OPTION_NO "Hayır" + IDS_D3DTEST_DESCRIPTION "React3D arayüz sınaması başlatılacak. Sürdürülsün mü?" + IDS_D3DTEST_D3Dx "Bu sınama, donanım hızlandırmalı React3D %u arayüzünü kullanacak." END diff --git a/base/applications/fontview/fontview.c b/base/applications/fontview/fontview.c index 4deea84a424..8ecf477fb90 100644 --- a/base/applications/fontview/fontview.c +++ b/base/applications/fontview/fontview.c @@ -94,7 +94,17 @@ WinMain (HINSTANCE hThisInstance, HINSTANCE hDLL; PGFRI GetFontResourceInfoW; LPCWSTR fileName; + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + default: + break; + } + g_hInstance = hThisInstance; /* Get unicode command line */ diff --git a/base/applications/fontview/fontview.h b/base/applications/fontview/fontview.h index 9dd5ac7dc17..578c1c49902 100644 --- a/base/applications/fontview/fontview.h +++ b/base/applications/fontview/fontview.h @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "resource.h" diff --git a/base/applications/fontview/fontview.rc b/base/applications/fontview/fontview.rc index 315e51861fb..226d4a71417 100644 --- a/base/applications/fontview/fontview.rc +++ b/base/applications/fontview/fontview.rc @@ -66,6 +66,9 @@ END #ifdef LANGUAGE_SV_SE #include "lang/sv-SE.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/base/applications/fontview/lang/tr-TR.rc b/base/applications/fontview/lang/tr-TR.rc new file mode 100644 index 00000000000..4d0b966381b --- /dev/null +++ b/base/applications/fontview/lang/tr-TR.rc @@ -0,0 +1,16 @@ +/* + * TRANSLATORS: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT +STRINGTABLE DISCARDABLE +BEGIN + IDS_INSTALL, "Kur..." + IDS_PRINT, "Yazdır..." + IDS_STRING, "ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ 1234567890" + IDS_OPEN, "Yazı Türü Aç..." + IDS_ERROR, "Hatâ" + IDS_ERROR_NOMEM, "Bu işlemin tamamlanması için yeterli bellek yok." + IDS_ERROR_NOFONT, "%1 kütüğü, geçerli bir yazı türü kütüğü değil." + IDS_ERROR_NOCLASS, "Pencere sınıfı başlatılamadı." +END diff --git a/base/applications/games/solitaire/CMakeLists.txt b/base/applications/games/solitaire/CMakeLists.txt index b91c58405fa..9bb86e79276 100644 --- a/base/applications/games/solitaire/CMakeLists.txt +++ b/base/applications/games/solitaire/CMakeLists.txt @@ -1,5 +1,5 @@ -set_cpp() +set_cpp(WITH_RUNTIME) include_directories(${REACTOS_SOURCE_DIR}/lib/3rdparty/cardlib) diff --git a/base/applications/games/solitaire/lang/tr-TR.rc b/base/applications/games/solitaire/lang/tr-TR.rc index f97c3d6a20c..80989414c02 100644 --- a/base/applications/games/solitaire/lang/tr-TR.rc +++ b/base/applications/games/solitaire/lang/tr-TR.rc @@ -1,10 +1,10 @@ /* - * PROJECT: Solitaire + * PROJECT: ReactOS Solitaire * LICENSE: Freeware, permission to use under Public Domain * FILE: base/applications/games/solitaire/lang/tr-TR.rc - * PURPOSE: Turkish Language File for Solitaire + * PURPOSE: Turkish Resource File for ReactOS Solitaire * PROGRAMMERS: Daniel "EmuandCo" Reimer (reimer.daniel@freenet.de) - * TRANSLATOR: Erdem Ersoy (eersoy93) + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT diff --git a/base/applications/games/spider/CMakeLists.txt b/base/applications/games/spider/CMakeLists.txt index 526e4017025..83660dd9d71 100644 --- a/base/applications/games/spider/CMakeLists.txt +++ b/base/applications/games/spider/CMakeLists.txt @@ -1,7 +1,9 @@ -set_cpp() +set_cpp(WITH_RUNTIME) -include_directories(${REACTOS_SOURCE_DIR}/lib/3rdparty/cardlib ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories( + ${REACTOS_SOURCE_DIR}/lib/3rdparty/cardlib + ${CMAKE_CURRENT_SOURCE_DIR}) add_executable(spider spider.cpp diff --git a/base/applications/games/spider/lang/tr-TR.rc b/base/applications/games/spider/lang/tr-TR.rc index 89a0a3ee5af..ce2c1d318f7 100644 --- a/base/applications/games/spider/lang/tr-TR.rc +++ b/base/applications/games/spider/lang/tr-TR.rc @@ -1,9 +1,10 @@ /* - * PROJECT: Spider Solitaire - * LICENSE: See COPYING in top level directory - * FILE: base/applications/games/spider/lang/tr-TR.rc - * PURPOSE: Turkish Language File for Spider Solitaire - * TRANSLATOR: Erdem Ersoy (eersoy93) + * PROJECT: ReactOS Spider Solitaire + * LICENSE: See COPYING in top level directory + * FILE: base/applications/games/spider/lang/tr-TR.rc + * PURPOSE: Turkish Resource File for ReactOS Spider Solitaire + * PROGRAMMERS: + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT diff --git a/base/applications/games/winmine/lang/tr-TR.rc b/base/applications/games/winmine/lang/tr-TR.rc index 6720aedfee2..71fa78aac78 100644 --- a/base/applications/games/winmine/lang/tr-TR.rc +++ b/base/applications/games/winmine/lang/tr-TR.rc @@ -1,9 +1,8 @@ /* - * WineMine - * Turkish Language Support + * Turkish Resources for ReactOS Winmine * - * Copyright 2006 Fatih Aşıcı - * Copyright 2013 Erdem Ersoy (eersoy93) + * Copyrights: 2006 Fatih Aşıcı + * 2013 Erdem Ersoy (eersoy93) (erdemersoy@live.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -81,8 +80,8 @@ STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHEL CAPTION "Özel" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "&Satır Sayısı:", -1, 5, 5, 30, 10 - LTEXT "S&ütun Sayısı:", -1, 5, 35, 30, 10 + LTEXT "&Yataç Sayısı:", -1, 5, 5, 30, 10 + LTEXT "&Dikeç Sayısı:", -1, 5, 35, 30, 10 LTEXT "&Mayın Sayısı:", -1, 5, 65, 30, 10 EDITTEXT IDC_EDITROWS, 5, 15, 20, 12, ES_NUMBER EDITTEXT IDC_EDITCOLS, 5, 45, 20, 12, ES_NUMBER diff --git a/base/applications/kbswitch/kbswitch.c b/base/applications/kbswitch/kbswitch.c index ab021e77016..42f02391de9 100644 --- a/base/applications/kbswitch/kbswitch.c +++ b/base/applications/kbswitch/kbswitch.c @@ -518,6 +518,15 @@ _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdSh MSG msg; HANDLE hMutex; + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + default: + break; + } + hMutex = CreateMutex(NULL, FALSE, szKbSwitcherName); if (!hMutex) return 1; diff --git a/base/applications/kbswitch/lang/tr-TR.rc b/base/applications/kbswitch/lang/tr-TR.rc index a9f5e137449..76996d0f286 100644 --- a/base/applications/kbswitch/lang/tr-TR.rc +++ b/base/applications/kbswitch/lang/tr-TR.rc @@ -1,3 +1,7 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDR_POPUP MENU diff --git a/base/applications/magnify/lang/tr-TR.rc b/base/applications/magnify/lang/tr-TR.rc index d50bffd8183..7b7b3377b16 100644 --- a/base/applications/magnify/lang/tr-TR.rc +++ b/base/applications/magnify/lang/tr-TR.rc @@ -2,8 +2,9 @@ * PROJECT: ReactOS Magnifier * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/magnify/lang/tr-TR.rc - * PURPOSE: Turkish Language File for Magnifier - * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) + * PURPOSE: Turkish Resource File for RecatOS Magnifier + * PROGRAMMERS: + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT diff --git a/base/applications/magnify/magnifier.c b/base/applications/magnify/magnifier.c index 126acccc56b..671b082ef4f 100644 --- a/base/applications/magnify/magnifier.c +++ b/base/applications/magnify/magnifier.c @@ -49,6 +49,16 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } + // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); MyRegisterClass(hInstance); @@ -170,7 +180,7 @@ void Draw(HDC aDc) HDC HdcStrech; HANDLE hOld; HBITMAP HbmpStrech; - + RECT R; RECT appRect; DWORD rop = SRCCOPY; @@ -202,7 +212,7 @@ void Draw(HDC aDc) /* Select our bitmap in memory DC and save the old one.*/ hOld = SelectObject (HdcStrech , HbmpStrech); - + /* Paint the screen bitmap to our in memory DC */ BitBlt( HdcStrech, @@ -214,7 +224,7 @@ void Draw(HDC aDc) 0, 0, SRCCOPY); - + /* Draw the mouse pointer in the right position */ DrawIcon( HdcStrech , @@ -271,8 +281,9 @@ void Draw(HDC aDc) blitAreaY, blitAreaWidth, blitAreaHeight, - rop); - + rop | NOMIRRORBITMAP); + + /* Cleanup.*/ if (iinfo.hbmMask) DeleteObject(iinfo.hbmMask); diff --git a/base/applications/magnify/magnifier.h b/base/applications/magnify/magnifier.h index 6deb5c11dd1..4b211d557ef 100644 --- a/base/applications/magnify/magnifier.h +++ b/base/applications/magnify/magnifier.h @@ -25,6 +25,7 @@ #include #include #include +#include //test #include "resource.h" diff --git a/base/applications/mmc/lang/tr-TR.rc b/base/applications/mmc/lang/tr-TR.rc new file mode 100644 index 00000000000..e669b0027fb --- /dev/null +++ b/base/applications/mmc/lang/tr-TR.rc @@ -0,0 +1,25 @@ +/* + * TRANSLATORS: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +IDM_CONSOLEROOT MENU DISCARDABLE +BEGIN + POPUP "&Kütük" + BEGIN + MENUITEM SEPARATOR + MENUITEM "&Çıkış\tAlt+F4", ID_FILE_EXIT + END + + POPUP "&Yardım" + BEGIN + MENUITEM "&Hakkında...", ID_HELP_ABOUT + END +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APPTITLE "Yönetim Konsolu" + IDS_CONSOLETITLE "Konsol%1!u!" +END diff --git a/base/applications/mmc/rsrc.rc b/base/applications/mmc/rsrc.rc index 35e6cf55416..ddc56049ad5 100644 --- a/base/applications/mmc/rsrc.rc +++ b/base/applications/mmc/rsrc.rc @@ -58,6 +58,9 @@ #ifdef LANGUAGE_SV_SE #include "lang/sv-SE.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/base/applications/mplay32/lang/tr-TR.rc b/base/applications/mplay32/lang/tr-TR.rc index 8628e026482..ec7a357d3bd 100644 --- a/base/applications/mplay32/lang/tr-TR.rc +++ b/base/applications/mplay32/lang/tr-TR.rc @@ -1,30 +1,34 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDR_MAINMENU MENU BEGIN - POPUP "&Kütük" - BEGIN - MENUITEM "&Aç...", IDM_OPEN_FILE - MENUITEM "&Kapat", IDM_CLOSE_FILE - MENUITEM SEPARATOR - MENUITEM "&Çıkış", IDM_EXIT - END - POPUP "&Yardım" - BEGIN - MENUITEM "&Hakkında", IDM_ABOUT - END + POPUP "&Kütük" + BEGIN + MENUITEM "&Aç...", IDM_OPEN_FILE + MENUITEM "&Kapat", IDM_CLOSE_FILE + MENUITEM SEPARATOR + MENUITEM "&Çıkış", IDM_EXIT + END + POPUP "&Yardım" + BEGIN + MENUITEM "&Hakkında", IDM_ABOUT + END END STRINGTABLE DISCARDABLE BEGIN - IDS_ALL_TYPES_FILTER "Desteklenen Kütükler (*.wav, *.cda, *.mid, *.midi, *.avi)\0*.wav;*.cda;*.mid;*.midi;*.avi\0" - IDS_TOOLTIP_PLAY "Çal" - IDS_TOOLTIP_STOP "Durdur" - IDS_TOOLTIP_EJECT "Çıkar" - IDS_TOOLTIP_BACKWARD "Bir Önceki" - IDS_TOOLTIP_SEEKBACK "Geri Sar" - IDS_TOOLTIP_SEEKFORW "İleri Sar" - IDS_TOOLTIP_FORWARD "Bir Sonraki" - IDS_APPTITLE "Ortam Oynatıcısı" - IDS_PLAY "Çal" + IDS_ALL_TYPES_FILTER "Desteklenen Kütükler (*.wav, *.cda, *.mid, *.midi, *.avi)\0*.wav;*.cda;*.mid;*.midi;*.avi\0" + IDS_TOOLTIP_PLAY "Çal" + IDS_TOOLTIP_STOP "Durdur" + IDS_TOOLTIP_EJECT "Çıkar" + IDS_TOOLTIP_BACKWARD "Bir Önceki" + IDS_TOOLTIP_SEEKBACK "Geri Sar" + IDS_TOOLTIP_SEEKFORW "İleri Sar" + IDS_TOOLTIP_FORWARD "Bir Sonraki" + IDS_APPTITLE "Ortam Oynatıcısı" + IDS_PLAY "Çal" END diff --git a/base/applications/msconfig/lang/tr-TR.rc b/base/applications/msconfig/lang/tr-TR.rc new file mode 100644 index 00000000000..da74f8d4e8e --- /dev/null +++ b/base/applications/msconfig/lang/tr-TR.rc @@ -0,0 +1,178 @@ +/* + * TRANSLATORS: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +IDD_MSCONFIG_DIALOG DIALOGEX DISCARDABLE 0, 0, 378, 220 +STYLE DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +CAPTION "Dizge Yapılandırıcı" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Tab1",IDC_TAB,"SysTabControl32", WS_TABSTOP, 2, 2, 374, 195 + DEFPUSHBUTTON "Tamam", IDOK, 211, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Yardım", IDC_BTN_HELP, 2, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "Vazgeç", IDCANCEL, 267, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + PUSHBUTTON "&Uygula", IDC_BTN_APPLY, 323, 201, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +IDD_STARTUP_PAGE DIALOGEX DISCARDABLE 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "List3",IDC_STARTUP_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 2, 1, 360, 148 + PUSHBUTTON "&Hepsini Etkinleştir", IDC_BTN_STARTUP_ACTIVATE, 223, 155, 66, 14 + PUSHBUTTON "H&epsini Devre Dışı Bırak", IDC_BTN_STARTUP_DEACTIVATE, 295, 155, 66, 14 +END + +IDD_SYSTEM_PAGE DIALOGEX DISCARDABLE 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", IDC_SYSTEM_TREE, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 2, 1, 280, 148 + PUSHBUTTON "B&ir Yukarı Taşı", IDC_BTN_SYSTEM_UP, 290, 5, 66, 14 + PUSHBUTTON "Bi&r Aşağı Taşı", IDC_BTN_SYSTEM_DOWN, 290, 25, 66, 14 + + PUSHBUTTON "E&tkinleştir", IDC_BTN_SYSTEM_ENABLE, 290, 50, 66, 14 + PUSHBUTTON "&Devre Dışı Bırak", IDC_BTN_SYSTEM_DISABLE, 290, 70, 66, 14 + + PUSHBUTTON "&Ara", IDC_BTN_SYSTEM_FIND, 290, 95, 66, 14 + PUSHBUTTON "Ye&ni", IDC_BTN_SYSTEM_NEW, 290, 115, 66, 14 + PUSHBUTTON "De&ğiştir", IDC_BTN_SYSTEM_EDIT, 290, 135, 66, 14 + + PUSHBUTTON "&Hepsini Etkinleştir", IDC_BTN_SYSTEM_ACTIVATE, 123, 155, 66, 14 + PUSHBUTTON "H&epsini Devre Dışı Bırak",IDC_BTN_SYSTEM_DEACTIVATE, 195, 155, 66, 14 +END + +IDD_TOOLS_PAGE DIALOGEX DISCARDABLE 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "List2",IDC_TOOLS_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 2, 1, 360, 134 + EDITTEXT IDC_TOOLS_CMDLINE, 1, 139, 360, 12, ES_READONLY + PUSHBUTTON "&Çalıştır", IDC_BTN_RUN, 311, 155, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP +END + +IDD_SERVICES_PAGE DIALOGEX DISCARDABLE 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "List1",IDC_SERVICES_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 2, 1, 360, 148 + PUSHBUTTON "&Hepsini Etkinleştir", IDC_BTN_SERVICES_ACTIVATE, 223, 155, 66, 14 + PUSHBUTTON "H&epsini Devre Dışı Bırak", IDC_BTN_SERVICES_DEACTIVATE, 295, 155, 66, 14 +END + +IDD_GENERAL_PAGE DIALOGEX DISCARDABLE 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Başlangıç Seçenekleri", -1, 10, 10, 340, 150,0, WS_EX_TRANSPARENT + CONTROL "&Bilindik Başlangıç (Sürücülerin ve hizmetlerin tümü yüklensin.)", IDC_CBX_NORMAL_START, "Button", 0x50010009, 20, 30, 180, 10 + CONTROL "&Tanılık Başlangıç (Yalnızca sürücülerin ve hizmetlerin zorunluları yüklensin.)", IDC_CBX_DIAGNOSTIC_START, "Button", 0x50010009, 20, 45, 195, 10 + CONTROL "&Seçmeli Başlangıç", IDC_CBX_SELECTIVE_STARTUP, "Button", 0x50010009, 20, 60, 70, 10 + AUTOCHECKBOX "syst&em.ini Kütüğünü Yükle", IDC_CBX_SYSTEM_INI, 30, 80, 95, 10 + AUTOCHECKBOX "&Hizmetleri Yükle", IDC_CBX_SYSTEM_SERVICE, 30, 95, 90, 10 + AUTOCHECKBOX "B&aşlangıç Öğelerini Yükle", IDC_CBX_STARTUP_ITEM, 30, 110, 75, 10 +END + +IDD_FREELDR_PAGE DIALOGEX DISCARDABLE 0, 0, 362, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + LISTBOX IDC_LIST_BOX, 10, 10, 340, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL + PUSHBUTTON "&Tüm Ön Yükleme Yollarını Denetle", IDC_BTN_CHECK_BOOT_PATH, 10, 65, 70, 12 + PUSHBUTTON "&Ön Tanımlı Yap", IDC_BTN_SET_DEFAULT_BOOT, 100, 65, 70, 12 + PUSHBUTTON "B&ir Yukarı Taşı", IDC_BTN_MOVE_UP_BOOT_OPTION, 190, 65, 70, 12 + PUSHBUTTON "Bi&r Aşağı Taşı", IDC_BTN_MOVE_DOWN_BOOT_OPTION, 280, 65, 70, 12 + GROUPBOX "Ön Yükleme Seçenekleri", -1, 10, 80, 250, 90,0,WS_EX_TRANSPARENT + CHECKBOX "/SA&FEBOOT", IDC_CBX_SAFE_BOOT, 15, 90, 55, 10 + CHECKBOX "/&NOGUIBOOT", IDC_CBX_NO_GUI_BOOT, 15, 105, 60, 10 + CHECKBOX "/&BOOTLOG", IDC_CBX_BOOT_LOG, 15, 120, 50, 10 + CHECKBOX "/BAS&EVIDEO", IDC_CBX_BASE_VIDEO, 15, 135, 55, 10 + CHECKBOX "/S&OS", IDC_CBX_SOS, 15, 150, 50, 10 + PUSHBUTTON "&Gelişmiş Seçenekler...", IDC_BTN_ADVANCED_OPTIONS, 100, 150, 70, 12 + LTEXT "&Verilen Süre:", -1, 280, 91, 30, 10 + EDITTEXT IDC_TXT_BOOT_TIMEOUT, 310, 90, 25, 12, ES_LEFT + LTEXT "sec.", -1, 340, 91, 15, 10 +END + +IDD_FREELDR_ADVANCED_PAGE DIALOGEX DISCARDABLE 0, 0, 175, 175 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CHECKBOX "/&MAXMEM=", IDC_CBX_MAX_MEM, 10, 10, 50, 10 + EDITTEXT IDC_TXT_MAX_MEM, 80, 10, 60, 12 + CONTROL "",IDC_SCR_MAX_MEM, "msctls_updown32", 0x50000000, 140, 10, 11, 11 + CHECKBOX "/&NUMPROC=", IDC_CBX_NUM_PROC, 10, 25, 50, 10 + COMBOBOX IDC_DRP_NUM_PROC, 80, 25, 60, 10, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP + CHECKBOX "/&PCILOCK", IDC_CBX_PCI_LOCK, 10, 40, 50, 10 + CHECKBOX "/P&ROFILE", IDC_CBX_PROFILE, 10, 55, 50, 10 + CHECKBOX "/&IRQ", IDC_CBX_IRQ, 10, 70, 40, 12 + EDITTEXT IDC_TXT_IRQ, 80, 70, 60, 12, ES_LEFT + CHECKBOX "/&DEBUG", IDC_CBX_DEBUG, 10, 85, 40, 10 + CHECKBOX "/D&EBUGPORT", IDC_CBX_DEBUG_PORT, 20, 100, 60, 10 + COMBOBOX IDC_DRP_DEBUG_PORT, 80, 100, 60, 10, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP + CHECKBOX "/&BAUDRATE", IDC_CBX_BAUD_RATE, 20, 115, 50, 10 + COMBOBOX IDC_DRP_DRP_BAUD_RATE, 80, 115, 60, 10, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP + CHECKBOX "/&CHANNEL", IDC_CBX_CHANNEL, 20, 130, 50, 10 + EDITTEXT IDC_TXT_CHANNEL, 80, 130, 60, 12, ES_LEFT + CONTROL "",IDC_SCR_CHANNEL, "msctls_updown32", 0x50000000, 140, 130, 11, 11 + PUSHBUTTON "Tamam", IDC_OK, 20, 160, 50, 12 + PUSHBUTTON "Vazgeç", IDC_CANCEL, 100, 160, 50, 12 +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_MSCONFIG "Dizge Yapılandırıcı" + IDS_TAB_GENERAL "Umûmî" + IDS_TAB_SYSTEM "system.ini" + IDS_TAB_FREELDR "freeldr.ini" + IDS_TAB_SERVICES "Hizmetler" + IDS_TAB_STARTUP "Başlangıç" + IDS_TAB_TOOLS "Araçlar" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_SERVICES_COLUMN_SERVICE "Hizmet" + IDS_SERVICES_COLUMN_REQ "Gerekli" + IDS_SERVICES_COLUMN_VENDOR "Sağlayıcı" + IDS_SERVICES_COLUMN_STATUS "Durum" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TOOLS_COLUMN_NAME "Ad" + IDS_TOOLS_COLUMN_DESCR "Tanım" + + IDS_TOOLS_CMD_NAME "Komut İstemi" + IDS_TOOLS_CMD_DESCR "Komut İstemi'ni açar." + IDS_TOOLS_CMD_CMD "cmd.exe" + + IDS_TOOLS_INFO_NAME "ReactOS Sürümü Bilgisi" + IDS_TOOLS_INFO_DESCR "ReactOS'un sürüm bilgisini görüntüler." + IDS_TOOLS_INFO_CMD "winver.exe" + + IDS_TOOLS_REGEDIT_NAME "Değer Defteri Düzenleyicisi" + IDS_TOOLS_REGEDIT_DESCR "Değer Defteri Düzenleyicisi'ni açar." + IDS_TOOLS_REGEDIT_CMD "regedit.exe" + + IDS_TOOLS_SYSDM_NAME "Dizge Özellikleri" + IDS_TOOLS_SYSDM_DESCR "Bu bilgisayarla ilgili bilgi verir." + IDS_TOOLS_SYSDM_CMD "control.exe" + IDS_TOOLS_SYSDM_PARAM "sysdm.cpl" + + IDS_STARTUP_COLUMN_ELEMENT "Öğe" + IDS_STARTUP_COLUMN_CMD "Komut" + IDS_STARTUP_COLUMN_PATH "Yol" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_SERVICES_STATUS_RUNNING "Çalışıyor" + IDS_SERVICES_STATUS_STOPPED "Durduruldu" + IDS_SERVICES_YES "Evet" + IDS_SERVICES_UNKNOWN "Bilinmiyor" +END diff --git a/base/applications/msconfig/rsrc.rc b/base/applications/msconfig/rsrc.rc index a32fd208184..6f87a9c29e3 100644 --- a/base/applications/msconfig/rsrc.rc +++ b/base/applications/msconfig/rsrc.rc @@ -71,6 +71,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #ifdef LANGUAGE_TH_TH #include "lang/th-TH.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/base/applications/mscutils/devmgmt/devmgmt.c b/base/applications/mscutils/devmgmt/devmgmt.c index 2a4812df908..406a304f5b4 100644 --- a/base/applications/mscutils/devmgmt/devmgmt.c +++ b/base/applications/mscutils/devmgmt/devmgmt.c @@ -34,7 +34,17 @@ _tWinMain(HINSTANCE hThisInstance, } return 0; } + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + default: + break; + } + hInstance = hThisInstance; ProcessHeap = GetProcessHeap(); diff --git a/base/applications/mscutils/devmgmt/precomp.h b/base/applications/mscutils/devmgmt/precomp.h index 0454af851d7..83966705624 100644 --- a/base/applications/mscutils/devmgmt/precomp.h +++ b/base/applications/mscutils/devmgmt/precomp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/base/applications/mscutils/servman/precomp.h b/base/applications/mscutils/servman/precomp.h index 9bde57022b5..eb6d1076a54 100644 --- a/base/applications/mscutils/servman/precomp.h +++ b/base/applications/mscutils/servman/precomp.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include /* GET_X/Y_LPARAM */ diff --git a/base/applications/mscutils/servman/servman.c b/base/applications/mscutils/servman/servman.c index c6756d4db25..999decd55c3 100644 --- a/base/applications/mscutils/servman/servman.c +++ b/base/applications/mscutils/servman/servman.c @@ -8,7 +8,6 @@ */ #include "precomp.h" - HINSTANCE hInstance; HANDLE ProcessHeap; @@ -23,7 +22,17 @@ _tWinMain(HINSTANCE hThisInstance, MSG Msg; int Ret = 1; INITCOMMONCONTROLSEX icex; + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + default: + break; + } + hInstance = hThisInstance; ProcessHeap = GetProcessHeap(); diff --git a/base/applications/mspaint/lang/tr-TR.rc b/base/applications/mspaint/lang/tr-TR.rc index d64cdad6d2b..31ebaa61dd5 100644 --- a/base/applications/mspaint/lang/tr-TR.rc +++ b/base/applications/mspaint/lang/tr-TR.rc @@ -1,9 +1,10 @@ /* - * PROJECT: PAINT for ReactOS + * PROJECT: ReactOS Paint * LICENSE: unknown (LGPL assumed) * FILE: base/applications/mspaint/lang/tr-TR.rc - * PURPOSE: Turkish Language resource file - * TRANSLATORS: 2013 - Erdem Ersoy (eersoy93) + * PURPOSE: Turkish Resource file for ReactOS Paint + * PROGRAMMERS: + * TRANSLATORS: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT @@ -71,8 +72,8 @@ BEGIN MENUITEM "&Döndür ya da Evir...\tCtrl+R", IDM_IMAGEROTATEMIRROR MENUITEM "&Boyutlandır...\tCtrl+W", IDM_IMAGECHANGESIZE MENUITEM "&Kırp", IDM_IMAGECROP - MENUITEM "&Renkleri Evir...\tCtrl+I", IDM_IMAGEINVERTCOLORS - MENUITEM "&Öz Nitelikler\tCtrl+E", IDM_IMAGEATTRIBUTES + MENUITEM "&Renkleri Evir\tCtrl+I", IDM_IMAGEINVERTCOLORS + MENUITEM "&Öz Nitelikler...\tCtrl+E", IDM_IMAGEATTRIBUTES MENUITEM "R&esmi Temizle\tCtrl+Shft+N", IDM_IMAGEDELETEIMAGE MENUITEM "D&onuk Çiz", IDM_IMAGEDRAWOPAQUE END diff --git a/base/applications/mstsc/lang/tr-TR.rc b/base/applications/mstsc/lang/tr-TR.rc index 54a1b0ebc7e..c49d68df6e0 100644 --- a/base/applications/mstsc/lang/tr-TR.rc +++ b/base/applications/mstsc/lang/tr-TR.rc @@ -1,3 +1,7 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDD_GENERAL DIALOGEX 0, 0, 242, 175 @@ -50,7 +54,7 @@ END STRINGTABLE BEGIN - IDS_TAB_GENERAL "Genel" + IDS_TAB_GENERAL "Umûmî" IDS_TAB_DISPLAY "Görüntü" IDS_256COLORS "256 Renk" IDS_HIGHCOLOR15 "32,768 (15 İkillik) Renk" diff --git a/base/applications/network/CMakeLists.txt b/base/applications/network/CMakeLists.txt index dc22e24020a..4f95614999e 100644 --- a/base/applications/network/CMakeLists.txt +++ b/base/applications/network/CMakeLists.txt @@ -10,9 +10,7 @@ add_subdirectory(netstat) add_subdirectory(nslookup) add_subdirectory(ping) add_subdirectory(route) -if(NOT MSVC) - add_subdirectory(telnet) # FIXME: fix msvc build -endif() +add_subdirectory(telnet) add_subdirectory(tracert) add_subdirectory(whois) add_subdirectory(wlanconf) diff --git a/base/applications/network/telnet/CMakeLists.txt b/base/applications/network/telnet/CMakeLists.txt index 74f41d0ea5b..672a0de7130 100644 --- a/base/applications/network/telnet/CMakeLists.txt +++ b/base/applications/network/telnet/CMakeLists.txt @@ -1,8 +1,8 @@ +set_cpp(WITH_EXCEPTIONS WITH_STL) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) -set_cpp() - add_executable(telnet src/ansiprsr.cpp src/keytrans.cpp @@ -27,5 +27,9 @@ add_executable(telnet set_module_type(telnet win32cui) add_pch(telnet src/precomp.h) -add_importlibs(telnet ws2_32 user32 msvcrt kernel32) +add_importlibs(telnet ws2_32 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET telnet DESTINATION reactos/system32 FOR all) + +if(NOT MSVC) + add_compile_flags_language("-Wno-narrowing" "CXX") +endif() diff --git a/base/applications/network/telnet/src/precomp.h b/base/applications/network/telnet/src/precomp.h index 8691fbb04f3..1c8f9001f96 100644 --- a/base/applications/network/telnet/src/precomp.h +++ b/base/applications/network/telnet/src/precomp.h @@ -18,7 +18,7 @@ //#include //#include //#include -//#include +#include #include #include //#include diff --git a/base/applications/notepad/lang/tr-TR.rc b/base/applications/notepad/lang/tr-TR.rc index 1b5b8568de8..0135dcc835d 100644 --- a/base/applications/notepad/lang/tr-TR.rc +++ b/base/applications/notepad/lang/tr-TR.rc @@ -1,8 +1,8 @@ /* - * Notepad (Turkish resources) + * Turkish Resources for ReactOS Notepad * - * Copyright 2012 Arda Tanrıkulu - * Copyright 2013 Erdem Ersoy (eersoy93) + * Copyrights: 2012 Arda Tanrıkulu (ardatanrikulu@gmail.com) + * 2013 Erdem Ersoy (eersoy93) (erdemersoy@live.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -69,12 +69,12 @@ BEGIN MENUITEM "G&it...\tCtrl+G", CMD_GOTO MENUITEM SEPARATOR MENUITEM "&Tümünü Seç\tCtrl+A", CMD_SELECT_ALL - MENUITEM "&Şimdiki Zamanı Koy\tF5", CMD_TIME_DATE + MENUITEM "&Şimdiki Zamânı Koy\tF5", CMD_TIME_DATE END POPUP "&Biçim" BEGIN - MENUITEM "&Satır Kaydır", CMD_WRAP - MENUITEM "&Yazı Türü...", CMD_FONT + MENUITEM "&Yataç Kaydır", CMD_WRAP + MENUITEM "Y&azı Türü...", CMD_FONT END POPUP "&Görünüm" BEGIN @@ -83,7 +83,7 @@ BEGIN POPUP "&Yardım" BEGIN MENUITEM "&Yardım Konuları", CMD_HELP_CONTENTS - MENUITEM "Y&ardımda Ara...", CMD_HELP_SEARCH + MENUITEM "Y&ardımda Ara", CMD_HELP_SEARCH MENUITEM "Ya&rdım İçin Yardım", CMD_HELP_ON_HELP MENUITEM SEPARATOR MENUITEM "&Bilgi", CMD_ABOUT @@ -133,10 +133,10 @@ END DIALOG_GOTO DIALOGEX 0,0,165,50 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU FONT 8, "MS Shell Dlg" -CAPTION "Satıra Git" +CAPTION "Yataca Git" BEGIN EDITTEXT ID_LINENUMBER,54,10,106,12,WS_CHILD | WS_BORDER | WS_TABSTOP -LTEXT "Satır Nu:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER +LTEXT "Yataç Numarası:",0x155,5,12,41,12,WS_CHILD | WS_TABSTOP | ES_NUMBER DEFPUSHBUTTON "Tamam",IDOK, 75, 30, 40, 15, WS_CHILD | WS_TABSTOP PUSHBUTTON "Vazgeç",IDCANCEL, 120, 30, 40, 15, WS_CHILD | WS_TABSTOP END @@ -171,7 +171,7 @@ STRING_PAGESETUP_TOPVALUE, "25 mm" /* FIXME */ STRING_PAGESETUP_BOTTOMVALUE, "25 mm" /* FIXME */ STRING_NOTEPAD, "Metin Düzenleyicisi" -STRING_ERROR, "HATA" +STRING_ERROR, "HATÂ" STRING_WARNING, "UYARI" STRING_INFO, "Bilgi" @@ -194,5 +194,5 @@ STRING_UTF8, "UTF-8" STRING_CRLF, "Windows" STRING_LF, "UNIX" STRING_CR, "Mac" -STRING_LINE_COLUMN, "%d. Satır, %d. Sütun" +STRING_LINE_COLUMN, "%d. Yataç, %d. Dikeç" END diff --git a/base/applications/notepad/main.c b/base/applications/notepad/main.c index 30a1aa34b31..24d2458870c 100644 --- a/base/applications/notepad/main.c +++ b/base/applications/notepad/main.c @@ -554,9 +554,19 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE prev, LPTSTR cmdline, int sh HMONITOR monitor; MONITORINFO info; INT x, y; - + static const TCHAR className[] = _T("NPClass"); static const TCHAR winName[] = _T("Notepad"); + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } UNREFERENCED_PARAMETER(prev); diff --git a/base/applications/rapps/lang/tr-TR.rc b/base/applications/rapps/lang/tr-TR.rc index cf88c2d7cd6..f2b2aa1c061 100644 --- a/base/applications/rapps/lang/tr-TR.rc +++ b/base/applications/rapps/lang/tr-TR.rc @@ -1,55 +1,60 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDR_MAINMENU MENU BEGIN - POPUP "&Kütük" - BEGIN - MENUITEM "&Ayarlar...", ID_SETTINGS - MENUITEM SEPARATOR - MENUITEM "&Çıkış", ID_EXIT - END - POPUP "&Yazılım" - BEGIN - MENUITEM "&Kur", ID_INSTALL - MENUITEM "K&aldır", ID_UNINSTALL - MENUITEM "&Değiştir", ID_MODIFY - MENUITEM SEPARATOR - MENUITEM "&Bu Bilgiyi Değer Defteri'nden Kaldır.", ID_REGREMOVE - MENUITEM SEPARATOR - MENUITEM "&Yenile", ID_REFRESH - MENUITEM SEPARATOR - MENUITEM "Update Da&tabase", ID_RESETDB - END - POPUP "Y&ardım" - BEGIN - MENUITEM "&Yardım Konuları", ID_HELP, GRAYED - MENUITEM "&Hakkında", ID_ABOUT - END + POPUP "&Kütük" + BEGIN + MENUITEM "&Ayarlar...", ID_SETTINGS + MENUITEM SEPARATOR + MENUITEM "&Çıkış", ID_EXIT + END + POPUP "&Yazılım" + BEGIN + MENUITEM "&Kur", ID_INSTALL + MENUITEM "K&aldır", ID_UNINSTALL + MENUITEM "&Değiştir", ID_MODIFY + MENUITEM SEPARATOR + MENUITEM "&Girişi Değer Defteri'nden Kaldır", ID_REGREMOVE + MENUITEM SEPARATOR + MENUITEM "&Yenile", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "Y&azılım Veritabanını Güncelle", ID_RESETDB + END + POPUP "Y&ardım" + BEGIN + MENUITEM "&Yardım Konuları", ID_HELP, GRAYED + MENUITEM "&Hakkında", ID_ABOUT + END + END IDR_LINKMENU MENU BEGIN - POPUP "popup" - BEGIN - MENUITEM "&Tarayıcıda Aç", ID_OPEN_LINK - MENUITEM "&Panoya Çoğalt", ID_COPY_LINK - END + POPUP "popup" + BEGIN + MENUITEM "&Tarayıcıda Aç", ID_OPEN_LINK + MENUITEM "&Panoya Çoğalt", ID_COPY_LINK + END END IDR_APPLICATIONMENU MENU BEGIN - POPUP "popup" - BEGIN - MENUITEM "&Kur", ID_INSTALL - MENUITEM "K&aldır", ID_UNINSTALL - MENUITEM "&Değiştir", ID_MODIFY - MENUITEM SEPARATOR - MENUITEM "&Bu Bilgiyi Değer Defteri'nden Kaldır", ID_REGREMOVE - MENUITEM SEPARATOR - MENUITEM "&Yenile", ID_REFRESH - MENUITEM SEPARATOR - MENUITEM "Update Da&tabase", ID_RESETDB - END + POPUP "popup" + BEGIN + MENUITEM "&Kur", ID_INSTALL + MENUITEM "K&aldır", ID_UNINSTALL + MENUITEM "&Değiştir", ID_MODIFY + MENUITEM SEPARATOR + MENUITEM "&Girişi Değer Defteri'nden Kaldır", ID_REGREMOVE + MENUITEM SEPARATOR + MENUITEM "&Yenile", ID_REFRESH + MENUITEM SEPARATOR + MENUITEM "Y&azılım Veritabanını Güncelle", ID_RESETDB + END END IDD_SETTINGS_DIALOG DIALOGEX DISCARDABLE 0, 0, 250, 144 @@ -57,20 +62,20 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Ayarlar" FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Genel", -1, 4, 2, 240, 61 - AUTOCHECKBOX "&Pencere Konumunu Kaydet", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 - AUTOCHECKBOX "&Her Başlangıçta Erişilebilir Yazılım Dizelgesini Güncelle", IDC_UPDATE_AVLIST, 15, 29, 222, 12 - AUTOCHECKBOX "&Yazılımların Kuruluş ve Kaldırılışlarını Kaydet", IDC_LOG_ENABLED, 15, 46, 219, 12 + GROUPBOX "Umûmî", -1, 4, 2, 240, 61 + AUTOCHECKBOX "&Pencere Konumunu Kaydet", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12 + AUTOCHECKBOX "&Her Başlangıçta Erişilebilir Yazılım Dizelgesini Güncelle", IDC_UPDATE_AVLIST, 15, 29, 222, 12 + AUTOCHECKBOX "&Yazılımların Kuruluş ve Kaldırılışlarını Kaydet", IDC_LOG_ENABLED, 15, 46, 219, 12 - GROUPBOX "İndirme", -1, 4, 65, 240, 51 - LTEXT "İndirme Dizini:", -1, 16, 75, 100, 9 - EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP - PUSHBUTTON "&Seç", IDC_CHOOSE, 187, 85, 50, 14 - AUTOCHECKBOX "&Kurulumdan Sonra Yazılımın Kurulum Kütüğünü Sil", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12 + GROUPBOX "İndirme", -1, 4, 65, 240, 51 + LTEXT "İndirme Dizini:", -1, 16, 75, 100, 9 + EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP + PUSHBUTTON "&Seç", IDC_CHOOSE, 187, 85, 50, 14 + AUTOCHECKBOX "&Kurulumdan Sonra Yazılımın Kurulum Kütüğünü Sil", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12 - PUSHBUTTON "Ön Tanımlılar", IDC_DEFAULT_SETTINGS, 8, 124, 60, 14 - PUSHBUTTON "Tamam", IDOK, 116, 124, 60, 14 - PUSHBUTTON "Vazgeç", IDCANCEL, 181, 124, 60, 14 + PUSHBUTTON "Ön Tanımlılar", IDC_DEFAULT_SETTINGS, 8, 124, 60, 14 + PUSHBUTTON "Tamam", IDOK, 116, 124, 60, 14 + PUSHBUTTON "Vazgeç", IDCANCEL, 181, 124, 60, 14 END IDD_INSTALL_DIALOG DIALOGEX DISCARDABLE 0, 0, 216, 97 @@ -78,13 +83,13 @@ STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYS CAPTION "Yazılım Kurulumu" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "...", IDC_INSTALL_TEXT, 4, 5, 209, 35 + LTEXT "...", IDC_INSTALL_TEXT, 4, 5, 209, 35 - AUTORADIOBUTTON "&Bir Diskten Kur", IDC_CD_INSTALL, 10, 46, 197, 11, WS_GROUP - AUTORADIOBUTTON "&İndir ve Kur", IDC_DOWNLOAD_INSTALL, 10, 59, 197, 11, NOT WS_TABSTOP + AUTORADIOBUTTON "&Bir Diskten Kur", IDC_CD_INSTALL, 10, 46, 197, 11, WS_GROUP + AUTORADIOBUTTON "&İndir ve Kur", IDC_DOWNLOAD_INSTALL, 10, 59, 197, 11, NOT WS_TABSTOP - PUSHBUTTON "Tamam", IDOK, 86, 78, 60, 14 - PUSHBUTTON "Vazgeç", IDCANCEL, 150, 78, 60, 14 + PUSHBUTTON "Tamam", IDOK, 86, 78, 60, 14 + PUSHBUTTON "Vazgeç", IDCANCEL, 150, 78, 60, 14 END IDD_DOWNLOAD_DIALOG DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 0, 0, 220, 76 @@ -102,96 +107,96 @@ STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME CAPTION "Hakkında" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "ReactOS Yazılım Yöneticisi\nTelif Hakkı: 2009\nDmitry Chapyshev (dmitry@reactos.org) tarafından yazılmıştır.", IDC_STATIC, 48, 7, 130, 39 - PUSHBUTTON "Tamam", IDOK, 133, 46, 50, 14 - ICON IDI_MAIN, IDC_STATIC, 10, 10, 7, 30 + LTEXT "ReactOS Yazılım Yöneticisi\nTelif Hakkı: 2009\nDmitry Chapyshev (dmitry@reactos.org) tarafından yazılmıştır.", IDC_STATIC, 48, 7, 130, 39 + PUSHBUTTON "Tamam", IDOK, 133, 46, 50, 14 + ICON IDI_MAIN, IDC_STATIC, 10, 10, 7, 30 END STRINGTABLE DISCARDABLE BEGIN - IDS_TOOLTIP_INSTALL "Kur" - IDS_TOOLTIP_UNINSTALL "Kaldır" - IDS_TOOLTIP_MODIFY "Değiştir" - IDS_TOOLTIP_SETTINGS "Ayarlar" - IDS_TOOLTIP_REFRESH "Yenile" - IDS_TOOLTIP_EXIT "Çıkış" + IDS_TOOLTIP_INSTALL "Kur" + IDS_TOOLTIP_UNINSTALL "Kaldır" + IDS_TOOLTIP_MODIFY "Değiştir" + IDS_TOOLTIP_SETTINGS "Ayarlar" + IDS_TOOLTIP_REFRESH "Yenile" + IDS_TOOLTIP_EXIT "Çıkış" END STRINGTABLE DISCARDABLE BEGIN - IDS_APP_NAME "Yazılımın Adı" - IDS_APP_INST_VERSION "Sürüm" - IDS_APP_DESCRIPTION "Ek Bilgi" + IDS_APP_NAME "Yazılımın Adı" + IDS_APP_INST_VERSION "Sürüm" + IDS_APP_DESCRIPTION "Ek Bilgi" END STRINGTABLE DISCARDABLE BEGIN - IDS_INFO_VERSION "\nSürüm: " - IDS_INFO_DESCRIPTION "\nEk Bilgi: " - IDS_INFO_PUBLISHER "\nYayımcı: " - IDS_INFO_HELPLINK "\nYardım Bağlantısı: " - IDS_INFO_HELPPHONE "\nYardım Telefonu: " - IDS_INFO_README "\nBenioku: " - IDS_INFO_REGOWNER "\nKayıtlı Olduğu Kullanıcısı: " - IDS_INFO_PRODUCTID "\nÜrün Kimliği: " - IDS_INFO_CONTACT "\nİletişim: " - IDS_INFO_UPDATEINFO "\nGücnelleme Bilgisi: " - IDS_INFO_INFOABOUT "\nHakkında Bilgi: " - IDS_INFO_COMMENTS "\nYorumlar: " - IDS_INFO_INSTLOCATION "\nKurulum Konumu: " - IDS_INFO_INSTALLSRC "\nKurulum Kaynağı: " - IDS_INFO_UNINSTALLSTR "\nKaldırma Dizgisi: " - IDS_INFO_MODIFYPATH "\nDeğiştirme Yolu: " - IDS_INFO_INSTALLDATE "\nKurulum Zamanı: " + IDS_INFO_VERSION "\nSürüm: " + IDS_INFO_DESCRIPTION "\nEk Bilgi: " + IDS_INFO_PUBLISHER "\nYayımcı: " + IDS_INFO_HELPLINK "\nYardım Bağlantısı: " + IDS_INFO_HELPPHONE "\nYardım Telefonu: " + IDS_INFO_README "\nBenioku: " + IDS_INFO_REGOWNER "\nKayıtlı Olduğu Kullanıcısı: " + IDS_INFO_PRODUCTID "\nÜrün Kimliği: " + IDS_INFO_CONTACT "\nİletişim: " + IDS_INFO_UPDATEINFO "\nGücnelleme Bilgisi: " + IDS_INFO_INFOABOUT "\nHakkında Bilgi: " + IDS_INFO_COMMENTS "\nYorumlar: " + IDS_INFO_INSTLOCATION "\nKurulum Konumu: " + IDS_INFO_INSTALLSRC "\nKurulum Kaynağı: " + IDS_INFO_UNINSTALLSTR "\nKaldırma Dizgisi: " + IDS_INFO_MODIFYPATH "\nDeğiştirme Yolu: " + IDS_INFO_INSTALLDATE "\nKurulum Zamanı: " END STRINGTABLE DISCARDABLE BEGIN - IDS_AINFO_VERSION "\nSürüm: " - IDS_AINFO_DESCRIPTION "\nEk Bilgi: " - IDS_AINFO_SIZE "\nBoyut: " - IDS_AINFO_URLSITE "\nAna Sayfa: " - IDS_AINFO_LICENCE "\nLisans: " + IDS_AINFO_VERSION "\nSürüm: " + IDS_AINFO_DESCRIPTION "\nEk Bilgi: " + IDS_AINFO_SIZE "\nBoyut: " + IDS_AINFO_URLSITE "\nAna Sayfa: " + IDS_AINFO_LICENCE "\nLisans: " END STRINGTABLE DISCARDABLE BEGIN - IDS_CAT_AUDIO "Ses" - IDS_CAT_DEVEL "Geliştirme" - IDS_CAT_DRIVERS "Sürücüler" - IDS_CAT_EDU "Eğitim" - IDS_CAT_ENGINEER "Mühendislik" - IDS_CAT_FINANCE "Mâli" - IDS_CAT_GAMES "Oyun ve Eğlence" - IDS_CAT_GRAPHICS "Çizge" - IDS_CAT_INTERNET "Ağ" - IDS_CAT_LIBS "Kitaplıklar" - IDS_CAT_OFFICE "Büro" - IDS_CAT_OTHER "Diğer" - IDS_CAT_SCIENCE "Bilim" - IDS_CAT_TOOLS "Araçlar" - IDS_CAT_VIDEO "Vidyo" + IDS_CAT_AUDIO "Ses" + IDS_CAT_DEVEL "Geliştirme" + IDS_CAT_DRIVERS "Sürücüler" + IDS_CAT_EDU "Eğitim" + IDS_CAT_ENGINEER "Mühendislik" + IDS_CAT_FINANCE "Mâli" + IDS_CAT_GAMES "Oyun ve Eğlence" + IDS_CAT_GRAPHICS "Çizge" + IDS_CAT_INTERNET "Ağ" + IDS_CAT_LIBS "Kitaplıklar" + IDS_CAT_OFFICE "Büro" + IDS_CAT_OTHER "Diğer" + IDS_CAT_SCIENCE "Bilim" + IDS_CAT_TOOLS "Araçlar" + IDS_CAT_VIDEO "Vidyo" END STRINGTABLE DISCARDABLE BEGIN - IDS_APPTITLE "ReactOS Yazılım Yöneticisi" - IDS_SEARCH_TEXT "Ara" - IDS_INSTALL "Kur" - IDS_UNINSTALL "Kaldır" - IDS_MODIFY "Değiştir" - IDS_APPS_COUNT "Yazılım Sayısı: %d" - IDS_WELCOME_TITLE "ReactOS Yazılım Yöneticisi'ne hoşgeldiniz.\n\n" - IDS_WELCOME_TEXT "Soldaki herhangi bir ulamı seçip ulamdaki herhangi bir yazılımı kaldırabilir veya kurabilrisiniz.\nReactOS'un genelağ sitesi: " - IDS_WELCOME_URL "http://www.reactos.org" - IDS_INSTALLED "Kurulanlar" - IDS_AVAILABLEFORINST "Kurulabilenler" - IDS_UPDATES "Güncellemeler" - IDS_APPLICATIONS "Yazılımlar" - IDS_CHOOSE_FOLDER_TEXT "İndirme dizinini seçiniz:" - IDS_CHOOSE_FOLDER_ERROR "Belirttiğiniz dizin yok. Belirttiğiniz dizin oluşturulsun mu?" - IDS_USER_NOT_ADMIN "ReactOS Yazılım Yöneticisi'ni yönetici olarak çalıştırmalısınız." - IDS_APP_REG_REMOVE "Bu yazılımın bilgilerini Değer Defteri'nden kaldırmaya emin misiniz?" - IDS_INFORMATION "Bilgi" - IDS_UNABLE_TO_REMOVE "Bu yazılımın bilgileri Değer Defteri'nden kaldırılamıyor." + IDS_APPTITLE "ReactOS Yazılım Yöneticisi" + IDS_SEARCH_TEXT "Ara" + IDS_INSTALL "Kur" + IDS_UNINSTALL "Kaldır" + IDS_MODIFY "Değiştir" + IDS_APPS_COUNT "Yazılım Sayısı: %d" + IDS_WELCOME_TITLE "ReactOS Yazılım Yöneticisi'ne hoşgeldiniz.\n\n" + IDS_WELCOME_TEXT "Soldaki herhangi bir ulamı seçip ulamdaki herhangi bir yazılımı kaldırabilir veya kurabilrisiniz.\nReactOS'un örütbağ sitesi: " + IDS_WELCOME_URL "http://www.reactos.org" + IDS_INSTALLED "Kurulanlar" + IDS_AVAILABLEFORINST "Kurulabilenler" + IDS_UPDATES "Güncellemeler" + IDS_APPLICATIONS "Yazılımlar" + IDS_CHOOSE_FOLDER_TEXT "İndirme dizinini seçiniz:" + IDS_CHOOSE_FOLDER_ERROR "Belirttiğiniz dizin yok. Belirttiğiniz dizin oluşturulsun mu?" + IDS_USER_NOT_ADMIN "ReactOS Yazılım Yöneticisi'ni yönetici olarak çalıştırmalısınız." + IDS_APP_REG_REMOVE "Bu yazılımın bilgilerini Değer Defteri'nden kaldırmaya emin misiniz?" + IDS_INFORMATION "Bilgi" + IDS_UNABLE_TO_REMOVE "Bu yazılımın bilgileri Değer Defteri'nden kaldırılamıyor." END diff --git a/base/applications/rapps/rapps/7zip.txt b/base/applications/rapps/rapps/7zip.txt index 31014b816a9..32101e357a8 100644 --- a/base/applications/rapps/rapps/7zip.txt +++ b/base/applications/rapps/rapps/7zip.txt @@ -2,13 +2,13 @@ [Section] Name = 7-Zip -Version = 9.25 +Version = 9.30a Licence = LGPL Description = Utility to create and open 7zip, zip, tar, rar and other archive files. -Size = 1.03MB +Size = 1.1MB Category = 12 URLSite = http://www.7-zip.org/ -URLDownload = http://dl.7-zip.org/7z925.exe +URLDownload = http://dl.7-zip.org/7z930.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/abyss.txt b/base/applications/rapps/rapps/abyss.txt index 90a7533673a..9edb1f57023 100644 --- a/base/applications/rapps/rapps/abyss.txt +++ b/base/applications/rapps/rapps/abyss.txt @@ -2,10 +2,10 @@ [Section] Name = Abyss Web server X1 -Version = 2.8 +Version = 2.9 Licence = Freeware Description = Abyss Web Server enables you to host your Web sites on your computer. It supports secure SSL/TLS connections (HTTPS) as well as a wide range of Web technologies. It can also run advanced PHP, Perl, Python, ASP, ASP.NET, and Ruby on Rails Web applications, which can be backed by databases such as MySQL, SQLite, MS SQL Server, MS Access, or Oracle. -Size = 1.94MB +Size = 2.1MB Category = 5 URLSite = http://www.aprelium.com/ URLDownload = http://www.aprelium.com/data/abwsx1.exe diff --git a/base/applications/rapps/rapps/doublecommander.txt b/base/applications/rapps/rapps/doublecommander.txt index 2ae437b9c0b..b2e9c242993 100644 --- a/base/applications/rapps/rapps/doublecommander.txt +++ b/base/applications/rapps/rapps/doublecommander.txt @@ -2,13 +2,13 @@ [Section] Name = Double Commander -Version = 0.5.4 +Version = 0.5.5 Licence = GPL Description = Double Commander is an open source file manager with two panels side by side. You need 7-Zip or a similar Utility to extract it. -Size = 6.5MB +Size = 7.5MB Category = 12 URLSite = http://doublecmd.sourceforge.net/ -URLDownload = http://freefr.dl.sourceforge.net/project/doublecmd/DC%20for%20Windows%2032%20bit/Double%20Commander%200.5.4%20beta/doublecmd-0.5.4.i386-win32.exe +URLDownload = http://freefr.dl.sourceforge.net/project/doublecmd/DC%20for%20Windows%2032%20bit/Double%20Commander%200.5.5%20beta/doublecmd-0.5.5.i386-win32.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/dvdwritenow.txt b/base/applications/rapps/rapps/dvdwritenow.txt new file mode 100644 index 00000000000..342eab6f6c3 --- /dev/null +++ b/base/applications/rapps/rapps/dvdwritenow.txt @@ -0,0 +1,14 @@ +; UTF-8 + +[Section] +Name = DVD Write Now +Version = 1.5.12 sp2 +Licence = Freeware +Description = A free direct CD/DVD recording software. Once installed, you can use your CD/DVD RW as USB Flash or removable hard drives. Along with this you can write to CD/DVD RW recorded with UDF filesystem. You can also read UDF disks created with other software. (Microsoft DVD−ROMs, RW disks recorded with Ahead InCD). You need a ZIP decompression program to install it. +Size = 1.2MB +Category = 13 +URLDownload = http://dwn.alter.org.ua/downloads/dwn_1_5_12_sp2.zip +CDPath = none + +[Section.0407] +Description = Eine kostenlose CD/DVD Brennsoftware. Sobald es installiert ist, kann man CD/DVD RW als USB Flash oder Wechseldatenträger beschreiben. Auch kann man hiermit auf CD/DVD RW schreiben, welche mit dem UDF Dateisystem beschrieben wurden. Auch kann man mit dieser Software UDF Disks, welche mit anderer Software erstellt wurden, lesen. (Microsoft DVD−ROMs, RW Disks erstellt mit Ahead InCD). Es wird für die Installation ein ZIP Dekomprimierprogramm benötigt. diff --git a/base/applications/rapps/rapps/fap.txt b/base/applications/rapps/rapps/fap.txt index 7c448e3e3a8..1438b1d27e7 100644 --- a/base/applications/rapps/rapps/fap.txt +++ b/base/applications/rapps/rapps/fap.txt @@ -2,13 +2,13 @@ [Section] Name = Fox Audio Player -Version = 0.9.2 +Version = 0.10.0 Licence = GPL Description = Simple and lightweight audio player. -Size = 1.86MB +Size = 1.89MB Category = 1 URLSite = http://foxaudioplayer.sourceforge.net/ -URLDownload = http://svn.reactos.org/packages/fap-0.9.2-win32-bin.exe +URLDownload = http://svn.reactos.org/packages/fap-0.10.0-win32-bin.exe CDPath = none [Section.0407] @@ -19,7 +19,7 @@ Description = Reproductor de audio simple y ligero. [Section.040c] Description = Lecteur audio simple et léger. -Size = 1,86 Mo +Size = 1,89 Mo [Section.0410] Description = Un semplice e leggero lettore audio. @@ -32,7 +32,7 @@ Description = Prosty i lekki odtwarzacz audio. [Section.0418] Description = Un lector audio simplu și ușor. -Size = 1,86 Mo +Size = 1,89 Mo [Section.0422] Description = Простий та маленький програвач аудіо файлів. diff --git a/base/applications/rapps/rapps/firefox5.txt b/base/applications/rapps/rapps/firefox5.txt index 6b75d88ce37..99eeb3ea0c3 100644 --- a/base/applications/rapps/rapps/firefox5.txt +++ b/base/applications/rapps/rapps/firefox5.txt @@ -1,78 +1,78 @@ ; UTF-8 [Section] -Name = Mozilla Firefox 21 -Version = 21.0 +Name = Mozilla Firefox 22 +Version = 22.0 Licence = MPL/GPL/LGPL Description = The most popular and one of the best free Web Browsers out there. Size = 20.3MB Category = 5 URLSite = http://www.mozilla.org/en-US/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/en-US/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/en-US/Firefox%20Setup%2022.0.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. Size = 20.17MB URLSite = http://www.mozilla-europe.org/de/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/de/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/de/Firefox%20Setup%2022.0.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. Size = 20.13MB URLSite = http://www.mozilla-europe.org/es/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/es-ES/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/es-ES/Firefox%20Setup%2022.0.exe [Section.040c] Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs. Size = 20,46 Mo URLSite = http://www.mozilla-europe.org/fr/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/fr/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/fr/Firefox%20Setup%2022.0.exe [Section.0410] Description = Il più popolare e uno dei migliori web browser gratuiti. Size = 20.1MB URLSite = http://www.mozilla-europe.org/it/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/it/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/it/Firefox%20Setup%2022.0.exe [Section.0413] Description = De meest populaire en een van de beste gratis Web browsers. Size = 20.82MB URLSite = http://www.mozilla-europe.org/nl/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/nl/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/nl/Firefox%20Setup%2022.0.exe [Section.0414] Description = Mest populære og best også gratis nettleserene der ute. Size = 20.18MB URLSite = http://www.mozilla-europe.org/no/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/nb-NO/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/nb-NO/Firefox%20Setup%2022.0.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych. Size = 21.03MB URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/pl/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/pl/Firefox%20Setup%2022.0.exe [Section.0418] Description = Cel mai popular și unul dintre cele mai bune navigatoare web gratuite existente. Size = 20,65 Mo URLSite = http://www.mozilla-europe.org/ro/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/ro/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/ro/Firefox%20Setup%2022.0.exe [Section.0419] Description = Один из самых популярных и лучших бесплатных браузеров. Size = 20.59MB URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/ru/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/ru/Firefox%20Setup%2022.0.exe [Section.041b] Description = Najpopulárnejší a jeden z najlepších slobodný webových prehliadačov. Size = 20.84MB URLSite = http://www.mozilla-europe.org/sk/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/sk/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/sk/Firefox%20Setup%2022.0.exe [Section.0422] Description = Найпопулярніший та один з кращих безплатних веб-браузерів. Size = 20.6MB URLSite = http://www.mozilla-europe.org/uk/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/21.0/win32/uk/Firefox%20Setup%2021.0.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/22.0/win32/uk/Firefox%20Setup%2022.0.exe diff --git a/base/applications/rapps/rapps/freebasic.txt b/base/applications/rapps/rapps/freebasic.txt index 938644eecbe..aff9cf6c829 100644 --- a/base/applications/rapps/rapps/freebasic.txt +++ b/base/applications/rapps/rapps/freebasic.txt @@ -2,13 +2,13 @@ [Section] Name = FreeBASIC -Version = 0.24.0 +Version = 0.90.0 Licence = GPL/LGPL Description = Open Source BASIC Compiler. The BASIC syntax is compatible to QBASIC. -Size = 8.65MB +Size = 7.3MB Category = 7 URLSite = http://www.freebasic.net/ -URLDownload = http://garr.dl.sourceforge.net/project/fbc/Binaries%20-%20Windows/FreeBASIC-0.24.0-win32.exe +URLDownload = http://garr.dl.sourceforge.net/project/fbc/Binaries%20-%20Windows/FreeBASIC-0.90.0-win32.exe CDPath = none [Section.0407] @@ -19,7 +19,7 @@ Description = Compilador BASIC de código abierto. El lenguaje BASIC es compatib [Section.040c] Description = Compilateur BASIC open source. La syntaxe du BASIC est compatible avec le QBASIC. -Size = 8,65 Mo +Size = 7,3 Mo [Section.0410] Description = Compilatore BASIC open source. La sintassi del BASIC è compatibile con il QBASIC. @@ -29,7 +29,7 @@ Description = Otwarty kompilator BASIC, ze składnią kompatybilną z QBASIC. [Section.0419] Description = Compilator (open-source) BASIC. Sintaxa BASIC este compatibilă cu QBASIC. -Size = 8,65 Mo +Size = 7,3 Mo [Section.0422] Description = Відкритий компілятор BASIC. Синтаксис сумісний з QBASIC. diff --git a/base/applications/rapps/rapps/irfanview.txt b/base/applications/rapps/rapps/irfanview.txt index 2d102facd72..c4991522365 100644 --- a/base/applications/rapps/rapps/irfanview.txt +++ b/base/applications/rapps/rapps/irfanview.txt @@ -2,13 +2,13 @@ [Section] Name = IrfanView -Version = 4.35 +Version = 4.36 Licence = Freeware (for personal use) Description = Viewer for all kinds of graphics/audio files/video files. -Size = 1.57MB +Size = 1.77MB Category = 3 URLSite = http://www.irfanview.com/ -URLDownload = http://irfanview.tuwien.ac.at/iview435_setup.exe +URLDownload = http://ring.maffin.ad.jp/archives/pc/forest/i/irfanview/10829/iview436_setup.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/irfanviewplugins.txt b/base/applications/rapps/rapps/irfanviewplugins.txt index a272641b9a9..c88bb52f783 100644 --- a/base/applications/rapps/rapps/irfanviewplugins.txt +++ b/base/applications/rapps/rapps/irfanviewplugins.txt @@ -8,7 +8,7 @@ Description = Additional Plugins for supporting more file types. Size = 9.85MB Category = 3 URLSite = http://www.irfanview.com/ -URLDownload = http://irfanview.tuwien.ac.at/plugins/irfanview_plugins_435_setup.exe +URLDownload = http://ring.maffin.ad.jp/archives/pc/forest/i/irfanview/10830/irfanview_plugins_436_setup.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/lazaruside.txt b/base/applications/rapps/rapps/lazaruside.txt new file mode 100644 index 00000000000..b9a5ab37843 --- /dev/null +++ b/base/applications/rapps/rapps/lazaruside.txt @@ -0,0 +1,15 @@ +; UTF-8 + +[Section] +Name = Lazarus +Version = 1.0.10 +Licence = modified LGPL, GPL +Description = A cross-platform integrated development environment (IDE) that lets you create visual (GUI) and non-visual Object Pascal programs, and uses the Free Pascal compiler to generate your executable. +Size = 106MB +Category = 7 +URLSite = http://www.lazarus.freepascal.org/ +URLDownload = http://garr.dl.sourceforge.net/project/lazarus/Lazarus%20Windows%2032%20bits/Lazarus%201.0.10/lazarus-1.0.10-fpc-2.6.2-win32.exe +CDPath = none + +[Section.0407] +Description = Eine plattformunabhängige, integrierte Entwicklungsumgebung (IDE), mit der man grafische (GUI) und nicht-grafische Pascal-Programme erstellen kann. Es verwendet den Free Pascal Compiler um die Programme zu erzeugen. diff --git a/base/applications/rapps/rapps/libreoffice.txt b/base/applications/rapps/rapps/libreoffice.txt index 05782ff25d8..ffa3e430dd8 100644 --- a/base/applications/rapps/rapps/libreoffice.txt +++ b/base/applications/rapps/rapps/libreoffice.txt @@ -2,13 +2,13 @@ [Section] Name = LibreOffice -Version = 4.0.3 +Version = 4.0.4 Licence = LGPL Description = Former called OpenOffice. Open Source Office Suite. Size = 182.5MB Category = 6 URLSite = http://www.documentfoundation.org/ -URLDownload = http://download.documentfoundation.org/libreoffice/stable/4.0.3/win/x86/LibreOffice_4.0.3_Win_x86.msi +URLDownload = http://download.documentfoundation.org/libreoffice/stable/4.0.4/win/x86/LibreOffice_4.0.4_Win_x86.msi CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/mirandaim.txt b/base/applications/rapps/rapps/mirandaim.txt index 50d5c30a331..a439efc0c47 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.10.13 +Version = 0.10.14 Licence = GPL Description = Open source multiprotocol instant messaging application - May not work completely. Size = 2.81MB Category = 5 URLSite = http://www.miranda-im.org/ -URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.10.13-unicode.exe +URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.10.14-unicode.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/mpc.txt b/base/applications/rapps/rapps/mpc.txt index 723f0410be0..ee7be799fdf 100644 --- a/base/applications/rapps/rapps/mpc.txt +++ b/base/applications/rapps/rapps/mpc.txt @@ -2,13 +2,13 @@ [Section] Name = Media Player Classic Home Cinema -Version = 1.6.7.7114 +Version = 1.6.8 Licence = GPL Description = A media player. Size = 7.08MB Category = 1 URLSite = http://mpc-hc.sourceforge.net/ -URLDownload = http://garr.dl.sourceforge.net/project/mpc-hc/MPC%20HomeCinema%20-%20Win32/MPC-HC_v1.6.7.7114_x86/MPC-HC.1.6.7.7114.x86.exe +URLDownload = http://garr.dl.sourceforge.net/project/mpc-hc/MPC%20HomeCinema%20-%20Win32/MPC-HC_v1.6.8_x86/MPC-HC.1.6.8.x86.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/npp.txt b/base/applications/rapps/rapps/npp.txt index d83261bf4da..741e4de23ac 100644 --- a/base/applications/rapps/rapps/npp.txt +++ b/base/applications/rapps/rapps/npp.txt @@ -2,13 +2,13 @@ [Section] Name = Notepad++ -Version = 6.3.3 +Version = 6.4.1 Licence = GPL Description = A text editor. -Size = 6.7MB +Size = 7.1MB Category = 6 URLSite = http://notepad-plus-plus.org/ -URLDownload = http://download.tuxfamily.org/notepadplus/6.3.3/npp.6.3.3.Installer.exe +URLDownload = http://download.tuxfamily.org/notepadplus/6.4.1/npp.6.4.1.Installer.exe CDPath = none [Section.0407] @@ -19,7 +19,7 @@ Description = Un editor de text. [Section.040c] Description = Un éditeur de texte. -Size = 6,7 Mo +Size = 7,1 Mo [Section.0410] Description = Un editor di testo. @@ -32,7 +32,7 @@ Description = Edytor tekstu. [Section.0418] Description = A text editor. -Size = 6,7 Mo +Size = 7,1 Mo [Section.0419] Description = Текстовый редактор. diff --git a/base/applications/rapps/rapps/openttd.txt b/base/applications/rapps/rapps/openttd.txt index 874ebe686a7..4579c914765 100644 --- a/base/applications/rapps/rapps/openttd.txt +++ b/base/applications/rapps/rapps/openttd.txt @@ -2,13 +2,13 @@ [Section] Name = OpenTTD -Version = 1.3.0 +Version = 1.3.1 Licence = GPL v2 Description = Open Source clone of the "Transport Tycoon Deluxe" game engine. You need a copy of Transport Tycoon. -Size = 4.74MB +Size = 4.9MB Category = 4 URLSite = http://www.openttd.org/ -URLDownload = http://binaries.openttd.org/releases/1.3.0/openttd-1.3.0-windows-win32.exe +URLDownload = http://binaries.openttd.org/releases/1.3.1/openttd-1.3.1-windows-win32.exe CDPath = none [Section.0407] @@ -19,7 +19,7 @@ Description = Clon del motor de juegos "Transport Tycoon Deluxe" de código abie [Section.040c] Description = Clone open source du moteur de jeu "Transport Tycoon Deluxe". Vous aurez besoin d'une copie de Transport Tycoon. -Size = 4,74 Mo +Size = 4,9 Mo [Section.0410] Description = Clone open source del motore di gioco di "Transport Tycoon Deluxe". Hai bisogno di una copia di Transport Tycoon. @@ -32,7 +32,7 @@ Description = Otwarty klon silnika gry "Transport Tycoon Deluxe". Do poprawnego [Section.0418] Description = Clona (open-source a) motorului de joc "Transport Tycoon Deluxe". Este necesară o copie a jocului Transport Tycoon. -Size = 4,74 Mo +Size = 4,9 Mo [Section.0422] Description = Відкритий клон двигуна гри "Transport Tycoon Deluxe". Вам потрібна копія гри Transport Tycoon. diff --git a/base/applications/rapps/rapps/scite.txt b/base/applications/rapps/rapps/scite.txt index 2a1a424d6ce..7827522fcf8 100644 --- a/base/applications/rapps/rapps/scite.txt +++ b/base/applications/rapps/rapps/scite.txt @@ -2,13 +2,13 @@ [Section] Name = SciTE -Version = 3.3.2 +Version = 3.3.3 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 = 700kB +Size = 702kB Category = 7 URLSite = http://www.scintilla.org/ -URLDownload = http://heanet.dl.sourceforge.net/project/scintilla/SciTE/3.3.2/Sc332.exe +URLDownload = http://heanet.dl.sourceforge.net/project/scintilla/SciTE/3.3.3/Sc333.exe CDPath = none [Section.0407] @@ -19,7 +19,7 @@ Description = Editor de texto basado en SCIntilla. Originalmente creado para dem [Section.040c] Description = SciTE est un éditeur de texte basé sur SCIntilla. Originelement réalisé pour montrer Scintilla, il a évolué pour devenir un éditeur généralement utile avec des options pour compiler et lancer des programmes. -Size = 700 ko +Size = 702 ko [Section.0410] Description = SciTE è un editor di testo basato scintilla. Originariamente costruito per dimostrare Scintilla, è cresciuto fino a essere un editor generalmente utile con strutture per la creazione e l'esecuzione di programmi. @@ -33,7 +33,7 @@ Description = SciTE to edytor tekstu bazowany na SCIntilla. Oryginalnie stworzon [Section.0418] Licence = Gratuită Description = SciTE este un editor de text bazat pe SCIntilla. Construit inițial pentru a demonstra Scintilla, a crescut ulterior într-un editor de uz general cu funcționalități de compilare și execuție a programelor. -Size = 700 ko +Size = 702 ko [Section.0422] Description = Текстовий редактор на основі SCIntilla. Був зібраний як презентація Scintilla, але виріс до редактора загального користування з засобами збирання та запуску програм. diff --git a/base/applications/rapps/rapps/scummvm.txt b/base/applications/rapps/rapps/scummvm.txt index 2ae8e838260..f0af63c9a8b 100644 --- a/base/applications/rapps/rapps/scummvm.txt +++ b/base/applications/rapps/rapps/scummvm.txt @@ -2,13 +2,13 @@ [Section] Name = ScummVM -Version = 1.5.0 +Version = 1.6.0 Licence = GPL Description = Sam and Max, Day of the Tentacle, etc on ReactOS. Size = 6.28MB Category = 4 URLSite = http://scummvm.org/ -URLDownload = http://heanet.dl.sourceforge.net/project/scummvm/scummvm/1.5.0/scummvm-1.5.0-win32.exe +URLDownload = http://heanet.dl.sourceforge.net/project/scummvm/scummvm/1.6.0/scummvm-1.6.0-win32.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/thunderbird5.txt b/base/applications/rapps/rapps/thunderbird5.txt index 8f42cbec5f6..ca0206f9457 100644 --- a/base/applications/rapps/rapps/thunderbird5.txt +++ b/base/applications/rapps/rapps/thunderbird5.txt @@ -2,65 +2,65 @@ [Section] Name = Mozilla Thunderbird 17 -Version = 17.0.6 +Version = 17.0.7 Licence = MPL/GPL/LGPL Description = The most popular and one of the best free Mail Clients out there. Size = 18.91MB Category = 5 URLSite = http://www.mozilla.org/en/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/en-US/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/en-US/Thunderbird%20Setup%2017.0.7.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Mail-Clients. Size = 18.77MB URLSite = http://www.mozilla-europe.org/de/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/de/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/de/Thunderbird%20Setup%2017.0.7.exe [Section.040a] Description = El más popular y uno de los mejores clientes mail que hay. Size = 18.73MB URLSite = http://www.mozilla-europe.org/es/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/es-ES/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/es-ES/Thunderbird%20Setup%2017.0.7.exe [Section.040c] Description = Le plus populaire et l'un des meilleurs clients mail gratuits disponible. Size = 19,06 Mo URLSite = http://www.mozilla-europe.org/fr/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/fr/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/fr/Thunderbird%20Setup%2017.0.7.exe [Section.0410] Description = Il più popolare e il migliore Clients mail gratuito. Size = 18.7MB URLSite = http://www.mozilla-europe.org/it/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/it/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/it/Thunderbird%20Setup%2017.0.7.exe [Section.0413] Description = De meest populaire en een van de beste gratis e-mail-programma's. Size = 19.28MB URLSite = http://www.mozilla-europe.org/nl/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/nl/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/nl/Thunderbird%20Setup%2017.0.7.exe [Section.0415] Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty. Size = 19.62MB URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/pl/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/pl/Thunderbird%20Setup%2017.0.7.exe [Section.0418] Description = Cel mai popular și unul dintre cele mai bune clientele gratuite de poștă electronică. Size = 19,28 Mo URLSite = http://www.mozilla-europe.org/ro/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/ro/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/ro/Thunderbird%20Setup%2017.0.7.exe [Section.0419] Description = Один из самых популярных и лучших бесплатных почтовых клиентов. Size = 19.19MB URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/ru/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/ru/Thunderbird%20Setup%2017.0.7.exe [Section.0422] Description = Найпопулярніший та один з кращих поштових клієнтів. Size = 19.21MB URLSite = http://www.mozillamessaging.com/uk/thunderbird/ -URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.6/win32/uk/Thunderbird%20Setup%2017.0.6.exe +URLDownload = http://ftp.mozilla.org/pub/mozilla.org/thunderbird/releases/17.0.7/win32/uk/Thunderbird%20Setup%2017.0.7.exe diff --git a/base/applications/rapps/rapps/vlc.txt b/base/applications/rapps/rapps/vlc.txt index 16c233d2f57..1837f0756b8 100644 --- a/base/applications/rapps/rapps/vlc.txt +++ b/base/applications/rapps/rapps/vlc.txt @@ -2,13 +2,13 @@ [Section] Name = VLC media player -Version = 2.0.6 +Version = 2.0.7 Licence = GPL Description = A media player. Size = 21.88MB Category = 1 URLSite = http://www.videolan.org/vlc/ -URLDownload = http://garr.dl.sourceforge.net/project/vlc/2.0.6/win32/vlc-2.0.6-win32.exe +URLDownload = http://mirror.de.leaseweb.net/videolan/vlc/2.0.7/win32/vlc-2.0.7-win32.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/winmain.c b/base/applications/rapps/winmain.c index cb1e95a6b09..53ca0ddcdb1 100644 --- a/base/applications/rapps/winmain.c +++ b/base/applications/rapps/winmain.c @@ -763,7 +763,17 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh WCHAR szErrorText[MAX_STR_LEN]; HANDLE hMutex = NULL; MSG Msg; + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + default: + break; + } + hInst = hInstance; if (!IsUserAnAdmin()) diff --git a/base/applications/regedit/childwnd.c b/base/applications/regedit/childwnd.c index b5135cb94ce..f656498a3d6 100644 --- a/base/applications/regedit/childwnd.c +++ b/base/applications/regedit/childwnd.c @@ -439,8 +439,8 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } goto def; case WM_DESTROY: - DestroyTreeView(); DestroyListView(g_pChildWnd->hListWnd); + DestroyTreeView(g_pChildWnd->hTreeWnd); DestroyMainMenu(); HeapFree(GetProcessHeap(), 0, g_pChildWnd); g_pChildWnd = NULL; diff --git a/base/applications/regedit/clb/lang/tr-TR.rc b/base/applications/regedit/clb/lang/tr-TR.rc new file mode 100644 index 00000000000..bb199cc5c66 --- /dev/null +++ b/base/applications/regedit/clb/lang/tr-TR.rc @@ -0,0 +1,31 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +IDD_COLUMNLISTBOXSTYLES DIALOGEX 0, 0, 227, 215 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Dikeçli Dizelge Kutusu Biçimleri" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "Dikeçli Dizelge Kutusu Biçimleri", -1, 6, 7, 158, 71 + CHECKBOX "&Ölçünlü", 1710, 10, 20, 42, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Sınırlar", 1713, 10, 30, 34, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "S&ırala", 1705, 10, 40, 26, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Bildirme", 1706, 10, 50, 32, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Dikey Kaydırma Çubuğu", 1707, 10, 60, 64, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Çoklu Seçim", -1, 79, 20, 72, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP | WS_DISABLED + CHECKBOX "&Genişletilmiş Seçim", -1, 79, 30, 77, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP | WS_DISABLED + CHECKBOX "&Açılan Başlıklar", 1714, 79, 40, 68, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "&Esnek Dikeçler", 1715, 79, 50, 66, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + GROUPBOX "Temel Biçimler", -1, 6, 80, 158, 34 + CHECKBOX "Gö&rünür", 1701, 10, 92, 34, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "De&vre Dışı", 1702, 10, 102, 41, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "K&üme", 1703, 79, 92, 32, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Se&kme Durağı", 1704, 79, 102, 44, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Tamam", IDOK, 37, 125, 40, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Vazgeç", IDCANCEL, 93, 125, 40, 14, BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP + CHECKBOX "Ka&ydırmayı Etkinleştir", 1708, 79, 60, 66, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP +END + diff --git a/base/applications/regedit/clb/rsrc.rc b/base/applications/regedit/clb/rsrc.rc index 231c540b46e..2e4df17acf5 100644 --- a/base/applications/regedit/clb/rsrc.rc +++ b/base/applications/regedit/clb/rsrc.rc @@ -64,6 +64,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #ifdef LANGUAGE_TH_TH #include "lang/th-TH.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/base/applications/regedit/lang/tr-TR.rc b/base/applications/regedit/lang/tr-TR.rc new file mode 100644 index 00000000000..2754a35a58e --- /dev/null +++ b/base/applications/regedit/lang/tr-TR.rc @@ -0,0 +1,598 @@ +/* + * Turkish Resources for ReactOS Regedit + * + * Copyright: 2013 Erdem Ersoy (eersoy93) (erdemersoy@lve.com) + * + * 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 + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +ID_ACCEL ACCELERATORS +BEGIN + VK_DELETE, ID_EDIT_DELETE, VIRTKEY, NOINVERT + "^F", ID_EDIT_FIND + VK_F3, ID_EDIT_FINDNEXT, VIRTKEY, NOINVERT + VK_F5, ID_VIEW_REFRESH, VIRTKEY, NOINVERT + VK_F1, ID_HELP_HELPTOPICS, VIRTKEY, NOINVERT +END + +/* + * Menu + */ + +IDC_REGEDIT MENU DISCARDABLE +BEGIN + POPUP "&Kütük" + BEGIN + MENUITEM "&Çıkış", ID_REGISTRY_EXIT + END + POPUP "&Yardım" + BEGIN + MENUITEM "&Hakkında", ID_HELP_ABOUT + END +END + +IDR_REGEDIT_MENU MENU DISCARDABLE +BEGIN + POPUP "&Kütük" + BEGIN + MENUITEM "&Al...", ID_REGISTRY_IMPORTREGISTRYFILE + + MENUITEM "&Ver...", ID_REGISTRY_EXPORTREGISTRYFILE + + MENUITEM SEPARATOR + MENUITEM "&Yığın Yükle...", ID_REGISTRY_LOADHIVE, GRAYED + MENUITEM "Y&ığını kaldır...", ID_REGISTRY_UNLOADHIVE, GRAYED + MENUITEM SEPARATOR + MENUITEM "A&ğ Değerlerine Bağlan...", ID_REGISTRY_CONNECTNETWORKREGISTRY + MENUITEM "Ağ &Değerlerine Bağlantıyı Kes...", ID_REGISTRY_DISCONNECTNETWORKREGISTRY, GRAYED + MENUITEM SEPARATOR + MENUITEM "Ya&zdır...\tCtrl+P", ID_REGISTRY_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Çıkış", ID_REGISTRY_EXIT + END + POPUP "&Düzen" + BEGIN + MENUITEM "&Değiştir...", ID_EDIT_MODIFY + MENUITEM SEPARATOR + POPUP "&Yeni" + BEGIN + MENUITEM "&Dizin", ID_EDIT_NEW_KEY + MENUITEM SEPARATOR + MENUITEM "D&izgi Değeri", ID_EDIT_NEW_STRINGVALUE + MENUITEM "İ&kili Değer", ID_EDIT_NEW_BINARYVALUE + MENUITEM "&32 İkillik Değer", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Çok Dizeli Dizgi Değeri", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Genişletilebilir Dizgi Değeri", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + END + MENUITEM SEPARATOR + MENUITEM "&İzinler...", ID_EDIT_PERMISSIONS + MENUITEM SEPARATOR + MENUITEM "&Sil\tDel", ID_EDIT_DELETE + MENUITEM "&Adını Değiştir", ID_EDIT_RENAME + MENUITEM SEPARATOR + MENUITEM "Y&olunu Çoğalt", ID_EDIT_COPYKEYNAME + MENUITEM SEPARATOR + MENUITEM "A&ra...\tCtrl+F", ID_EDIT_FIND + MENUITEM "So&nrakini Ara\tF3", ID_EDIT_FINDNEXT + END + POPUP "&Görünüm" + BEGIN + MENUITEM "&Durum Çubuğu", ID_VIEW_STATUSBAR + MENUITEM SEPARATOR + MENUITEM "&Ayırıcının Yerini Değiştir", ID_VIEW_SPLIT + MENUITEM SEPARATOR + MENUITEM "&Yenile\tF5", ID_VIEW_REFRESH + END + POPUP "Y&er İmleri" + BEGIN + MENUITEM "&Yer İmlerine Ekle...", ID_FAVOURITES_ADDTOFAVOURITES, GRAYED + MENUITEM "Y&er İmlerinden Çıkar...", ID_FAVOURITES_REMOVEFAVOURITE, GRAYED + END + POPUP "&Yardım" + BEGIN + MENUITEM "&Yardım Konuları\tF1", ID_HELP_HELPTOPICS + MENUITEM SEPARATOR + MENUITEM "&Hakkında", ID_HELP_ABOUT + END +END + +IDR_POPUP_MENUS MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "&Değiştir...", ID_EDIT_MODIFY + MENUITEM "&İkili Olarak Değiştir...", ID_EDIT_MODIFY_BIN + MENUITEM SEPARATOR + MENUITEM "&Sil\tDel", ID_EDIT_DELETE + MENUITEM "&Adını Değiştir", ID_EDIT_RENAME + END + POPUP "" + BEGIN + POPUP "&Yeni" + BEGIN + MENUITEM "&Dizin", ID_EDIT_NEW_KEY + MENUITEM SEPARATOR + MENUITEM "D&izgi Değeri", ID_EDIT_NEW_STRINGVALUE + MENUITEM "İ&kili Değer", ID_EDIT_NEW_BINARYVALUE + MENUITEM "&32 İkillik Değer", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Çoklu Dizeli Dizgi Değeri", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Genişletilebilir Dizgi Değeri", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + END + END + POPUP "" + BEGIN + MENUITEM "&Genişlet ya da Daralt", ID_TREE_EXPANDBRANCH + POPUP "&Yeni" + BEGIN + MENUITEM "&Dizin", ID_EDIT_NEW_KEY + MENUITEM SEPARATOR + MENUITEM "D&izgi Değeri", ID_EDIT_NEW_STRINGVALUE + MENUITEM "İ&kili Değer", ID_EDIT_NEW_BINARYVALUE + MENUITEM "&32 İkillik Değer", ID_EDIT_NEW_DWORDVALUE + MENUITEM "&Çoklu Dizeli Dizgi Değeri", ID_EDIT_NEW_MULTISTRINGVALUE + MENUITEM "&Genişletilebilir Dizgi Değeri", ID_EDIT_NEW_EXPANDABLESTRINGVALUE + END + MENUITEM "A&ra...", ID_EDIT_FIND + MENUITEM SEPARATOR + MENUITEM "&Sil", ID_TREE_DELETE + MENUITEM "&Adını Değiştir", ID_TREE_RENAME + MENUITEM SEPARATOR + MENUITEM "&Ver...", ID_TREE_EXPORT + MENUITEM "&İzinler...", ID_TREE_PERMISSIONS, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Dizin Yolunu Çoğalt", ID_EDIT_COPYKEYNAME + END + POPUP "" + BEGIN + MENUITEM "&Kes", ID_HEXEDIT_CUT + MENUITEM "&Çoğalt", ID_HEXEDIT_COPY + MENUITEM "&Yapıştır", ID_HEXEDIT_PASTE + MENUITEM "&Sil", ID_HEXEDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "&Tümünü Seç", ID_HEXEDIT_SELECT_ALL + END +END + + +/* + * Dialog + */ + +IDD_EDIT_STRING DIALOGEX 32, 24, 252, 84 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Dizgi Değerini Düzenle" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Değer Adı:",IDC_STATIC,6,6,134,8 + EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "D&eğer Bilgisi:",IDC_STATIC,6,35,161,8 + EDITTEXT IDC_VALUE_DATA,6,46,240,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "Tamam",IDOK,142,64,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,196,64,50,14 +END + +IDD_EDIT_MULTI_STRING DIALOGEX 32, 24, 252, 174 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Çoklu Dizeli Dizgi Değerini Düzenle" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Değer Adı:",IDC_STATIC,6,6,134,8 + EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "D&eğer Bilgisi:",IDC_STATIC,6,35,161,8 + EDITTEXT IDC_VALUE_DATA,6,46,240,102,ES_AUTOHSCROLL | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL + DEFPUSHBUTTON "Tamam",IDOK,142,154,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,196,154,50,14 +END + +IDD_EDIT_BIN_DATA DIALOGEX 32, 24, 252, 174 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "İkili Değeri Düzenle" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Değer Adı:",IDC_STATIC,6,6,134,8 + EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "D&eğer Bilgisi:",IDC_STATIC,6,35,161,8 + CONTROL "",IDC_VALUE_DATA,"HexEdit32",WS_VSCROLL | WS_BORDER | WS_TABSTOP,6,46,240,102 + DEFPUSHBUTTON "Tamam",IDOK,142,154,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,196,154,50,14 +END + + +IDD_EDIT_DWORD DIALOGEX 32, 24, 252, 104 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "32 İkillik Değeri Düzenle" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Değer Adı:",IDC_STATIC,6,6,134,8 + EDITTEXT IDC_VALUE_NAME,6,17,240,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "D&eğer:",IDC_STATIC,6,35,161,8 + EDITTEXT IDC_VALUE_DATA,6,46,116,12,ES_AUTOHSCROLL + GROUPBOX "Şimdi Girilen Değer",IDC_STATIC,130,35,116,39 + AUTORADIOBUTTON "&Onaltılık",IDC_FORMAT_HEX,141,46,60,10,WS_GROUP + AUTORADIOBUTTON "O&nluk",IDC_FORMAT_DEC,141,59,60,10 + DEFPUSHBUTTON "Tamam",IDOK,142,82,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,196,82,50,14 +END + + +IDD_EDIT_RESOURCE_LIST DIALOGEX 32, 24, 170, 120 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Kaynak Dizelgesi" +FONT 8, "MS Shell Dlg" +{ + CONTROL "", IDC_RESOURCE_LIST, "SysListView32", LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 10, 150, 75 + DEFPUSHBUTTON "Tamam", IDOK, 27, 100, 50, 14 + PUSHBUTTON "Göster...", IDC_SHOW_RESOURCE, 93, 100, 50, 14, WS_DISABLED +} + + +IDD_EDIT_RESOURCE DIALOGEX 6, 18, 281, 283 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_NOIDLEMSG | DS_CONTEXTHELP | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Kaynaklar" +FONT 8, "MS Shell Dlg" +{ + LTEXT "DMA:", IDC_STATIC, 10, 5, 20, 8 + CONTROL "", IDC_DMA_LIST, "SysListView32", LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 15, 261, 31 + LTEXT "Kesme:", IDC_STATIC, 10, 48, 35, 8 + CONTROL "", IDC_IRQ_LIST, "SysListView32", LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 58, 261, 31 + LTEXT "Bellek:", IDC_STATIC, 10, 91, 32, 8 + CONTROL "", IDC_MEMORY_LIST, "SysListView32", LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 101, 261, 31 + LTEXT "Giriş:", IDC_STATIC, 10, 134, 38, 8 + CONTROL "", IDC_PORT_LIST, "SysListView32", LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 144, 261, 31 + LTEXT "Özel Aygıt Bilgisi:", IDC_STATIC, 10, 177, 80, 8 + CONTROL "", IDC_DEVICE_LIST, "SysListView32", LVS_REPORT | LVS_NOSORTHEADER | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 10, 188, 261, 31 + GROUPBOX "Kullanım", IDC_STATIC, 10, 219, 125, 39 + LTEXT "Belirsiz:", IDC_UNDETERMINED, 18, 230, 46, 8, WS_DISABLED + LTEXT "Paylaşılan:", IDC_SHARED, 18, 240, 48, 8, WS_DISABLED + LTEXT "Özel Aygıt", IDC_DEVICE_EXCLUSIVE, 72, 230, 58, 8, WS_DISABLED + LTEXT "Özel Sürücü", IDC_DRIVER_EXCLUSIVE, 72, 240, 54, 8, WS_DISABLED + RTEXT "Arayüz Türü:", IDC_STATIC, 144, 220, 58, 8 + LTEXT "", IDC_INTERFACETYPE, 205, 220, 66, 8 + RTEXT "Veri Yolu Numarası:", IDC_STATIC, 151, 230, 51, 8 + LTEXT "", IDC_BUSNUMBER, 205, 230, 66, 8 + RTEXT "Sürüm:", IDC_STATIC, 151, 240, 51, 8 + LTEXT "", IDC_VERSION, 205, 240, 66, 8 + RTEXT "Düzeltme:", IDC_STATIC, 151, 250, 51, 8 + LTEXT "", IDC_REVISION, 205, 250, 66, 8 + DEFPUSHBUTTON "Tamam",IDOK, 92, 263, 40, 14 + PUSHBUTTON "Kaynak Bilgisi...", IDC_SHOW_RESOURCE_DATA, 148, 263, 40, 14, WS_DISABLED +} + + +/* + * String Table + */ + +STRINGTABLE DISCARDABLE +BEGIN + IDS_LIST_COLUMN_NAME "Değerin Adı" + IDS_LIST_COLUMN_TYPE "Değerin Türü" + IDS_LIST_COLUMN_DATA "Değer" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_TITLE "Değer Defteri Düzenleyicisi" + IDC_REGEDIT "REGEDIT" + IDC_REGEDIT_FRAME "REGEDIT_FRAME" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_REGISTRY_MENU "Bu seçke, bütün Değer Defteri ile çalışma komutlarını içerir." + ID_EDIT_MENU "Bu seçke, dizinleri veya değerleri düzenleme komutlarını içerir." + ID_VIEW_MENU "Bu seçke, Değer Defteri Düzenleyicisi'nin penceresini özelleştirme komutlarını içerir." + ID_FAVOURITES_MENU "Bu seçke, yer imleri ile ilgili komutları içerir." + ID_HELP_MENU "Bu seçke, Değer Defteri Düzenleyicisi ile ilgili bilgi veya yardım alma komutlarını içerir." + ID_EDIT_NEW_MENU "Bu seçke, yeni bir dizin veya yeni bir değer oluşturma komutlarını içerir." +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_EDIT_MODIFY "Değeri değiştirir." + ID_EDIT_NEW_KEY "Yeni bir dizin oluşturur." + ID_EDIT_NEW_STRINGVALUE "Yeni bir dizgi değeri oluşturur." + ID_EDIT_NEW_BINARYVALUE "Yeni bir ikili değer oluşturur." + ID_EDIT_NEW_DWORDVALUE "Yeni bir 32 ikillik değer oluşturur." + ID_REGISTRY_IMPORTREGISTRYFILE "Uygun bir kütükten bilgiler alır." + ID_REGISTRY_EXPORTREGISTRYFILE "Değer Defteri'nin tümünü ya da bir bölümünü bir kütüğe kaydeder." + ID_REGISTRY_LOADHIVE "Değer Defteri'ne bir yığın yükler." + ID_REGISTRY_UNLOADHIVE "Değer Defteri'nden bir yığın kaldırır." + ID_REGISTRY_CONNECTNETWORKREGISTRY "Uzaktaki bir bilgisyarın değerlerine bağlanır." + ID_REGISTRY_DISCONNECTNETWORKREGISTRY "Uzaktaki bir bilgisayarın değerlerine olan bağlantıyı keser." + ID_REGISTRY_PRINT "Değer Defteri'nin tümünü ya da bir bölümünü yazdırır." + /*ID_HELP_HELPTOPICS "Değer Defteri Düzenleyicisi ile ilgili yardım konularını açar."*/ + ID_HELP_ABOUT "Değer Defteri Düzenleyicisi ile ilgili bilgi görüntüler." +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_REGISTRY_EXIT "Değer Defteri Düzenleyicisi'nden çıkar." + ID_FAVOURITES_ADDTOFAVOURITES "Bir dizini yer imlerine ekler." + ID_FAVOURITES_REMOVEFAVOURITE "Dizinleri yer imlerinden kaldırır." + ID_VIEW_STATUSBAR "Durum çubuğunu gizler ya da gösterir." + ID_VIEW_SPLIT "Ayırıcının yerini değiştirir." + ID_VIEW_REFRESH "Pencereyi yeniler." + ID_EDIT_DELETE "Seçilen öğeyi siler." + ID_EDIT_RENAME "Seçilen öğenin adını değiştirir." + ID_EDIT_COPYKEYNAME "Seçilen öğenin dizin yolunu çoğaltır." + ID_EDIT_FIND "Belirtilen dizgiyi dizinlerin adlarında, değerlerde veya değer adlarında arar." + ID_EDIT_FINDNEXT "Bulunan dizgiyi bulunduğu yerden başlayarak bir daha arar." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ERROR "Hatâ" + IDS_WARNING "Uyarı" + IDS_BAD_KEY "Dizin sorgulanamıyor: %s" + IDS_BAD_VALUE "Değer sorgulanamıyor: %s" + IDS_UNSUPPORTED_TYPE "Bu türdeki dizinler değiştirilemez: %ld" + IDS_TOO_BIG_VALUE "Değer çok büyük: %ld" + IDS_MULTI_SZ_EMPTY_STRING "REG_MULTI_SZ boş dizgi içeremez.\nBoş dizgiler dizelgeden silinmiştir." + IDS_QUERY_DELETE_KEY_ONE "Bu dizini silmeye emin misiniz?" + IDS_QUERY_DELETE_KEY_MORE "Bu dizinleri silmeye emin misiniz?" + IDS_QUERY_DELETE_KEY_CONFIRM "Emin Misiniz?" + IDS_QUERY_DELETE_ONE "Bu değeri silmeye emin misiniz?" + IDS_QUERY_DELETE_MORE "Bu değerleri silmeye emin misiniz?" + IDS_QUERY_DELETE_CONFIRM "Emin Misiniz?" + IDS_ERR_DELVAL_CAPTION "Değerlerin Silinmesi" + IDS_ERR_DELETEVALUE "Belirtilmiş değerler silinemiyor." + IDS_ERR_RENVAL_CAPTION "Değerin Adının Değiştirilmesi" + IDS_ERR_RENVAL_TOEMPTY "Yeni bir ad girmediğinizden dolayı bu değerin adı değiştirilemiyor: %s" + IDS_QUERY_IMPORT_HIVE_CAPTION "Emin Misiniz?" + IDS_QUERY_IMPORT_HIVE_MSG "Bu dizin, seçili dizinle yenilenecektir.\nBu yüzden bu dizinin tüm alt dizinleri ve değerleri silinecektir.\nİşlemi sürdürmek istiyor musunuz?" + IDS_NEW_KEY "%d. Yeni Dizin" + IDS_NEW_VALUE "%d. Yeni Değer" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_BINARY_EMPTY "(Bu değer sıfır uzunluktadır.)" + IDS_DEFAULT_VALUE_NAME "(Ön tanımlı)" + IDS_VALUE_NOT_SET "(Bu değer belirtilmemiştir.)" + IDS_UNKNOWN_TYPE "Bilinmeyen tür: (0x%lx)" + IDS_MY_COMPUTER "Bilgisayar" + IDS_IMPORT_REG_FILE "Değer Kütüğünden Al" + IDS_EXPORT_REG_FILE "Değer Kütüğüne Ver" + IDS_LOAD_HIVE "Yığın Yükle" + IDS_UNLOAD_HIVE "Yığını Kaldır" + IDS_INVALID_DWORD "(Bu 32 ikillik değer geçersizdir.)" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_FLT_REGFILE "Değer Kütüğü" + IDS_FLT_REGFILES "Değer Kütükleri (*.reg)" + IDS_FLT_REGFILES_FLT "*.reg" + IDS_FLT_HIVFILES "Yığın Dosyaları (*.*)" + IDS_FLT_HIVFILES_FLT "*.*" + IDS_FLT_REGEDIT4 "Windows 9x ve Windows NT 4.0 Türündeki Değer Kütükleri (*.reg)" + IDS_FLT_REGEDIT4_FLT "*.reg" + IDS_FLT_ALLFILES "Tüm Kütükler (*.*)" + IDS_FLT_ALLFILES_FLT "*.*" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_ACCESS_FULLCONTROL "Tam Denetim" + IDS_ACCESS_READ "Okuma" + IDS_ACCESS_QUERYVALUE "Değer Sorgulama" + IDS_ACCESS_SETVALUE "Değer Atama" + IDS_ACCESS_CREATESUBKEY "Alt Dizin Oluşturma" + IDS_ACCESS_ENUMERATESUBKEYS "Alt Dizinleri Sıralama" + IDS_ACCESS_NOTIFY "Bildirme" + IDS_ACCESS_CREATELINK "Bağlantı Oluşturma" + IDS_ACCESS_DELETE "Silme" + IDS_ACCESS_WRITEDAC "DAC Yazma" + IDS_ACCESS_WRITEOWNER "Sahibi Yazma" + IDS_ACCESS_READCONTROL "Okuma Denetimi" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_INHERIT_THISKEYONLY "Yalnızca bu dizin" + IDS_INHERIT_THISKEYANDSUBKEYS "Alt dizinleriyle birlikte bu dizin" + IDS_INHERIT_SUBKEYSONLY "Yalnızca bu dizinin alt dizinleri" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_EXPAND "&Genişlet" + IDS_COLLAPSE "&Daralt" + IDS_GOTO_SUGGESTED_KEY "G&it: %s" + IDS_FINISHEDFIND "Değer defterinde arama tamamlandı." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_IMPORT_PROMPT "Eklenen bilgiler değerleri değiştirebilir veya bileşenlerin doğru çalışmasını engelleyebilir.\nEğer %s kütüğündeki bilgilerin kaynağını bilmiyorsanız bu bilgileri değer defterine eklemeyiniz.\n\nSürdürmek istiyor musunuz?" + IDS_IMPORT_OK "Bilgiler, %s kütüğünden başarıyla alındı." + IDS_IMPORT_ERROR "%s alınamıyor. Disk hatâsı, kütük dizgesi hatâsı ya da belirtilen kütüğün olmamasından dolayı bilgi alınacak kütük açılamıyor." + IDS_EXPORT_ERROR "%s verilemiyor. Disk hatâsı ya da kütük dizgesi hatâsından dolayı belirtilen kütük oluşturulamıyor ya da bilgiler bu kütüğün üzerine yazılamıyor." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_BUSNUMBER "Veri Yolu Numarası" + IDS_INTERFACE "Arayüz" + IDS_DMA_CHANNEL "Kanal" + IDS_DMA_PORT "Giriş" + IDS_INTERRUPT_VECTOR "Yöney" + IDS_INTERRUPT_LEVEL "Düzey" + IDS_INTERRUPT_AFFINITY "Benzerlik" + IDS_INTERRUPT_TYPE "Tür" + IDS_MEMORY_ADDRESS "Fiziksel Erişki" + IDS_MEMORY_LENGTH "Uzunluk" + IDS_MEMORY_ACCESS "Erişim" + IDS_PORT_ADDRESS "Fiziksel Erişki" + IDS_PORT_LENGTH "Uzunluk" + IDS_PORT_ACCESS "Erişim" + IDS_SPECIFIC_RESERVED1 "Ayrılmış 1" + IDS_SPECIFIC_RESERVED2 "Ayrılmış 2" + IDS_SPECIFIC_DATASIZE "Veri Niceliği" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PORT_PORT_IO "Giriş" + IDS_PORT_MEMORY_IO "Bellek" + IDS_INTERRUPT_EDGE_SENSITIVE "Kenar Duyarlılığı" + IDS_INTERRUPT_LEVEL_SENSITIVE "Düzey Duyarlılığı" + IDS_MEMORY_READ_ONLY "Salt Okunur" + IDS_MEMORY_WRITE_ONLY "Salt Yazılır" + IDS_MEMORY_READ_WRITE "Okuma/Yazma" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_BUS_UNDEFINED "Tanımlanmamış" + IDS_BUS_INTERNAL "Dâhilî" + IDS_BUS_ISA "ISA" + IDS_BUS_EISA "EISA" + IDS_BUS_MICROCHANNEL "MikroKanal" + IDS_BUS_TURBOCHANNEL "TurboKanal" + IDS_BUS_PCIBUS "PCI" + IDS_BUS_VMEBUS "VME" + IDS_BUS_NUBUS "Nu Veri Yolu" + IDS_BUS_PCMCIABUS "PCMCIA" + IDS_BUS_CBUS "C Veri Yolu" + IDS_BUS_MPIBUS "MPI Veri Yolu" + IDS_BUS_MPSABUS "MPSA Veri Yolu" + IDS_BUS_PROCESSORINTERNAL "Dâhilî İşlemci" + IDS_BUS_INTERNALPOWERBUS "Dâhilî Güç Veri Yolu" + IDS_BUS_PNPISABUS "PnP-ISA Veri Yolu" + IDS_BUS_PNPBUS "PnP Veri Yolu" + IDS_BUS_UNKNOWNTYPE "Bilinmeyen Arayüz Türü" +END + +/*****************************************************************/ + + +/* + * Dialog + */ + +IDD_EXPORTRANGE DIALOGEX DISCARDABLE 50, 50, 370, 50 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Verme Kapsamı",IDC_STATIC,2,0,366,48 + CONTROL "&Tümü",IDC_EXPORT_ALL,"Button",BS_AUTORADIOBUTTON,10,10, 29,11 + CONTROL "&Seçili Dal",IDC_EXPORT_BRANCH,"Button",BS_AUTORADIOBUTTON,10,22, 100,11 + EDITTEXT IDC_EXPORT_BRANCH_TEXT,30,34,335,12 +END + +// +// Dialog resources +// +IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Yığın Yükleme" +FONT 8, "Ms Shell Dlg" +{ + LTEXT "Dizin:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT + EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13 + DEFPUSHBUTTON "Tamam", IDOK, 140, 17, 50, 14 + PUSHBUTTON "Vazgeç", IDCANCEL, 89, 17, 50, 14 +} + +IDD_ADDFAVORITES DIALOGEX DISCARDABLE 0, 0, 186, 46 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Yer İmlerine Ekleme" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "Tamam",IDOK,129,7,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,129,24,50,14 + LTEXT "Yer İmi Adı:",IDC_STATIC,7,7,70,10 + EDITTEXT IDC_FAVORITENAME,7,26,110,13,ES_AUTOHSCROLL +END + +IDD_REMOVEFAVORITES DIALOGEX DISCARDABLE 0, 0, 164, 135 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Yer İmlerini Silme" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "Tamam",IDOK,107,114,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,7,114,50,14 + CONTROL "List1",IDC_FAVORITESLIST,"SysListView32",LVS_LIST | + WS_BORDER | WS_TABSTOP,7,20,150,90 + LTEXT "Yer İmlerini Seç:",IDC_STATIC,7,7,99,12 +END + +IDD_FIND DIALOGEX DISCARDABLE 0, 0, 254, 82 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Ara" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "&Sonrakini Ara",IDOK,197,7,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,197,24,50,14 + GROUPBOX "Şunlara Bak",IDC_STATIC,7,25,63,51 + LTEXT "Şunu Ara:",IDC_STATIC,7,8,37,10 + EDITTEXT IDC_FINDWHAT,47,7,142,13,ES_AUTOHSCROLL + CONTROL "D&iznler",IDC_LOOKAT_KEYS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,14,36,35,8 + CONTROL "D&eğer Adları",IDC_LOOKAT_VALUES,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,14,48,36,8 + CONTROL "&Değerler",IDC_LOOKAT_DATA,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,14,60,42,8 + CONTROL "Aranan, bir şeyin tam adı olsun.",IDC_MATCHSTRING,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,83,32,94,13 + CONTROL "Büyük-küçük hârf ayrımı olsun.",IDC_MATCHCASE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,83,48,90,12 +END + +IDD_FINDING DIALOGEX 0, 0, 145, 50 +STYLE DS_SHELLFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_CAPTION | WS_SYSMENU +CAPTION "Arama" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + ICON IDI_REGEDIT,IDC_STATIC,7,7,20,20 + DEFPUSHBUTTON "Vazgeç",IDCANCEL,93,29,45,14 + LTEXT "Aranıyor...",IDC_STATIC,33,12,83,8 +END + +/* + * TEXTINCLUDE + */ + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + + + +/* + * String Table + */ + +/* + *STRINGTABLE DISCARDABLE + *BEGIN + * ID_HELP_HELPTOPICS "Değer Defteri Düzenleyicisi ile ilgili yardım konularını açar." + * ID_HELP_ABOUT "Değer Defteri Düzenleyicisi ile ilgili bilgi görüntüler." + *END + */ + +/*****************************************************************/ diff --git a/base/applications/regedit/main.c b/base/applications/regedit/main.c index bb27a5713a7..6964cfcdb6b 100644 --- a/base/applications/regedit/main.c +++ b/base/applications/regedit/main.c @@ -207,6 +207,16 @@ int APIENTRY wWinMain(HINSTANCE hInstance, LoadStringW(hInstance, IDC_REGEDIT_FRAME, szFrameClass, MAX_LOADSTRING); LoadStringW(hInstance, IDC_REGEDIT, szChildClass, MAX_LOADSTRING); + + switch (GetUserDefaultUILanguage()) + { + case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT): + SetProcessDefaultLayout(LAYOUT_RTL); + break; + + default: + break; + } /* Store instance handle in our global variable */ hInst = hInstance; diff --git a/base/applications/regedit/main.h b/base/applications/regedit/main.h index 46ade6bf2fd..1060c2f9dd0 100644 --- a/base/applications/regedit/main.h +++ b/base/applications/regedit/main.h @@ -129,9 +129,9 @@ extern HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name); extern HWND StartKeyRename(HWND hwndTV); extern BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem); extern BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath); -extern void DestroyTreeView( void ); -extern void DestroyListView( HWND hwndLV ); -extern void DestroyMainMenu( void ); +extern void DestroyTreeView(HWND hwndTV); +extern void DestroyListView(HWND hwndLV); +extern void DestroyMainMenu(void); /* edit.c */ extern BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCWSTR valueName, BOOL EditBin); diff --git a/base/applications/regedit/rsrc.rc b/base/applications/regedit/rsrc.rc index 7805baa78c6..e6cf367322c 100644 --- a/base/applications/regedit/rsrc.rc +++ b/base/applications/regedit/rsrc.rc @@ -98,6 +98,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #ifdef LANGUAGE_TH_TH #include "lang/th-TH.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/base/applications/regedit/settings.c b/base/applications/regedit/settings.c index b9165e47cb2..8f05f4b1ea6 100644 --- a/base/applications/regedit/settings.c +++ b/base/applications/regedit/settings.c @@ -149,7 +149,7 @@ extern void SaveSettings(void) /* Get program window settings */ tConfig.tPlacement.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(hFrameWnd , &tConfig.tPlacement); + GetWindowPlacement(hFrameWnd, &tConfig.tPlacement); /* Save all the data */ RegSetValueExW(hKey, L"View", 0, REG_BINARY, (LPBYTE)&tConfig, iBufferSize); diff --git a/base/applications/regedit/treeview.c b/base/applications/regedit/treeview.c index fbd05d75898..0f1a7706839 100644 --- a/base/applications/regedit/treeview.c +++ b/base/applications/regedit/treeview.c @@ -651,10 +651,15 @@ HWND CreateTreeView(HWND hwndParent, LPWSTR pHostName, HMENU id) return hwndTV; } -void DestroyTreeView() +void DestroyTreeView(HWND hwndTV) { - if (pathBuffer) - HeapFree(GetProcessHeap(), 0, pathBuffer); + HIMAGELIST himl; + + if (pathBuffer) HeapFree(GetProcessHeap(), 0, pathBuffer); + + /* Destroy the image list associated with the tree view control */ + himl = TreeView_GetImageList(hwndTV, TVSIL_NORMAL); + if (himl) ImageList_Destroy(himl); } BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath) diff --git a/base/applications/sndrec32/CMakeLists.txt b/base/applications/sndrec32/CMakeLists.txt index 7c8b4ebe5b4..72640fc35ae 100644 --- a/base/applications/sndrec32/CMakeLists.txt +++ b/base/applications/sndrec32/CMakeLists.txt @@ -1,5 +1,5 @@ -set_cpp() +set_cpp(WITH_RUNTIME) add_executable(sndrec32 audio_format.cpp diff --git a/base/applications/sndrec32/lang/tr-TR.rc b/base/applications/sndrec32/lang/tr-TR.rc index 2e6553392d9..b3e8dcb5f77 100644 --- a/base/applications/sndrec32/lang/tr-TR.rc +++ b/base/applications/sndrec32/lang/tr-TR.rc @@ -1,3 +1,7 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDC_REACTOS_SNDREC32 ACCELERATORS @@ -47,7 +51,7 @@ BEGIN IDS_STRPOS "Konum: %.2f s" IDS_STRDUR "Uzunluk: %.2f s" IDS_STRBUF "Ara Bellek: %.2f KB" - IDS_STRFMT "%.1f kHz, %u bitlik" + IDS_STRFMT "%.1f kHz, %u ikillik" IDS_STRMONO "Tek Yollu" IDS_STRSTEREO "Çift Yollu" IDS_STRCHAN "%s" diff --git a/base/applications/taskmgr/lang/tr-TR.rc b/base/applications/taskmgr/lang/tr-TR.rc new file mode 100644 index 00000000000..7336f6b9d79 --- /dev/null +++ b/base/applications/taskmgr/lang/tr-TR.rc @@ -0,0 +1,619 @@ +/* + * TRANSLATOR: 2013 - Erdem Ersoy (eersoy93) (erdemersoy@live.com) + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +IDR_TASKMANAGER MENU DISCARDABLE +BEGIN + POPUP "&Kütük" + BEGIN + MENUITEM "&Yeni Görev Çalıştır...", ID_FILE_NEW + MENUITEM SEPARATOR + MENUITEM "&Çıkış", ID_FILE_EXIT + END + POPUP "&Seçenekler" + BEGIN + MENUITEM "&Her Zaman Üstte", ID_OPTIONS_ALWAYSONTOP, CHECKED + MENUITEM "&Kullanımda Simge Durumuna Küçült", ID_OPTIONS_MINIMIZEONUSE, CHECKED + MENUITEM "&Simge Durumuna Küçültüldüğünde Gizle", ID_OPTIONS_HIDEWHENMINIMIZED, CHECKED + MENUITEM "&16 İkillik Görevleri Göster", ID_OPTIONS_SHOW16BITTASKS, CHECKED + END + POPUP "&Görünüm" + BEGIN + MENUITEM "&Yenile", ID_VIEW_REFRESH + POPUP "&Gücelleme Hızı" + BEGIN + MENUITEM "&Yüksek", ID_VIEW_UPDATESPEED_HIGH + MENUITEM "&Orta", ID_VIEW_UPDATESPEED_NORMAL, CHECKED + MENUITEM "&Düşük", ID_VIEW_UPDATESPEED_LOW + MENUITEM "&Sıfır", ID_VIEW_UPDATESPEED_PAUSED + END + MENUITEM SEPARATOR + MENUITEM "&Büyük Simgeler", ID_VIEW_LARGE + MENUITEM "&Küçük Simgeler", ID_VIEW_SMALL + MENUITEM "&Ayrıntılar", ID_VIEW_DETAILS, CHECKED + MENUITEM "&Dikeçleri Seç...", ID_VIEW_SELECTCOLUMNS + POPUP "&CPU Geçmişi" + BEGIN + MENUITEM "&Tüm CPU'lar İçin Aynı Çizge", ID_VIEW_CPUHISTORY_ONEGRAPHALL + MENUITEM "&Her CPU'ya Birer Çizge", ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, CHECKED + END + MENUITEM "&Çekirdek Zamanlarını Göster", ID_VIEW_SHOWKERNELTIMES + END + POPUP "&Pencereler" + BEGIN + MENUITEM "&Yatay Olarak Sırala", ID_WINDOWS_TILEHORIZONTALLY + MENUITEM "&Dikey Olarak Sırala", ID_WINDOWS_TILEVERTICALLY + MENUITEM "&Küçült", ID_WINDOWS_MINIMIZE + MENUITEM "&Büyüt", ID_WINDOWS_MAXIMIZE + MENUITEM "B&asamakla", ID_WINDOWS_CASCADE + MENUITEM "&Öne Getir", ID_WINDOWS_BRINGTOFRONT + END + POPUP "&Yardım" + BEGIN + MENUITEM "&Yardım Konuları", ID_HELP_TOPICS + MENUITEM SEPARATOR + MENUITEM "&Hakkında", ID_HELP_ABOUT + END +END + +IDR_WINDOWSMENU MENU DISCARDABLE +BEGIN + MENUITEM "&Yatay Olarak Sırala", ID_WINDOWS_TILEHORIZONTALLY + MENUITEM "&Dikey Olarak Sırala", ID_WINDOWS_TILEVERTICALLY + MENUITEM "&Küçült", ID_WINDOWS_MINIMIZE + MENUITEM "&Büyüt", ID_WINDOWS_MAXIMIZE + MENUITEM "B&asamakla", ID_WINDOWS_CASCADE + MENUITEM "&Öne Getir", ID_WINDOWS_BRINGTOFRONT +END + +IDR_APPLICATION_PAGE_CONTEXT1 MENU DISCARDABLE +BEGIN + POPUP "SAHTE" + BEGIN + MENUITEM "&Yeni Görev Çalıştır...", ID_FILE_NEW + MENUITEM SEPARATOR + MENUITEM "&Büyük Simgeler", ID_VIEW_LARGE + MENUITEM "&Küçük Simgeler", ID_VIEW_SMALL + MENUITEM "&Ayrıntılar", ID_VIEW_DETAILS, CHECKED + END +END + +IDR_APPLICATION_PAGE_CONTEXT2 MENU DISCARDABLE +BEGIN + POPUP "SAHTE" + BEGIN + MENUITEM "&Geçiş Yap", ID_APPLICATION_PAGE_SWITCHTO + MENUITEM "&Öne Getir", ID_WINDOWS_BRINGTOFRONT + MENUITEM SEPARATOR + MENUITEM "&Yatay Olarak Sırala", ID_WINDOWS_TILEHORIZONTALLY + MENUITEM "&Dikey Olarak Sırala", ID_WINDOWS_TILEVERTICALLY + MENUITEM "&Küçült", ID_WINDOWS_MINIMIZE + MENUITEM "&Büyüt", ID_WINDOWS_MAXIMIZE + MENUITEM "B&asamakla", ID_WINDOWS_CASCADE + MENUITEM SEPARATOR + MENUITEM "Gö&revi Sonlandır", ID_APPLICATION_PAGE_ENDTASK + MENUITEM "&İşleme Git", ID_APPLICATION_PAGE_GOTOPROCESS + + END +END + +IDR_TRAY_POPUP MENU DISCARDABLE +BEGIN + POPUP "SAHTE" + BEGIN + MENUITEM "&Önceki Boyutuna Getir", ID_RESTORE + MENUITEM "&Kapat", ID_FILE_EXIT + MENUITEM SEPARATOR + MENUITEM "&Her Zaman Üstte", ID_OPTIONS_ALWAYSONTOP + END +END + +IDR_PROCESS_PAGE_CONTEXT MENU DISCARDABLE +BEGIN + POPUP "SAHTE" + BEGIN + MENUITEM "&İşlemi Sonlandır", ID_PROCESS_PAGE_ENDPROCESS + MENUITEM "İ&şlem Ağacını Sonlandır", ID_PROCESS_PAGE_ENDPROCESSTREE + + MENUITEM "&Hatâ Ayıkla", ID_PROCESS_PAGE_DEBUG + MENUITEM SEPARATOR + POPUP "&Öncelik Ata" + BEGIN + MENUITEM "&Eş Zamanlı", ID_PROCESS_PAGE_SETPRIORITY_REALTIME + MENUITEM "&Yüksek", ID_PROCESS_PAGE_SETPRIORITY_HIGH + MENUITEM "&Orta-Yüksek", ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL + MENUITEM "O&rta", ID_PROCESS_PAGE_SETPRIORITY_NORMAL + MENUITEM "Or&ta-Düşük", ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL + MENUITEM "&Düşük", ID_PROCESS_PAGE_SETPRIORITY_LOW + END + MENUITEM "&CPU'larla İlişkisini Ayarla...", ID_PROCESS_PAGE_SETAFFINITY + MENUITEM "H&atâ Ayıklama Kanallarını Düzenle...", ID_PROCESS_PAGE_DEBUGCHANNELS + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_TASKMGR_DIALOG DIALOGEX DISCARDABLE 0, 0, 264, 246 +STYLE DS_SHELLFONT | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +CAPTION "Görev Yöneticisi" +MENU IDR_TASKMANAGER +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Tab1",IDC_TAB,"SysTabControl32",WS_TABSTOP,3,3,257,228 +END + +IDD_APPLICATION_PAGE DIALOGEX DISCARDABLE 0, 0, 247, 210 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "List2",IDC_APPLIST,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,233,177 + PUSHBUTTON "&Yeni Görev...",IDC_NEWTASK,187,189,53,14 + PUSHBUTTON "&Geçiş Yap",IDC_SWITCHTO,131,189,53,14,WS_DISABLED + PUSHBUTTON "G&örevi Sonlandır",IDC_ENDTASK,75,189,53,14,WS_DISABLED +END + +IDD_PROCESS_PAGE DIALOGEX DISCARDABLE 0, 0, 247, 210 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "List2",IDC_PROCESSLIST,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | + WS_BORDER | WS_TABSTOP,7,7,233,177 + PUSHBUTTON "&İşlemi Sonlandır",IDC_ENDPROCESS,171,189,69,14 + CONTROL "&Her Kullanıcıda Çalışan İşlemleri Göster",IDC_SHOWALLPROCESSES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,191,111,10 +END + +//IDD_PERFORMANCE_PAGE DIALOGEX 0, 0, 247, 210 +IDD_PERFORMANCE_PAGE DIALOGEX DISCARDABLE 0, 0, 247, 210 +STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "CPU Kullanımı",IDC_CPU_USAGE_FRAME,5,5,60,54,0,WS_EX_TRANSPARENT + GROUPBOX "Bellek Kullanımı",IDC_MEM_USAGE_FRAME,5,63,60,54,BS_LEFTTEXT,WS_EX_TRANSPARENT + GROUPBOX "Toplam",IDC_TOTALS_FRAME,5,122,111,39,0,WS_EX_TRANSPARENT + GROUPBOX "Ayrılmış Bellek (KB)",IDC_COMMIT_CHARGE_FRAME,5,166,111,39,0,WS_EX_TRANSPARENT + GROUPBOX "Fiziksel Bellek (KB)",IDC_PHYSICAL_MEMORY_FRAME,131,122,111,39,0,WS_EX_TRANSPARENT + GROUPBOX "Çekirdek Belleği (KB)",IDC_KERNEL_MEMORY_FRAME,131,166,111,39,0,WS_EX_TRANSPARENT + LTEXT "İşleçler",IDS_TOTALS_HANDLE_COUNT,12,131,27,8 + LTEXT "İş Parçacıkları",IDS_TOTALS_THREAD_COUNT,12,140,27,8 + LTEXT "İşlemler",IDS_TOTALS_PROCESS_COUNT,12,149,34,8 + EDITTEXT IDC_TOTALS_HANDLE_COUNT,65,131,45,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_TOTALS_THREAD_COUNT,65,140,45,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_TOTALS_PROCESS_COUNT,65,149,45,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + LTEXT "Toplam",IDS_COMMIT_CHARGE_TOTAL,12,175,27,8 + LTEXT "Sınır",IDS_COMMIT_CHARGE_LIMIT,12,184,15,8,NOT WS_BORDER + LTEXT "En Yüksek",IDS_COMMIT_CHARGE_PEAK,12,193,34,8 + EDITTEXT IDC_COMMIT_CHARGE_TOTAL,65,174,45,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_COMMIT_CHARGE_LIMIT,65,184,45,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_COMMIT_CHARGE_PEAK,65,193,45,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + LTEXT "Toplam",IDS_PHYSICAL_MEMORY_TOTAL,137,131,27,8 + LTEXT "Kullanılabilir",IDS_PHYSICAL_MEMORY_AVAILABLE,137,140,30,8 + LTEXT "Dizge Ön Belleği",IDS_PHYSICAL_MEMORY_SYSTEM_CACHE,137,149,46,8 + EDITTEXT IDC_PHYSICAL_MEMORY_TOTAL,185,131,48,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_PHYSICAL_MEMORY_AVAILABLE,185,140,48,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_PHYSICAL_MEMORY_SYSTEM_CACHE,185,149,48,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + LTEXT "Toplam",IDS_KERNEL_MEMORY_TOTAL,137,174,27,8 + LTEXT "Sayfalanmış",IDS_KERNEL_MEMORY_PAGED,137,184,21,8 + LTEXT "Sayfalanmamış",IDS_KERNEL_MEMORY_NONPAGED,137,193,34,8 + EDITTEXT IDC_KERNEL_MEMORY_TOTAL,185,174,48,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_KERNEL_MEMORY_PAGED,185,184,48,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + EDITTEXT IDC_KERNEL_MEMORY_NONPAGED,185,193,48,8,ES_RIGHT | + ES_READONLY | ES_NUMBER | NOT WS_BORDER | NOT WS_TABSTOP + GROUPBOX "CPU Kullanım Geçmişi",IDC_CPU_USAGE_HISTORY_FRAME,74,5,168,54,0,WS_EX_TRANSPARENT + GROUPBOX "Sayfalama Dosyası Kullanım Geçmişi",IDC_MEMORY_USAGE_HISTORY_FRAME,74,63,168,54,0,WS_EX_TRANSPARENT + PUSHBUTTON "CPU Kullanım Çizgesi",IDC_CPU_USAGE_GRAPH,12,17,47,37,NOT WS_TABSTOP,WS_EX_CLIENTEDGE + PUSHBUTTON "Sayfalama Dosyası Kullanım Çizgesi",IDC_MEM_USAGE_GRAPH,12,75,47,37,NOT WS_TABSTOP,WS_EX_CLIENTEDGE + PUSHBUTTON "CPU Kullanım Geçmişi Çizgesi",IDC_CPU_USAGE_HISTORY_GRAPH,81,17, + 153,37,NOT WS_TABSTOP,WS_EX_CLIENTEDGE + PUSHBUTTON "Sayfalama Dosyası Kullanım Geçmişi Çizgesi",IDC_MEM_USAGE_HISTORY_GRAPH,81,75, + 153,37,NOT WS_TABSTOP,WS_EX_CLIENTEDGE +END + +IDD_DEBUG_CHANNELS_DIALOG DIALOGEX DISCARDABLE 0, 0, 247, 210 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Hatâ Ayıklama Kanalları" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "List2",IDC_DEBUG_CHANNELS_LIST,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP | + LVS_SORTASCENDING,7,7,233,177 + PUSHBUTTON "Kapat",IDOK,171,189,69,14 +END + +IDD_AFFINITY_DIALOG DIALOGEX DISCARDABLE 0, 0, 231, 154 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "CPU'larla İlişkisini Ayarla" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "Tamam",IDOK,120,133,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,174,133,50,14 + LTEXT "Bu ayar, bu işlemin hangi CPU'larla yürütüleceğini ayarlar.", + IDC_STATIC,5,5,220,16 + CONTROL "0. CPU",IDC_CPU0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 11,28,37,10 + CONTROL "1. CPU",IDC_CPU1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,41,37,10 + CONTROL "2. CPU",IDC_CPU2,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,54,37,10 + CONTROL "3. CPU",IDC_CPU3,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,67,37,10 + CONTROL "4. CPU",IDC_CPU4,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,80,37,10 + CONTROL "5. CPU",IDC_CPU5,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,93,37,10 + CONTROL "6. CPU",IDC_CPU6,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,106,37,10 + CONTROL "7. CPU",IDC_CPU7,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,11,119,37,10 + CONTROL "8. CPU",IDC_CPU8,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,61,28,37,10 + CONTROL "9. CPU",IDC_CPU9,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,61,41,37,10 + CONTROL "10. CPU",IDC_CPU10,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,61,54,41,10 + CONTROL "11. CPU",IDC_CPU11,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,61,67,41,10 + CONTROL "12. CPU",IDC_CPU12,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,61,80,41,10 + CONTROL "13. CPU",IDC_CPU13,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,61,93,41,10 + CONTROL "14. CPU",IDC_CPU14,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,61,106,41,10 + CONTROL "15. CPU",IDC_CPU15,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,61,119,41,10 + CONTROL "16. CPU",IDC_CPU16,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,28,41,10 + CONTROL "17. CPU",IDC_CPU17,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,41,41,10 + CONTROL "18. CPU",IDC_CPU18,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,54,41,10 + CONTROL "19. CPU",IDC_CPU19,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,67,41,10 + CONTROL "20. CPU",IDC_CPU20,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,80,41,10 + CONTROL "21. CPU",IDC_CPU21,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,93,41,10 + CONTROL "22. CPU",IDC_CPU22,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,106,41,10 + CONTROL "23. CPU",IDC_CPU23,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,116,119,41,10 + CONTROL "24. CPU",IDC_CPU24,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,28,41,10 + CONTROL "25. CPU",IDC_CPU25,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,41,41,10 + CONTROL "26. CPU",IDC_CPU26,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,54,41,10 + CONTROL "27. CPU",IDC_CPU27,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,67,41,10 + CONTROL "28. CPU",IDC_CPU28,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,80,41,10 + CONTROL "29. CPU",IDC_CPU29,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,93,41,10 + CONTROL "30. CPU",IDC_CPU30,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,106,41,10 + CONTROL "31. CPU",IDC_CPU31,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,175,119,41,10 +END + +IDD_COLUMNS_DIALOG DIALOGEX DISCARDABLE 0, 0, 195, 199 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dikeçleri Seç" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "Tamam",IDOK,84,178,50,14 + PUSHBUTTON "Vazgeç",IDCANCEL,138,178,50,14 + LTEXT "Bu ayar, ""İşlemci"" sekmesindeki dikeçlerin hangisinin görüntülenip görüntülenmeyeceğini belirler.", + IDC_STATIC,7,7,181,17 + CONTROL "Yansıma Adı",IDC_IMAGENAME,"Button",BS_AUTOCHECKBOX | + WS_DISABLED | WS_TABSTOP,7,28,56,10 + CONTROL "PID (İşlem Tanımlayıcı)",IDC_PID,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,39,88,10 + CONTROL "CPU Kullanımı",IDC_CPUUSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,50,53,10 + CONTROL "CPU Çalışma Süresi",IDC_CPUTIME,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,61,48,10 + CONTROL "Bellek Kullanımı",IDC_MEMORYUSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,72,63,10 + CONTROL "Bellek Kullanım Aralığı",IDC_MEMORYUSAGEDELTA,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,83,82,10 + CONTROL "En Yüksek Bellek Kullanımı",IDC_PEAKMEMORYUSAGE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,94,82,10 + CONTROL "Sayfa Hatâları",IDC_PAGEFAULTS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,105,53,10 + CONTROL "Kullanıcı Nesneleri",IDC_USEROBJECTS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,116,62,10 + CONTROL "G/Ç Okuma",IDC_IOREADS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,127,49,10 + CONTROL "G/Ç Okuma Sekizlikleri",IDC_IOREADBYTES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,138,65,10 + CONTROL "Oturum Kimliği",IDC_SESSIONID,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,149,50,10 + CONTROL "Kullanıcı Adı",IDC_USERNAME,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,160,51,10 + CONTROL "Sayfa Hatâları Aralığı",IDC_PAGEFAULTSDELTA,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,107,28,72,10 + CONTROL "Farazî Bellek Boyutu",IDC_VIRTUALMEMORYSIZE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,107,39,77,10 + CONTROL "Sayfalanmış Havuz",IDC_PAGEDPOOL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,107,50,53,10 + CONTROL "Sayfalanmamış Havuz",IDC_NONPAGEDPOOL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,107,61,67,10 + CONTROL "Öncelik",IDC_BASEPRIORITY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,107,72,55,10 + CONTROL "İşleçler",IDC_HANDLECOUNT,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,107,83,59,10 + CONTROL "İş Parçacıkları",IDC_THREADCOUNT,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,107,94,59,10 + CONTROL "GDI Nesneleri",IDC_GDIOBJECTS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,107,105,55,10 + CONTROL "G/Ç Yazma",IDC_IOWRITES,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,107,116,49,10 + CONTROL "G/Ç Yazma Sekizlikleri",IDC_IOWRITEBYTES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,107,127,65,10 + CONTROL "G/Ç Diğer",IDC_IOOTHER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,107,138,46,10 + CONTROL "G/Ç Diğer Sekizlikler",IDC_IOOTHERBYTES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,107,149,65,10 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 252 + TOPMARGIN, 7 + BOTTOMMARGIN, 203 + END + + IDD_TASKMGR_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 260 + TOPMARGIN, 3 + BOTTOMMARGIN, 231 + END + + IDD_APPLICATION_PAGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 240 + TOPMARGIN, 7 + BOTTOMMARGIN, 203 + END + + IDD_PROCESS_PAGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 240 + TOPMARGIN, 7 + BOTTOMMARGIN, 203 + END + + IDD_PERFORMANCE_PAGE, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 242 + VERTGUIDE, 12 + VERTGUIDE, 65 + VERTGUIDE, 110 + TOPMARGIN, 5 + BOTTOMMARGIN, 205 + END + + IDD_AFFINITY_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 224 + VERTGUIDE, 11 + VERTGUIDE, 61 + VERTGUIDE, 116 + VERTGUIDE, 175 + TOPMARGIN, 7 + BOTTOMMARGIN, 147 + HORZGUIDE, 28 + HORZGUIDE, 38 + HORZGUIDE, 51 + HORZGUIDE, 64 + HORZGUIDE, 77 + HORZGUIDE, 90 + HORZGUIDE, 103 + HORZGUIDE, 116 + HORZGUIDE, 129 + END + + IDD_COLUMNS_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 188 + VERTGUIDE, 107 + TOPMARGIN, 7 + BOTTOMMARGIN, 192 + HORZGUIDE, 28 + END +END +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_TITLE "Görev Yöneticisi" + IDC_TASKMGR "Görev Yöneticisi" + IDS_IDLE_PROCESS "Çalışmayan İşlemci Yüzdesi İşlemi" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_NEW "Yeni görev çalıştırır." + ID_OPTIONS_ALWAYSONTOP "Görev Yöneticisi'ni diğer pencerelerin üstünde tutar." + ID_OPTIONS_MINIMIZEONUSE "Geçiş yapılırken Görev Yöneticisi'ni simge durumuna küçültür." + ID_OPTIONS_HIDEWHENMINIMIZED "Görev Yöneticisi simge durumuna küçültüldüğünde Görev Yöneticisi'ni gizler." + ID_VIEW_REFRESH "Görev Yöneticisi'ndeki bilgileri yeniler." + ID_VIEW_LARGE "Görevleri büyük simgelerle gösterir." + ID_VIEW_SMALL "Görevleri küçük simgelerle gösterir." + ID_VIEW_DETAILS "Görevleri küçük simgelerle, ayrıntılı olarak gösterir." + ID_VIEW_UPDATESPEED_HIGH "Her yarım sâniyede bir Görev Yöneticisi'ndeki bilgileri yeniler." + ID_VIEW_UPDATESPEED_NORMAL "Her iki sâniyede bir Görev Yöneticisi'ndeki bilgileri yeniler." + ID_VIEW_UPDATESPEED_LOW "Her dört sâniyede bir Görev Yöneticisi'ndeki bilgileri yeniler." +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_VIEW_UPDATESPEED_PAUSED "Görev Yöneticisi'ndeki bilgilerin kendiliğinden yenilenmesini durdurur. " + ID_WINDOWS_TILEHORIZONTALLY "Masaüstündeki pencereleri yatay olarak sıralar." + ID_WINDOWS_TILEVERTICALLY "Masaüstündeki pencereleri dikey olarak sıralar." + ID_WINDOWS_MINIMIZE "Pencereleri simge durumuna küçültür." + ID_WINDOWS_MAXIMIZE "Pencereleri her bir pencerenin ekranı kaplayacağı şekilde büyütür." + ID_WINDOWS_CASCADE "Pencereleri masaüstünde çapraz olarak sıralar." + ID_WINDOWS_BRINGTOFRONT "Pencereyi öne getirir ancak o pencereye geçiş yapmaz." + ID_HELP_TOPICS "Görev Yöneticisi ile ilgili yardım konularını görüntüler." + ID_HELP_ABOUT "Görev Yöneticisi ile ilgili bilgi görüntüler." + ID_FILE_EXIT "Görev Yöneticisi'nden çıkar." + ID_OPTIONS_SHOW16BITTASKS "Farazî DOS makinesi (ntvdm.exe) altında çalışan 16 ikillik uygulamaları da görüntüler." + ID_VIEW_SELECTCOLUMNS """İşlemler"" sekmesinde hangi dikeçlerin görüntülenip görüntülenmeyeceğini belirler." + ID_VIEW_SHOWKERNELTIMES "İşlemci çizgelerinde çekirdek zamanlarını gösterir." + ID_VIEW_CPUHISTORY_ONEGRAPHALL "Toplam CPU kullanımını tek çizgede gösterir." + ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU "Her CPU'nun kullanımını ayrı çizgelerde gösterir." + ID_APPLICATION_PAGE_SWITCHTO "Seçilen görevi öne getirip o göreve odaklatır." +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_ENDTASK "Seçili görevi sonlandırmaya çalışır." + ID_GOTOPROCESS "Seçili görevin işlemine gider." + ID_RESTORE "Görev Yöneticisi'ni gizli olmaktan çıkarır." + ID_PROCESS_PAGE_ENDPROCESS "Seçili işlemi sonlandırır." + ID_PROCESS_PAGE_ENDPROCESSTREE "Seçili işlemi ve bu işlemin bağlı olduğu tüm işlemleri sonlandırır." + ID_PROCESS_PAGE_DEBUG "Seçili işleme bir hatâ ayıklayıcı bağlar." + ID_PROCESS_PAGE_SETAFFINITY "Seçili işlemin hangi CPU'larla yürütüleceğini ayarlar." + ID_PROCESS_PAGE_SETPRIORITY_REALTIME "Seçili işlemin öncelik sırasını EŞ ZAMANLI yapar." + ID_PROCESS_PAGE_SETPRIORITY_HIGH "Seçili işlemin öncelik sırasını YÜKSEK yapar." + ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL "Seçili işlemin öncelik sırasını ORTA-YÜKSEK yapar." + ID_PROCESS_PAGE_SETPRIORITY_NORMAL "Seçili işlemin öncelik sırasını ORTA yapar." + ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL "Seçili işlemin öncelik sırasını ORTA-DÜŞÜK yapar." + ID_PROCESS_PAGE_SETPRIORITY_LOW "Seçili işlemin öncelik sırasını DÜŞÜK yapar." +END + + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TAB_APPS "Görevler" + IDS_TAB_PROCESSES "İşlemler" + IDS_TAB_PERFORMANCE "Başarım" + IDS_TAB_TASK "Görev" + IDS_TAB_STATUS "Durum" + IDS_TAB_IMAGENAME "Yansıma Adı" + IDS_TAB_PID "PID" + IDS_TAB_USERNAME "Kullanıcı Adı" + IDS_TAB_SESSIONID "Oturum Kimliği" + IDS_TAB_CPU "CPU Kullanımı" + IDS_TAB_CPUTIME "CPU Çalışma Süresi" + IDS_TAB_MEMUSAGE "Bellek Kullanımı" + IDS_TAB_PEAKMEMUSAGE "En Yüksek Bellek Kullanımı" + IDS_TAB_MEMDELTA "Bellek Kullanım Aralığı" + IDS_TAB_PAGEFAULT "Sayfa Hatâları" + IDS_TAB_PFDELTA "Sayfa Hatâları Aralığı" + IDS_TAB_VMSIZE "Farazî Bellek Boyutu" + IDS_TAB_PAGEDPOOL "Sayfalanmış Havuz" + IDS_TAB_NPPOOL "Sayfalanmamış Havuz" + IDS_TAB_BASEPRI "Öncelik" + IDS_TAB_HANDLES "İşleçler" + IDS_TAB_THREADS "İş Parçacıkları" + IDS_TAB_USERPBJECTS "Kullanıcı Nesneleri" + IDS_TAB_GDIOBJECTS "GDI Nesneleri" + IDS_TAB_IOREADS "G/Ç Okuma" + IDS_TAB_IOWRITES "G/Ç Yazma" + IDS_TAB_IOOTHER "G/Ç Diğer" + IDS_TAB_IOREADBYTES "G/Ç Okuma Sekizlikleri" + IDS_TAB_IOWRITESBYTES "G/Ç Yazma Sekizlikleri" + IDS_TAB_IOOTHERBYTES "G/Ç Diğer Sekizlikler" + IDS_MENU_SELECTCOLUMNS "&Dikeçleri Seç..." + IDS_MENU_16BITTASK "&16 İkillik Görevleri Göster" + IDS_MENU_WINDOWS "&Pencereler" + IDS_MENU_LARGEICONS "&Büyük Simgeler" + IDS_MENU_SMALLICONS "&Küçük Simgeler" + IDS_MENU_DETAILS "&Ayrıntılar" + IDS_MENU_ONEGRAPHALLCPUS "&Tüm CPU'lar İçin Aynı Çizge" + IDS_MENU_ONEGRAPHPERCPU "&Her CPU'ya Birer Çizge" + IDS_MENU_CPUHISTORY "&CPU Geçmişi" + IDS_MENU_SHOWKERNELTIMES "&Çekirdek Zamanlarını Göster" + IDS_CREATENEWTASK "Yeni Görev Oluşturma" + IDS_CREATENEWTASK_DESC "Çalıştırılacak görevin konumunu yazınız:" + IDS_MSG_ACCESSPROCESSAFF "CPU'larla ilişkisi erişilemez veya ayarlanamaz." + IDS_MSG_PROCESSONEPRO "Herhangi bir işlem, en az bir CPU ile ilişkili olmalıdır." + IDS_MSG_INVALIDOPTION "Geçersiz seçenek." + IDS_MSG_UNABLEDEBUGPROCESS "Hatâ ayıklama işlemi yapılamaz." + IDS_MSG_WARNINGDEBUG "UYARI: Bu işlemde hatâ ayıklama, veri yitimine neden olabilir.\nBu işleme bir hatâ ayıklayıcı bağlamaya emin misiniz?" + IDS_MSG_TASKMGRWARNING "Uyarı" + IDS_MSG_WARNINGTERMINATING "UYARI: Bir işlemin sonlandırılması, dizge\nkararsızlığı veya veri yitimi gibi istenmeyen durumlara neden olabilir. Bu\nişlemi sonlandırmaya emin misiniz?" + IDS_MSG_UNABLETERMINATEPRO "İşlem sonlandırma yapılamaz." + IDS_MSG_UNABLECHANGEPRIORITY "İşlemci önceliği değiştirilemez." + IDS_MSG_WARNINGCHANGEPRIORITY "UYARI: İşlemci önceliğinin değiştirilmesi, dizge\nkararsızlığı gibi istenmeyen durumlara neden olabilir. Bu işlemin\nişlemci önceliğini değiştirmeye emin misiniz?" + IDS_MSG_TRAYICONCPUUSAGE "CPU Kullanımı: %%%d" + IDS_STATUS_MEMUSAGE "Bellek Kullanımı: %d KB / %d KB" + IDS_STATUS_CPUUSAGE "CPU Kullanımı: %%%3d" + IDS_STATUS_PROCESSES "İşlem Sayısı: %d" + IDS_Not_Responding "Yanıt Vermiyor" + IDS_Running "Çalışıyor" +END diff --git a/base/applications/taskmgr/rsrc.rc b/base/applications/taskmgr/rsrc.rc index 922099849fc..4e6aa6395b8 100644 --- a/base/applications/taskmgr/rsrc.rc +++ b/base/applications/taskmgr/rsrc.rc @@ -67,6 +67,9 @@ #ifdef LANGUAGE_SV_SE #include "lang/sv-SE.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/base/services/svchost/svchost.c b/base/services/svchost/svchost.c index b3259132403..a04346962cd 100644 --- a/base/services/svchost/svchost.c +++ b/base/services/svchost/svchost.c @@ -1,9 +1,9 @@ /* - * PROJECT: ReactOS SvcHost - * LICENSE: GPL - See COPYING in the top level directory - * FILE: /base/services/svchost/svchost.c - * PURPOSE: Provide dll service loader - * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) + * PROJECT: ReactOS SvcHost + * LICENSE: GPL - See COPYING in the top level directory + * FILE: /base/services/svchost/svchost.c + * PURPOSE: Provide dll service loader + * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) */ /* INCLUDES ******************************************************************/ @@ -15,248 +15,289 @@ /* DEFINES *******************************************************************/ -static LPCTSTR SVCHOST_REG_KEY = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost"); -static LPCTSTR SERVICE_KEY = _T("SYSTEM\\CurrentControlSet\\Services\\"); -static LPCTSTR PARAMETERS_KEY = _T("\\Parameters"); +static PCWSTR SVCHOST_REG_KEY = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost"; +static PCWSTR SERVICE_KEY = L"SYSTEM\\CurrentControlSet\\Services\\"; +static PCWSTR PARAMETERS_KEY = L"\\Parameters"; -#define SERVICE_KEY_LENGTH _tcslen(SERVICE_KEY); -#define REG_MAX_DATA_SIZE 2048 +#define REG_MAX_DATA_SIZE 2048 static PSERVICE FirstService = NULL; /* FUNCTIONS *****************************************************************/ -BOOL PrepareService(LPCTSTR ServiceName) +BOOL PrepareService(PCWSTR ServiceName) { - HKEY hServiceKey; - TCHAR ServiceKeyBuffer[MAX_PATH + 1]; - DWORD LeftOfBuffer = sizeof(ServiceKeyBuffer) / sizeof(ServiceKeyBuffer[0]); - DWORD KeyType; - PTSTR Buffer = NULL; - DWORD BufferSize = MAX_PATH + 1; - LONG RetVal; - HINSTANCE hServiceDll; - TCHAR DllPath[MAX_PATH + 2]; /* See MSDN on ExpandEnvironmentStrings() for ANSI strings for more details on + 2 */ - LPSERVICE_MAIN_FUNCTION ServiceMainFunc; - PSERVICE Service; + HKEY hServiceKey; + WCHAR ServiceKeyBuffer[512]; + HRESULT Result; + DWORD ValueType; + PWSTR Buffer; + DWORD BufferSize; + LONG RetVal; + HINSTANCE hServiceDll; + PWSTR DllPath; + DWORD DllPathSize; + LPSERVICE_MAIN_FUNCTION ServiceMainFunc; + PSERVICE Service; + DWORD ServiceNameSize; - /* Compose the registry path to the service's "Parameter" key */ - _tcsncpy(ServiceKeyBuffer, SERVICE_KEY, LeftOfBuffer); - LeftOfBuffer -= _tcslen(SERVICE_KEY); - _tcsncat(ServiceKeyBuffer, ServiceName, LeftOfBuffer); - LeftOfBuffer -= _tcslen(ServiceName); - _tcsncat(ServiceKeyBuffer, PARAMETERS_KEY, LeftOfBuffer); - LeftOfBuffer -= _tcslen(PARAMETERS_KEY); + /* Compose the registry path to the service's "Parameter" key */ + Result = StringCbCopy(ServiceKeyBuffer, sizeof(ServiceKeyBuffer), SERVICE_KEY); + if (FAILED(Result)) + { + DPRINT1("Buffer overflow for service name: '%ls'\n", ServiceName); + return FALSE; + } + Result = StringCbCat(ServiceKeyBuffer, sizeof(ServiceKeyBuffer), ServiceName); + if (FAILED(Result)) + { + DPRINT1("Buffer overflow for service name: '%ls'\n", ServiceName); + return FALSE; + } + Result = StringCbCat(ServiceKeyBuffer, sizeof(ServiceKeyBuffer), PARAMETERS_KEY); + if (FAILED(Result)) + { + DPRINT1("Buffer overflow for service name: '%ls'\n", ServiceName); + return FALSE; + } - if (LeftOfBuffer < 0) - { - DPRINT1("Buffer overflow for service name: '%s'\n", ServiceName); - return FALSE; - } + /* Open the service registry key to find the dll name */ + RetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ServiceKeyBuffer, 0, KEY_READ, &hServiceKey); + if (RetVal != ERROR_SUCCESS) + { + DPRINT1("Could not open service key (%ls)\n", ServiceKeyBuffer); + return FALSE; + } - /* Open the service registry key to find the dll name */ - if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, ServiceKeyBuffer, 0, KEY_READ, &hServiceKey)) - { - DPRINT1("Could not open service key (%s)\n", ServiceKeyBuffer); - return FALSE; - } + BufferSize = 0; + RetVal = RegQueryValueEx(hServiceKey, L"ServiceDll", NULL, &ValueType, NULL, &BufferSize); + if (RetVal != ERROR_SUCCESS) + { + RegCloseKey(hServiceKey); + return FALSE; + } - do - { - if (Buffer) - HeapFree(GetProcessHeap(), 0, Buffer); + Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); + if (Buffer == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + RegCloseKey(hServiceKey); + return FALSE; + } - Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); - if (NULL == Buffer) - { - DPRINT1("Not enough memory for service: %s\n", ServiceName); - return FALSE; - } + RetVal = RegQueryValueEx(hServiceKey, L"ServiceDll", NULL, &ValueType, (LPBYTE)Buffer, &BufferSize); + if (RetVal != ERROR_SUCCESS || BufferSize == 0) + { + DPRINT1("Could not read 'ServiceDll' value from service: %ls, ErrorCode: 0x%lx\n", ServiceName, RetVal); + RegCloseKey(hServiceKey); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + RegCloseKey(hServiceKey); - RetVal = RegQueryValueEx(hServiceKey, _T("ServiceDll"), NULL, &KeyType, (LPBYTE)Buffer, &BufferSize); + if (ValueType == REG_EXPAND_SZ) + { + /* Convert possible %SystemRoot% to a real path */ + DllPathSize = ExpandEnvironmentStrings(Buffer, NULL, 0); + if (DllPathSize == 0) + { + DPRINT1("Invalid ServiceDll path: %ls, ErrorCode: %lu\n", Buffer, GetLastError()); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + DllPath = HeapAlloc(GetProcessHeap(), 0, DllPathSize * sizeof(WCHAR)); + if (DllPath == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + if (ExpandEnvironmentStrings(Buffer, DllPath, DllPathSize) != DllPathSize) + { + DPRINT1("Invalid ServiceDll path: %ls, ErrorCode: %lu\n", Buffer, GetLastError()); + HeapFree(GetProcessHeap(), 0, DllPath); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } - } while (ERROR_MORE_DATA == RetVal); + HeapFree(GetProcessHeap(), 0, Buffer); + } + else if (ValueType == REG_SZ) + { + DllPath = Buffer; + } + else + { + DPRINT1("Invalid ServiceDll value type %lu for service: %ls, ErrorCode: %lu\n", ValueType, ServiceName, GetLastError()); + HeapFree(GetProcessHeap(), 0, Buffer); + return FALSE; + } + /* Load the service dll */ + DPRINT("Trying to load dll\n"); + hServiceDll = LoadLibrary(DllPath); + if (hServiceDll == NULL) + { + DPRINT1("Unable to load ServiceDll: %ls, ErrorCode: %lu\n", DllPath, GetLastError()); + HeapFree(GetProcessHeap(), 0, DllPath); + return FALSE; + } + HeapFree(GetProcessHeap(), 0, DllPath); - RegCloseKey(hServiceKey); + ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain"); - if (ERROR_SUCCESS != RetVal || 0 == BufferSize) - { - DPRINT1("Could not read 'ServiceDll' value from service: %s, ErrorCode: 0x%x\n", ServiceName, RetVal); - HeapFree(GetProcessHeap(), 0, Buffer); - return FALSE; - } + /* Allocate a service node in the linked list */ + Service = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SERVICE)); + if (Service == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + return FALSE; + } - /* Convert possible %SystemRoot% to a real path */ - BufferSize = ExpandEnvironmentStrings(Buffer, DllPath, _countof(DllPath)); - if (0 == BufferSize) - { - DPRINT1("Invalid ServiceDll path: %s\n", Buffer); - HeapFree(GetProcessHeap(), 0, Buffer); - return FALSE; - } + ServiceNameSize = (wcslen(ServiceName) + 1) * sizeof(WCHAR); + Service->Name = HeapAlloc(GetProcessHeap(), 0, ServiceNameSize); + if (Service->Name == NULL) + { + DPRINT1("Not enough memory for service: %ls\n", ServiceName); + HeapFree(GetProcessHeap(), 0, Service); + return FALSE; + } + Result = StringCbCopy(Service->Name, ServiceNameSize, ServiceName); + ASSERT(SUCCEEDED(Result)); + (VOID)Result; - HeapFree(GetProcessHeap(), 0, Buffer); + Service->hServiceDll = hServiceDll; + Service->ServiceMainFunc = ServiceMainFunc; - /* Load the service dll */ - DPRINT("Trying to load dll\n"); - hServiceDll = LoadLibrary(DllPath); + Service->Next = FirstService; + FirstService = Service; - if (NULL == hServiceDll) - { - DPRINT1("Unable to load ServiceDll: %s, ErrorCode: %u\n", DllPath, GetLastError()); - return FALSE; - } - - ServiceMainFunc = (LPSERVICE_MAIN_FUNCTION)GetProcAddress(hServiceDll, "ServiceMain"); - - /* Allocate a service node in the linked list */ - Service = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE)); - if (NULL == Service) - { - DPRINT1("Not enough memory for service: %s\n", ServiceName); - return FALSE; - } - - memset(Service, 0, sizeof(SERVICE)); - Service->Name = HeapAlloc(GetProcessHeap(), 0, (_tcslen(ServiceName)+1) * sizeof(TCHAR)); - if (NULL == Service->Name) - { - DPRINT1("Not enough memory for service: %s\n", ServiceName); - HeapFree(GetProcessHeap(), 0, Service); - return FALSE; - } - _tcscpy(Service->Name, ServiceName); - - Service->hServiceDll = hServiceDll; - Service->ServiceMainFunc = ServiceMainFunc; - - Service->Next = FirstService; - FirstService = Service; - - return TRUE; + return TRUE; } VOID FreeServices(VOID) { - while (FirstService) - { - PSERVICE Service = FirstService; - FirstService = Service->Next; + while (FirstService) + { + PSERVICE Service = FirstService; + FirstService = Service->Next; - FreeLibrary(Service->hServiceDll); + FreeLibrary(Service->hServiceDll); - HeapFree(GetProcessHeap(), 0, Service->Name); - HeapFree(GetProcessHeap(), 0, Service); - } + HeapFree(GetProcessHeap(), 0, Service->Name); + HeapFree(GetProcessHeap(), 0, Service); + } } /* * Returns the number of services successfully loaded from the category */ -DWORD LoadServiceCategory(LPCTSTR ServiceCategory) +DWORD LoadServiceCategory(PCWSTR ServiceCategory) { - HKEY hServicesKey; - DWORD KeyType; - DWORD BufferSize = REG_MAX_DATA_SIZE; - TCHAR Buffer[REG_MAX_DATA_SIZE]; - LPCTSTR ServiceName; - DWORD BufferIndex = 0; - DWORD NrOfServices = 0; + HKEY hServicesKey; + DWORD ValueType; + WCHAR Buffer[REG_MAX_DATA_SIZE]; + DWORD BufferSize = sizeof(Buffer); + PCWSTR ServiceName; + DWORD BufferIndex = 0; + DWORD NrOfServices = 0; + LONG RetVal; - /* Get all the services in this category */ - if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_REG_KEY, 0, KEY_READ, &hServicesKey)) - { - DPRINT1("Could not open service category: %s\n", ServiceCategory); - return 0; - } + /* Get all the services in this category */ + RetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SVCHOST_REG_KEY, 0, KEY_READ, &hServicesKey); + if (RetVal != ERROR_SUCCESS) + { + DPRINT1("Could not open service category: %ls\n", ServiceCategory); + return 0; + } - if (ERROR_SUCCESS != RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &KeyType, (LPBYTE)Buffer, &BufferSize)) - { - DPRINT1("Could not open service category (2): %s\n", ServiceCategory); - RegCloseKey(hServicesKey); - return 0; - } + RetVal = RegQueryValueEx(hServicesKey, ServiceCategory, NULL, &ValueType, (LPBYTE)Buffer, &BufferSize); + if (RetVal != ERROR_SUCCESS) + { + DPRINT1("Could not open service category (2): %ls\n", ServiceCategory); + RegCloseKey(hServicesKey); + return 0; + } - /* Clean up */ - RegCloseKey(hServicesKey); + /* Clean up */ + RegCloseKey(hServicesKey); - /* Load services in the category */ - ServiceName = Buffer; - while (_T('\0') != ServiceName[0]) - { - size_t Length; - - Length = _tcslen(ServiceName); - if (0 == Length) - break; + /* Load services in the category */ + ServiceName = Buffer; + while (ServiceName[0] != UNICODE_NULL) + { + size_t Length; - if (TRUE == PrepareService(ServiceName)) - ++NrOfServices; + Length = wcslen(ServiceName); + if (Length == 0) + break; - BufferIndex += Length + 1; + if (PrepareService(ServiceName)) + ++NrOfServices; - ServiceName = &Buffer[BufferIndex]; - } + BufferIndex += Length + 1; - return NrOfServices; + ServiceName = &Buffer[BufferIndex]; + } + + return NrOfServices; } -int _tmain (int argc, LPTSTR argv []) +int wmain(int argc, wchar_t **argv) { - DWORD NrOfServices; - LPSERVICE_TABLE_ENTRY ServiceTable; + DWORD NrOfServices; + LPSERVICE_TABLE_ENTRY ServiceTable; - if (argc < 3) - { - /* MS svchost.exe doesn't seem to print help, should we? */ - return 0; - } + if (argc < 3) + { + /* MS svchost.exe doesn't seem to print help, should we? */ + return 0; + } - if (_tcscmp(argv[1], _T("-k")) != 0) - { - /* For now, we only handle "-k" */ - return 0; - } + if (wcscmp(argv[1], L"-k")) + { + /* For now, we only handle "-k" */ + return 0; + } - NrOfServices = LoadServiceCategory(argv[2]); + NrOfServices = LoadServiceCategory(argv[2]); - DPRINT("NrOfServices: %lu\n", NrOfServices); - if (0 == NrOfServices) - return 0; + DPRINT("NrOfServices: %lu\n", NrOfServices); + if (NrOfServices == 0) + return 0; - ServiceTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); + ServiceTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); + if (ServiceTable != NULL) + { + DWORD i; + PSERVICE Service = FirstService; - if (NULL != ServiceTable) - { - DWORD i; - PSERVICE Service = FirstService; + /* Fill the service table */ + for (i = 0; i < NrOfServices; i++) + { + DPRINT("Loading service: %ls\n", Service->Name); + ServiceTable[i].lpServiceName = Service->Name; + ServiceTable[i].lpServiceProc = Service->ServiceMainFunc; + Service = Service->Next; + } + ASSERT(Service == NULL); - /* Fill the service table */ - for (i = 0; i < NrOfServices; i++) - { - DPRINT("Loading service: %s\n", Service->Name); - ServiceTable[i].lpServiceName = Service->Name; - ServiceTable[i].lpServiceProc = Service->ServiceMainFunc; - Service = Service->Next; - } + /* Set a NULL entry to end the service table */ + ServiceTable[i].lpServiceName = NULL; + ServiceTable[i].lpServiceProc = NULL; - /* Set a NULL entry to end the service table */ - ServiceTable[i].lpServiceName = NULL; - ServiceTable[i].lpServiceProc = NULL; + if (!StartServiceCtrlDispatcher(ServiceTable)) + DPRINT1("Failed to start service control dispatcher, ErrorCode: %lu\n", GetLastError()); - if (FALSE == StartServiceCtrlDispatcher(ServiceTable)) - DPRINT1("Failed to start service control dispatcher, ErrorCode: %lu\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, ServiceTable); + } + else + { + DPRINT1("Not enough memory for the service table, trying to allocate %u bytes\n", sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); + } - HeapFree(GetProcessHeap(), 0, ServiceTable); - } - else - { - DPRINT1("Not enough memory for the service table, trying to allocate %u bytes\n", sizeof(SERVICE_TABLE_ENTRY) * (NrOfServices + 1)); - } - - DPRINT("Freeing services...\n"); - FreeServices(); + DPRINT("Freeing services...\n"); + FreeServices(); return 0; } diff --git a/base/services/svchost/svchost.h b/base/services/svchost/svchost.h index 2956fad9fa0..1702b3da692 100644 --- a/base/services/svchost/svchost.h +++ b/base/services/svchost/svchost.h @@ -1,39 +1,32 @@ /* - * PROJECT: ReactOS SvcHost - * LICENSE: GPL - See COPYING in the top level directory - * FILE: /base/services/svchost/svchost.h - * PURPOSE: Provide dll service loader - * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) + * PROJECT: ReactOS SvcHost + * LICENSE: GPL - See COPYING in the top level directory + * FILE: /base/services/svchost/svchost.h + * PURPOSE: Provide dll service loader + * PROGRAMMERS: Gregor Brunmar (gregor.brunmar@home.se) */ #pragma once /* INCLUDES ******************************************************************/ -#if 0 -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - #include #include #include #include #include #include -#include +#include /* DEFINES *******************************************************************/ -#define CS_TIMEOUT 1000 - typedef struct _SERVICE { - PTSTR Name; - HINSTANCE hServiceDll; - LPSERVICE_MAIN_FUNCTION ServiceMainFunc; - struct _SERVICE *Next; + PWSTR Name; + HINSTANCE hServiceDll; + LPSERVICE_MAIN_FUNCTION ServiceMainFunc; + struct _SERVICE *Next; } SERVICE, *PSERVICE; - /* FUNCTIONS *****************************************************************/ /* EOF */ diff --git a/base/shell/CMakeLists.txt b/base/shell/CMakeLists.txt index 4849ec112a6..dc06a56fcda 100644 --- a/base/shell/CMakeLists.txt +++ b/base/shell/CMakeLists.txt @@ -1,7 +1,4 @@ add_subdirectory(cmd) -if(NOT MSVC) add_subdirectory(explorer) -endif() add_subdirectory(explorer-new) - diff --git a/base/shell/cmd/alias.c b/base/shell/cmd/alias.c index 577c2404990..4c71d378bec 100644 --- a/base/shell/cmd/alias.c +++ b/base/shell/cmd/alias.c @@ -25,10 +25,10 @@ * 24-Jan-1998 Eric Kohl * Redirection safe! * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc * - * 02-Feb-2008 (Christoph von Wittich) ) + * 02-Feb-2008 (Christoph von Wittich ) * rewrote alias handling for doskey compat */ @@ -42,168 +42,168 @@ static VOID partstrlwr (LPTSTR str) { - LPTSTR c = str; - while (*c && !_istspace (*c) && *c != _T('=')) - { - *c = _totlower (*c); - c++; - } + LPTSTR c = str; + while (*c && !_istspace (*c) && *c != _T('=')) + { + *c = _totlower (*c); + c++; + } } static VOID PrintAlias (VOID) { - LPTSTR Aliases; - LPTSTR ptr; - DWORD len; + LPTSTR Aliases; + LPTSTR ptr; + DWORD len; - len = GetConsoleAliasesLength(_T("cmd.exe")); - if (len <= 0) - return; + len = GetConsoleAliasesLength(_T("cmd.exe")); + if (len <= 0) + return; - /* allocate memory for an extra \0 char to make parsing easier */ - ptr = cmd_alloc(len + sizeof(TCHAR)); - if (!ptr) - return; + /* allocate memory for an extra \0 char to make parsing easier */ + ptr = cmd_alloc(len + sizeof(TCHAR)); + if (!ptr) + return; - Aliases = ptr; + Aliases = ptr; - ZeroMemory(Aliases, len + sizeof(TCHAR)); + ZeroMemory(Aliases, len + sizeof(TCHAR)); - if (GetConsoleAliases(Aliases, len, _T("cmd.exe")) != 0) - { - while (*Aliases != '\0') - { - ConOutPrintf(_T("%s\n"), Aliases); - Aliases = Aliases + lstrlen(Aliases); - Aliases++; - } - } - cmd_free(ptr); + if (GetConsoleAliases(Aliases, len, _T("cmd.exe")) != 0) + { + while (*Aliases != '\0') + { + ConOutPrintf(_T("%s\n"), Aliases); + Aliases = Aliases + lstrlen(Aliases); + Aliases++; + } + } + cmd_free(ptr); } /* specified routines */ VOID ExpandAlias (LPTSTR cmd, INT maxlen) { - LPTSTR buffer; - TCHAR *position, *in, *out; - LPTSTR Token; - LPTSTR tmp; + LPTSTR buffer; + TCHAR *position, *in, *out; + LPTSTR Token; + LPTSTR tmp; - tmp = cmd_dup(cmd); - if (!tmp) - return; + tmp = cmd_dup(cmd); + if (!tmp) + return; - /* first part is the macro name */ - position = tmp + _tcscspn(tmp, _T(" \n")); - if (position == tmp) - { - cmd_free(tmp); - return; - } - *position++ = _T('\0'); - position += _tcsspn(position, _T(" ")); + /* first part is the macro name */ + position = tmp + _tcscspn(tmp, _T(" \n")); + if (position == tmp) + { + cmd_free(tmp); + return; + } + *position++ = _T('\0'); + position += _tcsspn(position, _T(" ")); - buffer = cmd_alloc(maxlen); - if (!buffer) - { - cmd_free(tmp); - return; - } - - if (GetConsoleAlias(tmp, buffer, maxlen, _T("cmd.exe")) == 0) - { - cmd_free(tmp); - cmd_free(buffer); - return; - } + buffer = cmd_alloc(maxlen); + if (!buffer) + { + cmd_free(tmp); + return; + } - in = buffer; - out = cmd; - while (*in) - { - if (*in == _T('$')) - { - Token = position; - if (in[1] >= _T('1') && in[1] <= _T('9')) - { - /* Copy a single space-delimited token from the input line */ - INT num; - for (num = in[1] - _T('1'); num > 0; num--) - { - Token += _tcscspn(Token, _T(" \n")); - Token += _tcsspn(Token, _T(" ")); - } - while (!_tcschr(_T(" \n"), *Token)) - { - if (out >= &cmd[maxlen - 1]) - break; - *out++ = *Token++; - } - in += 2; - continue; - } - else if (in[1] == _T('*')) - { - /* Copy the entire remainder of the line */ - while (*Token && *Token != _T('\n')) - { - if (out >= &cmd[maxlen - 1]) - break; - *out++ = *Token++; - } - in += 2; - continue; - } - } - if (out >= &cmd[maxlen - 1]) - break; - *out++ = *in++; - } - *out++ = _T('\n'); - *out = _T('\0'); + if (GetConsoleAlias(tmp, buffer, maxlen, _T("cmd.exe")) == 0) + { + cmd_free(tmp); + cmd_free(buffer); + return; + } - cmd_free(buffer); - cmd_free(tmp); + in = buffer; + out = cmd; + while (*in) + { + if (*in == _T('$')) + { + Token = position; + if (in[1] >= _T('1') && in[1] <= _T('9')) + { + /* Copy a single space-delimited token from the input line */ + INT num; + for (num = in[1] - _T('1'); num > 0; num--) + { + Token += _tcscspn(Token, _T(" \n")); + Token += _tcsspn(Token, _T(" ")); + } + while (!_tcschr(_T(" \n"), *Token)) + { + if (out >= &cmd[maxlen - 1]) + break; + *out++ = *Token++; + } + in += 2; + continue; + } + else if (in[1] == _T('*')) + { + /* Copy the entire remainder of the line */ + while (*Token && *Token != _T('\n')) + { + if (out >= &cmd[maxlen - 1]) + break; + *out++ = *Token++; + } + in += 2; + continue; + } + } + if (out >= &cmd[maxlen - 1]) + break; + *out++ = *in++; + } + *out++ = _T('\n'); + *out = _T('\0'); + + cmd_free(buffer); + cmd_free(tmp); } INT CommandAlias (LPTSTR param) { - LPTSTR ptr; + LPTSTR ptr; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_ALIAS_HELP); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_ALIAS_HELP); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - if (param[0] == _T('\0')) - { - PrintAlias (); - return 0; - } + if (param[0] == _T('\0')) + { + PrintAlias (); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - /* error if no '=' found */ - if ((ptr = _tcschr (param, _T('='))) == 0) - { - nErrorLevel = 1; - return 1; - } + /* error if no '=' found */ + if ((ptr = _tcschr (param, _T('='))) == 0) + { + nErrorLevel = 1; + return 1; + } - /* Split rest into name and substitute */ - *ptr++ = _T('\0'); + /* Split rest into name and substitute */ + *ptr++ = _T('\0'); - partstrlwr (param); + partstrlwr (param); - if (ptr[0] == _T('\0')) - AddConsoleAlias(param, NULL, _T("cmd.exe")); - else - AddConsoleAlias(param, ptr, _T("cmd.exe")); + if (ptr[0] == _T('\0')) + AddConsoleAlias(param, NULL, _T("cmd.exe")); + else + AddConsoleAlias(param, ptr, _T("cmd.exe")); - return 0; + return 0; } #endif diff --git a/base/shell/cmd/assoc.c b/base/shell/cmd/assoc.c index b2e7e25492e..d78a225ab1c 100644 --- a/base/shell/cmd/assoc.c +++ b/base/shell/cmd/assoc.c @@ -24,236 +24,235 @@ static INT PrintAssociation(LPTSTR extension) { - DWORD return_val; - HKEY hKey = NULL, hInsideKey = NULL; + DWORD return_val; + HKEY hKey = NULL, hInsideKey = NULL; - DWORD fileTypeLength = 0; - LPTSTR fileType = NULL; + DWORD fileTypeLength = 0; + LPTSTR fileType = NULL; - return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_READ, &hKey); + return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_READ, &hKey); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return -1; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return -1; + } - return_val = RegOpenKeyEx(hKey, extension, 0, KEY_READ, &hInsideKey); + return_val = RegOpenKeyEx(hKey, extension, 0, KEY_READ, &hInsideKey); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hKey); - RegCloseKey(hInsideKey); - return 0; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hKey); + RegCloseKey(hInsideKey); + return 0; + } - /* obtain string length */ - return_val = RegQueryValueEx(hInsideKey, NULL, NULL, NULL, NULL, &fileTypeLength); + /* obtain string length */ + return_val = RegQueryValueEx(hInsideKey, NULL, NULL, NULL, NULL, &fileTypeLength); - if(return_val == ERROR_FILE_NOT_FOUND) /* no default value, don't display */ - { - RegCloseKey(hInsideKey); - RegCloseKey(hKey); - return 0; - } + if (return_val == ERROR_FILE_NOT_FOUND) /* no default value, don't display */ + { + RegCloseKey(hInsideKey); + RegCloseKey(hKey); + return 0; + } - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hInsideKey); - RegCloseKey(hKey); - return -2; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hInsideKey); + RegCloseKey(hKey); + return -2; + } - fileType = cmd_alloc(fileTypeLength * sizeof(TCHAR)); + fileType = cmd_alloc(fileTypeLength * sizeof(TCHAR)); - /* obtain actual file type */ - return_val = RegQueryValueEx(hInsideKey, NULL, NULL, NULL, (LPBYTE) fileType, &fileTypeLength); + /* obtain actual file type */ + return_val = RegQueryValueEx(hInsideKey, NULL, NULL, NULL, (LPBYTE) fileType, &fileTypeLength); - RegCloseKey(hInsideKey); - RegCloseKey(hKey); + RegCloseKey(hInsideKey); + RegCloseKey(hKey); - if(return_val != ERROR_SUCCESS) - { - cmd_free(fileType); - return -2; - } + if (return_val != ERROR_SUCCESS) + { + cmd_free(fileType); + return -2; + } - if(fileTypeLength != 0) /* if there is a default key, display relevant information */ - { - ConOutPrintf(_T("%s=%s\r\n"), extension, fileType); - } + if (fileTypeLength != 0) /* if there is a default key, display relevant information */ + { + ConOutPrintf(_T("%s=%s\n"), extension, fileType); + } - if(fileTypeLength) - cmd_free(fileType); + if (fileTypeLength) + cmd_free(fileType); - return 1; + return 1; } static INT PrintAllAssociations() { - DWORD return_val = 0; - HKEY hKey = NULL; - DWORD numKeys = 0; + DWORD return_val = 0; + HKEY hKey = NULL; + DWORD numKeys = 0; - DWORD extLength = 0; - LPTSTR extName = NULL; - DWORD keyCtr = 0; + DWORD extLength = 0; + LPTSTR extName = NULL; + DWORD keyCtr = 0; - return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_READ, &hKey); + return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_READ, &hKey); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return -1; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return -1; + } - return_val = RegQueryInfoKey(hKey, NULL, NULL, NULL, &numKeys, &extLength, NULL, NULL, NULL, NULL, NULL, NULL); + return_val = RegQueryInfoKey(hKey, NULL, NULL, NULL, &numKeys, &extLength, NULL, NULL, NULL, NULL, NULL, NULL); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return -2; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return -2; + } - extName = cmd_alloc(extLength * sizeof(TCHAR)); + extName = cmd_alloc(extLength * sizeof(TCHAR)); - for(keyCtr = 0; keyCtr < numKeys; keyCtr++) - { - DWORD buffer_size = extLength; - return_val = RegEnumKeyEx(hKey, keyCtr, extName, &buffer_size, NULL, NULL, NULL, NULL); + for(keyCtr = 0; keyCtr < numKeys; keyCtr++) + { + DWORD buffer_size = extLength; + return_val = RegEnumKeyEx(hKey, keyCtr, extName, &buffer_size, NULL, NULL, NULL, NULL); - if(return_val == ERROR_SUCCESS || return_val == ERROR_MORE_DATA) - { - if(*extName == _T('.')) - PrintAssociation(extName); - } - else - { - cmd_free(extName); - RegCloseKey(hKey); - return -1; - } - } + if (return_val == ERROR_SUCCESS || return_val == ERROR_MORE_DATA) + { + if (*extName == _T('.')) + PrintAssociation(extName); + } + else + { + cmd_free(extName); + RegCloseKey(hKey); + return -1; + } + } - RegCloseKey(hKey); + RegCloseKey(hKey); - if(extName) - cmd_free(extName); + if (extName) + cmd_free(extName); - return numKeys; + return numKeys; } static INT AddAssociation(LPTSTR extension, LPTSTR type) { - DWORD return_val; - HKEY hKey = NULL, insideKey = NULL; + DWORD return_val; + HKEY hKey = NULL, insideKey = NULL; - return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_ALL_ACCESS, &hKey); + return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_ALL_ACCESS, &hKey); - if(return_val != ERROR_SUCCESS) - return -1; + if (return_val != ERROR_SUCCESS) + return -1; - return_val = RegCreateKeyEx(hKey, extension, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &insideKey, NULL); + return_val = RegCreateKeyEx(hKey, extension, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &insideKey, NULL); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return -1; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return -1; + } - return_val = RegSetValueEx(insideKey, NULL, 0, REG_SZ, (LPBYTE)type, (_tcslen(type) + 1) * sizeof(TCHAR)); + return_val = RegSetValueEx(insideKey, NULL, 0, REG_SZ, (LPBYTE)type, (_tcslen(type) + 1) * sizeof(TCHAR)); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(insideKey); - RegCloseKey(hKey); - return -2; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(insideKey); + RegCloseKey(hKey); + return -2; + } - RegCloseKey(insideKey); - RegCloseKey(hKey); - return 0; + RegCloseKey(insideKey); + RegCloseKey(hKey); + return 0; } static int RemoveAssociation(LPTSTR extension) { - DWORD return_val; - HKEY hKey; + DWORD return_val; + HKEY hKey; - return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_ALL_ACCESS, &hKey); + return_val = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0, KEY_ALL_ACCESS, &hKey); - if(return_val != ERROR_SUCCESS) - return -1; + if (return_val != ERROR_SUCCESS) + return -1; - return_val = RegDeleteKey(hKey, extension); + return_val = RegDeleteKey(hKey, extension); - if(return_val != ERROR_SUCCESS) - { - RegCloseKey(hKey); - return -2; - } + if (return_val != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return -2; + } - RegCloseKey(hKey); - return 0; + RegCloseKey(hKey); + return 0; } INT CommandAssoc (LPTSTR param) { + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_ASSOC_HELP); + return 0; + } - /* print help */ - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_ASSOC_HELP); - return 0; - } + nErrorLevel = 0; - nErrorLevel = 0; + if (_tcslen(param) == 0) + PrintAllAssociations(); + else + { + LPTSTR lpEqualSign = _tcschr(param, _T('=')); + if (lpEqualSign != NULL) + { + LPTSTR fileType = lpEqualSign + 1; + LPTSTR extension = cmd_alloc((lpEqualSign - param + 1) * sizeof(TCHAR)); - if(_tcslen(param) == 0) - PrintAllAssociations(); - else - { - LPTSTR lpEqualSign = _tcschr(param, _T('=')); - if(lpEqualSign != NULL) - { - LPTSTR fileType = lpEqualSign + 1; - LPTSTR extension = cmd_alloc((lpEqualSign - param + 1) * sizeof(TCHAR)); + _tcsncpy(extension, param, lpEqualSign - param); + extension[lpEqualSign - param] = (TCHAR)0; - _tcsncpy(extension, param, lpEqualSign - param); - extension[lpEqualSign - param] = (TCHAR)0; + if (_tcslen(fileType) == 0) + /* if the equal sign is the last character + in the string, then delete the key */ + { + RemoveAssociation(extension); + } + else + /* otherwise, add the key and print out the association*/ + { + AddAssociation( extension, fileType); + PrintAssociation(extension); + } - if(_tcslen(fileType) == 0) - /* if the equal sign is the last character - in the string, then delete the key */ - { - RemoveAssociation(extension); - } - else - /* otherwise, add the key and print out the association*/ - { - AddAssociation( extension, fileType); - PrintAssociation(extension); - } + cmd_free(extension); + } + else + { + /* no equal sign, print all associations */ + INT retval = PrintAssociation(param); - cmd_free(extension); - } - else - { - /* no equal sign, print all associations */ - INT retval = PrintAssociation(param); + if (retval == 0) /* if nothing printed out */ + ConOutResPrintf(STRING_ASSOC_ERROR, param); + } + } - if(retval == 0) /* if nothing printed out */ - ConOutResPrintf(STRING_ASSOC_ERROR, param); - } - } - - return 0; + return 0; } #endif /* INCLUDE_CMD_ASSOC */ diff --git a/base/shell/cmd/attrib.c b/base/shell/cmd/attrib.c index 91c3e81a7a0..dfc0f1aff99 100644 --- a/base/shell/cmd/attrib.c +++ b/base/shell/cmd/attrib.c @@ -28,8 +28,8 @@ * 23-Jan-1999 Eric Kohl * Added handling of multiple filenames. * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -39,306 +39,306 @@ static VOID PrintAttribute (LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse) { - WIN32_FIND_DATA findData; - HANDLE hFind; - TCHAR szFullName[MAX_PATH]; - LPTSTR pszFileName; + WIN32_FIND_DATA findData; + HANDLE hFind; + TCHAR szFullName[MAX_PATH]; + LPTSTR pszFileName; - /* prepare full file name buffer */ - _tcscpy (szFullName, pszPath); - pszFileName = szFullName + _tcslen (szFullName); + /* prepare full file name buffer */ + _tcscpy (szFullName, pszPath); + pszFileName = szFullName + _tcslen (szFullName); - /* display all subdirectories */ - if (bRecurse) - { - /* append file name */ - _tcscpy (pszFileName, pszFile); + /* display all subdirectories */ + if (bRecurse) + { + /* append file name */ + _tcscpy (pszFileName, pszFile); - hFind = FindFirstFile (szFullName, &findData); - if (hFind == INVALID_HANDLE_VALUE) - { - ErrorMessage (GetLastError (), pszFile); - return; - } + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); + return; + } - do - { - if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - continue; + do + { + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; - if (!_tcscmp (findData.cFileName, _T(".")) || - !_tcscmp (findData.cFileName, _T(".."))) - continue; + if (!_tcscmp (findData.cFileName, _T(".")) || + !_tcscmp (findData.cFileName, _T(".."))) + continue; - _tcscpy (pszFileName, findData.cFileName); - _tcscat (pszFileName, _T("\\")); - PrintAttribute (szFullName, pszFile, bRecurse); - } - while (FindNextFile (hFind, &findData)); - FindClose (hFind); - } + _tcscpy (pszFileName, findData.cFileName); + _tcscat (pszFileName, _T("\\")); + PrintAttribute (szFullName, pszFile, bRecurse); + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); + } - /* append file name */ - _tcscpy (pszFileName, pszFile); + /* append file name */ + _tcscpy (pszFileName, pszFile); - /* display current directory */ - hFind = FindFirstFile (szFullName, &findData); - if (hFind == INVALID_HANDLE_VALUE) - { - ErrorMessage (GetLastError (), pszFile); - return; - } + /* display current directory */ + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); + return; + } - do - { - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; - _tcscpy (pszFileName, findData.cFileName); + _tcscpy (pszFileName, findData.cFileName); - ConOutPrintf (_T("%c %c%c%c %s\n"), - (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? _T('A') : _T(' '), - (findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? _T('S') : _T(' '), - (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? _T('H') : _T(' '), - (findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _T('R') : _T(' '), - szFullName); - } - while (FindNextFile (hFind, &findData)); - FindClose (hFind); + ConOutPrintf(_T("%c %c%c%c %s\n"), + (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? _T('A') : _T(' '), + (findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? _T('S') : _T(' '), + (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? _T('H') : _T(' '), + (findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _T('R') : _T(' '), + szFullName); + } + while (FindNextFile(hFind, &findData)); + FindClose(hFind); } static VOID -ChangeAttribute (LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask, - DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories) +ChangeAttribute(LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask, + DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories) { - WIN32_FIND_DATA findData; - HANDLE hFind; - DWORD dwAttribute; - TCHAR szFullName[MAX_PATH]; - LPTSTR pszFileName; + WIN32_FIND_DATA findData; + HANDLE hFind; + DWORD dwAttribute; + TCHAR szFullName[MAX_PATH]; + LPTSTR pszFileName; - /* prepare full file name buffer */ - _tcscpy (szFullName, pszPath); - pszFileName = szFullName + _tcslen (szFullName); + /* prepare full file name buffer */ + _tcscpy (szFullName, pszPath); + pszFileName = szFullName + _tcslen (szFullName); - /* change all subdirectories */ - if (bRecurse) - { - /* append file name */ - _tcscpy (pszFileName, _T("*.*")); + /* change all subdirectories */ + if (bRecurse) + { + /* append file name */ + _tcscpy (pszFileName, _T("*.*")); - hFind = FindFirstFile (szFullName, &findData); - if (hFind == INVALID_HANDLE_VALUE) - { - ErrorMessage (GetLastError (), pszFile); + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); nErrorLevel = 1; - return; - } + return; + } - do - { - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - if (!_tcscmp (findData.cFileName, _T(".")) || - !_tcscmp (findData.cFileName, _T(".."))) - continue; + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!_tcscmp (findData.cFileName, _T(".")) || + !_tcscmp (findData.cFileName, _T(".."))) + continue; - _tcscpy (pszFileName, findData.cFileName); - _tcscat (pszFileName, _T("\\")); + _tcscpy (pszFileName, findData.cFileName); + _tcscat (pszFileName, _T("\\")); - ChangeAttribute (szFullName, pszFile, dwMask, - dwAttrib, bRecurse, bDirectories); - } - } - while (FindNextFile (hFind, &findData)); - FindClose (hFind); - } + ChangeAttribute (szFullName, pszFile, dwMask, + dwAttrib, bRecurse, bDirectories); + } + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); + } - /* append file name */ - _tcscpy (pszFileName, pszFile); + /* append file name */ + _tcscpy (pszFileName, pszFile); - hFind = FindFirstFile (szFullName, &findData); - if (hFind == INVALID_HANDLE_VALUE) - { - ErrorMessage (GetLastError (), pszFile); + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); nErrorLevel = 1; - return; - } + return; + } - do - { - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; - _tcscpy (pszFileName, findData.cFileName); + _tcscpy (pszFileName, findData.cFileName); - dwAttribute = GetFileAttributes (szFullName); + dwAttribute = GetFileAttributes (szFullName); - if (dwAttribute != 0xFFFFFFFF) - { - dwAttribute = (dwAttribute & ~dwMask) | dwAttrib; - SetFileAttributes (szFullName, dwAttribute); - } - } - while (FindNextFile (hFind, &findData)); - FindClose (hFind); + if (dwAttribute != 0xFFFFFFFF) + { + dwAttribute = (dwAttribute & ~dwMask) | dwAttrib; + SetFileAttributes (szFullName, dwAttribute); + } + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); } INT CommandAttrib (LPTSTR param) { - LPTSTR *arg; - INT argc, i; - TCHAR szPath[MAX_PATH]; - TCHAR szFileName [MAX_PATH]; - BOOL bRecurse = FALSE; - BOOL bDirectories = FALSE; - DWORD dwAttrib = 0; - DWORD dwMask = 0; + LPTSTR *arg; + INT argc, i; + TCHAR szPath[MAX_PATH]; + TCHAR szFileName [MAX_PATH]; + BOOL bRecurse = FALSE; + BOOL bDirectories = FALSE; + DWORD dwAttrib = 0; + DWORD dwMask = 0; - /* initialize strings */ - szPath[0] = _T('\0'); - szFileName[0] = _T('\0'); + /* initialize strings */ + szPath[0] = _T('\0'); + szFileName[0] = _T('\0'); - /* print help */ - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_ATTRIB_HELP); - return 0; - } + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_ATTRIB_HELP); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - /* build parameter array */ - arg = split (param, &argc, FALSE, FALSE); + /* build parameter array */ + arg = split (param, &argc, FALSE, FALSE); - /* check for options */ - for (i = 0; i < argc; i++) - { - if (_tcsicmp (arg[i], _T("/s")) == 0) - bRecurse = TRUE; - else if (_tcsicmp (arg[i], _T("/d")) == 0) - bDirectories = TRUE; - } + /* check for options */ + for (i = 0; i < argc; i++) + { + if (_tcsicmp (arg[i], _T("/s")) == 0) + bRecurse = TRUE; + else if (_tcsicmp (arg[i], _T("/d")) == 0) + bDirectories = TRUE; + } - /* create attributes and mask */ - for (i = 0; i < argc; i++) - { - if (*arg[i] == _T('+')) - { - if (_tcslen (arg[i]) != 2) - { - error_invalid_parameter_format (arg[i]); - freep (arg); - return -1; - } + /* create attributes and mask */ + for (i = 0; i < argc; i++) + { + if (*arg[i] == _T('+')) + { + if (_tcslen (arg[i]) != 2) + { + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } - switch ((TCHAR)_totupper (arg[i][1])) - { - case _T('A'): - dwMask |= FILE_ATTRIBUTE_ARCHIVE; - dwAttrib |= FILE_ATTRIBUTE_ARCHIVE; - break; + switch ((TCHAR)_totupper (arg[i][1])) + { + case _T('A'): + dwMask |= FILE_ATTRIBUTE_ARCHIVE; + dwAttrib |= FILE_ATTRIBUTE_ARCHIVE; + break; - case _T('H'): - dwMask |= FILE_ATTRIBUTE_HIDDEN; - dwAttrib |= FILE_ATTRIBUTE_HIDDEN; - break; + case _T('H'): + dwMask |= FILE_ATTRIBUTE_HIDDEN; + dwAttrib |= FILE_ATTRIBUTE_HIDDEN; + break; - case _T('R'): - dwMask |= FILE_ATTRIBUTE_READONLY; - dwAttrib |= FILE_ATTRIBUTE_READONLY; - break; + case _T('R'): + dwMask |= FILE_ATTRIBUTE_READONLY; + dwAttrib |= FILE_ATTRIBUTE_READONLY; + break; - case _T('S'): - dwMask |= FILE_ATTRIBUTE_SYSTEM; - dwAttrib |= FILE_ATTRIBUTE_SYSTEM; - break; + case _T('S'): + dwMask |= FILE_ATTRIBUTE_SYSTEM; + dwAttrib |= FILE_ATTRIBUTE_SYSTEM; + break; - default: - error_invalid_parameter_format (arg[i]); - freep (arg); - return -1; - } - } - else if (*arg[i] == _T('-')) - { - if (_tcslen (arg[i]) != 2) - { - error_invalid_parameter_format (arg[i]); - freep (arg); - return -1; - } + default: + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } + } + else if (*arg[i] == _T('-')) + { + if (_tcslen (arg[i]) != 2) + { + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } - switch ((TCHAR)_totupper (arg[i][1])) - { - case _T('A'): - dwMask |= FILE_ATTRIBUTE_ARCHIVE; - dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE; - break; + switch ((TCHAR)_totupper (arg[i][1])) + { + case _T('A'): + dwMask |= FILE_ATTRIBUTE_ARCHIVE; + dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE; + break; - case _T('H'): - dwMask |= FILE_ATTRIBUTE_HIDDEN; - dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN; - break; + case _T('H'): + dwMask |= FILE_ATTRIBUTE_HIDDEN; + dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN; + break; - case _T('R'): - dwMask |= FILE_ATTRIBUTE_READONLY; - dwAttrib &= ~FILE_ATTRIBUTE_READONLY; - break; + case _T('R'): + dwMask |= FILE_ATTRIBUTE_READONLY; + dwAttrib &= ~FILE_ATTRIBUTE_READONLY; + break; - case _T('S'): - dwMask |= FILE_ATTRIBUTE_SYSTEM; - dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM; - break; + case _T('S'): + dwMask |= FILE_ATTRIBUTE_SYSTEM; + dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM; + break; - default: - error_invalid_parameter_format (arg[i]); - freep (arg); - return -1; - } - } - } + default: + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } + } + } - if (argc == 0) - { - DWORD len; + if (argc == 0) + { + DWORD len; - len = GetCurrentDirectory (MAX_PATH, szPath); - if (szPath[len-1] != _T('\\')) - { - szPath[len] = _T('\\'); - szPath[len + 1] = 0; - } - _tcscpy (szFileName, _T("*.*")); - PrintAttribute (szPath, szFileName, bRecurse); - freep (arg); - return 0; - } + len = GetCurrentDirectory (MAX_PATH, szPath); + if (szPath[len-1] != _T('\\')) + { + szPath[len] = _T('\\'); + szPath[len + 1] = 0; + } + _tcscpy (szFileName, _T("*.*")); + PrintAttribute (szPath, szFileName, bRecurse); + freep (arg); + return 0; + } - /* get full file name */ - for (i = 0; i < argc; i++) - { - if ((*arg[i] != _T('+')) && (*arg[i] != _T('-')) && (*arg[i] != _T('/'))) - { - LPTSTR p; - GetFullPathName (arg[i], MAX_PATH, szPath, NULL); - p = _tcsrchr (szPath, _T('\\')) + 1; - _tcscpy (szFileName, p); - *p = _T('\0'); + /* get full file name */ + for (i = 0; i < argc; i++) + { + if ((*arg[i] != _T('+')) && (*arg[i] != _T('-')) && (*arg[i] != _T('/'))) + { + LPTSTR p; + GetFullPathName (arg[i], MAX_PATH, szPath, NULL); + p = _tcsrchr (szPath, _T('\\')) + 1; + _tcscpy (szFileName, p); + *p = _T('\0'); - if (dwMask == 0) - PrintAttribute (szPath, szFileName, bRecurse); - else - ChangeAttribute (szPath, szFileName, dwMask, - dwAttrib, bRecurse, bDirectories); - } - } + if (dwMask == 0) + PrintAttribute (szPath, szFileName, bRecurse); + else + ChangeAttribute (szPath, szFileName, dwMask, + dwAttrib, bRecurse, bDirectories); + } + } - freep (arg); - return 0; + freep (arg); + return 0; } #endif /* INCLUDE_CMD_ATTRIB */ diff --git a/base/shell/cmd/batch.c b/base/shell/cmd/batch.c index fba5fa9f0a8..e2f7d360c57 100644 --- a/base/shell/cmd/batch.c +++ b/base/shell/cmd/batch.c @@ -54,8 +54,8 @@ * 23-Feb-2001 (Carl Nettelblad ) * Fixes made to get "for" working. * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -65,7 +65,7 @@ */ LPBATCH_CONTEXT bc = NULL; -BOOL bEcho = TRUE; /* The echo flag */ +BOOL bEcho = TRUE; /* The echo flag */ @@ -82,24 +82,24 @@ TCHAR textline[BATCH_BUFFSIZE]; LPTSTR FindArg(TCHAR Char, BOOL *IsParam0) { - LPTSTR pp; - INT n = Char - _T('0'); + LPTSTR pp; + INT n = Char - _T('0'); - TRACE ("FindArg: (%d)\n", n); + TRACE ("FindArg: (%d)\n", n); - if (n < 0 || n > 9) - return NULL; + if (n < 0 || n > 9) + return NULL; - n = bc->shiftlevel[n]; - *IsParam0 = (n == 0); - pp = bc->params; + n = bc->shiftlevel[n]; + *IsParam0 = (n == 0); + pp = bc->params; - /* Step up the strings till we reach the end */ - /* or the one we want */ - while (*pp && n--) - pp += _tcslen (pp) + 1; + /* Step up the strings till we reach the end */ + /* or the one we want */ + while (*pp && n--) + pp += _tcslen (pp) + 1; - return pp; + return pp; } @@ -108,51 +108,51 @@ LPTSTR FindArg(TCHAR Char, BOOL *IsParam0) * The parameters consist of null terminated strings with a final * NULL character signalling the end of the parameters. * -*/ + */ LPTSTR BatchParams (LPTSTR s1, LPTSTR s2) { - LPTSTR dp = (LPTSTR)cmd_alloc ((_tcslen(s1) + _tcslen(s2) + 3) * sizeof (TCHAR)); + LPTSTR dp = (LPTSTR)cmd_alloc ((_tcslen(s1) + _tcslen(s2) + 3) * sizeof (TCHAR)); - /* JPP 20-Jul-1998 added error checking */ - if (dp == NULL) - { - error_out_of_memory(); - return NULL; - } + /* JPP 20-Jul-1998 added error checking */ + if (dp == NULL) + { + error_out_of_memory(); + return NULL; + } - if (s1 && *s1) - { - s1 = _stpcpy (dp, s1); - *s1++ = _T('\0'); - } - else - s1 = dp; + if (s1 && *s1) + { + s1 = _stpcpy (dp, s1); + *s1++ = _T('\0'); + } + else + s1 = dp; - while (*s2) - { - BOOL inquotes = FALSE; + while (*s2) + { + BOOL inquotes = FALSE; - /* Find next parameter */ - while (_istspace(*s2) || (*s2 && _tcschr(_T(",;="), *s2))) - s2++; - if (!*s2) - break; + /* Find next parameter */ + while (_istspace(*s2) || (*s2 && _tcschr(_T(",;="), *s2))) + s2++; + if (!*s2) + break; - /* Copy it */ - do - { - if (!inquotes && (_istspace(*s2) || _tcschr(_T(",;="), *s2))) - break; - inquotes ^= (*s2 == _T('"')); - *s1++ = *s2++; - } while (*s2); - *s1++ = _T('\0'); - } + /* Copy it */ + do + { + if (!inquotes && (_istspace(*s2) || _tcschr(_T(",;="), *s2))) + break; + inquotes ^= (*s2 == _T('"')); + *s1++ = *s2++; + } while (*s2); + *s1++ = _T('\0'); + } - *s1 = _T('\0'); + *s1 = _T('\0'); - return dp; + return dp; } /* @@ -160,16 +160,16 @@ LPTSTR BatchParams (LPTSTR s1, LPTSTR s2) */ VOID ClearBatch() { - TRACE ("ClearBatch mem = %08x free = %d\n", bc->mem, bc->memfree); + TRACE ("ClearBatch mem = %08x free = %d\n", bc->mem, bc->memfree); - if (bc->mem && bc->memfree) - cmd_free(bc->mem); + if (bc->mem && bc->memfree) + cmd_free(bc->mem); - if (bc->raw_params) - cmd_free(bc->raw_params); + if (bc->raw_params) + cmd_free(bc->raw_params); - if (bc->params) - cmd_free(bc->params); + if (bc->params) + cmd_free(bc->params); } /* @@ -184,20 +184,20 @@ VOID ClearBatch() VOID ExitBatch() { - ClearBatch(); + ClearBatch(); - TRACE ("ExitBatch\n"); + TRACE ("ExitBatch\n"); - UndoRedirection(bc->RedirList, NULL); - FreeRedirection(bc->RedirList); + UndoRedirection(bc->RedirList, NULL); + FreeRedirection(bc->RedirList); - /* Preserve echo state across batch calls */ - bEcho = bc->bEcho; + /* Preserve echo state across batch calls */ + bEcho = bc->bEcho; - while (bc->setlocal) - cmd_endlocal(_T("")); + while (bc->setlocal) + cmd_endlocal(_T("")); - bc = bc->prev; + bc = bc->prev; } /* @@ -206,26 +206,26 @@ VOID ExitBatch() */ void BatchFile2Mem(HANDLE hBatchFile) { - TRACE ("BatchFile2Mem ()\n"); + TRACE ("BatchFile2Mem ()\n"); - bc->memsize = GetFileSize(hBatchFile, NULL); - bc->mem = (char *)cmd_alloc(bc->memsize+1); /* 1 extra for '\0' */ - - /* if memory is available, read it in and close the file */ - if (bc->mem != NULL) - { - TRACE ("BatchFile2Mem memory %08x - %08x\n",bc->mem,bc->memsize); - SetFilePointer (hBatchFile, 0, NULL, FILE_BEGIN); - ReadFile(hBatchFile, (LPVOID)bc->mem, bc->memsize, &bc->memsize, NULL); - bc->mem[bc->memsize]='\0'; /* end this, so you can dump it as a string */ - bc->memfree=TRUE; /* this one needs to be freed */ - } - else - { - bc->memsize=0; /* this will prevent mem being accessed */ - bc->memfree=FALSE; - } - bc->mempos = 0; /* set position to the start */ + bc->memsize = GetFileSize(hBatchFile, NULL); + bc->mem = (char *)cmd_alloc(bc->memsize+1); /* 1 extra for '\0' */ + + /* if memory is available, read it in and close the file */ + if (bc->mem != NULL) + { + TRACE ("BatchFile2Mem memory %08x - %08x\n",bc->mem,bc->memsize); + SetFilePointer (hBatchFile, 0, NULL, FILE_BEGIN); + ReadFile(hBatchFile, (LPVOID)bc->mem, bc->memsize, &bc->memsize, NULL); + bc->mem[bc->memsize]='\0'; /* end this, so you can dump it as a string */ + bc->memfree=TRUE; /* this one needs to be freed */ + } + else + { + bc->memsize=0; /* this will prevent mem being accessed */ + bc->memfree=FALSE; + } + bc->mempos = 0; /* set position to the start */ } /* @@ -234,97 +234,96 @@ void BatchFile2Mem(HANDLE hBatchFile) * The firstword parameter is the full filename of the batch file. * */ - INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd) { - BATCH_CONTEXT new; - LPFOR_CONTEXT saved_fc; - INT i; - INT ret = 0; - BOOL same_fn = FALSE; + BATCH_CONTEXT new; + LPFOR_CONTEXT saved_fc; + INT i; + INT ret = 0; + BOOL same_fn = FALSE; - HANDLE hFile = 0; - SetLastError(0); - if (bc && bc->mem) - { - TCHAR fpname[MAX_PATH]; - GetFullPathName(fullname, sizeof(fpname) / sizeof(TCHAR), fpname, NULL); - if (_tcsicmp(bc->BatchFilePath,fpname)==0) - same_fn=TRUE; - } - TRACE ("Batch: (\'%s\', \'%s\', \'%s\') same_fn = %d\n", - debugstr_aw(fullname), debugstr_aw(firstword), debugstr_aw(param), same_fn); + HANDLE hFile = 0; + SetLastError(0); + if (bc && bc->mem) + { + TCHAR fpname[MAX_PATH]; + GetFullPathName(fullname, sizeof(fpname) / sizeof(TCHAR), fpname, NULL); + if (_tcsicmp(bc->BatchFilePath,fpname)==0) + same_fn=TRUE; + } + TRACE ("Batch: (\'%s\', \'%s\', \'%s\') same_fn = %d\n", + debugstr_aw(fullname), debugstr_aw(firstword), debugstr_aw(param), same_fn); - if (!same_fn) - { - hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | - FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (!same_fn) + { + hFile = CreateFile(fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | + FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - ConErrResPuts(STRING_BATCH_ERROR); - return 1; - } - } - - if (bc != NULL && Cmd == bc->current) - { - /* Then we are transferring to another batch */ - ClearBatch(); - AddBatchRedirection(&Cmd->Redirections); - } - else - { - struct _SETLOCAL *setlocal = NULL; + if (hFile == INVALID_HANDLE_VALUE) + { + ConErrResPuts(STRING_BATCH_ERROR); + return 1; + } + } - if (Cmd == NULL) - { - /* This is a CALL. CALL will set errorlevel to our return value, so - * in order to keep the value of errorlevel unchanged in the case - * of calling an empty batch file, we must return that same value. */ - ret = nErrorLevel; - } - else if (bc) - { - /* If a batch file runs another batch file as part of a compound command - * (e.g. "x.bat & somethingelse") then the first file gets terminated. */ + if (bc != NULL && Cmd == bc->current) + { + /* Then we are transferring to another batch */ + ClearBatch(); + AddBatchRedirection(&Cmd->Redirections); + } + else + { + struct _SETLOCAL *setlocal = NULL; - /* Get its SETLOCAL stack so it can be migrated to the new context */ - setlocal = bc->setlocal; - bc->setlocal = NULL; - ExitBatch(); - } + if (Cmd == NULL) + { + /* This is a CALL. CALL will set errorlevel to our return value, so + * in order to keep the value of errorlevel unchanged in the case + * of calling an empty batch file, we must return that same value. */ + ret = nErrorLevel; + } + else if (bc) + { + /* If a batch file runs another batch file as part of a compound command + * (e.g. "x.bat & somethingelse") then the first file gets terminated. */ - /* Create a new context. This function will not - * return until this context has been exited */ - new.prev = bc; - /* copy some fields in the new structure if it is the same file */ - if (same_fn) { - new.mem = bc->mem; - new.memsize = bc->memsize; - new.mempos = 0; - new.memfree = FALSE; /* don't free this, being used before this */ - } - bc = &new; - bc->RedirList = NULL; - bc->setlocal = setlocal; - } + /* Get its SETLOCAL stack so it can be migrated to the new context */ + setlocal = bc->setlocal; + bc->setlocal = NULL; + ExitBatch(); + } - GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL); - /* if a new batch file, load it into memory and close the file */ - if (!same_fn) - { - BatchFile2Mem(hFile); - CloseHandle(hFile); - } - - bc->mempos = 0; /* goto begin of batch file */ - bc->bEcho = bEcho; /* Preserve echo across batch calls */ - for (i = 0; i < 10; i++) - bc->shiftlevel[i] = i; - - bc->params = BatchParams (firstword, param); + /* Create a new context. This function will not + * return until this context has been exited */ + new.prev = bc; + /* copy some fields in the new structure if it is the same file */ + if (same_fn) { + new.mem = bc->mem; + new.memsize = bc->memsize; + new.mempos = 0; + new.memfree = FALSE; /* don't free this, being used before this */ + } + bc = &new; + bc->RedirList = NULL; + bc->setlocal = setlocal; + } + + GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL); + /* if a new batch file, load it into memory and close the file */ + if (!same_fn) + { + BatchFile2Mem(hFile); + CloseHandle(hFile); + } + + bc->mempos = 0; /* goto begin of batch file */ + bc->bEcho = bEcho; /* Preserve echo across batch calls */ + for (i = 0; i < 10; i++) + bc->shiftlevel[i] = i; + + bc->params = BatchParams (firstword, param); // // Allocate enough memory to hold the params and copy them over without modifications // @@ -335,58 +334,58 @@ INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd) return 1; } - /* Check if this is a "CALL :label" */ - if (*firstword == _T(':')) - cmd_goto(firstword); + /* Check if this is a "CALL :label" */ + if (*firstword == _T(':')) + cmd_goto(firstword); - /* If we are calling from inside a FOR, hide the FOR variables */ - saved_fc = fc; - fc = NULL; + /* If we are calling from inside a FOR, hide the FOR variables */ + saved_fc = fc; + fc = NULL; - /* If we have created a new context, don't return - * until this batch file has completed. */ - while (bc == &new && !bExit) - { - Cmd = ParseCommand(NULL); - if (!Cmd) - continue; + /* If we have created a new context, don't return + * until this batch file has completed. */ + while (bc == &new && !bExit) + { + Cmd = ParseCommand(NULL); + if (!Cmd) + continue; - /* JPP 19980807 */ - /* Echo batch file line */ - if (bEcho && !bDisableBatchEcho && Cmd->Type != C_QUIET) - { - if (!bIgnoreEcho) - ConOutChar(_T('\n')); - PrintPrompt(); - EchoCommand(Cmd); - ConOutChar(_T('\n')); - } + /* JPP 19980807 */ + /* Echo batch file line */ + if (bEcho && !bDisableBatchEcho && Cmd->Type != C_QUIET) + { + if (!bIgnoreEcho) + ConOutChar(_T('\n')); + PrintPrompt(); + EchoCommand(Cmd); + ConOutChar(_T('\n')); + } - bc->current = Cmd; - ret = ExecuteCommand(Cmd); - FreeCommand(Cmd); - } + bc->current = Cmd; + ret = ExecuteCommand(Cmd); + FreeCommand(Cmd); + } - TRACE ("Batch: returns TRUE\n"); + TRACE ("Batch: returns TRUE\n"); - fc = saved_fc; - return ret; + fc = saved_fc; + return ret; } VOID AddBatchRedirection(REDIRECTION **RedirList) { - REDIRECTION **ListEnd; + REDIRECTION **ListEnd; - /* Prepend the list to the batch context's list */ - ListEnd = RedirList; - while (*ListEnd) - ListEnd = &(*ListEnd)->Next; - *ListEnd = bc->RedirList; - bc->RedirList = *RedirList; + /* Prepend the list to the batch context's list */ + ListEnd = RedirList; + while (*ListEnd) + ListEnd = &(*ListEnd)->Next; + *ListEnd = bc->RedirList; + bc->RedirList = *RedirList; - /* Null out the pointer so that the list will not be cleared prematurely. - * These redirections should persist until the batch file exits. */ - *RedirList = NULL; + /* Null out the pointer so that the list will not be cleared prematurely. + * These redirections should persist until the batch file exits. */ + *RedirList = NULL; } /* @@ -395,41 +394,41 @@ VOID AddBatchRedirection(REDIRECTION **RedirList) */ BOOL BatchGetString (LPTSTR lpBuffer, INT nBufferLength) { - LPSTR lpString; - INT len = 0; + LPSTR lpString; + INT len = 0; #ifdef _UNICODE - lpString = cmd_alloc(nBufferLength); + lpString = cmd_alloc(nBufferLength); #else - lpString = lpBuffer; + lpString = lpBuffer; #endif - /* read all chars from memory until a '\n' is encountered */ - if (bc->mem) - { - for (; (bc->mempos < bc->memsize && len < (nBufferLength-1)); len++) - { - lpString[len] = bc->mem[bc->mempos++]; - if (lpString[len] == '\n' ) - { - len++; - break; - } - } - } + /* read all chars from memory until a '\n' is encountered */ + if (bc->mem) + { + for (; (bc->mempos < bc->memsize && len < (nBufferLength-1)); len++) + { + lpString[len] = bc->mem[bc->mempos++]; + if (lpString[len] == '\n' ) + { + len++; + break; + } + } + } - if (!len) - { + if (!len) + { #ifdef _UNICODE - cmd_free(lpString); + cmd_free(lpString); #endif - return FALSE; - } + return FALSE; + } - lpString[len++] = '\0'; + lpString[len++] = '\0'; #ifdef _UNICODE - MultiByteToWideChar(OutputCodePage, 0, lpString, -1, lpBuffer, len); - cmd_free(lpString); + MultiByteToWideChar(OutputCodePage, 0, lpString, -1, lpBuffer, len); + cmd_free(lpString); #endif - return TRUE; + return TRUE; } /* @@ -442,30 +441,30 @@ BOOL BatchGetString (LPTSTR lpBuffer, INT nBufferLength) */ LPTSTR ReadBatchLine () { - TRACE ("ReadBatchLine ()\n"); + TRACE ("ReadBatchLine ()\n"); - /* User halt */ - if (CheckCtrlBreak (BREAK_BATCHFILE)) - { - while (bc) - ExitBatch(); - return NULL; - } + /* User halt */ + if (CheckCtrlBreak (BREAK_BATCHFILE)) + { + while (bc) + ExitBatch(); + return NULL; + } - if (!BatchGetString (textline, sizeof (textline) / sizeof (textline[0]) - 1)) - { - TRACE ("ReadBatchLine(): Reached EOF!\n"); - /* End of file.... */ - ExitBatch(); - return NULL; - } + if (!BatchGetString (textline, sizeof (textline) / sizeof (textline[0]) - 1)) + { + TRACE ("ReadBatchLine(): Reached EOF!\n"); + /* End of file.... */ + ExitBatch(); + return NULL; + } - TRACE ("ReadBatchLine(): textline: \'%s\'\n", debugstr_aw(textline)); + TRACE ("ReadBatchLine(): textline: \'%s\'\n", debugstr_aw(textline)); - if (textline[_tcslen(textline) - 1] != _T('\n')) - _tcscat(textline, _T("\n")); + if (textline[_tcslen(textline) - 1] != _T('\n')) + _tcscat(textline, _T("\n")); - return textline; + return textline; } /* EOF */ diff --git a/base/shell/cmd/batch.h b/base/shell/cmd/batch.h index ae44e67e6a2..53d1903f4d4 100644 --- a/base/shell/cmd/batch.h +++ b/base/shell/cmd/batch.h @@ -1,38 +1,37 @@ /* * BATCH.H - A structure to preserve the context of a batch file - * - * */ #pragma once typedef struct tagBATCHCONTEXT { - struct tagBATCHCONTEXT *prev; - char *mem; /* batchfile content in memory */ - DWORD memsize; /* size of batchfile */ - DWORD mempos; /* current position to read from */ - BOOL memfree; /* true if it need to be freed when exitbatch is called */ - TCHAR BatchFilePath[MAX_PATH]; - LPTSTR params; - LPTSTR raw_params; /* Holds the raw params given by the input */ - INT shiftlevel[10]; - BOOL bEcho; /* Preserve echo flag across batch calls */ - REDIRECTION *RedirList; - PARSED_COMMAND *current; - struct _SETLOCAL *setlocal; + struct tagBATCHCONTEXT *prev; + char *mem; /* batchfile content in memory */ + DWORD memsize; /* size of batchfile */ + DWORD mempos; /* current position to read from */ + BOOL memfree; /* true if it need to be freed when exitbatch is called */ + TCHAR BatchFilePath[MAX_PATH]; + LPTSTR params; + LPTSTR raw_params; /* Holds the raw params given by the input */ + INT shiftlevel[10]; + BOOL bEcho; /* Preserve echo flag across batch calls */ + REDIRECTION *RedirList; + PARSED_COMMAND *current; + struct _SETLOCAL *setlocal; } BATCH_CONTEXT, *LPBATCH_CONTEXT; typedef struct tagFORCONTEXT { - struct tagFORCONTEXT *prev; - TCHAR firstvar; - UINT varcount; - LPTSTR *values; + struct tagFORCONTEXT *prev; + TCHAR firstvar; + UINT varcount; + LPTSTR *values; } FOR_CONTEXT, *LPFOR_CONTEXT; -/* The stack of current batch contexts. +/* + * The stack of current batch contexts. * NULL when no batch is active */ extern LPBATCH_CONTEXT bc; diff --git a/base/shell/cmd/beep.c b/base/shell/cmd/beep.c index 30a786b511e..2506be1c221 100644 --- a/base/shell/cmd/beep.c +++ b/base/shell/cmd/beep.c @@ -20,8 +20,8 @@ * 20-Jan-1999 (Eric Kohl) * Redirection ready! * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -31,19 +31,19 @@ INT cmd_beep (LPTSTR param) { - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE,STRING_BEEP_HELP); - return 0; - } + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE,STRING_BEEP_HELP); + return 0; + } #if 0 - /* check if run in batch mode */ - if (bc == NULL) - return 1; + /* check if run in batch mode */ + if (bc == NULL) + return 1; #endif - MessageBeep (-1); + MessageBeep (-1); - return 0; + return 0; } #endif diff --git a/base/shell/cmd/call.c b/base/shell/cmd/call.c index f729c79fde8..5eb9639ef12 100644 --- a/base/shell/cmd/call.c +++ b/base/shell/cmd/call.c @@ -24,8 +24,8 @@ * 20-Jan-1999 (Eric Kohl) * Unicode and redirection safe! * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -36,48 +36,48 @@ INT cmd_call (LPTSTR param) { - TCHAR line[CMDLINE_LENGTH + 1]; - TCHAR *first; - BOOL bInQuote = FALSE; + TCHAR line[CMDLINE_LENGTH + 1]; + TCHAR *first; + BOOL bInQuote = FALSE; - TRACE ("cmd_call: (\'%s\')\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_CALL_HELP); - return 0; - } + TRACE ("cmd_call: (\'%s\')\n", debugstr_aw(param)); + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_CALL_HELP); + return 0; + } - /* Do a second round of %-variable substitutions */ - if (!SubstituteVars(param, line, _T('%'))) - return nErrorLevel = 1; + /* Do a second round of %-variable substitutions */ + if (!SubstituteVars(param, line, _T('%'))) + return nErrorLevel = 1; - /* Find start and end of first word */ - first = line; - while (_istspace(*first)) - first++; + /* Find start and end of first word */ + first = line; + while (_istspace(*first)) + first++; - for (param = first; *param; param++) - { - if (!bInQuote && (_istspace(*param) || _tcschr(_T(",;="), *param))) - break; - bInQuote ^= (*param == _T('"')); - } + for (param = first; *param; param++) + { + if (!bInQuote && (_istspace(*param) || _tcschr(_T(",;="), *param))) + break; + bInQuote ^= (*param == _T('"')); + } - /* Separate first word from rest of line */ - memmove(param + 1, param, (_tcslen(param) + 1) * sizeof(TCHAR)); - *param++ = _T('\0'); + /* Separate first word from rest of line */ + memmove(param + 1, param, (_tcslen(param) + 1) * sizeof(TCHAR)); + *param++ = _T('\0'); - if (*first == _T(':') && (bc)) - { - /* CALL :label - call a subroutine of the current batch file */ - while (*param == _T(' ')) - param++; - nErrorLevel = Batch(bc->BatchFilePath, first, param, NULL); - return nErrorLevel; - } + if (*first == _T(':') && (bc)) + { + /* CALL :label - call a subroutine of the current batch file */ + while (*param == _T(' ')) + param++; + nErrorLevel = Batch(bc->BatchFilePath, first, param, NULL); + return nErrorLevel; + } - nErrorLevel = DoCommand(first, param, NULL); - return nErrorLevel; + nErrorLevel = DoCommand(first, param, NULL); + return nErrorLevel; } /* EOF */ diff --git a/base/shell/cmd/chcp.c b/base/shell/cmd/chcp.c index ac012f56318..3db6d369ad4 100644 --- a/base/shell/cmd/chcp.c +++ b/base/shell/cmd/chcp.c @@ -7,8 +7,8 @@ * 23-Dec-1998 (Eric Kohl) * Started. * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -17,64 +17,63 @@ INT CommandChcp (LPTSTR param) { - LPTSTR *arg; - INT args; - UINT uNewCodePage; + LPTSTR *arg; + INT args; + UINT uNewCodePage; - /* print help */ - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_CHCP_HELP); - return 0; - } + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_CHCP_HELP); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - /* get parameters */ - arg = split (param, &args, FALSE, FALSE); + /* get parameters */ + arg = split (param, &args, FALSE, FALSE); - if (args == 0) - { - /* display active code page number */ - ConErrResPrintf(STRING_CHCP_ERROR1, InputCodePage); - freep (arg); - return 0; - } + if (args == 0) + { + /* display active code page number */ + ConErrResPrintf(STRING_CHCP_ERROR1, InputCodePage); + freep (arg); + return 0; + } - if (args >= 2) - { - /* too many parameters */ - ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, param); - nErrorLevel = 1; - freep (arg); - return 1; - } + if (args >= 2) + { + /* too many parameters */ + ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, param); + nErrorLevel = 1; + freep (arg); + return 1; + } - uNewCodePage = (UINT)_ttoi(arg[0]); + uNewCodePage = (UINT)_ttoi(arg[0]); - if (uNewCodePage == 0) - { - ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, arg[0]); - freep (arg); - nErrorLevel = 1; - return 1; - } + if (uNewCodePage == 0) + { + ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, arg[0]); + freep (arg); + nErrorLevel = 1; + return 1; + } - if (!SetConsoleCP(uNewCodePage)) - { - ConErrResPuts(STRING_CHCP_ERROR4); - } - else - { + if (!SetConsoleCP(uNewCodePage)) + { + ConErrResPuts(STRING_CHCP_ERROR4); + } + else + { - SetConsoleOutputCP (uNewCodePage); - InitLocale (); - InputCodePage= GetConsoleCP(); - } + SetConsoleOutputCP (uNewCodePage); + InitLocale (); + InputCodePage= GetConsoleCP(); + } - freep (arg); - - return 0; + freep (arg); + return 0; } #endif /* INCLUDE_CMD_CHCP */ diff --git a/base/shell/cmd/choice.c b/base/shell/cmd/choice.c index 4fec759d91a..1cfaa5641e4 100644 --- a/base/shell/cmd/choice.c +++ b/base/shell/cmd/choice.c @@ -13,9 +13,8 @@ * 26 Sep 1999 (Paolo Pantaleo) * Fixed timeout. * - * 02 Apr 2005 (Magnus Olsen - * Remove Hardcode string so - * they can be translate + * 02 Apr 2005 (Magnus Olsen) + * Remove hardcoded strings so that they can be translated. * */ @@ -24,9 +23,9 @@ #ifdef INCLUDE_CMD_CHOICE -#define GC_TIMEOUT -1 -#define GC_NOKEY 0 //an event occurred but it wasn't a key pressed -#define GC_KEYREAD 1 //a key has been read +#define GC_TIMEOUT -1 +#define GC_NOKEY 0 //an event occurred but it wasn't a key pressed +#define GC_KEYREAD 1 //a key has been read static INT @@ -37,275 +36,275 @@ GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds) // The function will wait a limited amount // of time, then the function returns GC_TIMEOUT. // -// dwMilliseconds is the timeout value, that can -// be set to INFINITE, so the function works like -// stdio.h's getchar() +// dwMilliseconds is the timeout value, that can +// be set to INFINITE, so the function works like +// stdio.h's getchar() - HANDLE hInput; - DWORD dwRead; + HANDLE hInput; + DWORD dwRead; - INPUT_RECORD lpBuffer; + INPUT_RECORD lpBuffer; - hInput = GetStdHandle (STD_INPUT_HANDLE); + hInput = GetStdHandle (STD_INPUT_HANDLE); - //if the timeout experied return GC_TIMEOUT - if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT) - return GC_TIMEOUT; + //if the timeout experied return GC_TIMEOUT + if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT) + return GC_TIMEOUT; - //otherwise get the event - ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead); + //otherwise get the event + ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead); - //if the event is a key pressed - if ((lpBuffer.EventType == KEY_EVENT) && - (lpBuffer.Event.KeyEvent.bKeyDown == TRUE)) - { - //read the key + //if the event is a key pressed + if ((lpBuffer.EventType == KEY_EVENT) && + (lpBuffer.Event.KeyEvent.bKeyDown == TRUE)) + { + //read the key #ifdef _UNICODE - *ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar; + *ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar; #else - *ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar; + *ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar; #endif - return GC_KEYREAD; - } + return GC_KEYREAD; + } - //else return no key - return GC_NOKEY; + //else return no key + return GC_NOKEY; } static INT IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive) { - LPTCH p = lpString; - INT val = 0; + LPTCH p = lpString; + INT val = 0; - while (*p) - { - if (bCaseSensitive) - { - if (*p == cKey) - return val; - } - else - { - if (_totlower (*p) == _totlower (cKey)) - return val; - } + while (*p) + { + if (bCaseSensitive) + { + if (*p == cKey) + return val; + } + else + { + if (_totlower (*p) == _totlower (cKey)) + return val; + } - val++; - p++; - } + val++; + p++; + } - return -1; + return -1; } INT CommandChoice (LPTSTR param) { - LPTSTR lpOptions; - TCHAR Options[6]; - LPTSTR lpText = NULL; - BOOL bNoPrompt = FALSE; - BOOL bCaseSensitive = FALSE; - BOOL bTimeout = FALSE; - INT nTimeout = 0; - TCHAR cDefault = _T('\0'); - INPUT_RECORD ir; - LPTSTR p, np; - LPTSTR *arg; - INT argc; - INT i; - INT val; + LPTSTR lpOptions; + TCHAR Options[6]; + LPTSTR lpText = NULL; + BOOL bNoPrompt = FALSE; + BOOL bCaseSensitive = FALSE; + BOOL bTimeout = FALSE; + INT nTimeout = 0; + TCHAR cDefault = _T('\0'); + INPUT_RECORD ir; + LPTSTR p, np; + LPTSTR *arg; + INT argc; + INT i; + INT val; - INT GCret; - TCHAR Ch; - DWORD amount,clk; + INT GCret; + TCHAR Ch; + DWORD amount,clk; - LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, Options, 4); - lpOptions = Options; + LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, Options, 4); + lpOptions = Options; - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE,STRING_CHOICE_HELP); - return 0; - } + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE,STRING_CHOICE_HELP); + return 0; + } - /* retrieve text */ - p = param; + /* retrieve text */ + p = param; - while (TRUE) - { - if (*p == _T('\0')) - break; + while (TRUE) + { + if (*p == _T('\0')) + break; - if (*p != _T('/')) - { - lpText = p; - break; - } - np = _tcschr (p, _T(' ')); - if (!np) - break; - p = np + 1; - } + if (*p != _T('/')) + { + lpText = p; + break; + } + np = _tcschr (p, _T(' ')); + if (!np) + break; + p = np + 1; + } - /* build parameter array */ - arg = split (param, &argc, FALSE, FALSE); + /* build parameter array */ + arg = split (param, &argc, FALSE, FALSE); - /* evaluate arguments */ - if (argc > 0) - { - for (i = 0; i < argc; i++) - { - if (_tcsnicmp (arg[i], _T("/c"), 2) == 0) - { - if (arg[i][2] == _T(':')) - lpOptions = &arg[i][3]; - else - lpOptions = &arg[i][2]; + /* evaluate arguments */ + if (argc > 0) + { + for (i = 0; i < argc; i++) + { + if (_tcsnicmp (arg[i], _T("/c"), 2) == 0) + { + if (arg[i][2] == _T(':')) + lpOptions = &arg[i][3]; + else + lpOptions = &arg[i][2]; - if (_tcslen (lpOptions) == 0) - { - ConErrResPuts(STRING_CHOICE_ERROR); - freep (arg); - return 1; - } - } - else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0) - { - bNoPrompt = TRUE; - } - else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0) - { - bCaseSensitive = TRUE; - } - else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0) - { - LPTSTR s; + if (_tcslen (lpOptions) == 0) + { + ConErrResPuts(STRING_CHOICE_ERROR); + freep (arg); + return 1; + } + } + else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0) + { + bNoPrompt = TRUE; + } + else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0) + { + bCaseSensitive = TRUE; + } + else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0) + { + LPTSTR s; - if (arg[i][2] == _T(':')) - { - cDefault = arg[i][3]; - s = &arg[i][4]; - } - else - { - cDefault = arg[i][2]; - s = &arg[i][3]; - } + if (arg[i][2] == _T(':')) + { + cDefault = arg[i][3]; + s = &arg[i][4]; + } + else + { + cDefault = arg[i][2]; + s = &arg[i][3]; + } - if (*s != _T(',')) - { - ConErrResPuts(STRING_CHOICE_ERROR_TXT); - freep (arg); - return 1; - } + if (*s != _T(',')) + { + ConErrResPuts(STRING_CHOICE_ERROR_TXT); + freep (arg); + return 1; + } - s++; - nTimeout = _ttoi(s); - bTimeout = TRUE; - } - else if (arg[i][0] == _T('/')) - { - ConErrResPrintf(STRING_CHOICE_ERROR_OPTION, arg[i]); - freep (arg); - return 1; - } - } - } + s++; + nTimeout = _ttoi(s); + bTimeout = TRUE; + } + else if (arg[i][0] == _T('/')) + { + ConErrResPrintf(STRING_CHOICE_ERROR_OPTION, arg[i]); + freep (arg); + return 1; + } + } + } - /* print text */ - if (lpText) - ConOutPrintf (_T("%s"), lpText); + /* print text */ + if (lpText) + ConOutPrintf (_T("%s"), lpText); - /* print options */ - if (bNoPrompt == FALSE) - { - ConOutPrintf (_T("[%c"), lpOptions[0]); + /* print options */ + if (bNoPrompt == FALSE) + { + ConOutPrintf (_T("[%c"), lpOptions[0]); - for (i = 1; (unsigned)i < _tcslen (lpOptions); i++) - ConOutPrintf (_T(",%c"), lpOptions[i]); + for (i = 1; (unsigned)i < _tcslen (lpOptions); i++) + ConOutPrintf (_T(",%c"), lpOptions[i]); - ConOutPrintf (_T("]?")); - } + ConOutPrintf (_T("]?")); + } - ConInFlush (); + ConInFlush (); - if(!bTimeout) - { - while (TRUE) - { - ConInKey (&ir); + if (!bTimeout) + { + while (TRUE) + { + ConInKey (&ir); - val = IsKeyInString (lpOptions, + val = IsKeyInString (lpOptions, #ifdef _UNICODE - ir.Event.KeyEvent.uChar.UnicodeChar, + ir.Event.KeyEvent.uChar.UnicodeChar, #else - ir.Event.KeyEvent.uChar.AsciiChar, + ir.Event.KeyEvent.uChar.AsciiChar, #endif - bCaseSensitive); + bCaseSensitive); - if (val >= 0) - { - ConOutPrintf (_T("%c\n"), lpOptions[val]); + if (val >= 0) + { + ConOutPrintf (_T("%c\n"), lpOptions[val]); - nErrorLevel = val + 1; + nErrorLevel = val + 1; - break; - } + break; + } - Beep (440, 50); - } + Beep (440, 50); + } - freep (arg); - TRACE ("ErrorLevel: %d\n", nErrorLevel); - return 0; - } + freep (arg); + TRACE ("ErrorLevel: %d\n", nErrorLevel); + return 0; + } - clk = GetTickCount (); - amount = nTimeout*1000; + clk = GetTickCount (); + amount = nTimeout*1000; loop: - GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk)); + GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk)); - switch (GCret) - { - case GC_TIMEOUT: - TRACE ("GC_TIMEOUT\n"); - TRACE ("elapsed %d msecs\n", GetTickCount () - clk); - break; + switch (GCret) + { + case GC_TIMEOUT: + TRACE ("GC_TIMEOUT\n"); + TRACE ("elapsed %d msecs\n", GetTickCount () - clk); + break; - case GC_NOKEY: - TRACE ("GC_NOKEY\n"); - TRACE ("elapsed %d msecs\n", GetTickCount () - clk); - goto loop; + case GC_NOKEY: + TRACE ("GC_NOKEY\n"); + TRACE ("elapsed %d msecs\n", GetTickCount () - clk); + goto loop; - case GC_KEYREAD: - TRACE ("GC_KEYREAD\n"); - TRACE ("elapsed %d msecs\n", GetTickCount () - clk); - TRACE ("read %c", Ch); - if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1) - { - Beep (440, 50); - goto loop; - } - cDefault=Ch; - break; - } + case GC_KEYREAD: + TRACE ("GC_KEYREAD\n"); + TRACE ("elapsed %d msecs\n", GetTickCount () - clk); + TRACE ("read %c", Ch); + if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1) + { + Beep (440, 50); + goto loop; + } + cDefault=Ch; + break; + } - TRACE ("exiting wait loop after %d msecs\n", - GetTickCount () - clk); + TRACE ("exiting wait loop after %d msecs\n", + GetTickCount () - clk); - val = IsKeyInString (lpOptions, cDefault, bCaseSensitive); - ConOutPrintf (_T("%c\n"), lpOptions[val]); + val = IsKeyInString (lpOptions, cDefault, bCaseSensitive); + ConOutPrintf(_T("%c\n"), lpOptions[val]); - nErrorLevel = val + 1; + nErrorLevel = val + 1; - freep (arg); + freep (arg); - TRACE ("ErrorLevel: %d\n", nErrorLevel); + TRACE ("ErrorLevel: %d\n", nErrorLevel); - return 0; + return 0; } #endif /* INCLUDE_CMD_CHOICE */ diff --git a/base/shell/cmd/cls.c b/base/shell/cmd/cls.c index 8814b5dfbbc..5cf6aa02bb0 100644 --- a/base/shell/cmd/cls.c +++ b/base/shell/cmd/cls.c @@ -22,8 +22,8 @@ * 20-Jan-1998 (Eric Kohl) * Redirection ready! * - * 02-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 02-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -32,34 +32,34 @@ INT cmd_cls (LPTSTR param) { - HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csbi; - COORD coPos; - DWORD dwWritten; + HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD coPos; + DWORD dwWritten; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_CLS_HELP); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_CLS_HELP); + return 0; + } - if (GetConsoleScreenBufferInfo(hOutput, &csbi)) - { - coPos.X = 0; - coPos.Y = 0; - FillConsoleOutputAttribute(hOutput, csbi.wAttributes, - csbi.dwSize.X * csbi.dwSize.Y, - coPos, &dwWritten); - FillConsoleOutputCharacter(hOutput, _T(' '), - csbi.dwSize.X * csbi.dwSize.Y, - coPos, &dwWritten); - SetConsoleCursorPosition(hOutput, coPos); - } - else - { - ConOutChar(_T('\f')); - } + if (GetConsoleScreenBufferInfo(hOutput, &csbi)) + { + coPos.X = 0; + coPos.Y = 0; + FillConsoleOutputAttribute(hOutput, csbi.wAttributes, + csbi.dwSize.X * csbi.dwSize.Y, + coPos, &dwWritten); + FillConsoleOutputCharacter(hOutput, _T(' '), + csbi.dwSize.X * csbi.dwSize.Y, + coPos, &dwWritten); + SetConsoleCursorPosition(hOutput, coPos); + } + else + { + ConOutChar(_T('\f')); + } - return 0; + return 0; } #endif diff --git a/base/shell/cmd/cmd.c b/base/shell/cmd/cmd.c index ae0f7c3dc52..2a56ed93c55 100644 --- a/base/shell/cmd/cmd.c +++ b/base/shell/cmd/cmd.c @@ -184,34 +184,34 @@ WORD wDefColor; /* default color */ INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator) { - TCHAR temp[39]; /* maximum length with nNumberGroups == 1 */ - UINT n, iTarget; + TCHAR temp[39]; /* maximum length with nNumberGroups == 1 */ + UINT n, iTarget; - if (len <= 1) - return 0; + if (len <= 1) + return 0; - n = 0; - iTarget = nNumberGroups; - if (!nNumberGroups) - bPutSeperator = FALSE; + n = 0; + iTarget = nNumberGroups; + if (!nNumberGroups) + bPutSeperator = FALSE; - do - { - if (iTarget == n && bPutSeperator) - { - iTarget += nNumberGroups + 1; - temp[38 - n++] = cThousandSeparator; - } - temp[38 - n++] = (TCHAR)(num % 10) + _T('0'); - num /= 10; - } while (num > 0); - if (n > len-1) - n = len-1; + do + { + if (iTarget == n && bPutSeperator) + { + iTarget += nNumberGroups + 1; + temp[38 - n++] = cThousandSeparator; + } + temp[38 - n++] = (TCHAR)(num % 10) + _T('0'); + num /= 10; + } while (num > 0); + if (n > len-1) + n = len-1; - memcpy(des, temp + 39 - n, n * sizeof(TCHAR)); - des[n] = _T('\0'); + memcpy(des, temp + 39 - n, n * sizeof(TCHAR)); + des[n] = _T('\0'); - return n; + return n; } /* @@ -219,42 +219,42 @@ ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator) */ static BOOL IsConsoleProcess(HANDLE Process) { - NTSTATUS Status; - PROCESS_BASIC_INFORMATION Info; - PEB ProcessPeb; - ULONG BytesRead; + NTSTATUS Status; + PROCESS_BASIC_INFORMATION Info; + PEB ProcessPeb; + ULONG BytesRead; - if (NULL == NtQueryInformationProcessPtr || NULL == NtReadVirtualMemoryPtr) - { - return TRUE; - } + if (NULL == NtQueryInformationProcessPtr || NULL == NtReadVirtualMemoryPtr) + { + return TRUE; + } - Status = NtQueryInformationProcessPtr ( - Process, ProcessBasicInformation, - &Info, sizeof(PROCESS_BASIC_INFORMATION), NULL); - if (! NT_SUCCESS(Status)) - { - WARN ("NtQueryInformationProcess failed with status %08x\n", Status); - return TRUE; - } - Status = NtReadVirtualMemoryPtr ( - Process, Info.PebBaseAddress, &ProcessPeb, - sizeof(PEB), &BytesRead); - if (! NT_SUCCESS(Status) || sizeof(PEB) != BytesRead) - { - WARN ("Couldn't read virt mem status %08x bytes read %lu\n", Status, BytesRead); - return TRUE; - } + Status = NtQueryInformationProcessPtr ( + Process, ProcessBasicInformation, + &Info, sizeof(PROCESS_BASIC_INFORMATION), NULL); + if (! NT_SUCCESS(Status)) + { + WARN ("NtQueryInformationProcess failed with status %08x\n", Status); + return TRUE; + } + Status = NtReadVirtualMemoryPtr ( + Process, Info.PebBaseAddress, &ProcessPeb, + sizeof(PEB), &BytesRead); + if (! NT_SUCCESS(Status) || sizeof(PEB) != BytesRead) + { + WARN ("Couldn't read virt mem status %08x bytes read %lu\n", Status, BytesRead); + return TRUE; + } - return IMAGE_SUBSYSTEM_WINDOWS_CUI == ProcessPeb.ImageSubsystem; + return IMAGE_SUBSYSTEM_WINDOWS_CUI == ProcessPeb.ImageSubsystem; } #ifdef _UNICODE -#define SHELLEXECUTETEXT "ShellExecuteExW" +#define SHELLEXECUTETEXT "ShellExecuteExW" #else -#define SHELLEXECUTETEXT "ShellExecuteExA" +#define SHELLEXECUTETEXT "ShellExecuteExA" #endif typedef BOOL (WINAPI *MYEX)(LPSHELLEXECUTEINFO lpExecInfo); @@ -262,42 +262,42 @@ typedef BOOL (WINAPI *MYEX)(LPSHELLEXECUTEINFO lpExecInfo); HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params, LPTSTR directory, INT show) { - SHELLEXECUTEINFO sei; - HMODULE hShell32; - MYEX hShExt; - BOOL ret; + SHELLEXECUTEINFO sei; + HMODULE hShell32; + MYEX hShExt; + BOOL ret; - TRACE ("RunFile(%s)\n", debugstr_aw(filename)); - hShell32 = LoadLibrary(_T("SHELL32.DLL")); - if (!hShell32) - { - WARN ("RunFile: couldn't load SHELL32.DLL!\n"); - return NULL; - } + TRACE ("RunFile(%s)\n", debugstr_aw(filename)); + hShell32 = LoadLibrary(_T("SHELL32.DLL")); + if (!hShell32) + { + WARN ("RunFile: couldn't load SHELL32.DLL!\n"); + return NULL; + } - hShExt = (MYEX)(FARPROC)GetProcAddress(hShell32, SHELLEXECUTETEXT); - if (!hShExt) - { - WARN ("RunFile: couldn't find ShellExecuteExA/W in SHELL32.DLL!\n"); - FreeLibrary(hShell32); - return NULL; - } + hShExt = (MYEX)(FARPROC)GetProcAddress(hShell32, SHELLEXECUTETEXT); + if (!hShExt) + { + WARN ("RunFile: couldn't find ShellExecuteExA/W in SHELL32.DLL!\n"); + FreeLibrary(hShell32); + return NULL; + } - TRACE ("RunFile: ShellExecuteExA/W is at %x\n", hShExt); + TRACE ("RunFile: ShellExecuteExA/W is at %x\n", hShExt); - memset(&sei, 0, sizeof sei); - sei.cbSize = sizeof sei; - sei.fMask = flags; - sei.lpFile = filename; - sei.lpParameters = params; - sei.lpDirectory = directory; - sei.nShow = show; - ret = hShExt(&sei); + memset(&sei, 0, sizeof sei); + sei.cbSize = sizeof sei; + sei.fMask = flags; + sei.lpFile = filename; + sei.lpParameters = params; + sei.lpDirectory = directory; + sei.nShow = show; + ret = hShExt(&sei); - TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret); + TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret); - FreeLibrary(hShell32); - return ret ? sei.hProcess : NULL; + FreeLibrary(hShell32); + return ret ? sei.hProcess : NULL; } @@ -309,175 +309,174 @@ HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params, * First - first word on command line * Rest - rest of command line */ - static INT -Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) +Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) { - TCHAR szFullName[MAX_PATH]; - TCHAR *first, *rest, *dot; - TCHAR szWindowTitle[MAX_PATH]; - DWORD dwExitCode = 0; - TCHAR *FirstEnd; - TCHAR szFullCmdLine [CMDLINE_LENGTH]; + TCHAR szFullName[MAX_PATH]; + TCHAR *first, *rest, *dot; + TCHAR szWindowTitle[MAX_PATH]; + DWORD dwExitCode = 0; + TCHAR *FirstEnd; + TCHAR szFullCmdLine [CMDLINE_LENGTH]; - TRACE ("Execute: \'%s\' \'%s\'\n", debugstr_aw(First), debugstr_aw(Rest)); + TRACE ("Execute: \'%s\' \'%s\'\n", debugstr_aw(First), debugstr_aw(Rest)); - /* Though it was already parsed once, we have a different set of rules - for parsing before we pass to CreateProccess */ - if (First[0] == _T('/') || (First[0] && First[1] == _T(':'))) - { - /* Use the entire first word as the program name (no change) */ - FirstEnd = First + _tcslen(First); - } - else - { - /* If present in the first word, spaces and ,;=/ end the program - * name and become the beginning of its parameters. */ - BOOL bInside = FALSE; - for (FirstEnd = First; *FirstEnd; FirstEnd++) - { - if (!bInside && (_istspace(*FirstEnd) || _tcschr(_T(",;=/"), *FirstEnd))) - break; - bInside ^= *FirstEnd == _T('"'); - } - } + /* Though it was already parsed once, we have a different set of rules + for parsing before we pass to CreateProccess */ + if (First[0] == _T('/') || (First[0] && First[1] == _T(':'))) + { + /* Use the entire first word as the program name (no change) */ + FirstEnd = First + _tcslen(First); + } + else + { + /* If present in the first word, spaces and ,;=/ end the program + * name and become the beginning of its parameters. */ + BOOL bInside = FALSE; + for (FirstEnd = First; *FirstEnd; FirstEnd++) + { + if (!bInside && (_istspace(*FirstEnd) || _tcschr(_T(",;=/"), *FirstEnd))) + break; + bInside ^= *FirstEnd == _T('"'); + } + } - /* Copy the new first/rest into the buffer */ - first = Full; - rest = &Full[FirstEnd - First + 1]; - _tcscpy(rest, FirstEnd); - _tcscat(rest, Rest); - *FirstEnd = _T('\0'); - _tcscpy(first, First); + /* Copy the new first/rest into the buffer */ + first = Full; + rest = &Full[FirstEnd - First + 1]; + _tcscpy(rest, FirstEnd); + _tcscat(rest, Rest); + *FirstEnd = _T('\0'); + _tcscpy(first, First); - /* check for a drive change */ - if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":")))) - { - BOOL working = TRUE; - if (!SetCurrentDirectory(first)) - /* Guess they changed disc or something, handle that gracefully and get to root */ - { - TCHAR str[4]; - str[0]=first[0]; - str[1]=_T(':'); - str[2]=_T('\\'); - str[3]=0; - working = SetCurrentDirectory(str); - } + /* check for a drive change */ + if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":")))) + { + BOOL working = TRUE; + if (!SetCurrentDirectory(first)) + /* Guess they changed disc or something, handle that gracefully and get to root */ + { + TCHAR str[4]; + str[0]=first[0]; + str[1]=_T(':'); + str[2]=_T('\\'); + str[3]=0; + working = SetCurrentDirectory(str); + } - if (!working) ConErrResPuts (STRING_FREE_ERROR1); - return !working; - } + if (!working) ConErrResPuts (STRING_FREE_ERROR1); + return !working; + } - /* get the PATH environment variable and parse it */ - /* search the PATH environment variable for the binary */ - StripQuotes(First); - if (!SearchForExecutable(First, szFullName)) - { - error_bad_command(first); - return 1; - } + /* get the PATH environment variable and parse it */ + /* search the PATH environment variable for the binary */ + StripQuotes(First); + if (!SearchForExecutable(First, szFullName)) + { + error_bad_command(first); + return 1; + } - GetConsoleTitle (szWindowTitle, MAX_PATH); + GetConsoleTitle (szWindowTitle, MAX_PATH); - /* check if this is a .BAT or .CMD file */ - dot = _tcsrchr (szFullName, _T('.')); - if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd")))) - { - while (*rest == _T(' ')) - rest++; - TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest)); - dwExitCode = Batch(szFullName, first, rest, Cmd); - } - else - { - /* exec the program */ - PROCESS_INFORMATION prci; - STARTUPINFO stui; + /* check if this is a .BAT or .CMD file */ + dot = _tcsrchr (szFullName, _T('.')); + if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd")))) + { + while (*rest == _T(' ')) + rest++; + TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest)); + dwExitCode = Batch(szFullName, first, rest, Cmd); + } + else + { + /* exec the program */ + PROCESS_INFORMATION prci; + STARTUPINFO stui; - /* build command line for CreateProcess(): FullName + " " + rest */ + /* build command line for CreateProcess(): FullName + " " + rest */ BOOL quoted = !!_tcschr(First, ' '); - _tcscpy(szFullCmdLine, quoted ? _T("\"") : _T("")); - _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + _tcscpy(szFullCmdLine, quoted ? _T("\"") : _T("")); + _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - if (*rest) - { - _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - } + if (*rest) + { + _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + } - TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine)); + TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine)); - /* fill startup info */ - memset (&stui, 0, sizeof (STARTUPINFO)); - stui.cb = sizeof (STARTUPINFO); - stui.dwFlags = STARTF_USESHOWWINDOW; - stui.wShowWindow = SW_SHOWDEFAULT; + /* fill startup info */ + memset (&stui, 0, sizeof (STARTUPINFO)); + stui.cb = sizeof (STARTUPINFO); + stui.dwFlags = STARTF_USESHOWWINDOW; + stui.wShowWindow = SW_SHOWDEFAULT; - // return console to standard mode - SetConsoleMode (GetStdHandle(STD_INPUT_HANDLE), - ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT ); + /* Set the console to standard mode */ + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), + ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); - if (CreateProcess (szFullName, - szFullCmdLine, - NULL, - NULL, - TRUE, - 0, /* CREATE_NEW_PROCESS_GROUP */ - NULL, - NULL, - &stui, - &prci)) + if (CreateProcess(szFullName, + szFullCmdLine, + NULL, + NULL, + TRUE, + 0, /* CREATE_NEW_PROCESS_GROUP */ + NULL, + NULL, + &stui, + &prci)) + { + CloseHandle(prci.hThread); + } + else + { + // See if we can run this with ShellExecute() ie myfile.xls + prci.hProcess = RunFile(SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE, + szFullName, + rest, + NULL, + SW_SHOWNORMAL); + } - { - CloseHandle(prci.hThread); - } - else - { - // See if we can run this with ShellExecute() ie myfile.xls - prci.hProcess = RunFile(SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE, - szFullName, - rest, - NULL, - SW_SHOWNORMAL); - } + if (prci.hProcess != NULL) + { + if (IsConsoleProcess(prci.hProcess)) + { + EnterCriticalSection(&ChildProcessRunningLock); + dwChildProcessId = prci.dwProcessId; - if (prci.hProcess != NULL) - { - if (IsConsoleProcess(prci.hProcess)) - { - EnterCriticalSection(&ChildProcessRunningLock); - dwChildProcessId = prci.dwProcessId; + WaitForSingleObject(prci.hProcess, INFINITE); - WaitForSingleObject (prci.hProcess, INFINITE); + LeaveCriticalSection(&ChildProcessRunningLock); - LeaveCriticalSection(&ChildProcessRunningLock); + GetExitCodeProcess(prci.hProcess, &dwExitCode); + nErrorLevel = (INT)dwExitCode; + } + CloseHandle(prci.hProcess); + } + else + { + TRACE ("[ShellExecute failed!: %s]\n", debugstr_aw(Full)); + error_bad_command(first); + dwExitCode = 1; + } - GetExitCodeProcess (prci.hProcess, &dwExitCode); - nErrorLevel = (INT)dwExitCode; - } - CloseHandle (prci.hProcess); - } - else - { - TRACE ("[ShellExecute failed!: %s]\n", debugstr_aw(Full)); - error_bad_command (first); - dwExitCode = 1; - } + /* Restore our default console mode */ + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), + ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); + SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), + ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); + } - // restore console mode - SetConsoleMode ( - GetStdHandle( STD_INPUT_HANDLE ), - ENABLE_PROCESSED_INPUT ); - } + /* Get code page if it has been changed */ + InputCodePage= GetConsoleCP(); + OutputCodePage = GetConsoleOutputCP(); + SetConsoleTitle(szWindowTitle); - /* Get code page if it has been change */ - InputCodePage= GetConsoleCP(); - OutputCodePage = GetConsoleOutputCP(); - SetConsoleTitle (szWindowTitle); - - return dwExitCode; + return dwExitCode; } @@ -489,70 +488,69 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) * first - first word on command line * rest - rest of command line */ - INT DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd) { - TCHAR *com; - TCHAR *cp; - LPTSTR param; /* pointer to command's parameters */ - INT cl; - LPCOMMAND cmdptr; - BOOL nointernal = FALSE; - INT ret; + TCHAR *com; + TCHAR *cp; + LPTSTR param; /* pointer to command's parameters */ + INT cl; + LPCOMMAND cmdptr; + BOOL nointernal = FALSE; + INT ret; - TRACE ("DoCommand: (\'%s\' \'%s\')\n", debugstr_aw(first), debugstr_aw(rest)); + TRACE ("DoCommand: (\'%s\' \'%s\')\n", debugstr_aw(first), debugstr_aw(rest)); - /* full command line */ - com = cmd_alloc((_tcslen(first) + _tcslen(rest) + 2) * sizeof(TCHAR)); - if (com == NULL) - { - error_out_of_memory(); - return 1; - } + /* full command line */ + com = cmd_alloc((_tcslen(first) + _tcslen(rest) + 2) * sizeof(TCHAR)); + if (com == NULL) + { + error_out_of_memory(); + return 1; + } - /* If present in the first word, these characters end the name of an - * internal command and become the beginning of its parameters. */ - cp = first + _tcscspn(first, _T("\t +,/;=[]")); + /* If present in the first word, these characters end the name of an + * internal command and become the beginning of its parameters. */ + cp = first + _tcscspn(first, _T("\t +,/;=[]")); - for (cl = 0; cl < (cp - first); cl++) - { - /* These characters do it too, but if one of them is present, - * then we check to see if the word is a file name and skip - * checking for internal commands if so. - * This allows running programs with names like "echo.exe" */ - if (_tcschr(_T(".:\\"), first[cl])) - { - TCHAR tmp = *cp; - *cp = _T('\0'); - nointernal = IsExistingFile(first); - *cp = tmp; - break; - } - } + for (cl = 0; cl < (cp - first); cl++) + { + /* These characters do it too, but if one of them is present, + * then we check to see if the word is a file name and skip + * checking for internal commands if so. + * This allows running programs with names like "echo.exe" */ + if (_tcschr(_T(".:\\"), first[cl])) + { + TCHAR tmp = *cp; + *cp = _T('\0'); + nointernal = IsExistingFile(first); + *cp = tmp; + break; + } + } - /* Scan internal command table */ - for (cmdptr = cmds; !nointernal && cmdptr->name; cmdptr++) - { - if (!_tcsnicmp(first, cmdptr->name, cl) && cmdptr->name[cl] == _T('\0')) - { - _tcscpy(com, first); - _tcscat(com, rest); - param = &com[cl]; + /* Scan internal command table */ + for (cmdptr = cmds; !nointernal && cmdptr->name; cmdptr++) + { + if (!_tcsnicmp(first, cmdptr->name, cl) && cmdptr->name[cl] == _T('\0')) + { + _tcscpy(com, first); + _tcscat(com, rest); + param = &com[cl]; - /* Skip over whitespace to rest of line, exclude 'echo' command */ - if (_tcsicmp(cmdptr->name, _T("echo")) != 0) - while (_istspace(*param)) - param++; - ret = cmdptr->func(param); - cmd_free(com); - return ret; - } - } + /* Skip over whitespace to rest of line, exclude 'echo' command */ + if (_tcsicmp(cmdptr->name, _T("echo")) != 0) + while (_istspace(*param)) + param++; + ret = cmdptr->func(param); + cmd_free(com); + return ret; + } + } - ret = Execute(com, first, rest, Cmd); - cmd_free(com); - return ret; + ret = Execute(com, first, rest, Cmd); + cmd_free(com); + return ret; } @@ -560,17 +558,16 @@ DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd) * process the command line and execute the appropriate functions * full input/output redirection and piping are supported */ - INT ParseCommandLine (LPTSTR cmd) { - INT Ret = 0; - PARSED_COMMAND *Cmd = ParseCommand(cmd); - if (Cmd) - { - Ret = ExecuteCommand(Cmd); - FreeCommand(Cmd); - } - return Ret; + INT Ret = 0; + PARSED_COMMAND *Cmd = ParseCommand(cmd); + if (Cmd) + { + Ret = ExecuteCommand(Cmd); + FreeCommand(Cmd); + } + return Ret; } /* Execute a command without waiting for it to finish. If it's an internal @@ -581,545 +578,545 @@ INT ParseCommandLine (LPTSTR cmd) static HANDLE ExecuteAsync(PARSED_COMMAND *Cmd) { - TCHAR CmdPath[MAX_PATH]; - TCHAR CmdParams[CMDLINE_LENGTH], *ParamsEnd; - STARTUPINFO stui; - PROCESS_INFORMATION prci; + TCHAR CmdPath[MAX_PATH]; + TCHAR CmdParams[CMDLINE_LENGTH], *ParamsEnd; + STARTUPINFO stui; + PROCESS_INFORMATION prci; - /* Get the path to cmd.exe */ - GetModuleFileName(NULL, CmdPath, MAX_PATH); + /* Get the path to cmd.exe */ + GetModuleFileName(NULL, CmdPath, MAX_PATH); - /* Build the parameter string to pass to cmd.exe */ - ParamsEnd = _stpcpy(CmdParams, _T("/S/D/C\"")); - ParamsEnd = Unparse(Cmd, ParamsEnd, &CmdParams[CMDLINE_LENGTH - 2]); - if (!ParamsEnd) - { - error_out_of_memory(); - return NULL; - } - _tcscpy(ParamsEnd, _T("\"")); + /* Build the parameter string to pass to cmd.exe */ + ParamsEnd = _stpcpy(CmdParams, _T("/S/D/C\"")); + ParamsEnd = Unparse(Cmd, ParamsEnd, &CmdParams[CMDLINE_LENGTH - 2]); + if (!ParamsEnd) + { + error_out_of_memory(); + return NULL; + } + _tcscpy(ParamsEnd, _T("\"")); - memset(&stui, 0, sizeof stui); - stui.cb = sizeof(STARTUPINFO); - if (!CreateProcess(CmdPath, CmdParams, NULL, NULL, TRUE, 0, - NULL, NULL, &stui, &prci)) - { - ErrorMessage(GetLastError(), NULL); - return NULL; - } + memset(&stui, 0, sizeof stui); + stui.cb = sizeof(STARTUPINFO); + if (!CreateProcess(CmdPath, CmdParams, NULL, NULL, TRUE, 0, + NULL, NULL, &stui, &prci)) + { + ErrorMessage(GetLastError(), NULL); + return NULL; + } - CloseHandle(prci.hThread); - return prci.hProcess; + CloseHandle(prci.hThread); + return prci.hProcess; } static VOID ExecutePipeline(PARSED_COMMAND *Cmd) { #ifdef FEATURE_REDIRECTION - HANDLE hInput = NULL; - HANDLE hOldConIn = GetStdHandle(STD_INPUT_HANDLE); - HANDLE hOldConOut = GetStdHandle(STD_OUTPUT_HANDLE); - HANDLE hProcess[MAXIMUM_WAIT_OBJECTS]; - INT nProcesses = 0; - DWORD dwExitCode; + HANDLE hInput = NULL; + HANDLE hOldConIn = GetStdHandle(STD_INPUT_HANDLE); + HANDLE hOldConOut = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE hProcess[MAXIMUM_WAIT_OBJECTS]; + INT nProcesses = 0; + DWORD dwExitCode; - /* Do all but the last pipe command */ - do - { - HANDLE hPipeRead, hPipeWrite; - if (nProcesses > (MAXIMUM_WAIT_OBJECTS - 2)) - { - error_too_many_parameters(_T("|")); - goto failed; - } + /* Do all but the last pipe command */ + do + { + HANDLE hPipeRead, hPipeWrite; + if (nProcesses > (MAXIMUM_WAIT_OBJECTS - 2)) + { + error_too_many_parameters(_T("|")); + goto failed; + } - /* Create the pipe that this process will write into. - * Make the handles non-inheritable initially, because this - * process shouldn't inherit the reading handle. */ - if (!CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0)) - { - error_no_pipe(); - goto failed; - } + /* Create the pipe that this process will write into. + * Make the handles non-inheritable initially, because this + * process shouldn't inherit the reading handle. */ + if (!CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0)) + { + error_no_pipe(); + goto failed; + } - /* The writing side of the pipe is STDOUT for this process */ - SetHandleInformation(hPipeWrite, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); - SetStdHandle(STD_OUTPUT_HANDLE, hPipeWrite); + /* The writing side of the pipe is STDOUT for this process */ + SetHandleInformation(hPipeWrite, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + SetStdHandle(STD_OUTPUT_HANDLE, hPipeWrite); - /* Execute it (error check is done later for easier cleanup) */ - hProcess[nProcesses] = ExecuteAsync(Cmd->Subcommands); - CloseHandle(hPipeWrite); - if (hInput) - CloseHandle(hInput); + /* Execute it (error check is done later for easier cleanup) */ + hProcess[nProcesses] = ExecuteAsync(Cmd->Subcommands); + CloseHandle(hPipeWrite); + if (hInput) + CloseHandle(hInput); - /* The reading side of the pipe will be STDIN for the next process */ - SetHandleInformation(hPipeRead, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); - SetStdHandle(STD_INPUT_HANDLE, hPipeRead); - hInput = hPipeRead; + /* The reading side of the pipe will be STDIN for the next process */ + SetHandleInformation(hPipeRead, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); + SetStdHandle(STD_INPUT_HANDLE, hPipeRead); + hInput = hPipeRead; - if (!hProcess[nProcesses]) - goto failed; - nProcesses++; + if (!hProcess[nProcesses]) + goto failed; + nProcesses++; - Cmd = Cmd->Subcommands->Next; - } while (Cmd->Type == C_PIPE); + Cmd = Cmd->Subcommands->Next; + } while (Cmd->Type == C_PIPE); - /* The last process uses the original STDOUT */ - SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut); - hProcess[nProcesses] = ExecuteAsync(Cmd); - if (!hProcess[nProcesses]) - goto failed; - nProcesses++; - CloseHandle(hInput); - SetStdHandle(STD_INPUT_HANDLE, hOldConIn); + /* The last process uses the original STDOUT */ + SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut); + hProcess[nProcesses] = ExecuteAsync(Cmd); + if (!hProcess[nProcesses]) + goto failed; + nProcesses++; + CloseHandle(hInput); + SetStdHandle(STD_INPUT_HANDLE, hOldConIn); - /* Wait for all processes to complete */ - EnterCriticalSection(&ChildProcessRunningLock); - WaitForMultipleObjects(nProcesses, hProcess, TRUE, INFINITE); - LeaveCriticalSection(&ChildProcessRunningLock); + /* Wait for all processes to complete */ + EnterCriticalSection(&ChildProcessRunningLock); + WaitForMultipleObjects(nProcesses, hProcess, TRUE, INFINITE); + LeaveCriticalSection(&ChildProcessRunningLock); - /* Use the exit code of the last process in the pipeline */ - GetExitCodeProcess(hProcess[nProcesses - 1], &dwExitCode); - nErrorLevel = (INT)dwExitCode; + /* Use the exit code of the last process in the pipeline */ + GetExitCodeProcess(hProcess[nProcesses - 1], &dwExitCode); + nErrorLevel = (INT)dwExitCode; - while (--nProcesses >= 0) - CloseHandle(hProcess[nProcesses]); - return; + while (--nProcesses >= 0) + CloseHandle(hProcess[nProcesses]); + return; failed: - if (hInput) - CloseHandle(hInput); - while (--nProcesses >= 0) - { - TerminateProcess(hProcess[nProcesses], 0); - CloseHandle(hProcess[nProcesses]); - } - SetStdHandle(STD_INPUT_HANDLE, hOldConIn); - SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut); + if (hInput) + CloseHandle(hInput); + while (--nProcesses >= 0) + { + TerminateProcess(hProcess[nProcesses], 0); + CloseHandle(hProcess[nProcesses]); + } + SetStdHandle(STD_INPUT_HANDLE, hOldConIn); + SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut); #endif } INT ExecuteCommand(PARSED_COMMAND *Cmd) { - PARSED_COMMAND *Sub; - LPTSTR First, Rest; - INT Ret = 0; + PARSED_COMMAND *Sub; + LPTSTR First, Rest; + INT Ret = 0; - if (!PerformRedirection(Cmd->Redirections)) - return 1; + if (!PerformRedirection(Cmd->Redirections)) + return 1; - switch (Cmd->Type) - { - case C_COMMAND: - Ret = 1; - First = DoDelayedExpansion(Cmd->Command.First); - if (First) - { - Rest = DoDelayedExpansion(Cmd->Command.Rest); - if (Rest) - { - Ret = DoCommand(First, Rest, Cmd); - cmd_free(Rest); - } - cmd_free(First); - } - break; - case C_QUIET: - case C_BLOCK: - case C_MULTI: - for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next) - Ret = ExecuteCommand(Sub); - break; - case C_IFFAILURE: - Sub = Cmd->Subcommands; - Ret = ExecuteCommand(Sub); - if (Ret != 0) - { - nErrorLevel = Ret; - Ret = ExecuteCommand(Sub->Next); - } - break; - case C_IFSUCCESS: - Sub = Cmd->Subcommands; - Ret = ExecuteCommand(Sub); - if (Ret == 0) - Ret = ExecuteCommand(Sub->Next); - break; - case C_PIPE: - ExecutePipeline(Cmd); - break; - case C_IF: - Ret = ExecuteIf(Cmd); - break; - case C_FOR: - Ret = ExecuteFor(Cmd); - break; - } + switch (Cmd->Type) + { + case C_COMMAND: + Ret = 1; + First = DoDelayedExpansion(Cmd->Command.First); + if (First) + { + Rest = DoDelayedExpansion(Cmd->Command.Rest); + if (Rest) + { + Ret = DoCommand(First, Rest, Cmd); + cmd_free(Rest); + } + cmd_free(First); + } + break; + case C_QUIET: + case C_BLOCK: + case C_MULTI: + for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next) + Ret = ExecuteCommand(Sub); + break; + case C_IFFAILURE: + Sub = Cmd->Subcommands; + Ret = ExecuteCommand(Sub); + if (Ret != 0) + { + nErrorLevel = Ret; + Ret = ExecuteCommand(Sub->Next); + } + break; + case C_IFSUCCESS: + Sub = Cmd->Subcommands; + Ret = ExecuteCommand(Sub); + if (Ret == 0) + Ret = ExecuteCommand(Sub->Next); + break; + case C_PIPE: + ExecutePipeline(Cmd); + break; + case C_IF: + Ret = ExecuteIf(Cmd); + break; + case C_FOR: + Ret = ExecuteFor(Cmd); + break; + } - UndoRedirection(Cmd->Redirections, NULL); - return Ret; + UndoRedirection(Cmd->Redirections, NULL); + return Ret; } LPTSTR GetEnvVar(LPCTSTR varName) { - static LPTSTR ret = NULL; - UINT size; + static LPTSTR ret = NULL; + UINT size; - cmd_free(ret); - ret = NULL; - size = GetEnvironmentVariable(varName, NULL, 0); - if (size > 0) - { - ret = cmd_alloc(size * sizeof(TCHAR)); - if (ret != NULL) - GetEnvironmentVariable(varName, ret, size + 1); - } - return ret; + cmd_free(ret); + ret = NULL; + size = GetEnvironmentVariable(varName, NULL, 0); + if (size > 0) + { + ret = cmd_alloc(size * sizeof(TCHAR)); + if (ret != NULL) + GetEnvironmentVariable(varName, ret, size + 1); + } + return ret; } LPCTSTR GetEnvVarOrSpecial(LPCTSTR varName) { - static TCHAR ret[MAX_PATH]; + static TCHAR ret[MAX_PATH]; - LPTSTR var = GetEnvVar(varName); - if (var) - return var; + LPTSTR var = GetEnvVar(varName); + if (var) + return var; - /* env var doesn't exist, look for a "special" one */ - /* %CD% */ - if (_tcsicmp(varName,_T("cd")) ==0) - { - GetCurrentDirectory(MAX_PATH, ret); - return ret; - } - /* %TIME% */ - else if (_tcsicmp(varName,_T("time")) ==0) - { - return GetTimeString(); - } - /* %DATE% */ - else if (_tcsicmp(varName,_T("date")) ==0) - { - return GetDateString(); - } + /* env var doesn't exist, look for a "special" one */ + /* %CD% */ + if (_tcsicmp(varName,_T("cd")) ==0) + { + GetCurrentDirectory(MAX_PATH, ret); + return ret; + } + /* %TIME% */ + else if (_tcsicmp(varName,_T("time")) ==0) + { + return GetTimeString(); + } + /* %DATE% */ + else if (_tcsicmp(varName,_T("date")) ==0) + { + return GetDateString(); + } - /* %RANDOM% */ - else if (_tcsicmp(varName,_T("random")) ==0) - { - /* Get random number */ - _itot(rand(),ret,10); - return ret; - } + /* %RANDOM% */ + else if (_tcsicmp(varName,_T("random")) ==0) + { + /* Get random number */ + _itot(rand(),ret,10); + return ret; + } - /* %CMDCMDLINE% */ - else if (_tcsicmp(varName,_T("cmdcmdline")) ==0) - { - return GetCommandLine(); - } + /* %CMDCMDLINE% */ + else if (_tcsicmp(varName,_T("cmdcmdline")) ==0) + { + return GetCommandLine(); + } - /* %CMDEXTVERSION% */ - else if (_tcsicmp(varName,_T("cmdextversion")) ==0) - { - /* Set version number to 2 */ - _itot(2,ret,10); - return ret; - } + /* %CMDEXTVERSION% */ + else if (_tcsicmp(varName,_T("cmdextversion")) ==0) + { + /* Set version number to 2 */ + _itot(2,ret,10); + return ret; + } - /* %ERRORLEVEL% */ - else if (_tcsicmp(varName,_T("errorlevel")) ==0) - { - _itot(nErrorLevel,ret,10); - return ret; - } + /* %ERRORLEVEL% */ + else if (_tcsicmp(varName,_T("errorlevel")) ==0) + { + _itot(nErrorLevel,ret,10); + return ret; + } - return NULL; + return NULL; } /* Handle the %~var syntax */ static LPTSTR GetEnhancedVar(TCHAR **pFormat, LPTSTR (*GetVar)(TCHAR, BOOL *)) { - static const TCHAR ModifierTable[] = _T("dpnxfsatz"); - enum { - M_DRIVE = 1, /* D: drive letter */ - M_PATH = 2, /* P: path */ - M_NAME = 4, /* N: filename */ - M_EXT = 8, /* X: extension */ - M_FULL = 16, /* F: full path (drive+path+name+ext) */ - M_SHORT = 32, /* S: full path (drive+path+name+ext), use short names */ - M_ATTR = 64, /* A: attributes */ - M_TIME = 128, /* T: modification time */ - M_SIZE = 256, /* Z: file size */ - } Modifiers = 0; + static const TCHAR ModifierTable[] = _T("dpnxfsatz"); + enum { + M_DRIVE = 1, /* D: drive letter */ + M_PATH = 2, /* P: path */ + M_NAME = 4, /* N: filename */ + M_EXT = 8, /* X: extension */ + M_FULL = 16, /* F: full path (drive+path+name+ext) */ + M_SHORT = 32, /* S: full path (drive+path+name+ext), use short names */ + M_ATTR = 64, /* A: attributes */ + M_TIME = 128, /* T: modification time */ + M_SIZE = 256, /* Z: file size */ + } Modifiers = 0; - TCHAR *Format, *FormatEnd; - TCHAR *PathVarName = NULL; - LPTSTR Variable; - TCHAR *VarEnd; - BOOL VariableIsParam0; - TCHAR FullPath[MAX_PATH]; - TCHAR FixedPath[MAX_PATH], *Filename, *Extension; - HANDLE hFind; - WIN32_FIND_DATA w32fd; - TCHAR *In, *Out; + TCHAR *Format, *FormatEnd; + TCHAR *PathVarName = NULL; + LPTSTR Variable; + TCHAR *VarEnd; + BOOL VariableIsParam0; + TCHAR FullPath[MAX_PATH]; + TCHAR FixedPath[MAX_PATH], *Filename, *Extension; + HANDLE hFind; + WIN32_FIND_DATA w32fd; + TCHAR *In, *Out; - static TCHAR Result[CMDLINE_LENGTH]; + static TCHAR Result[CMDLINE_LENGTH]; - /* There is ambiguity between modifier characters and FOR variables; - * the rule that cmd uses is to pick the longest possible match. - * For example, if there is a %n variable, then out of %~anxnd, - * %~anxn will be substituted rather than just %~an. */ + /* There is ambiguity between modifier characters and FOR variables; + * the rule that cmd uses is to pick the longest possible match. + * For example, if there is a %n variable, then out of %~anxnd, + * %~anxn will be substituted rather than just %~an. */ - /* First, go through as many modifier characters as possible */ - FormatEnd = Format = *pFormat; - while (*FormatEnd && _tcschr(ModifierTable, _totlower(*FormatEnd))) - FormatEnd++; + /* First, go through as many modifier characters as possible */ + FormatEnd = Format = *pFormat; + while (*FormatEnd && _tcschr(ModifierTable, _totlower(*FormatEnd))) + FormatEnd++; - if (*FormatEnd == _T('$')) - { - /* $PATH: syntax */ - PathVarName = FormatEnd + 1; - FormatEnd = _tcschr(PathVarName, _T(':')); - if (!FormatEnd) - return NULL; + if (*FormatEnd == _T('$')) + { + /* $PATH: syntax */ + PathVarName = FormatEnd + 1; + FormatEnd = _tcschr(PathVarName, _T(':')); + if (!FormatEnd) + return NULL; - /* Must be immediately followed by the variable */ - Variable = GetVar(*++FormatEnd, &VariableIsParam0); - if (!Variable) - return NULL; - } - else - { - /* Backtrack if necessary to get a variable name match */ - while (!(Variable = GetVar(*FormatEnd, &VariableIsParam0))) - { - if (FormatEnd == Format) - return NULL; - FormatEnd--; - } - } + /* Must be immediately followed by the variable */ + Variable = GetVar(*++FormatEnd, &VariableIsParam0); + if (!Variable) + return NULL; + } + else + { + /* Backtrack if necessary to get a variable name match */ + while (!(Variable = GetVar(*FormatEnd, &VariableIsParam0))) + { + if (FormatEnd == Format) + return NULL; + FormatEnd--; + } + } - for (; Format < FormatEnd && *Format != _T('$'); Format++) - Modifiers |= 1 << (_tcschr(ModifierTable, _totlower(*Format)) - ModifierTable); + for (; Format < FormatEnd && *Format != _T('$'); Format++) + Modifiers |= 1 << (_tcschr(ModifierTable, _totlower(*Format)) - ModifierTable); - *pFormat = FormatEnd + 1; + *pFormat = FormatEnd + 1; - /* Exclude the leading and trailing quotes */ - VarEnd = &Variable[_tcslen(Variable)]; - if (*Variable == _T('"')) - { - Variable++; - if (VarEnd > Variable && VarEnd[-1] == _T('"')) - VarEnd--; - } + /* Exclude the leading and trailing quotes */ + VarEnd = &Variable[_tcslen(Variable)]; + if (*Variable == _T('"')) + { + Variable++; + if (VarEnd > Variable && VarEnd[-1] == _T('"')) + VarEnd--; + } - if ((char *)VarEnd - (char *)Variable >= sizeof Result) - return _T(""); - memcpy(Result, Variable, (char *)VarEnd - (char *)Variable); - Result[VarEnd - Variable] = _T('\0'); + if ((char *)VarEnd - (char *)Variable >= sizeof Result) + return _T(""); + memcpy(Result, Variable, (char *)VarEnd - (char *)Variable); + Result[VarEnd - Variable] = _T('\0'); - if (PathVarName) - { - /* $PATH: syntax - search the directories listed in the - * specified environment variable for the file */ - LPTSTR PathVar; - FormatEnd[-1] = _T('\0'); - PathVar = GetEnvVar(PathVarName); - FormatEnd[-1] = _T(':'); - if (!PathVar || - !SearchPath(PathVar, Result, NULL, MAX_PATH, FullPath, NULL)) - { - return _T(""); - } - } - else if (Modifiers == 0) - { - /* For plain %~var with no modifiers, just return the variable without quotes */ - return Result; - } - else if (VariableIsParam0) - { - /* Special case: If the variable is %0 and modifier characters are present, - * use the batch file's path (which includes the .bat/.cmd extension) - * rather than the actual %0 variable (which might not). */ - _tcscpy(FullPath, bc->BatchFilePath); - } - else - { - /* Convert the variable, now without quotes, to a full path */ - if (!GetFullPathName(Result, MAX_PATH, FullPath, NULL)) - return _T(""); - } + if (PathVarName) + { + /* $PATH: syntax - search the directories listed in the + * specified environment variable for the file */ + LPTSTR PathVar; + FormatEnd[-1] = _T('\0'); + PathVar = GetEnvVar(PathVarName); + FormatEnd[-1] = _T(':'); + if (!PathVar || + !SearchPath(PathVar, Result, NULL, MAX_PATH, FullPath, NULL)) + { + return _T(""); + } + } + else if (Modifiers == 0) + { + /* For plain %~var with no modifiers, just return the variable without quotes */ + return Result; + } + else if (VariableIsParam0) + { + /* Special case: If the variable is %0 and modifier characters are present, + * use the batch file's path (which includes the .bat/.cmd extension) + * rather than the actual %0 variable (which might not). */ + _tcscpy(FullPath, bc->BatchFilePath); + } + else + { + /* Convert the variable, now without quotes, to a full path */ + if (!GetFullPathName(Result, MAX_PATH, FullPath, NULL)) + return _T(""); + } - /* Next step is to change the path to fix letter case (e.g. - * C:\ReAcToS -> C:\ReactOS) and, if requested with the S modifier, - * replace long filenames with short. */ + /* Next step is to change the path to fix letter case (e.g. + * C:\ReAcToS -> C:\ReactOS) and, if requested with the S modifier, + * replace long filenames with short. */ - In = FullPath; - Out = FixedPath; + In = FullPath; + Out = FixedPath; - /* Copy drive letter */ - *Out++ = *In++; - *Out++ = *In++; - *Out++ = *In++; - /* Loop over each \-separated component in the path */ - do { - TCHAR *Next = _tcschr(In, _T('\\')); - if (Next) - *Next++ = _T('\0'); - /* Use FindFirstFile to get the correct name */ - if (Out + _tcslen(In) + 1 >= &FixedPath[MAX_PATH]) - return _T(""); - _tcscpy(Out, In); - hFind = FindFirstFile(FixedPath, &w32fd); - /* If it doesn't exist, just leave the name as it was given */ - if (hFind != INVALID_HANDLE_VALUE) - { - LPTSTR FixedComponent = w32fd.cFileName; - if (*w32fd.cAlternateFileName && - ((Modifiers & M_SHORT) || !_tcsicmp(In, w32fd.cAlternateFileName))) - { - FixedComponent = w32fd.cAlternateFileName; - } - FindClose(hFind); + /* Copy drive letter */ + *Out++ = *In++; + *Out++ = *In++; + *Out++ = *In++; + /* Loop over each \-separated component in the path */ + do { + TCHAR *Next = _tcschr(In, _T('\\')); + if (Next) + *Next++ = _T('\0'); + /* Use FindFirstFile to get the correct name */ + if (Out + _tcslen(In) + 1 >= &FixedPath[MAX_PATH]) + return _T(""); + _tcscpy(Out, In); + hFind = FindFirstFile(FixedPath, &w32fd); + /* If it doesn't exist, just leave the name as it was given */ + if (hFind != INVALID_HANDLE_VALUE) + { + LPTSTR FixedComponent = w32fd.cFileName; + if (*w32fd.cAlternateFileName && + ((Modifiers & M_SHORT) || !_tcsicmp(In, w32fd.cAlternateFileName))) + { + FixedComponent = w32fd.cAlternateFileName; + } + FindClose(hFind); - if (Out + _tcslen(FixedComponent) + 1 >= &FixedPath[MAX_PATH]) - return _T(""); - _tcscpy(Out, FixedComponent); - } - Filename = Out; - Out += _tcslen(Out); - *Out++ = _T('\\'); + if (Out + _tcslen(FixedComponent) + 1 >= &FixedPath[MAX_PATH]) + return _T(""); + _tcscpy(Out, FixedComponent); + } + Filename = Out; + Out += _tcslen(Out); + *Out++ = _T('\\'); - In = Next; - } while (In != NULL); - Out[-1] = _T('\0'); + In = Next; + } while (In != NULL); + Out[-1] = _T('\0'); - /* Build the result string. Start with attributes, modification time, and - * file size. If the file didn't exist, these fields will all be empty. */ - Out = Result; - if (hFind != INVALID_HANDLE_VALUE) - { - if (Modifiers & M_ATTR) - { - static const struct { - TCHAR Character; - WORD Value; - } *Attrib, Table[] = { - { _T('d'), FILE_ATTRIBUTE_DIRECTORY }, - { _T('r'), FILE_ATTRIBUTE_READONLY }, - { _T('a'), FILE_ATTRIBUTE_ARCHIVE }, - { _T('h'), FILE_ATTRIBUTE_HIDDEN }, - { _T('s'), FILE_ATTRIBUTE_SYSTEM }, - { _T('c'), FILE_ATTRIBUTE_COMPRESSED }, - { _T('o'), FILE_ATTRIBUTE_OFFLINE }, - { _T('t'), FILE_ATTRIBUTE_TEMPORARY }, - { _T('l'), FILE_ATTRIBUTE_REPARSE_POINT }, - }; - for (Attrib = Table; Attrib != &Table[9]; Attrib++) - { - *Out++ = w32fd.dwFileAttributes & Attrib->Value - ? Attrib->Character - : _T('-'); - } - *Out++ = _T(' '); - } - if (Modifiers & M_TIME) - { - FILETIME ft; - SYSTEMTIME st; - FileTimeToLocalFileTime(&w32fd.ftLastWriteTime, &ft); - FileTimeToSystemTime(&ft, &st); + /* Build the result string. Start with attributes, modification time, and + * file size. If the file didn't exist, these fields will all be empty. */ + Out = Result; + if (hFind != INVALID_HANDLE_VALUE) + { + if (Modifiers & M_ATTR) + { + static const struct { + TCHAR Character; + WORD Value; + } *Attrib, Table[] = { + { _T('d'), FILE_ATTRIBUTE_DIRECTORY }, + { _T('r'), FILE_ATTRIBUTE_READONLY }, + { _T('a'), FILE_ATTRIBUTE_ARCHIVE }, + { _T('h'), FILE_ATTRIBUTE_HIDDEN }, + { _T('s'), FILE_ATTRIBUTE_SYSTEM }, + { _T('c'), FILE_ATTRIBUTE_COMPRESSED }, + { _T('o'), FILE_ATTRIBUTE_OFFLINE }, + { _T('t'), FILE_ATTRIBUTE_TEMPORARY }, + { _T('l'), FILE_ATTRIBUTE_REPARSE_POINT }, + }; + for (Attrib = Table; Attrib != &Table[9]; Attrib++) + { + *Out++ = w32fd.dwFileAttributes & Attrib->Value + ? Attrib->Character + : _T('-'); + } + *Out++ = _T(' '); + } + if (Modifiers & M_TIME) + { + FILETIME ft; + SYSTEMTIME st; + FileTimeToLocalFileTime(&w32fd.ftLastWriteTime, &ft); + FileTimeToSystemTime(&ft, &st); - Out += FormatDate(Out, &st, TRUE); - *Out++ = _T(' '); - Out += FormatTime(Out, &st); - *Out++ = _T(' '); - } - if (Modifiers & M_SIZE) - { - ULARGE_INTEGER Size; - Size.LowPart = w32fd.nFileSizeLow; - Size.HighPart = w32fd.nFileSizeHigh; - Out += _stprintf(Out, _T("%I64u "), Size.QuadPart); - } - } + Out += FormatDate(Out, &st, TRUE); + *Out++ = _T(' '); + Out += FormatTime(Out, &st); + *Out++ = _T(' '); + } + if (Modifiers & M_SIZE) + { + ULARGE_INTEGER Size; + Size.LowPart = w32fd.nFileSizeLow; + Size.HighPart = w32fd.nFileSizeHigh; + Out += _stprintf(Out, _T("%I64u "), Size.QuadPart); + } + } - /* When using the path-searching syntax or the S modifier, - * at least part of the file path is always included. - * If none of the DPNX modifiers are present, include the full path */ - if (PathVarName || (Modifiers & M_SHORT)) - if ((Modifiers & (M_DRIVE | M_PATH | M_NAME | M_EXT)) == 0) - Modifiers |= M_FULL; + /* When using the path-searching syntax or the S modifier, + * at least part of the file path is always included. + * If none of the DPNX modifiers are present, include the full path */ + if (PathVarName || (Modifiers & M_SHORT)) + if ((Modifiers & (M_DRIVE | M_PATH | M_NAME | M_EXT)) == 0) + Modifiers |= M_FULL; - /* Now add the requested parts of the name. - * With the F modifier, add all parts to form the full path. */ - Extension = _tcsrchr(Filename, _T('.')); - if (Modifiers & (M_DRIVE | M_FULL)) - { - *Out++ = FixedPath[0]; - *Out++ = FixedPath[1]; - } - if (Modifiers & (M_PATH | M_FULL)) - { - memcpy(Out, &FixedPath[2], (char *)Filename - (char *)&FixedPath[2]); - Out += Filename - &FixedPath[2]; - } - if (Modifiers & (M_NAME | M_FULL)) - { - while (*Filename && Filename != Extension) - *Out++ = *Filename++; - } - if (Modifiers & (M_EXT | M_FULL)) - { - if (Extension) - Out = _stpcpy(Out, Extension); - } + /* Now add the requested parts of the name. + * With the F modifier, add all parts to form the full path. */ + Extension = _tcsrchr(Filename, _T('.')); + if (Modifiers & (M_DRIVE | M_FULL)) + { + *Out++ = FixedPath[0]; + *Out++ = FixedPath[1]; + } + if (Modifiers & (M_PATH | M_FULL)) + { + memcpy(Out, &FixedPath[2], (char *)Filename - (char *)&FixedPath[2]); + Out += Filename - &FixedPath[2]; + } + if (Modifiers & (M_NAME | M_FULL)) + { + while (*Filename && Filename != Extension) + *Out++ = *Filename++; + } + if (Modifiers & (M_EXT | M_FULL)) + { + if (Extension) + Out = _stpcpy(Out, Extension); + } - /* Trim trailing space which otherwise would appear as a - * result of using the A/T/Z modifiers but no others. */ - while (Out != &Result[0] && Out[-1] == _T(' ')) - Out--; - *Out = _T('\0'); + /* Trim trailing space which otherwise would appear as a + * result of using the A/T/Z modifiers but no others. */ + while (Out != &Result[0] && Out[-1] == _T(' ')) + Out--; + *Out = _T('\0'); - return Result; + return Result; } LPCTSTR GetBatchVar(TCHAR *varName, UINT *varNameLen) { - LPCTSTR ret; - TCHAR *varNameEnd; - BOOL dummy; + LPCTSTR ret; + TCHAR *varNameEnd; + BOOL dummy; - *varNameLen = 1; + *varNameLen = 1; - switch ( *varName ) - { - case _T('~'): - varNameEnd = varName + 1; - ret = GetEnhancedVar(&varNameEnd, FindArg); - if (!ret) - { - error_syntax(varName); - return NULL; - } - *varNameLen = varNameEnd - varName; - return ret; - case _T('0'): - case _T('1'): - case _T('2'): - case _T('3'): - case _T('4'): - case _T('5'): - case _T('6'): - case _T('7'): - case _T('8'): - case _T('9'): - return FindArg(*varName, &dummy); + switch ( *varName ) + { + case _T('~'): + varNameEnd = varName + 1; + ret = GetEnhancedVar(&varNameEnd, FindArg); + if (!ret) + { + error_syntax(varName); + return NULL; + } + *varNameLen = varNameEnd - varName; + return ret; + case _T('0'): + case _T('1'): + case _T('2'): + case _T('3'): + case _T('4'): + case _T('5'): + case _T('6'): + case _T('7'): + case _T('8'): + case _T('9'): + return FindArg(*varName, &dummy); case _T('*'): // @@ -1127,161 +1124,161 @@ GetBatchVar(TCHAR *varName, UINT *varNameLen) // return bc->raw_params; - case _T('%'): - return _T("%"); - } - return NULL; + case _T('%'): + return _T("%"); + } + return NULL; } BOOL SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim) { #define APPEND(From, Length) { \ - if (Dest + (Length) > DestEnd) \ - goto too_long; \ - memcpy(Dest, From, (Length) * sizeof(TCHAR)); \ - Dest += Length; } + if (Dest + (Length) > DestEnd) \ + goto too_long; \ + memcpy(Dest, From, (Length) * sizeof(TCHAR)); \ + Dest += Length; } #define APPEND1(Char) { \ - if (Dest >= DestEnd) \ - goto too_long; \ - *Dest++ = Char; } + if (Dest >= DestEnd) \ + goto too_long; \ + *Dest++ = Char; } - TCHAR *DestEnd = Dest + CMDLINE_LENGTH - 1; - const TCHAR *Var; - int VarLength; - TCHAR *SubstStart; - TCHAR EndChr; - while (*Src) - { - if (*Src != Delim) - { - APPEND1(*Src++) - continue; - } + TCHAR *DestEnd = Dest + CMDLINE_LENGTH - 1; + const TCHAR *Var; + int VarLength; + TCHAR *SubstStart; + TCHAR EndChr; + while (*Src) + { + if (*Src != Delim) + { + APPEND1(*Src++) + continue; + } - Src++; - if (bc && Delim == _T('%')) - { - UINT NameLen; - Var = GetBatchVar(Src, &NameLen); - if (Var != NULL) - { - VarLength = _tcslen(Var); - APPEND(Var, VarLength) - Src += NameLen; - continue; - } - } + Src++; + if (bc && Delim == _T('%')) + { + UINT NameLen; + Var = GetBatchVar(Src, &NameLen); + if (Var != NULL) + { + VarLength = _tcslen(Var); + APPEND(Var, VarLength) + Src += NameLen; + continue; + } + } - /* Find the end of the variable name. A colon (:) will usually - * end the name and begin the optional modifier, but not if it - * is immediately followed by the delimiter (%VAR:%). */ - SubstStart = Src; - while (*Src != Delim && !(*Src == _T(':') && Src[1] != Delim)) - { - if (!*Src) - goto bad_subst; - Src++; - } + /* Find the end of the variable name. A colon (:) will usually + * end the name and begin the optional modifier, but not if it + * is immediately followed by the delimiter (%VAR:%). */ + SubstStart = Src; + while (*Src != Delim && !(*Src == _T(':') && Src[1] != Delim)) + { + if (!*Src) + goto bad_subst; + Src++; + } - EndChr = *Src; - *Src = _T('\0'); - Var = GetEnvVarOrSpecial(SubstStart); - *Src++ = EndChr; - if (Var == NULL) - { - /* In a batch file, %NONEXISTENT% "expands" to an empty string */ - if (bc) - continue; - goto bad_subst; - } - VarLength = _tcslen(Var); + EndChr = *Src; + *Src = _T('\0'); + Var = GetEnvVarOrSpecial(SubstStart); + *Src++ = EndChr; + if (Var == NULL) + { + /* In a batch file, %NONEXISTENT% "expands" to an empty string */ + if (bc) + continue; + goto bad_subst; + } + VarLength = _tcslen(Var); - if (EndChr == Delim) - { - /* %VAR% - use as-is */ - APPEND(Var, VarLength) - } - else if (*Src == _T('~')) - { - /* %VAR:~[start][,length]% - substring - * Negative values are offsets from the end */ - int Start = _tcstol(Src + 1, &Src, 0); - int End = VarLength; - if (Start < 0) - Start += VarLength; - Start = max(Start, 0); - Start = min(Start, VarLength); - if (*Src == _T(',')) - { - End = _tcstol(Src + 1, &Src, 0); - End += (End < 0) ? VarLength : Start; - End = max(End, Start); - End = min(End, VarLength); - } - if (*Src++ != Delim) - goto bad_subst; - APPEND(&Var[Start], End - Start); - } - else - { - /* %VAR:old=new% - replace all occurrences of old with new - * %VAR:*old=new% - replace first occurrence only, - * and remove everything before it */ - TCHAR *Old, *New; - DWORD OldLength, NewLength; - BOOL Star = FALSE; - int LastMatch = 0, i = 0; + if (EndChr == Delim) + { + /* %VAR% - use as-is */ + APPEND(Var, VarLength) + } + else if (*Src == _T('~')) + { + /* %VAR:~[start][,length]% - substring + * Negative values are offsets from the end */ + int Start = _tcstol(Src + 1, &Src, 0); + int End = VarLength; + if (Start < 0) + Start += VarLength; + Start = max(Start, 0); + Start = min(Start, VarLength); + if (*Src == _T(',')) + { + End = _tcstol(Src + 1, &Src, 0); + End += (End < 0) ? VarLength : Start; + End = max(End, Start); + End = min(End, VarLength); + } + if (*Src++ != Delim) + goto bad_subst; + APPEND(&Var[Start], End - Start); + } + else + { + /* %VAR:old=new% - replace all occurrences of old with new + * %VAR:*old=new% - replace first occurrence only, + * and remove everything before it */ + TCHAR *Old, *New; + DWORD OldLength, NewLength; + BOOL Star = FALSE; + int LastMatch = 0, i = 0; - if (*Src == _T('*')) - { - Star = TRUE; - Src++; - } + if (*Src == _T('*')) + { + Star = TRUE; + Src++; + } - /* the string to replace may contain the delimiter */ - Src = _tcschr(Old = Src, _T('=')); - if (Src == NULL) - goto bad_subst; - OldLength = Src++ - Old; - if (OldLength == 0) - goto bad_subst; + /* the string to replace may contain the delimiter */ + Src = _tcschr(Old = Src, _T('=')); + if (Src == NULL) + goto bad_subst; + OldLength = Src++ - Old; + if (OldLength == 0) + goto bad_subst; - Src = _tcschr(New = Src, Delim); - if (Src == NULL) - goto bad_subst; - NewLength = Src++ - New; + Src = _tcschr(New = Src, Delim); + if (Src == NULL) + goto bad_subst; + NewLength = Src++ - New; - while (i < VarLength) - { - if (_tcsnicmp(&Var[i], Old, OldLength) == 0) - { - if (!Star) - APPEND(&Var[LastMatch], i - LastMatch) - APPEND(New, NewLength) - i += OldLength; - LastMatch = i; - if (Star) - break; - continue; - } - i++; - } - APPEND(&Var[LastMatch], VarLength - LastMatch) - } - continue; + while (i < VarLength) + { + if (_tcsnicmp(&Var[i], Old, OldLength) == 0) + { + if (!Star) + APPEND(&Var[LastMatch], i - LastMatch) + APPEND(New, NewLength) + i += OldLength; + LastMatch = i; + if (Star) + break; + continue; + } + i++; + } + APPEND(&Var[LastMatch], VarLength - LastMatch) + } + continue; - bad_subst: - Src = SubstStart; - if (!bc) - APPEND1(Delim) - } - *Dest = _T('\0'); - return TRUE; + bad_subst: + Src = SubstStart; + if (!bc) + APPEND1(Delim) + } + *Dest = _T('\0'); + return TRUE; too_long: - ConOutResPrintf(STRING_ALIAS_ERROR); - nErrorLevel = 9023; - return FALSE; + ConOutResPrintf(STRING_ALIAS_ERROR); + nErrorLevel = 9023; + return FALSE; #undef APPEND #undef APPEND1 } @@ -1289,69 +1286,71 @@ too_long: /* Search the list of FOR contexts for a variable */ static LPTSTR FindForVar(TCHAR Var, BOOL *IsParam0) { - FOR_CONTEXT *Ctx; - *IsParam0 = FALSE; - for (Ctx = fc; Ctx != NULL; Ctx = Ctx->prev) - if ((UINT)(Var - Ctx->firstvar) < Ctx->varcount) - return Ctx->values[Var - Ctx->firstvar]; - return NULL; + FOR_CONTEXT *Ctx; + *IsParam0 = FALSE; + for (Ctx = fc; Ctx != NULL; Ctx = Ctx->prev) + { + if ((UINT)(Var - Ctx->firstvar) < Ctx->varcount) + return Ctx->values[Var - Ctx->firstvar]; + } + return NULL; } BOOL SubstituteForVars(TCHAR *Src, TCHAR *Dest) { - TCHAR *DestEnd = &Dest[CMDLINE_LENGTH - 1]; - while (*Src) - { - if (Src[0] == _T('%')) - { - BOOL Dummy; - LPTSTR End = &Src[2]; - LPTSTR Value = NULL; + TCHAR *DestEnd = &Dest[CMDLINE_LENGTH - 1]; + while (*Src) + { + if (Src[0] == _T('%')) + { + BOOL Dummy; + LPTSTR End = &Src[2]; + LPTSTR Value = NULL; - if (Src[1] == _T('~')) - Value = GetEnhancedVar(&End, FindForVar); + if (Src[1] == _T('~')) + Value = GetEnhancedVar(&End, FindForVar); - if (!Value) - Value = FindForVar(Src[1], &Dummy); + if (!Value) + Value = FindForVar(Src[1], &Dummy); - if (Value) - { - if (Dest + _tcslen(Value) > DestEnd) - return FALSE; - Dest = _stpcpy(Dest, Value); - Src = End; - continue; - } - } - /* Not a variable; just copy the character */ - if (Dest >= DestEnd) - return FALSE; - *Dest++ = *Src++; - } - *Dest = _T('\0'); - return TRUE; + if (Value) + { + if (Dest + _tcslen(Value) > DestEnd) + return FALSE; + Dest = _stpcpy(Dest, Value); + Src = End; + continue; + } + } + /* Not a variable; just copy the character */ + if (Dest >= DestEnd) + return FALSE; + *Dest++ = *Src++; + } + *Dest = _T('\0'); + return TRUE; } LPTSTR DoDelayedExpansion(LPTSTR Line) { - TCHAR Buf1[CMDLINE_LENGTH]; - TCHAR Buf2[CMDLINE_LENGTH]; + TCHAR Buf1[CMDLINE_LENGTH]; + TCHAR Buf2[CMDLINE_LENGTH]; - /* First, substitute FOR variables */ - if (!SubstituteForVars(Line, Buf1)) - return NULL; + /* First, substitute FOR variables */ + if (!SubstituteForVars(Line, Buf1)) + return NULL; - if (!bDelayedExpansion || !_tcschr(Buf1, _T('!'))) - return cmd_dup(Buf1); + if (!bDelayedExpansion || !_tcschr(Buf1, _T('!'))) + return cmd_dup(Buf1); - /* FIXME: Delayed substitutions actually aren't quite the same as - * immediate substitutions. In particular, it's possible to escape - * the exclamation point using ^. */ - if (!SubstituteVars(Buf1, Buf2, _T('!'))) - return NULL; - return cmd_dup(Buf2); + /* FIXME: Delayed substitutions actually aren't quite the same as + * immediate substitutions. In particular, it's possible to escape + * the exclamation point using ^. */ + if (!SubstituteVars(Buf1, Buf2, _T('!'))) + return NULL; + return cmd_dup(Buf2); } @@ -1361,103 +1360,102 @@ DoDelayedExpansion(LPTSTR Line) */ BOOL -ReadLine (TCHAR *commandline, BOOL bMore) +ReadLine(TCHAR *commandline, BOOL bMore) { - TCHAR readline[CMDLINE_LENGTH]; - LPTSTR ip; + TCHAR readline[CMDLINE_LENGTH]; + LPTSTR ip; - /* if no batch input then... */ - if (bc == NULL) - { - if (bMore) - { - ConOutResPrintf(STRING_MORE); - } - else - { - /* JPP 19980807 - if echo off, don't print prompt */ - if (bEcho) - { - if (!bIgnoreEcho) - ConOutChar('\n'); - PrintPrompt(); - } - } + /* if no batch input then... */ + if (bc == NULL) + { + if (bMore) + { + ConOutResPrintf(STRING_MORE); + } + else + { + /* JPP 19980807 - if echo off, don't print prompt */ + if (bEcho) + { + if (!bIgnoreEcho) + ConOutChar(_T('\n')); + PrintPrompt(); + } + } - if (!ReadCommand(readline, CMDLINE_LENGTH - 1)) - { - bExit = TRUE; - return FALSE; - } + if (!ReadCommand(readline, CMDLINE_LENGTH - 1)) + { + bExit = TRUE; + return FALSE; + } - if (CheckCtrlBreak(BREAK_INPUT)) - { - ConOutPuts(_T("\n")); - return FALSE; - } - ip = readline; - } - else - { - ip = ReadBatchLine(); - if (!ip) - return FALSE; - } + if (CheckCtrlBreak(BREAK_INPUT)) + { + ConOutChar(_T('\n')); + return FALSE; + } + ip = readline; + } + else + { + ip = ReadBatchLine(); + if (!ip) + return FALSE; + } - return SubstituteVars(ip, commandline, _T('%')); + return SubstituteVars(ip, commandline, _T('%')); } static VOID ProcessInput() { - PARSED_COMMAND *Cmd; + PARSED_COMMAND *Cmd; - while (!bCanExit || !bExit) - { - Cmd = ParseCommand(NULL); - if (!Cmd) - continue; + while (!bCanExit || !bExit) + { + Cmd = ParseCommand(NULL); + if (!Cmd) + continue; - ExecuteCommand(Cmd); - FreeCommand(Cmd); - } + ExecuteCommand(Cmd); + FreeCommand(Cmd); + } } /* * control-break handler. */ -BOOL WINAPI BreakHandler (DWORD dwCtrlType) +BOOL WINAPI BreakHandler(DWORD dwCtrlType) { + DWORD dwWritten; + INPUT_RECORD rec; + static BOOL SelfGenerated = FALSE; - DWORD dwWritten; - INPUT_RECORD rec; - static BOOL SelfGenerated = FALSE; + if ((dwCtrlType != CTRL_C_EVENT) && + (dwCtrlType != CTRL_BREAK_EVENT)) + { + return FALSE; + } + else + { + if (SelfGenerated) + { + SelfGenerated = FALSE; + return TRUE; + } + } - if ((dwCtrlType != CTRL_C_EVENT) && - (dwCtrlType != CTRL_BREAK_EVENT)) - { - return FALSE; - } - else - { - if(SelfGenerated) - { - SelfGenerated = FALSE; - return TRUE; - } - } - - if (!TryEnterCriticalSection(&ChildProcessRunningLock)) - { - SelfGenerated = TRUE; - GenerateConsoleCtrlEvent (dwCtrlType, 0); - return TRUE; - } - else - { - LeaveCriticalSection(&ChildProcessRunningLock); - } + if (!TryEnterCriticalSection(&ChildProcessRunningLock)) + { + SelfGenerated = TRUE; + GenerateConsoleCtrlEvent (dwCtrlType, 0); + return TRUE; + } + else + { + LeaveCriticalSection(&ChildProcessRunningLock); + } rec.EventType = KEY_EVENT; rec.Event.KeyEvent.bKeyDown = TRUE; @@ -1468,31 +1466,29 @@ BOOL WINAPI BreakHandler (DWORD dwCtrlType) rec.Event.KeyEvent.uChar.UnicodeChar = _T('C'); rec.Event.KeyEvent.dwControlKeyState = RIGHT_CTRL_PRESSED; - WriteConsoleInput( - hIn, - &rec, - 1, - &dwWritten); + WriteConsoleInput(hIn, + &rec, + 1, + &dwWritten); - bCtrlBreak = TRUE; - /* FIXME: Handle batch files */ + bCtrlBreak = TRUE; + /* FIXME: Handle batch files */ - //ConOutPrintf(_T("^C")); + //ConOutPrintf(_T("^C")); - - return TRUE; + return TRUE; } VOID AddBreakHandler (VOID) { - SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE); + SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE); } VOID RemoveBreakHandler (VOID) { - SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE); + SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE); } @@ -1504,56 +1500,56 @@ VOID RemoveBreakHandler (VOID) static VOID ShowCommands (VOID) { - /* print command list */ - ConOutResPuts(STRING_CMD_HELP1); - PrintCommandList(); + /* print command list */ + ConOutResPuts(STRING_CMD_HELP1); + PrintCommandList(); - /* print feature list */ - ConOutResPuts(STRING_CMD_HELP2); + /* print feature list */ + ConOutResPuts(STRING_CMD_HELP2); #ifdef FEATURE_ALIASES - ConOutResPuts(STRING_CMD_HELP3); + ConOutResPuts(STRING_CMD_HELP3); #endif #ifdef FEATURE_HISTORY - ConOutResPuts(STRING_CMD_HELP4); + ConOutResPuts(STRING_CMD_HELP4); #endif #ifdef FEATURE_UNIX_FILENAME_COMPLETION - ConOutResPuts(STRING_CMD_HELP5); + ConOutResPuts(STRING_CMD_HELP5); #endif #ifdef FEATURE_DIRECTORY_STACK - ConOutResPuts(STRING_CMD_HELP6); + ConOutResPuts(STRING_CMD_HELP6); #endif #ifdef FEATURE_REDIRECTION - ConOutResPuts(STRING_CMD_HELP7); + ConOutResPuts(STRING_CMD_HELP7); #endif - ConOutChar(_T('\n')); + ConOutChar(_T('\n')); } #endif static VOID ExecuteAutoRunFile(HKEY hkeyRoot) { - TCHAR autorun[2048]; - DWORD len = sizeof autorun; - HKEY hkey; + TCHAR autorun[2048]; + DWORD len = sizeof autorun; + HKEY hkey; if (RegOpenKeyEx(hkeyRoot, - _T("SOFTWARE\\Microsoft\\Command Processor"), - 0, - KEY_READ, - &hkey ) == ERROR_SUCCESS) + _T("SOFTWARE\\Microsoft\\Command Processor"), + 0, + KEY_READ, + &hkey) == ERROR_SUCCESS) { - if(RegQueryValueEx(hkey, + if (RegQueryValueEx(hkey, _T("AutoRun"), 0, 0, (LPBYTE)autorun, &len) == ERROR_SUCCESS) - { - if (*autorun) - ParseCommandLine(autorun); - } - RegCloseKey(hkey); + { + if (*autorun) + ParseCommandLine(autorun); + } + RegCloseKey(hkey); } } @@ -1561,53 +1557,53 @@ ExecuteAutoRunFile(HKEY hkeyRoot) static VOID GetCmdLineCommand(TCHAR *commandline, TCHAR *ptr, BOOL AlwaysStrip) { - TCHAR *LastQuote; + TCHAR *LastQuote; - while (_istspace(*ptr)) - ptr++; + while (_istspace(*ptr)) + ptr++; - /* Remove leading quote, find final quote */ - if (*ptr == _T('"') && - (LastQuote = _tcsrchr(++ptr, _T('"'))) != NULL) - { - TCHAR *Space; - /* Under certain circumstances, all quotes are preserved. - * CMD /? documents these conditions as follows: - * 1. No /S switch - * 2. Exactly two quotes - * 3. No "special characters" between the quotes - * (CMD /? says &<>()@^| but parentheses did not - * trigger this rule when I tested them.) - * 4. Whitespace exists between the quotes - * 5. Enclosed string is an executable filename - */ - *LastQuote = _T('\0'); - for (Space = ptr + 1; Space < LastQuote; Space++) - { - if (_istspace(*Space)) /* Rule 4 */ - { - if (!AlwaysStrip && /* Rule 1 */ - !_tcspbrk(ptr, _T("\"&<>@^|")) && /* Rules 2, 3 */ - SearchForExecutable(ptr, commandline)) /* Rule 5 */ - { - /* All conditions met: preserve both the quotes */ - *LastQuote = _T('"'); - _tcscpy(commandline, ptr - 1); - return; - } - break; - } - } + /* Remove leading quote, find final quote */ + if (*ptr == _T('"') && + (LastQuote = _tcsrchr(++ptr, _T('"'))) != NULL) + { + TCHAR *Space; + /* Under certain circumstances, all quotes are preserved. + * CMD /? documents these conditions as follows: + * 1. No /S switch + * 2. Exactly two quotes + * 3. No "special characters" between the quotes + * (CMD /? says &<>()@^| but parentheses did not + * trigger this rule when I tested them.) + * 4. Whitespace exists between the quotes + * 5. Enclosed string is an executable filename + */ + *LastQuote = _T('\0'); + for (Space = ptr + 1; Space < LastQuote; Space++) + { + if (_istspace(*Space)) /* Rule 4 */ + { + if (!AlwaysStrip && /* Rule 1 */ + !_tcspbrk(ptr, _T("\"&<>@^|")) && /* Rules 2, 3 */ + SearchForExecutable(ptr, commandline)) /* Rule 5 */ + { + /* All conditions met: preserve both the quotes */ + *LastQuote = _T('"'); + _tcscpy(commandline, ptr - 1); + return; + } + break; + } + } - /* The conditions were not met: remove both the - * leading quote and the last quote */ - _tcscpy(commandline, ptr); - _tcscpy(&commandline[LastQuote - ptr], LastQuote + 1); - return; - } + /* The conditions were not met: remove both the + * leading quote and the last quote */ + _tcscpy(commandline, ptr); + _tcscpy(&commandline[LastQuote - ptr], LastQuote + 1); + return; + } - /* No quotes; just copy */ - _tcscpy(commandline, ptr); + /* No quotes; just copy */ + _tcscpy(commandline, ptr); } /* @@ -1616,200 +1612,203 @@ GetCmdLineCommand(TCHAR *commandline, TCHAR *ptr, BOOL AlwaysStrip) static VOID Initialize() { - HMODULE NtDllModule; - TCHAR commandline[CMDLINE_LENGTH]; - TCHAR ModuleName[_MAX_PATH + 1]; - TCHAR lpBuffer[2]; - INT nExitCode; + HMODULE NtDllModule; + TCHAR commandline[CMDLINE_LENGTH]; + TCHAR ModuleName[_MAX_PATH + 1]; + INT nExitCode; - //INT len; - TCHAR *ptr, *cmdLine, option = 0; - BOOL AlwaysStrip = FALSE; - BOOL AutoRun = TRUE; + //INT len; + TCHAR *ptr, *cmdLine, option = 0; + BOOL AlwaysStrip = FALSE; + BOOL AutoRun = TRUE; - /* get version information */ - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx (&osvi); + /* get version information */ + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx (&osvi); - /* Some people like to run ReactOS cmd.exe on Win98, it helps in the - * build process. So don't link implicitly against ntdll.dll, load it - * dynamically instead */ - NtDllModule = GetModuleHandle(TEXT("ntdll.dll")); - if (NtDllModule != NULL) - { - NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess"); - NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory"); - } + /* Some people like to run ReactOS cmd.exe on Win98, it helps in the + * build process. So don't link implicitly against ntdll.dll, load it + * dynamically instead */ + NtDllModule = GetModuleHandle(TEXT("ntdll.dll")); + if (NtDllModule != NULL) + { + NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess"); + NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory"); + } - InitLocale (); + InitLocale(); - /* get default input and output console handles */ - hOut = GetStdHandle (STD_OUTPUT_HANDLE); - hIn = GetStdHandle (STD_INPUT_HANDLE); + /* get default input and output console handles */ + hOut = GetStdHandle(STD_OUTPUT_HANDLE); + hIn = GetStdHandle(STD_INPUT_HANDLE); - /* Set EnvironmentVariable PROMPT if it does not exists any env value. - for you can change the EnvirommentVariable for prompt before cmd start - this patch are not 100% right, if it does not exists a PROMPT value cmd should use - $P$G as defualt not set EnvirommentVariable PROMPT to $P$G if it does not exists */ - if (GetEnvironmentVariable(_T("PROMPT"),lpBuffer, sizeof(lpBuffer) / sizeof(lpBuffer[0])) == 0) - SetEnvironmentVariable (_T("PROMPT"), _T("$P$G")); + /* Initialize prompt support */ + InitPrompt(); #ifdef FEATURE_DIR_STACK - /* initialize directory stack */ - InitDirectoryStack (); + /* initialize directory stack */ + InitDirectoryStack(); #endif #ifdef FEATURE_HISTORY - /*initialize history*/ - InitHistory(); + /*initialize history*/ + InitHistory(); #endif - /* Set COMSPEC environment variable */ - if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1)) - { - ModuleName[_MAX_PATH] = _T('\0'); - SetEnvironmentVariable (_T("COMSPEC"), ModuleName); - } + /* Set COMSPEC environment variable */ + if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1)) + { + ModuleName[_MAX_PATH] = _T('\0'); + SetEnvironmentVariable (_T("COMSPEC"), ModuleName); + } - /* add ctrl break handler */ - AddBreakHandler (); + /* Add ctrl break handler */ + AddBreakHandler(); + /* Set our default console mode */ + SetConsoleMode(hOut, 0); // Reinitialize the console output mode + SetConsoleMode(hOut, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); + SetConsoleMode(hIn , ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); - SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT); + cmdLine = GetCommandLine(); + TRACE ("[command args: %s]\n", debugstr_aw(cmdLine)); - cmdLine = GetCommandLine(); - TRACE ("[command args: %s]\n", debugstr_aw(cmdLine)); - - for (ptr = cmdLine; *ptr; ptr++) - { - if (*ptr == _T('/')) - { - option = _totupper(ptr[1]); - if (option == _T('?')) - { - ConOutResPaging(TRUE,STRING_CMD_HELP8); - nErrorLevel = 1; - bExit = TRUE; - return; - } - else if (option == _T('P')) - { - if (!IsExistingFile (_T("\\autoexec.bat"))) - { + for (ptr = cmdLine; *ptr; ptr++) + { + if (*ptr == _T('/')) + { + option = _totupper(ptr[1]); + if (option == _T('?')) + { + ConOutResPaging(TRUE,STRING_CMD_HELP8); + nErrorLevel = 1; + bExit = TRUE; + return; + } + else if (option == _T('P')) + { + if (!IsExistingFile (_T("\\autoexec.bat"))) + { #ifdef INCLUDE_CMD_DATE - cmd_date (_T("")); + cmd_date (_T("")); #endif #ifdef INCLUDE_CMD_TIME - cmd_time (_T("")); + cmd_time (_T("")); #endif - } - else - { - ParseCommandLine (_T("\\autoexec.bat")); - } - bCanExit = FALSE; - } - else if (option == _T('A')) - { - bUnicodeOutput = FALSE; - } - else if (option == _T('C') || option == _T('K') || option == _T('R')) - { - /* Remainder of command line is a command to be run */ - break; - } - else if (option == _T('D')) - { - AutoRun = FALSE; - } - else if (option == _T('Q')) - { - bDisableBatchEcho = TRUE; - } - else if (option == _T('S')) - { - AlwaysStrip = TRUE; - } + } + else + { + ParseCommandLine (_T("\\autoexec.bat")); + } + bCanExit = FALSE; + } + else if (option == _T('A')) + { + bUnicodeOutput = FALSE; + } + else if (option == _T('C') || option == _T('K') || option == _T('R')) + { + /* Remainder of command line is a command to be run */ + break; + } + else if (option == _T('D')) + { + AutoRun = FALSE; + } + else if (option == _T('Q')) + { + bDisableBatchEcho = TRUE; + } + else if (option == _T('S')) + { + AlwaysStrip = TRUE; + } #ifdef INCLUDE_CMD_COLOR - else if (!_tcsnicmp(ptr, _T("/T:"), 3)) - { - /* process /T (color) argument */ - wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16); - SetScreenColor(wDefColor, FALSE); - } + else if (!_tcsnicmp(ptr, _T("/T:"), 3)) + { + /* process /T (color) argument */ + wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16); + SetScreenColor(wDefColor, FALSE); + } #endif - else if (option == _T('U')) - { - bUnicodeOutput = TRUE; - } - else if (option == _T('V')) - { - bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4); - } - } - } + else if (option == _T('U')) + { + bUnicodeOutput = TRUE; + } + else if (option == _T('V')) + { + bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4); + } + } + } - if (!*ptr) - { - /* If neither /C or /K was given, display a simple version string */ - ConOutResPrintf(STRING_REACTOS_VERSION, - _T(KERNEL_RELEASE_STR), - _T(KERNEL_VERSION_BUILD_STR)); - ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n")); - } + if (!*ptr) + { + /* If neither /C or /K was given, display a simple version string */ + ConOutChar(_T('\n')); + ConOutResPrintf(STRING_REACTOS_VERSION, + _T(KERNEL_RELEASE_STR), + _T(KERNEL_VERSION_BUILD_STR)); + ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n")); + } - if (AutoRun) - { - ExecuteAutoRunFile(HKEY_LOCAL_MACHINE); - ExecuteAutoRunFile(HKEY_CURRENT_USER); - } + if (AutoRun) + { + ExecuteAutoRunFile(HKEY_LOCAL_MACHINE); + ExecuteAutoRunFile(HKEY_CURRENT_USER); + } - if (*ptr) - { - /* Do the /C or /K command */ - GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip); - nExitCode = ParseCommandLine(commandline); - if (option != _T('K')) - { - nErrorLevel = nExitCode; - bExit = TRUE; - } - } + if (*ptr) + { + /* Do the /C or /K command */ + GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip); + nExitCode = ParseCommandLine(commandline); + if (option != _T('K')) + { + nErrorLevel = nExitCode; + bExit = TRUE; + } + } } static VOID Cleanup() { - /* run cmdexit.bat */ - if (IsExistingFile (_T("cmdexit.bat"))) - { - ConErrResPuts(STRING_CMD_ERROR5); + /* run cmdexit.bat */ + if (IsExistingFile (_T("cmdexit.bat"))) + { + ConErrResPuts(STRING_CMD_ERROR5); - ParseCommandLine (_T("cmdexit.bat")); - } - else if (IsExistingFile (_T("\\cmdexit.bat"))) - { - ConErrResPuts (STRING_CMD_ERROR5); - ParseCommandLine (_T("\\cmdexit.bat")); - } + ParseCommandLine (_T("cmdexit.bat")); + } + else if (IsExistingFile (_T("\\cmdexit.bat"))) + { + ConErrResPuts (STRING_CMD_ERROR5); + ParseCommandLine (_T("\\cmdexit.bat")); + } #ifdef FEATURE_DIECTORY_STACK - /* destroy directory stack */ - DestroyDirectoryStack (); + /* destroy directory stack */ + DestroyDirectoryStack (); #endif #ifdef FEATURE_HISTORY - CleanHistory(); + CleanHistory(); #endif - /* free GetEnvVar's buffer */ - GetEnvVar(NULL); + /* free GetEnvVar's buffer */ + GetEnvVar(NULL); - /* remove ctrl break handler */ - RemoveBreakHandler (); - SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ), - ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT ); - DeleteCriticalSection(&ChildProcessRunningLock); + /* Remove ctrl break handler */ + RemoveBreakHandler(); + + /* Restore the default console mode */ + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), + ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); + SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), + ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); + + DeleteCriticalSection(&ChildProcessRunningLock); } /* @@ -1817,51 +1816,51 @@ static VOID Cleanup() */ int _tmain(int argc, const TCHAR *argv[]) { - HANDLE hConsole; - TCHAR startPath[MAX_PATH]; - CONSOLE_SCREEN_BUFFER_INFO Info; + HANDLE hConsole; + TCHAR startPath[MAX_PATH]; + CONSOLE_SCREEN_BUFFER_INFO Info; - InitializeCriticalSection(&ChildProcessRunningLock); - lpOriginalEnvironment = DuplicateEnvironment(); + InitializeCriticalSection(&ChildProcessRunningLock); + lpOriginalEnvironment = DuplicateEnvironment(); - GetCurrentDirectory(MAX_PATH,startPath); - _tchdir(startPath); + GetCurrentDirectory(MAX_PATH,startPath); + _tchdir(startPath); - SetFileApisToOEM(); - InputCodePage = 0; - OutputCodePage = 0; + SetFileApisToOEM(); + InputCodePage = 0; + OutputCodePage = 0; - hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, 0, NULL); - if (hConsole != INVALID_HANDLE_VALUE) - { - if (!GetConsoleScreenBufferInfo(hConsole, &Info)) - { - ConErrFormatMessage(GetLastError()); - return(1); - } - wDefColor = Info.wAttributes; - CloseHandle(hConsole); - } + hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + if (hConsole != INVALID_HANDLE_VALUE) + { + if (!GetConsoleScreenBufferInfo(hConsole, &Info)) + { + ConErrFormatMessage(GetLastError()); + return(1); + } + wDefColor = Info.wAttributes; + CloseHandle(hConsole); + } - InputCodePage = GetConsoleCP(); - OutputCodePage = GetConsoleOutputCP(); - CMD_ModuleHandle = GetModuleHandle(NULL); + InputCodePage = GetConsoleCP(); + OutputCodePage = GetConsoleOutputCP(); + CMD_ModuleHandle = GetModuleHandle(NULL); - /* check switches on command-line */ - Initialize(); + /* check switches on command-line */ + Initialize(); - /* call prompt routine */ - ProcessInput(); + /* call prompt routine */ + ProcessInput(); - /* do the cleanup */ - Cleanup(); + /* do the cleanup */ + Cleanup(); - cmd_free(lpOriginalEnvironment); + cmd_free(lpOriginalEnvironment); - cmd_exit(nErrorLevel); - return(nErrorLevel); + cmd_exit(nErrorLevel); + return(nErrorLevel); } /* EOF */ diff --git a/base/shell/cmd/cmd.h b/base/shell/cmd/cmd.h index 014b399d105..a39950bf431 100644 --- a/base/shell/cmd/cmd.h +++ b/base/shell/cmd/cmd.h @@ -129,12 +129,12 @@ BOOL ReadCommand (LPTSTR, INT); typedef struct tagCOMMAND { - LPTSTR name; - INT flags; - INT (*func)(LPTSTR); + LPTSTR name; + INT flags; + INT (*func)(LPTSTR); } COMMAND, *LPCOMMAND; -extern COMMAND cmds[]; /* The internal command table */ +extern COMMAND cmds[]; /* The internal command table */ VOID PrintCommandList (VOID); VOID PrintCommandListDetail (VOID); @@ -366,33 +366,33 @@ INT CommandMsgbox (LPTSTR); enum { C_COMMAND, C_QUIET, C_BLOCK, C_MULTI, C_IFFAILURE, C_IFSUCCESS, C_PIPE, C_IF, C_FOR }; typedef struct _PARSED_COMMAND { - struct _PARSED_COMMAND *Subcommands; - struct _PARSED_COMMAND *Next; - struct _REDIRECTION *Redirections; - BYTE Type; - union - { - struct - { - TCHAR *Rest; - TCHAR First[]; - } Command; - struct - { - BYTE Flags; - BYTE Operator; - TCHAR *LeftArg; - TCHAR *RightArg; - } If; - struct - { - BYTE Switches; - TCHAR Variable; - LPTSTR Params; - LPTSTR List; - struct tagFORCONTEXT *Context; - } For; - }; + struct _PARSED_COMMAND *Subcommands; + struct _PARSED_COMMAND *Next; + struct _REDIRECTION *Redirections; + BYTE Type; + union + { + struct + { + TCHAR *Rest; + TCHAR First[]; + } Command; + struct + { + BYTE Flags; + BYTE Operator; + TCHAR *LeftArg; + TCHAR *RightArg; + } If; + struct + { + BYTE Switches; + TCHAR Variable; + LPTSTR Params; + LPTSTR List; + struct tagFORCONTEXT *Context; + } For; + }; } PARSED_COMMAND; PARSED_COMMAND *ParseCommand(LPTSTR Line); VOID EchoCommand(PARSED_COMMAND *Cmd); @@ -405,6 +405,7 @@ INT cmd_path (LPTSTR); /* Prototypes from PROMPT.C */ +VOID InitPrompt (VOID); VOID PrintPrompt (VOID); INT cmd_prompt (LPTSTR); @@ -412,17 +413,17 @@ INT cmd_prompt (LPTSTR); /* Prototypes for REDIR.C */ typedef enum _REDIR_MODE { - REDIR_READ = 0, - REDIR_WRITE = 1, - REDIR_APPEND = 2 + REDIR_READ = 0, + REDIR_WRITE = 1, + REDIR_APPEND = 2 } REDIR_MODE; typedef struct _REDIRECTION { - struct _REDIRECTION *Next; - HANDLE OldHandle; - BYTE Number; - REDIR_MODE Mode; - TCHAR Filename[]; + struct _REDIRECTION *Next; + HANDLE OldHandle; + BYTE Number; + REDIR_MODE Mode; + TCHAR Filename[]; } REDIRECTION; BOOL PerformRedirection(REDIRECTION *); VOID UndoRedirection(REDIRECTION *, REDIRECTION *End); diff --git a/base/shell/cmd/cmd.rc b/base/shell/cmd/cmd.rc index cbc10e09fef..802390ee497 100644 --- a/base/shell/cmd/cmd.rc +++ b/base/shell/cmd/cmd.rc @@ -3,28 +3,28 @@ #include "resource.h" #include "cmdver.h" -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Command Processor\0" -#define REACTOS_STR_INTERNAL_NAME "cmd\0" -#define REACTOS_STR_ORIGINAL_FILENAME "cmd.exe\0" -#define REACTOS_STR_ORIGINAL_COPYRIGHT "Copyright (C) 1994-1998 Tim Norman and others\0" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Command Processor\0" +#define REACTOS_STR_INTERNAL_NAME "cmd\0" +#define REACTOS_STR_ORIGINAL_FILENAME "cmd.exe\0" +#define REACTOS_STR_ORIGINAL_COPYRIGHT "Copyright (C) 1994-1998 Tim Norman and others\0" #define REACTOS_STR_LEGAL_COPYRIGHT "Copyright (C) 1998-2006 Eric Kohl and others\0" #include STRINGTABLE DISCARDABLE BEGIN - STRING_FREEDOS_DEV, " Tim Norman Matt Rains\n\ - Evan Jeffrey Steffen Kaiser\n\ - Svante Frey Oliver Mueller\n\ - Aaron Kaufman Marc Desrochers\n\ - Rob Lake John P Price\n\ - Hans B Pufal\n" + STRING_FREEDOS_DEV, " Tim Norman Matt Rains\n\ + Evan Jeffrey Steffen Kaiser\n\ + Svante Frey Oliver Mueller\n\ + Aaron Kaufman Marc Desrochers\n\ + Rob Lake John P Price\n\ + Hans B Pufal\n" - STRING_REACTOS_DEV, " Eric Kohl Emanuele Aliberti\n\ - Paolo Pantaleo Phillip Susi\n\ - Sylvain Petreolle\n" + STRING_REACTOS_DEV, " Eric Kohl Emanuele Aliberti\n\ + Paolo Pantaleo Phillip Susi\n\ + Sylvain Petreolle\n" END -1 ICON DISCARDABLE res/terminal.ico +1 ICON DISCARDABLE res/terminal.ico #include "rsrc.rc" diff --git a/base/shell/cmd/cmdinput.c b/base/shell/cmd/cmdinput.c index 6edfd2dc25e..c904717f4e5 100644 --- a/base/shell/cmd/cmdinput.c +++ b/base/shell/cmd/cmdinput.c @@ -112,503 +112,491 @@ static BOOL bInsert = TRUE; static VOID -ClearCommandLine (LPTSTR str, INT maxlen, SHORT orgx, SHORT orgy) +ClearCommandLine(LPTSTR str, INT maxlen, SHORT orgx, SHORT orgy) { - INT count; + INT count; - SetCursorXY (orgx, orgy); - for (count = 0; count < (INT)_tcslen (str); count++) - ConOutChar (_T(' ')); - _tcsnset (str, _T('\0'), maxlen); - SetCursorXY (orgx, orgy); + SetCursorXY (orgx, orgy); + for (count = 0; count < (INT)_tcslen (str); count++) + ConOutChar (_T(' ')); + _tcsnset (str, _T('\0'), maxlen); + SetCursorXY (orgx, orgy); } /* read in a command line */ -BOOL ReadCommand (LPTSTR str, INT maxlen) +BOOL ReadCommand(LPTSTR str, INT maxlen) { - CONSOLE_SCREEN_BUFFER_INFO csbi; - SHORT orgx; /* origin x/y */ - SHORT orgy; - SHORT curx; /*current x/y cursor position*/ - SHORT cury; - SHORT tempscreen; - INT count; /*used in some for loops*/ - INT current = 0; /*the position of the cursor in the string (str)*/ - INT charcount = 0;/*chars in the string (str)*/ - INPUT_RECORD ir; + CONSOLE_SCREEN_BUFFER_INFO csbi; + SHORT orgx; /* origin x/y */ + SHORT orgy; + SHORT curx; /*current x/y cursor position*/ + SHORT cury; + SHORT tempscreen; + INT count; /*used in some for loops*/ + INT current = 0; /*the position of the cursor in the string (str)*/ + INT charcount = 0;/*chars in the string (str)*/ + INPUT_RECORD ir; #ifdef FEATURE_UNIX_FILENAME_COMPLETION - WORD wLastKey = 0; + WORD wLastKey = 0; #endif - TCHAR ch; - BOOL bReturn = FALSE; - BOOL bCharInput; + TCHAR ch; + BOOL bReturn = FALSE; + BOOL bCharInput; #ifdef FEATURE_4NT_FILENAME_COMPLETION - TCHAR szPath[MAX_PATH]; + TCHAR szPath[MAX_PATH]; #endif #ifdef FEATURE_HISTORY - //BOOL bContinue=FALSE;/*is TRUE the second case will not be executed*/ - TCHAR PreviousChar; + //BOOL bContinue=FALSE;/*is TRUE the second case will not be executed*/ + TCHAR PreviousChar; #endif - if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) - { - /* No console */ - HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); - DWORD dwRead; - CHAR chr; - do - { - if (!ReadFile(hStdin, &chr, 1, &dwRead, NULL) || !dwRead) - return FALSE; + if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + { + /* No console */ + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD dwRead; + CHAR chr; + do + { + if (!ReadFile(hStdin, &chr, 1, &dwRead, NULL) || !dwRead) + return FALSE; #ifdef _UNICODE - MultiByteToWideChar(InputCodePage, 0, &chr, 1, &str[charcount++], 1); + MultiByteToWideChar(InputCodePage, 0, &chr, 1, &str[charcount++], 1); #endif - } while (chr != '\n' && charcount < maxlen); - str[charcount] = _T('\0'); - return TRUE; - } + } while (chr != '\n' && charcount < maxlen); + str[charcount] = _T('\0'); + return TRUE; + } - /* get screen size */ - maxx = csbi.dwSize.X; - maxy = csbi.dwSize.Y; + /* get screen size */ + maxx = csbi.dwSize.X; + maxy = csbi.dwSize.Y; - curx = orgx = csbi.dwCursorPosition.X; - cury = orgy = csbi.dwCursorPosition.Y; + curx = orgx = csbi.dwCursorPosition.X; + cury = orgy = csbi.dwCursorPosition.Y; - memset (str, 0, maxlen * sizeof (TCHAR)); + memset (str, 0, maxlen * sizeof (TCHAR)); - SetCursorType (bInsert, TRUE); + SetCursorType (bInsert, TRUE); - do - { - - bReturn = FALSE; - - ConInKey (&ir); - - if (ir.Event.KeyEvent.dwControlKeyState & - (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED| - RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) ) - { - - switch (ir.Event.KeyEvent.wVirtualKeyCode) - { + do + { + bReturn = FALSE; + ConInKey (&ir); + if (ir.Event.KeyEvent.dwControlKeyState & + (RIGHT_ALT_PRESSED |LEFT_ALT_PRESSED| + RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) ) + { + switch (ir.Event.KeyEvent.wVirtualKeyCode) + { #ifdef FEATURE_HISTORY + case 'K': + /*add the current command line to the history*/ + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + if (str[0]) + History(0,str); - case 'K': - /*add the current command line to the history*/ - if (ir.Event.KeyEvent.dwControlKeyState & - (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) - { + ClearCommandLine (str, maxlen, orgx, orgy); + current = charcount = 0; + curx = orgx; + cury = orgy; + //bContinue=TRUE; + break; + } - if (str[0]) - History(0,str); + case 'D': + /*delete current history entry*/ + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + ClearCommandLine (str, maxlen, orgx, orgy); + History_del_current_entry(str); + current = charcount = _tcslen (str); + ConOutPrintf (_T("%s"), str); + GetCursorXY (&curx, &cury); + //bContinue=TRUE; + break; + } - ClearCommandLine (str, maxlen, orgx, orgy); - current = charcount = 0; - curx = orgx; - cury = orgy; - //bContinue=TRUE; - break; - } +#endif /*FEATURE_HISTORY*/ + } + } - case 'D': - /*delete current history entry*/ - if (ir.Event.KeyEvent.dwControlKeyState & - (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) - { - ClearCommandLine (str, maxlen, orgx, orgy); - History_del_current_entry(str); - current = charcount = _tcslen (str); - ConOutPrintf (_T("%s"), str); - GetCursorXY (&curx, &cury); - //bContinue=TRUE; - break; - } + bCharInput = FALSE; -#endif/*FEATURE_HISTORY*/ - } + switch (ir.Event.KeyEvent.wVirtualKeyCode) + { + case VK_BACK: + /* - delete character to left of cursor */ + if (current > 0 && charcount > 0) + { + if (current == charcount) + { + /* if at end of line */ + str[current - 1] = _T('\0'); + if (GetCursorX () != 0) + { + ConOutPrintf (_T("\b \b")); + curx--; + } + else + { + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + ConOutChar (_T(' ')); + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + cury--; + curx = maxx - 1; + } + } + else + { + for (count = current - 1; count < charcount; count++) + str[count] = str[count + 1]; + if (GetCursorX () != 0) + { + SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ()); + curx--; + } + else + { + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + cury--; + curx = maxx - 1; + } + GetCursorXY (&curx, &cury); + ConOutPrintf (_T("%s "), &str[current - 1]); + SetCursorXY (curx, cury); + } + charcount--; + current--; + } + break; + case VK_INSERT: + /* toggle insert/overstrike mode */ + bInsert ^= TRUE; + SetCursorType (bInsert, TRUE); + break; + case VK_DELETE: + /* delete character under cursor */ + if (current != charcount && charcount > 0) + { + for (count = current; count < charcount; count++) + str[count] = str[count + 1]; + charcount--; + GetCursorXY (&curx, &cury); + ConOutPrintf (_T("%s "), &str[current]); + SetCursorXY (curx, cury); + } + break; + case VK_HOME: + /* goto beginning of string */ + if (current != 0) + { + SetCursorXY (orgx, orgy); + curx = orgx; + cury = orgy; + current = 0; + } + break; - } + case VK_END: + /* goto end of string */ + if (current != charcount) + { + SetCursorXY (orgx, orgy); + ConOutPrintf (_T("%s"), str); + GetCursorXY (&curx, &cury); + current = charcount; + } + break; - bCharInput = FALSE; - - switch (ir.Event.KeyEvent.wVirtualKeyCode) - { - case VK_BACK: - /* - delete character to left of cursor */ - if (current > 0 && charcount > 0) - { - if (current == charcount) - { - /* if at end of line */ - str[current - 1] = _T('\0'); - if (GetCursorX () != 0) - { - ConOutPrintf (_T("\b \b")); - curx--; - } - else - { - SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); - ConOutChar (_T(' ')); - SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); - cury--; - curx = maxx - 1; - } - } - else - { - for (count = current - 1; count < charcount; count++) - str[count] = str[count + 1]; - if (GetCursorX () != 0) - { - SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ()); - curx--; - } - else - { - SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); - cury--; - curx = maxx - 1; - } - GetCursorXY (&curx, &cury); - ConOutPrintf (_T("%s "), &str[current - 1]); - SetCursorXY (curx, cury); - } - charcount--; - current--; - } - break; - - case VK_INSERT: - /* toggle insert/overstrike mode */ - bInsert ^= TRUE; - SetCursorType (bInsert, TRUE); - break; - - case VK_DELETE: - /* delete character under cursor */ - if (current != charcount && charcount > 0) - { - for (count = current; count < charcount; count++) - str[count] = str[count + 1]; - charcount--; - GetCursorXY (&curx, &cury); - ConOutPrintf (_T("%s "), &str[current]); - SetCursorXY (curx, cury); - } - break; - - case VK_HOME: - /* goto beginning of string */ - if (current != 0) - { - SetCursorXY (orgx, orgy); - curx = orgx; - cury = orgy; - current = 0; - } - break; - - case VK_END: - /* goto end of string */ - if (current != charcount) - { - SetCursorXY (orgx, orgy); - ConOutPrintf (_T("%s"), str); - GetCursorXY (&curx, &cury); - current = charcount; - } - break; - - case VK_TAB: + case VK_TAB: #ifdef FEATURE_UNIX_FILENAME_COMPLETION - /* expand current file name */ - if ((current == charcount) || - (current == charcount - 1 && - str[current] == _T('"'))) /* only works at end of line*/ - { - if (wLastKey != VK_TAB) - { - /* if first TAB, complete filename*/ - tempscreen = charcount; - CompleteFilename (str, charcount); - charcount = _tcslen (str); - current = charcount; + /* expand current file name */ + if ((current == charcount) || + (current == charcount - 1 && + str[current] == _T('"'))) /* only works at end of line*/ + { + if (wLastKey != VK_TAB) + { + /* if first TAB, complete filename*/ + tempscreen = charcount; + CompleteFilename (str, charcount); + charcount = _tcslen (str); + current = charcount; - SetCursorXY (orgx, orgy); - ConOutPrintf (_T("%s"), str); + SetCursorXY (orgx, orgy); + ConOutPrintf (_T("%s"), str); - if (tempscreen > charcount) - { - GetCursorXY (&curx, &cury); - for (count = tempscreen - charcount; count--; ) - ConOutChar (_T(' ')); - SetCursorXY (curx, cury); - } - else - { - if (((charcount + orgx) / maxx) + orgy > maxy - 1) - orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); - } + if (tempscreen > charcount) + { + GetCursorXY (&curx, &cury); + for (count = tempscreen - charcount; count--; ) + ConOutChar (_T(' ')); + SetCursorXY (curx, cury); + } + else + { + if (((charcount + orgx) / maxx) + orgy > maxy - 1) + orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); + } - /* set cursor position */ - SetCursorXY ((orgx + current) % maxx, - orgy + (orgx + current) / maxx); - GetCursorXY (&curx, &cury); - } - else - { - /*if second TAB, list matches*/ - if (ShowCompletionMatches (str, charcount)) - { - PrintPrompt (); - GetCursorXY (&orgx, &orgy); - ConOutPrintf (_T("%s"), str); + /* set cursor position */ + SetCursorXY ((orgx + current) % maxx, + orgy + (orgx + current) / maxx); + GetCursorXY (&curx, &cury); + } + else + { + /*if second TAB, list matches*/ + if (ShowCompletionMatches (str, charcount)) + { + PrintPrompt(); + GetCursorXY(&orgx, &orgy); + ConOutPrintf(_T("%s"), str); - /* set cursor position */ - SetCursorXY ((orgx + current) % maxx, - orgy + (orgx + current) / maxx); - GetCursorXY (&curx, &cury); - } + /* set cursor position */ + SetCursorXY((orgx + current) % maxx, + orgy + (orgx + current) / maxx); + GetCursorXY(&curx, &cury); + } - } - } - else - { - MessageBeep (-1); - } + } + } + else + { + MessageBeep(-1); + } #endif #ifdef FEATURE_4NT_FILENAME_COMPLETION + /* used to later see if we went down to the next line */ + tempscreen = charcount; + szPath[0]=_T('\0'); - /* used to later see if we went down to the next line */ - tempscreen = charcount; - szPath[0]=_T('\0'); + /* str is the whole things that is on the current line + that is and and out. arg 2 is weather it goes back + one file or forward one file */ + CompleteFilename(str, !(ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED), szPath, current); + /* Attempt to clear the line */ + ClearCommandLine (str, maxlen, orgx, orgy); + curx = orgx; + cury = orgy; + current = charcount = 0; - /* str is the whole things that is on the current line - that is and and out. arg 2 is weather it goes back - one file or forward one file */ - CompleteFilename(str, !(ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED), szPath, current); - /* Attempt to clear the line */ - ClearCommandLine (str, maxlen, orgx, orgy); - curx = orgx; - cury = orgy; - current = charcount = 0; + /* Everything is deleted, lets add it back in */ + _tcscpy(str,szPath); - /* Everything is deleted, lets add it back in */ - _tcscpy(str,szPath); + /* Figure out where cusor is going to be after we print it */ + charcount = _tcslen(str); + current = charcount; - /* Figure out where cusor is going to be after we print it */ - charcount = _tcslen (str); - current = charcount; - - SetCursorXY (orgx, orgy); - /* Print out what we have now */ - ConOutPrintf (_T("%s"), str); - - /* Move cursor accordingly */ - if(tempscreen > charcount) - { - GetCursorXY (&curx, &cury); - for(count = tempscreen - charcount; count--; ) - ConOutChar (_T(' ')); - SetCursorXY (curx, cury); - } - else - { - if(((charcount + orgx) / maxx) + orgy > maxy - 1) - orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); - } - SetCursorXY((short)(((int)orgx + current) % maxx), (short)((int)orgy + ((int)orgx + current) / maxx)); - GetCursorXY(&curx, &cury); + SetCursorXY(orgx, orgy); + /* Print out what we have now */ + ConOutPrintf(_T("%s"), str); + /* Move cursor accordingly */ + if (tempscreen > charcount) + { + GetCursorXY(&curx, &cury); + for(count = tempscreen - charcount; count--; ) + ConOutChar(_T(' ')); + SetCursorXY(curx, cury); + } + else + { + if (((charcount + orgx) / maxx) + orgy > maxy - 1) + orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); + } + SetCursorXY((short)(((int)orgx + current) % maxx), (short)((int)orgy + ((int)orgx + current) / maxx)); + GetCursorXY(&curx, &cury); #endif - break; + break; - case _T('M'): - case _T('C'): - /* ^M does the same as return */ - bCharInput = TRUE; - if(!(ir.Event.KeyEvent.dwControlKeyState & - (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))) - { - break; - } + case _T('M'): + case _T('C'): + /* ^M does the same as return */ + bCharInput = TRUE; + if (!(ir.Event.KeyEvent.dwControlKeyState & + (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED))) + { + break; + } - case VK_RETURN: - /* end input, return to main */ + case VK_RETURN: + /* end input, return to main */ #ifdef FEATURE_HISTORY - /* add to the history */ - if (str[0]) - History (0, str); + /* add to the history */ + if (str[0]) + History (0, str); #endif - str[charcount++] = _T('\n'); - str[charcount] = _T('\0'); - ConOutChar (_T('\n')); - bReturn = TRUE; - break; + str[charcount++] = _T('\n'); + str[charcount] = _T('\0'); + ConOutChar(_T('\n')); + bReturn = TRUE; + break; - case VK_ESCAPE: - /* clear str Make this callable! */ - ClearCommandLine (str, maxlen, orgx, orgy); - curx = orgx; - cury = orgy; - current = charcount = 0; - break; + case VK_ESCAPE: + /* clear str Make this callable! */ + ClearCommandLine (str, maxlen, orgx, orgy); + curx = orgx; + cury = orgy; + current = charcount = 0; + break; #ifdef FEATURE_HISTORY - case VK_F3: - History_move_to_bottom(); + case VK_F3: + History_move_to_bottom(); #endif - case VK_UP: + case VK_UP: #ifdef FEATURE_HISTORY - /* get previous command from buffer */ - ClearCommandLine (str, maxlen, orgx, orgy); - History (-1, str); - current = charcount = _tcslen (str); - if (((charcount + orgx) / maxx) + orgy > maxy - 1) - orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); - ConOutPrintf (_T("%s"), str); - GetCursorXY (&curx, &cury); + /* get previous command from buffer */ + ClearCommandLine (str, maxlen, orgx, orgy); + History (-1, str); + current = charcount = _tcslen (str); + if (((charcount + orgx) / maxx) + orgy > maxy - 1) + orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); + ConOutPrintf (_T("%s"), str); + GetCursorXY (&curx, &cury); #endif - break; + break; - case VK_DOWN: + case VK_DOWN: #ifdef FEATURE_HISTORY - /* get next command from buffer */ - ClearCommandLine (str, maxlen, orgx, orgy); - History (1, str); - current = charcount = _tcslen (str); - if (((charcount + orgx) / maxx) + orgy > maxy - 1) - orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); - ConOutPrintf (_T("%s"), str); - GetCursorXY (&curx, &cury); + /* get next command from buffer */ + ClearCommandLine (str, maxlen, orgx, orgy); + History (1, str); + current = charcount = _tcslen (str); + if (((charcount + orgx) / maxx) + orgy > maxy - 1) + orgy += maxy - ((charcount + orgx) / maxx + orgy + 1); + ConOutPrintf (_T("%s"), str); + GetCursorXY (&curx, &cury); #endif - break; + break; - case VK_LEFT: - /* move cursor left */ - if (current > 0) - { - current--; - if (GetCursorX () == 0) - { - SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); - curx = maxx - 1; - cury--; - } - else - { - SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ()); - curx--; - } - } - else - { - MessageBeep (-1); - } - break; + case VK_LEFT: + /* move cursor left */ + if (current > 0) + { + current--; + if (GetCursorX () == 0) + { + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + curx = maxx - 1; + cury--; + } + else + { + SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ()); + curx--; + } + } + else + { + MessageBeep (-1); + } + break; - case VK_RIGHT: - /* move cursor right */ - if (current != charcount) - { - current++; - if (GetCursorX () == maxx - 1) - { - SetCursorXY (0, (SHORT)(GetCursorY () + 1)); - curx = 0; - cury++; - } - else - { - SetCursorXY ((SHORT)(GetCursorX () + 1), GetCursorY ()); - curx++; - } - } + case VK_RIGHT: + /* move cursor right */ + if (current != charcount) + { + current++; + if (GetCursorX () == maxx - 1) + { + SetCursorXY (0, (SHORT)(GetCursorY () + 1)); + curx = 0; + cury++; + } + else + { + SetCursorXY ((SHORT)(GetCursorX () + 1), GetCursorY ()); + curx++; + } + } #ifdef FEATURE_HISTORY - else - { - LPCTSTR last = PeekHistory(-1); - if (last && charcount < (INT)_tcslen (last)) - { - PreviousChar = last[current]; - ConOutChar(PreviousChar); - GetCursorXY(&curx, &cury); - str[current++] = PreviousChar; - charcount++; - } - } + else + { + LPCTSTR last = PeekHistory(-1); + if (last && charcount < (INT)_tcslen (last)) + { + PreviousChar = last[current]; + ConOutChar(PreviousChar); + GetCursorXY(&curx, &cury); + str[current++] = PreviousChar; + charcount++; + } + } #endif - break; + break; - default: - /* This input is just a normal char */ - bCharInput = TRUE; + default: + /* This input is just a normal char */ + bCharInput = TRUE; - } + } #ifdef _UNICODE - ch = ir.Event.KeyEvent.uChar.UnicodeChar; - if (ch >= 32 && (charcount != (maxlen - 2)) && bCharInput) + ch = ir.Event.KeyEvent.uChar.UnicodeChar; + if (ch >= 32 && (charcount != (maxlen - 2)) && bCharInput) #else - ch = ir.Event.KeyEvent.uChar.AsciiChar; - if ((UCHAR)ch >= 32 && (charcount != (maxlen - 2)) && bCharInput) + ch = ir.Event.KeyEvent.uChar.AsciiChar; + if ((UCHAR)ch >= 32 && (charcount != (maxlen - 2)) && bCharInput) #endif /* _UNICODE */ - { - /* insert character into string... */ - if (bInsert && current != charcount) - { - /* If this character insertion will cause screen scrolling, - * adjust the saved origin of the command prompt. */ - tempscreen = _tcslen(str + current) + curx; - if ((tempscreen % maxx) == (maxx - 1) && - (tempscreen / maxx) + cury == (maxy - 1)) - { - orgy--; - cury--; - } + { + /* insert character into string... */ + if (bInsert && current != charcount) + { + /* If this character insertion will cause screen scrolling, + * adjust the saved origin of the command prompt. */ + tempscreen = _tcslen(str + current) + curx; + if ((tempscreen % maxx) == (maxx - 1) && + (tempscreen / maxx) + cury == (maxy - 1)) + { + orgy--; + cury--; + } - for (count = charcount; count > current; count--) - str[count] = str[count - 1]; - str[current++] = ch; - if (curx == maxx - 1) - curx = 0, cury++; - else - curx++; - ConOutPrintf (_T("%s"), &str[current - 1]); - SetCursorXY (curx, cury); - charcount++; - } - else - { - if (current == charcount) - charcount++; - str[current++] = ch; - if (GetCursorX () == maxx - 1 && GetCursorY () == maxy - 1) - orgy--, cury--; - if (GetCursorX () == maxx - 1) - curx = 0, cury++; - else - curx++; - ConOutChar (ch); - } - } + for (count = charcount; count > current; count--) + str[count] = str[count - 1]; + str[current++] = ch; + if (curx == maxx - 1) + curx = 0, cury++; + else + curx++; + ConOutPrintf (_T("%s"), &str[current - 1]); + SetCursorXY (curx, cury); + charcount++; + } + else + { + if (current == charcount) + charcount++; + str[current++] = ch; + if (GetCursorX () == maxx - 1 && GetCursorY () == maxy - 1) + orgy--, cury--; + if (GetCursorX () == maxx - 1) + curx = 0, cury++; + else + curx++; + ConOutChar (ch); + } + } - //wLastKey = ir.Event.KeyEvent.wVirtualKeyCode; - } - while (!bReturn); + //wLastKey = ir.Event.KeyEvent.wVirtualKeyCode; + } + while (!bReturn); - SetCursorType (bInsert, TRUE); + SetCursorType (bInsert, TRUE); #ifdef FEATURE_ALIASES - /* expand all aliases */ - ExpandAlias (str, maxlen); + /* expand all aliases */ + ExpandAlias (str, maxlen); #endif /* FEATURE_ALIAS */ - return TRUE; + return TRUE; } diff --git a/base/shell/cmd/cmdtable.c b/base/shell/cmd/cmdtable.c index 6053958b8a3..bd0a0dca298 100644 --- a/base/shell/cmd/cmdtable.c +++ b/base/shell/cmd/cmdtable.c @@ -19,263 +19,265 @@ #include "precomp.h" -/* a list of all the internal commands, associating their command names */ -/* to the functions to process them */ +/* + * A list of all the internal commands, associating their command names + * to the functions to process them. + */ COMMAND cmds[] = { - {_T("?"), 0, CommandShowCommands}, + {_T("?"), 0, CommandShowCommands}, #ifdef INCLUDE_CMD_ACTIVATE - {_T("activate"), 0, CommandActivate}, + {_T("activate"), 0, CommandActivate}, #endif #ifdef FEATURE_ALIASES - {_T("alias"), 0, CommandAlias}, + {_T("alias"), 0, CommandAlias}, #endif #ifdef INCLUDE_CMD_ASSOC - {_T("assoc"), 0, CommandAssoc}, + {_T("assoc"), 0, CommandAssoc}, #endif #ifdef INCLUDE_CMD_ATTRIB - {_T("attrib"), 0, CommandAttrib}, + {_T("attrib"), 0, CommandAttrib}, #endif #ifdef INCLUDE_CMD_BEEP - {_T("beep"), 0, cmd_beep}, + {_T("beep"), 0, cmd_beep}, #endif - {_T("call"), CMD_BATCHONLY, cmd_call}, + {_T("call"), CMD_BATCHONLY, cmd_call}, #ifdef INCLUDE_CMD_CHDIR - {_T("cd"), CMD_SPECIAL, cmd_chdir}, - {_T("chdir"), CMD_SPECIAL, cmd_chdir}, + {_T("cd"), CMD_SPECIAL, cmd_chdir}, + {_T("chdir"), CMD_SPECIAL, cmd_chdir}, #endif #ifdef INCLUDE_CMD_CHCP - {_T("chcp"), 0, CommandChcp}, + {_T("chcp"), 0, CommandChcp}, #endif #ifdef INCLUDE_CMD_CHOICE - {_T("choice"), 0, CommandChoice}, + {_T("choice"), 0, CommandChoice}, #endif #ifdef INCLUDE_CMD_CLS - {_T("cls"), 0, cmd_cls}, + {_T("cls"), 0, cmd_cls}, #endif #ifdef INCLUDE_CMD_COLOR - {_T("color"), 0, CommandColor}, + {_T("color"), 0, CommandColor}, #endif #ifdef INCLUDE_CMD_COPY - {_T("copy"), 0, cmd_copy}, + {_T("copy"), 0, cmd_copy}, #endif #ifdef INCLUDE_CMD_DATE - {_T("date"), 0, cmd_date}, + {_T("date"), 0, cmd_date}, #endif #ifdef INCLUDE_CMD_DEL - {_T("del"), 0, CommandDelete}, - {_T("delete"), 0, CommandDelete}, + {_T("del"), 0, CommandDelete}, + {_T("delete"), 0, CommandDelete}, #endif #ifdef INCLUDE_CMD_DELAY - {_T("delay"), 0, CommandDelay}, + {_T("delay"), 0, CommandDelay}, #endif #ifdef INCLUDE_CMD_DIR - {_T("dir"), CMD_SPECIAL, CommandDir}, + {_T("dir"), CMD_SPECIAL, CommandDir}, #endif #ifdef FEATURE_DIRECTORY_STACK - {_T("dirs"), 0, CommandDirs}, + {_T("dirs"), 0, CommandDirs}, #endif - {_T("echo"), CMD_SPECIAL, CommandEcho}, - {_T("echos"), 0, CommandEchos}, - {_T("echoerr"), CMD_SPECIAL, CommandEchoerr}, - {_T("echoserr"), 0, CommandEchoserr}, + {_T("echo"), CMD_SPECIAL, CommandEcho}, + {_T("echos"), 0, CommandEchos}, + {_T("echoerr"), CMD_SPECIAL, CommandEchoerr}, + {_T("echoserr"), 0, CommandEchoserr}, - {_T("endlocal"), 0, cmd_endlocal}, + {_T("endlocal"), 0, cmd_endlocal}, #ifdef INCLUDE_CMD_DEL - {_T("erase"), 0, CommandDelete}, + {_T("erase"), 0, CommandDelete}, #endif - {_T("exit"), 0, CommandExit}, + {_T("exit"), 0, CommandExit}, - {_T("for"), 0, cmd_for}, + {_T("for"), 0, cmd_for}, #ifdef INCLUDE_CMD_FREE - {_T("free"), 0, CommandFree}, + {_T("free"), 0, CommandFree}, #endif - {_T("goto"), CMD_BATCHONLY, cmd_goto}, + {_T("goto"), CMD_BATCHONLY, cmd_goto}, - {_T("help"), 0, CommandShowCommandsDetail}, + {_T("help"), 0, CommandShowCommandsDetail}, #ifdef FEATURE_HISTORY - {_T("history"), 0, CommandHistory}, + {_T("history"), 0, CommandHistory}, #endif - {_T("if"), 0, cmd_if}, + {_T("if"), 0, cmd_if}, #ifdef INCLUDE_CMD_LABEL - {_T("label"), 0, cmd_label}, + {_T("label"), 0, cmd_label}, #endif #ifdef INCLUDE_CMD_MEMORY - {_T("memory"), 0, CommandMemory}, + {_T("memory"), 0, CommandMemory}, #endif #ifdef INCLUDE_CMD_MKDIR - {_T("md"), CMD_SPECIAL, cmd_mkdir}, - {_T("mkdir"), CMD_SPECIAL, cmd_mkdir}, + {_T("md"), CMD_SPECIAL, cmd_mkdir}, + {_T("mkdir"), CMD_SPECIAL, cmd_mkdir}, #endif #ifdef INCLUDE_CMD_MKLINK - {_T("mklink"), 0, cmd_mklink}, + {_T("mklink"), 0, cmd_mklink}, #endif #ifdef INCLUDE_CMD_MOVE - {_T("move"), 0, cmd_move}, + {_T("move"), 0, cmd_move}, #endif #ifdef INCLUDE_CMD_MSGBOX - {_T("msgbox"), 0, CommandMsgbox}, + {_T("msgbox"), 0, CommandMsgbox}, #endif #ifdef INCLUDE_CMD_PATH - {_T("path"), 0, cmd_path}, + {_T("path"), 0, cmd_path}, #endif #ifdef INCLUDE_CMD_PAUSE - {_T("pause"), 0, cmd_pause}, + {_T("pause"), 0, cmd_pause}, #endif #ifdef FEATURE_DIRECTORY_STACK - {_T("popd"), 0, CommandPopd}, + {_T("popd"), 0, CommandPopd}, #endif #ifdef INCLUDE_CMD_PROMPT - {_T("prompt"), 0, cmd_prompt}, + {_T("prompt"), 0, cmd_prompt}, #endif #ifdef FEATURE_DIRECTORY_STACK - {_T("pushd"), 0, CommandPushd}, + {_T("pushd"), 0, CommandPushd}, #endif #ifdef INCLUDE_CMD_RMDIR - {_T("rd"), CMD_SPECIAL, cmd_rmdir}, + {_T("rd"), CMD_SPECIAL, cmd_rmdir}, #endif #ifdef INCLUDE_CMD_REM - {_T("rem"), 0, CommandRem}, + {_T("rem"), 0, CommandRem}, #endif #ifdef INCLUDE_CMD_RENAME - {_T("ren"), 0, cmd_rename}, - {_T("rename"), 0, cmd_rename}, + {_T("ren"), 0, cmd_rename}, + {_T("rename"), 0, cmd_rename}, #endif #ifdef INCLUDE_CMD_REPLACE - {_T("replace"), 0, cmd_replace}, + {_T("replace"), 0, cmd_replace}, #endif #ifdef INCLUDE_CMD_RMDIR - {_T("rmdir"), CMD_SPECIAL, cmd_rmdir}, + {_T("rmdir"), CMD_SPECIAL, cmd_rmdir}, #endif #ifdef INCLUDE_CMD_SCREEN - {_T("screen"), 0, CommandScreen}, + {_T("screen"), 0, CommandScreen}, #endif #ifdef INCLUDE_CMD_SET - {_T("set"), 0, cmd_set}, + {_T("set"), 0, cmd_set}, #endif - {_T("setlocal"), 0, cmd_setlocal}, + {_T("setlocal"), 0, cmd_setlocal}, - {_T("shift"), CMD_BATCHONLY, cmd_shift}, + {_T("shift"), CMD_BATCHONLY, cmd_shift}, #ifdef INCLUDE_CMD_START - {_T("start"), 0, cmd_start}, + {_T("start"), 0, cmd_start}, #endif #ifdef INCLUDE_CMD_TIME - {_T("time"), 0, cmd_time}, + {_T("time"), 0, cmd_time}, #endif #ifdef INCLUDE_CMD_TIMER - {_T("timer"), 0, CommandTimer}, + {_T("timer"), 0, CommandTimer}, #endif #ifdef INCLUDE_CMD_TITLE - {_T("title"), 0, cmd_title}, + {_T("title"), 0, cmd_title}, #endif #ifdef INCLUDE_CMD_TYPE - {_T("type"), 0, cmd_type}, + {_T("type"), 0, cmd_type}, #endif #ifdef INCLUDE_CMD_VER - {_T("ver"), 0, cmd_ver}, + {_T("ver"), 0, cmd_ver}, #endif #ifdef INCLUDE_CMD_VERIFY - {_T("verify"), 0, cmd_verify}, + {_T("verify"), 0, cmd_verify}, #endif #ifdef INCLUDE_CMD_VOL - {_T("vol"), 0, cmd_vol}, + {_T("vol"), 0, cmd_vol}, #endif #ifdef INCLUDE_CMD_WINDOW - {_T("window"), 0, CommandWindow}, + {_T("window"), 0, CommandWindow}, #endif - {NULL, 0, NULL} + {NULL, 0, NULL} }; -VOID PrintCommandList (VOID) +VOID PrintCommandList(VOID) { - LPCOMMAND cmdptr; - INT y; + LPCOMMAND cmdptr; + INT y; - y = 0; - cmdptr = cmds; - while (cmdptr->name) - { - if (!(cmdptr->flags & CMD_HIDE)) - { - if (++y == 8) - { - ConOutPuts (cmdptr->name); - y = 0; - } - else - { - ConOutPrintf (_T("%-10s"), cmdptr->name); - } - } + y = 0; + cmdptr = cmds; + while (cmdptr->name) + { + if (!(cmdptr->flags & CMD_HIDE)) + { + if (++y == 8) + { + ConOutPuts(cmdptr->name); + y = 0; + } + else + { + ConOutPrintf (_T("%-10s"), cmdptr->name); + } + } - cmdptr++; - } + cmdptr++; + } - if (y != 0) - ConOutChar ('\n'); + if (y != 0) + ConOutChar(_T('\n')); } -VOID PrintCommandListDetail (VOID) +VOID PrintCommandListDetail(VOID) { - ConOutResPaging(TRUE,STRING_HELP1); - ConOutResPaging(FALSE,STRING_HELP2); + ConOutResPaging(TRUE , STRING_HELP1); + ConOutResPaging(FALSE, STRING_HELP2); } /* EOF */ diff --git a/base/shell/cmd/color.c b/base/shell/cmd/color.c index 4254255d9e7..cce61831aa7 100644 --- a/base/shell/cmd/color.c +++ b/base/shell/cmd/color.c @@ -16,8 +16,8 @@ * 14-Oct-1999 (Paolo Pantaleo ) * 4nt's syntax implemented. * - * 03-Apr-2005 (Magnus Olsen) ) - * Move all hardcoded strings to En.rc. + * 03-Apr-2005 (Magnus Olsen ) + * Move all hardcoded strings in En.rc. */ #include "precomp.h" @@ -26,32 +26,32 @@ BOOL SetScreenColor(WORD wColor, BOOL bNoFill) { - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD dwWritten; - CONSOLE_SCREEN_BUFFER_INFO csbi; - COORD coPos; + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD coPos; - /* Foreground and Background colors can't be the same */ - if ((wColor & 0x0F) == (wColor & 0xF0) >> 4) - return FALSE; + /* Foreground and Background colors can't be the same */ + if ((wColor & 0x0F) == (wColor & 0xF0) >> 4) + return FALSE; - /* Fill the whole background if needed */ - if (bNoFill != TRUE) - { - GetConsoleScreenBufferInfo(hConsole, &csbi); + /* Fill the whole background if needed */ + if (bNoFill != TRUE) + { + GetConsoleScreenBufferInfo(hConsole, &csbi); - coPos.X = 0; - coPos.Y = 0; - FillConsoleOutputAttribute(hConsole, - wColor & 0x00FF, - csbi.dwSize.X * csbi.dwSize.Y, - coPos, - &dwWritten); - } + coPos.X = 0; + coPos.Y = 0; + FillConsoleOutputAttribute(hConsole, + wColor & 0x00FF, + csbi.dwSize.X * csbi.dwSize.Y, + coPos, + &dwWritten); + } - /* Set the text attribute */ - SetConsoleTextAttribute(hConsole, wColor & 0x00FF); - return TRUE; + /* Set the text attribute */ + SetConsoleTextAttribute(hConsole, wColor & 0x00FF); + return TRUE; } /* @@ -61,76 +61,76 @@ BOOL SetScreenColor(WORD wColor, BOOL bNoFill) */ INT CommandColor(LPTSTR rest) { - WORD wColor = 0x00; + WORD wColor = 0x00; - /* The user asked for help */ - if (_tcsncmp(rest, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE, STRING_COLOR_HELP1); - return 0; - } + /* The user asked for help */ + if (_tcsncmp(rest, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE, STRING_COLOR_HELP1); + return 0; + } - /* Let's prepare %ERRORLEVEL% */ - nErrorLevel = 0; + /* Let's prepare %ERRORLEVEL% */ + nErrorLevel = 0; - /* No parameter. Set the default colors */ - if (rest[0] == _T('\0')) - { - SetScreenColor(wDefColor, FALSE); - return 0; - } + /* No parameter. Set the default colors */ + if (rest[0] == _T('\0')) + { + SetScreenColor(wDefColor, FALSE); + return 0; + } - /* The parameter is just one character: Set color text */ - if (_tcslen(rest) == 1) - { - if ((rest[0] >= _T('0')) && (rest[0] <= _T('9'))) - { - wColor = (WORD)_ttoi(rest); - } - else if ((rest[0] >= _T('a')) && (rest[0] <= _T('f'))) - { - wColor = (WORD)(rest[0] + 10 - _T('a')); - } - else if ((rest[0] >= _T('A')) && (rest[0] <= _T('F'))) - { - wColor = (WORD)(rest[0] + 10 - _T('A')); - } - else /* Invalid character */ - { - ConOutResPaging(TRUE, STRING_COLOR_HELP1); - nErrorLevel = 1; - return 1; - } - } - /* Color string: advanced choice: two-digits, "Color ON Color" , "Foreground ON Background" */ - else if (StringToColor(&wColor, &rest) == FALSE) - { - /* Invalid color string */ - ConOutResPaging(TRUE, STRING_COLOR_HELP1); - nErrorLevel = 1; - return 1; - } + /* The parameter is just one character: Set color text */ + if (_tcslen(rest) == 1) + { + if ((rest[0] >= _T('0')) && (rest[0] <= _T('9'))) + { + wColor = (WORD)_ttoi(rest); + } + else if ((rest[0] >= _T('a')) && (rest[0] <= _T('f'))) + { + wColor = (WORD)(rest[0] + 10 - _T('a')); + } + else if ((rest[0] >= _T('A')) && (rest[0] <= _T('F'))) + { + wColor = (WORD)(rest[0] + 10 - _T('A')); + } + else /* Invalid character */ + { + ConOutResPaging(TRUE, STRING_COLOR_HELP1); + nErrorLevel = 1; + return 1; + } + } + /* Color string: advanced choice: two-digits, "Color ON Color" , "Foreground ON Background" */ + else if (StringToColor(&wColor, &rest) == FALSE) + { + /* Invalid color string */ + ConOutResPaging(TRUE, STRING_COLOR_HELP1); + nErrorLevel = 1; + return 1; + } - /* Print the chosen color if we are in echo mode (NOTE: Not Windows-compliant) */ - if ((bc && bc->bEcho) || !bc) - { - ConErrResPrintf(STRING_COLOR_ERROR3, wColor); - } + /* Print the chosen color if we are in echo mode (NOTE: Not Windows-compliant) */ + if ((bc && bc->bEcho) || !bc) + { + ConErrResPrintf(STRING_COLOR_ERROR3, wColor); + } - /* - * Set the chosen color. Use also the following advanced flag: - * /-F to avoid changing already buffered foreground/background. - */ - if (SetScreenColor(wColor, (_tcsstr(rest, _T("/-F")) || _tcsstr(rest, _T("/-f")))) == FALSE) - { - /* Failed because foreground and background colors were the same */ - ConErrResPuts(STRING_COLOR_ERROR1); - nErrorLevel = 1; - return 1; - } + /* + * Set the chosen color. Use also the following advanced flag: + * /-F to avoid changing already buffered foreground/background. + */ + if (SetScreenColor(wColor, (_tcsstr(rest, _T("/-F")) || _tcsstr(rest, _T("/-f")))) == FALSE) + { + /* Failed because foreground and background colors were the same */ + ConErrResPuts(STRING_COLOR_ERROR1); + nErrorLevel = 1; + return 1; + } - /* Return success */ - return 0; + /* Return success */ + return 0; } #endif /* INCLUDE_CMD_COLOR */ diff --git a/base/shell/cmd/console.c b/base/shell/cmd/console.c index 3175bb5ac65..921684b08ba 100644 --- a/base/shell/cmd/console.c +++ b/base/shell/cmd/console.c @@ -7,13 +7,13 @@ * 20-Jan-1999 (Eric Kohl) * started * - * 03-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 03-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc * - * 01-Jul-2005 (Brandon Turner) ) + * 01-Jul-2005 (Brandon Turner ) * Added ConPrintfPaging and ConOutPrintfPaging * - * 02-Feb-2007 (Paolo Devoti) ) + * 02-Feb-2007 (Paolo Devoti ) * Fixed ConPrintfPaging */ @@ -26,443 +26,514 @@ UINT InputCodePage; UINT OutputCodePage; -VOID ConInDisable (VOID) +BOOL IsConsoleHandle(HANDLE hHandle) { - HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); - DWORD dwMode; + DWORD dwMode; - GetConsoleMode (hInput, &dwMode); - dwMode &= ~ENABLE_PROCESSED_INPUT; - SetConsoleMode (hInput, dwMode); + /* Check whether the handle may be that of a console... */ + if ((GetFileType(hHandle) & FILE_TYPE_CHAR) == 0) return FALSE; + + /* + * It may be. Perform another test... The idea comes from the + * MSDN description of the WriteConsole API: + * + * "WriteConsole fails if it is used with a standard handle + * that is redirected to a file. If an application processes + * multilingual output that can be redirected, determine whether + * the output handle is a console handle (one method is to call + * the GetConsoleMode function and check whether it succeeds). + * If the handle is a console handle, call WriteConsole. If the + * handle is not a console handle, the output is redirected and + * you should call WriteFile to perform the I/O." + */ + return GetConsoleMode(hHandle, &dwMode); +} + +VOID ConInDisable(VOID) +{ + HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); + DWORD dwMode; + + GetConsoleMode(hInput, &dwMode); + dwMode &= ~ENABLE_PROCESSED_INPUT; + SetConsoleMode(hInput, dwMode); } -VOID ConInEnable (VOID) +VOID ConInEnable(VOID) { - HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); - DWORD dwMode; + HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); + DWORD dwMode; - GetConsoleMode (hInput, &dwMode); - dwMode |= ENABLE_PROCESSED_INPUT; - SetConsoleMode (hInput, dwMode); + GetConsoleMode(hInput, &dwMode); + dwMode |= ENABLE_PROCESSED_INPUT; + SetConsoleMode(hInput, dwMode); } VOID ConInFlush (VOID) { - FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); + FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); } -VOID ConInKey (PINPUT_RECORD lpBuffer) +VOID ConInKey(PINPUT_RECORD lpBuffer) { - HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); - DWORD dwRead; + HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); + DWORD dwRead; - if (hInput == INVALID_HANDLE_VALUE) - WARN ("Invalid input handle!!!\n"); + if (hInput == INVALID_HANDLE_VALUE) + WARN ("Invalid input handle!!!\n"); - do - { - ReadConsoleInput (hInput, lpBuffer, 1, &dwRead); - if ((lpBuffer->EventType == KEY_EVENT) && - (lpBuffer->Event.KeyEvent.bKeyDown == TRUE)) - break; - } - while (TRUE); + do + { + ReadConsoleInput(hInput, lpBuffer, 1, &dwRead); + if ((lpBuffer->EventType == KEY_EVENT) && + (lpBuffer->Event.KeyEvent.bKeyDown == TRUE)) + break; + } + while (TRUE); } -VOID ConInString (LPTSTR lpInput, DWORD dwLength) +VOID ConInString(LPTSTR lpInput, DWORD dwLength) { - DWORD dwOldMode; - DWORD dwRead = 0; - HANDLE hFile; + DWORD dwOldMode; + DWORD dwRead = 0; + HANDLE hFile; - LPTSTR p; - PCHAR pBuf; + LPTSTR p; + PCHAR pBuf; #ifdef _UNICODE - pBuf = (PCHAR)cmd_alloc(dwLength - 1); + pBuf = (PCHAR)cmd_alloc(dwLength - 1); #else - pBuf = lpInput; + pBuf = lpInput; #endif - ZeroMemory (lpInput, dwLength * sizeof(TCHAR)); - hFile = GetStdHandle (STD_INPUT_HANDLE); - GetConsoleMode (hFile, &dwOldMode); + ZeroMemory(lpInput, dwLength * sizeof(TCHAR)); + hFile = GetStdHandle(STD_INPUT_HANDLE); + GetConsoleMode(hFile, &dwOldMode); - SetConsoleMode (hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); + SetConsoleMode(hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); - ReadFile (hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL); + ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL); #ifdef _UNICODE - MultiByteToWideChar(InputCodePage, 0, pBuf, dwRead, lpInput, dwLength - 1); - cmd_free(pBuf); + MultiByteToWideChar(InputCodePage, 0, pBuf, dwRead, lpInput, dwLength - 1); + cmd_free(pBuf); #endif - for (p = lpInput; *p; p++) - { - if (*p == _T('\x0d')) - { - *p = _T('\0'); - break; - } - } + for (p = lpInput; *p; p++) + { + if (*p == _T('\x0d')) + { + *p = _T('\0'); + break; + } + } - SetConsoleMode (hFile, dwOldMode); + SetConsoleMode(hFile, dwOldMode); } static VOID ConWrite(TCHAR *str, DWORD len, DWORD nStdHandle) { - DWORD dwWritten; - HANDLE hOutput = GetStdHandle(nStdHandle); + DWORD dwWritten; + HANDLE hOutput = GetStdHandle(nStdHandle); + PVOID p; - if (WriteConsole(hOutput, str, len, &dwWritten, NULL)) - return; + /* Check whether we are writing to a console and if so, write to it */ + if (IsConsoleHandle(hOutput)) + { + if (WriteConsole(hOutput, str, len, &dwWritten, NULL)) + return; + } - /* We're writing to a file or pipe instead of the console. Convert the - * string from TCHARs to the desired output format, if the two differ */ - if (bUnicodeOutput) - { + /* We're writing to a file or pipe instead of the console. Convert the + * string from TCHARs to the desired output format, if the two differ */ + if (bUnicodeOutput) + { #ifndef _UNICODE - WCHAR *buffer = cmd_alloc(len * sizeof(WCHAR)); - if (!buffer) - { - error_out_of_memory(); - return; - } - len = MultiByteToWideChar(OutputCodePage, 0, str, len, buffer, len); - str = (PVOID)buffer; + WCHAR *buffer = cmd_alloc(len * sizeof(WCHAR)); + if (!buffer) + { + error_out_of_memory(); + return; + } + len = (DWORD)MultiByteToWideChar(OutputCodePage, 0, str, (INT)len, buffer, (INT)len); + str = (PVOID)buffer; #endif - WriteFile(hOutput, str, len * sizeof(WCHAR), &dwWritten, NULL); + /* + * Find any newline character in the buffer, + * send the part BEFORE the newline, then send + * a carriage-return + newline, and then send + * the remaining part of the buffer. + * + * This fixes output in files and serial console. + */ + while (str && *(PWCHAR)str && len > 0) + { + p = wcspbrk((PWCHAR)str, L"\r\n"); + if (p) + { + len -= ((PWCHAR)p - (PWCHAR)str) + 1; + WriteFile(hOutput, str, ((PWCHAR)p - (PWCHAR)str) * sizeof(WCHAR), &dwWritten, NULL); + WriteFile(hOutput, L"\r\n", 2 * sizeof(WCHAR), &dwWritten, NULL); + str = (PVOID)((PWCHAR)p + 1); + } + else + { + WriteFile(hOutput, str, len * sizeof(WCHAR), &dwWritten, NULL); + break; + } + } + + // WriteFile(hOutput, str, len * sizeof(WCHAR), &dwWritten, NULL); #ifndef _UNICODE - cmd_free(buffer); + cmd_free(buffer); #endif - } - else - { + } + else + { #ifdef _UNICODE - CHAR *buffer = cmd_alloc(len * MB_LEN_MAX * sizeof(CHAR)); - if (!buffer) - { - error_out_of_memory(); - return; - } - len = WideCharToMultiByte(OutputCodePage, 0, str, len, buffer, len * MB_LEN_MAX, NULL, NULL); - str = (PVOID)buffer; + CHAR *buffer = cmd_alloc(len * MB_LEN_MAX * sizeof(CHAR)); + if (!buffer) + { + error_out_of_memory(); + return; + } + len = WideCharToMultiByte(OutputCodePage, 0, str, len, buffer, len * MB_LEN_MAX, NULL, NULL); + str = (PVOID)buffer; #endif - WriteFile(hOutput, str, len, &dwWritten, NULL); + /* + * Find any newline character in the buffer, + * send the part BEFORE the newline, then send + * a carriage-return + newline, and then send + * the remaining part of the buffer. + * + * This fixes output in files and serial console. + */ + while (str && *(PCHAR)str && len > 0) + { + p = strpbrk((PCHAR)str, "\r\n"); + if (p) + { + len -= ((PCHAR)p - (PCHAR)str) + 1; + WriteFile(hOutput, str, ((PCHAR)p - (PCHAR)str), &dwWritten, NULL); + WriteFile(hOutput, "\r\n", 2, &dwWritten, NULL); + str = (PVOID)((PCHAR)p + 1); + } + else + { + WriteFile(hOutput, str, len, &dwWritten, NULL); + break; + } + } + + // WriteFile(hOutput, str, len, &dwWritten, NULL); #ifdef _UNICODE - cmd_free(buffer); + cmd_free(buffer); #endif - } + } } -VOID ConOutChar (TCHAR c) +VOID ConOutChar(TCHAR c) { - ConWrite(&c, 1, STD_OUTPUT_HANDLE); + ConWrite(&c, 1, STD_OUTPUT_HANDLE); } VOID ConPuts(LPTSTR szText, DWORD nStdHandle) { - ConWrite(szText, _tcslen(szText), nStdHandle); + ConWrite(szText, (DWORD)_tcslen(szText), nStdHandle); } VOID ConOutResPaging(BOOL NewPage, UINT resID) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); - ConOutPrintfPaging(NewPage, szMsg); + TCHAR szMsg[RC_STRING_MAX_SIZE]; + LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); + ConOutPrintfPaging(NewPage, szMsg); } -VOID ConOutResPuts (UINT resID) +VOID ConOutResPuts(UINT resID) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); - - ConPuts(szMsg, STD_OUTPUT_HANDLE); + TCHAR szMsg[RC_STRING_MAX_SIZE]; + LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); + ConPuts(szMsg, STD_OUTPUT_HANDLE); } -VOID ConOutPuts (LPTSTR szText) +VOID ConOutPuts(LPTSTR szText) { - ConPuts(szText, STD_OUTPUT_HANDLE); + ConPuts(szText, STD_OUTPUT_HANDLE); } VOID ConPrintf(LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle) { - TCHAR szOut[OUTPUT_BUFFER_SIZE]; - ConWrite(szOut, _vstprintf(szOut, szFormat, arg_ptr), nStdHandle); + TCHAR szOut[OUTPUT_BUFFER_SIZE]; + DWORD len; + + len = (DWORD)_vstprintf(szOut, szFormat, arg_ptr); + ConWrite(szOut, len, nStdHandle); } INT ConPrintfPaging(BOOL NewPage, LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle) { - INT len; - CONSOLE_SCREEN_BUFFER_INFO csbi; - TCHAR szOut[OUTPUT_BUFFER_SIZE]; - DWORD dwWritten; - HANDLE hOutput = GetStdHandle(nStdHandle); + INT len; + CONSOLE_SCREEN_BUFFER_INFO csbi; + TCHAR szOut[OUTPUT_BUFFER_SIZE]; + DWORD dwWritten; + HANDLE hOutput = GetStdHandle(nStdHandle); - /* used to count number of lines since last pause */ - static int LineCount = 0; + /* used to count number of lines since last pause */ + static int LineCount = 0; - /* used to see how big the screen is */ - int ScreenLines = 0; + /* used to see how big the screen is */ + int ScreenLines = 0; - /* chars since start of line */ - int CharSL; + /* chars since start of line */ + int CharSL; - int from = 0, i = 0; + int from = 0, i = 0; - if(NewPage == TRUE) - LineCount = 0; + if (NewPage == TRUE) + LineCount = 0; - /* rest LineCount and return if no string have been given */ - if (szFormat == NULL) - return 0; + /* rest LineCount and return if no string have been given */ + if (szFormat == NULL) + return 0; + /* Get the size of the visual screen that can be printed too */ + if (!IsConsoleHandle(hOutput) || !GetConsoleScreenBufferInfo(hOutput, &csbi)) + { + /* We assume it's a file handle */ + ConPrintf(szFormat, arg_ptr, nStdHandle); + return 0; + } + /* Subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt() */ + ScreenLines = (csbi.srWindow.Bottom - csbi.srWindow.Top) - 4; + CharSL = csbi.dwCursorPosition.X; - //get the size of the visual screen that can be printed too - if (!GetConsoleScreenBufferInfo(hOutput, &csbi)) - { - // we assuming its a file handle - ConPrintf(szFormat, arg_ptr, nStdHandle); - return 0; - } - //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt() - ScreenLines = (csbi.srWindow.Bottom - csbi.srWindow.Top) - 4; - CharSL = csbi.dwCursorPosition.X; + /* Make sure they didn't make the screen to small */ + if (ScreenLines < 4) + { + ConPrintf(szFormat, arg_ptr, nStdHandle); + return 0; + } - //make sure they didnt make the screen to small - if(ScreenLines<4) - { - ConPrintf(szFormat, arg_ptr, nStdHandle); - return 0; - } + len = _vstprintf(szOut, szFormat, arg_ptr); - len = _vstprintf (szOut, szFormat, arg_ptr); + while (i < len) + { + /* Search until the end of a line is reached */ + if (szOut[i++] != _T('\n') && ++CharSL < csbi.dwSize.X) + continue; - while (i < len) - { - // Search until the end of a line is reached - if (szOut[i++] != _T('\n') && ++CharSL < csbi.dwSize.X) - continue; + LineCount++; + CharSL=0; - LineCount++; - CharSL=0; + if (LineCount >= ScreenLines) + { + WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL); + from = i; - if(LineCount >= ScreenLines) - { - WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL); - from = i; + if (PagePrompt() != PROMPT_YES) + { + return 1; + } + /* Reset the number of lines being printed */ + LineCount = 0; + } + } - if(PagePrompt() != PROMPT_YES) - { - return 1; - } - //reset the number of lines being printed - LineCount = 0; - } - } + WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL); - WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL); - - return 0; + return 0; } -VOID ConErrFormatMessage (DWORD MessageId, ...) +VOID ConErrFormatMessage(DWORD MessageId, ...) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - DWORD ret; - LPTSTR text; - va_list arg_ptr; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + DWORD ret; + LPTSTR text; + va_list arg_ptr; - va_start (arg_ptr, MessageId); - ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - MessageId, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &text, - 0, - &arg_ptr); + va_start(arg_ptr, MessageId); + ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + MessageId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &text, + 0, + &arg_ptr); - va_end (arg_ptr); - if(ret > 0) - { - ConErrPuts (text); - LocalFree(text); - } - else - { - LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf(szMsg); - } + va_end(arg_ptr); + if (ret > 0) + { + ConErrPuts(text); + LocalFree(text); + } + else + { + LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE); + ConErrPrintf(szMsg); + } } -VOID ConOutFormatMessage (DWORD MessageId, ...) +VOID ConOutFormatMessage(DWORD MessageId, ...) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - DWORD ret; - LPTSTR text; - va_list arg_ptr; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + DWORD ret; + LPTSTR text; + va_list arg_ptr; - va_start (arg_ptr, MessageId); - ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - MessageId, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &text, - 0, - &arg_ptr); + va_start(arg_ptr, MessageId); + ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + MessageId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &text, + 0, + &arg_ptr); - va_end (arg_ptr); - if(ret > 0) - { - ConErrPuts (text); - LocalFree(text); - } - else - { - LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf(szMsg); - } + va_end(arg_ptr); + if (ret > 0) + { + ConErrPuts(text); + LocalFree(text); + } + else + { + LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE); + ConErrPrintf(szMsg); + } } -VOID ConOutResPrintf (UINT resID, ...) +VOID ConOutResPrintf(UINT resID, ...) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - va_list arg_ptr; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + va_list arg_ptr; - va_start (arg_ptr, resID); - LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); - ConPrintf(szMsg, arg_ptr, STD_OUTPUT_HANDLE); - va_end (arg_ptr); + va_start(arg_ptr, resID); + LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); + ConPrintf(szMsg, arg_ptr, STD_OUTPUT_HANDLE); + va_end(arg_ptr); } -VOID ConOutPrintf (LPTSTR szFormat, ...) +VOID ConOutPrintf(LPTSTR szFormat, ...) { - va_list arg_ptr; + va_list arg_ptr; - va_start (arg_ptr, szFormat); - ConPrintf(szFormat, arg_ptr, STD_OUTPUT_HANDLE); - va_end (arg_ptr); + va_start(arg_ptr, szFormat); + ConPrintf(szFormat, arg_ptr, STD_OUTPUT_HANDLE); + va_end(arg_ptr); } -INT ConOutPrintfPaging (BOOL NewPage, LPTSTR szFormat, ...) +INT ConOutPrintfPaging(BOOL NewPage, LPTSTR szFormat, ...) { - INT iReturn; - va_list arg_ptr; + INT iReturn; + va_list arg_ptr; - va_start (arg_ptr, szFormat); - iReturn = ConPrintfPaging(NewPage, szFormat, arg_ptr, STD_OUTPUT_HANDLE); - va_end (arg_ptr); - return iReturn; + va_start(arg_ptr, szFormat); + iReturn = ConPrintfPaging(NewPage, szFormat, arg_ptr, STD_OUTPUT_HANDLE); + va_end(arg_ptr); + return iReturn; } -VOID ConErrChar (TCHAR c) +VOID ConErrChar(TCHAR c) { - ConWrite(&c, 1, STD_ERROR_HANDLE); + ConWrite(&c, 1, STD_ERROR_HANDLE); } -VOID ConErrResPuts (UINT resID) +VOID ConErrResPuts(UINT resID) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); - ConPuts(szMsg, STD_ERROR_HANDLE); + TCHAR szMsg[RC_STRING_MAX_SIZE]; + LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); + ConPuts(szMsg, STD_ERROR_HANDLE); } -VOID ConErrPuts (LPTSTR szText) +VOID ConErrPuts(LPTSTR szText) { - ConPuts(szText, STD_ERROR_HANDLE); + ConPuts(szText, STD_ERROR_HANDLE); } -VOID ConErrResPrintf (UINT resID, ...) +VOID ConErrResPrintf(UINT resID, ...) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - va_list arg_ptr; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + va_list arg_ptr; - va_start (arg_ptr, resID); - LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); - ConPrintf(szMsg, arg_ptr, STD_ERROR_HANDLE); - va_end (arg_ptr); + va_start(arg_ptr, resID); + LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE); + ConPrintf(szMsg, arg_ptr, STD_ERROR_HANDLE); + va_end(arg_ptr); } -VOID ConErrPrintf (LPTSTR szFormat, ...) +VOID ConErrPrintf(LPTSTR szFormat, ...) { - va_list arg_ptr; + va_list arg_ptr; - va_start (arg_ptr, szFormat); - ConPrintf(szFormat, arg_ptr, STD_ERROR_HANDLE); - va_end (arg_ptr); -} - -VOID SetCursorXY (SHORT x, SHORT y) -{ - COORD coPos; - - coPos.X = x; - coPos.Y = y; - SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coPos); + va_start(arg_ptr, szFormat); + ConPrintf(szFormat, arg_ptr, STD_ERROR_HANDLE); + va_end(arg_ptr); } -VOID GetCursorXY (PSHORT x, PSHORT y) +VOID SetCursorXY(SHORT x, SHORT y) { - CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD coPos; - GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - - *x = csbi.dwCursorPosition.X; - *y = csbi.dwCursorPosition.Y; + coPos.X = x; + coPos.Y = y; + SetConsoleCursorPosition(GetStdHandle (STD_OUTPUT_HANDLE), coPos); } - -SHORT GetCursorX (VOID) +VOID GetCursorXY(PSHORT x, PSHORT y) { - CONSOLE_SCREEN_BUFFER_INFO csbi; + CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - return csbi.dwCursorPosition.X; + *x = csbi.dwCursorPosition.X; + *y = csbi.dwCursorPosition.Y; } - -SHORT GetCursorY (VOID) +SHORT GetCursorX(VOID) { - CONSOLE_SCREEN_BUFFER_INFO csbi; + CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - - return csbi.dwCursorPosition.Y; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + return csbi.dwCursorPosition.X; } - -VOID GetScreenSize (PSHORT maxx, PSHORT maxy) +SHORT GetCursorY(VOID) { - CONSOLE_SCREEN_BUFFER_INFO csbi; + CONSOLE_SCREEN_BUFFER_INFO csbi; - if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) - { - csbi.dwSize.X = 80; - csbi.dwSize.Y = 25; - } - - if (maxx) - *maxx = csbi.dwSize.X; - if (maxy) - *maxy = csbi.dwSize.Y; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + return csbi.dwCursorPosition.Y; } - -VOID SetCursorType (BOOL bInsert, BOOL bVisible) +VOID SetCursorType(BOOL bInsert, BOOL bVisible) { - CONSOLE_CURSOR_INFO cci; + CONSOLE_CURSOR_INFO cci; - cci.dwSize = bInsert ? 10 : 99; - cci.bVisible = bVisible; + cci.dwSize = bInsert ? 10 : 99; + cci.bVisible = bVisible; - SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cci); + SetConsoleCursorInfo(GetStdHandle (STD_OUTPUT_HANDLE), &cci); +} + +VOID GetScreenSize(PSHORT maxx, PSHORT maxy) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + { + csbi.dwSize.X = 80; + csbi.dwSize.Y = 25; + } + + if (maxx) *maxx = csbi.dwSize.X; + if (maxy) *maxy = csbi.dwSize.Y; } /* EOF */ diff --git a/base/shell/cmd/copy.c b/base/shell/cmd/copy.c index 95fdb78007d..a5f896d17dd 100644 --- a/base/shell/cmd/copy.c +++ b/base/shell/cmd/copy.c @@ -20,13 +20,13 @@ * 27-Oct-1998 (Eric Kohl) * Disabled prompting when used in batch mode. * - * 03-Apr-2005 (Magnus Olsen) ) + * 03-Apr-2005 (Magnus Olsen ) * Remove all hardcode string to En.rc * - * 13-Jul-2005 (Brandon Turner) ) + * 13-Jul-2005 (Brandon Turner ) * Rewrite to clean up copy and support wildcard. * - * 20-Jul-2005 (Brandon Turner) ) + * 20-Jul-2005 (Brandon Turner ) * Add touch syntax. "copy arp.exe+,," * Copy command is now completed. */ @@ -68,12 +68,12 @@ copy(TCHAR source[MAX_PATH], SYSTEMTIME CurrentTime; /* Check Breaker */ - if(CheckCtrlBreak(BREAK_INPUT)) + if (CheckCtrlBreak(BREAK_INPUT)) return 0; TRACE ("checking mode\n"); - if(bTouch) + if (bTouch) { hFileSrc = CreateFile (source, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); @@ -86,7 +86,7 @@ copy(TCHAR source[MAX_PATH], GetSystemTime(&CurrentTime); SystemTimeToFileTime(&CurrentTime, &NewFileTime); - if(SetFileTime(hFileSrc,(LPFILETIME) NULL, (LPFILETIME) NULL, &NewFileTime)) + if (SetFileTime(hFileSrc,(LPFILETIME) NULL, (LPFILETIME) NULL, &NewFileTime)) { CloseHandle(hFileSrc); nErrorLevel = 1; @@ -120,7 +120,7 @@ copy(TCHAR source[MAX_PATH], /* Check to see if /D or /Z are true, if so we need a middle man to copy the file too to allow us to use CopyFileEx later */ - if(lpdwFlags & COPY_DECRYPT) + if (lpdwFlags & COPY_DECRYPT) { GetEnvironmentVariable(_T("TEMP"),TempSrc,MAX_PATH); _tcscat(TempSrc,_T("\\")); @@ -134,7 +134,7 @@ copy(TCHAR source[MAX_PATH], which would error when it tried to open the handles for ReadFile and WriteFile */ _tcscat(TempSrc,_T(".decrypt")); - if(!CopyFileEx(source, TempSrc, NULL, NULL, FALSE, COPY_FILE_ALLOW_DECRYPTED_DESTINATION)) + if (!CopyFileEx(source, TempSrc, NULL, NULL, FALSE, COPY_FILE_ALLOW_DECRYPTED_DESTINATION)) { nErrorLevel = 1; return 0; @@ -143,7 +143,7 @@ copy(TCHAR source[MAX_PATH], } - if(lpdwFlags & COPY_RESTART) + if (lpdwFlags & COPY_RESTART) { _tcscpy(TrueDest, dest); GetEnvironmentVariable(_T("TEMP"),dest,MAX_PATH); @@ -260,9 +260,9 @@ copy(TCHAR source[MAX_PATH], SetFileAttributes (dest, dwAttrib); /* Now finish off the copy if needed with CopyFileEx */ - if(lpdwFlags & COPY_RESTART) + if (lpdwFlags & COPY_RESTART) { - if(!CopyFileEx(dest, TrueDest, NULL, NULL, FALSE, COPY_FILE_RESTARTABLE)) + if (!CopyFileEx(dest, TrueDest, NULL, NULL, FALSE, COPY_FILE_RESTARTABLE)) { nErrorLevel = 1; DeleteFile(dest); @@ -273,7 +273,7 @@ copy(TCHAR source[MAX_PATH], } - if(lpdwFlags & COPY_DECRYPT) + if (lpdwFlags & COPY_DECRYPT) DeleteFile(TempSrc); return 1; @@ -480,8 +480,8 @@ INT cmd_copy(LPTSTR param) break; case _T('-'): - if(_tcslen(arg[i]) >= 3) - if(_totupper(arg[i][2]) == _T('Y')) + if (_tcslen(arg[i]) >= 3) + if (_totupper(arg[i][2]) == _T('Y')) { dwFlags &= ~COPY_NO_PROMPT; dwFlags |= COPY_PROMPT; @@ -538,7 +538,7 @@ INT cmd_copy(LPTSTR param) bMoreFiles = FALSE; } - else if(nDes == -1) + else if (nDes == -1) { nDes = i; } @@ -825,7 +825,7 @@ INT cmd_copy(LPTSTR param) _tcscat (tmpSrcPath, findBuffer.cFileName); /* Check to see if the file is the same file */ - if(!bTouch && !_tcscmp(tmpSrcPath, tmpDestPath)) + if (!bTouch && !_tcscmp(tmpSrcPath, tmpDestPath)) { ConOutResPrintf(STRING_COPY_ERROR2); @@ -846,7 +846,7 @@ INT cmd_copy(LPTSTR param) dwFlags |= COPY_NO_PROMPT; /* Tell weather the copy was successful or not */ - if(copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags, bTouch)) + if (copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags, bTouch)) { nFiles++; //LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE); diff --git a/base/shell/cmd/date.c b/base/shell/cmd/date.c index b120b419633..7704cde50a7 100644 --- a/base/shell/cmd/date.c +++ b/base/shell/cmd/date.c @@ -27,8 +27,8 @@ * 04-Feb-1999 (Eric Kohl) * Fixed date input bug. * - * 03-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 03-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -38,227 +38,222 @@ static WORD awMonths[2][13] = { - {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; static VOID PrintDateString (VOID) { - switch (nDateFormat) - { - case 0: /* mmddyy */ - default: - ConOutResPrintf(STRING_DATE_HELP1, cDateSeparator, cDateSeparator); - break; + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + ConOutResPrintf(STRING_DATE_HELP1, cDateSeparator, cDateSeparator); + break; - case 1: /* ddmmyy */ - ConOutResPrintf(STRING_DATE_HELP2, cDateSeparator, cDateSeparator); - break; + case 1: /* ddmmyy */ + ConOutResPrintf(STRING_DATE_HELP2, cDateSeparator, cDateSeparator); + break; - case 2: /* yymmdd */ - ConOutResPrintf(STRING_DATE_HELP3, cDateSeparator, cDateSeparator); - break; - } + case 2: /* yymmdd */ + ConOutResPrintf(STRING_DATE_HELP3, cDateSeparator, cDateSeparator); + break; + } } - static BOOL ReadNumber (LPTSTR *s, LPWORD lpwValue) { - if (_istdigit (**s)) - { - while (_istdigit (**s)) - { - *lpwValue = *lpwValue * 10 + **s - _T('0'); - (*s)++; - } - return TRUE; - } - return FALSE; + if (_istdigit (**s)) + { + while (_istdigit (**s)) + { + *lpwValue = *lpwValue * 10 + **s - _T('0'); + (*s)++; + } + return TRUE; + } + return FALSE; } - static BOOL ReadSeparator (LPTSTR *s) { - if (**s == _T('/') || **s == _T('-') || **s == cDateSeparator) - { - (*s)++; - return TRUE; - } - return FALSE; + if (**s == _T('/') || **s == _T('-') || **s == cDateSeparator) + { + (*s)++; + return TRUE; + } + return FALSE; } - static BOOL ParseDate (LPTSTR s) { - SYSTEMTIME d; - unsigned char leap; - LPTSTR p = s; + SYSTEMTIME d; + unsigned char leap; + LPTSTR p = s; - if (!*s) - return TRUE; + if (!*s) + return TRUE; - GetLocalTime (&d); + GetLocalTime (&d); - d.wYear = 0; - d.wDay = 0; - d.wMonth = 0; + d.wYear = 0; + d.wDay = 0; + d.wMonth = 0; - switch (nDateFormat) - { - case 0: /* mmddyy */ - default: - if (!ReadNumber (&p, &d.wMonth)) - return FALSE; - if (!ReadSeparator (&p)) - return FALSE; - if (!ReadNumber (&p, &d.wDay)) - return FALSE; - if (!ReadSeparator (&p)) - return FALSE; - if (!ReadNumber (&p, &d.wYear)) - return FALSE; - break; + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + if (!ReadNumber (&p, &d.wMonth)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wDay)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wYear)) + return FALSE; + break; - case 1: /* ddmmyy */ - if (!ReadNumber (&p, &d.wDay)) - return FALSE; - if (!ReadSeparator (&p)) - return FALSE; - if (!ReadNumber (&p, &d.wMonth)) - return FALSE; - if (!ReadSeparator (&p)) - return FALSE; - if (!ReadNumber (&p, &d.wYear)) - return FALSE; - break; + case 1: /* ddmmyy */ + if (!ReadNumber (&p, &d.wDay)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wMonth)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wYear)) + return FALSE; + break; - case 2: /* yymmdd */ - if (!ReadNumber (&p, &d.wYear)) - return FALSE; - if (!ReadSeparator (&p)) - return FALSE; - if (!ReadNumber (&p, &d.wMonth)) - return FALSE; - if (!ReadSeparator (&p)) - return FALSE; - if (!ReadNumber (&p, &d.wDay)) - return FALSE; - break; - } + case 2: /* yymmdd */ + if (!ReadNumber (&p, &d.wYear)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wMonth)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wDay)) + return FALSE; + break; + } - /* if only entered two digits: */ - /* assume 2000's if value less than 80 */ - /* assume 1900's if value greater or equal 80 */ - if (d.wYear <= 99) - { - if (d.wYear >= 80) - d.wYear = 1900 + d.wYear; - else - d.wYear = 2000 + d.wYear; - } + /* if only entered two digits: */ + /* assume 2000's if value less than 80 */ + /* assume 1900's if value greater or equal 80 */ + if (d.wYear <= 99) + { + if (d.wYear >= 80) + d.wYear = 1900 + d.wYear; + else + d.wYear = 2000 + d.wYear; + } - leap = (!(d.wYear % 4) && (d.wYear % 100)) || !(d.wYear % 400); + leap = (!(d.wYear % 4) && (d.wYear % 100)) || !(d.wYear % 400); - if ((d.wMonth >= 1 && d.wMonth <= 12) && - (d.wDay >= 1 && d.wDay <= awMonths[leap][d.wMonth]) && - (d.wYear >= 1980 && d.wYear <= 2099)) - { - SetLocalTime (&d); - return TRUE; - } + if ((d.wMonth >= 1 && d.wMonth <= 12) && + (d.wDay >= 1 && d.wDay <= awMonths[leap][d.wMonth]) && + (d.wYear >= 1980 && d.wYear <= 2099)) + { + SetLocalTime (&d); + return TRUE; + } - return FALSE; + return FALSE; } INT cmd_date (LPTSTR param) { - LPTSTR *arg; - INT argc; - INT i; - BOOL bPrompt = TRUE; - INT nDateString = -1; + LPTSTR *arg; + INT argc; + INT i; + BOOL bPrompt = TRUE; + INT nDateString = -1; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_DATE_HELP4); - return 0; - } - - nErrorLevel = 0; - - /* build parameter array */ - arg = split (param, &argc, FALSE, FALSE); - - /* check for options */ - for (i = 0; i < argc; i++) - { - if (_tcsicmp (arg[i], _T("/t")) == 0) - bPrompt = FALSE; - if ((*arg[i] != _T('/')) && (nDateString == -1)) - nDateString = i; - } - - if (nDateString == -1) - ConOutPrintf(_T("%s"), GetDateString()); - - if (!bPrompt) - { - freep (arg); - return 0; - } - - if (nDateString == -1) - { - while (TRUE) /* forever loop */ - { - TCHAR s[40]; - - PrintDateString (); - ConInString (s, 40); - TRACE ("\'%s\'\n", debugstr_aw(s)); - while (*s && s[_tcslen (s) - 1] < _T(' ')) - s[_tcslen (s) - 1] = _T('\0'); - if (ParseDate (s)) - { - freep (arg); - return 0; - } - ConErrResPuts(STRING_DATE_ERROR); - - } - } - else - { - if (!ParseDate (arg[nDateString])) + if (!_tcsncmp (param, _T("/?"), 2)) { - while (TRUE) /* forever loop */ - { - TCHAR s[40]; - ConErrResPuts(STRING_DATE_ERROR); - - PrintDateString (); - ConInString (s, 40); - - while (*s && s[_tcslen (s) - 1] < _T(' ')) - s[_tcslen (s) - 1] = _T('\0'); - if (ParseDate (s)) - { - freep (arg); - return 0; - } - } + ConOutResPaging(TRUE,STRING_DATE_HELP4); + return 0; } - } - freep (arg); + nErrorLevel = 0; - return 0; + /* build parameter array */ + arg = split (param, &argc, FALSE, FALSE); + + /* check for options */ + for (i = 0; i < argc; i++) + { + if (_tcsicmp (arg[i], _T("/t")) == 0) + bPrompt = FALSE; + if ((*arg[i] != _T('/')) && (nDateString == -1)) + nDateString = i; + } + + if (nDateString == -1) + ConOutPrintf(_T("%s"), GetDateString()); + + if (!bPrompt) + { + freep (arg); + return 0; + } + + if (nDateString == -1) + { + while (TRUE) /* forever loop */ + { + TCHAR s[40]; + + PrintDateString (); + ConInString (s, 40); + TRACE ("\'%s\'\n", debugstr_aw(s)); + while (*s && s[_tcslen (s) - 1] < _T(' ')) + s[_tcslen (s) - 1] = _T('\0'); + if (ParseDate (s)) + { + freep (arg); + return 0; + } + ConErrResPuts(STRING_DATE_ERROR); + } + } + else + { + if (!ParseDate (arg[nDateString])) + { + while (TRUE) /* forever loop */ + { + TCHAR s[40]; + ConErrResPuts(STRING_DATE_ERROR); + + PrintDateString (); + ConInString (s, 40); + + while (*s && s[_tcslen (s) - 1] < _T(' ')) + s[_tcslen (s) - 1] = _T('\0'); + if (ParseDate (s)) + { + freep (arg); + return 0; + } + } + } + } + + freep (arg); + return 0; } #endif /* INCLUDE_CMD_DATE */ diff --git a/base/shell/cmd/del.c b/base/shell/cmd/del.c index 046469122fc..aad2ee8d65b 100644 --- a/base/shell/cmd/del.c +++ b/base/shell/cmd/del.c @@ -52,28 +52,28 @@ enum { - DEL_ATTRIBUTES = 0x001, /* /A */ - DEL_NOTHING = 0x004, /* /N */ - DEL_PROMPT = 0x008, /* /P */ - DEL_QUIET = 0x010, /* /Q */ - DEL_SUBDIR = 0x020, /* /S */ - DEL_TOTAL = 0x040, /* /T */ - DEL_WIPE = 0x080, /* /W */ - DEL_EMPTYDIR = 0x100, /* /X : not implemented */ - DEL_YES = 0x200, /* /Y */ - DEL_FORCE = 0x800 /* /F */ + DEL_ATTRIBUTES = 0x001, /* /A */ + DEL_NOTHING = 0x004, /* /N */ + DEL_PROMPT = 0x008, /* /P */ + DEL_QUIET = 0x010, /* /Q */ + DEL_SUBDIR = 0x020, /* /S */ + DEL_TOTAL = 0x040, /* /T */ + DEL_WIPE = 0x080, /* /W */ + DEL_EMPTYDIR = 0x100, /* /X : not implemented */ + DEL_YES = 0x200, /* /Y */ + DEL_FORCE = 0x800 /* /F */ }; enum { - ATTR_ARCHIVE = 0x001, /* /A:A */ - ATTR_HIDDEN = 0x002, /* /A:H */ - ATTR_SYSTEM = 0x004, /* /A:S */ - ATTR_READ_ONLY = 0x008, /* /A:R */ - ATTR_N_ARCHIVE = 0x010, /* /A:-A */ - ATTR_N_HIDDEN = 0x020, /* /A:-H */ - ATTR_N_SYSTEM = 0x040, /* /A:-S */ - ATTR_N_READ_ONLY = 0x080 /* /A:-R */ + ATTR_ARCHIVE = 0x001, /* /A:A */ + ATTR_HIDDEN = 0x002, /* /A:H */ + ATTR_SYSTEM = 0x004, /* /A:S */ + ATTR_READ_ONLY = 0x008, /* /A:R */ + ATTR_N_ARCHIVE = 0x010, /* /A:-A */ + ATTR_N_HIDDEN = 0x020, /* /A:-H */ + ATTR_N_SYSTEM = 0x040, /* /A:-S */ + ATTR_N_READ_ONLY = 0x080 /* /A:-R */ }; static TCHAR szDeleteWipe[RC_STRING_MAX_SIZE]; @@ -83,471 +83,460 @@ static BOOLEAN StringsLoaded = FALSE; static VOID LoadStrings(VOID) { - LoadString( CMD_ModuleHandle, STRING_DELETE_WIPE, szDeleteWipe, RC_STRING_MAX_SIZE); - GetModuleFileName(NULL, CMDPath, MAX_PATH); - StringsLoaded = TRUE; + LoadString( CMD_ModuleHandle, STRING_DELETE_WIPE, szDeleteWipe, RC_STRING_MAX_SIZE); + GetModuleFileName(NULL, CMDPath, MAX_PATH); + StringsLoaded = TRUE; } static BOOL RemoveFile (LPTSTR lpFileName, DWORD dwFlags, WIN32_FIND_DATA* f) { - /*This function is called by CommandDelete and - does the actual process of deleting the single - file*/ - if(CheckCtrlBreak(BREAK_INPUT)) - return 1; + /*This function is called by CommandDelete and + does the actual process of deleting the single + file*/ + if (CheckCtrlBreak(BREAK_INPUT)) + return 1; - /*check to see if it is read only and if this is done based on /A - if it is done by file name, access is denied. However, if it is done - using the /A switch you must un-read only the file and allow it to be - deleted*/ - if((dwFlags & DEL_ATTRIBUTES) || (dwFlags & DEL_FORCE)) + /*check to see if it is read only and if this is done based on /A + if it is done by file name, access is denied. However, if it is done + using the /A switch you must un-read only the file and allow it to be + deleted*/ + if ((dwFlags & DEL_ATTRIBUTES) || (dwFlags & DEL_FORCE)) + { + if (f->dwFileAttributes & FILE_ATTRIBUTE_READONLY) { - if(f->dwFileAttributes & FILE_ATTRIBUTE_READONLY) - { - /*setting file to normal, not saving old attrs first - because the file is going to be deleted anyways - so the only thing that matters is that it isn't - read only.*/ - SetFileAttributes(lpFileName,FILE_ATTRIBUTE_NORMAL); - } + /*setting file to normal, not saving old attrs first + because the file is going to be deleted anyways + so the only thing that matters is that it isn't + read only.*/ + SetFileAttributes(lpFileName,FILE_ATTRIBUTE_NORMAL); } + } - if (dwFlags & DEL_WIPE) - { - - HANDLE file; - DWORD temp; + if (dwFlags & DEL_WIPE) + { + HANDLE file; + DWORD temp; #define BufferSize 65536 - BYTE buffer[BufferSize]; - LONGLONG i; - LARGE_INTEGER FileSize; + BYTE buffer[BufferSize]; + LONGLONG i; + LARGE_INTEGER FileSize; - FileSize.u.HighPart = f->nFileSizeHigh; - FileSize.u.LowPart = f->nFileSizeLow; + FileSize.u.HighPart = f->nFileSizeHigh; + FileSize.u.LowPart = f->nFileSizeLow; - for(i = 0; i < BufferSize; i++) - { - buffer[i]=rand() % 256; - } - file = CreateFile (lpFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); - if (file != INVALID_HANDLE_VALUE) - { - for(i = 0; i < (FileSize.QuadPart - BufferSize); i += BufferSize) - { - WriteFile (file, buffer, BufferSize, &temp, NULL); - ConOutPrintf (_T("%I64d%% %s\r"),(i * (LONGLONG)100)/FileSize.QuadPart,szDeleteWipe); - } - WriteFile (file, buffer, (DWORD)(FileSize.QuadPart - i), &temp, NULL); - ConOutPrintf (_T("100%% %s\n"),szDeleteWipe); - CloseHandle (file); - } + for(i = 0; i < BufferSize; i++) + { + buffer[i]=rand() % 256; } + file = CreateFile (lpFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); + if (file != INVALID_HANDLE_VALUE) + { + for(i = 0; i < (FileSize.QuadPart - BufferSize); i += BufferSize) + { + WriteFile (file, buffer, BufferSize, &temp, NULL); + ConOutPrintf (_T("%I64d%% %s\r"),(i * (LONGLONG)100)/FileSize.QuadPart,szDeleteWipe); + } + WriteFile (file, buffer, (DWORD)(FileSize.QuadPart - i), &temp, NULL); + ConOutPrintf (_T("100%% %s\n"),szDeleteWipe); + CloseHandle (file); + } + } - return DeleteFile (lpFileName); + return DeleteFile (lpFileName); } static DWORD DeleteFiles(LPTSTR FileName, DWORD* dwFlags, DWORD dwAttrFlags) { - TCHAR szFullPath[MAX_PATH]; - TCHAR szFileName[MAX_PATH]; - LPTSTR pFilePart; - HANDLE hFile; - WIN32_FIND_DATA f; - BOOL bExclusion; - INT res; - DWORD dwFiles = 0; + TCHAR szFullPath[MAX_PATH]; + TCHAR szFileName[MAX_PATH]; + LPTSTR pFilePart; + HANDLE hFile; + WIN32_FIND_DATA f; + BOOL bExclusion; + INT res; + DWORD dwFiles = 0; - _tcscpy(szFileName, FileName); + _tcscpy(szFileName, FileName); - if(_tcschr (szFileName, _T('*')) == NULL && - IsExistingDirectory (szFileName)) + if (_tcschr (szFileName, _T('*')) == NULL && + IsExistingDirectory (szFileName)) + { + /* If it doesnt have a \ at the end already then on needs to be added */ + if (szFileName[_tcslen(szFileName) - 1] != _T('\\')) + _tcscat (szFileName, _T("\\")); + /* Add a wildcard after the \ */ + _tcscat (szFileName, _T("*")); + } + + if (!_tcscmp (szFileName, _T("*")) || + !_tcscmp (szFileName, _T("*.*")) || + (szFileName[_tcslen(szFileName) - 2] == _T('\\') && szFileName[_tcslen(szFileName) - 1] == _T('*'))) + { + /* well, the user wants to delete everything but if they didnt yes DEL_YES, DEL_QUIET, or DEL_PROMPT + then we are going to want to make sure that in fact they want to do that. */ + + if (!((*dwFlags & DEL_YES) || (*dwFlags & DEL_QUIET) || (*dwFlags & DEL_PROMPT))) { - /* If it doesnt have a \ at the end already then on needs to be added */ - if(szFileName[_tcslen(szFileName) - 1] != _T('\\')) - _tcscat (szFileName, _T("\\")); - /* Add a wildcard after the \ */ - _tcscat (szFileName, _T("*")); + res = FilePromptYNA (STRING_DEL_HELP2); + if ((res == PROMPT_NO) || (res == PROMPT_BREAK)) + return 0x80000000; + if (res == PROMPT_ALL) + *dwFlags |= DEL_YES; } + } - if(!_tcscmp (szFileName, _T("*")) || - !_tcscmp (szFileName, _T("*.*")) || - (szFileName[_tcslen(szFileName) - 2] == _T('\\') && szFileName[_tcslen(szFileName) - 1] == _T('*'))) + GetFullPathName(szFileName, + MAX_PATH, + szFullPath, + &pFilePart); + + hFile = FindFirstFile(szFullPath, &f); + if (hFile != INVALID_HANDLE_VALUE) + { + do { - /* well, the user wants to delete everything but if they didnt yes DEL_YES, DEL_QUIET, or DEL_PROMPT - then we are going to want to make sure that in fact they want to do that. */ + bExclusion = FALSE; - if (!((*dwFlags & DEL_YES) || (*dwFlags & DEL_QUIET) || (*dwFlags & DEL_PROMPT))) - { - res = FilePromptYNA (STRING_DEL_HELP2); - if ((res == PROMPT_NO) || (res == PROMPT_BREAK)) - return 0x80000000; - if(res == PROMPT_ALL) - *dwFlags |= DEL_YES; - } - } + /*if it is going to be excluded by - no need to check attrs*/ + if (*dwFlags & DEL_ATTRIBUTES && !bExclusion) + { + /*save if file attr check if user doesnt care about that attr anyways*/ + if (dwAttrFlags & ATTR_ARCHIVE && !(f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_HIDDEN && !(f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_SYSTEM && !(f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_READ_ONLY && !(f.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_N_ARCHIVE && (f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_N_HIDDEN && (f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_N_SYSTEM && (f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) + bExclusion = TRUE; + if (dwAttrFlags & ATTR_N_READ_ONLY && (f.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + bExclusion = TRUE; + } + if (bExclusion) continue; - GetFullPathName (szFileName, - MAX_PATH, - szFullPath, - &pFilePart); + /* ignore directories */ + if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - hFile = FindFirstFile(szFullPath, &f); - if (hFile != INVALID_HANDLE_VALUE) - { - do + _tcscpy (pFilePart, f.cFileName); + + /* We cant delete ourselves */ + if (!_tcscmp (CMDPath,szFullPath)) continue; + + TRACE("Full filename: %s\n", debugstr_aw(szFullPath)); + + /* ask for deleting */ + if (*dwFlags & DEL_PROMPT) + { + ConErrResPrintf(STRING_DEL_ERROR5, szFullPath); + + res = FilePromptYN (STRING_DEL_ERROR6); + + if ((res == PROMPT_NO) || (res == PROMPT_BREAK)) { - bExclusion = FALSE; - - /*if it is going to be excluded by - no need to check attrs*/ - if(*dwFlags & DEL_ATTRIBUTES && !bExclusion) - { - - /*save if file attr check if user doesnt care about that attr anyways*/ - if(dwAttrFlags & ATTR_ARCHIVE && !(f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_HIDDEN && !(f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_SYSTEM && !(f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_READ_ONLY && !(f.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_N_ARCHIVE && (f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_N_HIDDEN && (f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_N_SYSTEM && (f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) - bExclusion = TRUE; - if(dwAttrFlags & ATTR_N_READ_ONLY && (f.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - bExclusion = TRUE; - } - if(bExclusion) - continue; - - /* ignore directories */ - if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - - - _tcscpy (pFilePart, f.cFileName); - - /* We cant delete ourselves */ - if(!_tcscmp (CMDPath,szFullPath)) - continue; - - - TRACE("Full filename: %s\n", debugstr_aw(szFullPath)); - - /* ask for deleting */ - if (*dwFlags & DEL_PROMPT) - { - ConErrResPrintf(STRING_DEL_ERROR5, szFullPath); - - res = FilePromptYN (STRING_DEL_ERROR6); - - if ((res == PROMPT_NO) || (res == PROMPT_BREAK)) - { - nErrorLevel = 0; - continue; - } - } - - /*user cant ask it to be quiet and tell you what it did*/ - if (!(*dwFlags & DEL_QUIET) && !(*dwFlags & DEL_TOTAL)) - { - ConErrResPrintf(STRING_DEL_ERROR7, szFullPath); - } - - /* delete the file */ - if(*dwFlags & DEL_NOTHING) - continue; - - if(RemoveFile (szFullPath, *dwFlags, &f)) - dwFiles++; - else - { - ErrorMessage (GetLastError(), _T("")); -// FindClose(hFile); -// return -1; - } + nErrorLevel = 0; + continue; } - while (FindNextFile (hFile, &f)); - FindClose (hFile); + } + + /*user cant ask it to be quiet and tell you what it did*/ + if (!(*dwFlags & DEL_QUIET) && !(*dwFlags & DEL_TOTAL)) + { + ConErrResPrintf(STRING_DEL_ERROR7, szFullPath); + } + + /* delete the file */ + if (*dwFlags & DEL_NOTHING) continue; + + if (RemoveFile (szFullPath, *dwFlags, &f)) + { + dwFiles++; + } + else + { + ErrorMessage (GetLastError(), _T("")); +// FindClose(hFile); +// return -1; + } } - else error_sfile_not_found(szFullPath); - return dwFiles; + while (FindNextFile (hFile, &f)); + FindClose (hFile); + } + else error_sfile_not_found(szFullPath); + return dwFiles; } static DWORD ProcessDirectory(LPTSTR FileName, DWORD* dwFlags, DWORD dwAttrFlags) { - TCHAR szFullPath[MAX_PATH]; - LPTSTR pFilePart; - LPTSTR pSearchPart; - HANDLE hFile; - WIN32_FIND_DATA f; - DWORD dwFiles = 0; + TCHAR szFullPath[MAX_PATH]; + LPTSTR pFilePart; + LPTSTR pSearchPart; + HANDLE hFile; + WIN32_FIND_DATA f; + DWORD dwFiles = 0; - GetFullPathName (FileName, - MAX_PATH, - szFullPath, - &pFilePart); + GetFullPathName(FileName, + MAX_PATH, + szFullPath, + &pFilePart); - dwFiles = DeleteFiles(szFullPath, dwFlags, dwAttrFlags); - if (dwFiles & 0x80000000) - return dwFiles; + dwFiles = DeleteFiles(szFullPath, dwFlags, dwAttrFlags); + if (dwFiles & 0x80000000) return dwFiles; - if (*dwFlags & DEL_SUBDIR) + if (*dwFlags & DEL_SUBDIR) + { + /* Get just the file name */ + pSearchPart = _tcsrchr(FileName,_T('\\')); + if (pSearchPart != NULL) + pSearchPart++; + else + pSearchPart = FileName; + + /* Get the full path to the file */ + GetFullPathName (FileName,MAX_PATH,szFullPath,NULL); + + /* strip the filename off of it */ + pFilePart = _tcsrchr(szFullPath, _T('\\')); + if (pFilePart == NULL) { - /* Get just the file name */ - pSearchPart = _tcsrchr(FileName,_T('\\')); - if(pSearchPart != NULL) - pSearchPart++; - else - pSearchPart = FileName; - - /* Get the full path to the file */ - GetFullPathName (FileName,MAX_PATH,szFullPath,NULL); - - /* strip the filename off of it */ - pFilePart = _tcsrchr(szFullPath, _T('\\')); - if (pFilePart == NULL) - { - pFilePart = szFullPath; - } - else - { - pFilePart++; - } - - _tcscpy(pFilePart, _T("*")); - - hFile = FindFirstFile(szFullPath, &f); - if (hFile != INVALID_HANDLE_VALUE) - { - do - { - if (!(f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || - !_tcscmp(f.cFileName, _T(".")) || - !_tcscmp(f.cFileName, _T(".."))) - continue; - - _tcscpy(pFilePart, f.cFileName); - _tcscat(pFilePart, _T("\\")); - _tcscat(pFilePart, pSearchPart); - - dwFiles +=ProcessDirectory(szFullPath, dwFlags, dwAttrFlags); - if (dwFiles & 0x80000000) - { - break; - } - } - while (FindNextFile (hFile, &f)); - FindClose (hFile); - } + pFilePart = szFullPath; } - return dwFiles; + else + { + pFilePart++; + } + + _tcscpy(pFilePart, _T("*")); + + hFile = FindFirstFile(szFullPath, &f); + if (hFile != INVALID_HANDLE_VALUE) + { + do + { + if (!(f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || + !_tcscmp(f.cFileName, _T(".")) || + !_tcscmp(f.cFileName, _T(".."))) + continue; + + _tcscpy(pFilePart, f.cFileName); + _tcscat(pFilePart, _T("\\")); + _tcscat(pFilePart, pSearchPart); + + dwFiles +=ProcessDirectory(szFullPath, dwFlags, dwAttrFlags); + if (dwFiles & 0x80000000) + { + break; + } + } + while (FindNextFile (hFile, &f)); + FindClose (hFile); + } + } + return dwFiles; } INT CommandDelete (LPTSTR param) { - /*cmd is the command that was given, in this case it will always be "del" or "delete" - param is whatever is given after the command*/ + /*cmd is the command that was given, in this case it will always be "del" or "delete" + param is whatever is given after the command*/ - LPTSTR *arg = NULL; - INT args; - INT i; - INT nEvalArgs = 0; /* nunber of evaluated arguments */ - DWORD dwFlags = 0; - DWORD dwAttrFlags = 0; - DWORD dwFiles = 0; - LONG ch; - TCHAR szOrginalArg[MAX_PATH]; + LPTSTR *arg = NULL; + INT args; + INT i; + INT nEvalArgs = 0; /* nunber of evaluated arguments */ + DWORD dwFlags = 0; + DWORD dwAttrFlags = 0; + DWORD dwFiles = 0; + LONG ch; + TCHAR szOrginalArg[MAX_PATH]; - /*checks the first two chars of param to see if it is /? - this however allows the following command to not show help - "del frog.txt /?" */ + /*checks the first two chars of param to see if it is /? + this however allows the following command to not show help + "del frog.txt /?" */ - if (!StringsLoaded) + if (!StringsLoaded) + { + LoadStrings(); + } + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_DEL_HELP1); + return 0; + } + + nErrorLevel = 0; + + arg = split (param, &args, FALSE, FALSE); + + if (args == 0) + { + /* only command given */ + error_req_param_missing (); + freep (arg); + return 1; + } + /* check for options anywhere in command line */ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/')) { - LoadStrings(); + /*found a command, but check to make sure it has something after it*/ + if (_tcslen (arg[i]) >= 2) + { + ch = _totupper (arg[i][1]); + if (ch == _T('N')) + { + dwFlags |= DEL_NOTHING; + } + else if (ch == _T('P')) + { + dwFlags |= DEL_PROMPT; + } + else if (ch == _T('Q')) + { + dwFlags |= DEL_QUIET; + } + else if (ch == _T('F')) + { + dwFlags |= DEL_FORCE; + } + else if (ch == _T('S')) + { + dwFlags |= DEL_SUBDIR; + } + else if (ch == _T('T')) + { + dwFlags |= DEL_TOTAL; + } + else if (ch == _T('W')) + { + dwFlags |= DEL_WIPE; + } + else if (ch == _T('Y')) + { + dwFlags |= DEL_YES; + } + else if (ch == _T('A')) + { + dwFlags |= DEL_ATTRIBUTES; + /*the proper syntax for /A has a min of 4 chars + i.e. /A:R or /A:-H */ + if (_tcslen (arg[i]) < 4) + { + error_invalid_parameter_format(arg[i]); + return 0; + } + ch = _totupper (arg[i][3]); + if (_tcslen (arg[i]) == 4) + { + if (ch == _T('A')) + { + dwAttrFlags |= ATTR_ARCHIVE; + } + if (ch == _T('H')) + { + dwAttrFlags |= ATTR_HIDDEN; + } + if (ch == _T('S')) + { + dwAttrFlags |= ATTR_SYSTEM; + } + if (ch == _T('R')) + { + dwAttrFlags |= ATTR_READ_ONLY; + } + } + if (_tcslen (arg[i]) == 5) + { + if (ch == _T('-')) + { + ch = _totupper (arg[i][4]); + if (ch == _T('A')) + { + dwAttrFlags |= ATTR_N_ARCHIVE; + } + if (ch == _T('H')) + { + dwAttrFlags |= ATTR_N_HIDDEN; + } + if (ch == _T('S')) + { + dwAttrFlags |= ATTR_N_SYSTEM; + } + if (ch == _T('R')) + { + dwAttrFlags |= ATTR_N_READ_ONLY; + } + } + } + } + } + + nEvalArgs++; } + } - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_DEL_HELP1); - return 0; - } + /* there are only options on the command line --> error!!! + there is the same number of args as there is flags, so none of the args were filenames*/ + if (args == nEvalArgs) + { + error_req_param_missing (); + freep (arg); + return 1; + } - nErrorLevel = 0; - - arg = split (param, &args, FALSE, FALSE); - - if (args == 0) - { - /* only command given */ - error_req_param_missing (); - freep (arg); - return 1; - } - /* check for options anywhere in command line */ - for (i = 0; i < args; i++) - { - if (*arg[i] == _T('/')) - { - /*found a command, but check to make sure it has something after it*/ - if (_tcslen (arg[i]) >= 2) - { - ch = _totupper (arg[i][1]); - if (ch == _T('N')) - { - dwFlags |= DEL_NOTHING; - } - else if (ch == _T('P')) - { - dwFlags |= DEL_PROMPT; - } - else if (ch == _T('Q')) - { - dwFlags |= DEL_QUIET; - } - else if (ch == _T('F')) - { - dwFlags |= DEL_FORCE; - } - else if (ch == _T('S')) - { - dwFlags |= DEL_SUBDIR; - } - else if (ch == _T('T')) - { - dwFlags |= DEL_TOTAL; - } - else if (ch == _T('W')) - { - dwFlags |= DEL_WIPE; - } - else if (ch == _T('Y')) - { - dwFlags |= DEL_YES; - } - else if (ch == _T('A')) - { - - dwFlags |= DEL_ATTRIBUTES; - /*the proper syntax for /A has a min of 4 chars - i.e. /A:R or /A:-H */ - if (_tcslen (arg[i]) < 4) - { - error_invalid_parameter_format(arg[i]); - return 0; - } - ch = _totupper (arg[i][3]); - if (_tcslen (arg[i]) == 4) - { - if(ch == _T('A')) - { - dwAttrFlags |= ATTR_ARCHIVE; - } - if(ch == _T('H')) - { - dwAttrFlags |= ATTR_HIDDEN; - } - if(ch == _T('S')) - { - dwAttrFlags |= ATTR_SYSTEM; - } - if(ch == _T('R')) - { - dwAttrFlags |= ATTR_READ_ONLY; - } - } - if (_tcslen (arg[i]) == 5) - { - if(ch == _T('-')) - { - ch = _totupper (arg[i][4]); - if(ch == _T('A')) - { - dwAttrFlags |= ATTR_N_ARCHIVE; - } - if(ch == _T('H')) - { - dwAttrFlags |= ATTR_N_HIDDEN; - } - if(ch == _T('S')) - { - dwAttrFlags |= ATTR_N_SYSTEM; - } - if(ch == _T('R')) - { - dwAttrFlags |= ATTR_N_READ_ONLY; - } - } - } - } - } - - nEvalArgs++; - } - } - - /* there are only options on the command line --> error!!! - there is the same number of args as there is flags, so none of the args were filenames*/ - if (args == nEvalArgs) - { - error_req_param_missing (); - freep (arg); - return 1; - } - - /* keep quiet within batch files */ - if (bc != NULL) - dwFlags |= DEL_QUIET; - - /* check for filenames anywhere in command line */ - for (i = 0; i < args && !(dwFiles & 0x80000000); i++) - { + /* keep quiet within batch files */ + if (bc != NULL) dwFlags |= DEL_QUIET; + /* check for filenames anywhere in command line */ + for (i = 0; i < args && !(dwFiles & 0x80000000); i++) + { /*this checks to see if it is a flag; if it isn't, we assume it is a file name*/ - if((*arg[i] == _T('/')) || (*arg[i] == _T('-'))) - continue; - - /* We want to make a copies of the argument */ - if(_tcslen(arg[i]) == 2 && arg[i][1] == _T(':')) - { - /* Check for C: D: ... */ - GetRootPath(arg[i],szOrginalArg,MAX_PATH); - } - else - { - _tcscpy(szOrginalArg,arg[i]); - } - dwFiles += ProcessDirectory(szOrginalArg, &dwFlags, dwAttrFlags); + if ((*arg[i] == _T('/')) || (*arg[i] == _T('-'))) + continue; + /* We want to make a copies of the argument */ + if (_tcslen(arg[i]) == 2 && arg[i][1] == _T(':')) + { + /* Check for C: D: ... */ + GetRootPath(arg[i], szOrginalArg, MAX_PATH); } + else + { + _tcscpy(szOrginalArg,arg[i]); + } + dwFiles += ProcessDirectory(szOrginalArg, &dwFlags, dwAttrFlags); + } - freep (arg); + freep (arg); - /*Based on MS cmd, we only tell what files are being deleted when /S is used */ - if (dwFlags & DEL_TOTAL) - { - dwFiles &= 0x7fffffff; - if (dwFiles < 2) - { - ConOutResPrintf(STRING_DEL_HELP3, dwFiles); - } - else - { - ConOutResPrintf(STRING_DEL_HELP4, dwFiles); - } - } + /*Based on MS cmd, we only tell what files are being deleted when /S is used */ + if (dwFlags & DEL_TOTAL) + { + dwFiles &= 0x7fffffff; + if (dwFiles < 2) + { + ConOutResPrintf(STRING_DEL_HELP3, dwFiles); + } + else + { + ConOutResPrintf(STRING_DEL_HELP4, dwFiles); + } + } - return 0; + return 0; } #endif diff --git a/base/shell/cmd/delay.c b/base/shell/cmd/delay.c index 252cf66c62b..83b6310fdd5 100644 --- a/base/shell/cmd/delay.c +++ b/base/shell/cmd/delay.c @@ -16,33 +16,33 @@ INT CommandDelay (LPTSTR param) { - DWORD val; - DWORD mul=1000; + DWORD val; + DWORD mul=1000; - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE,STRING_DELAY_HELP); - return 0; - } + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE,STRING_DELAY_HELP); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - if (*param==0) - { - error_req_param_missing (); - return 1; - } + if (*param==0) + { + error_req_param_missing (); + return 1; + } - if (_tcsnicmp(param,_T("/m"),2) == 0) - { - mul = 1; - param += 2; - } + if (_tcsnicmp(param,_T("/m"),2) == 0) + { + mul = 1; + param += 2; + } - val = _ttoi(param); - Sleep(val * mul); + val = _ttoi(param); + Sleep(val * mul); - return 0; + return 0; } #endif /* INCLUDE_CMD_DELAY */ diff --git a/base/shell/cmd/dir.c b/base/shell/cmd/dir.c index 2f9f54677c6..b2433d9ed7f 100644 --- a/base/shell/cmd/dir.c +++ b/base/shell/cmd/dir.c @@ -130,8 +130,8 @@ * * 3-feb-2007 (Paolo Devoti devotip at gmail) * Removed variables formerly in use to handle pagination - * Pagination belongs to ConOutPrintfPaging - * Removed already commented out code of old pagination + * Pagination belongs to ConOutPrintfPaging + * Removed already commented out code of old pagination */ #include "precomp.h" @@ -143,71 +143,67 @@ /* Time Field enumeration */ enum ETimeField { - TF_CREATIONDATE = 0, - TF_MODIFIEDDATE = 1, - TF_LASTACCESSEDDATE = 2 + TF_CREATIONDATE = 0, + TF_MODIFIEDDATE = 1, + TF_LASTACCESSEDDATE = 2 }; /* Ordered by enumeration */ enum EOrderBy { - ORDER_NAME = 0, - ORDER_SIZE = 1, - ORDER_DIRECTORY = 2, - ORDER_EXTENSION = 3, - ORDER_TIME = 4 + ORDER_NAME = 0, + ORDER_SIZE = 1, + ORDER_DIRECTORY = 2, + ORDER_EXTENSION = 3, + ORDER_TIME = 4 }; /* The struct for holding the switches */ typedef struct _DirSwitchesFlags { - BOOL bBareFormat; /* Bare Format */ - BOOL bTSeperator; /* Thousands seperator */ - BOOL bWideList; /* Wide list format */ - BOOL bWideListColSort; /* Wide list format but sorted by column */ - BOOL bLowerCase; /* Uses lower case */ - BOOL bNewLongList; /* New long list */ - BOOL bPause; /* Pause per page */ - BOOL bUser; /* Displays the owner of file */ - BOOL bRecursive; /* Displays files in specified directory and all sub */ - BOOL bShortName; /* Displays the sort name of files if exist */ - BOOL b4Digit; /* Four digit year */ - struct - { - DWORD dwAttribVal; /* The desired state of attribute */ - DWORD dwAttribMask; /* Which attributes to check */ - } stAttribs; /* Displays files with this attributes only */ - struct - { - enum EOrderBy eCriteria[3]; /* Criterias used to order by */ - BOOL bCriteriaRev[3]; /* If the criteria is in reversed order */ - short sCriteriaCount; /* The quantity of criterias */ - } stOrderBy; /* Ordered by criterias */ - struct - { - enum ETimeField eTimeField; /* The time field that will be used for */ - } stTimeField; /* The time field to display or use for sorting */ + BOOL bBareFormat; /* Bare Format */ + BOOL bTSeperator; /* Thousands seperator */ + BOOL bWideList; /* Wide list format */ + BOOL bWideListColSort; /* Wide list format but sorted by column */ + BOOL bLowerCase; /* Uses lower case */ + BOOL bNewLongList; /* New long list */ + BOOL bPause; /* Pause per page */ + BOOL bUser; /* Displays the owner of file */ + BOOL bRecursive; /* Displays files in specified directory and all sub */ + BOOL bShortName; /* Displays the sort name of files if exist */ + BOOL b4Digit; /* Four digit year */ + struct + { + DWORD dwAttribVal; /* The desired state of attribute */ + DWORD dwAttribMask; /* Which attributes to check */ + } stAttribs; /* Displays files with this attributes only */ + struct + { + enum EOrderBy eCriteria[3]; /* Criterias used to order by */ + BOOL bCriteriaRev[3]; /* If the criteria is in reversed order */ + short sCriteriaCount; /* The quantity of criterias */ + } stOrderBy; /* Ordered by criterias */ + struct + { + enum ETimeField eTimeField; /* The time field that will be used for */ + } stTimeField; /* The time field to display or use for sorting */ } DIRSWITCHFLAGS, *LPDIRSWITCHFLAGS; - typedef struct _DIRFINDLISTNODE { - WIN32_FIND_DATA stFindInfo; - struct _DIRFINDLISTNODE *ptrNext; + WIN32_FIND_DATA stFindInfo; + struct _DIRFINDLISTNODE *ptrNext; } DIRFINDLISTNODE, *PDIRFINDLISTNODE; - typedef BOOL (WINAPI *PGETFREEDISKSPACEEX)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); - /* Globally save the # of dirs, files and bytes, * probabaly later pass them to functions. Rob Lake */ static ULONG recurse_dir_cnt; static ULONG recurse_file_cnt; static ULONGLONG recurse_bytes; - /* * help * @@ -217,339 +213,337 @@ static ULONGLONG recurse_bytes; static VOID DirHelp(VOID) { - ConOutResPaging(TRUE, STRING_DIR_HELP1); + ConOutResPaging(TRUE, STRING_DIR_HELP1); } - - /* * DirReadParameters * * Parse the parameters and switches of the command line and exports them */ static BOOL -DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */ - LPTSTR** params, /* [OUT] The parameters after parsing */ - LPINT entries, /* [OUT] The number of parameters after parsing */ - LPDIRSWITCHFLAGS lpFlags) /* [IN/OUT] The flags after calculating switches */ +DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */ + LPTSTR** params, /* [OUT] The parameters after parsing */ + LPINT entries, /* [OUT] The number of parameters after parsing */ + LPDIRSWITCHFLAGS lpFlags) /* [IN/OUT] The flags after calculating switches */ { - TCHAR cCurSwitch; /* The current switch */ - TCHAR cCurChar; /* Current examing character */ - TCHAR cCurUChar; /* Current upper examing character */ - BOOL bNegative; /* Negative switch */ - BOOL bPNegative; /* Negative switch parameter */ - BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */ - LPTSTR ptrStart; /* A pointer to the first character of a parameter */ - LPTSTR ptrEnd; /* A pointer to the last character of a parameter */ - BOOL bOrderByNoPar; /* A flag to indicate /O with no switch parameter */ - LPTSTR temp; + TCHAR cCurSwitch; /* The current switch */ + TCHAR cCurChar; /* Current examing character */ + TCHAR cCurUChar; /* Current upper examing character */ + BOOL bNegative; /* Negative switch */ + BOOL bPNegative; /* Negative switch parameter */ + BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */ + LPTSTR ptrStart; /* A pointer to the first character of a parameter */ + LPTSTR ptrEnd; /* A pointer to the last character of a parameter */ + BOOL bOrderByNoPar; /* A flag to indicate /O with no switch parameter */ + LPTSTR temp; - /* Initialize parameter array */ - *params = NULL; - *entries = 0; + /* Initialize parameter array */ + *params = NULL; + *entries = 0; - /* Initialize variables; */ - cCurSwitch = _T(' '); - bNegative = FALSE; - bPNegative = FALSE; + /* Initialize variables; */ + cCurSwitch = _T(' '); + bNegative = FALSE; + bPNegative = FALSE; - /* We suppose that switch parameters - were given to avoid setting them to default - if the switch was not given */ - bOrderByNoPar = FALSE; + /* We suppose that switch parameters + were given to avoid setting them to default + if the switch was not given */ + bOrderByNoPar = FALSE; - /* Main Loop (see README_DIR.txt) */ - /* scan the command line char per char, and we process its char */ - while (*Line) - { - /* we save current character as it is and its upper case */ - cCurChar = *Line; - cCurUChar = _totupper(*Line); + /* Main Loop (see README_DIR.txt) */ + /* scan the command line char per char, and we process its char */ + while (*Line) + { + /* we save current character as it is and its upper case */ + cCurChar = *Line; + cCurUChar = _totupper(*Line); - /* 1st section (see README_DIR.txt) */ - /* When a switch is expecting */ - if (cCurSwitch == _T('/')) - { - while (*Line == _T(' ')) - Line++; + /* 1st section (see README_DIR.txt) */ + /* When a switch is expecting */ + if (cCurSwitch == _T('/')) + { + while (*Line == _T(' ')) + Line++; - bNegative = (*Line == _T('-')); - Line += bNegative; + bNegative = (*Line == _T('-')); + Line += bNegative; - cCurChar = *Line; - cCurUChar = _totupper(*Line); + cCurChar = *Line; + cCurUChar = _totupper(*Line); - if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O'))) - { - /* If positive, prepare for parameters... if negative, reset to defaults */ - switch (cCurUChar) - { - case _T('A'): - lpFlags->stAttribs.dwAttribVal = 0L; - lpFlags->stAttribs.dwAttribMask = 0L; - if (bNegative) - lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; - break; - case _T('T'): - if (bNegative) - lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE; - break; - case _T('O'): - bOrderByNoPar = !bNegative; - lpFlags->stOrderBy.sCriteriaCount = 0; - break; - } + if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O'))) + { + /* If positive, prepare for parameters... if negative, reset to defaults */ + switch (cCurUChar) + { + case _T('A'): + lpFlags->stAttribs.dwAttribVal = 0L; + lpFlags->stAttribs.dwAttribMask = 0L; + if (bNegative) + lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; + break; + case _T('T'): + if (bNegative) + lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE; + break; + case _T('O'): + bOrderByNoPar = !bNegative; + lpFlags->stOrderBy.sCriteriaCount = 0; + break; + } - if (!bNegative) - { - /* Positive switch, so it can take parameters. */ - cCurSwitch = cCurUChar; - Line++; - /* Skip optional leading colon */ - if (*Line == _T(':')) - Line++; - continue; - } - } - else if (cCurUChar == _T('L')) - lpFlags->bLowerCase = ! bNegative; - else if (cCurUChar == _T('B')) - lpFlags->bBareFormat = ! bNegative; - else if (cCurUChar == _T('C')) - lpFlags->bTSeperator = ! bNegative; - else if (cCurUChar == _T('W')) - lpFlags->bWideList = ! bNegative; - else if (cCurUChar == _T('D')) - lpFlags->bWideListColSort = ! bNegative; - else if (cCurUChar == _T('N')) - lpFlags->bNewLongList = ! bNegative; - else if (cCurUChar == _T('P')) - lpFlags->bPause = ! bNegative; - else if (cCurUChar == _T('Q')) - lpFlags->bUser = ! bNegative; - else if (cCurUChar == _T('S')) - lpFlags->bRecursive = ! bNegative; - else if (cCurUChar == _T('X')) - lpFlags->bShortName = ! bNegative; - else if (cCurChar == _T('4')) - lpFlags->b4Digit = ! bNegative; - else if (cCurChar == _T('?')) - { - DirHelp(); - return FALSE; - } - else - { - error_invalid_switch ((TCHAR)_totupper (*Line)); - return FALSE; - } + if (!bNegative) + { + /* Positive switch, so it can take parameters. */ + cCurSwitch = cCurUChar; + Line++; + /* Skip optional leading colon */ + if (*Line == _T(':')) + Line++; + continue; + } + } + else if (cCurUChar == _T('L')) + lpFlags->bLowerCase = ! bNegative; + else if (cCurUChar == _T('B')) + lpFlags->bBareFormat = ! bNegative; + else if (cCurUChar == _T('C')) + lpFlags->bTSeperator = ! bNegative; + else if (cCurUChar == _T('W')) + lpFlags->bWideList = ! bNegative; + else if (cCurUChar == _T('D')) + lpFlags->bWideListColSort = ! bNegative; + else if (cCurUChar == _T('N')) + lpFlags->bNewLongList = ! bNegative; + else if (cCurUChar == _T('P')) + lpFlags->bPause = ! bNegative; + else if (cCurUChar == _T('Q')) + lpFlags->bUser = ! bNegative; + else if (cCurUChar == _T('S')) + lpFlags->bRecursive = ! bNegative; + else if (cCurUChar == _T('X')) + lpFlags->bShortName = ! bNegative; + else if (cCurChar == _T('4')) + lpFlags->b4Digit = ! bNegative; + else if (cCurChar == _T('?')) + { + DirHelp(); + return FALSE; + } + else + { + error_invalid_switch ((TCHAR)_totupper (*Line)); + return FALSE; + } - /* Make sure there's no extra characters at the end of the switch */ - if (Line[1] && Line[1] != _T('/') && Line[1] != _T(' ')) - { - error_parameter_format(Line[1]); - return FALSE; - } + /* Make sure there's no extra characters at the end of the switch */ + if (Line[1] && Line[1] != _T('/') && Line[1] != _T(' ')) + { + error_parameter_format(Line[1]); + return FALSE; + } - cCurSwitch = _T(' '); - } - else if (cCurSwitch == _T(' ')) - { - /* 2nd section (see README_DIR.txt) */ - /* We are expecting parameter or the unknown */ + cCurSwitch = _T(' '); + } + else if (cCurSwitch == _T(' ')) + { + /* 2nd section (see README_DIR.txt) */ + /* We are expecting parameter or the unknown */ - if (cCurChar == _T('/')) - cCurSwitch = _T('/'); - else if (cCurChar == _T(' ')) - /* do nothing */; - else - { - /* This is a file/directory name parameter. Find its end */ - ptrStart = Line; - bIntoQuotes = FALSE; - while (*Line) - { - if (!bIntoQuotes && (*Line == _T('/') || *Line == _T(' '))) - break; - bIntoQuotes ^= (*Line == _T('"')); - Line++; - } - ptrEnd = Line; + if (cCurChar == _T('/')) + cCurSwitch = _T('/'); + else if (cCurChar == _T(' ')) + /* do nothing */; + else + { + /* This is a file/directory name parameter. Find its end */ + ptrStart = Line; + bIntoQuotes = FALSE; + while (*Line) + { + if (!bIntoQuotes && (*Line == _T('/') || *Line == _T(' '))) + break; + bIntoQuotes ^= (*Line == _T('"')); + Line++; + } + ptrEnd = Line; - /* Copy it to the entries list */ - temp = cmd_alloc((ptrEnd - ptrStart + 1) * sizeof (TCHAR)); - if(!temp) - return FALSE; - memcpy(temp, ptrStart, (ptrEnd - ptrStart) * sizeof (TCHAR)); - temp[ptrEnd - ptrStart] = _T('\0'); - StripQuotes(temp); - if(!add_entry(entries, params, temp)) - { - cmd_free(temp); - freep(*params); - return FALSE; - } + /* Copy it to the entries list */ + temp = cmd_alloc((ptrEnd - ptrStart + 1) * sizeof (TCHAR)); + if (!temp) + return FALSE; + memcpy(temp, ptrStart, (ptrEnd - ptrStart) * sizeof (TCHAR)); + temp[ptrEnd - ptrStart] = _T('\0'); + StripQuotes(temp); + if (!add_entry(entries, params, temp)) + { + cmd_free(temp); + freep(*params); + return FALSE; + } - cmd_free(temp); - continue; - } - } - else - { - /* 3rd section (see README_DIR.txt) */ - /* We are waiting for switch parameters */ + cmd_free(temp); + continue; + } + } + else + { + /* 3rd section (see README_DIR.txt) */ + /* We are waiting for switch parameters */ - /* Check if there are no more switch parameters */ - if ((cCurChar == _T('/')) || ( cCurChar == _T(' '))) - { - /* Wrong desicion path, reprocess current character */ - cCurSwitch = _T(' '); - continue; - } - /* Process parameter switch */ - switch(cCurSwitch) - { - case _T('A'): /* Switch parameters for /A (attributes filter) */ - if(cCurChar == _T('-')) - bPNegative = TRUE; - else if(cCurUChar == _T('D')) - { - lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_DIRECTORY; - if (bPNegative) - lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_DIRECTORY; - else - lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_DIRECTORY; - } - else if(cCurUChar == _T('R')) - { - lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_READONLY; - if (bPNegative) - lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_READONLY; - else - lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_READONLY; - } - else if(cCurUChar == _T('H')) - { - lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_HIDDEN; - if (bPNegative) - lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_HIDDEN; - else - lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_HIDDEN; - } - else if(cCurUChar == _T('A')) - { - lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_ARCHIVE; - if (bPNegative) - lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_ARCHIVE; - else - lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_ARCHIVE; - } - else if(cCurUChar == _T('S')) - { - lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_SYSTEM; - if (bPNegative) - lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_SYSTEM; - else - lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_SYSTEM; - } - else - { - error_parameter_format((TCHAR)_totupper (*Line)); - return FALSE; - } - break; - case _T('T'): /* Switch parameters for /T (time field) */ - if(cCurUChar == _T('C')) - lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ; - else if(cCurUChar == _T('A')) - lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ; - else if(cCurUChar == _T('W')) - lpFlags->stTimeField.eTimeField= TF_MODIFIEDDATE ; - else - { - error_parameter_format((TCHAR)_totupper (*Line)); - return FALSE; - } - break; - case _T('O'): /* Switch parameters for /O (order) */ - /* Ok a switch parameter was given */ - bOrderByNoPar = FALSE; + /* Check if there are no more switch parameters */ + if ((cCurChar == _T('/')) || ( cCurChar == _T(' '))) + { + /* Wrong desicion path, reprocess current character */ + cCurSwitch = _T(' '); + continue; + } + /* Process parameter switch */ + switch(cCurSwitch) + { + case _T('A'): /* Switch parameters for /A (attributes filter) */ + if (cCurChar == _T('-')) + bPNegative = TRUE; + else if (cCurUChar == _T('D')) + { + lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_DIRECTORY; + if (bPNegative) + lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_DIRECTORY; + else + lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_DIRECTORY; + } + else if (cCurUChar == _T('R')) + { + lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_READONLY; + if (bPNegative) + lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_READONLY; + else + lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_READONLY; + } + else if (cCurUChar == _T('H')) + { + lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_HIDDEN; + if (bPNegative) + lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_HIDDEN; + else + lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_HIDDEN; + } + else if (cCurUChar == _T('A')) + { + lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_ARCHIVE; + if (bPNegative) + lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_ARCHIVE; + else + lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_ARCHIVE; + } + else if (cCurUChar == _T('S')) + { + lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_SYSTEM; + if (bPNegative) + lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_SYSTEM; + else + lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_SYSTEM; + } + else + { + error_parameter_format((TCHAR)_totupper (*Line)); + return FALSE; + } + break; + case _T('T'): /* Switch parameters for /T (time field) */ + if (cCurUChar == _T('C')) + lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ; + else if (cCurUChar == _T('A')) + lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ; + else if (cCurUChar == _T('W')) + lpFlags->stTimeField.eTimeField= TF_MODIFIEDDATE ; + else + { + error_parameter_format((TCHAR)_totupper (*Line)); + return FALSE; + } + break; + case _T('O'): /* Switch parameters for /O (order) */ + /* Ok a switch parameter was given */ + bOrderByNoPar = FALSE; - if(cCurChar == _T('-')) - bPNegative = TRUE; - else if(cCurUChar == _T('N')) - { - if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; - lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; - lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_NAME; - } - else if(cCurUChar == _T('S')) - { - if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; - lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; - lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_SIZE; - } - else if(cCurUChar == _T('G')) - { - if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; - lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; - lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_DIRECTORY; - } - else if(cCurUChar == _T('E')) - { - if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; - lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; - lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_EXTENSION; - } - else if(cCurUChar == _T('D')) - { - if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; - lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; - lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_TIME; - } + if (cCurChar == _T('-')) + bPNegative = TRUE; + else if (cCurUChar == _T('N')) + { + if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; + lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; + lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_NAME; + } + else if (cCurUChar == _T('S')) + { + if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; + lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; + lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_SIZE; + } + else if (cCurUChar == _T('G')) + { + if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; + lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; + lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_DIRECTORY; + } + else if (cCurUChar == _T('E')) + { + if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; + lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; + lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_EXTENSION; + } + else if (cCurUChar == _T('D')) + { + if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++; + lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative; + lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_TIME; + } - else - { - error_parameter_format((TCHAR)_totupper (*Line)); - return FALSE; - } + else + { + error_parameter_format((TCHAR)_totupper (*Line)); + return FALSE; + } - } - /* We check if we calculated the negative value and realese the flag */ - if ((cCurChar != _T('-')) && bPNegative) - bPNegative = FALSE; - } + } + /* We check if we calculated the negative value and realese the flag */ + if ((cCurChar != _T('-')) && bPNegative) + bPNegative = FALSE; + } - Line++; - } + Line++; + } - /* /O with no switch parameters acts like /O:GN */ - if (bOrderByNoPar) - { - lpFlags->stOrderBy.sCriteriaCount = 2; - lpFlags->stOrderBy.eCriteria[0] = ORDER_DIRECTORY; - lpFlags->stOrderBy.bCriteriaRev[0] = FALSE; - lpFlags->stOrderBy.eCriteria[1] = ORDER_NAME; - lpFlags->stOrderBy.bCriteriaRev[1] = FALSE; - } + /* /O with no switch parameters acts like /O:GN */ + if (bOrderByNoPar) + { + lpFlags->stOrderBy.sCriteriaCount = 2; + lpFlags->stOrderBy.eCriteria[0] = ORDER_DIRECTORY; + lpFlags->stOrderBy.bCriteriaRev[0] = FALSE; + lpFlags->stOrderBy.eCriteria[1] = ORDER_NAME; + lpFlags->stOrderBy.bCriteriaRev[1] = FALSE; + } - return TRUE; + return TRUE; } /* Print either with or without paging, depending on /P switch */ static INT DirPrintf(LPDIRSWITCHFLAGS lpFlags, LPTSTR szFormat, ...) { - INT iReturn = 0; - va_list arg_ptr; - va_start(arg_ptr, szFormat); - if (lpFlags->bPause) - iReturn = ConPrintfPaging(FALSE, szFormat, arg_ptr, STD_OUTPUT_HANDLE); - else - ConPrintf(szFormat, arg_ptr, STD_OUTPUT_HANDLE); - va_end(arg_ptr); - return iReturn; + INT iReturn = 0; + va_list arg_ptr; + va_start(arg_ptr, szFormat); + if (lpFlags->bPause) + iReturn = ConPrintfPaging(FALSE, szFormat, arg_ptr, STD_OUTPUT_HANDLE); + else + ConPrintf(szFormat, arg_ptr, STD_OUTPUT_HANDLE); + va_end(arg_ptr); + return iReturn; } @@ -561,50 +555,50 @@ DirPrintf(LPDIRSWITCHFLAGS lpFlags, LPTSTR szFormat, ...) static BOOL PrintDirectoryHeader(LPTSTR szPath, LPDIRSWITCHFLAGS lpFlags) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - TCHAR szFullDir[MAX_PATH]; - TCHAR szRootName[MAX_PATH]; - TCHAR szVolName[80]; - LPTSTR pszFilePart; - DWORD dwSerialNr; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szFullDir[MAX_PATH]; + TCHAR szRootName[MAX_PATH]; + TCHAR szVolName[80]; + LPTSTR pszFilePart; + DWORD dwSerialNr; + + if (lpFlags->bBareFormat) + return TRUE; + + if (GetFullPathName(szPath, sizeof(szFullDir) / sizeof(TCHAR), szFullDir, &pszFilePart) == 0) + { + ErrorMessage(GetLastError(), _T("Failed to build full directory path")); + return FALSE; + } + + if (pszFilePart != NULL) + *pszFilePart = _T('\0'); + + /* get the media ID of the drive */ + if (!GetVolumePathName(szFullDir, szRootName, sizeof(szRootName) / sizeof(TCHAR)) || + !GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr, + NULL, NULL, NULL, 0)) + { + return TRUE; + } + + /* print drive info */ + if (szVolName[0] != _T('\0')) + { + LoadString(CMD_ModuleHandle, STRING_DIR_HELP2, szMsg, RC_STRING_MAX_SIZE); + DirPrintf(lpFlags, szMsg, szRootName[0], szVolName); + } + else + { + LoadString(CMD_ModuleHandle, STRING_DIR_HELP3, szMsg, RC_STRING_MAX_SIZE); + DirPrintf(lpFlags, szMsg, szRootName[0]); + } + + /* print the volume serial number if the return was successful */ + LoadString(CMD_ModuleHandle, STRING_DIR_HELP4, (LPTSTR) szMsg, RC_STRING_MAX_SIZE); + DirPrintf(lpFlags, szMsg, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); - if (lpFlags->bBareFormat) return TRUE; - - if (GetFullPathName(szPath, sizeof(szFullDir) / sizeof(TCHAR), szFullDir, &pszFilePart) == 0) - { - ErrorMessage(GetLastError(), _T("Failed to build full directory path")); - return FALSE; - } - - if (pszFilePart != NULL) - *pszFilePart = _T('\0'); - - /* get the media ID of the drive */ - if (!GetVolumePathName(szFullDir, szRootName, sizeof(szRootName) / sizeof(TCHAR)) || - !GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr, - NULL, NULL, NULL, 0)) - { - return(TRUE); - } - - /* print drive info */ - if (szVolName[0] != _T('\0')) - { - LoadString(CMD_ModuleHandle, STRING_DIR_HELP2, szMsg, RC_STRING_MAX_SIZE); - DirPrintf(lpFlags, szMsg, szRootName[0], szVolName); - } - else - { - LoadString(CMD_ModuleHandle, STRING_DIR_HELP3, szMsg, RC_STRING_MAX_SIZE); - DirPrintf(lpFlags, szMsg, szRootName[0]); - } - - /* print the volume serial number if the return was successful */ - LoadString(CMD_ModuleHandle, STRING_DIR_HELP4, (LPTSTR) szMsg, RC_STRING_MAX_SIZE); - DirPrintf(lpFlags, szMsg, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); - - return TRUE; } @@ -614,123 +608,123 @@ DirPrintFileDateTime(TCHAR *lpDate, LPWIN32_FIND_DATA lpFile, LPDIRSWITCHFLAGS lpFlags) { - FILETIME ft; - SYSTEMTIME dt; + FILETIME ft; + SYSTEMTIME dt; - /* Select the right time field */ - switch (lpFlags->stTimeField.eTimeField) - { - case TF_CREATIONDATE: - if (!FileTimeToLocalFileTime(&lpFile->ftCreationTime, &ft)) - return; - FileTimeToSystemTime(&ft, &dt); - break; + /* Select the right time field */ + switch (lpFlags->stTimeField.eTimeField) + { + case TF_CREATIONDATE: + if (!FileTimeToLocalFileTime(&lpFile->ftCreationTime, &ft)) + return; + FileTimeToSystemTime(&ft, &dt); + break; - case TF_LASTACCESSEDDATE : - if (!FileTimeToLocalFileTime(&lpFile->ftLastAccessTime, &ft)) - return; - FileTimeToSystemTime(&ft, &dt); - break; + case TF_LASTACCESSEDDATE : + if (!FileTimeToLocalFileTime(&lpFile->ftLastAccessTime, &ft)) + return; + FileTimeToSystemTime(&ft, &dt); + break; - case TF_MODIFIEDDATE: - if (!FileTimeToLocalFileTime(&lpFile->ftLastWriteTime, &ft)) - return; - FileTimeToSystemTime(&ft, &dt); - break; - } + case TF_MODIFIEDDATE: + if (!FileTimeToLocalFileTime(&lpFile->ftLastWriteTime, &ft)) + return; + FileTimeToSystemTime(&ft, &dt); + break; + } - FormatDate(lpDate, &dt, lpFlags->b4Digit); - FormatTime(lpTime, &dt); + FormatDate(lpDate, &dt, lpFlags->b4Digit); + FormatTime(lpTime, &dt); } INT FormatDate(TCHAR *lpDate, LPSYSTEMTIME dt, BOOL b4Digit) { - /* Format date */ - WORD wYear = b4Digit ? dt->wYear : dt->wYear%100; - switch (nDateFormat) - { - case 0: /* mmddyy */ - default: - return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"), - dt->wMonth, cDateSeparator, - dt->wDay, cDateSeparator, - b4Digit?4:2, wYear); - break; + /* Format date */ + WORD wYear = b4Digit ? dt->wYear : dt->wYear%100; + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"), + dt->wMonth, cDateSeparator, + dt->wDay, cDateSeparator, + b4Digit?4:2, wYear); + break; - case 1: /* ddmmyy */ - return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"), - dt->wDay, cDateSeparator, dt->wMonth, - cDateSeparator, b4Digit?4:2, wYear); - break; + case 1: /* ddmmyy */ + return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"), + dt->wDay, cDateSeparator, dt->wMonth, + cDateSeparator, b4Digit?4:2, wYear); + break; - case 2: /* yymmdd */ - return _stprintf(lpDate, _T("%0*d%c%02d%c%02d"), - b4Digit?4:2, wYear, cDateSeparator, - dt->wMonth, cDateSeparator, dt->wDay); - break; - } + case 2: /* yymmdd */ + return _stprintf(lpDate, _T("%0*d%c%02d%c%02d"), + b4Digit?4:2, wYear, cDateSeparator, + dt->wMonth, cDateSeparator, dt->wDay); + break; + } } INT FormatTime(TCHAR *lpTime, LPSYSTEMTIME dt) { - /* Format Time */ - switch (nTimeFormat) - { - case 0: /* 12 hour format */ - default: - return _stprintf(lpTime,_T("%02d%c%02u %cM"), - (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)), - cTimeSeparator, - dt->wMinute, (dt->wHour <= 11 ? _T('A') : _T('P'))); - break; + /* Format Time */ + switch (nTimeFormat) + { + case 0: /* 12 hour format */ + default: + return _stprintf(lpTime,_T("%02d%c%02u %cM"), + (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)), + cTimeSeparator, + dt->wMinute, (dt->wHour <= 11 ? _T('A') : _T('P'))); + break; - case 1: /* 24 hour format */ - return _stprintf(lpTime, _T("%02d%c%02u"), - dt->wHour, cTimeSeparator, dt->wMinute); - break; - } + case 1: /* 24 hour format */ + return _stprintf(lpTime, _T("%02d%c%02u"), + dt->wHour, cTimeSeparator, dt->wMinute); + break; + } } static VOID GetUserDiskFreeSpace(LPCTSTR lpRoot, - PULARGE_INTEGER lpFreeSpace) + PULARGE_INTEGER lpFreeSpace) { - PGETFREEDISKSPACEEX pGetFreeDiskSpaceEx; - HINSTANCE hInstance; - DWORD dwSecPerCl; - DWORD dwBytPerSec; - DWORD dwFreeCl; - DWORD dwTotCl; - ULARGE_INTEGER TotalNumberOfBytes, TotalNumberOfFreeBytes; + PGETFREEDISKSPACEEX pGetFreeDiskSpaceEx; + HINSTANCE hInstance; + DWORD dwSecPerCl; + DWORD dwBytPerSec; + DWORD dwFreeCl; + DWORD dwTotCl; + ULARGE_INTEGER TotalNumberOfBytes, TotalNumberOfFreeBytes; - lpFreeSpace->QuadPart = 0; + lpFreeSpace->QuadPart = 0; - hInstance = GetModuleHandle(_T("KERNEL32")); - if (hInstance != NULL) + hInstance = GetModuleHandle(_T("KERNEL32")); + if (hInstance != NULL) { - pGetFreeDiskSpaceEx = (PGETFREEDISKSPACEEX)GetProcAddress(hInstance, + pGetFreeDiskSpaceEx = (PGETFREEDISKSPACEEX)GetProcAddress(hInstance, #ifdef _UNICODE - "GetDiskFreeSpaceExW"); + "GetDiskFreeSpaceExW"); #else - "GetDiskFreeSpaceExA"); + "GetDiskFreeSpaceExA"); #endif - if (pGetFreeDiskSpaceEx != NULL) - { - if (pGetFreeDiskSpaceEx(lpRoot, lpFreeSpace, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == TRUE) - return; - } + if (pGetFreeDiskSpaceEx != NULL) + { + if (pGetFreeDiskSpaceEx(lpRoot, lpFreeSpace, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == TRUE) + return; + } } - GetDiskFreeSpace(lpRoot, - &dwSecPerCl, - &dwBytPerSec, - &dwFreeCl, - &dwTotCl); + GetDiskFreeSpace(lpRoot, + &dwSecPerCl, + &dwBytPerSec, + &dwFreeCl, + &dwTotCl); - lpFreeSpace->QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl; + lpFreeSpace->QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl; } @@ -738,63 +732,60 @@ GetUserDiskFreeSpace(LPCTSTR lpRoot, * print_summary: prints dir summary * Added by Rob Lake 06/17/98 to compact code * Just copied Tim's Code and patched it a bit - * */ static INT PrintSummary(LPTSTR szPath, - ULONG ulFiles, - ULONG ulDirs, - ULONGLONG u64Bytes, - LPDIRSWITCHFLAGS lpFlags, - BOOL TotalSummary) + ULONG ulFiles, + ULONG ulDirs, + ULONGLONG u64Bytes, + LPDIRSWITCHFLAGS lpFlags, + BOOL TotalSummary) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - TCHAR szBuffer[64]; - ULARGE_INTEGER uliFree; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szBuffer[64]; + ULARGE_INTEGER uliFree; + /* Here we check if we didn't find anything */ + if (!(ulFiles + ulDirs)) + { + if (!lpFlags->bRecursive || (TotalSummary && lpFlags->bRecursive)) + error_file_not_found(); + return 1; + } - /* Here we check if we didn't find anything */ - if (!(ulFiles + ulDirs)) - { - if (!lpFlags->bRecursive || (TotalSummary && lpFlags->bRecursive)) - error_file_not_found(); - return 1; - } + /* In bare format we don't print results */ + if (lpFlags->bBareFormat) + return 0; - - /* In bare format we don't print results */ - if (lpFlags->bBareFormat) - return 0; - - /* Print recursive specific results */ + /* Print recursive specific results */ /* Take this code offline to fix /S does not print duoble info */ - if (TotalSummary && lpFlags->bRecursive) - { - ConvertULargeInteger(u64Bytes, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator); - LoadString(CMD_ModuleHandle, STRING_DIR_HELP5, szMsg, RC_STRING_MAX_SIZE); - DirPrintf(lpFlags, szMsg, ulFiles, szBuffer); - } - else - { - /* Print File Summary */ - /* Condition to print summary is: - If we are not in bare format and if we have results! */ - ConvertULargeInteger(u64Bytes, szBuffer, 20, lpFlags->bTSeperator); - LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE); - DirPrintf(lpFlags, szMsg, ulFiles, szBuffer); - } + if (TotalSummary && lpFlags->bRecursive) + { + ConvertULargeInteger(u64Bytes, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator); + LoadString(CMD_ModuleHandle, STRING_DIR_HELP5, szMsg, RC_STRING_MAX_SIZE); + DirPrintf(lpFlags, szMsg, ulFiles, szBuffer); + } + else + { + /* Print File Summary */ + /* Condition to print summary is: + If we are not in bare format and if we have results! */ + ConvertULargeInteger(u64Bytes, szBuffer, 20, lpFlags->bTSeperator); + LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE); + DirPrintf(lpFlags, szMsg, ulFiles, szBuffer); + } - /* Print total directories and freespace */ - if (!lpFlags->bRecursive || TotalSummary) - { - GetUserDiskFreeSpace(szPath, &uliFree); - ConvertULargeInteger(uliFree.QuadPart, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator); - LoadString(CMD_ModuleHandle, STRING_DIR_HELP6, (LPTSTR) szMsg, RC_STRING_MAX_SIZE); - DirPrintf(lpFlags, szMsg, ulDirs, szBuffer); - } + /* Print total directories and freespace */ + if (!lpFlags->bRecursive || TotalSummary) + { + GetUserDiskFreeSpace(szPath, &uliFree); + ConvertULargeInteger(uliFree.QuadPart, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator); + LoadString(CMD_ModuleHandle, STRING_DIR_HELP6, (LPTSTR) szMsg, RC_STRING_MAX_SIZE); + DirPrintf(lpFlags, szMsg, ulDirs, szBuffer); + } - return 0; + return 0; } /* @@ -804,9 +795,9 @@ PrintSummary(LPTSTR szPath, */ TCHAR* getExt(const TCHAR* file) { - static TCHAR *NoExt = _T(""); - TCHAR* lastdot = _tcsrchr(file, _T('.')); - return (lastdot != NULL ? lastdot + 1 : NoExt); + static TCHAR *NoExt = _T(""); + TCHAR* lastdot = _tcsrchr(file, _T('.')); + return (lastdot != NULL ? lastdot + 1 : NoExt); } /* @@ -817,28 +808,27 @@ TCHAR* getExt(const TCHAR* file) static LPTSTR getName(const TCHAR* file, TCHAR * dest) { - INT_PTR iLen; - LPTSTR end; + INT_PTR iLen; + LPTSTR end; - /* Check for "." and ".." folders */ - if ((_tcscmp(file, _T(".")) == 0) || - (_tcscmp(file, _T("..")) == 0)) - { - _tcscpy(dest,file); - return dest; - } + /* Check for "." and ".." folders */ + if ((_tcscmp(file, _T(".")) == 0) || + (_tcscmp(file, _T("..")) == 0)) + { + _tcscpy(dest,file); + return dest; + } - end = _tcsrchr(file, _T('.')); - if (!end) - iLen = _tcslen(file); - else - iLen = (end - file); + end = _tcsrchr(file, _T('.')); + if (!end) + iLen = _tcslen(file); + else + iLen = (end - file); + _tcsncpy(dest, file, iLen); + *(dest + iLen) = _T('\0'); - _tcsncpy(dest, file, iLen); - *(dest + iLen) = _T('\0'); - - return dest; + return dest; } @@ -848,60 +838,60 @@ getName(const TCHAR* file, TCHAR * dest) * The function that prints in new style */ static VOID -DirPrintNewList(LPWIN32_FIND_DATA ptrFiles[], /* [IN]Files' Info */ - DWORD dwCount, /* [IN] The quantity of files */ - TCHAR *szCurPath, /* [IN] Full path of current directory */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ +DirPrintNewList(LPWIN32_FIND_DATA ptrFiles[], /* [IN]Files' Info */ + DWORD dwCount, /* [IN] The quantity of files */ + TCHAR *szCurPath, /* [IN] Full path of current directory */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ { - DWORD i; - TCHAR szSize[30]; - TCHAR szShortName[15]; - TCHAR szDate[20]; - TCHAR szTime[20]; - INT iSizeFormat; - ULARGE_INTEGER u64FileSize; + DWORD i; + TCHAR szSize[30]; + TCHAR szShortName[15]; + TCHAR szDate[20]; + TCHAR szTime[20]; + INT iSizeFormat; + ULARGE_INTEGER u64FileSize; - for (i = 0; i < dwCount && !bCtrlBreak; i++) - { - /* Calculate size */ - if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + for (i = 0; i < dwCount && !bCtrlBreak; i++) { - /* Junction */ - iSizeFormat = -14; - _tcscpy(szSize, _T("")); - } - else if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - /* Directory */ - iSizeFormat = -14; - _tcscpy(szSize, _T("")); - } - else - { - /* File */ - iSizeFormat = 14; - u64FileSize.HighPart = ptrFiles[i]->nFileSizeHigh; - u64FileSize.LowPart = ptrFiles[i]->nFileSizeLow; - ConvertULargeInteger(u64FileSize.QuadPart, szSize, 20, lpFlags->bTSeperator); - } + /* Calculate size */ + if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + { + /* Junction */ + iSizeFormat = -14; + _tcscpy(szSize, _T("")); + } + else if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + /* Directory */ + iSizeFormat = -14; + _tcscpy(szSize, _T("")); + } + else + { + /* File */ + iSizeFormat = 14; + u64FileSize.HighPart = ptrFiles[i]->nFileSizeHigh; + u64FileSize.LowPart = ptrFiles[i]->nFileSizeLow; + ConvertULargeInteger(u64FileSize.QuadPart, szSize, 20, lpFlags->bTSeperator); + } - /* Calculate short name */ - szShortName[0] = _T('\0'); - if (lpFlags->bShortName) - _stprintf(szShortName, _T(" %-12s"), ptrFiles[i]->cAlternateFileName); + /* Calculate short name */ + szShortName[0] = _T('\0'); + if (lpFlags->bShortName) + _stprintf(szShortName, _T(" %-12s"), ptrFiles[i]->cAlternateFileName); - /* Format date and time */ - DirPrintFileDateTime(szDate, szTime, ptrFiles[i], lpFlags); + /* Format date and time */ + DirPrintFileDateTime(szDate, szTime, ptrFiles[i], lpFlags); - /* Print the line */ - DirPrintf(lpFlags, _T("%10s %-6s %*s%s %s\n"), - szDate, - szTime, - iSizeFormat, - szSize, - szShortName, - ptrFiles[i]->cFileName); - } + /* Print the line */ + DirPrintf(lpFlags, _T("%10s %-6s %*s%s %s\n"), + szDate, + szTime, + iSizeFormat, + szSize, + szShortName, + ptrFiles[i]->cFileName); + } } @@ -911,81 +901,79 @@ DirPrintNewList(LPWIN32_FIND_DATA ptrFiles[], /* [IN]Files' Info */ * The function that prints in wide list */ static VOID -DirPrintWideList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ - DWORD dwCount, /* [IN] The quantity of files */ - TCHAR *szCurPath, /* [IN] Full path of current directory */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ +DirPrintWideList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ + DWORD dwCount, /* [IN] The quantity of files */ + TCHAR *szCurPath, /* [IN] Full path of current directory */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ { - SHORT iScreenWidth; - USHORT iColumns; - USHORT iLines; - UINT_PTR iLongestName; - TCHAR szTempFname[MAX_PATH]; - DWORD i; - DWORD j; - DWORD temp; + SHORT iScreenWidth; + USHORT iColumns; + USHORT iLines; + UINT_PTR iLongestName; + TCHAR szTempFname[MAX_PATH]; + DWORD i; + DWORD j; + DWORD temp; - /* Calculate longest name */ - iLongestName = 1; - for (i = 0; i < dwCount; i++) - { - if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + /* Calculate longest name */ + iLongestName = 1; + for (i = 0; i < dwCount; i++) { - /* Directories need 2 additinal characters for brackets */ - if ((_tcslen(ptrFiles[i]->cFileName) + 2) > iLongestName) - iLongestName = _tcslen(ptrFiles[i]->cFileName) + 2; - } - else - { - if (_tcslen(ptrFiles[i]->cFileName) > iLongestName) - iLongestName = _tcslen(ptrFiles[i]->cFileName); - } - } - - /* Count the highest number of columns */ - GetScreenSize(&iScreenWidth, 0); - iColumns = (USHORT)(iScreenWidth / iLongestName); - - /* Check if there is enough space for spaces between names */ - if (((iLongestName * iColumns) + iColumns) >= (UINT)iScreenWidth) - iColumns --; - - /* A last check at iColumns to avoid division by zero */ - if (!(iColumns)) - iColumns = 1; - - /* Calculate the lines that will be printed */ - iLines = (USHORT)((dwCount + iColumns - 1) / iColumns); - - for (i = 0; i < iLines && !bCtrlBreak; i++) - { - for (j = 0; j < iColumns; j++) - { - if (lpFlags->bWideListColSort) - { - /* Print Column sorted */ - temp = (j * iLines) + i; - } - else - { - /* Print Line sorted */ - temp = (i * iColumns) + j; - } - - if (temp >= dwCount) - break; - - if (ptrFiles[temp]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - _stprintf(szTempFname, _T("[%s]"), ptrFiles[temp]->cFileName); - else - _stprintf(szTempFname, _T("%s"), ptrFiles[temp]->cFileName); - - DirPrintf(lpFlags, _T("%-*s"), iLongestName + 1, szTempFname); + if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + /* Directories need 2 additinal characters for brackets */ + if ((_tcslen(ptrFiles[i]->cFileName) + 2) > iLongestName) + iLongestName = _tcslen(ptrFiles[i]->cFileName) + 2; + } + else + { + if (_tcslen(ptrFiles[i]->cFileName) > iLongestName) + iLongestName = _tcslen(ptrFiles[i]->cFileName); + } } - /* Add a new line after the last item in the column */ - DirPrintf(lpFlags, _T("\n")); - } + /* Count the highest number of columns */ + GetScreenSize(&iScreenWidth, 0); + iColumns = (USHORT)(iScreenWidth / iLongestName); + + /* Check if there is enough space for spaces between names */ + if (((iLongestName * iColumns) + iColumns) >= (UINT)iScreenWidth) + iColumns --; + + /* A last check at iColumns to avoid division by zero */ + if (!iColumns) iColumns = 1; + + /* Calculate the lines that will be printed */ + iLines = (USHORT)((dwCount + iColumns - 1) / iColumns); + + for (i = 0; i < iLines && !bCtrlBreak; i++) + { + for (j = 0; j < iColumns; j++) + { + if (lpFlags->bWideListColSort) + { + /* Print Column sorted */ + temp = (j * iLines) + i; + } + else + { + /* Print Line sorted */ + temp = (i * iColumns) + j; + } + + if (temp >= dwCount) break; + + if (ptrFiles[temp]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + _stprintf(szTempFname, _T("[%s]"), ptrFiles[temp]->cFileName); + else + _stprintf(szTempFname, _T("%s"), ptrFiles[temp]->cFileName); + + DirPrintf(lpFlags, _T("%-*s"), iLongestName + 1, szTempFname); + } + + /* Add a new line after the last item in the column */ + DirPrintf(lpFlags, _T("\n")); + } } @@ -995,63 +983,63 @@ DirPrintWideList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ * The function that prints in old style */ static VOID -DirPrintOldList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ - DWORD dwCount, /* [IN] The quantity of files */ - TCHAR * szCurPath, /* [IN] Full path of current directory */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ +DirPrintOldList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ + DWORD dwCount, /* [IN] The quantity of files */ + TCHAR * szCurPath, /* [IN] Full path of current directory */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ { -DWORD i; /* An indexer for "for"s */ -TCHAR szName[10]; /* The name of file */ -TCHAR szExt[5]; /* The extension of file */ -TCHAR szDate[30],szTime[30]; /* Used to format time and date */ -TCHAR szSize[30]; /* The size of file */ -int iSizeFormat; /* The format of size field */ -ULARGE_INTEGER u64FileSize; /* The file size */ + DWORD i; /* An indexer for "for"s */ + TCHAR szName[10]; /* The name of file */ + TCHAR szExt[5]; /* The extension of file */ + TCHAR szDate[30],szTime[30]; /* Used to format time and date */ + TCHAR szSize[30]; /* The size of file */ + int iSizeFormat; /* The format of size field */ + ULARGE_INTEGER u64FileSize; /* The file size */ - for (i = 0; i < dwCount && !bCtrlBreak; i++) - { - /* Broke 8.3 format */ - if (*ptrFiles[i]->cAlternateFileName ) - { - /* If the file is long named then we read the alter name */ - getName( ptrFiles[i]->cAlternateFileName, szName); - _tcscpy(szExt, getExt( ptrFiles[i]->cAlternateFileName)); - } - else - { - /* If the file is not long name we read its original name */ - getName( ptrFiles[i]->cFileName, szName); - _tcscpy(szExt, getExt( ptrFiles[i]->cFileName)); - } + for (i = 0; i < dwCount && !bCtrlBreak; i++) + { + /* Broke 8.3 format */ + if (*ptrFiles[i]->cAlternateFileName ) + { + /* If the file is long named then we read the alter name */ + getName( ptrFiles[i]->cAlternateFileName, szName); + _tcscpy(szExt, getExt( ptrFiles[i]->cAlternateFileName)); + } + else + { + /* If the file is not long name we read its original name */ + getName( ptrFiles[i]->cFileName, szName); + _tcscpy(szExt, getExt( ptrFiles[i]->cFileName)); + } - /* Calculate size */ - if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - /* Directory, no size it's a directory*/ - iSizeFormat = -17; - _tcscpy(szSize, _T("")); - } - else - { - /* File */ - iSizeFormat = 17; - u64FileSize.HighPart = ptrFiles[i]->nFileSizeHigh; - u64FileSize.LowPart = ptrFiles[i]->nFileSizeLow; - ConvertULargeInteger(u64FileSize.QuadPart, szSize, 20, lpFlags->bTSeperator); - } + /* Calculate size */ + if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + /* Directory, no size it's a directory*/ + iSizeFormat = -17; + _tcscpy(szSize, _T("")); + } + else + { + /* File */ + iSizeFormat = 17; + u64FileSize.HighPart = ptrFiles[i]->nFileSizeHigh; + u64FileSize.LowPart = ptrFiles[i]->nFileSizeLow; + ConvertULargeInteger(u64FileSize.QuadPart, szSize, 20, lpFlags->bTSeperator); + } - /* Format date and time */ - DirPrintFileDateTime(szDate,szTime,ptrFiles[i],lpFlags); + /* Format date and time */ + DirPrintFileDateTime(szDate,szTime,ptrFiles[i],lpFlags); - /* Print the line */ - DirPrintf(lpFlags, _T("%-8s %-3s %*s %s %s\n"), - szName, /* The file's 8.3 name */ - szExt, /* The file's 8.3 extension */ - iSizeFormat, /* print format for size column */ - szSize, /* The size of file or "" for dirs */ - szDate, /* The date of file/dir */ - szTime); /* The time of file/dir */ - } + /* Print the line */ + DirPrintf(lpFlags, _T("%-8s %-3s %*s %s %s\n"), + szName, /* The file's 8.3 name */ + szExt, /* The file's 8.3 extension */ + iSizeFormat, /* print format for size column */ + szSize, /* The size of file or "" for dirs */ + szDate, /* The date of file/dir */ + szTime); /* The time of file/dir */ + } } /* @@ -1060,32 +1048,32 @@ ULARGE_INTEGER u64FileSize; /* The file size */ * The function that prints in bare format */ static VOID -DirPrintBareList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ - DWORD dwCount, /* [IN] The number of files */ - LPTSTR lpCurPath, /* [IN] Full path of current directory */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ +DirPrintBareList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ + DWORD dwCount, /* [IN] The number of files */ + LPTSTR lpCurPath, /* [IN] Full path of current directory */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ { - DWORD i; + DWORD i; - for (i = 0; i < dwCount && !bCtrlBreak; i++) - { - if ((_tcscmp(ptrFiles[i]->cFileName, _T(".")) == 0) || - (_tcscmp(ptrFiles[i]->cFileName, _T("..")) == 0)) - { - /* at bare format we don't print "." and ".." folder */ - continue; - } - if (lpFlags->bRecursive) - { - /* at recursive mode we print full path of file */ - DirPrintf(lpFlags, _T("%s\\%s\n"), lpCurPath, ptrFiles[i]->cFileName); - } - else - { - /* if we are not in recursive mode we print the file names */ - DirPrintf(lpFlags, _T("%s\n"), ptrFiles[i]->cFileName); - } - } + for (i = 0; i < dwCount && !bCtrlBreak; i++) + { + if ((_tcscmp(ptrFiles[i]->cFileName, _T(".")) == 0) || + (_tcscmp(ptrFiles[i]->cFileName, _T("..")) == 0)) + { + /* at bare format we don't print "." and ".." folder */ + continue; + } + if (lpFlags->bRecursive) + { + /* at recursive mode we print full path of file */ + DirPrintf(lpFlags, _T("%s\\%s\n"), lpCurPath, ptrFiles[i]->cFileName); + } + else + { + /* if we are not in recursive mode we print the file names */ + DirPrintf(lpFlags, _T("%s\n"), ptrFiles[i]->cFileName); + } + } } @@ -1095,157 +1083,155 @@ DirPrintBareList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ * The functions that prints the files list */ static VOID -DirPrintFiles(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ - DWORD dwCount, /* [IN] The quantity of files */ - TCHAR *szCurPath, /* [IN] Full path of current directory */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ +DirPrintFiles(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ + DWORD dwCount, /* [IN] The quantity of files */ + TCHAR *szCurPath, /* [IN] Full path of current directory */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags used */ { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - TCHAR szTemp[MAX_PATH]; /* A buffer to format the directory header */ + TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szTemp[MAX_PATH]; /* A buffer to format the directory header */ - /* Print trailing backslash for root directory of drive */ - _tcscpy(szTemp, szCurPath); - if (_tcslen(szTemp) == 2 && szTemp[1] == _T(':')) - _tcscat(szTemp, _T("\\")); + /* Print trailing backslash for root directory of drive */ + _tcscpy(szTemp, szCurPath); + if (_tcslen(szTemp) == 2 && szTemp[1] == _T(':')) + _tcscat(szTemp, _T("\\")); - /* Condition to print header: - We are not printing in bare format - and if we are in recursive mode... we must have results */ - if (!(lpFlags->bBareFormat ) && !((lpFlags->bRecursive) && (dwCount <= 0))) - { - LoadString(CMD_ModuleHandle, STRING_DIR_HELP7, szMsg, RC_STRING_MAX_SIZE); - if (DirPrintf(lpFlags, szMsg, szTemp)) - return; - } + /* Condition to print header: + We are not printing in bare format + and if we are in recursive mode... we must have results */ + if (!(lpFlags->bBareFormat ) && !((lpFlags->bRecursive) && (dwCount <= 0))) + { + LoadString(CMD_ModuleHandle, STRING_DIR_HELP7, szMsg, RC_STRING_MAX_SIZE); + if (DirPrintf(lpFlags, szMsg, szTemp)) + return; + } - if (lpFlags->bBareFormat) - { - /* Bare format */ - DirPrintBareList(ptrFiles, dwCount, szCurPath, lpFlags); - } - else if(lpFlags->bShortName) - { - /* New list style / Short names */ - DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags); - } - else if(lpFlags->bWideListColSort || lpFlags->bWideList) - { - /* Wide list */ - DirPrintWideList(ptrFiles, dwCount, szCurPath, lpFlags); - } - else if (lpFlags->bNewLongList ) - { - /* New list style*/ - DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags); - } - else - { - /* If nothing is selected old list is the default */ - DirPrintOldList(ptrFiles, dwCount, szCurPath, lpFlags); - } + if (lpFlags->bBareFormat) + { + /* Bare format */ + DirPrintBareList(ptrFiles, dwCount, szCurPath, lpFlags); + } + else if (lpFlags->bShortName) + { + /* New list style / Short names */ + DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags); + } + else if (lpFlags->bWideListColSort || lpFlags->bWideList) + { + /* Wide list */ + DirPrintWideList(ptrFiles, dwCount, szCurPath, lpFlags); + } + else if (lpFlags->bNewLongList ) + { + /* New list style*/ + DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags); + } + else + { + /* If nothing is selected old list is the default */ + DirPrintOldList(ptrFiles, dwCount, szCurPath, lpFlags); + } } - - /* * CompareFiles * * Compares 2 files based on the order criteria */ static BOOL -CompareFiles(LPWIN32_FIND_DATA lpFile1, /* [IN] A pointer to WIN32_FIND_DATA of file 1 */ - LPWIN32_FIND_DATA lpFile2, /* [IN] A pointer to WIN32_FIND_DATA of file 2 */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags that we use to list */ +CompareFiles(LPWIN32_FIND_DATA lpFile1, /* [IN] A pointer to WIN32_FIND_DATA of file 1 */ + LPWIN32_FIND_DATA lpFile2, /* [IN] A pointer to WIN32_FIND_DATA of file 2 */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags that we use to list */ { ULARGE_INTEGER u64File1; ULARGE_INTEGER u64File2; int i; - long iComp = 0; /* The comparison result */ + long iComp = 0; /* The comparison result */ - /* Calculate critiries by order given from user */ - for (i = 0;i < lpFlags->stOrderBy.sCriteriaCount;i++) - { + /* Calculate critiries by order given from user */ + for (i = 0;i < lpFlags->stOrderBy.sCriteriaCount;i++) + { - /* Calculate criteria */ - switch(lpFlags->stOrderBy.eCriteria[i]) - { - case ORDER_SIZE: /* Order by size /o:s */ - /* concat the 32bit integers to a 64bit */ - u64File1.LowPart = lpFile1->nFileSizeLow; - u64File1.HighPart = lpFile1->nFileSizeHigh; - u64File2.LowPart = lpFile2->nFileSizeLow; - u64File2.HighPart = lpFile2->nFileSizeHigh; + /* Calculate criteria */ + switch(lpFlags->stOrderBy.eCriteria[i]) + { + case ORDER_SIZE: /* Order by size /o:s */ + /* concat the 32bit integers to a 64bit */ + u64File1.LowPart = lpFile1->nFileSizeLow; + u64File1.HighPart = lpFile1->nFileSizeHigh; + u64File2.LowPart = lpFile2->nFileSizeLow; + u64File2.HighPart = lpFile2->nFileSizeHigh; - /* In case that differnce is too big for a long */ - if (u64File1.QuadPart < u64File2.QuadPart) - iComp = -1; - else if (u64File1.QuadPart > u64File2.QuadPart) - iComp = 1; - else - iComp = 0; - break; + /* In case that differnce is too big for a long */ + if (u64File1.QuadPart < u64File2.QuadPart) + iComp = -1; + else if (u64File1.QuadPart > u64File2.QuadPart) + iComp = 1; + else + iComp = 0; + break; - case ORDER_DIRECTORY: /* Order by directory attribute /o:g */ - iComp = ((lpFile2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)- - (lpFile1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); - break; + case ORDER_DIRECTORY: /* Order by directory attribute /o:g */ + iComp = ((lpFile2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)- + (lpFile1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); + break; - case ORDER_EXTENSION: /* Order by extension name /o:e */ - iComp = _tcsicmp(getExt(lpFile1->cFileName),getExt(lpFile2->cFileName)); - break; + case ORDER_EXTENSION: /* Order by extension name /o:e */ + iComp = _tcsicmp(getExt(lpFile1->cFileName),getExt(lpFile2->cFileName)); + break; - case ORDER_NAME: /* Order by filename /o:n */ - iComp = _tcsicmp(lpFile1->cFileName, lpFile2->cFileName); - break; + case ORDER_NAME: /* Order by filename /o:n */ + iComp = _tcsicmp(lpFile1->cFileName, lpFile2->cFileName); + break; - case ORDER_TIME: /* Order by file's time /o:t */ - /* We compare files based on the time field selected by /t */ - switch(lpFlags->stTimeField.eTimeField) - { - case TF_CREATIONDATE: - /* concat the 32bit integers to a 64bit */ - u64File1.LowPart = lpFile1->ftCreationTime.dwLowDateTime; - u64File1.HighPart = lpFile1->ftCreationTime.dwHighDateTime ; - u64File2.LowPart = lpFile2->ftCreationTime.dwLowDateTime; - u64File2.HighPart = lpFile2->ftCreationTime.dwHighDateTime ; - break; - case TF_LASTACCESSEDDATE : - /* concat the 32bit integers to a 64bit */ - u64File1.LowPart = lpFile1->ftLastAccessTime.dwLowDateTime; - u64File1.HighPart = lpFile1->ftLastAccessTime.dwHighDateTime ; - u64File2.LowPart = lpFile2->ftLastAccessTime.dwLowDateTime; - u64File2.HighPart = lpFile2->ftLastAccessTime.dwHighDateTime ; - break; - case TF_MODIFIEDDATE: - /* concat the 32bit integers to a 64bit */ - u64File1.LowPart = lpFile1->ftLastWriteTime.dwLowDateTime; - u64File1.HighPart = lpFile1->ftLastWriteTime.dwHighDateTime ; - u64File2.LowPart = lpFile2->ftLastWriteTime.dwLowDateTime; - u64File2.HighPart = lpFile2->ftLastWriteTime.dwHighDateTime ; - break; - } + case ORDER_TIME: /* Order by file's time /o:t */ + /* We compare files based on the time field selected by /t */ + switch(lpFlags->stTimeField.eTimeField) + { + case TF_CREATIONDATE: + /* concat the 32bit integers to a 64bit */ + u64File1.LowPart = lpFile1->ftCreationTime.dwLowDateTime; + u64File1.HighPart = lpFile1->ftCreationTime.dwHighDateTime ; + u64File2.LowPart = lpFile2->ftCreationTime.dwLowDateTime; + u64File2.HighPart = lpFile2->ftCreationTime.dwHighDateTime ; + break; + case TF_LASTACCESSEDDATE : + /* concat the 32bit integers to a 64bit */ + u64File1.LowPart = lpFile1->ftLastAccessTime.dwLowDateTime; + u64File1.HighPart = lpFile1->ftLastAccessTime.dwHighDateTime ; + u64File2.LowPart = lpFile2->ftLastAccessTime.dwLowDateTime; + u64File2.HighPart = lpFile2->ftLastAccessTime.dwHighDateTime ; + break; + case TF_MODIFIEDDATE: + /* concat the 32bit integers to a 64bit */ + u64File1.LowPart = lpFile1->ftLastWriteTime.dwLowDateTime; + u64File1.HighPart = lpFile1->ftLastWriteTime.dwHighDateTime ; + u64File2.LowPart = lpFile2->ftLastWriteTime.dwLowDateTime; + u64File2.HighPart = lpFile2->ftLastWriteTime.dwHighDateTime ; + break; + } - /* In case that differnce is too big for a long */ - if (u64File1.QuadPart < u64File2.QuadPart) - iComp = -1; - else if (u64File1.QuadPart > u64File2.QuadPart) - iComp = 1; - else - iComp = 0; - break; - } + /* In case that differnce is too big for a long */ + if (u64File1.QuadPart < u64File2.QuadPart) + iComp = -1; + else if (u64File1.QuadPart > u64File2.QuadPart) + iComp = 1; + else + iComp = 0; + break; + } - /* Reverse if desired */ - if (lpFlags->stOrderBy.bCriteriaRev[i]) - iComp *= -1; + /* Reverse if desired */ + if (lpFlags->stOrderBy.bCriteriaRev[i]) + iComp *= -1; - /* If that criteria was enough for distinguishing - the files/dirs,there is no need to calculate the others*/ - if (iComp != 0) break; - } + /* If that criteria was enough for distinguishing + the files/dirs,there is no need to calculate the others*/ + if (iComp != 0) break; + } - /* Translate the value of iComp to boolean */ - return iComp > 0; + /* Translate the value of iComp to boolean */ + return iComp > 0; } /* @@ -1254,290 +1240,287 @@ CompareFiles(LPWIN32_FIND_DATA lpFile1, /* [IN] A pointer to WIN32_FIND_DATA of * Sort files by the order criterias using quicksort method */ static VOID -QsortFiles(LPWIN32_FIND_DATA ptrArray[], /* [IN/OUT] The array with file info pointers */ - int i, /* [IN] The index of first item in array */ - int j, /* [IN] The index to last item in array */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags that we will use to sort */ +QsortFiles(LPWIN32_FIND_DATA ptrArray[], /* [IN/OUT] The array with file info pointers */ + int i, /* [IN] The index of first item in array */ + int j, /* [IN] The index to last item in array */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags that we will use to sort */ { - LPWIN32_FIND_DATA lpTemp; /* A temporary pointer */ - BOOL Way; + LPWIN32_FIND_DATA lpTemp; /* A temporary pointer */ + BOOL Way; - if (i < j) - { - int First = i, Last = j, Temp; - Way = TRUE; - while (i != j) - { - if (Way == CompareFiles(ptrArray[i], ptrArray[j], lpFlags)) - { - /* Swap the pointers of the array */ - lpTemp = ptrArray[i]; - ptrArray[i]= ptrArray[j]; - ptrArray[j] = lpTemp; + if (i < j) + { + int First = i, Last = j, Temp; + Way = TRUE; + while (i != j) + { + if (Way == CompareFiles(ptrArray[i], ptrArray[j], lpFlags)) + { + /* Swap the pointers of the array */ + lpTemp = ptrArray[i]; + ptrArray[i]= ptrArray[j]; + ptrArray[j] = lpTemp; - /* Swap the indexes for inverting sorting */ - Temp = i; - i = j; - j =Temp; + /* Swap the indexes for inverting sorting */ + Temp = i; + i = j; + j =Temp; - Way = !Way; - } + Way = !Way; + } - j += (!Way - Way); - } + j += (!Way - Way); + } - QsortFiles(ptrArray,First, i-1, lpFlags); - QsortFiles(ptrArray,i+1,Last, lpFlags); - } + QsortFiles(ptrArray,First, i-1, lpFlags); + QsortFiles(ptrArray,i+1,Last, lpFlags); + } } - - /* * DirList * * The functions that does everything except for printing results */ static INT -DirList(LPTSTR szPath, /* [IN] The path that dir starts */ - LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags of the listing */ +DirList(LPTSTR szPath, /* [IN] The path that dir starts */ + LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags of the listing */ { - BOOL fPoint; /* If szPath is a file with extension fPoint will be True*/ - HANDLE hSearch; /* The handle of the search */ - HANDLE hRecSearch; /* The handle for searching recursivly */ - WIN32_FIND_DATA wfdFileInfo; /* The info of file that found */ - LPWIN32_FIND_DATA * ptrFileArray; /* An array of pointers with all the files */ - PDIRFINDLISTNODE ptrStartNode; /* The pointer to the first node */ - PDIRFINDLISTNODE ptrNextNode; /* A pointer used for relatives refernces */ - TCHAR szFullPath[MAX_PATH]; /* The full path that we are listing with trailing \ */ - TCHAR szSubPath[MAX_PATH]; - LPTSTR pszFilePart; - DWORD dwCount; /* A counter of files found in directory */ - DWORD dwCountFiles; /* Counter for files */ - DWORD dwCountDirs; /* Counter for directories */ - ULONGLONG u64CountBytes; /* Counter for bytes */ - ULARGE_INTEGER u64Temp; /* A temporary counter */ + BOOL fPoint; /* If szPath is a file with extension fPoint will be True*/ + HANDLE hSearch; /* The handle of the search */ + HANDLE hRecSearch; /* The handle for searching recursivly */ + WIN32_FIND_DATA wfdFileInfo; /* The info of file that found */ + LPWIN32_FIND_DATA * ptrFileArray; /* An array of pointers with all the files */ + PDIRFINDLISTNODE ptrStartNode; /* The pointer to the first node */ + PDIRFINDLISTNODE ptrNextNode; /* A pointer used for relatives refernces */ + TCHAR szFullPath[MAX_PATH]; /* The full path that we are listing with trailing \ */ + TCHAR szSubPath[MAX_PATH]; + LPTSTR pszFilePart; + DWORD dwCount; /* A counter of files found in directory */ + DWORD dwCountFiles; /* Counter for files */ + DWORD dwCountDirs; /* Counter for directories */ + ULONGLONG u64CountBytes; /* Counter for bytes */ + ULARGE_INTEGER u64Temp; /* A temporary counter */ - /* Initialize Variables */ - ptrStartNode = NULL; - ptrNextNode = NULL; - dwCount = 0; - dwCountFiles = 0; - dwCountDirs = 0; - u64CountBytes = 0; - fPoint= FALSE; + /* Initialize Variables */ + ptrStartNode = NULL; + ptrNextNode = NULL; + dwCount = 0; + dwCountFiles = 0; + dwCountDirs = 0; + u64CountBytes = 0; + fPoint= FALSE; - /* Create szFullPath */ - if (GetFullPathName(szPath, sizeof(szFullPath) / sizeof(TCHAR), szFullPath, &pszFilePart) == 0) - { - _tcscpy (szFullPath, szPath); - pszFilePart = NULL; - } + /* Create szFullPath */ + if (GetFullPathName(szPath, sizeof(szFullPath) / sizeof(TCHAR), szFullPath, &pszFilePart) == 0) + { + _tcscpy (szFullPath, szPath); + pszFilePart = NULL; + } - /* If no wildcard or file was specified and this is a directory, then - display all files in it */ - if (pszFilePart == NULL || IsExistingDirectory(szFullPath)) - { - pszFilePart = &szFullPath[_tcslen(szFullPath)]; - if (pszFilePart[-1] != _T('\\')) - *pszFilePart++ = _T('\\'); - _tcscpy(pszFilePart, _T("*")); - } + /* If no wildcard or file was specified and this is a directory, then + display all files in it */ + if (pszFilePart == NULL || IsExistingDirectory(szFullPath)) + { + pszFilePart = &szFullPath[_tcslen(szFullPath)]; + if (pszFilePart[-1] != _T('\\')) + *pszFilePart++ = _T('\\'); + _tcscpy(pszFilePart, _T("*")); + } - /* Prepare the linked list, first node is allocated */ - ptrStartNode = cmd_alloc(sizeof(DIRFINDLISTNODE)); - if (ptrStartNode == NULL) - { - WARN("DEBUG: Cannot allocate memory for ptrStartNode!\n"); - return 1; /* Error cannot allocate memory for 1st object */ - } - ptrNextNode = ptrStartNode; + /* Prepare the linked list, first node is allocated */ + ptrStartNode = cmd_alloc(sizeof(DIRFINDLISTNODE)); + if (ptrStartNode == NULL) + { + WARN("DEBUG: Cannot allocate memory for ptrStartNode!\n"); + return 1; /* Error cannot allocate memory for 1st object */ + } + ptrNextNode = ptrStartNode; - /*Checking ir szPath is a File with/wout extension*/ - if (szPath[_tcslen(szPath) - 1] == _T('.')) - fPoint= TRUE; + /*Checking ir szPath is a File with/wout extension*/ + if (szPath[_tcslen(szPath) - 1] == _T('.')) + fPoint= TRUE; - /* Collect the results for the current folder */ - hSearch = FindFirstFile(szFullPath, &wfdFileInfo); - if (hSearch != INVALID_HANDLE_VALUE) - { - do - { - /*If retrieved FileName has extension,and szPath doesnt have extension then JUMP the retrieved FileName*/ - if(_tcschr(wfdFileInfo.cFileName,_T('.'))&&(fPoint==TRUE)) - { - continue; - /* Here we filter all the specified attributes */ - }else if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask ) - == (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal )) - { - ptrNextNode->ptrNext = cmd_alloc(sizeof(DIRFINDLISTNODE)); - if (ptrNextNode->ptrNext == NULL) - { - WARN("DEBUG: Cannot allocate memory for ptrNextNode->ptrNext!\n"); - while (ptrStartNode) - { - ptrNextNode = ptrStartNode->ptrNext; - cmd_free(ptrStartNode); - ptrStartNode = ptrNextNode; - dwCount --; - } - FindClose(hSearch); - return 1; - } + /* Collect the results for the current folder */ + hSearch = FindFirstFile(szFullPath, &wfdFileInfo); + if (hSearch != INVALID_HANDLE_VALUE) + { + do + { + /*If retrieved FileName has extension,and szPath doesnt have extension then JUMP the retrieved FileName*/ + if (_tcschr(wfdFileInfo.cFileName,_T('.'))&&(fPoint==TRUE)) + { + continue; + /* Here we filter all the specified attributes */ + } + else if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask ) + == (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal )) + { + ptrNextNode->ptrNext = cmd_alloc(sizeof(DIRFINDLISTNODE)); + if (ptrNextNode->ptrNext == NULL) + { + WARN("DEBUG: Cannot allocate memory for ptrNextNode->ptrNext!\n"); + while (ptrStartNode) + { + ptrNextNode = ptrStartNode->ptrNext; + cmd_free(ptrStartNode); + ptrStartNode = ptrNextNode; + dwCount--; + } + FindClose(hSearch); + return 1; + } - /* If cmd_alloc fails we go to next file in hope it works, - without braking the linked list! */ - if (ptrNextNode->ptrNext) - { - /* Copy the info of search at linked list */ - memcpy(&ptrNextNode->ptrNext->stFindInfo, - &wfdFileInfo, - sizeof(WIN32_FIND_DATA)); + /* If cmd_alloc fails we go to next file in hope it works, + without braking the linked list! */ + if (ptrNextNode->ptrNext) + { + /* Copy the info of search at linked list */ + memcpy(&ptrNextNode->ptrNext->stFindInfo, + &wfdFileInfo, + sizeof(WIN32_FIND_DATA)); - /* If lower case is selected do it here */ - if (lpFlags->bLowerCase) - { - _tcslwr(ptrNextNode->ptrNext->stFindInfo.cAlternateFileName); - _tcslwr(ptrNextNode->ptrNext->stFindInfo.cFileName); - } + /* If lower case is selected do it here */ + if (lpFlags->bLowerCase) + { + _tcslwr(ptrNextNode->ptrNext->stFindInfo.cAlternateFileName); + _tcslwr(ptrNextNode->ptrNext->stFindInfo.cFileName); + } - /* Continue at next node at linked list */ - ptrNextNode = ptrNextNode->ptrNext; - dwCount ++; + /* Continue at next node at linked list */ + ptrNextNode = ptrNextNode->ptrNext; + dwCount ++; - /* Grab statistics */ - if (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - /* Directory */ - dwCountDirs++; - } - else - { - /* File */ - dwCountFiles++; - u64Temp.HighPart = wfdFileInfo.nFileSizeHigh; - u64Temp.LowPart = wfdFileInfo.nFileSizeLow; - u64CountBytes += u64Temp.QuadPart; - } - } - } - } while (FindNextFile(hSearch, &wfdFileInfo)); - FindClose(hSearch); - } + /* Grab statistics */ + if (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + /* Directory */ + dwCountDirs++; + } + else + { + /* File */ + dwCountFiles++; + u64Temp.HighPart = wfdFileInfo.nFileSizeHigh; + u64Temp.LowPart = wfdFileInfo.nFileSizeLow; + u64CountBytes += u64Temp.QuadPart; + } + } + } + } while (FindNextFile(hSearch, &wfdFileInfo)); + FindClose(hSearch); + } - /* Terminate list */ - ptrNextNode->ptrNext = NULL; + /* Terminate list */ + ptrNextNode->ptrNext = NULL; - /* Calculate and allocate space need for making an array of pointers */ - ptrFileArray = cmd_alloc(sizeof(LPWIN32_FIND_DATA) * dwCount); - if (ptrFileArray == NULL) - { - WARN("DEBUG: Cannot allocate memory for ptrFileArray!\n"); - while (ptrStartNode) - { - ptrNextNode = ptrStartNode->ptrNext; - cmd_free(ptrStartNode); - ptrStartNode = ptrNextNode; - dwCount --; - } - return 1; - } + /* Calculate and allocate space need for making an array of pointers */ + ptrFileArray = cmd_alloc(sizeof(LPWIN32_FIND_DATA) * dwCount); + if (ptrFileArray == NULL) + { + WARN("DEBUG: Cannot allocate memory for ptrFileArray!\n"); + while (ptrStartNode) + { + ptrNextNode = ptrStartNode->ptrNext; + cmd_free(ptrStartNode); + ptrStartNode = ptrNextNode; + dwCount --; + } + return 1; + } - /* - * Create an array of pointers from the linked list - * this will be used to sort and print data, rather than the list - */ - ptrNextNode = ptrStartNode; - dwCount = 0; - while (ptrNextNode->ptrNext) - { - *(ptrFileArray + dwCount) = &ptrNextNode->ptrNext->stFindInfo; - ptrNextNode = ptrNextNode->ptrNext; - dwCount++; - } + /* + * Create an array of pointers from the linked list + * this will be used to sort and print data, rather than the list + */ + ptrNextNode = ptrStartNode; + dwCount = 0; + while (ptrNextNode->ptrNext) + { + *(ptrFileArray + dwCount) = &ptrNextNode->ptrNext->stFindInfo; + ptrNextNode = ptrNextNode->ptrNext; + dwCount++; + } - /* Sort Data if requested*/ - if (lpFlags->stOrderBy.sCriteriaCount > 0) - QsortFiles(ptrFileArray, 0, dwCount-1, lpFlags); + /* Sort Data if requested*/ + if (lpFlags->stOrderBy.sCriteriaCount > 0) + QsortFiles(ptrFileArray, 0, dwCount-1, lpFlags); - /* Print Data */ - pszFilePart[-1] = _T('\0'); /* truncate to directory name only */ - DirPrintFiles(ptrFileArray, dwCount, szFullPath, lpFlags); - pszFilePart[-1] = _T('\\'); + /* Print Data */ + pszFilePart[-1] = _T('\0'); /* truncate to directory name only */ + DirPrintFiles(ptrFileArray, dwCount, szFullPath, lpFlags); + pszFilePart[-1] = _T('\\'); - if (lpFlags->bRecursive) - { - PrintSummary(szFullPath, - dwCountFiles, - dwCountDirs, - u64CountBytes, - lpFlags, - FALSE); - } + if (lpFlags->bRecursive) + { + PrintSummary(szFullPath, + dwCountFiles, + dwCountDirs, + u64CountBytes, + lpFlags, + FALSE); + } - /* Free array */ - cmd_free(ptrFileArray); - /* Free linked list */ - while (ptrStartNode) - { - ptrNextNode = ptrStartNode->ptrNext; - cmd_free(ptrStartNode); - ptrStartNode = ptrNextNode; - dwCount --; - } + /* Free array */ + cmd_free(ptrFileArray); + /* Free linked list */ + while (ptrStartNode) + { + ptrNextNode = ptrStartNode->ptrNext; + cmd_free(ptrStartNode); + ptrStartNode = ptrNextNode; + dwCount --; + } - if (CheckCtrlBreak(BREAK_INPUT)) - return 1; + if (CheckCtrlBreak(BREAK_INPUT)) + return 1; - /* Add statistics to recursive statistics*/ - recurse_dir_cnt += dwCountDirs; - recurse_file_cnt += dwCountFiles; - recurse_bytes += u64CountBytes; + /* Add statistics to recursive statistics*/ + recurse_dir_cnt += dwCountDirs; + recurse_file_cnt += dwCountFiles; + recurse_bytes += u64CountBytes; - /* Do the recursive job if requested - the recursive is be done on ALL(indepent of their attribs) - directoried of the current one.*/ - if (lpFlags->bRecursive) - { - /* The new search is involving any *.* file */ - memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR)); - _tcscpy(&szSubPath[pszFilePart - szFullPath], _T("*.*")); + /* Do the recursive job if requested + the recursive is be done on ALL(indepent of their attribs) + directoried of the current one.*/ + if (lpFlags->bRecursive) + { + /* The new search is involving any *.* file */ + memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR)); + _tcscpy(&szSubPath[pszFilePart - szFullPath], _T("*.*")); - hRecSearch = FindFirstFile (szSubPath, &wfdFileInfo); - if (hRecSearch != INVALID_HANDLE_VALUE) - { - do - { - /* We search for directories other than "." and ".." */ - if ((_tcsicmp(wfdFileInfo.cFileName, _T(".")) != 0) && - (_tcsicmp(wfdFileInfo.cFileName, _T("..")) != 0 ) && - (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - /* Concat the path and the directory to do recursive */ - memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR)); - _tcscpy(&szSubPath[pszFilePart - szFullPath], wfdFileInfo.cFileName); - _tcscat(szSubPath, _T("\\")); - _tcscat(szSubPath, pszFilePart); + hRecSearch = FindFirstFile (szSubPath, &wfdFileInfo); + if (hRecSearch != INVALID_HANDLE_VALUE) + { + do + { + /* We search for directories other than "." and ".." */ + if ((_tcsicmp(wfdFileInfo.cFileName, _T(".")) != 0) && + (_tcsicmp(wfdFileInfo.cFileName, _T("..")) != 0 ) && + (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + /* Concat the path and the directory to do recursive */ + memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR)); + _tcscpy(&szSubPath[pszFilePart - szFullPath], wfdFileInfo.cFileName); + _tcscat(szSubPath, _T("\\")); + _tcscat(szSubPath, pszFilePart); - /* We do the same for the folder */ - if (DirList(szSubPath, lpFlags) != 0) - { - FindClose(hRecSearch); - return 1; - } - } - } while(FindNextFile(hRecSearch, &wfdFileInfo)); - } - FindClose(hRecSearch); - } + /* We do the same for the folder */ + if (DirList(szSubPath, lpFlags) != 0) + { + FindClose(hRecSearch); + return 1; + } + } + } while(FindNextFile(hRecSearch, &wfdFileInfo)); + } + FindClose(hRecSearch); + } - return 0; + return 0; } - - /* * dir * @@ -1546,147 +1529,155 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */ INT CommandDir(LPTSTR rest) { - TCHAR dircmd[256]; /* A variable to store the DIRCMD enviroment variable */ - TCHAR path[MAX_PATH]; - TCHAR prev_volume[MAX_PATH]; - LPTSTR* params = NULL; - LPTSTR pszFilePart; - INT entries = 0; - UINT loop = 0; - DIRSWITCHFLAGS stFlags; - INT ret = 1; - BOOL ChangedVolume; + TCHAR dircmd[256]; /* A variable to store the DIRCMD enviroment variable */ + TCHAR path[MAX_PATH]; + TCHAR prev_volume[MAX_PATH]; + LPTSTR* params = NULL; + LPTSTR pszFilePart; + INT entries = 0; + UINT loop = 0; + DIRSWITCHFLAGS stFlags; + INT ret = 1; + BOOL ChangedVolume; - /* Initialize Switch Flags < Default switches are setted here!> */ - stFlags.b4Digit = TRUE; - stFlags.bBareFormat = FALSE; - stFlags.bLowerCase = FALSE; - stFlags.bNewLongList = TRUE; - stFlags.bPause = FALSE; - stFlags.bRecursive = FALSE; - stFlags.bShortName = FALSE; - stFlags.bTSeperator = TRUE; - stFlags.bUser = FALSE; - stFlags.bWideList = FALSE; - stFlags.bWideListColSort = FALSE; - stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE; - stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; - stFlags.stAttribs.dwAttribVal = 0L; - stFlags.stOrderBy.sCriteriaCount = 0; + /* Initialize Switch Flags < Default switches are setted here!> */ + stFlags.b4Digit = TRUE; + stFlags.bBareFormat = FALSE; + stFlags.bLowerCase = FALSE; + stFlags.bNewLongList = TRUE; + stFlags.bPause = FALSE; + stFlags.bRecursive = FALSE; + stFlags.bShortName = FALSE; + stFlags.bTSeperator = TRUE; + stFlags.bUser = FALSE; + stFlags.bWideList = FALSE; + stFlags.bWideListColSort = FALSE; + stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE; + stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; + stFlags.stAttribs.dwAttribVal = 0L; + stFlags.stOrderBy.sCriteriaCount = 0; - nErrorLevel = 0; + nErrorLevel = 0; - /* read the parameters from the DIRCMD environment variable */ - if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256)) - if (!DirReadParam(dircmd, ¶ms, &entries, &stFlags)) - { - nErrorLevel = 1; - goto cleanup; - } + /* read the parameters from the DIRCMD environment variable */ + if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256)) + { + if (!DirReadParam(dircmd, ¶ms, &entries, &stFlags)) + { + nErrorLevel = 1; + goto cleanup; + } + } - /* read the parameters */ - if (!DirReadParam(rest, ¶ms, &entries, &stFlags) || CheckCtrlBreak(BREAK_INPUT)) - { - nErrorLevel = 1; - goto cleanup; - } + /* read the parameters */ + if (!DirReadParam(rest, ¶ms, &entries, &stFlags) || CheckCtrlBreak(BREAK_INPUT)) + { + nErrorLevel = 1; + goto cleanup; + } - /* default to current directory */ - if(entries == 0) { - if(!add_entry(&entries, ¶ms, _T("*"))) { - nErrorLevel = 1; - goto cleanup; - } - } + /* default to current directory */ + if (entries == 0) + { + if (!add_entry(&entries, ¶ms, _T("*"))) + { + nErrorLevel = 1; + goto cleanup; + } + } - prev_volume[0] = _T('\0'); + prev_volume[0] = _T('\0'); - /* Reset paging state */ - if (stFlags.bPause) - ConOutPrintfPaging(TRUE, _T("")); + /* Reset paging state */ + if (stFlags.bPause) + ConOutPrintfPaging(TRUE, _T("")); - for(loop = 0; loop < (UINT)entries; loop++) - { - if (CheckCtrlBreak(BREAK_INPUT)) - { - nErrorLevel = 1; - goto cleanup; - } + for(loop = 0; loop < (UINT)entries; loop++) + { + if (CheckCtrlBreak(BREAK_INPUT)) + { + nErrorLevel = 1; + goto cleanup; + } - recurse_dir_cnt = 0L; - recurse_file_cnt = 0L; - recurse_bytes = 0; + recurse_dir_cnt = 0L; + recurse_file_cnt = 0L; + recurse_bytes = 0; - /* - Uncomment this to show the final state of switch flags*/ - { - int i; - TRACE("Attributes mask/value %x/%x\n",stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal ); - TRACE("(B) Bare format : %i\n", stFlags.bBareFormat ); - TRACE("(C) Thousand : %i\n", stFlags.bTSeperator ); - TRACE("(W) Wide list : %i\n", stFlags.bWideList ); - TRACE("(D) Wide list sort by column : %i\n", stFlags.bWideListColSort ); - TRACE("(L) Lowercase : %i\n", stFlags.bLowerCase ); - TRACE("(N) New : %i\n", stFlags.bNewLongList ); - TRACE("(O) Order : %i\n", stFlags.stOrderBy.sCriteriaCount ); - for (i =0;i + Uncomment this to show the final state of switch flags*/ + { + int i; + TRACE("Attributes mask/value %x/%x\n",stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal ); + TRACE("(B) Bare format : %i\n", stFlags.bBareFormat ); + TRACE("(C) Thousand : %i\n", stFlags.bTSeperator ); + TRACE("(W) Wide list : %i\n", stFlags.bWideList ); + TRACE("(D) Wide list sort by column : %i\n", stFlags.bWideListColSort ); + TRACE("(L) Lowercase : %i\n", stFlags.bLowerCase ); + TRACE("(N) New : %i\n", stFlags.bNewLongList ); + TRACE("(O) Order : %i\n", stFlags.stOrderBy.sCriteriaCount ); + for (i =0;iprev = NULL; - lpDir->next = lpStackTop; - if (lpStackTop == NULL) - lpStackBottom = lpDir; - else - lpStackTop->prev = lpDir; - lpStackTop = lpDir; + lpDir->prev = NULL; + lpDir->next = lpStackTop; + if (lpStackTop == NULL) + lpStackBottom = lpDir; + else + lpStackTop->prev = lpDir; + lpStackTop = lpDir; - _tcscpy(lpDir->szPath, pszPath); + _tcscpy(lpDir->szPath, pszPath); - nStackDepth++; + nStackDepth++; - return nErrorLevel = 0; + return nErrorLevel = 0; } static VOID PopDirectory (VOID) { - LPDIRENTRY lpDir = lpStackTop; - lpStackTop = lpDir->next; - if (lpStackTop != NULL) - lpStackTop->prev = NULL; - else - lpStackBottom = NULL; + LPDIRENTRY lpDir = lpStackTop; + lpStackTop = lpDir->next; + if (lpStackTop != NULL) + lpStackTop->prev = NULL; + else + lpStackBottom = NULL; - cmd_free (lpDir); + cmd_free (lpDir); - nStackDepth--; + nStackDepth--; } @@ -78,9 +78,9 @@ PopDirectory (VOID) */ VOID InitDirectoryStack (VOID) { - nStackDepth = 0; - lpStackTop = NULL; - lpStackBottom = NULL; + nStackDepth = 0; + lpStackTop = NULL; + lpStackBottom = NULL; } @@ -89,14 +89,14 @@ VOID InitDirectoryStack (VOID) */ VOID DestroyDirectoryStack (VOID) { - while (nStackDepth) - PopDirectory (); + while (nStackDepth) + PopDirectory (); } INT GetDirectoryStackDepth (VOID) { - return nStackDepth; + return nStackDepth; } @@ -105,23 +105,23 @@ INT GetDirectoryStackDepth (VOID) */ INT CommandPushd (LPTSTR rest) { - TCHAR curPath[MAX_PATH]; + TCHAR curPath[MAX_PATH]; - if (!_tcsncmp (rest, _T("/?"), 2)) - { - ConOutResPuts(STRING_DIRSTACK_HELP1); - return 0; - } + if (!_tcsncmp (rest, _T("/?"), 2)) + { + ConOutResPuts(STRING_DIRSTACK_HELP1); + return 0; + } - GetCurrentDirectory (MAX_PATH, curPath); + GetCurrentDirectory (MAX_PATH, curPath); - if (rest[0] != _T('\0')) - { - if (!SetRootPath(NULL, rest)) - return 1; - } + if (rest[0] != _T('\0')) + { + if (!SetRootPath(NULL, rest)) + return 1; + } - return PushDirectory(curPath); + return PushDirectory(curPath); } @@ -130,20 +130,20 @@ INT CommandPushd (LPTSTR rest) */ INT CommandPopd (LPTSTR rest) { - INT ret = 0; - if (!_tcsncmp(rest, _T("/?"), 2)) - { - ConOutResPuts(STRING_DIRSTACK_HELP2); - return 0; - } + INT ret = 0; + if (!_tcsncmp(rest, _T("/?"), 2)) + { + ConOutResPuts(STRING_DIRSTACK_HELP2); + return 0; + } - if (nStackDepth == 0) - return 1; + if (nStackDepth == 0) + return 1; - ret = _tchdir(lpStackTop->szPath) != 0; - PopDirectory (); + ret = _tchdir(lpStackTop->szPath) != 0; + PopDirectory (); - return ret; + return ret; } @@ -152,31 +152,31 @@ INT CommandPopd (LPTSTR rest) */ INT CommandDirs (LPTSTR rest) { - LPDIRENTRY lpDir; + LPDIRENTRY lpDir; - if (!_tcsncmp(rest, _T("/?"), 2)) - { - ConOutResPuts(STRING_DIRSTACK_HELP3); - return 0; - } + if (!_tcsncmp(rest, _T("/?"), 2)) + { + ConOutResPuts(STRING_DIRSTACK_HELP3); + return 0; + } nErrorLevel = 0; - lpDir = lpStackBottom; + lpDir = lpStackBottom; - if (lpDir == NULL) - { - ConOutResPuts(STRING_DIRSTACK_HELP4); - return 0; - } + if (lpDir == NULL) + { + ConOutResPuts(STRING_DIRSTACK_HELP4); + return 0; + } - while (lpDir != NULL) - { - ConOutPuts(lpDir->szPath); - lpDir = lpDir->prev; - } + while (lpDir != NULL) + { + ConOutPuts(lpDir->szPath); + lpDir = lpDir->prev; + } - return 0; + return 0; } #endif /* FEATURE_DIRECTORY_STACK */ diff --git a/base/shell/cmd/echo.c b/base/shell/cmd/echo.c index 5cf90fd1ce0..e3678b6d3f7 100644 --- a/base/shell/cmd/echo.c +++ b/base/shell/cmd/echo.c @@ -22,8 +22,8 @@ * 13-Jul-2000 (Eric Kohl) * Implemented 'echo.' and 'echoerr.'. * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -31,105 +31,105 @@ BOOL OnOffCommand(LPTSTR param, LPBOOL flag, INT message) { - TCHAR *p2; - if (_tcsnicmp(param, D_OFF, sizeof(D_OFF)/sizeof(TCHAR) - 1) == 0) - { - p2 = param + sizeof(D_OFF)/sizeof(TCHAR) - 1; - while (_istspace(*p2)) - p2++; - if (*p2 == _T('\0')) - { - *flag = FALSE; - return TRUE; - } - } - else if (_tcsnicmp(param, D_ON, sizeof(D_ON)/sizeof(TCHAR) - 1) == 0) - { - p2 = param + sizeof(D_ON)/sizeof(TCHAR) - 1; - while (_istspace(*p2)) - p2++; - if (*p2 == _T('\0')) - { - *flag = TRUE; - return TRUE; - } - } - else if (*param == _T('\0')) - { - ConOutResPrintf(message, *flag ? D_ON : D_OFF); - return TRUE; - } - return FALSE; + TCHAR *p2; + if (_tcsnicmp(param, D_OFF, sizeof(D_OFF)/sizeof(TCHAR) - 1) == 0) + { + p2 = param + sizeof(D_OFF)/sizeof(TCHAR) - 1; + while (_istspace(*p2)) + p2++; + if (*p2 == _T('\0')) + { + *flag = FALSE; + return TRUE; + } + } + else if (_tcsnicmp(param, D_ON, sizeof(D_ON)/sizeof(TCHAR) - 1) == 0) + { + p2 = param + sizeof(D_ON)/sizeof(TCHAR) - 1; + while (_istspace(*p2)) + p2++; + if (*p2 == _T('\0')) + { + *flag = TRUE; + return TRUE; + } + } + else if (*param == _T('\0')) + { + ConOutResPrintf(message, *flag ? D_ON : D_OFF); + return TRUE; + } + return FALSE; } INT CommandEcho (LPTSTR param) { - LPTSTR p1; + LPTSTR p1; - TRACE ("CommandEcho: '%s'\n", debugstr_aw(param)); + TRACE ("CommandEcho: '%s'\n", debugstr_aw(param)); - /* skip all spaces for the check of '/?', 'ON' and 'OFF' */ - p1 = param; - while(_istspace(*p1)) - p1++; + /* skip all spaces for the check of '/?', 'ON' and 'OFF' */ + p1 = param; + while(_istspace(*p1)) + p1++; - if (!_tcsncmp (p1, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_ECHO_HELP4); - return 0; - } + if (!_tcsncmp (p1, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_ECHO_HELP4); + return 0; + } - if (!OnOffCommand(p1, &bEcho, STRING_ECHO_HELP5)) - { - /* skip the first character */ - ConOutPuts(param + 1); - ConOutPuts(_T("\r\n")); - } - return 0; + if (!OnOffCommand(p1, &bEcho, STRING_ECHO_HELP5)) + { + /* skip the first character */ + ConOutPuts(param + 1); + ConOutChar(_T('\n')); + } + return 0; } INT CommandEchos (LPTSTR param) { - TRACE ("CommandEchos: '%s'\n", debugstr_aw(param)); + TRACE ("CommandEchos: '%s'\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPuts(STRING_ECHO_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPuts(STRING_ECHO_HELP1); + return 0; + } - ConOutPrintf (_T("%s"), param); - return 0; + ConOutPrintf (_T("%s"), param); + return 0; } INT CommandEchoerr (LPTSTR param) { - TRACE ("CommandEchoerr: '%s'\n", debugstr_aw(param)); + TRACE ("CommandEchoerr: '%s'\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPuts(STRING_ECHO_HELP2); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPuts(STRING_ECHO_HELP2); + return 0; + } - ConErrPuts (param); - return 0; + ConErrPuts (param); + return 0; } INT CommandEchoserr (LPTSTR param) { - TRACE ("CommandEchoserr: '%s'\n", debugstr_aw(param)); + TRACE ("CommandEchoserr: '%s'\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPuts(STRING_ECHO_HELP3); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPuts(STRING_ECHO_HELP3); + return 0; + } - ConErrPrintf (_T("%s"), param); - return 0; + ConErrPrintf (_T("%s"), param); + return 0; } /* EOF */ diff --git a/base/shell/cmd/error.c b/base/shell/cmd/error.c index f90621b6ec4..e02c7cd0898 100644 --- a/base/shell/cmd/error.c +++ b/base/shell/cmd/error.c @@ -16,8 +16,8 @@ * 02-Feb-1999 (Eric Kohl) * Use FormatMessage() for error reports. * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -25,145 +25,145 @@ VOID ErrorMessage (DWORD dwErrorCode, LPTSTR szFormat, ...) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - TCHAR szMessage[1024]; - LPTSTR szError; - va_list arg_ptr; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szMessage[1024]; + LPTSTR szError; + va_list arg_ptr; - if (dwErrorCode == ERROR_SUCCESS) - return; + if (dwErrorCode == ERROR_SUCCESS) + return; - nErrorLevel = 1; + nErrorLevel = 1; - if (szFormat) - { - va_start (arg_ptr, szFormat); - _vstprintf (szMessage, szFormat, arg_ptr); - va_end (arg_ptr); - } + if (szFormat) + { + va_start(arg_ptr, szFormat); + _vstprintf(szMessage, szFormat, arg_ptr); + va_end(arg_ptr); + } - if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&szError, 0, NULL)) - { - ConErrPrintf (_T("%s %s\n"), szError, szMessage); - if(szError) - LocalFree (szError); - return; - } + if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&szError, 0, NULL)) + { + ConErrPrintf(_T("%s %s\n"), szError, szMessage); + if (szError) + LocalFree (szError); + return; + } - /* Fall back just in case the error is not defined */ - if (szFormat) - ConErrPrintf (_T("%s -- %s\n"), szMsg, szMessage); - else - ConErrPrintf (_T("%s\n"), szMsg); + /* Fall back just in case the error is not defined */ + if (szFormat) + ConErrPrintf(_T("%s -- %s\n"), szMsg, szMessage); + else + ConErrPrintf(_T("%s\n"), szMsg); } VOID error_parameter_format(TCHAR ch) { - ConErrResPrintf(STRING_ERROR_PARAMETERF_ERROR, ch); - nErrorLevel = 1; + ConErrResPrintf(STRING_ERROR_PARAMETERF_ERROR, ch); + nErrorLevel = 1; } VOID error_invalid_switch (TCHAR ch) { - ConErrResPrintf(STRING_ERROR_INVALID_SWITCH, ch); - nErrorLevel = 1; + ConErrResPrintf(STRING_ERROR_INVALID_SWITCH, ch); + nErrorLevel = 1; } VOID error_too_many_parameters (LPTSTR s) { - ConErrResPrintf(STRING_ERROR_TOO_MANY_PARAMETERS, s); - nErrorLevel = 1; + ConErrResPrintf(STRING_ERROR_TOO_MANY_PARAMETERS, s); + nErrorLevel = 1; } VOID error_path_not_found (VOID) { - ConErrResPuts(STRING_ERROR_PATH_NOT_FOUND); - nErrorLevel = 1; + ConErrResPuts(STRING_ERROR_PATH_NOT_FOUND); + nErrorLevel = 1; } VOID error_file_not_found (VOID) { - ConErrResPuts(STRING_ERROR_FILE_NOT_FOUND); - nErrorLevel = 1; + ConErrResPuts(STRING_ERROR_FILE_NOT_FOUND); + nErrorLevel = 1; } VOID error_sfile_not_found (LPTSTR f) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, STRING_ERROR_FILE_NOT_FOUND, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf(_T("%s - %s\n"), szMsg, f); - nErrorLevel = 1; + LoadString(CMD_ModuleHandle, STRING_ERROR_FILE_NOT_FOUND, szMsg, RC_STRING_MAX_SIZE); + ConErrPrintf(_T("%s - %s\n"), szMsg, f); + nErrorLevel = 1; } VOID error_req_param_missing (VOID) { - ConErrResPuts(STRING_ERROR_REQ_PARAM_MISSING); - nErrorLevel = 1; + ConErrResPuts(STRING_ERROR_REQ_PARAM_MISSING); + nErrorLevel = 1; } VOID error_invalid_drive (VOID) { - ConErrResPuts(STRING_ERROR_INVALID_DRIVE); - nErrorLevel = 1; + ConErrResPuts(STRING_ERROR_INVALID_DRIVE); + nErrorLevel = 1; } VOID error_bad_command (LPTSTR s) { - ConErrResPrintf(STRING_ERROR_BADCOMMAND, s); - nErrorLevel = 9009; + ConErrResPrintf(STRING_ERROR_BADCOMMAND, s); + nErrorLevel = 9009; } VOID error_no_pipe (VOID) { - ConErrResPuts(STRING_ERROR_CANNOTPIPE); - nErrorLevel = 1; + ConErrResPuts(STRING_ERROR_CANNOTPIPE); + nErrorLevel = 1; } VOID error_out_of_memory (VOID) { - ConErrResPuts(STRING_ERROR_OUT_OF_MEMORY); - nErrorLevel = 1; + ConErrResPuts(STRING_ERROR_OUT_OF_MEMORY); + nErrorLevel = 1; } VOID error_invalid_parameter_format (LPTSTR s) { - ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, s); - nErrorLevel = 1; + ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, s); + nErrorLevel = 1; } VOID error_syntax (LPTSTR s) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, STRING_ERROR_ERROR2, szMsg, RC_STRING_MAX_SIZE); + LoadString(CMD_ModuleHandle, STRING_ERROR_ERROR2, szMsg, RC_STRING_MAX_SIZE); - if (s) - ConErrPrintf(_T("%s - %s\n"), szMsg, s); - else - ConErrPrintf(_T("%s.\n"), szMsg); + if (s) + ConErrPrintf(_T("%s - %s\n"), szMsg, s); + else + ConErrPrintf(_T("%s.\n"), szMsg); - nErrorLevel = 1; + nErrorLevel = 1; } VOID msg_pause (VOID) { - ConOutResPuts(STRING_ERROR_D_PAUSEMSG); + ConOutResPuts(STRING_ERROR_D_PAUSEMSG); } /* EOF */ diff --git a/base/shell/cmd/filecomp.c b/base/shell/cmd/filecomp.c index 4015dcf43b4..f5b6ac67f23 100644 --- a/base/shell/cmd/filecomp.c +++ b/base/shell/cmd/filecomp.c @@ -26,323 +26,322 @@ VOID CompleteFilename (LPTSTR str, UINT charcount) { - WIN32_FIND_DATA file; - HANDLE hFile; - INT curplace = 0; - INT start; - INT count; - INT step; - INT c = 0; - BOOL found_dot = FALSE; - BOOL perfectmatch = TRUE; - TCHAR path[MAX_PATH]; - TCHAR fname[MAX_PATH]; - TCHAR maxmatch[MAX_PATH] = _T(""); - TCHAR directory[MAX_PATH]; - LPCOMMAND cmds_ptr; + WIN32_FIND_DATA file; + HANDLE hFile; + INT curplace = 0; + INT start; + INT count; + INT step; + INT c = 0; + BOOL found_dot = FALSE; + BOOL perfectmatch = TRUE; + TCHAR path[MAX_PATH]; + TCHAR fname[MAX_PATH]; + TCHAR maxmatch[MAX_PATH] = _T(""); + TCHAR directory[MAX_PATH]; + LPCOMMAND cmds_ptr; - /* expand current file name */ - count = charcount - 1; - if (count < 0) - count = 0; + /* expand current file name */ + count = charcount - 1; + if (count < 0) + count = 0; - /* find how many '"'s there is typed already.*/ - step = count; - while (step > 0) - { - if (str[step] == _T('"')) - c++; - step--; - } - /* if c is odd, then user typed " before name, else not.*/ + /* find how many '"'s there is typed already. */ + step = count; + while (step > 0) + { + if (str[step] == _T('"')) + c++; + step--; + } + /* if c is odd, then user typed " before name, else not. */ - /* find front of word */ - if (str[count] == _T('"') || (c % 2)) - { - count--; - while (count > 0 && str[count] != _T('"')) - count--; - } - else - { - while (count > 0 && str[count] != _T(' ')) - count--; - } + /* find front of word */ + if (str[count] == _T('"') || (c % 2)) + { + count--; + while (count > 0 && str[count] != _T('"')) + count--; + } + else + { + while (count > 0 && str[count] != _T(' ')) + count--; + } - /* if not at beginning, go forward 1 */ - if (str[count] == _T(' ')) - count++; + /* if not at beginning, go forward 1 */ + if (str[count] == _T(' ')) + count++; - start = count; + start = count; - if (str[count] == _T('"')) - count++; /* don't increment start */ + if (str[count] == _T('"')) + count++; /* don't increment start */ - /* extract directory from word */ - _tcscpy (directory, &str[count]); - curplace = _tcslen (directory) - 1; + /* extract directory from word */ + _tcscpy (directory, &str[count]); + curplace = _tcslen (directory) - 1; - if (curplace >= 0 && directory[curplace] == _T('"')) - directory[curplace--] = _T('\0'); + if (curplace >= 0 && directory[curplace] == _T('"')) + directory[curplace--] = _T('\0'); - _tcscpy (path, directory); + _tcscpy (path, directory); - while (curplace >= 0 && directory[curplace] != _T('\\') && + while (curplace >= 0 && directory[curplace] != _T('\\') && directory[curplace] != _T('/') && - directory[curplace] != _T(':')) - { - directory[curplace] = 0; - curplace--; - } + directory[curplace] != _T(':')) + { + directory[curplace] = 0; + curplace--; + } - /* look for a '.' in the filename */ - for (count = _tcslen (directory); path[count] != _T('\0'); count++) - { - if (path[count] == _T('.')) - { - found_dot = TRUE; - break; - } - } + /* look for a '.' in the filename */ + for (count = _tcslen (directory); path[count] != _T('\0'); count++) + { + if (path[count] == _T('.')) + { + found_dot = TRUE; + break; + } + } - if (found_dot) - _tcscat (path, _T("*")); - else - _tcscat (path, _T("*.*")); + if (found_dot) + _tcscat (path, _T("*")); + else + _tcscat (path, _T("*.*")); - /* current fname */ - curplace = 0; + /* current fname */ + curplace = 0; - hFile = FindFirstFile (path, &file); - if (hFile != INVALID_HANDLE_VALUE) - { - /* find anything */ - do - { - /* ignore "." and ".." */ - if (!_tcscmp (file.cFileName, _T(".")) || - !_tcscmp (file.cFileName, _T(".."))) - continue; + hFile = FindFirstFile (path, &file); + if (hFile != INVALID_HANDLE_VALUE) + { + /* find anything */ + do + { + /* ignore "." and ".." */ + if (!_tcscmp (file.cFileName, _T(".")) || + !_tcscmp (file.cFileName, _T(".."))) + continue; - _tcscpy (fname, file.cFileName); + _tcscpy (fname, file.cFileName); - if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - _tcscat (fname, _T("\\")); + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + _tcscat (fname, _T("\\")); - if (!maxmatch[0] && perfectmatch) - { - _tcscpy(maxmatch, fname); - } - else - { - for (count = 0; maxmatch[count] && fname[count]; count++) - { - if (tolower(maxmatch[count]) != tolower(fname[count])) - { - perfectmatch = FALSE; - maxmatch[count] = 0; - break; - } - } + if (!maxmatch[0] && perfectmatch) + { + _tcscpy(maxmatch, fname); + } + else + { + for (count = 0; maxmatch[count] && fname[count]; count++) + { + if (tolower(maxmatch[count]) != tolower(fname[count])) + { + perfectmatch = FALSE; + maxmatch[count] = 0; + break; + } + } - if (maxmatch[count] == _T('\0') && - fname[count] != _T('\0')) - perfectmatch = FALSE; - } - } - while (FindNextFile (hFile, &file)); + if (maxmatch[count] == _T('\0') && + fname[count] != _T('\0')) + perfectmatch = FALSE; + } + } + while (FindNextFile (hFile, &file)); - FindClose (hFile); + FindClose (hFile); - /* only quote if the filename contains spaces */ - if (_tcschr(directory, _T(' ')) || - _tcschr(maxmatch, _T(' '))) - { - str[start] = _T('\"'); - _tcscpy (&str[start+1], directory); - _tcscat (&str[start], maxmatch); - _tcscat (&str[start], _T("\"") ); - } - else - { - _tcscpy (&str[start], directory); - _tcscat (&str[start], maxmatch); - } + /* only quote if the filename contains spaces */ + if (_tcschr(directory, _T(' ')) || + _tcschr(maxmatch, _T(' '))) + { + str[start] = _T('\"'); + _tcscpy (&str[start+1], directory); + _tcscat (&str[start], maxmatch); + _tcscat (&str[start], _T("\"") ); + } + else + { + _tcscpy (&str[start], directory); + _tcscat (&str[start], maxmatch); + } - if(!perfectmatch) - { - MessageBeep (-1); - } - } - else - { - /* no match found - search for internal command */ - for (cmds_ptr = cmds; cmds_ptr->name; cmds_ptr++) - { - if (!_tcsnicmp (&str[start], cmds_ptr->name, - _tcslen (&str[start]))) - { - /* return the mach only if it is unique */ - if (_tcsnicmp (&str[start], (cmds_ptr+1)->name, _tcslen (&str[start]))) - _tcscpy (&str[start], cmds_ptr->name); - break; - } - } + if (!perfectmatch) + { + MessageBeep (-1); + } + } + else + { + /* no match found - search for internal command */ + for (cmds_ptr = cmds; cmds_ptr->name; cmds_ptr++) + { + if (!_tcsnicmp (&str[start], cmds_ptr->name, + _tcslen (&str[start]))) + { + /* return the mach only if it is unique */ + if (_tcsnicmp (&str[start], (cmds_ptr+1)->name, _tcslen (&str[start]))) + _tcscpy (&str[start], cmds_ptr->name); + break; + } + } - MessageBeep (-1); - } + MessageBeep (-1); + } } /* * returns 1 if at least one match, else returns 0 */ - BOOL ShowCompletionMatches (LPTSTR str, INT charcount) { - WIN32_FIND_DATA file; - HANDLE hFile; - BOOL found_dot = FALSE; - INT curplace = 0; - INT start; - INT count; - TCHAR path[MAX_PATH]; - TCHAR fname[MAX_PATH]; - TCHAR directory[MAX_PATH]; - SHORT screenwidth; + WIN32_FIND_DATA file; + HANDLE hFile; + BOOL found_dot = FALSE; + INT curplace = 0; + INT start; + INT count; + TCHAR path[MAX_PATH]; + TCHAR fname[MAX_PATH]; + TCHAR directory[MAX_PATH]; + SHORT screenwidth; - /* expand current file name */ - count = charcount - 1; - if (count < 0) - count = 0; + /* expand current file name */ + count = charcount - 1; + if (count < 0) + count = 0; - /* find front of word */ - if (str[count] == _T('"')) - { - count--; - while (count > 0 && str[count] != _T('"')) - count--; - } - else - { - while (count > 0 && str[count] != _T(' ')) - count--; - } + /* find front of word */ + if (str[count] == _T('"')) + { + count--; + while (count > 0 && str[count] != _T('"')) + count--; + } + else + { + while (count > 0 && str[count] != _T(' ')) + count--; + } - /* if not at beginning, go forward 1 */ - if (str[count] == _T(' ')) - count++; + /* if not at beginning, go forward 1 */ + if (str[count] == _T(' ')) + count++; - start = count; + start = count; - if (str[count] == _T('"')) - count++; /* don't increment start */ + if (str[count] == _T('"')) + count++; /* don't increment start */ - /* extract directory from word */ - _tcscpy (directory, &str[count]); - curplace = _tcslen (directory) - 1; + /* extract directory from word */ + _tcscpy (directory, &str[count]); + curplace = _tcslen (directory) - 1; - if (curplace >= 0 && directory[curplace] == _T('"')) - directory[curplace--] = _T('\0'); + if (curplace >= 0 && directory[curplace] == _T('"')) + directory[curplace--] = _T('\0'); - _tcscpy (path, directory); + _tcscpy (path, directory); - while (curplace >= 0 && - directory[curplace] != _T('\\') && - directory[curplace] != _T(':')) - { - directory[curplace] = 0; - curplace--; - } + while (curplace >= 0 && + directory[curplace] != _T('\\') && + directory[curplace] != _T(':')) + { + directory[curplace] = 0; + curplace--; + } - /* look for a . in the filename */ - for (count = _tcslen (directory); path[count] != _T('\0'); count++) - { - if (path[count] == _T('.')) - { - found_dot = TRUE; - break; - } - } + /* look for a . in the filename */ + for (count = _tcslen (directory); path[count] != _T('\0'); count++) + { + if (path[count] == _T('.')) + { + found_dot = TRUE; + break; + } + } - if (found_dot) - _tcscat (path, _T("*")); - else - _tcscat (path, _T("*.*")); + if (found_dot) + _tcscat (path, _T("*")); + else + _tcscat (path, _T("*.*")); - /* current fname */ - curplace = 0; + /* current fname */ + curplace = 0; - hFile = FindFirstFile (path, &file); - if (hFile != INVALID_HANDLE_VALUE) - { - UINT longestfname = 0; - /* Get the size of longest filename first. */ - do - { - if (_tcslen(file.cFileName) > longestfname) - { - longestfname = _tcslen(file.cFileName); - /* Directories get extra brackets around them. */ - if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - longestfname += 2; - } - } - while (FindNextFile (hFile, &file)); - FindClose (hFile); + hFile = FindFirstFile (path, &file); + if (hFile != INVALID_HANDLE_VALUE) + { + UINT longestfname = 0; + /* Get the size of longest filename first. */ + do + { + if (_tcslen(file.cFileName) > longestfname) + { + longestfname = _tcslen(file.cFileName); + /* Directories get extra brackets around them. */ + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + longestfname += 2; + } + } + while (FindNextFile (hFile, &file)); + FindClose (hFile); - hFile = FindFirstFile (path, &file); + hFile = FindFirstFile (path, &file); - /* Count the highest number of columns */ - GetScreenSize(&screenwidth, 0); + /* Count the highest number of columns */ + GetScreenSize(&screenwidth, 0); - /* For counting columns of output */ - count = 0; + /* For counting columns of output */ + count = 0; - /* Increase by the number of spaces behind file name */ - longestfname += 3; + /* Increase by the number of spaces behind file name */ + longestfname += 3; - /* find anything */ - ConOutChar (_T('\n')); - do - { - /* ignore . and .. */ - if (!_tcscmp (file.cFileName, _T(".")) || - !_tcscmp (file.cFileName, _T(".."))) - continue; + /* find anything */ + ConOutChar(_T('\n')); + do + { + /* ignore . and .. */ + if (!_tcscmp (file.cFileName, _T(".")) || + !_tcscmp (file.cFileName, _T(".."))) + continue; - if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - _stprintf (fname, _T("[%s]"), file.cFileName); - else - _tcscpy (fname, file.cFileName); + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + _stprintf (fname, _T("[%s]"), file.cFileName); + else + _tcscpy (fname, file.cFileName); - ConOutPrintf (_T("%*s"), - longestfname, fname); - count++; - /* output as much columns as fits on the screen */ - if (count >= (screenwidth / longestfname)) - { - /* print the new line only if we aren't on the - * last column, in this case it wraps anyway */ - if (count * longestfname != (UINT)screenwidth) - ConOutPrintf (_T("\n")); - count = 0; - } - } - while (FindNextFile (hFile, &file)); + ConOutPrintf (_T("%*s"), - longestfname, fname); + count++; + /* output as much columns as fits on the screen */ + if (count >= (screenwidth / longestfname)) + { + /* print the new line only if we aren't on the + * last column, in this case it wraps anyway */ + if (count * longestfname != (UINT)screenwidth) + ConOutChar(_T('\n')); + count = 0; + } + } + while (FindNextFile (hFile, &file)); - FindClose (hFile); + FindClose (hFile); - if (count) - ConOutChar (_T('\n')); - } - else - { - /* no match found */ - MessageBeep (-1); - return FALSE; - } + if (count) + ConOutChar(_T('\n')); + } + else + { + /* no match found */ + MessageBeep (-1); + return FALSE; + } - return TRUE; + return TRUE; } #endif @@ -350,166 +349,165 @@ BOOL ShowCompletionMatches (LPTSTR str, INT charcount) typedef struct _FileName { - TCHAR Name[MAX_PATH]; + TCHAR Name[MAX_PATH]; } FileName; VOID FindPrefixAndSuffix(LPTSTR strIN, LPTSTR szPrefix, LPTSTR szSuffix) { - /* String that is to be examined */ - TCHAR str[MAX_PATH]; - /* temp pointers to used to find needed parts */ - TCHAR * szSearch; - TCHAR * szSearch1; - TCHAR * szSearch2; - TCHAR * szSearch3; - /* number of quotes in the string */ - INT nQuotes = 0; - /* used in for loops */ - UINT i; - /* Char number to break the string at */ - INT PBreak = 0; - INT SBreak = 0; - /* when phrasing a string, this tells weather - you are inside quotes ot not. */ - BOOL bInside = FALSE; + /* String that is to be examined */ + TCHAR str[MAX_PATH]; + /* temp pointers to used to find needed parts */ + TCHAR * szSearch; + TCHAR * szSearch1; + TCHAR * szSearch2; + TCHAR * szSearch3; + /* number of quotes in the string */ + INT nQuotes = 0; + /* used in for loops */ + UINT i; + /* Char number to break the string at */ + INT PBreak = 0; + INT SBreak = 0; + /* when phrasing a string, this tells weather + you are inside quotes ot not. */ + BOOL bInside = FALSE; - szPrefix[0] = _T('\0'); - szSuffix[0] = _T('\0'); + szPrefix[0] = _T('\0'); + szSuffix[0] = _T('\0'); - /* Copy over the string to later be edited */ - _tcscpy(str,strIN); + /* Copy over the string to later be edited */ + _tcscpy(str,strIN); - /* Count number of " */ - for(i = 0; i < _tcslen(str); i++) - if(str[i] == _T('\"')) - nQuotes++; + /* Count number of " */ + for(i = 0; i < _tcslen(str); i++) + { + if (str[i] == _T('\"')) + nQuotes++; + } - /* Find the prefix and suffix */ - if(nQuotes % 2 && nQuotes >= 1) - { - /* Odd number of quotes. Just start from the last " */ - /* THis is the way MS does it, and is an easy way out */ - szSearch = _tcsrchr(str, _T('\"')); - /* Move to the next char past the " */ - szSearch++; - _tcscpy(szSuffix,szSearch); - /* Find the one closest to end */ - szSearch1 = _tcsrchr(str, _T('\"')); - szSearch2 = _tcsrchr(str, _T('\\')); - szSearch3 = _tcsrchr(str, _T('.')); - if(szSearch2 != NULL && _tcslen(szSearch1) > _tcslen(szSearch2)) - szSearch = szSearch2; - else if(szSearch3 != NULL && _tcslen(szSearch1) > _tcslen(szSearch3)) - szSearch = szSearch3; - else - szSearch = szSearch1; - /* Move one char past */ - szSearch++; - szSearch[0] = _T('\0'); - _tcscpy(szPrefix,str); - return; + /* Find the prefix and suffix */ + if (nQuotes % 2 && nQuotes >= 1) + { + /* Odd number of quotes. Just start from the last " */ + /* THis is the way MS does it, and is an easy way out */ + szSearch = _tcsrchr(str, _T('\"')); + /* Move to the next char past the " */ + szSearch++; + _tcscpy(szSuffix,szSearch); + /* Find the one closest to end */ + szSearch1 = _tcsrchr(str, _T('\"')); + szSearch2 = _tcsrchr(str, _T('\\')); + szSearch3 = _tcsrchr(str, _T('.')); + if (szSearch2 != NULL && _tcslen(szSearch1) > _tcslen(szSearch2)) + szSearch = szSearch2; + else if (szSearch3 != NULL && _tcslen(szSearch1) > _tcslen(szSearch3)) + szSearch = szSearch3; + else + szSearch = szSearch1; + /* Move one char past */ + szSearch++; + szSearch[0] = _T('\0'); + _tcscpy(szPrefix,str); + return; - } + } - if(!_tcschr(str, _T(' '))) - { - /* No spaces, everything goes to Suffix */ - _tcscpy(szSuffix,str); - /* look for a slash just in case */ - szSearch = _tcsrchr(str, _T('\\')); - if(szSearch) - { - szSearch++; - szSearch[0] = _T('\0'); - _tcscpy(szPrefix,str); - } - else - { - szPrefix[0] = _T('\0'); - } - return; - } + if (!_tcschr(str, _T(' '))) + { + /* No spaces, everything goes to Suffix */ + _tcscpy(szSuffix,str); + /* look for a slash just in case */ + szSearch = _tcsrchr(str, _T('\\')); + if (szSearch) + { + szSearch++; + szSearch[0] = _T('\0'); + _tcscpy(szPrefix,str); + } + else + { + szPrefix[0] = _T('\0'); + } + return; + } - if(!nQuotes) - { - /* No quotes, and there is a space*/ - /* Take it after the last space */ - szSearch = _tcsrchr(str, _T(' ')); - szSearch++; - _tcscpy(szSuffix,szSearch); - /* Find the closest to the end space or \ */ - _tcscpy(str,strIN); - szSearch1 = _tcsrchr(str, _T(' ')); - szSearch2 = _tcsrchr(str, _T('\\')); - szSearch3 = _tcsrchr(str, _T('/')); - if(szSearch2 != NULL && _tcslen(szSearch1) > _tcslen(szSearch2)) - szSearch = szSearch2; - else if(szSearch3 != NULL && _tcslen(szSearch1) > _tcslen(szSearch3)) - szSearch = szSearch3; - else - szSearch = szSearch1; - szSearch++; - szSearch[0] = _T('\0'); - _tcscpy(szPrefix,str); - return; - } + if (!nQuotes) + { + /* No quotes, and there is a space*/ + /* Take it after the last space */ + szSearch = _tcsrchr(str, _T(' ')); + szSearch++; + _tcscpy(szSuffix,szSearch); + /* Find the closest to the end space or \ */ + _tcscpy(str,strIN); + szSearch1 = _tcsrchr(str, _T(' ')); + szSearch2 = _tcsrchr(str, _T('\\')); + szSearch3 = _tcsrchr(str, _T('/')); + if (szSearch2 != NULL && _tcslen(szSearch1) > _tcslen(szSearch2)) + szSearch = szSearch2; + else if (szSearch3 != NULL && _tcslen(szSearch1) > _tcslen(szSearch3)) + szSearch = szSearch3; + else + szSearch = szSearch1; + szSearch++; + szSearch[0] = _T('\0'); + _tcscpy(szPrefix,str); + return; + } - /* All else fails and there is a lot of quotes, spaces and | - Then we search through and find the last space or \ that is - not inside a quotes */ - for(i = 0; i < _tcslen(str); i++) - { - if(str[i] == _T('\"')) - bInside = !bInside; - if(str[i] == _T(' ') && !bInside) - SBreak = i; - if((str[i] == _T(' ') || str[i] == _T('\\')) && !bInside) - PBreak = i; - - } - SBreak++; - PBreak++; - _tcscpy(szSuffix,&strIN[SBreak]); - strIN[PBreak] = _T('\0'); - _tcscpy(szPrefix,strIN); - if (szPrefix[_tcslen(szPrefix) - 2] == _T('\"') && + /* All else fails and there is a lot of quotes, spaces and | + Then we search through and find the last space or \ that is + not inside a quotes */ + for(i = 0; i < _tcslen(str); i++) + { + if (str[i] == _T('\"')) + bInside = !bInside; + if (str[i] == _T(' ') && !bInside) + SBreak = i; + if ((str[i] == _T(' ') || str[i] == _T('\\')) && !bInside) + PBreak = i; + } + SBreak++; + PBreak++; + _tcscpy(szSuffix,&strIN[SBreak]); + strIN[PBreak] = _T('\0'); + _tcscpy(szPrefix,strIN); + if (szPrefix[_tcslen(szPrefix) - 2] == _T('\"') && szPrefix[_tcslen(szPrefix) - 1] != _T(' ')) - { - /* need to remove the " right before a \ at the end to - allow the next stuff to stay inside one set of quotes - otherwise you would have multiple sets of quotes*/ - _tcscpy(&szPrefix[_tcslen(szPrefix) - 2],_T("\\")); - - } - + { + /* need to remove the " right before a \ at the end to + allow the next stuff to stay inside one set of quotes + otherwise you would have multiple sets of quotes*/ + _tcscpy(&szPrefix[_tcslen(szPrefix) - 2],_T("\\")); + } } int __cdecl compare(const void *arg1,const void *arg2) { - FileName * File1; - FileName * File2; - INT ret; + FileName * File1; + FileName * File2; + INT ret; - File1 = cmd_alloc(sizeof(FileName)); - if (!File1) - return 0; + File1 = cmd_alloc(sizeof(FileName)); + if (!File1) + return 0; - File2 = cmd_alloc(sizeof(FileName)); - if(!File2) - { - cmd_free(File1); - return 0; - } + File2 = cmd_alloc(sizeof(FileName)); + if (!File2) + { + cmd_free(File1); + return 0; + } - memcpy(File1,arg1,sizeof(FileName)); - memcpy(File2,arg2,sizeof(FileName)); + memcpy(File1,arg1,sizeof(FileName)); + memcpy(File2,arg2,sizeof(FileName)); - /* ret = _tcsicmp(File1->Name, File2->Name); */ - ret = lstrcmpi(File1->Name, File2->Name); + /* ret = _tcsicmp(File1->Name, File2->Name); */ + ret = lstrcmpi(File1->Name, File2->Name); - cmd_free(File1); - cmd_free(File2); - return ret; + cmd_free(File1); + cmd_free(File2); + return ret; } BOOL @@ -549,257 +547,258 @@ FileNameContainsSpecialCharacters(LPTSTR pszFileName) VOID CompleteFilename (LPTSTR strIN, BOOL bNext, LPTSTR strOut, UINT cusor) { - /* Length of string before we complete it */ - INT_PTR StartLength; - /* Length of string after completed */ - //INT EndLength; - /* The number of chars added too it */ - //static INT DiffLength = 0; - /* Used to find and assemble the string that is returned */ - TCHAR szBaseWord[MAX_PATH]; - TCHAR szPrefix[MAX_PATH]; - TCHAR szOrginal[MAX_PATH]; - TCHAR szSearchPath[MAX_PATH]; - /* Save the strings used last time, so if they hit tab again */ - static TCHAR LastReturned[MAX_PATH]; - static TCHAR LastSearch[MAX_PATH]; - static TCHAR LastPrefix[MAX_PATH]; - /* Used to search for files */ - HANDLE hFile; - WIN32_FIND_DATA file; - /* List of all the files */ - FileName * FileList = NULL; - /* Number of files */ - INT FileListSize = 0; - /* Used for loops */ - UINT i; - /* Editable string of what was passed in */ - TCHAR str[MAX_PATH]; - /* Keeps track of what element was last selected */ - static INT Sel; - BOOL NeededQuote = FALSE; - BOOL ShowAll = TRUE; - TCHAR * line = strIN; + /* Length of string before we complete it */ + INT_PTR StartLength; + /* Length of string after completed */ + //INT EndLength; + /* The number of chars added too it */ + //static INT DiffLength = 0; + /* Used to find and assemble the string that is returned */ + TCHAR szBaseWord[MAX_PATH]; + TCHAR szPrefix[MAX_PATH]; + TCHAR szOrginal[MAX_PATH]; + TCHAR szSearchPath[MAX_PATH]; + /* Save the strings used last time, so if they hit tab again */ + static TCHAR LastReturned[MAX_PATH]; + static TCHAR LastSearch[MAX_PATH]; + static TCHAR LastPrefix[MAX_PATH]; + /* Used to search for files */ + HANDLE hFile; + WIN32_FIND_DATA file; + /* List of all the files */ + FileName * FileList = NULL; + /* Number of files */ + INT FileListSize = 0; + /* Used for loops */ + UINT i; + /* Editable string of what was passed in */ + TCHAR str[MAX_PATH]; + /* Keeps track of what element was last selected */ + static INT Sel; + BOOL NeededQuote = FALSE; + BOOL ShowAll = TRUE; + TCHAR * line = strIN; - strOut[0] = _T('\0'); + strOut[0] = _T('\0'); - while (_istspace (*line)) - line++; - if(!_tcsnicmp (line, _T("rd "), 3) || !_tcsnicmp (line, _T("cd "), 3)) - ShowAll = FALSE; + while (_istspace (*line)) + line++; + if (!_tcsnicmp (line, _T("rd "), 3) || !_tcsnicmp (line, _T("cd "), 3)) + ShowAll = FALSE; - /* Copy the string, str can be edited and orginal should not be */ - _tcscpy(str,strIN); - _tcscpy(szOrginal,strIN); + /* Copy the string, str can be edited and orginal should not be */ + _tcscpy(str,strIN); + _tcscpy(szOrginal,strIN); - /* Look to see if the cusor is not at the end of the string */ - if((cusor + 1) < _tcslen(str)) - str[cusor] = _T('\0'); + /* Look to see if the cusor is not at the end of the string */ + if ((cusor + 1) < _tcslen(str)) + str[cusor] = _T('\0'); - /* Look to see if they hit tab again, if so cut off the diff length */ - if(_tcscmp(str,LastReturned) || !_tcslen(str)) - { - /* We need to know how many chars we added from the start */ - StartLength = _tcslen(str); + /* Look to see if they hit tab again, if so cut off the diff length */ + if (_tcscmp(str,LastReturned) || !_tcslen(str)) + { + /* We need to know how many chars we added from the start */ + StartLength = _tcslen(str); - /* no string, we need all files in that directory */ - if(!StartLength) - { - _tcscat(str,_T("*")); - } + /* no string, we need all files in that directory */ + if (!StartLength) + { + _tcscat(str,_T("*")); + } - /* Zero it out first */ - szBaseWord[0] = _T('\0'); - szPrefix[0] = _T('\0'); + /* Zero it out first */ + szBaseWord[0] = _T('\0'); + szPrefix[0] = _T('\0'); - /*What comes out of this needs to be: - szBaseWord = path no quotes to the object - szPrefix = what leads up to the filename - no quote at the END of the full name */ - FindPrefixAndSuffix(str,szPrefix,szBaseWord); - /* Strip quotes */ - for(i = 0; i < _tcslen(szBaseWord); ) - { - if(szBaseWord[i] == _T('\"')) - memmove(&szBaseWord[i],&szBaseWord[i + 1], _tcslen(&szBaseWord[i]) * sizeof(TCHAR)); - else - i++; - } + /*What comes out of this needs to be: + szBaseWord = path no quotes to the object + szPrefix = what leads up to the filename + no quote at the END of the full name */ + FindPrefixAndSuffix(str,szPrefix,szBaseWord); + /* Strip quotes */ + for(i = 0; i < _tcslen(szBaseWord); ) + { + if (szBaseWord[i] == _T('\"')) + memmove(&szBaseWord[i],&szBaseWord[i + 1], _tcslen(&szBaseWord[i]) * sizeof(TCHAR)); + else + i++; + } - /* clear it out */ - memset(szSearchPath, 0, sizeof(szSearchPath)); + /* clear it out */ + memset(szSearchPath, 0, sizeof(szSearchPath)); - /* Start the search for all the files */ - GetFullPathName(szBaseWord, MAX_PATH, szSearchPath, NULL); + /* Start the search for all the files */ + GetFullPathName(szBaseWord, MAX_PATH, szSearchPath, NULL); - /* Got a device path? Fallback to the the current dir plus the short path */ - if (szSearchPath[0] == _T('\\') && szSearchPath[1] == _T('\\') && - szSearchPath[2] == _T('.') && szSearchPath[3] == _T('\\')) - { - GetCurrentDirectory(MAX_PATH, szSearchPath); - _tcscat(szSearchPath, _T("\\")); - _tcscat(szSearchPath, szBaseWord); - } + /* Got a device path? Fallback to the the current dir plus the short path */ + if (szSearchPath[0] == _T('\\') && szSearchPath[1] == _T('\\') && + szSearchPath[2] == _T('.') && szSearchPath[3] == _T('\\')) + { + GetCurrentDirectory(MAX_PATH, szSearchPath); + _tcscat(szSearchPath, _T("\\")); + _tcscat(szSearchPath, szBaseWord); + } - if(StartLength > 0) - { - _tcscat(szSearchPath,_T("*")); - } - _tcscpy(LastSearch,szSearchPath); - _tcscpy(LastPrefix,szPrefix); - } - else - { - _tcscpy(szSearchPath, LastSearch); - _tcscpy(szPrefix, LastPrefix); - StartLength = 0; - } - /* search for the files it might be */ - hFile = FindFirstFile (szSearchPath, &file); - if(hFile == INVALID_HANDLE_VALUE) - { - /* Assemble the orginal string and return */ - _tcscpy(strOut,szOrginal); - return; - } + if (StartLength > 0) + { + _tcscat(szSearchPath,_T("*")); + } + _tcscpy(LastSearch,szSearchPath); + _tcscpy(LastPrefix,szPrefix); + } + else + { + _tcscpy(szSearchPath, LastSearch); + _tcscpy(szPrefix, LastPrefix); + StartLength = 0; + } + /* search for the files it might be */ + hFile = FindFirstFile (szSearchPath, &file); + if (hFile == INVALID_HANDLE_VALUE) + { + /* Assemble the orginal string and return */ + _tcscpy(strOut,szOrginal); + return; + } - /* aseemble a list of all files names */ - do - { - FileName * oldFileList = FileList; + /* aseemble a list of all files names */ + do + { + FileName * oldFileList = FileList; - if(!_tcscmp (file.cFileName, _T(".")) || - !_tcscmp (file.cFileName, _T(".."))) - continue; + if (!_tcscmp (file.cFileName, _T(".")) || + !_tcscmp (file.cFileName, _T(".."))) + continue; - /* Don't show files when they are doing 'cd' or 'rd' */ - if(!ShowAll && - file.dwFileAttributes != 0xFFFFFFFF && - !(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - continue; - } + /* Don't show files when they are doing 'cd' or 'rd' */ + if (!ShowAll && + file.dwFileAttributes != 0xFFFFFFFF && + !(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + continue; + } - /* Add the file to the list of files */ - FileList = cmd_realloc(FileList, ++FileListSize * sizeof(FileName)); + /* Add the file to the list of files */ + FileList = cmd_realloc(FileList, ++FileListSize * sizeof(FileName)); - if(FileList == NULL) - { - /* Don't leak old buffer */ - cmd_free(oldFileList); - /* Assemble the orginal string and return */ - _tcscpy(strOut,szOrginal); - FindClose(hFile); - ConOutFormatMessage (GetLastError()); - return; - } - /* Copies the file name into the struct */ - _tcscpy(FileList[FileListSize-1].Name,file.cFileName); + if (FileList == NULL) + { + /* Don't leak old buffer */ + cmd_free(oldFileList); + /* Assemble the orginal string and return */ + _tcscpy(strOut,szOrginal); + FindClose(hFile); + ConOutFormatMessage (GetLastError()); + return; + } + /* Copies the file name into the struct */ + _tcscpy(FileList[FileListSize-1].Name,file.cFileName); - } while(FindNextFile(hFile,&file)); + } while(FindNextFile(hFile,&file)); - FindClose(hFile); + FindClose(hFile); - /* Check the size of the list to see if we - found any matches */ - if(FileListSize == 0) - { - _tcscpy(strOut,szOrginal); - if(FileList != NULL) - cmd_free(FileList); - return; + /* Check the size of the list to see if we + found any matches */ + if (FileListSize == 0) + { + _tcscpy(strOut,szOrginal); + if (FileList != NULL) + cmd_free(FileList); + return; - } - /* Sort the files */ - qsort(FileList,FileListSize,sizeof(FileName), compare); + } + /* Sort the files */ + qsort(FileList,FileListSize,sizeof(FileName), compare); - /* Find the next/previous */ - if(!_tcscmp(szOrginal,LastReturned)) - { - if(bNext) - { - if(FileListSize - 1 == Sel) - Sel = 0; - else - Sel++; - } - else - { - if(!Sel) - Sel = FileListSize - 1; - else - Sel--; - } - } - else - { - Sel = 0; - } + /* Find the next/previous */ + if (!_tcscmp(szOrginal,LastReturned)) + { + if (bNext) + { + if (FileListSize - 1 == Sel) + Sel = 0; + else + Sel++; + } + else + { + if (!Sel) + Sel = FileListSize - 1; + else + Sel--; + } + } + else + { + Sel = 0; + } - /* nothing found that matched last time - so return the first thing in the list */ - strOut[0] = _T('\0'); + /* nothing found that matched last time + so return the first thing in the list */ + strOut[0] = _T('\0'); - /* Special character in the name */ - if (FileNameContainsSpecialCharacters(FileList[Sel].Name)) - { - INT LastSpace; - BOOL bInside; - /* It needs a " at the end */ - NeededQuote = TRUE; - LastSpace = -1; - bInside = FALSE; - /* Find the place to put the " at the start */ - for(i = 0; i < _tcslen(szPrefix); i++) - { - if(szPrefix[i] == _T('\"')) - bInside = !bInside; - if(szPrefix[i] == _T(' ') && !bInside) - LastSpace = i; + /* Special character in the name */ + if (FileNameContainsSpecialCharacters(FileList[Sel].Name)) + { + INT LastSpace; + BOOL bInside; + /* It needs a " at the end */ + NeededQuote = TRUE; + LastSpace = -1; + bInside = FALSE; + /* Find the place to put the " at the start */ + for(i = 0; i < _tcslen(szPrefix); i++) + { + if (szPrefix[i] == _T('\"')) + bInside = !bInside; + if (szPrefix[i] == _T(' ') && !bInside) + LastSpace = i; + } - } - /* 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) ); + /* 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) ); - if((UINT)(LastSpace + 1) == _tcslen(szPrefix)) - { - _tcscat(szPrefix,_T("\"")); - } - szPrefix[LastSpace + 1] = _T('\"'); - } - else if(LastSpace == -1) - { - /* Add quotation only if none exists already */ - if (szPrefix[0] != _T('\"')) - { - _tcscpy(szBaseWord,_T("\"")); - _tcscat(szBaseWord,szPrefix); - _tcscpy(szPrefix,szBaseWord); - } - } - } + if ((UINT)(LastSpace + 1) == _tcslen(szPrefix)) + { + _tcscat(szPrefix,_T("\"")); + } + szPrefix[LastSpace + 1] = _T('\"'); + } + else if (LastSpace == -1) + { + /* Add quotation only if none exists already */ + if (szPrefix[0] != _T('\"')) + { + _tcscpy(szBaseWord,_T("\"")); + _tcscat(szBaseWord,szPrefix); + _tcscpy(szPrefix,szBaseWord); + } + } + } - _tcscpy(strOut,szPrefix); - _tcscat(strOut,FileList[Sel].Name); + _tcscpy(strOut,szPrefix); + _tcscat(strOut,FileList[Sel].Name); - /* check for odd number of quotes means we need to close them */ - if(!NeededQuote) - { - for(i = 0; i < _tcslen(strOut); i++) - if(strOut[i] == _T('\"')) - NeededQuote = !NeededQuote; - } + /* check for odd number of quotes means we need to close them */ + if (!NeededQuote) + { + for(i = 0; i < _tcslen(strOut); i++) + { + if (strOut[i] == _T('\"')) + NeededQuote = !NeededQuote; + } + } - if(szPrefix[_tcslen(szPrefix) - 1] == _T('\"') || NeededQuote) - _tcscat(strOut,_T("\"")); - - _tcscpy(LastReturned,strOut); - //EndLength = _tcslen(strOut); - //DiffLength = EndLength - StartLength; - if(FileList != NULL) - cmd_free(FileList); + if (szPrefix[_tcslen(szPrefix) - 1] == _T('\"') || NeededQuote) + _tcscat(strOut,_T("\"")); + _tcscpy(LastReturned,strOut); + //EndLength = _tcslen(strOut); + //DiffLength = EndLength - StartLength; + if (FileList != NULL) + cmd_free(FileList); } #endif diff --git a/base/shell/cmd/for.c b/base/shell/cmd/for.c index 62802121119..44540030280 100644 --- a/base/shell/cmd/for.c +++ b/base/shell/cmd/for.c @@ -26,8 +26,8 @@ * Implemented preservation of echo flag. Some other for related * code in other files fixed, too. * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -36,16 +36,16 @@ /* FOR is a special command, so this function is only used for showing help now */ INT cmd_for (LPTSTR param) { - TRACE ("cmd_for (\'%s\')\n", debugstr_aw(param)); + TRACE ("cmd_for (\'%s\')\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_FOR_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_FOR_HELP1); + return 0; + } - error_syntax(param); - return 1; + error_syntax(param); + return 1; } /* The stack of current FOR contexts. @@ -55,322 +55,322 @@ LPFOR_CONTEXT fc = NULL; /* Get the next element of the FOR's list */ static BOOL GetNextElement(TCHAR **pStart, TCHAR **pEnd) { - TCHAR *p = *pEnd; - BOOL InQuotes = FALSE; - while (_istspace(*p)) - p++; - if (!*p) - return FALSE; - *pStart = p; - while (*p && (InQuotes || !_istspace(*p))) - InQuotes ^= (*p++ == _T('"')); - *pEnd = p; - return TRUE; + TCHAR *p = *pEnd; + BOOL InQuotes = FALSE; + while (_istspace(*p)) + p++; + if (!*p) + return FALSE; + *pStart = p; + while (*p && (InQuotes || !_istspace(*p))) + InQuotes ^= (*p++ == _T('"')); + *pEnd = p; + return TRUE; } /* Execute a single instance of a FOR command */ static INT RunInstance(PARSED_COMMAND *Cmd) { - if (bEcho && !bDisableBatchEcho && Cmd->Subcommands->Type != C_QUIET) - { - if (!bIgnoreEcho) - ConOutChar(_T('\n')); - PrintPrompt(); - EchoCommand(Cmd->Subcommands); - ConOutChar(_T('\n')); - } - /* Just run the command (variable expansion is done in DoDelayedExpansion) */ - return ExecuteCommand(Cmd->Subcommands); + if (bEcho && !bDisableBatchEcho && Cmd->Subcommands->Type != C_QUIET) + { + if (!bIgnoreEcho) + ConOutChar(_T('\n')); + PrintPrompt(); + EchoCommand(Cmd->Subcommands); + ConOutChar(_T('\n')); + } + /* Just run the command (variable expansion is done in DoDelayedExpansion) */ + return ExecuteCommand(Cmd->Subcommands); } /* Check if this FOR should be terminated early */ static BOOL Exiting(PARSED_COMMAND *Cmd) { - /* Someone might have removed our context */ - return bCtrlBreak || fc != Cmd->For.Context; + /* Someone might have removed our context */ + return bCtrlBreak || fc != Cmd->For.Context; } /* Read the contents of a text file into memory, * dynamically allocating enough space to hold it all */ static LPTSTR ReadFileContents(FILE *InputFile, TCHAR *Buffer) { - SIZE_T Len = 0; - SIZE_T AllocLen = 1000; - LPTSTR Contents = cmd_alloc(AllocLen * sizeof(TCHAR)); - if (!Contents) - return NULL; + SIZE_T Len = 0; + SIZE_T AllocLen = 1000; + LPTSTR Contents = cmd_alloc(AllocLen * sizeof(TCHAR)); + if (!Contents) + return NULL; - while (_fgetts(Buffer, CMDLINE_LENGTH, InputFile)) - { - ULONG_PTR CharsRead = _tcslen(Buffer); - while (Len + CharsRead >= AllocLen) - { - LPTSTR OldContents = Contents; - Contents = cmd_realloc(Contents, (AllocLen *= 2) * sizeof(TCHAR)); - if (!Contents) - { - cmd_free(OldContents); - return NULL; - } - } - _tcscpy(&Contents[Len], Buffer); - Len += CharsRead; - } + while (_fgetts(Buffer, CMDLINE_LENGTH, InputFile)) + { + ULONG_PTR CharsRead = _tcslen(Buffer); + while (Len + CharsRead >= AllocLen) + { + LPTSTR OldContents = Contents; + Contents = cmd_realloc(Contents, (AllocLen *= 2) * sizeof(TCHAR)); + if (!Contents) + { + cmd_free(OldContents); + return NULL; + } + } + _tcscpy(&Contents[Len], Buffer); + Len += CharsRead; + } - Contents[Len] = _T('\0'); - return Contents; + Contents[Len] = _T('\0'); + return Contents; } static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer) { - LPTSTR Delims = _T(" \t"); - TCHAR Eol = _T(';'); - INT SkipLines = 0; - DWORD Tokens = (1 << 1); - BOOL RemainderVar = FALSE; - TCHAR StringQuote = _T('"'); - TCHAR CommandQuote = _T('\''); - LPTSTR Variables[32]; - TCHAR *Start, *End; - INT i; - INT Ret = 0; + LPTSTR Delims = _T(" \t"); + TCHAR Eol = _T(';'); + INT SkipLines = 0; + DWORD Tokens = (1 << 1); + BOOL RemainderVar = FALSE; + TCHAR StringQuote = _T('"'); + TCHAR CommandQuote = _T('\''); + LPTSTR Variables[32]; + TCHAR *Start, *End; + INT i; + INT Ret = 0; - if (Cmd->For.Params) - { - TCHAR Quote = 0; - TCHAR *Param = Cmd->For.Params; - if (*Param == _T('"') || *Param == _T('\'')) - Quote = *Param++; + if (Cmd->For.Params) + { + TCHAR Quote = 0; + TCHAR *Param = Cmd->For.Params; + if (*Param == _T('"') || *Param == _T('\'')) + Quote = *Param++; - while (*Param && *Param != Quote) - { - if (*Param <= _T(' ')) - { - Param++; - } - else if (_tcsnicmp(Param, _T("delims="), 7) == 0) - { - Param += 7; - /* delims=xxx: Specifies the list of characters that separate tokens */ - Delims = Param; - while (*Param && *Param != Quote) - { - if (*Param == _T(' ')) - { - TCHAR *FirstSpace = Param; - Param += _tcsspn(Param, _T(" ")); - /* Exclude trailing spaces if this is not the last parameter */ - if (*Param && *Param != Quote) - *FirstSpace = _T('\0'); - break; - } - Param++; - } - if (*Param == Quote) - *Param++ = _T('\0'); - } - else if (_tcsnicmp(Param, _T("eol="), 4) == 0) - { - Param += 4; - /* eol=c: Lines starting with this character (may be - * preceded by delimiters) are skipped. */ - Eol = *Param; - if (Eol != _T('\0')) - Param++; - } - else if (_tcsnicmp(Param, _T("skip="), 5) == 0) - { - /* skip=n: Number of lines to skip at the beginning of each file */ - SkipLines = _tcstol(Param + 5, &Param, 0); - if (SkipLines <= 0) - goto error; - } - else if (_tcsnicmp(Param, _T("tokens="), 7) == 0) - { - Param += 7; - /* tokens=x,y,m-n: List of token numbers (must be between - * 1 and 31) that will be assigned into variables. */ - Tokens = 0; - while (*Param && *Param != Quote && *Param != _T('*')) - { - INT First = _tcstol(Param, &Param, 0); - INT Last = First; - if (First < 1) - goto error; - if (*Param == _T('-')) - { - /* It's a range of tokens */ - Last = _tcstol(Param + 1, &Param, 0); - if (Last < First || Last > 31) - goto error; - } - Tokens |= (2 << Last) - (1 << First); + while (*Param && *Param != Quote) + { + if (*Param <= _T(' ')) + { + Param++; + } + else if (_tcsnicmp(Param, _T("delims="), 7) == 0) + { + Param += 7; + /* delims=xxx: Specifies the list of characters that separate tokens */ + Delims = Param; + while (*Param && *Param != Quote) + { + if (*Param == _T(' ')) + { + TCHAR *FirstSpace = Param; + Param += _tcsspn(Param, _T(" ")); + /* Exclude trailing spaces if this is not the last parameter */ + if (*Param && *Param != Quote) + *FirstSpace = _T('\0'); + break; + } + Param++; + } + if (*Param == Quote) + *Param++ = _T('\0'); + } + else if (_tcsnicmp(Param, _T("eol="), 4) == 0) + { + Param += 4; + /* eol=c: Lines starting with this character (may be + * preceded by delimiters) are skipped. */ + Eol = *Param; + if (Eol != _T('\0')) + Param++; + } + else if (_tcsnicmp(Param, _T("skip="), 5) == 0) + { + /* skip=n: Number of lines to skip at the beginning of each file */ + SkipLines = _tcstol(Param + 5, &Param, 0); + if (SkipLines <= 0) + goto error; + } + else if (_tcsnicmp(Param, _T("tokens="), 7) == 0) + { + Param += 7; + /* tokens=x,y,m-n: List of token numbers (must be between + * 1 and 31) that will be assigned into variables. */ + Tokens = 0; + while (*Param && *Param != Quote && *Param != _T('*')) + { + INT First = _tcstol(Param, &Param, 0); + INT Last = First; + if (First < 1) + goto error; + if (*Param == _T('-')) + { + /* It's a range of tokens */ + Last = _tcstol(Param + 1, &Param, 0); + if (Last < First || Last > 31) + goto error; + } + Tokens |= (2 << Last) - (1 << First); - if (*Param != _T(',')) - break; - Param++; - } - /* With an asterisk at the end, an additional variable - * will be created to hold the remainder of the line - * (after the last token specified). */ - if (*Param == _T('*')) - { - RemainderVar = TRUE; - Param++; - } - } - else if (_tcsnicmp(Param, _T("useback"), 7) == 0) - { - Param += 7; - /* usebackq: Use alternate quote characters */ - StringQuote = _T('\''); - CommandQuote = _T('`'); - /* Can be written as either "useback" or "usebackq" */ - if (_totlower(*Param) == _T('q')) - Param++; - } - else - { - error: - error_syntax(Param); - return 1; - } - } - } + if (*Param != _T(',')) + break; + Param++; + } + /* With an asterisk at the end, an additional variable + * will be created to hold the remainder of the line + * (after the last token specified). */ + if (*Param == _T('*')) + { + RemainderVar = TRUE; + Param++; + } + } + else if (_tcsnicmp(Param, _T("useback"), 7) == 0) + { + Param += 7; + /* usebackq: Use alternate quote characters */ + StringQuote = _T('\''); + CommandQuote = _T('`'); + /* Can be written as either "useback" or "usebackq" */ + if (_totlower(*Param) == _T('q')) + Param++; + } + else + { + error: + error_syntax(Param); + return 1; + } + } + } - /* Count how many variables will be set: one for each token, - * plus maybe one for the remainder */ - fc->varcount = RemainderVar; - for (i = 1; i < 32; i++) - fc->varcount += (Tokens >> i & 1); - fc->values = Variables; + /* Count how many variables will be set: one for each token, + * plus maybe one for the remainder */ + fc->varcount = RemainderVar; + for (i = 1; i < 32; i++) + fc->varcount += (Tokens >> i & 1); + fc->values = Variables; - if (*List == StringQuote || *List == CommandQuote) - { - /* Treat the entire "list" as one single element */ - Start = List; - End = &List[_tcslen(List)]; - goto single_element; - } + if (*List == StringQuote || *List == CommandQuote) + { + /* Treat the entire "list" as one single element */ + Start = List; + End = &List[_tcslen(List)]; + goto single_element; + } - End = List; - while (GetNextElement(&Start, &End)) - { - FILE *InputFile; - LPTSTR FullInput, In, NextLine; - INT Skip; - single_element: + End = List; + while (GetNextElement(&Start, &End)) + { + FILE *InputFile; + LPTSTR FullInput, In, NextLine; + INT Skip; + single_element: - if (*Start == StringQuote && End[-1] == StringQuote) - { - /* Input given directly as a string */ - End[-1] = _T('\0'); - FullInput = cmd_dup(Start + 1); - } - else if (*Start == CommandQuote && End[-1] == CommandQuote) - { - /* Read input from a command */ - End[-1] = _T('\0'); - InputFile = _tpopen(Start + 1, _T("r")); - if (!InputFile) - { - error_bad_command(Start + 1); - return 1; - } - FullInput = ReadFileContents(InputFile, Buffer); - _pclose(InputFile); - } - else - { - /* Read input from a file */ - TCHAR Temp = *End; - *End = _T('\0'); - StripQuotes(Start); - InputFile = _tfopen(Start, _T("r")); - *End = Temp; - if (!InputFile) - { - error_sfile_not_found(Start); - return 1; - } - FullInput = ReadFileContents(InputFile, Buffer); - fclose(InputFile); - } + if (*Start == StringQuote && End[-1] == StringQuote) + { + /* Input given directly as a string */ + End[-1] = _T('\0'); + FullInput = cmd_dup(Start + 1); + } + else if (*Start == CommandQuote && End[-1] == CommandQuote) + { + /* Read input from a command */ + End[-1] = _T('\0'); + InputFile = _tpopen(Start + 1, _T("r")); + if (!InputFile) + { + error_bad_command(Start + 1); + return 1; + } + FullInput = ReadFileContents(InputFile, Buffer); + _pclose(InputFile); + } + else + { + /* Read input from a file */ + TCHAR Temp = *End; + *End = _T('\0'); + StripQuotes(Start); + InputFile = _tfopen(Start, _T("r")); + *End = Temp; + if (!InputFile) + { + error_sfile_not_found(Start); + return 1; + } + FullInput = ReadFileContents(InputFile, Buffer); + fclose(InputFile); + } - if (!FullInput) - { - error_out_of_memory(); - return 1; - } + if (!FullInput) + { + error_out_of_memory(); + return 1; + } - /* Loop over the input line by line */ - In = FullInput; - Skip = SkipLines; - do - { - DWORD RemainingTokens = Tokens; - LPTSTR *CurVar = Variables; + /* Loop over the input line by line */ + In = FullInput; + Skip = SkipLines; + do + { + DWORD RemainingTokens = Tokens; + LPTSTR *CurVar = Variables; - NextLine = _tcschr(In, _T('\n')); - if (NextLine) - *NextLine++ = _T('\0'); + NextLine = _tcschr(In, _T('\n')); + if (NextLine) + *NextLine++ = _T('\0'); - if (--Skip >= 0) - continue; + if (--Skip >= 0) + continue; - /* Ignore lines where the first token starts with the eol character */ - In += _tcsspn(In, Delims); - if (*In == Eol) - continue; + /* Ignore lines where the first token starts with the eol character */ + In += _tcsspn(In, Delims); + if (*In == Eol) + continue; - while ((RemainingTokens >>= 1) != 0) - { - /* Save pointer to this token in a variable if requested */ - if (RemainingTokens & 1) - *CurVar++ = In; - /* Find end of token */ - In += _tcscspn(In, Delims); - /* Nul-terminate it and advance to next token */ - if (*In) - { - *In++ = _T('\0'); - In += _tcsspn(In, Delims); - } - } - /* Save pointer to remainder of line */ - *CurVar = In; + while ((RemainingTokens >>= 1) != 0) + { + /* Save pointer to this token in a variable if requested */ + if (RemainingTokens & 1) + *CurVar++ = In; + /* Find end of token */ + In += _tcscspn(In, Delims); + /* Nul-terminate it and advance to next token */ + if (*In) + { + *In++ = _T('\0'); + In += _tcsspn(In, Delims); + } + } + /* Save pointer to remainder of line */ + *CurVar = In; - /* Don't run unless the line had enough tokens to fill at least one variable */ - if (*Variables[0]) - Ret = RunInstance(Cmd); - } while (!Exiting(Cmd) && (In = NextLine) != NULL); - cmd_free(FullInput); - } + /* Don't run unless the line had enough tokens to fill at least one variable */ + if (*Variables[0]) + Ret = RunInstance(Cmd); + } while (!Exiting(Cmd) && (In = NextLine) != NULL); + cmd_free(FullInput); + } - return Ret; + return Ret; } /* FOR /L: Do a numeric loop */ static INT ForLoop(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer) { - enum { START, STEP, END }; - INT params[3] = { 0, 0, 0 }; - INT i; - INT Ret = 0; + enum { START, STEP, END }; + INT params[3] = { 0, 0, 0 }; + INT i; + INT Ret = 0; - TCHAR *Start, *End = List; - for (i = 0; i < 3 && GetNextElement(&Start, &End); i++) - params[i] = _tcstol(Start, NULL, 0); + TCHAR *Start, *End = List; + for (i = 0; i < 3 && GetNextElement(&Start, &End); i++) + params[i] = _tcstol(Start, NULL, 0); - i = params[START]; - while (!Exiting(Cmd) && - (params[STEP] >= 0 ? (i <= params[END]) : (i >= params[END]))) - { - _itot(i, Buffer, 10); - Ret = RunInstance(Cmd); - i += params[STEP]; - } - return Ret; + i = params[START]; + while (!Exiting(Cmd) && + (params[STEP] >= 0 ? (i <= params[END]) : (i >= params[END]))) + { + _itot(i, Buffer, 10); + Ret = RunInstance(Cmd); + i += params[STEP]; + } + return Ret; } /* Process a FOR in one directory. Stored in Buffer (up to BufPos) is a @@ -378,135 +378,135 @@ static INT ForLoop(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer) * it will be empty, but in FOR /R it will be the directory name. */ static INT ForDir(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos) { - TCHAR *Start, *End = List; - INT Ret = 0; - while (!Exiting(Cmd) && GetNextElement(&Start, &End)) - { - if (BufPos + (End - Start) > &Buffer[CMDLINE_LENGTH]) - continue; - memcpy(BufPos, Start, (End - Start) * sizeof(TCHAR)); - BufPos[End - Start] = _T('\0'); + TCHAR *Start, *End = List; + INT Ret = 0; + while (!Exiting(Cmd) && GetNextElement(&Start, &End)) + { + if (BufPos + (End - Start) > &Buffer[CMDLINE_LENGTH]) + continue; + memcpy(BufPos, Start, (End - Start) * sizeof(TCHAR)); + BufPos[End - Start] = _T('\0'); - if (_tcschr(BufPos, _T('?')) || _tcschr(BufPos, _T('*'))) - { - WIN32_FIND_DATA w32fd; - HANDLE hFind; - TCHAR *FilePart; + if (_tcschr(BufPos, _T('?')) || _tcschr(BufPos, _T('*'))) + { + WIN32_FIND_DATA w32fd; + HANDLE hFind; + TCHAR *FilePart; - StripQuotes(BufPos); - hFind = FindFirstFile(Buffer, &w32fd); - if (hFind == INVALID_HANDLE_VALUE) - continue; - FilePart = _tcsrchr(BufPos, _T('\\')); - FilePart = FilePart ? FilePart + 1 : BufPos; - do - { - if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) - continue; - if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - != !(Cmd->For.Switches & FOR_DIRS)) - continue; - if (_tcscmp(w32fd.cFileName, _T(".")) == 0 || - _tcscmp(w32fd.cFileName, _T("..")) == 0) - continue; - _tcscpy(FilePart, w32fd.cFileName); - Ret = RunInstance(Cmd); - } while (!Exiting(Cmd) && FindNextFile(hFind, &w32fd)); - FindClose(hFind); - } - else - { - Ret = RunInstance(Cmd); - } - } - return Ret; + StripQuotes(BufPos); + hFind = FindFirstFile(Buffer, &w32fd); + if (hFind == INVALID_HANDLE_VALUE) + continue; + FilePart = _tcsrchr(BufPos, _T('\\')); + FilePart = FilePart ? FilePart + 1 : BufPos; + do + { + if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + continue; + if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + != !(Cmd->For.Switches & FOR_DIRS)) + continue; + if (_tcscmp(w32fd.cFileName, _T(".")) == 0 || + _tcscmp(w32fd.cFileName, _T("..")) == 0) + continue; + _tcscpy(FilePart, w32fd.cFileName); + Ret = RunInstance(Cmd); + } while (!Exiting(Cmd) && FindNextFile(hFind, &w32fd)); + FindClose(hFind); + } + else + { + Ret = RunInstance(Cmd); + } + } + return Ret; } /* FOR /R: Process a FOR in each directory of a tree, recursively. */ static INT ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos) { - HANDLE hFind; - WIN32_FIND_DATA w32fd; - INT Ret = 0; + HANDLE hFind; + WIN32_FIND_DATA w32fd; + INT Ret = 0; - if (BufPos[-1] != _T('\\')) - { - *BufPos++ = _T('\\'); - *BufPos = _T('\0'); - } + if (BufPos[-1] != _T('\\')) + { + *BufPos++ = _T('\\'); + *BufPos = _T('\0'); + } - Ret = ForDir(Cmd, List, Buffer, BufPos); + Ret = ForDir(Cmd, List, Buffer, BufPos); - _tcscpy(BufPos, _T("*")); - hFind = FindFirstFile(Buffer, &w32fd); - if (hFind == INVALID_HANDLE_VALUE) - return Ret; - do - { - if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - continue; - if (_tcscmp(w32fd.cFileName, _T(".")) == 0 || - _tcscmp(w32fd.cFileName, _T("..")) == 0) - continue; - Ret = ForRecursive(Cmd, List, Buffer, _stpcpy(BufPos, w32fd.cFileName)); - } while (!Exiting(Cmd) && FindNextFile(hFind, &w32fd)); - FindClose(hFind); - return Ret; + _tcscpy(BufPos, _T("*")); + hFind = FindFirstFile(Buffer, &w32fd); + if (hFind == INVALID_HANDLE_VALUE) + return Ret; + do + { + if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + if (_tcscmp(w32fd.cFileName, _T(".")) == 0 || + _tcscmp(w32fd.cFileName, _T("..")) == 0) + continue; + Ret = ForRecursive(Cmd, List, Buffer, _stpcpy(BufPos, w32fd.cFileName)); + } while (!Exiting(Cmd) && FindNextFile(hFind, &w32fd)); + FindClose(hFind); + return Ret; } BOOL ExecuteFor(PARSED_COMMAND *Cmd) { - TCHAR Buffer[CMDLINE_LENGTH]; /* Buffer to hold the variable value */ - LPTSTR BufferPtr = Buffer; - LPFOR_CONTEXT lpNew; - INT Ret; - LPTSTR List = DoDelayedExpansion(Cmd->For.List); + TCHAR Buffer[CMDLINE_LENGTH]; /* Buffer to hold the variable value */ + LPTSTR BufferPtr = Buffer; + LPFOR_CONTEXT lpNew; + INT Ret; + LPTSTR List = DoDelayedExpansion(Cmd->For.List); - if (!List) - return 1; + if (!List) + return 1; - /* Create our FOR context */ - lpNew = cmd_alloc(sizeof(FOR_CONTEXT)); - if (!lpNew) - { - cmd_free(List); - return 1; - } - lpNew->prev = fc; - lpNew->firstvar = Cmd->For.Variable; - lpNew->varcount = 1; - lpNew->values = &BufferPtr; + /* Create our FOR context */ + lpNew = cmd_alloc(sizeof(FOR_CONTEXT)); + if (!lpNew) + { + cmd_free(List); + return 1; + } + lpNew->prev = fc; + lpNew->firstvar = Cmd->For.Variable; + lpNew->varcount = 1; + lpNew->values = &BufferPtr; - Cmd->For.Context = lpNew; - fc = lpNew; + Cmd->For.Context = lpNew; + fc = lpNew; - if (Cmd->For.Switches & FOR_F) - { - Ret = ForF(Cmd, List, Buffer); - } - else if (Cmd->For.Switches & FOR_LOOP) - { - Ret = ForLoop(Cmd, List, Buffer); - } - else if (Cmd->For.Switches & FOR_RECURSIVE) - { - DWORD Len = GetFullPathName(Cmd->For.Params ? Cmd->For.Params : _T("."), - MAX_PATH, Buffer, NULL); - Ret = ForRecursive(Cmd, List, Buffer, &Buffer[Len]); - } - else - { - Ret = ForDir(Cmd, List, Buffer, Buffer); - } + if (Cmd->For.Switches & FOR_F) + { + Ret = ForF(Cmd, List, Buffer); + } + else if (Cmd->For.Switches & FOR_LOOP) + { + Ret = ForLoop(Cmd, List, Buffer); + } + else if (Cmd->For.Switches & FOR_RECURSIVE) + { + DWORD Len = GetFullPathName(Cmd->For.Params ? Cmd->For.Params : _T("."), + MAX_PATH, Buffer, NULL); + Ret = ForRecursive(Cmd, List, Buffer, &Buffer[Len]); + } + else + { + Ret = ForDir(Cmd, List, Buffer, Buffer); + } - /* Remove our context, unless someone already did that */ - if (fc == lpNew) - fc = lpNew->prev; + /* Remove our context, unless someone already did that */ + if (fc == lpNew) + fc = lpNew->prev; - cmd_free(lpNew); - cmd_free(List); - return Ret; + cmd_free(lpNew); + cmd_free(List); + return Ret; } /* EOF */ diff --git a/base/shell/cmd/free.c b/base/shell/cmd/free.c index 2d9a600b7b6..b7baa7b3a55 100644 --- a/base/shell/cmd/free.c +++ b/base/shell/cmd/free.c @@ -7,8 +7,8 @@ * 01-Sep-1999 (Eric Kohl) * Started. * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -18,102 +18,101 @@ static VOID PrintDiskInfo (LPTSTR szDisk) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; - TCHAR szRootPath[4] = _T("A:\\"); - TCHAR szDrive[2] = _T("A"); - TCHAR szVolume[64]; - TCHAR szSerial[10]; - TCHAR szTotal[40]; - TCHAR szUsed[40]; - TCHAR szFree[40]; - DWORD dwSerial; - ULONGLONG uliSize; - DWORD dwSecPerCl; - DWORD dwBytPerSec; - DWORD dwFreeCl; - DWORD dwTotCl; + TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szRootPath[4] = _T("A:\\"); + TCHAR szDrive[2] = _T("A"); + TCHAR szVolume[64]; + TCHAR szSerial[10]; + TCHAR szTotal[40]; + TCHAR szUsed[40]; + TCHAR szFree[40]; + DWORD dwSerial; + ULONGLONG uliSize; + DWORD dwSecPerCl; + DWORD dwBytPerSec; + DWORD dwFreeCl; + DWORD dwTotCl; - if (_tcslen (szDisk) < 2 || szDisk[1] != _T(':')) - { - ConErrResPrintf(STRING_FREE_ERROR1); - return; - } + if (_tcslen (szDisk) < 2 || szDisk[1] != _T(':')) + { + ConErrResPrintf(STRING_FREE_ERROR1); + return; + } - szRootPath[0] = szDisk[0]; - szDrive[0] = _totupper (szRootPath[0]); + szRootPath[0] = szDisk[0]; + szDrive[0] = _totupper (szRootPath[0]); - if (!GetVolumeInformation (szRootPath, szVolume, 64, &dwSerial, - NULL, NULL, NULL, 0)) - { - LoadString(CMD_ModuleHandle, STRING_FREE_ERROR1, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf(_T("%s %s:\n"), szMsg, szDrive); - return; - } + if (!GetVolumeInformation (szRootPath, szVolume, 64, &dwSerial, + NULL, NULL, NULL, 0)) + { + LoadString(CMD_ModuleHandle, STRING_FREE_ERROR1, szMsg, RC_STRING_MAX_SIZE); + ConErrPrintf(_T("%s %s:\n"), szMsg, szDrive); + return; + } - if (szVolume[0] == _T('\0')) - { + if (szVolume[0] == _T('\0')) + { - LoadString(CMD_ModuleHandle, STRING_FREE_ERROR2, szMsg, RC_STRING_MAX_SIZE); - _tcscpy (szVolume, szMsg); - } + LoadString(CMD_ModuleHandle, STRING_FREE_ERROR2, szMsg, RC_STRING_MAX_SIZE); + _tcscpy (szVolume, szMsg); + } - _stprintf (szSerial, - _T("%04X-%04X"), - HIWORD(dwSerial), - LOWORD(dwSerial)); + _stprintf (szSerial, + _T("%04X-%04X"), + HIWORD(dwSerial), + LOWORD(dwSerial)); - if (!GetDiskFreeSpace (szRootPath, &dwSecPerCl, - &dwBytPerSec, &dwFreeCl, &dwTotCl)) - { - LoadString(CMD_ModuleHandle, STRING_FREE_ERROR1, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf (_T("%s %s:\n"), szMsg, szDrive); - return; - } + if (!GetDiskFreeSpace (szRootPath, &dwSecPerCl, + &dwBytPerSec, &dwFreeCl, &dwTotCl)) + { + LoadString(CMD_ModuleHandle, STRING_FREE_ERROR1, szMsg, RC_STRING_MAX_SIZE); + ConErrPrintf(_T("%s %s:\n"), szMsg, szDrive); + return; + } - uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)dwTotCl; - ConvertULargeInteger(uliSize, szTotal, 40, TRUE); + uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)dwTotCl; + ConvertULargeInteger(uliSize, szTotal, 40, TRUE); - uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)(dwTotCl - dwFreeCl); - ConvertULargeInteger(uliSize, szUsed, 40, TRUE); + uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)(dwTotCl - dwFreeCl); + ConvertULargeInteger(uliSize, szUsed, 40, TRUE); - uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)dwFreeCl; - ConvertULargeInteger(uliSize, szFree, 40, TRUE); + uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)dwFreeCl; + ConvertULargeInteger(uliSize, szFree, 40, TRUE); - - ConOutResPrintf(STRING_FREE_HELP1, szDrive, szVolume, szSerial, szTotal, szUsed, szFree); + ConOutResPrintf(STRING_FREE_HELP1, szDrive, szVolume, szSerial, szTotal, szUsed, szFree); } INT CommandFree (LPTSTR param) { - LPTSTR szParam; - TCHAR szDefPath[MAX_PATH]; - INT argc, i; - LPTSTR *arg; + LPTSTR szParam; + TCHAR szDefPath[MAX_PATH]; + INT argc, i; + LPTSTR *arg; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_FREE_HELP2); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_FREE_HELP2); + return 0; + } - if (!param || *param == _T('\0')) - { - GetCurrentDirectory (MAX_PATH, szDefPath); - szDefPath[2] = _T('\0'); - szParam = szDefPath; - } - else - szParam = param; + if (!param || *param == _T('\0')) + { + GetCurrentDirectory (MAX_PATH, szDefPath); + szDefPath[2] = _T('\0'); + szParam = szDefPath; + } + else + szParam = param; - arg = split (szParam, &argc, FALSE, FALSE); + arg = split (szParam, &argc, FALSE, FALSE); - for (i = 0; i < argc; i++) - PrintDiskInfo (arg[i]); + for (i = 0; i < argc; i++) + PrintDiskInfo (arg[i]); - freep (arg); + freep (arg); - return 0; + return 0; } #endif /* INCLUDE_CMD_FREE */ diff --git a/base/shell/cmd/goto.c b/base/shell/cmd/goto.c index 0e90449f5b2..99a04cb081e 100644 --- a/base/shell/cmd/goto.c +++ b/base/shell/cmd/goto.c @@ -22,8 +22,8 @@ * 27-Jan-1999 (Eric Kohl) * Added help text ("/?"). * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -38,82 +38,82 @@ INT cmd_goto (LPTSTR param) { - LPTSTR tmp, tmp2; + LPTSTR tmp, tmp2; - TRACE ("cmd_goto (\'%s\')\n", debugstr_aw(param)); + TRACE ("cmd_goto (\'%s\')\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_GOTO_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_GOTO_HELP1); + return 0; + } - /* if not in batch -- error!! */ - if (bc == NULL) - { - return 1; - } + /* if not in batch -- error!! */ + if (bc == NULL) + { + return 1; + } - if (*param == _T('\0')) - { - ConErrResPrintf(STRING_GOTO_ERROR1); - ExitBatch(); - return 1; - } + if (*param == _T('\0')) + { + ConErrResPrintf(STRING_GOTO_ERROR1); + ExitBatch(); + return 1; + } - /* terminate label at first space char */ - tmp = param+1; - while (!_istcntrl (*tmp) && !_istspace (*tmp) && (*tmp != _T(':'))) - tmp++; - *(tmp) = _T('\0'); + /* terminate label at first space char */ + tmp = param+1; + while (!_istcntrl (*tmp) && !_istspace (*tmp) && (*tmp != _T(':'))) + tmp++; + *(tmp) = _T('\0'); - /* jump to end of the file */ - if ( _tcsicmp( param, _T(":eof"))==0) - { - bc->mempos=bc->memsize; /* position at the end of the batchfile */ - return 0; - } + /* jump to end of the file */ + if ( _tcsicmp( param, _T(":eof"))==0) + { + bc->mempos=bc->memsize; /* position at the end of the batchfile */ + return 0; + } - /* jump to begin of the file */ - bc->mempos=0; + /* jump to begin of the file */ + bc->mempos=0; - while (BatchGetString (textline, sizeof(textline) / sizeof(textline[0]))) - { - int pos; - INT_PTR size; + while (BatchGetString (textline, sizeof(textline) / sizeof(textline[0]))) + { + int pos; + INT_PTR size; - /* Strip out any trailing spaces or control chars */ - tmp = textline + _tcslen (textline) - 1; + /* Strip out any trailing spaces or control chars */ + tmp = textline + _tcslen (textline) - 1; - while (_istcntrl (*tmp) || _istspace (*tmp) || (*tmp == _T(':'))) - tmp--; - *(tmp + 1) = _T('\0'); + while (_istcntrl (*tmp) || _istspace (*tmp) || (*tmp == _T(':'))) + tmp--; + *(tmp + 1) = _T('\0'); - /* Then leading spaces... */ - tmp = textline; - while (_istspace (*tmp)) - tmp++; + /* Then leading spaces... */ + tmp = textline; + while (_istspace (*tmp)) + tmp++; - /* All space after leading space terminate the string */ - size = _tcslen(tmp) -1; - pos=0; - while (tmp+pos < tmp+size) - { - if (_istspace(tmp[pos])) - tmp[pos]=_T('\0'); - pos++; - } + /* All space after leading space terminate the string */ + size = _tcslen(tmp) -1; + pos=0; + while (tmp+pos < tmp+size) + { + if (_istspace(tmp[pos])) + tmp[pos]=_T('\0'); + pos++; + } - tmp2 = param; - /* use whole label name */ - if ((*tmp == _T(':')) && ((_tcsicmp (++tmp, param) == 0) || (_tcsicmp (tmp, ++tmp2) == 0))) - return 0; + tmp2 = param; + /* use whole label name */ + if ((*tmp == _T(':')) && ((_tcsicmp (++tmp, param) == 0) || (_tcsicmp (tmp, ++tmp2) == 0))) + return 0; - } + } - ConErrResPrintf(STRING_GOTO_ERROR2, param); - ExitBatch(); - return 1; + ConErrResPrintf(STRING_GOTO_ERROR2, param); + ExitBatch(); + return 1; } /* EOF */ diff --git a/base/shell/cmd/history.c b/base/shell/cmd/history.c index 9b5df8f6f07..347a7e12a62 100644 --- a/base/shell/cmd/history.c +++ b/base/shell/cmd/history.c @@ -43,23 +43,18 @@ typedef struct tagHISTORY { - struct tagHISTORY *prev; - struct tagHISTORY *next; - LPTSTR string; + struct tagHISTORY *prev; + struct tagHISTORY *next; + LPTSTR string; } HIST_ENTRY, * LPHIST_ENTRY; -static INT size, - max_size=100; - - +static INT size, max_size=100; static LPHIST_ENTRY Top; static LPHIST_ENTRY Bottom; - static LPHIST_ENTRY curr_ptr=0; - VOID InitHistory(VOID); VOID History_move_to_bottom(VOID); VOID History (INT dir, LPTSTR commandline); @@ -73,297 +68,273 @@ static VOID add_at_bottom(LPTSTR string); VOID set_size(INT new_size); - INT CommandHistory (LPTSTR param) { - LPTSTR tmp; - INT tmp_int; - LPHIST_ENTRY h_tmp; - TCHAR szBuffer[2048]; + LPTSTR tmp; + INT tmp_int; + LPHIST_ENTRY h_tmp; + TCHAR szBuffer[2048]; - tmp=_tcschr(param,_T('/')); + tmp=_tcschr(param,_T('/')); - if (tmp) - { - param=tmp; - switch (_totupper(param[1])) - { - case _T('F'):/*delete history*/ - CleanHistory();InitHistory(); - break; + if (tmp) + { + param=tmp; + switch (_totupper(param[1])) + { + case _T('F'):/*delete history*/ + CleanHistory();InitHistory(); + break; - case _T('R'):/*read history from standard in*/ - //hIn=GetStdHandle (STD_INPUT_HANDLE); + case _T('R'):/*read history from standard in*/ + //hIn=GetStdHandle (STD_INPUT_HANDLE); - for(;;) - { - ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR)); - if (*szBuffer!=_T('\0')) - History(0,szBuffer); - else - break; - } - break; + for(;;) + { + ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR)); + if (*szBuffer!=_T('\0')) + History(0,szBuffer); + else + break; + } + break; - case _T('A'):/*add an antry*/ - History(0,param+2); - break; + case _T('A'):/*add an antry*/ + History(0,param+2); + break; - case _T('S'):/*set history size*/ - if ((tmp_int=_ttoi(param+2))) - set_size(tmp_int); - break; + case _T('S'):/*set history size*/ + if ((tmp_int=_ttoi(param+2))) + set_size(tmp_int); + break; - default: - return 1; - } - } - else - { - for (h_tmp = Top->prev; h_tmp != Bottom; h_tmp = h_tmp->prev) - ConErrPuts(h_tmp->string); - } - return 0; + default: + return 1; + } + } + else + { + for (h_tmp = Top->prev; h_tmp != Bottom; h_tmp = h_tmp->prev) + ConErrPuts(h_tmp->string); + } + return 0; } VOID set_size(INT new_size) { - while (new_sizeprev); + while (new_sizeprev); - max_size=new_size; + max_size=new_size; } VOID InitHistory(VOID) { - size=0; + size=0; - Top = cmd_alloc(sizeof(HIST_ENTRY)); - Bottom = cmd_alloc(sizeof(HIST_ENTRY)); + Top = cmd_alloc(sizeof(HIST_ENTRY)); + Bottom = cmd_alloc(sizeof(HIST_ENTRY)); - Top->prev = Bottom; - Top->next = NULL; - Top->string = NULL; + Top->prev = Bottom; + Top->next = NULL; + Top->string = NULL; - Bottom->prev = NULL; - Bottom->next = Top; - Bottom->string = NULL; + Bottom->prev = NULL; + Bottom->next = Top; + Bottom->string = NULL; - curr_ptr=Bottom; + curr_ptr=Bottom; } - - VOID CleanHistory(VOID) { - while (Bottom->next!=Top) - del(Bottom->next); + while (Bottom->next!=Top) + del(Bottom->next); - cmd_free(Top); - cmd_free(Bottom); + cmd_free(Top); + cmd_free(Bottom); } VOID History_del_current_entry(LPTSTR str) { - LPHIST_ENTRY tmp; + LPHIST_ENTRY tmp; - if (size == 0) - return; + if (size == 0) + return; - if (curr_ptr == Bottom) - curr_ptr=Bottom->next; + if (curr_ptr == Bottom) + curr_ptr=Bottom->next; - if (curr_ptr == Top) - curr_ptr=Top->prev; + if (curr_ptr == Top) + curr_ptr=Top->prev; - tmp = curr_ptr; - curr_ptr = curr_ptr->prev; - del(tmp); - History(-1, str); + tmp = curr_ptr; + curr_ptr = curr_ptr->prev; + del(tmp); + History(-1, str); } static VOID del(LPHIST_ENTRY item) { - if (item==NULL || item==Top || item==Bottom) - { - TRACE ("del in " __FILE__ ": returning\n" - "item is 0x%08x (Bottom is0x%08x)\n", - item, Bottom); - return; - } + if (item==NULL || item==Top || item==Bottom) + { + TRACE ("del in " __FILE__ ": returning\n" + "item is 0x%08x (Bottom is0x%08x)\n", + item, Bottom); + return; + } + /*free string's mem*/ + if (item->string) + cmd_free(item->string); + /*set links in prev and next item*/ + item->next->prev=item->prev; + item->prev->next=item->next; - /*free string's mem*/ - if (item->string) - cmd_free(item->string); + cmd_free(item); - /*set links in prev and next item*/ - item->next->prev=item->prev; - item->prev->next=item->next; - - cmd_free(item); - - size--; + size--; } static VOID add_at_bottom(LPTSTR string) { + LPHIST_ENTRY tmp; + /*delete first entry if maximum number of entries is reached*/ + while(size>=max_size) + del(Top->prev); - LPHIST_ENTRY tmp; + while (_istspace(*string)) + string++; + if (*string==_T('\0')) + return; - /*delete first entry if maximum number of entries is reached*/ - while(size>=max_size) - del(Top->prev); + /*if new entry is the same than the last do not add it*/ + if (size) + if (_tcscmp(string,Bottom->next->string)==0) + return; - while (_istspace(*string)) - string++; + /*fill bottom with string, it will become Bottom->next*/ + Bottom->string=cmd_alloc((_tcslen(string)+1)*sizeof(TCHAR)); + _tcscpy(Bottom->string,string); - if (*string==_T('\0')) - return; + /*save Bottom value*/ + tmp=Bottom; + /*create new void Bottom*/ + Bottom=cmd_alloc(sizeof(HIST_ENTRY)); + Bottom->next=tmp; + Bottom->prev=NULL; + Bottom->string=NULL; - /*if new entry is the same than the last do not add it*/ - if(size) - if(_tcscmp(string,Bottom->next->string)==0) - return; - - - /*fill bottom with string, it will become Bottom->next*/ - Bottom->string=cmd_alloc((_tcslen(string)+1)*sizeof(TCHAR)); - _tcscpy(Bottom->string,string); - - /*save Bottom value*/ - tmp=Bottom; - - - /*create new void Bottom*/ - Bottom=cmd_alloc(sizeof(HIST_ENTRY)); - Bottom->next=tmp; - Bottom->prev=NULL; - Bottom->string=NULL; - - tmp->prev=Bottom; - - /*set new size*/ - size++; + tmp->prev=Bottom; + /*set new size*/ + size++; } - VOID History_move_to_bottom(VOID) { - curr_ptr=Bottom; - + curr_ptr=Bottom; } LPCTSTR PeekHistory(INT dir) { - LPHIST_ENTRY entry = curr_ptr; + LPHIST_ENTRY entry = curr_ptr; - if (dir == 0) - return NULL; + if (dir == 0) + return NULL; - if (dir < 0) - { - /* key up */ - if (entry->next == Top || entry == Top) - { + if (dir < 0) + { + /* key up */ + if (entry->next == Top || entry == Top) + { #ifdef WRAP_HISTORY - entry = Bottom; + entry = Bottom; #else - return NULL; + return NULL; #endif - } - entry = entry->next; - } - else - { - /* key down */ - if (entry->next == Bottom || entry == Bottom) - { + } + entry = entry->next; + } + else + { + /* key down */ + if (entry->next == Bottom || entry == Bottom) + { #ifdef WRAP_HISTORY - entry = Top; + entry = Top; #else - return NULL; + return NULL; #endif - } - entry = entry->prev; - } + } + entry = entry->prev; + } - return entry->string; + return entry->string; } VOID History (INT dir, LPTSTR commandline) { + if (dir==0) + { + add_at_bottom(commandline); + curr_ptr=Bottom; + return; + } - if(dir==0) - { - add_at_bottom(commandline); - curr_ptr=Bottom; - return; - } + if (size==0) + { + commandline[0]=_T('\0'); + return; + } - if (size==0) - { - commandline[0]=_T('\0'); - return; - } - - - if(dir<0)/*key up*/ - { - if (curr_ptr->next==Top || curr_ptr==Top) - { + if (dir<0)/*key up*/ + { + if (curr_ptr->next==Top || curr_ptr==Top) + { #ifdef WRAP_HISTORY - curr_ptr=Bottom; + curr_ptr=Bottom; #else - curr_ptr=Top; - commandline[0]=_T('\0'); - return; + curr_ptr=Top; + commandline[0]=_T('\0'); + return; #endif - } + } + curr_ptr = curr_ptr->next; + if (curr_ptr->string) + _tcscpy(commandline,curr_ptr->string); + } - curr_ptr = curr_ptr->next; - if(curr_ptr->string) - _tcscpy(commandline,curr_ptr->string); - - } - - - - - - if(dir>0) - { - - if (curr_ptr->prev==Bottom || curr_ptr==Bottom) - { + if (dir>0) + { + if (curr_ptr->prev==Bottom || curr_ptr==Bottom) + { #ifdef WRAP_HISTORY - curr_ptr=Top; + curr_ptr=Top; #else - curr_ptr=Bottom; - commandline[0]=_T('\0'); - return; + curr_ptr=Bottom; + commandline[0]=_T('\0'); + return; #endif - } + } - curr_ptr=curr_ptr->prev; - if(curr_ptr->string) - _tcscpy(commandline,curr_ptr->string); - - } + curr_ptr=curr_ptr->prev; + if (curr_ptr->string) + _tcscpy(commandline,curr_ptr->string); + } } #endif //#if FEATURE_HISTORY diff --git a/base/shell/cmd/if.c b/base/shell/cmd/if.c index d7a46c3b18d..d2e83e40dd7 100644 --- a/base/shell/cmd/if.c +++ b/base/shell/cmd/if.c @@ -25,8 +25,8 @@ * 17-Feb-2001 (ea) * IF DEFINED variable command * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen) + * Remove all hardcoded strings in En.rc * */ @@ -35,144 +35,144 @@ static INT GenericCmp(INT (*StringCmp)(LPCTSTR, LPCTSTR), LPCTSTR Left, LPCTSTR Right) { - TCHAR *end; - INT nLeft = _tcstol(Left, &end, 0); - if (*end == _T('\0')) - { - INT nRight = _tcstol(Right, &end, 0); - if (*end == _T('\0')) - { - /* both arguments are numeric */ - return (nLeft < nRight) ? -1 : (nLeft > nRight); - } - } - return StringCmp(Left, Right); + TCHAR *end; + INT nLeft = _tcstol(Left, &end, 0); + if (*end == _T('\0')) + { + INT nRight = _tcstol(Right, &end, 0); + if (*end == _T('\0')) + { + /* both arguments are numeric */ + return (nLeft < nRight) ? -1 : (nLeft > nRight); + } + } + return StringCmp(Left, Right); } INT cmd_if (LPTSTR param) { - TRACE ("cmd_if: (\'%s\')\n", debugstr_aw(param)); + TRACE ("cmd_if: (\'%s\')\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_IF_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_IF_HELP1); + return 0; + } - error_syntax(param); - return 1; + error_syntax(param); + return 1; } INT ExecuteIf(PARSED_COMMAND *Cmd) { - INT result = FALSE; /* when set cause 'then' clause to be executed */ - LPTSTR param; - LPTSTR Left = NULL, Right; + INT result = FALSE; /* when set cause 'then' clause to be executed */ + LPTSTR param; + LPTSTR Left = NULL, Right; - if (Cmd->If.LeftArg) - { - Left = DoDelayedExpansion(Cmd->If.LeftArg); - if (!Left) - return 1; - } - Right = DoDelayedExpansion(Cmd->If.RightArg); - if (!Right) - { - cmd_free(Left); - return 1; - } + if (Cmd->If.LeftArg) + { + Left = DoDelayedExpansion(Cmd->If.LeftArg); + if (!Left) + return 1; + } + Right = DoDelayedExpansion(Cmd->If.RightArg); + if (!Right) + { + cmd_free(Left); + return 1; + } - if (Cmd->If.Operator == IF_CMDEXTVERSION) - { - /* IF CMDEXTVERSION n: check if Command Extensions version - * is greater or equal to n */ - DWORD n = _tcstoul(Right, ¶m, 10); - if (*param != _T('\0')) - { - error_syntax(Right); - cmd_free(Right); - return 1; - } - result = (2 >= n); - } - else if (Cmd->If.Operator == IF_DEFINED) - { - /* IF DEFINED var: check if environment variable exists */ - result = (GetEnvVarOrSpecial(Right) != NULL); - } - else if (Cmd->If.Operator == IF_ERRORLEVEL) - { - /* IF ERRORLEVEL n: check if last exit code is greater or equal to n */ - INT n = _tcstol(Right, ¶m, 10); - if (*param != _T('\0')) - { - error_syntax(Right); - cmd_free(Right); - return 1; - } - result = (nErrorLevel >= n); - } - else if (Cmd->If.Operator == IF_EXIST) - { - /* IF EXIST filename: check if file exists (wildcards allowed) */ - StripQuotes(Right); + if (Cmd->If.Operator == IF_CMDEXTVERSION) + { + /* IF CMDEXTVERSION n: check if Command Extensions version + * is greater or equal to n */ + DWORD n = _tcstoul(Right, ¶m, 10); + if (*param != _T('\0')) + { + error_syntax(Right); + cmd_free(Right); + return 1; + } + result = (2 >= n); + } + else if (Cmd->If.Operator == IF_DEFINED) + { + /* IF DEFINED var: check if environment variable exists */ + result = (GetEnvVarOrSpecial(Right) != NULL); + } + else if (Cmd->If.Operator == IF_ERRORLEVEL) + { + /* IF ERRORLEVEL n: check if last exit code is greater or equal to n */ + INT n = _tcstol(Right, ¶m, 10); + if (*param != _T('\0')) + { + error_syntax(Right); + cmd_free(Right); + return 1; + } + result = (nErrorLevel >= n); + } + else if (Cmd->If.Operator == IF_EXIST) + { + /* IF EXIST filename: check if file exists (wildcards allowed) */ + StripQuotes(Right); - if (_tcschr(Right, _T('*')) || _tcschr(Right, _T('?'))) - { - WIN32_FIND_DATA f; - HANDLE hFind = FindFirstFile(Right, &f); - if (hFind != INVALID_HANDLE_VALUE) - { - result = TRUE; - FindClose(hFind); - } - } - else - { - result = (GetFileAttributes(Right) != INVALID_FILE_ATTRIBUTES); - } - } - else - { - /* Do case-insensitive string comparisons if /I specified */ - INT (*StringCmp)(LPCTSTR, LPCTSTR) = - (Cmd->If.Flags & IFFLAG_IGNORECASE) ? _tcsicmp : _tcscmp; + if (_tcschr(Right, _T('*')) || _tcschr(Right, _T('?'))) + { + WIN32_FIND_DATA f; + HANDLE hFind = FindFirstFile(Right, &f); + if (hFind != INVALID_HANDLE_VALUE) + { + result = TRUE; + FindClose(hFind); + } + } + else + { + result = (GetFileAttributes(Right) != INVALID_FILE_ATTRIBUTES); + } + } + else + { + /* Do case-insensitive string comparisons if /I specified */ + INT (*StringCmp)(LPCTSTR, LPCTSTR) = + (Cmd->If.Flags & IFFLAG_IGNORECASE) ? _tcsicmp : _tcscmp; - if (Cmd->If.Operator == IF_STRINGEQ) - { - /* IF str1 == str2 */ - result = StringCmp(Left, Right) == 0; - } - else - { - result = GenericCmp(StringCmp, Left, Right); - switch (Cmd->If.Operator) - { - case IF_EQU: result = (result == 0); break; - case IF_NEQ: result = (result != 0); break; - case IF_LSS: result = (result < 0); break; - case IF_LEQ: result = (result <= 0); break; - case IF_GTR: result = (result > 0); break; - case IF_GEQ: result = (result >= 0); break; - } - } - } + if (Cmd->If.Operator == IF_STRINGEQ) + { + /* IF str1 == str2 */ + result = StringCmp(Left, Right) == 0; + } + else + { + result = GenericCmp(StringCmp, Left, Right); + switch (Cmd->If.Operator) + { + case IF_EQU: result = (result == 0); break; + case IF_NEQ: result = (result != 0); break; + case IF_LSS: result = (result < 0); break; + case IF_LEQ: result = (result <= 0); break; + case IF_GTR: result = (result > 0); break; + case IF_GEQ: result = (result >= 0); break; + } + } + } - cmd_free(Left); - cmd_free(Right); + cmd_free(Left); + cmd_free(Right); - if (result ^ ((Cmd->If.Flags & IFFLAG_NEGATE) != 0)) - { - /* full condition was true, do the command */ - return ExecuteCommand(Cmd->Subcommands); - } - else - { - /* full condition was false, do the "else" command if there is one */ - if (Cmd->Subcommands->Next) - return ExecuteCommand(Cmd->Subcommands->Next); - return 0; - } + if (result ^ ((Cmd->If.Flags & IFFLAG_NEGATE) != 0)) + { + /* full condition was true, do the command */ + return ExecuteCommand(Cmd->Subcommands); + } + else + { + /* full condition was false, do the "else" command if there is one */ + if (Cmd->Subcommands->Next) + return ExecuteCommand(Cmd->Subcommands->Next); + return 0; + } } /* EOF */ diff --git a/base/shell/cmd/internal.c b/base/shell/cmd/internal.c index 173b69362c2..15f3c77ca2f 100644 --- a/base/shell/cmd/internal.c +++ b/base/shell/cmd/internal.c @@ -125,7 +125,7 @@ * * 02-Apr-2004 (Magnus Olsen ) * Remove all hard code string so they can be - * translate to other langues. + * translate to other langues. * * 19-Jul-2005 (Brandon Turner ) * Rewrite the CD, it working as Windows 2000 CMD @@ -151,61 +151,61 @@ INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size) { - if (InPath[0] && InPath[1] == _T(':')) - { - INT t=0; + if (InPath[0] && InPath[1] == _T(':')) + { + INT t=0; - if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9'))) - { - t = (InPath[0] - _T('0')) +28; - } + if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9'))) + { + t = (InPath[0] - _T('0')) +28; + } - if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z'))) - { - t = (InPath[0] - _T('a')) +1; - InPath[0] = t + _T('A') - 1; - } + if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z'))) + { + t = (InPath[0] - _T('a')) +1; + InPath[0] = t + _T('A') - 1; + } - if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z'))) - { - t = (InPath[0] - _T('A')) +1; - } + if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z'))) + { + t = (InPath[0] - _T('A')) +1; + } - return _tgetdcwd(t,OutPath,size) == NULL; - } + return _tgetdcwd(t,OutPath,size) == NULL; + } - /* Get current directory */ - return !GetCurrentDirectory(size,OutPath); + /* Get current directory */ + return !GetCurrentDirectory(size,OutPath); } BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath) { - TCHAR OutPath[MAX_PATH]; - TCHAR OutPathTemp[MAX_PATH]; + TCHAR OutPath[MAX_PATH]; + TCHAR OutPathTemp[MAX_PATH]; - /* The use of both of these together will correct the case of a path + /* The use of both of these together will correct the case of a path where as one alone or GetFullPath will not. Exameple: - c:\windows\SYSTEM32 => C:\WINDOWS\system32 */ - if (GetFullPathName(InPath, MAX_PATH, OutPathTemp, NULL)) - { - GetPathCase(OutPathTemp, OutPath); + c:\windows\SYSTEM32 => C:\WINDOWS\system32 */ + if (GetFullPathName(InPath, MAX_PATH, OutPathTemp, NULL)) + { + GetPathCase(OutPathTemp, OutPath); - /* Use _tchdir, since unlike SetCurrentDirectory it updates - * the current-directory-on-drive environment variables. */ - if (_tchdir(OutPath) != 0) - { - ConErrFormatMessage(GetLastError()); - nErrorLevel = 1; - return FALSE; - } + /* Use _tchdir, since unlike SetCurrentDirectory it updates + * the current-directory-on-drive environment variables. */ + if (_tchdir(OutPath) != 0) + { + ConErrFormatMessage(GetLastError()); + nErrorLevel = 1; + return FALSE; + } - /* Keep original drive in ordinary CD/CHDIR (without /D switch). */ - if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0) - SetCurrentDirectory(oldpath); - } + /* Keep original drive in ordinary CD/CHDIR (without /D switch). */ + if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0) + SetCurrentDirectory(oldpath); + } - return TRUE; + return TRUE; } @@ -215,63 +215,61 @@ BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath) */ INT cmd_chdir (LPTSTR param) { - TCHAR szCurrent[MAX_PATH]; - BOOL bChangeDrive = FALSE; + TCHAR szCurrent[MAX_PATH]; + BOOL bChangeDrive = FALSE; - /* Filter out special cases first */ + /* Filter out special cases first */ - /* Print Help */ - if (!_tcsncmp(param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_CD_HELP); - return 0; - } + /* Print Help */ + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_CD_HELP); + return 0; + } - /* Remove " */ - StripQuotes(param); + /* Remove " */ + StripQuotes(param); - /* Set Error Level to Success */ - nErrorLevel = 0; + /* Set Error Level to Success */ + nErrorLevel = 0; - /* Print Current Directory on a disk */ - if (_tcslen(param) == 2 && param[1] == _T(':')) - { - if (GetRootPath(param, szCurrent, MAX_PATH)) - { - error_invalid_drive(); - return 1; - } - ConOutPuts(szCurrent); - return 0; - } + /* Print Current Directory on a disk */ + if (_tcslen(param) == 2 && param[1] == _T(':')) + { + if (GetRootPath(param, szCurrent, MAX_PATH)) + { + error_invalid_drive(); + return 1; + } + ConOutPuts(szCurrent); + return 0; + } - /* Get Current Directory */ - GetCurrentDirectory(MAX_PATH, szCurrent); - if (param[0] == _T('\0')) - { - ConOutPuts(szCurrent); - return 0; - } + /* Get Current Directory */ + GetCurrentDirectory(MAX_PATH, szCurrent); + if (param[0] == _T('\0')) + { + ConOutPuts(szCurrent); + return 0; + } - /* Input String Contains /D Switch */ - if (!_tcsncicmp(param, _T("/D"), 2)) - { - bChangeDrive = TRUE; - param += 2; - while (_istspace(*param)) - param++; - } + /* Input String Contains /D Switch */ + if (!_tcsncicmp(param, _T("/D"), 2)) + { + bChangeDrive = TRUE; + param += 2; + while (_istspace(*param)) + param++; + } - if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param)) - return 1; + if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param)) + return 1; - return 0; + return 0; } #endif - - #ifdef INCLUDE_CMD_MKDIR /* Helper funtion for mkdir to make directories in a path. @@ -295,13 +293,15 @@ MakeFullPath(TCHAR * DirPath) p++; /* skip drive root */ do { - p = _tcschr(p, _T('\\')); - n = p ? p++ - DirPath : _tcslen(DirPath); - _tcsncpy(path, DirPath, n); - path[n] = _T('\0'); - if( !CreateDirectory(path, NULL) && - (GetLastError() != ERROR_ALREADY_EXISTS)) - return FALSE; + p = _tcschr(p, _T('\\')); + n = p ? p++ - DirPath : _tcslen(DirPath); + _tcsncpy(path, DirPath, n); + path[n] = _T('\0'); + if ( !CreateDirectory(path, NULL) && + (GetLastError() != ERROR_ALREADY_EXISTS)) + { + return FALSE; + } } while (p != NULL); return TRUE; @@ -309,46 +309,45 @@ MakeFullPath(TCHAR * DirPath) /* * MD / MKDIR - * */ INT cmd_mkdir (LPTSTR param) { - LPTSTR *p; - INT argc, i; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_MKDIR_HELP); - return 0; - } + LPTSTR *p; + INT argc, i; + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_MKDIR_HELP); + return 0; + } - p = split (param, &argc, FALSE, FALSE); - if (argc == 0) - { - ConErrResPuts(STRING_ERROR_REQ_PARAM_MISSING); - nErrorLevel = 1; - freep(p); - return 1; - } + p = split (param, &argc, FALSE, FALSE); + if (argc == 0) + { + ConErrResPuts(STRING_ERROR_REQ_PARAM_MISSING); + nErrorLevel = 1; + freep(p); + return 1; + } - nErrorLevel = 0; - for (i = 0; i < argc; i++) - { - if (!MakeFullPath(p[i])) - { - if(GetLastError() == ERROR_PATH_NOT_FOUND) - { - ConErrResPuts(STRING_MD_ERROR2); - } - else - { - ErrorMessage (GetLastError(), _T("MD")); - } - nErrorLevel = 1; - } - } + nErrorLevel = 0; + for (i = 0; i < argc; i++) + { + if (!MakeFullPath(p[i])) + { + if (GetLastError() == ERROR_PATH_NOT_FOUND) + { + ConErrResPuts(STRING_MD_ERROR2); + } + else + { + ErrorMessage (GetLastError(), _T("MD")); + } + nErrorLevel = 1; + } + } - freep (p); - return nErrorLevel; + freep (p); + return nErrorLevel; } #endif @@ -356,214 +355,218 @@ INT cmd_mkdir (LPTSTR param) #ifdef INCLUDE_CMD_RMDIR /* * RD / RMDIR - * */ BOOL DeleteFolder(LPTSTR FileName) { - TCHAR Base[MAX_PATH]; - TCHAR TempFileName[MAX_PATH]; - HANDLE hFile; + TCHAR Base[MAX_PATH]; + TCHAR TempFileName[MAX_PATH]; + HANDLE hFile; WIN32_FIND_DATA f; - _tcscpy(Base,FileName); - _tcscat(Base,_T("\\*")); - hFile = FindFirstFile(Base, &f); - Base[_tcslen(Base) - 1] = _T('\0'); + _tcscpy(Base,FileName); + _tcscat(Base,_T("\\*")); + hFile = FindFirstFile(Base, &f); + Base[_tcslen(Base) - 1] = _T('\0'); if (hFile != INVALID_HANDLE_VALUE) { do { - if (!_tcscmp(f.cFileName, _T(".")) || + if (!_tcscmp(f.cFileName, _T(".")) || !_tcscmp(f.cFileName, _T(".."))) - continue; - _tcscpy(TempFileName,Base); - _tcscat(TempFileName,f.cFileName); + continue; + _tcscpy(TempFileName,Base); + _tcscat(TempFileName,f.cFileName); - if(f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - DeleteFolder(TempFileName); - else - { - SetFileAttributes(TempFileName,FILE_ATTRIBUTE_NORMAL); - if(!DeleteFile(TempFileName)) - return 0; - } + if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + DeleteFolder(TempFileName); + else + { + SetFileAttributes(TempFileName,FILE_ATTRIBUTE_NORMAL); + if (!DeleteFile(TempFileName)) + return 0; + } }while (FindNextFile (hFile, &f)); - FindClose (hFile); + FindClose (hFile); } - return RemoveDirectory(FileName); + return RemoveDirectory(FileName); } + INT cmd_rmdir (LPTSTR param) { - TCHAR ch; - INT args; - INT dirCount; - LPTSTR *arg; - INT i; - BOOL RD_SUB = FALSE; - BOOL RD_QUIET = FALSE; - INT res; - INT nError = 0; - TCHAR szFullPath[MAX_PATH]; + TCHAR ch; + INT args; + INT dirCount; + LPTSTR *arg; + INT i; + BOOL RD_SUB = FALSE; + BOOL RD_QUIET = FALSE; + INT res; + INT nError = 0; + TCHAR szFullPath[MAX_PATH]; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_RMDIR_HELP); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_RMDIR_HELP); + return 0; + } - arg = split (param, &args, FALSE, FALSE); - dirCount = 0; + arg = split (param, &args, FALSE, FALSE); + dirCount = 0; - /* check for options anywhere in command line */ - for (i = 0; i < args; i++) - { - if (*arg[i] == _T('/')) - { - /*found a command, but check to make sure it has something after it*/ - if (_tcslen (arg[i]) == 2) - { - ch = _totupper (arg[i][1]); + /* check for options anywhere in command line */ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/')) + { + /*found a command, but check to make sure it has something after it*/ + if (_tcslen (arg[i]) == 2) + { + ch = _totupper (arg[i][1]); - if (ch == _T('S')) - { - RD_SUB = TRUE; - } - else if (ch == _T('Q')) - { - RD_QUIET = TRUE; - } - } - } - else - { - dirCount++; - } - } + if (ch == _T('S')) + { + RD_SUB = TRUE; + } + else if (ch == _T('Q')) + { + RD_QUIET = TRUE; + } + } + } + else + { + dirCount++; + } + } - if (dirCount == 0) - { - /* No folder to remove */ - error_req_param_missing(); - freep(arg); - return 1; - } + if (dirCount == 0) + { + /* No folder to remove */ + error_req_param_missing(); + freep(arg); + return 1; + } - for (i = 0; i < args; i++) - { - if (*arg[i] == _T('/')) - continue; + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/')) + continue; - if (RD_SUB) - { - /* ask if they want to delete evrything in the folder */ - if (!RD_QUIET) - { - res = FilePromptYNA (STRING_DEL_HELP2); - if (res == PROMPT_NO || res == PROMPT_BREAK) - { - nError = 1; - continue; - } - if (res == PROMPT_ALL) - RD_QUIET = TRUE; - } - /* get the folder name */ - GetFullPathName(arg[i],MAX_PATH,szFullPath,NULL); + if (RD_SUB) + { + /* ask if they want to delete evrything in the folder */ + if (!RD_QUIET) + { + res = FilePromptYNA (STRING_DEL_HELP2); + if (res == PROMPT_NO || res == PROMPT_BREAK) + { + nError = 1; + continue; + } + if (res == PROMPT_ALL) + RD_QUIET = TRUE; + } + /* get the folder name */ + GetFullPathName(arg[i],MAX_PATH,szFullPath,NULL); - /* remove trailing \ if any, but ONLY if dir is not the root dir */ - if (_tcslen (szFullPath) >= 2 && szFullPath[_tcslen (szFullPath) - 1] == _T('\\')) - szFullPath[_tcslen(szFullPath) - 1] = _T('\0'); + /* remove trailing \ if any, but ONLY if dir is not the root dir */ + if (_tcslen (szFullPath) >= 2 && szFullPath[_tcslen (szFullPath) - 1] == _T('\\')) + szFullPath[_tcslen(szFullPath) - 1] = _T('\0'); - res = DeleteFolder(szFullPath); - } - else - { - res = RemoveDirectory(arg[i]); - } + res = DeleteFolder(szFullPath); + } + else + { + res = RemoveDirectory(arg[i]); + } - if (!res) - { - /* Couldn't delete the folder, print out the error */ - nError = GetLastError(); - ErrorMessage(nError, _T("RD")); - } - } + if (!res) + { + /* Couldn't delete the folder, print out the error */ + nError = GetLastError(); + ErrorMessage(nError, _T("RD")); + } + } - freep (arg); - return nError; + freep (arg); + return nError; } #endif /* * set the exitflag to true - * */ INT CommandExit (LPTSTR param) { - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_EXIT_HELP); - /* Just make sure */ - bExit = FALSE; - /* Dont exit */ - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_EXIT_HELP); + /* Just make sure */ + bExit = FALSE; + /* Dont exit */ + return 0; + } - if (bc != NULL && _tcsnicmp(param,_T("/b"),2) == 0) - { - param += 2; - while (_istspace (*param)) - param++; - if (_istdigit(*param)) - nErrorLevel = _ttoi(param); - ExitBatch(); - } - - else - bExit = TRUE; - - - return 0; + if (bc != NULL && _tcsnicmp(param,_T("/b"),2) == 0) + { + param += 2; + while (_istspace (*param)) + param++; + if (_istdigit(*param)) + nErrorLevel = _ttoi(param); + ExitBatch(); + } + else + { + bExit = TRUE; + } + return 0; } #ifdef INCLUDE_CMD_REM /* * does nothing - * */ INT CommandRem (LPTSTR param) { - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_REM_HELP); - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_REM_HELP); + } - return 0; + return 0; } #endif /* INCLUDE_CMD_REM */ INT CommandShowCommands (LPTSTR param) { - PrintCommandList (); - return 0; + PrintCommandList(); + return 0; } -INT CommandShowCommandsDetail (LPTSTR param) +INT CommandShowCommandsDetail(LPTSTR param) { - /* If a param was send, display help of correspondent command */ - if (_tcslen(param)) - { - DoCommand(param, _T("/?"), NULL); - } - /* Else, display detailed commands list */ - else - { - PrintCommandListDetail (); - } - return 0; + /* We display help for the help command */ + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutResPaging(TRUE, STRING_HELP_HELP1); + return 0; + } + + /* If a param was send, display help of corresponding command */ + if (_tcslen(param)) + { + DoCommand(param, _T("/?"), NULL); + } + /* Else, display detailed commands list */ + else + { + PrintCommandListDetail(); + } + return 0; } /* EOF */ diff --git a/base/shell/cmd/label.c b/base/shell/cmd/label.c index 3ba4130cdd1..a42ac3b2d37 100644 --- a/base/shell/cmd/label.c +++ b/base/shell/cmd/label.c @@ -13,8 +13,8 @@ * 19-Jan-1998 (Eric Kohl) * Unicode ready! * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -24,80 +24,80 @@ INT cmd_label (LPTSTR param) { - TCHAR szRootPath[] = _T("A:\\"); - TCHAR szLabel[80]; - TCHAR szOldLabel[80]; - DWORD dwSerialNr; + TCHAR szRootPath[] = _T("A:\\"); + TCHAR szLabel[80]; + TCHAR szOldLabel[80]; + DWORD dwSerialNr; - /* set empty label string */ - szLabel[0] = _T('\0'); + /* set empty label string */ + szLabel[0] = _T('\0'); - nErrorLevel = 0; + nErrorLevel = 0; - /* print help */ - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_LABEL_HELP1); - return 0; - } + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_LABEL_HELP1); + return 0; + } - /* get parameters */ - if (param[0] != _T('\0') && param[1] == _T(':')) - { - szRootPath[0] = toupper(*param); - param += 2; - while (_istspace(*param)) - param++; - } - else - { - /* get label of current drive */ - TCHAR szCurPath[MAX_PATH]; - GetCurrentDirectory (MAX_PATH, szCurPath); - szRootPath[0] = szCurPath[0]; - } + /* get parameters */ + if (param[0] != _T('\0') && param[1] == _T(':')) + { + szRootPath[0] = toupper(*param); + param += 2; + while (_istspace(*param)) + param++; + } + else + { + /* get label of current drive */ + TCHAR szCurPath[MAX_PATH]; + GetCurrentDirectory (MAX_PATH, szCurPath); + szRootPath[0] = szCurPath[0]; + } - _tcsncat(szLabel, param, 79); + _tcsncat(szLabel, param, 79); - /* check root path */ - if (!IsValidPathName (szRootPath)) - { - error_invalid_drive (); - nErrorLevel = 1; - return 1; - } + /* check root path */ + if (!IsValidPathName (szRootPath)) + { + error_invalid_drive (); + nErrorLevel = 1; + return 1; + } - if (szLabel[0] == _T('\0')) - { - GetVolumeInformation(szRootPath, szOldLabel, 80, &dwSerialNr, - NULL, NULL, NULL, 0); + if (szLabel[0] == _T('\0')) + { + GetVolumeInformation(szRootPath, szOldLabel, 80, &dwSerialNr, + NULL, NULL, NULL, 0); - /* print drive info */ - if (szOldLabel[0] != _T('\0')) - { - ConOutResPrintf(STRING_LABEL_HELP2, _totupper(szRootPath[0]), szOldLabel); - } - else - { - ConOutResPrintf(STRING_LABEL_HELP3, _totupper(szRootPath[0])); - } + /* print drive info */ + if (szOldLabel[0] != _T('\0')) + { + ConOutResPrintf(STRING_LABEL_HELP2, _totupper(szRootPath[0]), szOldLabel); + } + else + { + ConOutResPrintf(STRING_LABEL_HELP3, _totupper(szRootPath[0])); + } - /* print the volume serial number */ - ConOutResPrintf(STRING_LABEL_HELP4, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); + /* print the volume serial number */ + ConOutResPrintf(STRING_LABEL_HELP4, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); - ConOutResPuts(STRING_LABEL_HELP5); + ConOutResPuts(STRING_LABEL_HELP5); - ConInString(szLabel, 80); - } + ConInString(szLabel, 80); + } - if (!SetVolumeLabel(szRootPath, szLabel)) - { - ConOutFormatMessage(GetLastError()); - nErrorLevel = 1; - return 1; - } + if (!SetVolumeLabel(szRootPath, szLabel)) + { + ConOutFormatMessage(GetLastError()); + nErrorLevel = 1; + return 1; + } - return 0; + return 0; } #endif /* INCLUDE_CMD_LABEL */ diff --git a/base/shell/cmd/lang/de-DE.rc b/base/shell/cmd/lang/de-DE.rc index f6c03e9e3d6..7136a37bce0 100644 --- a/base/shell/cmd/lang/de-DE.rc +++ b/base/shell/cmd/lang/de-DE.rc @@ -89,12 +89,12 @@ STRING_CMD_HELP7," [redirections and piping]" STRING_CMD_HELP8, "Startet eine neue Instanz des ReactOS-Befehlsinterpreters.\n\n\ CMD [/[C|K] Befehl][/P][/Q][/T:bf]\n\n\ - /C Befehl Führt den Befehl in der Zeichenfolge aus. Anschließend\n\ - wird diese Instanz beendet.\n\ - /K Befehl Führt den Befehl in der Zeichenfolge aus und läuft weiter.\n\ - /P CMD wird permanent und führt autoexec.bat aus\n\ - (kann nicht beendet werden).\n\ - /T:bf Ändert die Hintergrund- und Vordergrund-Farbe (siehe COLOR Befehl)." + /C Befehl Führt den Befehl in der Zeichenfolge aus. Anschließend\n\ + wird diese Instanz beendet.\n\ + /K Befehl Führt den Befehl in der Zeichenfolge aus und läuft weiter.\n\ + /P CMD wird permanent und führt autoexec.bat aus\n\ + (kann nicht beendet werden).\n\ + /T:bf Ändert die Hintergrund- und Vordergrund-Farbe (siehe COLOR Befehl)." STRING_COLOR_HELP1, "Legt die Standardhinter- und Vordergrundfarben für die Konsole fest.\n\n\ COLOR [attr [/F]] \n\n\ @@ -107,15 +107,15 @@ Die jeweils erste Angabe bezieht sich auf den Hintergrund, die zweite\n\ auf den Vordergrund. \n\ Es müssen jeweils zwei Werte angegeben werden. \n\ Farben:\n\ -Dez Hex Name dec hex name\n\ -0 0 Schwarz 8 8 Dunkelgrau\n\ +Dez Hex Name dec hex name\n\ +0 0 Schwarz 8 8 Dunkelgrau\n\ 1 1 Dunkelblau 9 9 Blau\n\ -2 2 Dunkelgrün 10 A Grün\n\ -3 3 Blaugrün 11 B Zyan\n\ -4 4 Dunkelrot 12 C Rot\n\ -5 5 Lila 13 D Magenta\n\ -6 6 Ocker 14 E Gelb\n\ -7 7 Hellgrau 15 F Weiß\n\ +2 2 Dunkelgrün 10 A Grün\n\ +3 3 Blaugrün 11 B Zyan\n\ +4 4 Dunkelrot 12 C Rot\n\ +5 5 Lila 13 D Magenta\n\ +6 6 Ocker 14 E Gelb\n\ +7 7 Hellgrau 15 F Weiß\n\ Beispiel: ""COLOR fc"" legt Rot als Text- und Weiß als Hintergrund-\n\ farbe fest" @@ -262,6 +262,15 @@ STRING_FREE_HELP1, "\nVolume in Laufwerk %s ist %-11s\n\ STRING_FREE_HELP2, "Zeigt die Volumeinformationen an.\n\nFREE [Laufwerk: ...]" +STRING_GOTO_HELP1, "Setzt die Ausführung eines Batchprogramms an einer Marke fort.\n\n\ +GOTO Marke\n\n\ + Marke Definiert eine Zeichenfolge als Marke in einem Batchprogramm.\n\n\ +Marken stehen am Zeilenanfang mit einem vorangestellten Doppelpunkt." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Verarbeitet Ausdrücke in einer Batchdatei abhängig von Bedingungen.\n\n\ IF [NOT] ERRORLEVEL Nummer Befehl\n\ IF [NOT] variable1==variable2 Befehl\n\ @@ -279,11 +288,6 @@ EXIST Dateiname Bedingung ist erfüllt, wenn die angegebene Datei existiert.\n DEFINED variable Bedingung ist erfüllt, wenn die angegebene Datei definiert\n\ wurde." -STRING_GOTO_HELP1, "Setzt die Ausführung eines Batchprogramms an einer Marke fort.\n\n\ -GOTO Marke\n\n\ - Marke Definiert eine Zeichenfolge als Marke in einem Batchprogramm.\n\n\ -Marken stehen am Zeilenanfang mit einem vorangestellten Doppelpunkt." - STRING_LABEL_HELP1, "Erstellt, ändert oder löscht die Bezeichnung eines Volumes.\n\nLABEL [Laufwerk:][label]" STRING_LABEL_HELP2, "Datenträger im Laufwerk %c: ist %s\n" @@ -357,10 +361,12 @@ Sie kann aus normalen Zeichen und folgenden Sonderzeichen bestehen:\n\n\ $F ) (Klammer zu)\n\ $G > (Größer-als-Zeichen)\n\ $H Rückschritt (löscht vorangehendes Zeichen)\n\ + $I Information line\n\ $L < (Kleiner-als-Zeichen)\n\ $N Aktuelles Laufwerk\n\ $P Aktuelles Laufwerk und Pfad\n\ $Q = (Gleichheitszeichen)\n\ + $S (space)\n\ $T Aktuelle Zeit\n\ $V Betriebssystem-Versionsnummer\n\ $_ Wagenrücklauf und Zeilenvorschub\n\ @@ -554,6 +560,7 @@ RESTORE stellt das Fenster wieder her\n\ title neuer Titel" STRING_HELP1, "Übersicht aller verfügbaren Befehle und deren Kurzbeschreibungen\n\n\ + help Befehl\n\ Befehl /? Um nähere Informationen zu einem bestimmten Befehl\n\ zu erhalten.\n\n\ ? Listet alle Befehle auf (ohne Erklärung).\n\ diff --git a/base/shell/cmd/lang/el-GR.rc b/base/shell/cmd/lang/el-GR.rc index bee177e170a..15f79119200 100644 --- a/base/shell/cmd/lang/el-GR.rc +++ b/base/shell/cmd/lang/el-GR.rc @@ -266,6 +266,15 @@ STRING_FREE_HELP1, "\nVolume in drive %s is %-11s\n\ STRING_FREE_HELP2, "Displays drive information.\n\nFREE [drive: ...]\n" +STRING_GOTO_HELP1, "Directs CMD to a labeled line in a batch script.\n\n\ +GOTO label\n\n\ + label Specifies a text string used in a batch script as a label.\n\n\ +You type a label on a line by itself, beginning with a colon." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Performs conditional processing in batch programs.\n\n\ IF [NOT] ERRORLEVEL number command\n\ IF [NOT] string1==string2 command\n\ @@ -282,11 +291,6 @@ EXIST filename Specifies a true condition if the specified filename exists.\n DEFINED variable Specifies a true condition if the specified variable is\n\ defined.\n" -STRING_GOTO_HELP1, "Directs CMD to a labeled line in a batch script.\n\n\ -GOTO label\n\n\ - label Specifies a text string used in a batch script as a label.\n\n\ -You type a label on a line by itself, beginning with a colon." - STRING_LABEL_HELP1, "Displays or changes drive label.\n\nLABEL [drive:][label]\n" STRING_LABEL_HELP2, "Volume in drive %c: is %s\n" @@ -360,10 +364,12 @@ Prompt can be made up of normal characters and the following special codes:\n\n\ $F ) (Right parenthesis)\n\ $G > (greater-than sign)\n\ $H Backspace (erases previous character)\n\ + $I Information line\n\ $L < (less-than sign)\n\ $N Current drive\n\ $P Current drive and path\n\ $Q = (equal sign)\n\ + $S (space)\n\ $T Current time\n\ $V OS version number\n\ $_ Carriage return and linefeed\n\ @@ -381,9 +387,9 @@ STRING_REM_HELP, "Starts a comment line in a batch file.\n\nREM [Comment]" STRING_RMDIR_HELP, "Removes a directory.\n\n\ RMDIR [drive:]path\nRD [drive:]path\n\ -/S Deletes all files and folders within target\n\ -/Q Doesnt prompt for user\n" -STRING_RMDIR_HELP2, "Directory is not empty!\n" +/S Deletes all files and folders within target\n\ +/Q Doesn't prompt for user\n" +STRING_RMDIR_HELP2, "Directory is not empty!\n" STRING_REN_HELP1, "Renames a file/directory or files/directories.\n\n\ RENAME [/E /N /P /Q /S /T] old_name ... new_name\n\ @@ -494,7 +500,7 @@ if none of ON, OFF or /S is specified the command\n\ will toggle stopwatch state\n\n" STRING_TYPE_HELP1, "Displays the contents of text files.\n\nTYPE [drive:][path]filename \n\ - /P Shows one screen of output at a time.\n" + /P Shows one screen of output at a time.\n" STRING_VERIFY_HELP1, "This command is just a dummy!!\n\ Sets whether to verify that your files are written correctly to a\n\ @@ -559,6 +565,7 @@ title new title\n" STRING_HELP1, "List of all available commands (+ description)\n\n\ + help command\n\ command /? For more information on a specific command\n\n\ ? List all available commands without description).\n\ ALIAS Sets, removes or shows aliases.\n\ diff --git a/base/shell/cmd/lang/en-US.rc b/base/shell/cmd/lang/en-US.rc index fdf87e7e257..b63393c0f0d 100644 --- a/base/shell/cmd/lang/en-US.rc +++ b/base/shell/cmd/lang/en-US.rc @@ -266,6 +266,15 @@ STRING_FREE_HELP1, "\nVolume in drive %s is %-11s\n\ STRING_FREE_HELP2, "Displays drive information.\n\nFREE [drive: ...]\n" +STRING_GOTO_HELP1, "Directs CMD to a labeled line in a batch script.\n\n\ +GOTO label\n\n\ + label Specifies a text string used in a batch script as a label.\n\n\ +You type a label on a line by itself, beginning with a colon." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Performs conditional processing in batch programs.\n\n\ IF [NOT] ERRORLEVEL number command\n\ IF [NOT] string1==string2 command\n\ @@ -282,11 +291,6 @@ EXIST filename Specifies a true condition if the specified filename exists.\n DEFINED variable Specifies a true condition if the specified variable is\n\ defined.\n" -STRING_GOTO_HELP1, "Directs CMD to a labeled line in a batch script.\n\n\ -GOTO label\n\n\ - label Specifies a text string used in a batch script as a label.\n\n\ -You type a label on a line by itself, beginning with a colon." - STRING_LABEL_HELP1, "Displays or changes drive label.\n\nLABEL [drive:][label]\n" STRING_LABEL_HELP2, "Volume in drive %c: is %s\n" @@ -360,10 +364,12 @@ Prompt can be made up of normal characters and the following special codes:\n\n\ $F ) (Right parenthesis)\n\ $G > (greater-than sign)\n\ $H Backspace (erases previous character)\n\ + $I Information line\n\ $L < (less-than sign)\n\ $N Current drive\n\ $P Current drive and path\n\ $Q = (equal sign)\n\ + $S (space)\n\ $T Current time\n\ $V OS version number\n\ $_ Carriage return and linefeed\n\ @@ -381,9 +387,9 @@ STRING_REM_HELP, "Starts a comment line in a batch file.\n\nREM [Comment]" STRING_RMDIR_HELP, "Removes a directory.\n\n\ RMDIR [drive:]path\nRD [drive:]path\n\ -/S Deletes all files and folders within target\n\ -/Q Doesnt prompt for user\n" -STRING_RMDIR_HELP2, "Directory is not empty!\n" +/S Deletes all files and folders within target\n\ +/Q Doesn't prompt for user\n" +STRING_RMDIR_HELP2, "Directory is not empty!\n" STRING_REN_HELP1, "Renames a file/directory or files/directories.\n\n\ RENAME [/E /N /P /Q /S /T] old_name ... new_name\n\ @@ -494,7 +500,7 @@ if none of ON, OFF or /S is specified the command\n\ will toggle stopwatch state\n\n" STRING_TYPE_HELP1, "Displays the contents of text files.\n\nTYPE [drive:][path]filename \n\ - /P Shows one screen of output at a time.\n" + /P Shows one screen of output at a time.\n" STRING_VERIFY_HELP1, "This command is just a dummy!!\n\ Sets whether to verify that your files are written correctly to a\n\ @@ -559,6 +565,7 @@ title new title\n" STRING_HELP1, "List of all available commands (+ description)\n\n\ + help command\n\ command /? For more information on a specific command\n\n\ ? List all available commands (without description).\n\ ALIAS Sets, removes or shows aliases.\n\ diff --git a/base/shell/cmd/lang/es-ES.rc b/base/shell/cmd/lang/es-ES.rc index 54c26add5a5..6690009ca43 100644 --- a/base/shell/cmd/lang/es-ES.rc +++ b/base/shell/cmd/lang/es-ES.rc @@ -152,7 +152,7 @@ ERASE [/N /P /T /Q /S /W /Y /Z /A[[:]atributos]] archivo ...\n\n\ /N Nada.\n\ /P Prompt. Pregunta antes de borar cada archivo\n\ /T Total. Muestra el número total de archivos eliminados y el espacio\n\ - liberado en disco\n\ + liberado en disco\n\ /Q Modo silencioso.\n\ /W Limpiar. Sobreescribe el archivo con números aleatorios después de eliminarlo.\n\ /Y Si. Borra incluso *.* sin preguntar.\n\ @@ -198,8 +198,8 @@ STRING_DIR_HELP1, "DIR [unidad:][ruta][nombre de archivo] [/A[[:]atributos]] [/B /S Muestra los archivos en el directorio especificado y sus subdirectorios.\n\ /T Controla que campo de tiempo se muestra o es usado para ordenar:\n\ campo de tiempo C Creación\n\ - A Último acceso\n\ - W Última escritura\n\ + A Último acceso\n\ + W Última escritura\n\ /W Usa el formato de lista a lo ancho.\n\ /X Muestra los nombres cortos generados para archivos que no tienen un\n\ nombre 8.3. El formato es como /N pero con el nombre corto colocado\n\ @@ -267,6 +267,15 @@ STRING_FREE_HELP1, "\nEl volumen en la unidad %s es %-11s\n\ STRING_FREE_HELP2, "Muestra la información de la unidad.\n\nFREE [unidad: ...]\n" +STRING_GOTO_HELP1, "Manda al CMD a una linea etiquetada en un archivo por lotes.\n\n\ +GOTO etiqueta\n\n\ + etiqueta Especifica la cadena de texto usada en el archivo por lotes como etiqueta.\n\n\ +Escriba la etiqueta en la linea misma, empezando con dos puntos." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Ejecuta procesos condicionales en archivos por lotes.\n\n\ IF [NOT] ERRORLEVEL número comando\n\ IF [NOT] string1==string2 comando\n\ @@ -281,11 +290,6 @@ string1==string2 Especifica una condición verdadera si las cadenas de texto co EXIST archivo Especifica una condición verdadera si existe el archivo especificado.\n\ DEFINED variable Especifica una condición verdadera si la variable está definida.\n" -STRING_GOTO_HELP1, "Manda al CMD a una linea etiquetada en un archivo por lotes.\n\n\ -GOTO etiqueta\n\n\ - etiqueta Especifica la cadena de texto usada en el archivo por lotes como etiqueta.\n\n\ -Escriba la etiqueta en la linea misma, empezando con dos puntos." - STRING_LABEL_HELP1, "Muestra o cambia la etiqueta de una unidad.\n\nLABEL [unidad:][etiqueta]\n" STRING_LABEL_HELP2, "El volumen en la unidad %c: es %s\n" @@ -360,10 +364,12 @@ códigos especiales:\n\n\ $F ) (Paréntesis derecho)\n\ $G > (Signo mayor que)\n\ $H Borra el caracter anterior\n\ + $I Information line\n\ $L < (Signo menor que)\n\ $N Unidad actual\n\ $P Unidad y ruta actuales\n\ $Q = (signo igual)\n\ + $S (space)\n\ $T Hora actual\n\ $V Número de versión del SO\n\ $_ Salto de linea\n\ @@ -495,7 +501,7 @@ Si ni ON, OFF o /S se especifican, el comando\n\ cambiara el estado de parada del reloj\n\n" STRING_TYPE_HELP1, "Muestra los contenidos de un archivo de texto.\n\nTYPE [unidad:][ruta]archivo \n\ - /P Muestra sólo una pantalla de salida cada vez.\n" + /P Muestra sólo una pantalla de salida cada vez.\n" STRING_VERIFY_HELP1, "¡¡Este comando es solo de relleno!!\n\ Configura si hay que verificar que los archivos se and escrito correctamente\n\ @@ -560,6 +566,7 @@ title Nuevo título\n" STRING_HELP1, "Lista de todos los comandos disponibles (con descripción)\n\n\ + help comando\n\ comando /? Para más información del comando especificado.\n\n\ ? Muestra todos los comandos disponibles (sin la descripción).\n\ ALIAS Crea, borra o muestra los alias.\n\ diff --git a/base/shell/cmd/lang/fr-FR.rc b/base/shell/cmd/lang/fr-FR.rc index f99b073b0df..c08527ec836 100644 --- a/base/shell/cmd/lang/fr-FR.rc +++ b/base/shell/cmd/lang/fr-FR.rc @@ -281,6 +281,15 @@ Le numéro de série est %s\n\ STRING_FREE_HELP2, "Affiche les information d'un disque.\n\nFREE [lecteur: ...]" +STRING_GOTO_HELP1, "Dirige CMD vers une ligne nommée dans un script batch.\n\n\ +GOTO label\n\n\ + label Spécifie un champ texte utilisé dans un script batch comme un label.\n\n\ +Vous écrivez un label seul sur une ligne commençant par un deux-points.\n" + +STRING_HELP_HELP1, "Fournit des informations d'aide pour les commandes de ReactOS.\n\n\ +HELP [commande]\n\n\ + commande - Affiche des informations d'aide sur cette commande.\n" + STRING_IF_HELP1, "Exécute un traitement conditionnel dans des programmes batch.\n\n\ IF [NOT] ERRORLEVEL nombre commande\n\ IF [NOT] chaine1==chaine2 commande\n\ @@ -294,11 +303,6 @@ chaine1==chaine2 La condition sera vraie si les deux chaines sont identiques.\n EXIST nomfichier La condition sera vraie si le fichier spécifié existe.\n\ DEFINED variable La condition sera vraie si la variable indiquée est définie." -STRING_GOTO_HELP1, "Dirige CMD vers une ligne nommée dans un script batch.\n\n\ -GOTO label\n\n\ - label Spécifie un champ texte utilisé dans un script batch comme un label.\n\n\ -Vous écrivez un label seul sur une ligne commençant par un deux-points.\n" - STRING_LABEL_HELP1, "Affiche ou change le nom de volume du disque.\n\nLABEL [disque:][nomdevolume]\n" STRING_LABEL_HELP2, "Le nom de volume du disque %c: est %s\n" @@ -374,10 +378,12 @@ des caractères spéciaux suivants:\n\n\ $F ) (parenthèse fermante)\n\ $G > (signe supérieur à)\n\ $H Backspace (efface le caractère précédent)\n\ + $I Ligne d'information\n\ $L < (signe inférieur à)\n\ $N Lecteur courant\n\ $P Lecteur et chemin courants\n\ $Q = (signe égale)\n\ + $S (espace)\n\ $T Heure courante\n\ $V Numéro de version de ReactOS\n\ $_ Retour chariot/saut de ligne\n\ @@ -396,9 +402,9 @@ STRING_REM_HELP, "Démarrer une ligne de commentaire dans un fichier batch.\n\nR STRING_RMDIR_HELP, "Supprime un répertoire.\n\n\ RMDIR [lecteur:]chemin\nRD [lecteur:]chemin\n\ -/S Supprime tous les fichiers et dossiers dans le répertoire cible\n\ -/Q N'interroge pas l'utilisateur\n" -STRING_RMDIR_HELP2, "Le répertoire n'est pas vide!\n" +/S Supprime tous les fichiers et dossiers dans le répertoire cible\n\ +/Q N'interroge pas l'utilisateur\n" +STRING_RMDIR_HELP2, "Le répertoire n'est pas vide!\n" STRING_REN_HELP1, "Renomme un(des) fichier(s)/répertoire(s)\n\ RENAME [/E /N /P /Q /S /T] ancien_nom ... nouveau_nom\n\ @@ -508,7 +514,7 @@ En l'absence d'une option ON, OFF ou /S la commande\n\ changera l'état du chronomètre sélectionné\n\n" STRING_TYPE_HELP1, "Affiche le contenu de fichiers textes.\n\nTYPE [lecteur:][chemin]nomfich \n\ - /P Ne montre qu'un écran de contenu à la fois.\n" + /P Ne montre qu'un écran de contenu à la fois.\n" STRING_VERIFY_HELP1, "Cette commande ne fait rien !!\n\ Spécifie s'il faut verifier que vos fichiers sont écrits correctement.\ @@ -573,6 +579,7 @@ titre titre de la fenêtre" STRING_HELP1, "Liste de toutes les commandes disponibles (+ description)\n\n\ + help commande\n\ commande /? Pour plus d'informations sur une commande spécifique\n\n\ ? Liste toutes les commandes disponibles sans leur description).\n\ ALIAS Défini, supprime ou montre les alias.\n\ @@ -713,7 +720,7 @@ STRING_REPLACE_ERROR6, "Aucun fichier trouvé - %s\n" STRING_REPLACE_ERROR7, "Erreur étendue 32\n" STRING_REACTOS_VERSION, "ReactOS Operating System [Version %s-%s]\n" -STRING_CMD_SHELLINFO, "\n Interpréteur de ligne de commandes ReactOS\nVersion %s %s" +STRING_CMD_SHELLINFO, "\nInterpréteur de ligne de commandes ReactOS\nVersion %s %s" STRING_VERSION_RUNVER, " tournant sur %s" STRING_COPY_FILE, " %d fichier(s) copié(s)\n" STRING_DELETE_WIPE, "effacé(s)" diff --git a/base/shell/cmd/lang/hu-HU.rc b/base/shell/cmd/lang/hu-HU.rc index 71986d9f515..c63be91b113 100644 --- a/base/shell/cmd/lang/hu-HU.rc +++ b/base/shell/cmd/lang/hu-HU.rc @@ -106,7 +106,7 @@ hex név hex név\n\ 3 Sötétlila B Türkízkék\n\ 4 Bordó C Vörös\n\ 5 Ciklámen D Ciklámen\n\ -6 Olíva E Sárga\n\ +6 Olíva E Sárga\n\ 7 Világos szürke F Fehér\n" STRING_COPY_HELP1, "Felülírja a következõt: %s (Igen/Nem/Mind)? " @@ -251,6 +251,15 @@ STRING_FREE_HELP1, "\nA (%s) meghajtóban lévõ kötet címkéje %-11s\n\ STRING_FREE_HELP2, "Kötet méret információk.\n\nFREE [meghajtó: ...]\n" +STRING_GOTO_HELP1, "Átirányít egy másik címkére a batch állományban.\n\n\ +GOTO címke\n\n\ + címke A megadott címkére fog ugrani az értelmezõ.\n\n\ +Egy címkét egy sorban lehet megadni, ':' -tal kezdve." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Performs conditional processing in batch programs.\n\n\ IF [NOT] ERRORLEVEL number command\n\ IF [NOT] string1==string2 command\n\ @@ -267,11 +276,6 @@ EXIST állományname Specifies a true condition if the specified állományna DEFINED variable Specifies a true condition if the specified variable is\n\ defined.\n" -STRING_GOTO_HELP1, "Átirányít egy másik címkére a batch állományban.\n\n\ -GOTO címke\n\n\ - címke A megadott címkére fog ugrani az értelmezõ.\n\n\ -Egy címkét egy sorban lehet megadni, ':' -tal kezdve." - STRING_LABEL_HELP1, "A kötet címkéjét megjeleníti, vagy megváltoztatja.\n\n\ LABEL [meghajtó:] [új_címke]\n" @@ -346,10 +350,12 @@ A parancssor speciális kódokat is tartalmazhat:\n\n\ $F ) (záró zárójel)\n\ $G > ('nagyobb' jel)\n\ $H Törlés (elötte lévõ karaktert törli)\n\ + $I Information line\n\ $L < ('kissebb' jel)\n\ $N Aktuális meghajtó\n\ $P Aktuális meghajtó és mappa\n\ $Q = (egyenlõség jel)\n\ + $S (space)\n\ $T Aktuális idõ\n\ $V OS verziószám\n\ $_ Újsor\n\ @@ -373,7 +379,7 @@ STRING_REN_HELP1, "Átnevez egy állományt.\n\n\ RENAME [/E /N /P /Q /S /T] régi_név ... új_név\n\ REN [/E /N /P /Q /S /T] régi_név ... új_név\n\n\ /E Hibaüzenetek elrejtése.\n\ - /N Ne csináljon semmit .\n\ + /N Ne csináljon semmit.\n\ /P Minden állománynál rákérdez. (Még NEM mûködik!!)\n\ /Q Csendes mûködés.\n\ /S Almappákat is átnevez.\n\ @@ -479,7 +485,7 @@ will toggle stopwatch state\n\n" STRING_TYPE_HELP1, "Megjeleníti az állományok tartalmát.\n\n\ TYPE [meghajtó:][elérési_út]állománynév \n\ - /P Csak egy képernyõnyi tartalmat jelenít meg egyszerre.\n" + /P Csak egy képernyõnyi tartalmat jelenít meg egyszerre.\n" STRING_VERIFY_HELP1, "Ez a parancs még nem mûködik!!\n\ Lemezre írás utáni ellenõrzést állítja be.\n\n\ @@ -543,6 +549,7 @@ title new title\n" STRING_HELP1, "Támogatott parancsok megjelenítése\n\n\ + help parancs\n\ parancs /? Több (részletes) információ megtekintéséhez használd ezt.\n\n\ ? Minden támogatott parancs megjelenítése (részletek nélkül).\n\ ALIAS Megjeleníti, vagy megváltoztatja az aliasokat.\n\ diff --git a/base/shell/cmd/lang/id-ID.rc b/base/shell/cmd/lang/id-ID.rc index 1bdc3675528..7608db7f3ee 100644 --- a/base/shell/cmd/lang/id-ID.rc +++ b/base/shell/cmd/lang/id-ID.rc @@ -267,6 +267,15 @@ STRING_FREE_HELP1, "\nVolume di drive %s adalah %-11s\n\ STRING_FREE_HELP2, "Menampilkan informasi drive.\n\nFREE [drive: ...]\n" +STRING_GOTO_HELP1, "Mengarahkan CMD ke baris berlabel dalam naskah batch.\n\n\ +GOTO label\n\n\ + label Menetapkan string teks yang digunakan dalam naskah batch sebagai label.\n\n\ +Anda mengetik label pada sebuah baris, dimulai dengan titik dua." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Melakukan pemrosesan kondisional dalam program batch.\n\n\ IF [NOT] ERRORLEVEL nomor perintah\n\ IF [NOT] string1==string2 perintah\n\ @@ -282,11 +291,6 @@ string1==string2 Menetapkan kondisi benar jika string teks yang ditetapkan\n\ EXIST filename Menetapkan kondisi benar jika nama file ada.\n\ DEFINED variable Menetapkan kondisi benar jika variabel didefinisikan.\n" -STRING_GOTO_HELP1, "Mengarahkan CMD ke baris berlabel dalam naskah batch.\n\n\ -GOTO label\n\n\ - label Menetapkan string teks yang digunakan dalam naskah batch sebagai label.\n\n\ -Anda mengetik label pada sebuah baris, dimulai dengan titik dua." - STRING_LABEL_HELP1, "Menampilkan atau mengubah label drive.\n\nLABEL [drive:][label]\n" STRING_LABEL_HELP2, "Volume di drive %c: adalah %s\n" @@ -360,10 +364,12 @@ Prompt bisa dibuat dari karakter normal dan kode spesial berikut:\n\n\ $F ) (Tanda kurung Kanan)\n\ $G > (Tanda lebih-dari)\n\ $H Backspace (menghapus karakter sebelumnya)\n\ + $I Information line\n\ $L < (tanda kurang-dari)\n\ $N Drive saat ini\n\ $P Drive dan path saat ini\n\ $Q = (tanda sama dengan)\n\ + $S (space)\n\ $T Jam saat ini\n\ $V Nomor versi OS\n\ $_ Carriage return dan linefeed\n\ @@ -381,9 +387,9 @@ STRING_REM_HELP, "Memulai baris komentar dalam file batch.\n\nREM [Komentar]" STRING_RMDIR_HELP, "Menghapus direktori.\n\n\ RMDIR [drive:]path\nRD [drive:]path\n\ -/S Menghapus semua file dan folder di dalam target\n\ -/Q Tidak bertanya pada pengguna\n" -STRING_RMDIR_HELP2, "Direktori tidak kosong!\n" +/S Menghapus semua file dan folder di dalam target\n\ +/Q Tidak bertanya pada pengguna\n" +STRING_RMDIR_HELP2, "Direktori tidak kosong!\n" STRING_REN_HELP1, "Mengganti nama file/direktori.\n\n\ RENAME [/E /N /P /Q /S /T] nama_lama ... nama_baru\n\ @@ -495,7 +501,7 @@ jika tidak ada yang ON, OFF atau /S ditetapkan dalam perintah\n\ akan menghidupkan/mematikan keadaan stopwatch\n\n" STRING_TYPE_HELP1, "Menampilkan isi dari file teks.\n\nTYPE [drive:][path]filename \n\ - /P Menampilkan satu layar output sekali waktu.\n" + /P Menampilkan satu layar output sekali waktu.\n" STRING_VERIFY_HELP1, "Perintah ini hanya dummy!!\n\ Menyetel apakah memverifikasi bawa file anda ditulis dengan benar ke\n\ @@ -558,6 +564,7 @@ title judul baru\n" STRING_HELP1, "Daftar semua perintah yang tersedia (+ deskripsi)\n\n\ + help command\n\ command /? Untuk informasi lengkap pada perintah tertentu\n\n\ ? Daftar semua perintah yang tersedia tanpa deskripsi.\n\ ALIAS Menyetel, menghapus atau menampilkan alias.\n\ diff --git a/base/shell/cmd/lang/it-IT.rc b/base/shell/cmd/lang/it-IT.rc index fafbcbea229..5c2f36b5c4b 100644 --- a/base/shell/cmd/lang/it-IT.rc +++ b/base/shell/cmd/lang/it-IT.rc @@ -264,6 +264,16 @@ STRING_FREE_HELP1, "\nIl Volume del disco %s è %-11s\n\ STRING_FREE_HELP2, "Visualizza le informazioni sul disco.\n\nFREE [disco: ...]\n" +STRING_GOTO_HELP1, "Porta l'esecuzione di un batch alla linea con l'etichetta\n\ + indicata.\n\n\ +GOTO etichetta\n\n\ + etichetta Indica il testo utilizzato come etichetta in un batch.\n\n\ +Nel batch questa deve trovarsi da sola in una linea con davanti due punti :.\n" + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Esegue una elaborazione condizionale nei batch.\n\n\ IF [NOT] ERRORLEVEL numero comando\n\ IF [NOT] stringa1==stringa2 comando\n\ @@ -279,12 +289,6 @@ string1==string2 E' verificata se sono uguali le due stringhe\n\ EXIST nomefile E' verificata se il file esiste.\n\ DEFINED variabile E' verificata se la variabile è definita.\n" -STRING_GOTO_HELP1, "Porta l'esecuzione di un batch alla linea con l'etichetta\n\ - indicata.\n\n\ -GOTO etichetta\n\n\ - etichetta Indica il testo utilizzato come etichetta in un batch.\n\n\ -Nel batch questa deve trovarsi da sola in una linea con davanti due punti :.\n" - STRING_LABEL_HELP1, "Visualizza o modifica l'etichetta di un disco.\n\n\ LABEL [disco:][etichetta]\n" @@ -364,10 +368,12 @@ Può essere composto da un testo qualunque e dai seguenti codici speciali:\n\n\ $F ) (parentesi destra)\n\ $G > (simbolo di maggiore di)\n\ $H Backspace (cancella il carattere precedente)\n\ + $I Information line\n\ $L < (simbolo di minore di)\n\ $N Disco corrente\n\ $P Disco e percorso corrente\n\ $Q = (simbolo di uguale)\n\ + $S (space)\n\ $T Ora attuale\n\ $V Versione del sistema operativo\n\ $_ CR LF (a capo)\n\ @@ -386,9 +392,9 @@ REM [Commento]" STRING_RMDIR_HELP, "Cancella una cartella.\n\n\ RMDIR [disco:]percorso\nRD [disco:]percorso\n\ -/S cancella tutti i file e le cartelle indicate\n\ -/Q non chiede conferma\n" -STRING_RMDIR_HELP2, "La cartella non è vuota!\n" +/S cancella tutti i file e le cartelle indicate\n\ +/Q non chiede conferma\n" +STRING_RMDIR_HELP2, "La cartella non è vuota!\n" STRING_REN_HELP1, "Rinomina file/cartella or file/cartelle.\n\n\ RENAME [/E /N /P /Q /S /T] vecchio_nome ... nuovo_nome\n\ @@ -500,7 +506,7 @@ del cronometro da attivo a fermo o viceversa\n\n" STRING_TYPE_HELP1, "Visualizza il contenuto di un file di testo.\n\n\ TYPE [disco:][percorso]nomefile \n\ - /P Mostra una schermata alla volta.\n" + /P Mostra una schermata alla volta.\n" STRING_VERIFY_HELP1, "Questo comando non è implementato!!\n\ Attiva o disattiva la verifica automatica della scrittura dei file\n\ @@ -566,6 +572,7 @@ titolo il nuovo titolo\n" STRING_HELP1, "Elenco di tutti i comandi disponibili (+ descrizione)\n\n\ + help comando\n\ comando /? Per i dettagli su uno specifico comando\n\n\ ? Elenco di tutti i comandi disponibili.\n\ ALIAS Imposta, toglie o visualizza gli alias.\n\ diff --git a/base/shell/cmd/lang/ja-JP.rc b/base/shell/cmd/lang/ja-JP.rc index e4ad3487d7e..9c7ccc5d226 100644 --- a/base/shell/cmd/lang/ja-JP.rc +++ b/base/shell/cmd/lang/ja-JP.rc @@ -271,6 +271,16 @@ STRING_FREE_HELP1, "\nドライブ %c のボリューム ラベルは %-11s で STRING_FREE_HELP2, "ドライブに関する情報を表示します。\n\nFREE [ドライブ: ...]\n" +STRING_GOTO_HELP1, "バッチ プログラム内の、ラベルで指定されている行へ制御を移動します。\n\n\ +GOTO ラベル\n\n\ + ラベル バッチ プログラムでラベルとして使用するテキスト文字列を指定します。\n\n\ +ラベルの先頭には : (コロン) を指定し、ラベルだけを単独で 1 行に入力してくだ\n\ +さい。" + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "バッチ プログラム中で条件処理を実行します。\n\n\ IF [NOT] ERRORLEVEL 番号 コマンド\n\ IF [NOT] 文字列1==文字列2 コマンド\n\ @@ -288,12 +298,6 @@ EXIST ファイル名 指定したファイル名が存在するときに条件 DEFINED 変数 指定した変数が定義されているときに条件が真になるように\n\ 指定します。\n" -STRING_GOTO_HELP1, "バッチ プログラム内の、ラベルで指定されている行へ制御を移動します。\n\n\ -GOTO ラベル\n\n\ - ラベル バッチ プログラムでラベルとして使用するテキスト文字列を指定します。\n\n\ -ラベルの先頭には : (コロン) を指定し、ラベルだけを単独で 1 行に入力してくだ\n\ -さい。" - STRING_LABEL_HELP1, "ディスクのボリューム ラベルを表示または変更します。\n\nLABEL [ドライブ:][ラベル]\n" STRING_LABEL_HELP2, "ドライブ %c: のボリューム ラベルは %s です\n" @@ -369,10 +373,12 @@ PROMPT には通常の文字と次に示す特殊コードを使用できます: $F ) (右かっこ)\n\ $G > (不等号 (大なり))\n\ $H バックスペース (直前の文字を削除します)\n\ + $I Information line\n\ $L < (不等号 (小なり))\n\ $N 現在のドライブ\n\ $P 現在のドライブとパス\n\ $Q = (等号)\n\ + $S (space)\n\ $T 現在の時刻\n\ $V OS のバージョン番号\n\ $_ キャリッジ リターンとラインフィード\n\ @@ -392,7 +398,7 @@ STRING_RMDIR_HELP, "ディレクトリを削除します。\n\n\ RMDIR [ドライブ:]パス\nRD [ドライブ:]パス\n\ /S 指定されたディレクトリ内にあるファイルやフォルダもすべて削除します。\n\ /Q 確認のメッセージを表示しません。\n" -STRING_RMDIR_HELP2, "ディレクトリが空ではありません!\n" +STRING_RMDIR_HELP2, "ディレクトリが空ではありません!\n" STRING_REN_HELP1, "ファイルやディレクトリ (複数可) の名前を変更します。\n\n\ RENAME [/E /N /P /Q /S /T] 元のファイル名 ... 新ファイル名\n\ @@ -503,7 +509,7 @@ ON、OFF、/S のいずれも指定しなかった場合には、ストップウ 状態を切り替えます。\n\n" STRING_TYPE_HELP1, "テキスト ファイルまたはファイルの内容を表示します。\n\nTYPE [ドライブ:][パス]ファイル名 \n\ - /P 1 度に 1 画面ずつ表示します。\n" + /P 1 度に 1 画面ずつ表示します。\n" STRING_VERIFY_HELP1, "このコマンドはダミーです!!\n\ ファイルがディスクに正しく書き込まれたことを照合するかどうかを指示します。\n\n\ @@ -566,6 +572,7 @@ RESTORE ウィンドウを元のサイズに戻します。\n\ STRING_HELP1, "利用可能なすべてのコマンドの一覧と、その説明。\n\n\ + help コマンド\n\ コマンド /? 特定のコマンドに関する詳細情報\n\n\ ? 利用可能なすべてのコマンドの一覧 (説明なし)。\n\ ALIAS エイリアスの設定や解除をしたり、エイリアスを表示したりします。\n\ diff --git a/base/shell/cmd/lang/no-NO.rc b/base/shell/cmd/lang/no-NO.rc index 3777833726a..114351d700b 100644 --- a/base/shell/cmd/lang/no-NO.rc +++ b/base/shell/cmd/lang/no-NO.rc @@ -118,7 +118,7 @@ COPY [/V][/Y|/-Y][/A|/B] kilde [/A|/B]\n\ kilde Spesifiserer filen eller filer som kopieres.\n\ /A Indikerer en ASCII tekst fil.\n\ /B Indikerer en binær fil.\n\ - mål Spesifiserer mappen og/eller filnavn for den nye fil(ene).\n\ + mål Spesifiserer mappen og/eller filnavn for den nye fil(ene).\n\ /V Bekreftet at nye filer er skrevet korrekt.\n\ /Y Undertrykker spørsmål om å godkjenne hvorvidt du ønsker å overskrive en\n\ eksisterende destinasjonsfil.\n\ @@ -262,6 +262,15 @@ STRING_FREE_HELP1, "\nVolum i stasjon %s er %-11s\n\ STRING_FREE_HELP2, "Vis stasjonsinformasjon.\n\nFREE [stasjon: ...]\n" +STRING_GOTO_HELP1, "Leder CMD til en merket linje i et satsvis skript.\n\n\ +GOTO merke\n\n\ + merke angir en tekst streng brukt i en satsvis skript.\n\n\ +Et merke opprettes på egen linje ved å skrive kolon fulgt av navn på merke." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Utføre betinget behandling i satsvise programmer.\n\n\ IF [NOT] ERRORLEVEL nummer kommando\n\ IF [NOT] streng1==streng2 kommando\n\ @@ -277,11 +286,6 @@ EXIST filnavn Angir et oppfylt vilkår hvis spesifisert filnavn eksisterer.\ DEFINED variabel Angir et oppfylt vilkår hvis spesifisert variabel er\n\ definert.\n" -STRING_GOTO_HELP1, "Leder CMD til en merket linje i et satsvis skript.\n\n\ -GOTO merke\n\n\ - merke angir en tekst streng brukt i en satsvis skript.\n\n\ -Et merke opprettes på egen linje ved å skrive kolon fulgt av navn på merke." - STRING_LABEL_HELP1, "Viser eller endrer navn på stasjon.\n\nLABEL [stasjon:][merke]\n" STRING_LABEL_HELP2, "Volumet i stasjon %c: er %s\n" @@ -333,7 +337,7 @@ type knapp vises\n\ YESNO, YESNOCANCEL\n\ tittel tittel på meldingsboks\n\ melding tekst som vises i meldingsboks\n\n\n\ -ERRORLEVEL settes avhengig av hvilken knapp som trykkes:\n\n\ +ERRORLEVEL settes avhengig av hvilken knapp som trykkes:\n\n\ JA : 10 | NEI : 11\n\ OK : 10 | AVBRYT : 12\n" @@ -355,10 +359,12 @@ Ledeteksten kan bli satt sammen av normale tegn og følgende spesielle koder:\n\ $F ) (Høyreparentes)\n\ $G > (større-enn symbol)\n\ $H Tilbake (sletter forrige tegn)\n\ + $I Information line\n\ $L < (mindre-enn symbol)\n\ $N Gjeldende stasjon\n\ $P Gjeldende stasjon og mappe\n\ $Q = (likhetstegn)\n\ + $S (space)\n\ $T Gjeldende klokkeslett\n\ $V Versjonsnummer for ReactOS\n\ $_ Retur og linjeskift\n\ @@ -376,9 +382,9 @@ STRING_REM_HELP, "Start en kommentarlinje i en satsvis fil.\n\nREM [Kommentar]" STRING_RMDIR_HELP, "Flytter en mappe.\n\n\ RMDIR [stasjon:]mappe\nRD [stasjon:]mappe\n\ -/S Sletter alle filer og mapper innenfor målet\n\ -/Q Ikke spør før sletting.\n" -STRING_RMDIR_HELP2, "Mappen er ikke tom!\n" +/S Sletter alle filer og mapper innenfor målet\n\ +/Q Ikke spør før sletting.\n" +STRING_RMDIR_HELP2, "Mappen er ikke tom!\n" STRING_REN_HELP1, "Endre navn på fil/mappe eller filer/mapper.\n\n\ ENDRE NAVN [/E /N /P /Q /S /T] gammelt_navn ... nytt_navn\n\ @@ -489,7 +495,7 @@ hvis hverken ON, OFF eller /S er spesifisert\n\ vil status for stoppeklokken veksles.\n\n" STRING_TYPE_HELP1, "Vis innholdet av tekstfiler.\n\nSkriv [stasjon:][mappe]filnavn \n\ - /P Vis en full skjerm om gangen.\n" + /P Vis en full skjerm om gangen.\n" STRING_VERIFY_HELP1, "Denne kommandoen er bare en etterlikning!!\n\ Angir om det skal bekreftes at dine filer er skrevet korrekt til disk \n\n\ @@ -553,6 +559,7 @@ tittel ny tittel\n" STRING_HELP1, "Liste av alle tilgjengelige kommandoer (+ beskrivelse)\n\n\ +help kommando\n\ kommando /? For mer informasjon om en bestemt kommando\n\n\ ? Lister alle tilgjengelige kommando uten beskrivelse).\n\ ALIAS Sett, fjern eller vis alias.\n\ diff --git a/base/shell/cmd/lang/pl-PL.rc b/base/shell/cmd/lang/pl-PL.rc index 686e0be74ae..b30e04052c6 100644 --- a/base/shell/cmd/lang/pl-PL.rc +++ b/base/shell/cmd/lang/pl-PL.rc @@ -270,6 +270,15 @@ STRING_FREE_HELP1, "\nWolumin w napędzie %s ma etykietę: %-11s\n\ STRING_FREE_HELP2, "Wyświetla informacje o wolnym miejscu w napędzie.\n\nFREE [napęd: ...]\n" +STRING_GOTO_HELP1, "Przekierowuje CMD do oznaczonej linii w programie wsadowym.\n\n\ +GOTO etykieta\n\n\ + etykieta Ciąg znaków, użyty w programie wsadowym do oznaczenia linii.\n\n\ +Możesz oznaczyć linie dowolną etykietą, zaczynając od dwukropka." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Wykonuje przetwarzanie warunkowe w programach wsadowych.\n\n\ IF [NOT] ERRORLEVEL numer komenda\n\ IF [NOT] ciąg_znaków1==ciąg_znaków2 komenda\n\ @@ -284,11 +293,6 @@ ciąg1==ciąg2 Zwraca PRAWDA, gdy oba ciągi znaków są identyczne\n\ EXIST plik Zwraca PRAWDA, jeśli podany plik istnieje.\n\ DEFINED zmienna Zwraca PRAWDA, jeśli podana zmienna została zdefiniowana\n" -STRING_GOTO_HELP1, "Przekierowuje CMD do oznaczonej linii w programie wsadowym.\n\n\ -GOTO etykieta\n\n\ - etykieta Ciąg znaków, użyty w programie wsadowym do oznaczenia linii.\n\n\ -Możesz oznaczyć linie dowolną etykietą, zaczynając od dwukropka." - STRING_LABEL_HELP1, "Wyświetla lub zmienia etykietę napędu.\n\nLABEL [napęd:][etykieta]\n" STRING_LABEL_HELP2, "Wolumin w napędzie %c: ma etykietę: %s\n" @@ -362,10 +366,12 @@ Znak zachęty może składać się z normalnych znaków, a także poniższych sy $F ) (prawy nawias)\n\ $G > (znak większości)\n\ $H (usuwa ostatni znak)\n\ + $I Information line\n\ $L < (znak mniejszości)\n\ $N Bieżący napęd\n\ $P Bieżący napęd i ścieżka\n\ $Q = (znak równości)\n\ + $S (space)\n\ $T Bieżący czas\n\ $V Wersja systemu\n\ $_ Znak CR/LF\n\ @@ -383,9 +389,9 @@ STRING_REM_HELP, "Definiuje linię komentarza w pliku wsadowym.\n\nREM [komentar STRING_RMDIR_HELP, "Usuwa katalog.\n\n\ RMDIR [napęd:]ścieżka\nRD [napęd:]ścieżka\n\ -/S Kasuje także wszystkie pliki i podkatalogi w danym katalogu\n\ -/Q Nie wyświetla prośby o potwierdzenie\n" -STRING_RMDIR_HELP2, "Katalog nie jest pusty!\n" +/S Kasuje także wszystkie pliki i podkatalogi w danym katalogu\n\ +/Q Nie wyświetla prośby o potwierdzenie\n" +STRING_RMDIR_HELP2, "Katalog nie jest pusty!\n" STRING_REN_HELP1, "Zmienia nazwę pliku/katalogu (także wielu).\n\n\ RENAME [/E /N /P /Q /S /T] stara_nazwa ... nowa_nazwa\n\ @@ -496,7 +502,7 @@ jeśli nie podano w składni parametrów: ON, OFF or /S, \n\ komenda zmieni obecny stan stopera\n\n" STRING_TYPE_HELP1, "Wyświetla zawartość plików tekstowych.\n\nTYPE [napęd:][ścieżka]nazwa_pliku \n\ - /P Pauzuje po każdym pełnym ekranie.\n" + /P Pauzuje po każdym pełnym ekranie.\n" STRING_VERIFY_HELP1, "Ta komenda jest tylko na podpuchę\ Odpowiada za to, czy po zapisaniu plików ma nastąpić sprawdzenie\n\ @@ -560,6 +566,7 @@ title nowy tytuł okna\n" STRING_HELP1, "Lista wszystkich dostępnych komend (+opisy)\n\n\ + help komenda\n\ komenda /? Wyświetla dokładny opis danej komendy\n\n\ ? Lista wszystkich dostępnych komend (bez opisów).\n\ ALIAS Ustawia, pokazuje lub usuwa aliasy.\n\ diff --git a/base/shell/cmd/lang/ro-RO.rc b/base/shell/cmd/lang/ro-RO.rc index 629bd780ff0..441038152c3 100644 --- a/base/shell/cmd/lang/ro-RO.rc +++ b/base/shell/cmd/lang/ro-RO.rc @@ -294,6 +294,16 @@ Numărul de serie este %s\n\ STRING_FREE_HELP2, "Afișează informația unei unități (de stocare).\n\nFREE [unitate: ...]\n" +STRING_GOTO_HELP1, "Execută un salt către o linie etichetată în interiorul unui fișier de comenzi.\n\n\ +GOTO etichetă\n\n\ + etichetă Specifică un șir text utilizat ca etichetă în\n\ + fișierele de comenzi.\n\n\ +O etichetă se va defini pe un rând întreg, începând cu două puncte (:)\n" + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Realizează execuția condiționată a comenzilor într-un fișier de comenzi.\n\n\ IF [NOT] ERRORLEVEL număr comandă\n\ IF [NOT] șir1==șir2 comandă\n\ @@ -313,12 +323,6 @@ STRING_IF_HELP1, "Realizează execuția condiționată a comenzilor într-un fi DEFINED variablă Determină o condiție satisfăcută dacă «variabilă»\n\ a fost anterior definită.\n" -STRING_GOTO_HELP1, "Execută un salt către o linie etichetată în interiorul unui fișier de comenzi.\n\n\ -GOTO etichetă\n\n\ - etichetă Specifică un șir text utilizat ca etichetă în\n\ - fișierele de comenzi.\n\n\ -O etichetă se va defini pe un rând întreg, începând cu două puncte (:)\n" - STRING_LABEL_HELP1, "Afișează sau modifică eticheta unei unități (de stocare).\n\nLABEL [unitate:][etichetă]\n" STRING_LABEL_HELP2, "Volumul unității %c: este etichetat ca %s\n" @@ -397,10 +401,12 @@ PROMPT [text]\n\n\ $F ) (paranteză dreapta)\n\ $G > (semnul mai mare decât)\n\ $H Backspace (ștergerea caracterului precedent)\n\ + $I Information line\n\ $L < (semnul mai mic decât)\n\ $N Unitatea de stocare curentă\n\ $P Unitatea de stocare și calea curentă\n\ $Q = (semnul egal)\n\ + $S (space)\n\ $T Ora curentă\n\ $V Numărul versiunii SO\n\ $_ Sfârșit de linie și rând nou\n\ @@ -420,7 +426,7 @@ STRING_RMDIR_HELP, "Șterge un director.\n\n\ RMDIR [unitate:]cale\nRD [unitate:]cale\n\ /S Șterge toate fișierele și directoarele țintă.\n\ /Q Omite cererile de confirmare.\n" -STRING_RMDIR_HELP2, "Directorul nu este gol!\n" +STRING_RMDIR_HELP2, "Directorul nu este gol!\n" STRING_REN_HELP1, "Redenumește un fișier/director sau fișiere/directoare.\n\n\ RENAME [/E /N /P /Q /S /T] nume_vechi ... nume_nou\n\ @@ -594,6 +600,7 @@ titlu Noul titlu.\n" STRING_HELP1, "Enumeră toate comenzile disponibile (+ descriere)\n\n\ + help comandă\n\ comandă /? Pentru mai multe informații referitoare la o anume comandă.\n\n\ ? Enumeră toate comenzile disponibile (fără descriere).\n\ ALIAS Instituie, destituie sau afișează alias.\n\ diff --git a/base/shell/cmd/lang/ru-RU.rc b/base/shell/cmd/lang/ru-RU.rc index 9af2ac35276..811e85d8517 100644 --- a/base/shell/cmd/lang/ru-RU.rc +++ b/base/shell/cmd/lang/ru-RU.rc @@ -267,6 +267,15 @@ STRING_FREE_HELP1, "\nТом диска %s: %-11s\n\ STRING_FREE_HELP2, "Выводит информацию о томе.\n\nFREE [drive: ...]\n" +STRING_GOTO_HELP1, "Передача управления содержащей метку строке пакетного файла.\n\n\ +GOTO метка\n\n\ + label Строка пакетного файла, оформленная как метка.\n\n\ +Метка должна находиться в отдельной строке и начинаться с двоеточия." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Оператор условного выполнения команд в пакетном файле.\n\n\ IF [NOT] ERRORLEVEL число команда\n\ IF [NOT] строка1==строка2 команда\n\ @@ -287,11 +296,6 @@ DEFINED переменная Это условие является истин служащее для указания команды, которая должна\n\ выполняться в том случае, если условие ложно.\n" -STRING_GOTO_HELP1, "Передача управления содержащей метку строке пакетного файла.\n\n\ -GOTO метка\n\n\ - label Строка пакетного файла, оформленная как метка.\n\n\ -Метка должна находиться в отдельной строке и начинаться с двоеточия." - STRING_LABEL_HELP1, "Создание, изменение и удаление меток тома.\n\nLABEL [диск:][метка]\n" STRING_LABEL_HELP2, "Том в устройстве %c имеет метку %s\n" @@ -365,10 +369,12 @@ PROMPT [текст]\n\n\ $F ) (правая круглая скобка)\n\ $G > (знак ""больше"")\n\ $H BACKSPACE (удаление предыдущего символа)\n\ + $I Information line\n\ $L < (знак ""меньше"")\n\ $N Текущий диск\n\ $P Текущие диск и каталог\n\ $Q = (знак равенства)\n\ + $S (space)\n\ $T Текущее время\n\ $V Номер версии операционной системы\n\ $_ Перевод строки\n\ @@ -386,9 +392,9 @@ STRING_REM_HELP, "Помещение комментариев в пакетны STRING_RMDIR_HELP, "Удаление каталога.\n\n\ RMDIR [диск:]путь\nRD [диск:]путь\n\ -/S Удаление дерева каталогов\n\ -/Q Отключение запроса подтверждения\n" -STRING_RMDIR_HELP2, "Каталог пуст!\n" +/S Удаление дерева каталогов\n\ +/Q Отключение запроса подтверждения\n" +STRING_RMDIR_HELP2, "Каталог пуст!\n" STRING_REN_HELP1, "Переименование одного или нескольких файлов или каталогов.\n\n\ RENAME [/E /N /P /Q /S /T] старое_имя ... новое_имя\n\ @@ -500,7 +506,7 @@ TIMER [ON|OFF] [/S] [/n] [/Fn]\n\n\ переключает состояние секундомера\n\n" STRING_TYPE_HELP1, "Вывод содержимого одного или нескольких текстовых файлов.\n\nTYPE [диск:][путь]имя файла \n\ - /P Поэкранный вывод.\n" + /P Поэкранный вывод.\n" STRING_VERIFY_HELP1, "This command is just a dummy!!\n\ Включение или отключение режима проверки правильности записи файлов a\n\ @@ -565,6 +571,7 @@ RESTORE восстанавливает окно\n\ STRING_HELP1, "Список всех доступных команд с коротким описанием\n\n\ + help команда\n\ команда /? Выводит подробную информацию о команде\n\n\ ? Список всех доступных команд без описания.\n\ ALIAS Вывод, установка или удаление псевдонимов.\n\ diff --git a/base/shell/cmd/lang/sk-SK.rc b/base/shell/cmd/lang/sk-SK.rc index 83fb1f85b59..0917bb195ff 100644 --- a/base/shell/cmd/lang/sk-SK.rc +++ b/base/shell/cmd/lang/sk-SK.rc @@ -270,6 +270,15 @@ STRING_FREE_HELP1, "\nVolume in drive %s is %-11s\n\ STRING_FREE_HELP2, "Displays drive information.\n\nFREE [drive: ...]\n" +STRING_GOTO_HELP1, "Directs CMD to a labeled line in a batch script.\n\n\ +GOTO label\n\n\ + label Specifies a text string used in a batch script as a label.\n\n\ +You type a label on a line by itself, beginning with a colon." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Performs conditional processing in batch programs.\n\n\ IF [NOT] ERRORLEVEL number command\n\ IF [NOT] string1==string2 command\n\ @@ -286,11 +295,6 @@ EXIST filename Specifies a true condition if the specified filename exists.\n DEFINED variable Specifies a true condition if the specified variable is\n\ defined.\n" -STRING_GOTO_HELP1, "Directs CMD to a labeled line in a batch script.\n\n\ -GOTO label\n\n\ - label Specifies a text string used in a batch script as a label.\n\n\ -You type a label on a line by itself, beginning with a colon." - STRING_LABEL_HELP1, "Displays or changes drive label.\n\nLABEL [drive:][label]\n" STRING_LABEL_HELP2, "Volume in drive %c: is %s\n" @@ -364,10 +368,12 @@ Prompt can be made up of normal characters and the following special codes:\n\n\ $F ) (Pravá okrúhla zátvorka)\n\ $G > (greater-than sign)\n\ $H Backspace (erases previous character)\n\ + $I Information line\n\ $L < (less-than sign)\n\ $N Current drive\n\ $P Current drive and path\n\ $Q = (equal sign)\n\ + $S (space)\n\ $T Aktuálny čas\n\ $V Číslo verzie OS\n\ $_ Carriage return and linefeed\n\ @@ -385,9 +391,9 @@ STRING_REM_HELP, "Starts a comment line in a batch file.\n\nREM [Comment]" STRING_RMDIR_HELP, "Removes a directory.\n\n\ RMDIR [drive:]path\nRD [drive:]path\n\ -/S Deletes all files and folders within target\n\ -/Q Doesnt prompt for user\n" -STRING_RMDIR_HELP2, "Directory is not empty!\n" +/S Deletes all files and folders within target\n\ +/Q Doesn't prompt for user\n" +STRING_RMDIR_HELP2, "Directory is not empty!\n" STRING_REN_HELP1, "Renames a file/directory or files/directories.\n\n\ RENAME [/E /N /P /Q /S /T] old_name ... new_name\n\ @@ -498,7 +504,7 @@ if none of ON, OFF or /S is specified the command\n\ will toggle stopwatch state\n\n" STRING_TYPE_HELP1, "Displays the contents of text files.\n\nTYPE [drive:][path]filename \n\ - /P Shows one screen of output at a time.\n" + /P Shows one screen of output at a time.\n" STRING_VERIFY_HELP1, "This command is just a dummy!!\n\ Sets whether to verify that your files are written correctly to a\n\ @@ -563,6 +569,7 @@ title new title\n" STRING_HELP1, "Zoznam všetkých dostupných príkazov (+ popis)\n\n\ + help príkaz\n\ príkaz /? Pre viac informácií o konkrétnom príkaze\n\n\ ? Zoznam všetkých dostupných príkazov (bez popisu).\n\ ALIAS Sets, removes or shows aliases.\n\ diff --git a/base/shell/cmd/lang/sv-SE.rc b/base/shell/cmd/lang/sv-SE.rc index 5ca41019278..440b3dd1e60 100644 --- a/base/shell/cmd/lang/sv-SE.rc +++ b/base/shell/cmd/lang/sv-SE.rc @@ -26,8 +26,8 @@ Skriv ATTRIB utan parametrar för att visa attributten för alla filer.\n" STRING_ALIAS_HELP, "Sätter, tar bort eller visar alias.\n\n\ ALIAS [alias=[Kommando]]\n\n\ - alias Namn på ett alias.\n\ - Kommando Text som skall erstättas av ett alias.\n\n\ + alias Namn på ett alias.\n\ + Kommando Text som skall erstättas av ett alias.\n\n\ för att lista alla alias:\n\ ALIAS\n\n\ För att sätta ett nytt eller ändra ett befintligt alias:\n\ @@ -118,7 +118,7 @@ COPY [/V][/Y|/-Y][/A|/B] källa [/A|/B]\n\ källa Anger filen eller filerna som kopieras.\n\ /A Anger att filen är en ASCII-textfil.\n\ /B Anger att filen är en binär-fil.\n\ - mål Anger mappen och/eller filnamn för den nya filen/filerna.\n\ + mål Anger mappen och/eller filnamn för den nya filen/filerna.\n\ /V Kontrollera att nya filer är korrekt skrivna.\n\ /Y Undertrycker frågor om att godkänna om du önskar att skriva över\n\ befintlig destinationsfil.\n\ @@ -262,6 +262,15 @@ STRING_FREE_HELP1, "\nVolum i enhet %s är %-11s\n\ STRING_FREE_HELP2, "Visa enhetsinformation.\n\nFREE [enhet: ...]\n" +STRING_GOTO_HELP1, "Dirigerar CMD till en namngiven etikett i ett batchprogram.\n\n\ +GOTO etikett\n\n\ + etikett Anger en text sträng använt i ett batchprogram.\n\n\ +En etikett skapas på en egen rad genom att skriva kolon följt av namn på etiketten." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Utför villkorsstyrd bearbetning i batchprogram.\n\n\ IF [NOT] ERRORLEVEL nummer kommando\n\ IF [NOT] sträng1==sträng2 kommando\n\ @@ -277,11 +286,6 @@ EXIST filnamn Anger ett uppfyllt villkor om angivet filnamn existerar.\n\ DEFINED variabel Anger ett uppfyllt villkor om angiven variabel är\n\ definerad.\n" -STRING_GOTO_HELP1, "Dirigerar CMD till en namngiven etikett i ett batchprogram.\n\n\ -GOTO etikett\n\n\ - etikett Anger en text sträng använt i ett batchprogram.\n\n\ -En etikett skapas på en egen rad genom att skriva kolon följt av namn på etiketten." - STRING_LABEL_HELP1, "Skapar, tar bort eller ändrar etikett på enhet.\n\nLABEL [enhet:][etikett]\n" STRING_LABEL_HELP2, "Volymen i enhet %c: är %s\n" @@ -333,9 +337,9 @@ type knapp vises\n\ YESNO, YESNOCANCEL\n\ tittel tittel på meldingsboks\n\ melding text som vises i meldingsboks\n\n\n\ -ERRORLEVEL settes avhengig av hvilken knapp som trykkes:\n\n\ -JA : 10 | NEI : 11\n\ -OK : 10 | AVBRYT : 12\n" +ERRORLEVEL settes avhengig av hvilken knapp som trykkes:\n\n\ +JA : 10 | NEI : 11\n\ +OK : 10 | AVBRYT : 12\n" STRING_PATH_HELP1, "Viser eller setter en søkesti for kjørbare filer.\n\n\ PATH [[enhet:]mapp[;...]]\nPATH ;\n\n\ @@ -355,10 +359,12 @@ Ledeteksten kan bli satt sammen av normale tegn och følgende spesielle koder:\n $F ) (Høyreparentes)\n\ $G > (større-enn symbol)\n\ $H Tilbake (sletter forrige tegn)\n\ + $I Information line\n\ $L < (mindre-enn symbol)\n\ $N aktuell enhet\n\ $P aktuell enhet och mapp\n\ $Q = (likhetstegn)\n\ + $S (space)\n\ $T aktuell klokkeslett\n\ $V Versjonsnummer for ReactOS\n\ $_ Retur och linjeskift\n\ @@ -376,9 +382,9 @@ STRING_REM_HELP, "Start en kommentarlinje i en satsvis fil.\n\nREM [Kommentar]" STRING_RMDIR_HELP, "Flytter en mapp.\n\n\ RMDIR [enhet:]mapp\nRD [enhet:]mapp\n\ -/S Sletter alle filer och mappar innenfor målet\n\ -/Q Inte spør før sletting.\n" -STRING_RMDIR_HELP2, "mappn är inte tom!\n" +/S Sletter alle filer och mappar innenfor målet\n\ +/Q Inte spør før sletting.\n" +STRING_RMDIR_HELP2, "mappn är inte tom!\n" STRING_REN_HELP1, "Ändra namn på fil/mapp eller filer/mappar.\n\n\ ENDRE NAVN [/E /N /P /Q /S /T] gammelt_namn ... nytt_namn\n\ @@ -489,7 +495,7 @@ hvis hverken ON, OFF eller /S är spesifisert\n\ vil status for stoppeklokken veksles.\n\n" STRING_TYPE_HELP1, "Vis innholdet av tekstfiler.\n\nSkriv [enhet:][mapp]filnamn \n\ - /P Vis en full skjerm om gangen.\n" + /P Vis en full skjerm om gangen.\n" STRING_VERIFY_HELP1, "Denne kommandoen är bare en etterlikning!!\n\ Anger om det skal bekreftes at dine filer är skrevet korrekt til disk \n\n\ @@ -553,6 +559,7 @@ tittel ny tittel\n" STRING_HELP1, "Liste av alle tilgjengelige kommandoer (+ beskrivelse)\n\n\ +help kommando\n\ kommando /? For mer informasjon om en bestemt kommando\n\n\ ? Lister alle tilgjengelige kommando uten beskrivelse).\n\ ALIAS Sett, fjern eller vis alias.\n\ diff --git a/base/shell/cmd/lang/uk-UA.rc b/base/shell/cmd/lang/uk-UA.rc index 9f80c74d12b..251f52f83a9 100644 --- a/base/shell/cmd/lang/uk-UA.rc +++ b/base/shell/cmd/lang/uk-UA.rc @@ -273,6 +273,15 @@ STRING_FREE_HELP1, "\nТом диску %s : %-11s\n\ STRING_FREE_HELP2, "Виводить iнформацiю про том.\n\nFREE [drive: ...]\n" +STRING_GOTO_HELP1, "Передача управління рядку пакетного файлу, що мiстить мiтку.\n\n\ +GOTO мiтка\n\n\ + label рядок пакетного файлу, визначений як мiтка.\n\n\ +Мітка повинна знаходитися в окремому рядку i починатися з двокрапки." + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "Оператор умовного виконання команд у пакетному файлi.\n\n\ IF [NOT] ERRORLEVEL число команда\n\ IF [NOT] рядок1==рядок2 команда\n\ @@ -289,11 +298,6 @@ EXIST iм'я_файлу Умова є iстинною, якщо файл з в DEFINED змiнна Ця умова є iстинною, якщо вказана змiнна\n\ задана.\n" -STRING_GOTO_HELP1, "Передача управління рядку пакетного файлу, що мiстить мiтку.\n\n\ -GOTO мiтка\n\n\ - label рядок пакетного файлу, визначений як мiтка.\n\n\ -Мітка повинна знаходитися в окремому рядку i починатися з двокрапки." - STRING_LABEL_HELP1, "Вiдображення або змiна мiтки тому.\n\nLABEL [диск:][мiтка]\n" STRING_LABEL_HELP2, "Том в пристрої %c: має мiтку %s\n" @@ -367,10 +371,12 @@ PROMPT [текст]\n\n\ $F ) (Права кругла дужка)\n\ $G > (знак більше)\n\ $H Backspace (видалення попередьного символу)\n\ + $I Information line\n\ $L < (знак меньше)\n\ $N Поточний диск\n\ $P Поточний диск та каталог\n\ $Q = (знак рiвностi)\n\ + $S (space)\n\ $T Поточний час\n\ $V Номер версiї операцiйної системи\n\ $_ Повернення каретки та переведення рядка\n\ @@ -388,9 +394,9 @@ STRING_REM_HELP, "Стартує рядок коментаря впакетно STRING_RMDIR_HELP, "Видалення каталогу.\n\n\ RMDIR [диск:]шлях\nRD [диск:]шлях\n\ -/S Видалення всього дерева всерединi цiлi\n\ -/Q Вимкнення запиту пiдтвердження\n" -STRING_RMDIR_HELP2, "Каталог не порожнiй!\n" +/S Видалення всього дерева всерединi цiлi\n\ +/Q Вимкнення запиту пiдтвердження\n" +STRING_RMDIR_HELP2, "Каталог не порожнiй!\n" STRING_REN_HELP1, "Перейменування одного чи кiлькох файлiв/каталогiв.\n\n\ RENAME [/E /N /P /Q /S /T] старе_iм'я ... нове_iм'я\n\ @@ -500,7 +506,7 @@ TIMER [ON|OFF] [/S] [/n] [/Fn]\n\n\ стан секундомiра\n\n" STRING_TYPE_HELP1, "Виведення вмiсту текстових файлiв.\n\nTYPE [диск:][шлях]iм'я_файлу \n\ - /P Поекранний вивiд.\n" + /P Поекранний вивiд.\n" STRING_VERIFY_HELP1, "This command is just a dummy!!\n\ Ввiмкнення чи вимкнення перевiрки правильностi запису файлiв\n\ @@ -565,6 +571,7 @@ title новий заголовок\n" STRING_HELP1, "Список всiх доступних команд (+ опис)\n\n\ + help команда\n\ команда /? Для докладної iнформацiї про конкретну команду\n\n\ ? Список всiх доступних команд без опису.\n\ ALIAS Встановлення, видалення або показ псевдонiмiв.\n\ @@ -663,8 +670,8 @@ STRING_FREE_ERROR2, "не вiдмiчено" STRING_GOTO_ERROR1, "Не визначена мiтка для GOTO" STRING_GOTO_ERROR2, "Мiтка '%s' не знайдена\n" -STRING_MD_ERROR, "Пiдкаталог чи файл вже iснує.\n" -STRING_MD_ERROR2, "Шлях до нового каталогу не iснує.\n" +STRING_MD_ERROR, "Пiдкаталог чи файл вже iснує.\n" +STRING_MD_ERROR2, "Шлях до нового каталогу не iснує.\n" STRING_MOVE_ERROR1, "[OK]\n" STRING_MOVE_ERROR2, "[Помилка]\n" diff --git a/base/shell/cmd/lang/zh-CN.rc b/base/shell/cmd/lang/zh-CN.rc index 195529e5176..5cf55cef849 100644 --- a/base/shell/cmd/lang/zh-CN.rc +++ b/base/shell/cmd/lang/zh-CN.rc @@ -254,6 +254,15 @@ STRING_FREE_HELP1, "\n驱动器 %s 中的卷是 %-11s\n\ STRING_FREE_HELP2, "显示驱动器信息。\n\nFREE [驱动器: ...]\n" +STRING_GOTO_HELP1, "在批处理脚本中将 CMD 定向到被标记的行执行。\n\n\ +GOTO 标签\n\n\ + 标签 在批处理脚本中被用作标签的文本字符串。\n\n\ +使用冒号开头的一行就作为一个标签。" + +STRING_HELP_HELP1, "Provides Help information for ReactOS commands.\n\n\ +HELP [command]\n\n\ + command - Display help information for this command.\n" + STRING_IF_HELP1, "在批处理文件中执行条件控制处理。\n\n\ IF [NOT] ERRORLEVEL 数字 命令\n\ IF [NOT] 字符串1==字符串2 命令\n\ @@ -266,11 +275,6 @@ ERRORLEVEL 数字 当上一个程序返回一个大于或等于指定数字 EXIST 文件名 当指定的文件名存在时为真。\n\ DEFINED 变量 当指定的变量已被定义时为真。\n" -STRING_GOTO_HELP1, "在批处理脚本中将 CMD 定向到被标记的行执行。\n\n\ -GOTO 标签\n\n\ - 标签 在批处理脚本中被用作标签的文本字符串。\n\n\ -使用冒号开头的一行就作为一个标签。" - STRING_LABEL_HELP1, "显示或改变驱动器卷标。\n\nLABEL [驱动器:][卷标]\n" STRING_LABEL_HELP2, "驱动器 %c 中的卷是 %s\n" @@ -342,10 +346,12 @@ PROMPT [文本]\n\n\ $F ) (右括号)\n\ $G > (大于号)\n\ $H 退格 (擦除前一个字符)\n\ + $I Information line\n\ $L < (小于号)\n\ $N 当前驱动器\n\ $P 当前驱动器和路径\n\ $Q = (等于号)\n\ + $S (space)\n\ $T 当前时间\n\ $V 操作系统版本号\n\ $_ 回车和换行符\n\ @@ -363,9 +369,9 @@ STRING_REM_HELP, "在批处理文件中开始一行注释。\n\nREM [注释]" STRING_RMDIR_HELP, "删除一个目录。\n\n\ RMDIR [驱动器:]路径\nRD [驱动器:]路径\n\ -/S 删除目标中的所有文件和文件夹。\n\ -/Q 删除时不要提示。\n" -STRING_RMDIR_HELP2, "目录非空!\n" +/S 删除目标中的所有文件和文件夹。\n\ +/Q 删除时不要提示。\n" +STRING_RMDIR_HELP2, "目录非空!\n" STRING_REN_HELP1, "重命名一个或者多个文件或文件夹。\n\n\ RENAME [/E /N /P /Q /S /T] 旧名称 ... 新名称\n\ @@ -463,7 +469,7 @@ TIMER [ON|OFF] [/S] [/n] [/Fn]\n\n\ 如果没有 ON,OFF 或者 /S 在调用该命令时被指定,将会切换停表状态。\n\n" STRING_TYPE_HELP1, "显示文本文件的内容。\n\nTYPE [驱动器:][路径]文件名 \n\ - /P 每次只显示一屏内容。\n" + /P 每次只显示一屏内容。\n" STRING_VERIFY_HELP1, "这条命令只是个摆设!!\n\ 设置是否检查您的文件已被正确地写入磁盘。\n\n\ @@ -527,6 +533,7 @@ RESTORE 恢复窗口\n\ STRING_HELP1, "列出所有可用命令 (+ 它们的描述)\n\n\ + help 命令\n\ 命令 /? 得到特定命令的更多信息\n\n\ ? 列出所有可用命令 (没有描述)。\n\ ALIAS 设置、删除或显示别名。\n\ diff --git a/base/shell/cmd/locale.c b/base/shell/cmd/locale.c index d67a381501b..80e72bc01a4 100644 --- a/base/shell/cmd/locale.c +++ b/base/shell/cmd/locale.c @@ -24,32 +24,32 @@ INT nNumberGroups; VOID InitLocale (VOID) { - TCHAR szBuffer[256]; + TCHAR szBuffer[256]; - /* date settings */ - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDATE, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); - cDateSeparator = szBuffer[0]; - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IDATE | LOCALE_RETURN_NUMBER, (LPTSTR)&nDateFormat, sizeof(nDateFormat) / sizeof(TCHAR)); + /* date settings */ + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDATE, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); + cDateSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IDATE | LOCALE_RETURN_NUMBER, (LPTSTR)&nDateFormat, sizeof(nDateFormat) / sizeof(TCHAR)); - /* time settings */ - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STIME, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); - cTimeSeparator = szBuffer[0]; - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME | LOCALE_RETURN_NUMBER, (LPTSTR)&nTimeFormat, sizeof(nTimeFormat) / sizeof(TCHAR)); + /* time settings */ + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STIME, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); + cTimeSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME | LOCALE_RETURN_NUMBER, (LPTSTR)&nTimeFormat, sizeof(nTimeFormat) / sizeof(TCHAR)); - /* number settings */ - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); - cThousandSeparator = szBuffer[0]; - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); - cDecimalSeparator = szBuffer[0]; + /* number settings */ + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); + cThousandSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); + cDecimalSeparator = szBuffer[0]; GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); nNumberGroups = _ttoi(szBuffer); #if 0 - /* days of week */ - for (i = 0; i < 7; i++) - { - GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1 + i, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); - _tcscpy (aszDayNames[(i+1)%7], szBuffer); /* little hack */ - } + /* days of week */ + for (i = 0; i < 7; i++) + { + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1 + i, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])); + _tcscpy (aszDayNames[(i+1)%7], szBuffer); /* little hack */ + } #endif } @@ -57,26 +57,26 @@ VOID InitLocale (VOID) LPTSTR GetDateString(VOID) { - static TCHAR szDate[32]; - SYSTEMTIME t; - INT len; - GetLocalTime(&t); + static TCHAR szDate[32]; + SYSTEMTIME t; + INT len; + GetLocalTime(&t); - len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &t, _T("ddd"), szDate, sizeof szDate); - szDate[len - 1] = _T(' '); - FormatDate(&szDate[len], &t, TRUE); - return szDate; + len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &t, _T("ddd"), szDate, sizeof szDate); + szDate[len - 1] = _T(' '); + FormatDate(&szDate[len], &t, TRUE); + return szDate; } /* Return time in hh:mm:ss.xx format. Used for $T in prompt and %TIME% */ LPTSTR GetTimeString(VOID) { - static TCHAR szTime[12]; - SYSTEMTIME t; - GetLocalTime(&t); - _stprintf(szTime, _T("%2d%c%02d%c%02d%c%02d"), - t.wHour, cTimeSeparator, t.wMinute, cTimeSeparator, - t.wSecond, cDecimalSeparator, t.wMilliseconds / 10); - return szTime; + static TCHAR szTime[12]; + SYSTEMTIME t; + GetLocalTime(&t); + _stprintf(szTime, _T("%2d%c%02d%c%02d%c%02d"), + t.wHour, cTimeSeparator, t.wMinute, cTimeSeparator, + t.wSecond, cDecimalSeparator, t.wMilliseconds / 10); + return szTime; } diff --git a/base/shell/cmd/memory.c b/base/shell/cmd/memory.c index cf3bc73f48e..fc1b7a3921a 100644 --- a/base/shell/cmd/memory.c +++ b/base/shell/cmd/memory.c @@ -7,8 +7,8 @@ * 01-Sep-1999 (Eric Kohl) * Started. * - * 28-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 28-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -17,56 +17,56 @@ INT CommandMemory (LPTSTR param) { - MEMORYSTATUSEX msex; - TCHAR szMemoryLoad[20]; - TCHAR szTotalPhys[40]; - TCHAR szAvailPhys[40]; - TCHAR szTotalPageFile[40]; - TCHAR szAvailPageFile[40]; - TCHAR szTotalVirtual[40]; - TCHAR szAvailVirtual[40]; - BOOL (WINAPI *GlobalMemoryStatusEx)(LPMEMORYSTATUSEX); + MEMORYSTATUSEX msex; + TCHAR szMemoryLoad[20]; + TCHAR szTotalPhys[40]; + TCHAR szAvailPhys[40]; + TCHAR szTotalPageFile[40]; + TCHAR szAvailPageFile[40]; + TCHAR szTotalVirtual[40]; + TCHAR szAvailVirtual[40]; + BOOL (WINAPI *GlobalMemoryStatusEx)(LPMEMORYSTATUSEX); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_MEMMORY_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_MEMMORY_HELP1); + return 0; + } - GlobalMemoryStatusEx - = (BOOL (WINAPI *)(LPMEMORYSTATUSEX))GetProcAddress(GetModuleHandle(_T("KERNEL32")), "GlobalMemoryStatusEx"); - if (GlobalMemoryStatusEx) - { - msex.dwLength = sizeof(MEMORYSTATUSEX); - GlobalMemoryStatusEx(&msex); - } - else - { - MEMORYSTATUS ms; - ms.dwLength = sizeof(MEMORYSTATUS); - GlobalMemoryStatus(&ms); - msex.dwMemoryLoad = ms.dwMemoryLoad; - msex.ullTotalPhys = ms.dwTotalPhys; - msex.ullAvailPhys = ms.dwAvailPhys; - msex.ullTotalPageFile = ms.dwTotalPageFile; - msex.ullAvailPageFile = ms.dwAvailPageFile; - msex.ullTotalVirtual = ms.dwTotalVirtual; - msex.ullAvailVirtual = ms.dwAvailVirtual; - } + GlobalMemoryStatusEx + = (BOOL (WINAPI *)(LPMEMORYSTATUSEX))GetProcAddress(GetModuleHandle(_T("KERNEL32")), "GlobalMemoryStatusEx"); + if (GlobalMemoryStatusEx) + { + msex.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&msex); + } + else + { + MEMORYSTATUS ms; + ms.dwLength = sizeof(MEMORYSTATUS); + GlobalMemoryStatus(&ms); + msex.dwMemoryLoad = ms.dwMemoryLoad; + msex.ullTotalPhys = ms.dwTotalPhys; + msex.ullAvailPhys = ms.dwAvailPhys; + msex.ullTotalPageFile = ms.dwTotalPageFile; + msex.ullAvailPageFile = ms.dwAvailPageFile; + msex.ullTotalVirtual = ms.dwTotalVirtual; + msex.ullAvailVirtual = ms.dwAvailVirtual; + } - ConvertULargeInteger(msex.dwMemoryLoad, szMemoryLoad, 20, FALSE); - ConvertULargeInteger(msex.ullTotalPhys, szTotalPhys, 40, TRUE); - ConvertULargeInteger(msex.ullAvailPhys, szAvailPhys, 40, TRUE); - ConvertULargeInteger(msex.ullTotalPageFile, szTotalPageFile, 40, TRUE); - ConvertULargeInteger(msex.ullAvailPageFile, szAvailPageFile, 40, TRUE); - ConvertULargeInteger(msex.ullTotalVirtual, szTotalVirtual, 40, TRUE); - ConvertULargeInteger(msex.ullAvailVirtual, szAvailVirtual, 40, TRUE); + ConvertULargeInteger(msex.dwMemoryLoad, szMemoryLoad, 20, FALSE); + ConvertULargeInteger(msex.ullTotalPhys, szTotalPhys, 40, TRUE); + ConvertULargeInteger(msex.ullAvailPhys, szAvailPhys, 40, TRUE); + ConvertULargeInteger(msex.ullTotalPageFile, szTotalPageFile, 40, TRUE); + ConvertULargeInteger(msex.ullAvailPageFile, szAvailPageFile, 40, TRUE); + ConvertULargeInteger(msex.ullTotalVirtual, szTotalVirtual, 40, TRUE); + ConvertULargeInteger(msex.ullAvailVirtual, szAvailVirtual, 40, TRUE); - ConOutResPrintf(STRING_MEMMORY_HELP2, - szMemoryLoad, szTotalPhys, szAvailPhys, szTotalPageFile, - szAvailPageFile, szTotalVirtual, szAvailVirtual); + ConOutResPrintf(STRING_MEMMORY_HELP2, + szMemoryLoad, szTotalPhys, szAvailPhys, szTotalPageFile, + szAvailPageFile, szTotalVirtual, szAvailVirtual); - return 0; + return 0; } #endif /* INCLUDE_CMD_MEMORY */ diff --git a/base/shell/cmd/misc.c b/base/shell/cmd/misc.c index 78056b81a53..45a12e5cc06 100644 --- a/base/shell/cmd/misc.c +++ b/base/shell/cmd/misc.c @@ -28,8 +28,8 @@ * 06-Nov-1999 (Eric Kohl) * Added PagePrompt() and FilePrompt(). * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -40,44 +40,43 @@ TCHAR cgetchar (VOID) { - HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); - INPUT_RECORD irBuffer; - DWORD dwRead; + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + INPUT_RECORD irBuffer; + DWORD dwRead; - do - { - ReadConsoleInput (hInput, &irBuffer, 1, &dwRead); - if ((irBuffer.EventType == KEY_EVENT) && - (irBuffer.Event.KeyEvent.bKeyDown == TRUE)) - { - if (irBuffer.Event.KeyEvent.dwControlKeyState & - (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - { - if (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C') - { - bCtrlBreak = TRUE; - break; - } - } - else if ((irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || - (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || - (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)) - { - ; - } - - else - { - break; - } - } - } - while (TRUE); + do + { + ReadConsoleInput (hInput, &irBuffer, 1, &dwRead); + if ((irBuffer.EventType == KEY_EVENT) && + (irBuffer.Event.KeyEvent.bKeyDown == TRUE)) + { + if (irBuffer.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + if (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C') + { + bCtrlBreak = TRUE; + break; + } + } + else if ((irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (irBuffer.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)) + { + // Nothing to do + } + else + { + break; + } + } + } + while (TRUE); #ifndef _UNICODE - return irBuffer.Event.KeyEvent.uChar.AsciiChar; + return irBuffer.Event.KeyEvent.uChar.AsciiChar; #else - return irBuffer.Event.KeyEvent.uChar.UnicodeChar; + return irBuffer.Event.KeyEvent.uChar.UnicodeChar; #endif /* _UNICODE */ } @@ -86,45 +85,44 @@ cgetchar (VOID) */ VOID GetPathCase( TCHAR * Path, TCHAR * OutPath) { - UINT i = 0; - TCHAR TempPath[MAX_PATH]; - WIN32_FIND_DATA FindFileData; - HANDLE hFind; - _tcscpy(TempPath, _T("")); - _tcscpy(OutPath, _T("")); + UINT i = 0; + TCHAR TempPath[MAX_PATH]; + WIN32_FIND_DATA FindFileData; + HANDLE hFind; + _tcscpy(TempPath, _T("")); + _tcscpy(OutPath, _T("")); - - for(i = 0; i < _tcslen(Path); i++) - { - if(Path[i] != _T('\\')) - { - _tcsncat(TempPath, &Path[i], 1); - if(i != _tcslen(Path) - 1) - continue; - } - /* Handle the base part of the path different. - Because if you put it into findfirstfile, it will - return your current folder */ - if(_tcslen(TempPath) == 2 && TempPath[1] == _T(':')) - { - _tcscat(OutPath, TempPath); - _tcscat(OutPath, _T("\\")); - _tcscat(TempPath, _T("\\")); - } - else - { - hFind = FindFirstFile(TempPath,&FindFileData); - if(hFind == INVALID_HANDLE_VALUE) - { - _tcscpy(OutPath, Path); - return; - } - _tcscat(TempPath, _T("\\")); - _tcscat(OutPath, FindFileData.cFileName); - _tcscat(OutPath, _T("\\")); - FindClose(hFind); - } - } + for(i = 0; i < _tcslen(Path); i++) + { + if (Path[i] != _T('\\')) + { + _tcsncat(TempPath, &Path[i], 1); + if (i != _tcslen(Path) - 1) + continue; + } + /* Handle the base part of the path different. + Because if you put it into findfirstfile, it will + return your current folder */ + if (_tcslen(TempPath) == 2 && TempPath[1] == _T(':')) + { + _tcscat(OutPath, TempPath); + _tcscat(OutPath, _T("\\")); + _tcscat(TempPath, _T("\\")); + } + else + { + hFind = FindFirstFile(TempPath,&FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + { + _tcscpy(OutPath, Path); + return; + } + _tcscat(TempPath, _T("\\")); + _tcscat(OutPath, FindFileData.cFileName); + _tcscat(OutPath, _T("\\")); + FindClose(hFind); + } + } } /* @@ -133,180 +131,179 @@ VOID GetPathCase( TCHAR * Path, TCHAR * OutPath) BOOL CheckCtrlBreak (INT mode) { - static BOOL bLeaveAll = FALSE; /* leave all batch files */ - TCHAR options[4]; /* Yes, No, All */ - TCHAR c; + static BOOL bLeaveAll = FALSE; /* leave all batch files */ + TCHAR options[4]; /* Yes, No, All */ + TCHAR c; - switch (mode) - { - case BREAK_OUTOFBATCH: - bLeaveAll = 0; - return FALSE; + switch (mode) + { + case BREAK_OUTOFBATCH: + bLeaveAll = 0; + return FALSE; - case BREAK_BATCHFILE: - if (bLeaveAll) - return TRUE; + case BREAK_BATCHFILE: + if (bLeaveAll) + return TRUE; - if (!bCtrlBreak) - return FALSE; + if (!bCtrlBreak) + return FALSE; - LoadString(CMD_ModuleHandle, STRING_COPY_OPTION, options, 4); + LoadString(CMD_ModuleHandle, STRING_COPY_OPTION, options, 4); - /* we need to be sure the string arrives on the screen! */ - do - { - ConOutResPuts(STRING_CANCEL_BATCH_FILE); - c = _totupper(cgetchar()); - } while (!(_tcschr(options, c) || c == _T('\3')) || !c); + /* we need to be sure the string arrives on the screen! */ + do + { + ConOutResPuts(STRING_CANCEL_BATCH_FILE); + c = _totupper(cgetchar()); + } while (!(_tcschr(options, c) || c == _T('\3')) || !c); - ConOutPuts (_T("\r\n")); + ConOutChar(_T('\n')); - if (c == options[1]) - return bCtrlBreak = FALSE; /* ignore */ + if (c == options[1]) + return bCtrlBreak = FALSE; /* ignore */ - /* leave all batch files */ - bLeaveAll = ((c == options[2]) || (c == _T('\3'))); - break; + /* leave all batch files */ + bLeaveAll = ((c == options[2]) || (c == _T('\3'))); + break; - case BREAK_INPUT: - if (!bCtrlBreak) - return FALSE; - break; - } + case BREAK_INPUT: + if (!bCtrlBreak) + return FALSE; + break; + } - /* state processed */ - bCtrlBreak = FALSE; - return TRUE; + /* state processed */ + bCtrlBreak = FALSE; + return TRUE; } /* add new entry for new argument */ BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry) { - LPTSTR q; - LPTSTR *oldarg; + LPTSTR q; + LPTSTR *oldarg; - q = cmd_alloc ((_tcslen(entry) + 1) * sizeof (TCHAR)); - if (NULL == q) - { - return FALSE; - } + q = cmd_alloc ((_tcslen(entry) + 1) * sizeof (TCHAR)); + if (NULL == q) + { + return FALSE; + } - _tcscpy (q, entry); - oldarg = *arg; - *arg = cmd_realloc (oldarg, (*ac + 2) * sizeof (LPTSTR)); - if (NULL == *arg) - { - *arg = oldarg; - return FALSE; - } + _tcscpy (q, entry); + oldarg = *arg; + *arg = cmd_realloc (oldarg, (*ac + 2) * sizeof (LPTSTR)); + if (NULL == *arg) + { + *arg = oldarg; + return FALSE; + } - /* save new entry */ - (*arg)[*ac] = q; - (*arg)[++(*ac)] = NULL; + /* save new entry */ + (*arg)[*ac] = q; + (*arg)[++(*ac)] = NULL; - return TRUE; + return TRUE; } static BOOL expand (LPINT ac, LPTSTR **arg, LPCTSTR pattern) { - HANDLE hFind; - WIN32_FIND_DATA FindData; - BOOL ok; - LPCTSTR pathend; - LPTSTR dirpart, fullname; + HANDLE hFind; + WIN32_FIND_DATA FindData; + BOOL ok; + LPCTSTR pathend; + LPTSTR dirpart, fullname; - pathend = _tcsrchr (pattern, _T('\\')); - if (NULL != pathend) - { - dirpart = cmd_alloc((pathend - pattern + 2) * sizeof(TCHAR)); - if (NULL == dirpart) - { - return FALSE; - } - memcpy(dirpart, pattern, pathend - pattern + 1); - dirpart[pathend - pattern + 1] = _T('\0'); - } - else - { - dirpart = NULL; - } - hFind = FindFirstFile (pattern, &FindData); - if (INVALID_HANDLE_VALUE != hFind) - { - do - { - if (NULL != dirpart) - { - fullname = cmd_alloc((_tcslen(dirpart) + _tcslen(FindData.cFileName) + 1) * sizeof(TCHAR)); - if (NULL == fullname) - { - ok = FALSE; - } - else - { - _tcscat (_tcscpy (fullname, dirpart), FindData.cFileName); - ok = add_entry(ac, arg, fullname); - cmd_free (fullname); - } - } - else - { - ok = add_entry(ac, arg, FindData.cFileName); - } - } while (FindNextFile (hFind, &FindData) && ok); - FindClose (hFind); - } - else - { - ok = add_entry(ac, arg, pattern); - } + pathend = _tcsrchr (pattern, _T('\\')); + if (NULL != pathend) + { + dirpart = cmd_alloc((pathend - pattern + 2) * sizeof(TCHAR)); + if (NULL == dirpart) + { + return FALSE; + } + memcpy(dirpart, pattern, pathend - pattern + 1); + dirpart[pathend - pattern + 1] = _T('\0'); + } + else + { + dirpart = NULL; + } + hFind = FindFirstFile (pattern, &FindData); + if (INVALID_HANDLE_VALUE != hFind) + { + do + { + if (NULL != dirpart) + { + fullname = cmd_alloc((_tcslen(dirpart) + _tcslen(FindData.cFileName) + 1) * sizeof(TCHAR)); + if (NULL == fullname) + { + ok = FALSE; + } + else + { + _tcscat (_tcscpy (fullname, dirpart), FindData.cFileName); + ok = add_entry(ac, arg, fullname); + cmd_free (fullname); + } + } + else + { + ok = add_entry(ac, arg, FindData.cFileName); + } + } while (FindNextFile (hFind, &FindData) && ok); + FindClose (hFind); + } + else + { + ok = add_entry(ac, arg, pattern); + } - if (NULL != dirpart) - { - cmd_free (dirpart); - } + if (NULL != dirpart) + { + cmd_free (dirpart); + } - return ok; + return ok; } /* * split - splits a line up into separate arguments, deliminators * are spaces and slashes ('/'). */ - LPTSTR *split (LPTSTR s, LPINT args, BOOL expand_wildcards, BOOL handle_plus) { - LPTSTR *arg; - LPTSTR start; - LPTSTR q; - INT ac; - INT_PTR len; + LPTSTR *arg; + LPTSTR start; + LPTSTR q; + INT ac; + INT_PTR len; - arg = cmd_alloc (sizeof (LPTSTR)); - if (!arg) - return NULL; - *arg = NULL; + arg = cmd_alloc (sizeof (LPTSTR)); + if (!arg) + return NULL; + *arg = NULL; - ac = 0; - while (*s) - { - BOOL bQuoted = FALSE; + ac = 0; + while (*s) + { + BOOL bQuoted = FALSE; - /* skip leading spaces */ - while (*s && (_istspace(*s) || _istcntrl(*s))) - ++s; + /* skip leading spaces */ + while (*s && (_istspace(*s) || _istcntrl(*s))) + ++s; - start = s; + start = s; - /* the first character can be '/' */ - if (*s == _T('/')) - ++s; + /* the first character can be '/' */ + if (*s == _T('/')) + ++s; - /* skip to next word delimiter or start of next option */ - while (_istprint(*s)) - { - /* if quote (") then set bQuoted */ - bQuoted ^= (*s == _T('\"')); + /* skip to next word delimiter or start of next option */ + while (_istprint(*s)) + { + /* if quote (") then set bQuoted */ + bQuoted ^= (*s == _T('\"')); /* Check if we have unquoted text */ if (!bQuoted) @@ -322,383 +319,376 @@ LPTSTR *split (LPTSTR s, LPINT args, BOOL expand_wildcards, BOOL handle_plus) } } - ++s; - } + ++s; + } - /* a word was found */ - if (s != start) - { - q = cmd_alloc (((len = s - start) + 1) * sizeof (TCHAR)); - if (!q) - { - return NULL; - } - memcpy (q, start, len * sizeof (TCHAR)); - q[len] = _T('\0'); - StripQuotes(q); - if (expand_wildcards && (_T('/') != *start) && - (NULL != _tcschr(q, _T('*')) || NULL != _tcschr(q, _T('?')))) - { - if (! expand(&ac, &arg, q)) - { - cmd_free (q); - freep (arg); - return NULL; - } - } - else - { - if (! add_entry(&ac, &arg, q)) - { - cmd_free (q); - freep (arg); - return NULL; - } - } - cmd_free (q); - } - } + /* a word was found */ + if (s != start) + { + q = cmd_alloc (((len = s - start) + 1) * sizeof (TCHAR)); + if (!q) + { + return NULL; + } + memcpy (q, start, len * sizeof (TCHAR)); + q[len] = _T('\0'); + StripQuotes(q); + if (expand_wildcards && (_T('/') != *start) && + (NULL != _tcschr(q, _T('*')) || NULL != _tcschr(q, _T('?')))) + { + if (! expand(&ac, &arg, q)) + { + cmd_free (q); + freep (arg); + return NULL; + } + } + else + { + if (! add_entry(&ac, &arg, q)) + { + cmd_free (q); + freep (arg); + return NULL; + } + } + cmd_free (q); + } + } - *args = ac; + *args = ac; - return arg; + return arg; } -/* splitspace() is a function which uses JUST spaces as delimeters. split() uses "/" AND spaces. +/* + * splitspace() is a function which uses JUST spaces as delimeters. split() uses "/" AND spaces. * The way it works is real similar to split(), search the difference ;) * splitspace is needed for commands such as "move" where paths as C:\this/is\allowed/ are allowed */ LPTSTR *splitspace (LPTSTR s, LPINT args) { - LPTSTR *arg; - LPTSTR start; - LPTSTR q; - INT ac; - INT_PTR len; + LPTSTR *arg; + LPTSTR start; + LPTSTR q; + INT ac; + INT_PTR len; - arg = cmd_alloc (sizeof (LPTSTR)); - if (!arg) - return NULL; - *arg = NULL; + arg = cmd_alloc (sizeof (LPTSTR)); + if (!arg) + return NULL; + *arg = NULL; - ac = 0; - while (*s) - { - BOOL bQuoted = FALSE; + ac = 0; + while (*s) + { + BOOL bQuoted = FALSE; - /* skip leading spaces */ - while (*s && (_istspace (*s) || _istcntrl (*s))) - ++s; + /* skip leading spaces */ + while (*s && (_istspace (*s) || _istcntrl (*s))) + ++s; - start = s; + start = s; - /* skip to next word delimiter or start of next option */ - while (_istprint(*s) && (bQuoted || !_istspace(*s))) - { - /* if quote (") then set bQuoted */ - bQuoted ^= (*s == _T('\"')); - ++s; - } + /* skip to next word delimiter or start of next option */ + while (_istprint(*s) && (bQuoted || !_istspace(*s))) + { + /* if quote (") then set bQuoted */ + bQuoted ^= (*s == _T('\"')); + ++s; + } - /* a word was found */ - if (s != start) - { - q = cmd_alloc (((len = s - start) + 1) * sizeof (TCHAR)); - if (!q) - { - return NULL; - } - memcpy (q, start, len * sizeof (TCHAR)); - q[len] = _T('\0'); - StripQuotes(q); - if (! add_entry(&ac, &arg, q)) - { - cmd_free (q); - freep (arg); - return NULL; - } - cmd_free (q); - } - } + /* a word was found */ + if (s != start) + { + q = cmd_alloc (((len = s - start) + 1) * sizeof (TCHAR)); + if (!q) + { + return NULL; + } + memcpy (q, start, len * sizeof (TCHAR)); + q[len] = _T('\0'); + StripQuotes(q); + if (! add_entry(&ac, &arg, q)) + { + cmd_free (q); + freep (arg); + return NULL; + } + cmd_free (q); + } + } - *args = ac; + *args = ac; - return arg; + return arg; } /* * freep -- frees memory used for a call to split - * */ VOID freep (LPTSTR *p) { - LPTSTR *q; + LPTSTR *q; - if (!p) - return; + if (!p) + return; - q = p; - while (*q) - cmd_free(*q++); + q = p; + while (*q) + cmd_free(*q++); - cmd_free(p); + cmd_free(p); } - LPTSTR _stpcpy (LPTSTR dest, LPCTSTR src) { - _tcscpy (dest, src); - return (dest + _tcslen (src)); + _tcscpy (dest, src); + return (dest + _tcslen (src)); } VOID StripQuotes(TCHAR *in) { - TCHAR *out = in; - for (; *in; in++) - { - if (*in != _T('"')) - *out++ = *in; - } - *out = _T('\0'); + TCHAR *out = in; + for (; *in; in++) + { + if (*in != _T('"')) + *out++ = *in; + } + *out = _T('\0'); } - /* * Checks if a path is valid (accessible) */ - BOOL IsValidPathName (LPCTSTR pszPath) { - TCHAR szOldPath[MAX_PATH]; - BOOL bResult; + TCHAR szOldPath[MAX_PATH]; + BOOL bResult; - GetCurrentDirectory (MAX_PATH, szOldPath); - bResult = SetCurrentDirectory (pszPath); + GetCurrentDirectory (MAX_PATH, szOldPath); + bResult = SetCurrentDirectory (pszPath); - SetCurrentDirectory (szOldPath); + SetCurrentDirectory (szOldPath); - return bResult; + return bResult; } /* * Checks if a file exists (accessible) */ - BOOL IsExistingFile (LPCTSTR pszPath) { - DWORD attr = GetFileAttributes (pszPath); - return (attr != 0xFFFFFFFF && (! (attr & FILE_ATTRIBUTE_DIRECTORY)) ); + DWORD attr = GetFileAttributes (pszPath); + return (attr != 0xFFFFFFFF && (! (attr & FILE_ATTRIBUTE_DIRECTORY)) ); } BOOL IsExistingDirectory (LPCTSTR pszPath) { - DWORD attr = GetFileAttributes (pszPath); - return (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) ); + DWORD attr = GetFileAttributes (pszPath); + return (attr != 0xFFFFFFFF && (attr & FILE_ATTRIBUTE_DIRECTORY) ); } BOOL FileGetString (HANDLE hFile, LPTSTR lpBuffer, INT nBufferLength) { - LPSTR lpString; - DWORD dwRead; - INT len = 0; + LPSTR lpString; + DWORD dwRead; + INT len = 0; #ifdef _UNICODE - lpString = cmd_alloc(nBufferLength); + lpString = cmd_alloc(nBufferLength); #else - lpString = lpBuffer; + lpString = lpBuffer; #endif - if (ReadFile(hFile, lpString, nBufferLength - 1, &dwRead, NULL)) - { - /* break at new line*/ - CHAR *end = memchr(lpString, '\n', dwRead); - len = dwRead; - if (end) - { - len = (INT)(end - lpString) + 1; - SetFilePointer(hFile, len - dwRead, NULL, FILE_CURRENT); - } - } + if (ReadFile(hFile, lpString, nBufferLength - 1, &dwRead, NULL)) + { + /* break at new line*/ + CHAR *end = memchr(lpString, '\n', dwRead); + len = dwRead; + if (end) + { + len = (INT)(end - lpString) + 1; + SetFilePointer(hFile, len - dwRead, NULL, FILE_CURRENT); + } + } - if (!len) - { + if (!len) + { #ifdef _UNICODE - cmd_free(lpString); + cmd_free(lpString); #endif - return FALSE; - } + return FALSE; + } - lpString[len++] = '\0'; + lpString[len++] = '\0'; #ifdef _UNICODE - MultiByteToWideChar(OutputCodePage, 0, lpString, -1, lpBuffer, len); - cmd_free(lpString); + MultiByteToWideChar(OutputCodePage, 0, lpString, -1, lpBuffer, len); + cmd_free(lpString); #endif - return TRUE; + return TRUE; } -INT PagePrompt (VOID) +INT PagePrompt(VOID) { - INPUT_RECORD ir; + INPUT_RECORD ir; - ConOutResPuts(STRING_MISC_HELP1); + ConOutResPuts(STRING_MISC_HELP1); - RemoveBreakHandler (); - ConInDisable (); + RemoveBreakHandler(); + ConInDisable(); - do - { - ConInKey (&ir); - } - while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || - (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || - (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); + do + { + ConInKey(&ir); + } + while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); - AddBreakHandler (); - ConInEnable (); + AddBreakHandler(); + ConInEnable(); - if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || - ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && - (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) - { - bCtrlBreak = TRUE; - return PROMPT_BREAK; - } + if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || + ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && + (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) + { + bCtrlBreak = TRUE; + return PROMPT_BREAK; + } - return PROMPT_YES; + return PROMPT_YES; } INT FilePromptYN (UINT resID) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; -// TCHAR cKey = 0; -// LPTSTR szKeys = _T("yna"); + TCHAR szMsg[RC_STRING_MAX_SIZE]; +// TCHAR cKey = 0; +// LPTSTR szKeys = _T("yna"); - TCHAR szIn[10]; - LPTSTR p; + TCHAR szIn[10]; + LPTSTR p; - if (resID != 0) - ConOutResPrintf (resID); + if (resID != 0) + ConOutResPrintf (resID); - /* preliminary fix */ - ConInString (szIn, 10); - ConOutPrintf (_T("\n")); + /* preliminary fix */ + ConInString(szIn, 10); + ConOutChar(_T('\n')); - _tcsupr (szIn); - for (p = szIn; _istspace (*p); p++) - ; + _tcsupr (szIn); + for (p = szIn; _istspace (*p); p++) + ; - LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, szMsg, RC_STRING_MAX_SIZE); + LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, szMsg, RC_STRING_MAX_SIZE); - if (_tcsncmp(p, &szMsg[0], 1) == 0) - return PROMPT_YES; - else if (_tcsncmp(p, &szMsg[1], 1) == 0) - return PROMPT_NO; + if (_tcsncmp(p, &szMsg[0], 1) == 0) + return PROMPT_YES; + else if (_tcsncmp(p, &szMsg[1], 1) == 0) + return PROMPT_NO; #if 0 - else if (*p == _T('\03')) - return PROMPT_BREAK; + else if (*p == _T('\03')) + return PROMPT_BREAK; #endif - return PROMPT_NO; + return PROMPT_NO; - - /* unfinished sollution */ + /* unfinished solution */ #if 0 - RemoveBreakHandler (); - ConInDisable (); + RemoveBreakHandler(); + ConInDisable(); - do - { - ConInKey (&ir); - cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); - if (_tcschr (szKeys, cKey[0]) == NULL) - cKey = 0; + do + { + ConInKey (&ir); + cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); + if (_tcschr (szKeys, cKey[0]) == NULL) + cKey = 0; - } - while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || - (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || - (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); + } + while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); - AddBreakHandler (); - ConInEnable (); + AddBreakHandler(); + ConInEnable(); - if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || - ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') && - (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) - return PROMPT_BREAK; + if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || + ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') && + (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) + return PROMPT_BREAK; - return PROMPT_YES; + return PROMPT_YES; #endif } INT FilePromptYNA (UINT resID) { - TCHAR szMsg[RC_STRING_MAX_SIZE]; -// TCHAR cKey = 0; -// LPTSTR szKeys = _T("yna"); + TCHAR szMsg[RC_STRING_MAX_SIZE]; +// TCHAR cKey = 0; +// LPTSTR szKeys = _T("yna"); - TCHAR szIn[10]; - LPTSTR p; + TCHAR szIn[10]; + LPTSTR p; - if (resID != 0) - ConOutResPrintf (resID); + if (resID != 0) + ConOutResPrintf (resID); - /* preliminary fix */ - ConInString (szIn, 10); - ConOutPrintf (_T("\n")); + /* preliminary fix */ + ConInString(szIn, 10); + ConOutChar(_T('\n')); - _tcsupr (szIn); - for (p = szIn; _istspace (*p); p++) - ; + _tcsupr (szIn); + for (p = szIn; _istspace (*p); p++) + ; - LoadString( CMD_ModuleHandle, STRING_COPY_OPTION, szMsg, RC_STRING_MAX_SIZE); - - if (_tcsncmp(p, &szMsg[0], 1) == 0) - return PROMPT_YES; - else if (_tcsncmp(p, &szMsg[1], 1) == 0) - return PROMPT_NO; - else if (_tcsncmp(p, &szMsg[2], 1) == 0) - return PROMPT_ALL; + LoadString( CMD_ModuleHandle, STRING_COPY_OPTION, szMsg, RC_STRING_MAX_SIZE); + if (_tcsncmp(p, &szMsg[0], 1) == 0) + return PROMPT_YES; + else if (_tcsncmp(p, &szMsg[1], 1) == 0) + return PROMPT_NO; + else if (_tcsncmp(p, &szMsg[2], 1) == 0) + return PROMPT_ALL; #if 0 - else if (*p == _T('\03')) - return PROMPT_BREAK; + else if (*p == _T('\03')) + return PROMPT_BREAK; #endif - return PROMPT_NO; + return PROMPT_NO; - -/* unfinished sollution */ + /* unfinished solution */ #if 0 - RemoveBreakHandler (); - ConInDisable (); + RemoveBreakHandler(); + ConInDisable(); - do - { - ConInKey (&ir); - cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); - if (_tcschr (szKeys, cKey[0]) == NULL) - cKey = 0; - } - while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || - (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || - (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); + do + { + ConInKey (&ir); + cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); + if (_tcschr (szKeys, cKey[0]) == NULL) + cKey = 0; + } + while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); - AddBreakHandler (); - ConInEnable (); + AddBreakHandler(); + ConInEnable(); - if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || - ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && - (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) - return PROMPT_BREAK; + if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || + ((ir.Event.KeyEvent.wVirtualKeyCode == _T('C')) && + (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) + return PROMPT_BREAK; - return PROMPT_YES; + return PROMPT_YES; #endif } diff --git a/base/shell/cmd/mklink.c b/base/shell/cmd/mklink.c index 9b1bed612ac..d511050c47c 100644 --- a/base/shell/cmd/mklink.c +++ b/base/shell/cmd/mklink.c @@ -9,211 +9,216 @@ /* There is no API for creating junctions, so we must do it the hard way */ static BOOL CreateJunction(LPCTSTR LinkName, LPCTSTR TargetName) { - /* Structure for reparse point daya when ReparseTag is one of - * the tags defined by Microsoft. Copied from MinGW winnt.h */ - typedef struct _REPARSE_DATA_BUFFER { - DWORD ReparseTag; - WORD ReparseDataLength; - WORD Reserved; - _ANONYMOUS_UNION union { - struct { - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - BYTE DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; - } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + /* Structure for reparse point daya when ReparseTag is one of + * the tags defined by Microsoft. Copied from MinGW winnt.h */ + typedef struct _REPARSE_DATA_BUFFER + { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + _ANONYMOUS_UNION union + { + struct + { + WORD SubstituteNameOffset; + WORD SubstituteNameLength; + WORD PrintNameOffset; + WORD PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct + { + WORD SubstituteNameOffset; + WORD SubstituteNameLength; + WORD PrintNameOffset; + WORD PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct + { + BYTE DataBuffer[1]; + } GenericReparseBuffer; + } DUMMYUNIONNAME; + } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; - HMODULE hNTDLL = GetModuleHandle(_T("NTDLL")); - BOOLEAN (WINAPI *RtlDosPathNameToNtPathName_U)(PCWSTR, PUNICODE_STRING, PCWSTR *, CURDIR *) - = (BOOLEAN (WINAPI *)(PCWSTR, PUNICODE_STRING, PCWSTR *, CURDIR *))GetProcAddress(hNTDLL, "RtlDosPathNameToNtPathName_U"); - VOID (WINAPI *RtlFreeUnicodeString)(PUNICODE_STRING) - = (VOID (WINAPI *)(PUNICODE_STRING))GetProcAddress(hNTDLL, "RtlFreeUnicodeString"); + HMODULE hNTDLL = GetModuleHandle(_T("NTDLL")); + BOOLEAN (WINAPI *RtlDosPathNameToNtPathName_U)(PCWSTR, PUNICODE_STRING, PCWSTR *, CURDIR *) + = (BOOLEAN (WINAPI *)(PCWSTR, PUNICODE_STRING, PCWSTR *, CURDIR *))GetProcAddress(hNTDLL, "RtlDosPathNameToNtPathName_U"); + VOID (WINAPI *RtlFreeUnicodeString)(PUNICODE_STRING) + = (VOID (WINAPI *)(PUNICODE_STRING))GetProcAddress(hNTDLL, "RtlFreeUnicodeString"); - TCHAR TargetFullPath[MAX_PATH]; + TCHAR TargetFullPath[MAX_PATH]; #ifdef UNICODE -#define TargetFullPathW TargetFullPath + #define TargetFullPathW TargetFullPath #else - WCHAR TargetFullPathW[MAX_PATH]; + WCHAR TargetFullPathW[MAX_PATH]; #endif - UNICODE_STRING TargetNTPath; - HANDLE hJunction; + UNICODE_STRING TargetNTPath; + HANDLE hJunction; - /* The data for this kind of reparse point has two strings: - * The first ("SubstituteName") is the full target path in NT format, - * the second ("PrintName") is the full target path in Win32 format. - * Both of these must be wide-character strings. */ - if (!RtlDosPathNameToNtPathName_U || - !RtlFreeUnicodeString || - !GetFullPathName(TargetName, MAX_PATH, TargetFullPath, NULL) || + /* The data for this kind of reparse point has two strings: + * The first ("SubstituteName") is the full target path in NT format, + * the second ("PrintName") is the full target path in Win32 format. + * Both of these must be wide-character strings. */ + if (!RtlDosPathNameToNtPathName_U || + !RtlFreeUnicodeString || + !GetFullPathName(TargetName, MAX_PATH, TargetFullPath, NULL) || #ifndef UNICODE - !MultiByteToWideChar(CP_ACP, 0, TargetFullPath, -1, TargetFullPathW, -1) || + !MultiByteToWideChar(CP_ACP, 0, TargetFullPath, -1, TargetFullPathW, -1) || #endif - !RtlDosPathNameToNtPathName_U(TargetFullPathW, &TargetNTPath, NULL, NULL)) - { - return FALSE; - } + !RtlDosPathNameToNtPathName_U(TargetFullPathW, &TargetNTPath, NULL, NULL)) + { + return FALSE; + } - /* We have both the names we need, so time to create the junction. - * Start with an empty directory */ - if (!CreateDirectory(LinkName, NULL)) - { - RtlFreeUnicodeString(&TargetNTPath); - return FALSE; - } + /* We have both the names we need, so time to create the junction. + * Start with an empty directory */ + if (!CreateDirectory(LinkName, NULL)) + { + RtlFreeUnicodeString(&TargetNTPath); + return FALSE; + } - /* Open the directory we just created */ - hJunction = CreateFile(LinkName, GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (hJunction != INVALID_HANDLE_VALUE) - { - /* Allocate a buffer large enough to hold both strings, including trailing NULs */ - SIZE_T TargetLen = wcslen(TargetFullPathW) * sizeof(WCHAR); - DWORD DataSize = (DWORD)(FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) - + TargetNTPath.Length + sizeof(WCHAR) - + TargetLen + sizeof(WCHAR)); - PREPARSE_DATA_BUFFER Data = _alloca(DataSize); + /* Open the directory we just created */ + hJunction = CreateFile(LinkName, GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (hJunction != INVALID_HANDLE_VALUE) + { + /* Allocate a buffer large enough to hold both strings, including trailing NULs */ + SIZE_T TargetLen = wcslen(TargetFullPathW) * sizeof(WCHAR); + DWORD DataSize = (DWORD)(FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + + TargetNTPath.Length + sizeof(WCHAR) + + TargetLen + sizeof(WCHAR)); + PREPARSE_DATA_BUFFER Data = _alloca(DataSize); - /* Fill it out and use it to turn the directory into a reparse point */ - Data->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - Data->ReparseDataLength = (WORD)(DataSize - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer)); - Data->Reserved = 0; - Data->MountPointReparseBuffer.SubstituteNameOffset = 0; - Data->MountPointReparseBuffer.SubstituteNameLength = TargetNTPath.Length; - wcscpy(Data->MountPointReparseBuffer.PathBuffer, - TargetNTPath.Buffer); - Data->MountPointReparseBuffer.PrintNameOffset = TargetNTPath.Length + sizeof(WCHAR); - Data->MountPointReparseBuffer.PrintNameLength = (USHORT)TargetLen; - wcscpy((WCHAR *)((BYTE *)Data->MountPointReparseBuffer.PathBuffer - + Data->MountPointReparseBuffer.PrintNameOffset), - TargetFullPathW); - if (DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, - Data, DataSize, NULL, 0, &DataSize, NULL)) - { - /* Success */ - CloseHandle(hJunction); - RtlFreeUnicodeString(&TargetNTPath); - return TRUE; - } - CloseHandle(hJunction); - } - RemoveDirectory(LinkName); - RtlFreeUnicodeString(&TargetNTPath); - return FALSE; + /* Fill it out and use it to turn the directory into a reparse point */ + Data->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + Data->ReparseDataLength = (WORD)(DataSize - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer)); + Data->Reserved = 0; + Data->MountPointReparseBuffer.SubstituteNameOffset = 0; + Data->MountPointReparseBuffer.SubstituteNameLength = TargetNTPath.Length; + wcscpy(Data->MountPointReparseBuffer.PathBuffer, + TargetNTPath.Buffer); + Data->MountPointReparseBuffer.PrintNameOffset = TargetNTPath.Length + sizeof(WCHAR); + Data->MountPointReparseBuffer.PrintNameLength = (USHORT)TargetLen; + wcscpy((WCHAR *)((BYTE *)Data->MountPointReparseBuffer.PathBuffer + + Data->MountPointReparseBuffer.PrintNameOffset), + TargetFullPathW); + if (DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, + Data, DataSize, NULL, 0, &DataSize, NULL)) + { + /* Success */ + CloseHandle(hJunction); + RtlFreeUnicodeString(&TargetNTPath); + return TRUE; + } + CloseHandle(hJunction); + } + RemoveDirectory(LinkName); + RtlFreeUnicodeString(&TargetNTPath); + return FALSE; } INT cmd_mklink(LPTSTR param) { - HMODULE hKernel32 = GetModuleHandle(_T("KERNEL32")); - DWORD Flags = 0; - enum { SYMBOLIC, HARD, JUNCTION } LinkType = SYMBOLIC; - INT NumFiles = 0; - LPTSTR Name[2]; - INT argc, i; - LPTSTR *arg; + HMODULE hKernel32 = GetModuleHandle(_T("KERNEL32")); + DWORD Flags = 0; + enum { SYMBOLIC, HARD, JUNCTION } LinkType = SYMBOLIC; + INT NumFiles = 0; + LPTSTR Name[2]; + INT argc, i; + LPTSTR *arg; - if (!_tcsncmp(param, _T("/?"), 2)) - { - ConOutResPuts(STRING_MKLINK_HELP); - return 0; - } + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutResPuts(STRING_MKLINK_HELP); + return 0; + } - arg = split(param, &argc, FALSE, FALSE); - for (i = 0; i < argc; i++) - { - if (arg[i][0] == _T('/')) - { - if (!_tcsicmp(arg[i], _T("/D"))) - Flags |= 1; /* SYMBOLIC_LINK_FLAG_DIRECTORY */ - else if (!_tcsicmp(arg[i], _T("/H"))) - LinkType = HARD; - else if (!_tcsicmp(arg[i], _T("/J"))) - LinkType = JUNCTION; - else - { - error_invalid_switch(arg[i][1]); - freep(arg); - return 1; - } - } - else - { - if (NumFiles == 2) - { - error_too_many_parameters(arg[i]); - freep(arg); - return 1; - } - Name[NumFiles++] = arg[i]; - } - } - freep(arg); + arg = split(param, &argc, FALSE, FALSE); + for (i = 0; i < argc; i++) + { + if (arg[i][0] == _T('/')) + { + if (!_tcsicmp(arg[i], _T("/D"))) + Flags |= 1; /* SYMBOLIC_LINK_FLAG_DIRECTORY */ + else if (!_tcsicmp(arg[i], _T("/H"))) + LinkType = HARD; + else if (!_tcsicmp(arg[i], _T("/J"))) + LinkType = JUNCTION; + else + { + error_invalid_switch(arg[i][1]); + freep(arg); + return 1; + } + } + else + { + if (NumFiles == 2) + { + error_too_many_parameters(arg[i]); + freep(arg); + return 1; + } + Name[NumFiles++] = arg[i]; + } + } + freep(arg); - if (NumFiles != 2) - { - error_req_param_missing(); - return 1; - } + if (NumFiles != 2) + { + error_req_param_missing(); + return 1; + } - nErrorLevel = 0; + nErrorLevel = 0; - if (LinkType == SYMBOLIC) - { - /* CreateSymbolicLink doesn't exist in old versions of Windows, - * so load dynamically */ - BOOL (WINAPI *CreateSymbolicLink)(LPCTSTR, LPCTSTR, DWORD) + if (LinkType == SYMBOLIC) + { + /* CreateSymbolicLink doesn't exist in old versions of Windows, + * so load dynamically */ + BOOL (WINAPI *CreateSymbolicLink)(LPCTSTR, LPCTSTR, DWORD) #ifdef UNICODE - = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, DWORD))GetProcAddress(hKernel32, "CreateSymbolicLinkW"); + = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, DWORD))GetProcAddress(hKernel32, "CreateSymbolicLinkW"); #else - = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, DWORD))GetProcAddress(hKernel32, "CreateSymbolicLinkA"); + = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, DWORD))GetProcAddress(hKernel32, "CreateSymbolicLinkA"); #endif - if (CreateSymbolicLink && CreateSymbolicLink(Name[0], Name[1], Flags)) - { - ConOutResPrintf(STRING_MKLINK_CREATED_SYMBOLIC, Name[0], Name[1]); - return 0; - } - } - else if (LinkType == HARD) - { - /* CreateHardLink doesn't exist in old versions of Windows, - * so load dynamically */ - BOOL (WINAPI *CreateHardLink)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES) + if (CreateSymbolicLink && CreateSymbolicLink(Name[0], Name[1], Flags)) + { + ConOutResPrintf(STRING_MKLINK_CREATED_SYMBOLIC, Name[0], Name[1]); + return 0; + } + } + else if (LinkType == HARD) + { + /* CreateHardLink doesn't exist in old versions of Windows, + * so load dynamically */ + BOOL (WINAPI *CreateHardLink)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES) #ifdef UNICODE - = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES))GetProcAddress(hKernel32, "CreateHardLinkW"); + = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES))GetProcAddress(hKernel32, "CreateHardLinkW"); #else - = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES))GetProcAddress(hKernel32, "CreateHardLinkA"); + = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES))GetProcAddress(hKernel32, "CreateHardLinkA"); #endif - if (CreateHardLink && CreateHardLink(Name[0], Name[1], NULL)) - { - ConOutResPrintf(STRING_MKLINK_CREATED_HARD, Name[0], Name[1]); - return 0; - } - } - else - { - if (CreateJunction(Name[0], Name[1])) - { - ConOutResPrintf(STRING_MKLINK_CREATED_JUNCTION, Name[0], Name[1]); - return 0; - } - } + if (CreateHardLink && CreateHardLink(Name[0], Name[1], NULL)) + { + ConOutResPrintf(STRING_MKLINK_CREATED_HARD, Name[0], Name[1]); + return 0; + } + } + else + { + if (CreateJunction(Name[0], Name[1])) + { + ConOutResPrintf(STRING_MKLINK_CREATED_JUNCTION, Name[0], Name[1]); + return 0; + } + } - ErrorMessage(GetLastError(), _T("MKLINK")); - return 1; + ErrorMessage(GetLastError(), _T("MKLINK")); + return 1; } #endif /* INCLUDE_CMD_MKLINK */ diff --git a/base/shell/cmd/move.c b/base/shell/cmd/move.c index df92513ffe9..f557f31496c 100644 --- a/base/shell/cmd/move.c +++ b/base/shell/cmd/move.c @@ -21,10 +21,10 @@ * 03-Feb-1999 (Eric Kohl) * Added "/N" option. * -* 30-Apr-2005 (Magnus Olsen) ) -* Remove all hardcode string to En.rc +* 30-Apr-2005 (Magnus Olsen ) +* Remove all hardcoded strings in En.rc * -* 24-Jun-2005 (Brandon Turner) ) +* 24-Jun-2005 (Brandon Turner ) * Fixed bug to allow MS style wildcards + code clean up * added /y and /-y */ @@ -35,486 +35,478 @@ enum { - MOVE_NOTHING = 0x001, /* /N */ - MOVE_OVER_YES = 0x002, /* /Y */ - MOVE_OVER_NO = 0x004, /* /-Y */ + MOVE_NOTHING = 0x001, /* /N */ + MOVE_OVER_YES = 0x002, /* /Y */ + MOVE_OVER_NO = 0x004, /* /-Y */ }; enum -{ /* Move status flags */ - MOVE_SOURCE_IS_DIR = 0x001, - MOVE_SOURCE_IS_FILE = 0x002, - MOVE_DEST_IS_DIR = 0x004, - MOVE_DEST_IS_FILE = 0x008, - MOVE_SOURCE_HAS_WILD = 0x010, /* source has wildcard */ - MOVE_SRC_CURRENT_IS_DIR = 0x020, /* source is file but at the current round we found a directory */ - MOVE_DEST_EXISTS = 0x040, - MOVE_PATHS_ON_DIF_VOL = 0x080 /* source and destination paths are on different volume */ +{ + /* Move status flags */ + MOVE_SOURCE_IS_DIR = 0x001, + MOVE_SOURCE_IS_FILE = 0x002, + MOVE_DEST_IS_DIR = 0x004, + MOVE_DEST_IS_FILE = 0x008, + MOVE_SOURCE_HAS_WILD = 0x010, /* source has wildcard */ + MOVE_SRC_CURRENT_IS_DIR = 0x020, /* source is file but at the current round we found a directory */ + MOVE_DEST_EXISTS = 0x040, + MOVE_PATHS_ON_DIF_VOL = 0x080 /* source and destination paths are on different volume */ }; static INT MoveOverwrite (LPTSTR fn) { - /*ask the user if they want to override*/ - INT res; - ConOutResPrintf(STRING_MOVE_HELP1, fn); - res = FilePromptYNA (0); - return res; + /* ask the user if they want to override */ + INT res; + ConOutResPrintf(STRING_MOVE_HELP1, fn); + res = FilePromptYNA (0); + return res; } void GetDirectory (LPTSTR wholepath, LPTSTR directory, BOOL CheckExisting) { - /* returns only directory part of path with backslash */ - /* TODO: make code unc aware */ - /* Is there a better alternative to this? */ - LPTSTR last; - if (CheckExisting && IsExistingDirectory(wholepath)) - { - _tcscpy(directory, wholepath); - } - else if ((last = _tcsrchr(wholepath,_T('\\'))) != NULL) - { - _tcsncpy(directory, wholepath, last - wholepath + 1); - directory[last - wholepath + 1] = 0; - } - else - { - GetRootPath(wholepath,directory, MAX_PATH); - } + /* returns only directory part of path with backslash */ + /* TODO: make code unc aware */ + /* Is there a better alternative to this? */ + LPTSTR last; + if (CheckExisting && IsExistingDirectory(wholepath)) + { + _tcscpy(directory, wholepath); + } + else if ((last = _tcsrchr(wholepath,_T('\\'))) != NULL) + { + _tcsncpy(directory, wholepath, last - wholepath + 1); + directory[last - wholepath + 1] = 0; + } + else + { + GetRootPath(wholepath,directory, MAX_PATH); + } } INT cmd_move (LPTSTR param) { - LPTSTR *arg; - INT argc, i, nFiles; - LPTSTR pszDest; - TCHAR szDestPath[MAX_PATH]; - TCHAR szFullDestPath[MAX_PATH]; - TCHAR szSrcDirPath[MAX_PATH]; - TCHAR szSrcPath[MAX_PATH]; - TCHAR szFullSrcPath[MAX_PATH]; - DWORD dwFlags = 0; - INT nOverwrite = 0; - WIN32_FIND_DATA findBuffer; - HANDLE hFile; - - /* used only when source and destination directories are on different volume*/ - HANDLE hDestFile; - WIN32_FIND_DATA findDestBuffer; - TCHAR szMoveDest[MAX_PATH]; - TCHAR szMoveSrc[MAX_PATH]; - LPTSTR pszDestDirPointer; - LPTSTR pszSrcDirPointer; - INT nDirLevel = 0; - - LPTSTR pszFile; - BOOL OnlyOneFile; - BOOL FoundFile; - BOOL MoveStatus; - DWORD dwMoveFlags = 0; - DWORD dwMoveStatusFlags = 0; + LPTSTR *arg; + INT argc, i, nFiles; + LPTSTR pszDest; + TCHAR szDestPath[MAX_PATH]; + TCHAR szFullDestPath[MAX_PATH]; + TCHAR szSrcDirPath[MAX_PATH]; + TCHAR szSrcPath[MAX_PATH]; + TCHAR szFullSrcPath[MAX_PATH]; + DWORD dwFlags = 0; + INT nOverwrite = 0; + WIN32_FIND_DATA findBuffer; + HANDLE hFile; + /* used only when source and destination directories are on different volume */ + HANDLE hDestFile; + WIN32_FIND_DATA findDestBuffer; + TCHAR szMoveDest[MAX_PATH]; + TCHAR szMoveSrc[MAX_PATH]; + LPTSTR pszDestDirPointer; + LPTSTR pszSrcDirPointer; + INT nDirLevel = 0; - if (!_tcsncmp (param, _T("/?"), 2)) - { + LPTSTR pszFile; + BOOL OnlyOneFile; + BOOL FoundFile; + BOOL MoveStatus; + DWORD dwMoveFlags = 0; + DWORD dwMoveStatusFlags = 0; + + if (!_tcsncmp (param, _T("/?"), 2)) + { #if 0 - ConOutPuts (_T("Moves files and renames files and directories.\n\n" - "To move one or more files:\n" - "MOVE [/N][/Y|/-Y][drive:][path]filename1[,...] destination\n" - "\n" - "To rename a directory:\n" - "MOVE [/N][/Y|/-Y][drive:][path]dirname1 dirname2\n" - "\n" - " [drive:][path]filename1 Specifies the location and name of the file\n" - " or files you want to move.\n" - " /N Nothing. Don everthing but move files or direcories.\n" - " /Y\n" - " /-Y\n" - "...")); + ConOutPuts (_T("Moves files and renames files and directories.\n\n" + "To move one or more files:\n" + "MOVE [/N][/Y|/-Y][drive:][path]filename1[,...] destination\n" + "\n" + "To rename a directory:\n" + "MOVE [/N][/Y|/-Y][drive:][path]dirname1 dirname2\n" + "\n" + " [drive:][path]filename1 Specifies the location and name of the file\n" + " or files you want to move.\n" + " /N Nothing. Don everthing but move files or direcories.\n" + " /Y\n" + " /-Y\n" + "...")); #else - ConOutResPaging(TRUE,STRING_MOVE_HELP2); + ConOutResPaging(TRUE,STRING_MOVE_HELP2); #endif - return 0; - } + return 0; + } - nErrorLevel = 0; - arg = splitspace(param, &argc); + nErrorLevel = 0; + arg = splitspace(param, &argc); - /* read options */ - for (i = 0; i < argc; i++) - { - if (!_tcsicmp(arg[i], _T("/N"))) - dwFlags |= MOVE_NOTHING; - else if (!_tcsicmp(arg[i], _T("/Y"))) - dwFlags |= MOVE_OVER_YES; - else if (!_tcsicmp(arg[i], _T("/-Y"))) - dwFlags |= MOVE_OVER_NO; - else - break; - } - nFiles = argc - i; + /* read options */ + for (i = 0; i < argc; i++) + { + if (!_tcsicmp(arg[i], _T("/N"))) + dwFlags |= MOVE_NOTHING; + else if (!_tcsicmp(arg[i], _T("/Y"))) + dwFlags |= MOVE_OVER_YES; + else if (!_tcsicmp(arg[i], _T("/-Y"))) + dwFlags |= MOVE_OVER_NO; + else + break; + } + nFiles = argc - i; - if (nFiles < 1) - { - /* there must be at least one pathspec */ - error_req_param_missing(); - freep(arg); - return 1; - } + if (nFiles < 1) + { + /* there must be at least one pathspec */ + error_req_param_missing(); + freep(arg); + return 1; + } - if (nFiles > 2) - { - /* there are more than two pathspecs */ - error_too_many_parameters(param); - freep(arg); - return 1; - } + if (nFiles > 2) + { + /* there are more than two pathspecs */ + error_too_many_parameters(param); + freep(arg); + return 1; + } - /* If no destination is given, default to current directory */ - pszDest = (nFiles == 1) ? _T(".") : arg[i + 1]; + /* If no destination is given, default to current directory */ + pszDest = (nFiles == 1) ? _T(".") : arg[i + 1]; - /* check for wildcards in source and destination */ - if (_tcschr(pszDest, _T('*')) != NULL || _tcschr(pszDest, _T('?')) != NULL) - { - /* '*'/'?' in dest, this doesnt happen. give folder name instead*/ - error_invalid_parameter_format(pszDest); - freep(arg); - return 1; - } - if (_tcschr(arg[i], _T('*')) != NULL || _tcschr(arg[i], _T('?')) != NULL) - { - dwMoveStatusFlags |= MOVE_SOURCE_HAS_WILD; - } - - - /* get destination */ - GetFullPathName (pszDest, MAX_PATH, szDestPath, NULL); - TRACE ("Destination: %s\n", debugstr_aw(szDestPath)); - - /* get source folder */ - GetFullPathName(arg[i], MAX_PATH, szSrcDirPath, &pszFile); - if (pszFile != NULL) - *pszFile = _T('\0'); - TRACE ("Source Folder: %s\n", debugstr_aw(szSrcDirPath)); - - hFile = FindFirstFile (arg[i], &findBuffer); - if (hFile == INVALID_HANDLE_VALUE) - { - ErrorMessage (GetLastError (), arg[i]); - freep (arg); - return 1; - - } + /* check for wildcards in source and destination */ + if (_tcschr(pszDest, _T('*')) != NULL || _tcschr(pszDest, _T('?')) != NULL) + { + /* '*'/'?' in dest, this doesnt happen. give folder name instead*/ + error_invalid_parameter_format(pszDest); + freep(arg); + return 1; + } + if (_tcschr(arg[i], _T('*')) != NULL || _tcschr(arg[i], _T('?')) != NULL) + { + dwMoveStatusFlags |= MOVE_SOURCE_HAS_WILD; + } - /* check for special cases "." and ".." and if found skip them */ - FoundFile = TRUE; - while(FoundFile && - (_tcscmp(findBuffer.cFileName,_T(".")) == 0 || - _tcscmp(findBuffer.cFileName,_T("..")) == 0)) - FoundFile = FindNextFile (hFile, &findBuffer); - - if (!FoundFile) - { - /* what? we don't have anything to move? */ - error_file_not_found(); - FindClose(hFile); - freep(arg); - return 1; - } - - OnlyOneFile = TRUE; - /* check if there can be found files as files have first priority */ - if (findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - dwMoveStatusFlags |= MOVE_SOURCE_IS_DIR; - else - dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE; - while(OnlyOneFile && FindNextFile(hFile,&findBuffer)) - { - if (!(findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - ConOutPrintf(_T("")); - if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) OnlyOneFile = FALSE; - else - { /* this has been done this way so that we don't disturb other settings if they have been set before this */ - dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE; - dwMoveStatusFlags &= ~MOVE_SOURCE_IS_DIR; - } - } - } - FindClose(hFile); + /* get destination */ + GetFullPathName (pszDest, MAX_PATH, szDestPath, NULL); + TRACE ("Destination: %s\n", debugstr_aw(szDestPath)); - TRACE ("Do we have only one file: %s\n", OnlyOneFile ? "TRUE" : "FALSE"); + /* get source folder */ + GetFullPathName(arg[i], MAX_PATH, szSrcDirPath, &pszFile); + if (pszFile != NULL) + *pszFile = _T('\0'); + TRACE ("Source Folder: %s\n", debugstr_aw(szSrcDirPath)); - /* we have to start again to be sure we don't miss any files or folders*/ - hFile = FindFirstFile (arg[i], &findBuffer); - if (hFile == INVALID_HANDLE_VALUE) - { - ErrorMessage (GetLastError (), arg[i]); - freep (arg); - return 1; - - } - - /* check for special cases "." and ".." and if found skip them */ - FoundFile = TRUE; - while(FoundFile && - (_tcscmp(findBuffer.cFileName,_T(".")) == 0 || - _tcscmp(findBuffer.cFileName,_T("..")) == 0)) - FoundFile = FindNextFile (hFile, &findBuffer); - - if (!FoundFile) - { - /* huh? somebody removed files and/or folders which were there */ - error_file_not_found(); - FindClose(hFile); - freep(arg); - return 1; - } - - /* check if source and destination paths are on different volumes */ - if (szSrcDirPath[0] != szDestPath[0]) - dwMoveStatusFlags |= MOVE_PATHS_ON_DIF_VOL; - - /* move it */ - do - { - TRACE ("Found file/directory: %s\n", debugstr_aw(findBuffer.cFileName)); - nOverwrite = 1; - dwMoveFlags = 0; - dwMoveStatusFlags &= ~MOVE_DEST_IS_FILE & - ~MOVE_DEST_IS_DIR & - ~MOVE_SRC_CURRENT_IS_DIR & - ~MOVE_DEST_EXISTS; - _tcscpy(szFullSrcPath,szSrcDirPath); - if(szFullSrcPath[_tcslen(szFullSrcPath) - 1] != _T('\\')) - _tcscat (szFullSrcPath, _T("\\")); - _tcscat(szFullSrcPath,findBuffer.cFileName); - _tcscpy(szSrcPath, szFullSrcPath); - - if (IsExistingDirectory(szSrcPath)) - { - /* source is directory */ - - if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) - { - dwMoveStatusFlags |= MOVE_SRC_CURRENT_IS_DIR; /* source is file but at the current round we found a directory */ - continue; - } - TRACE ("Source is dir: %s\n", debugstr_aw(szSrcPath)); - dwMoveFlags = MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; - } - - /* if source is file we don't need to do anything special */ - - if (IsExistingDirectory(szDestPath)) - { - /* destination is existing directory */ - TRACE ("Destination is directory: %s\n", debugstr_aw(szDestPath)); - - dwMoveStatusFlags |= MOVE_DEST_IS_DIR; - - /*build the dest string(accounts for *)*/ - _tcscpy (szFullDestPath, szDestPath); - /*check to see if there is an ending slash, if not add one*/ - if(szFullDestPath[_tcslen(szFullDestPath) - 1] != _T('\\')) - _tcscat (szFullDestPath, _T("\\")); - _tcscat (szFullDestPath, findBuffer.cFileName); - - if (IsExistingFile(szFullDestPath) || IsExistingDirectory(szFullDestPath)) - dwMoveStatusFlags |= MOVE_DEST_EXISTS; - - dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; - - } - if (IsExistingFile(szDestPath)) - { - /* destination is a file */ - TRACE ("Destination is file: %s\n", debugstr_aw(szDestPath)); - - dwMoveStatusFlags |= MOVE_DEST_IS_FILE | MOVE_DEST_EXISTS; - _tcscpy (szFullDestPath, szDestPath); - - dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; - - } - - TRACE ("Move Status Flags: 0x%X\n",dwMoveStatusFlags); - - if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR && - dwMoveStatusFlags & MOVE_DEST_IS_DIR && - dwMoveStatusFlags & MOVE_SOURCE_HAS_WILD) - { - /* We are not allowed to have existing source and destination dir when there is wildcard in source */ - error_syntax(NULL); - FindClose(hFile); - freep(arg); - return 1; - } - - if (!(dwMoveStatusFlags & (MOVE_DEST_IS_FILE | MOVE_DEST_IS_DIR))) - { - /* destination doesn't exist */ - _tcscpy (szFullDestPath, szDestPath); - if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) dwMoveStatusFlags |= MOVE_DEST_IS_FILE; - if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) dwMoveStatusFlags |= MOVE_DEST_IS_DIR; - - dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; - } - - if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE && - dwMoveStatusFlags & MOVE_DEST_IS_FILE && - !OnlyOneFile) - { - /*source has many files but there is only one destination file*/ - error_invalid_parameter_format(pszDest); - FindClose(hFile); - freep (arg); - return 1; - } - - /*checks to make sure user wanted/wants the override*/ - if((dwFlags & MOVE_OVER_NO) && - (dwMoveStatusFlags & MOVE_DEST_EXISTS)) - continue; - if(!(dwFlags & MOVE_OVER_YES) && - (dwMoveStatusFlags & MOVE_DEST_EXISTS)) - nOverwrite = MoveOverwrite (szFullDestPath); - if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK) - continue; - if (nOverwrite == PROMPT_ALL) - dwFlags |= MOVE_OVER_YES; - - - ConOutPrintf (_T("%s => %s "), szSrcPath, szFullDestPath); - - /* are we really supposed to do something */ - if (dwFlags & MOVE_NOTHING) - continue; - - /*move the file*/ - if (!(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR && - dwMoveStatusFlags & MOVE_PATHS_ON_DIF_VOL)) - /* we aren't moving source folder to different drive */ - MoveStatus = MoveFileEx (szSrcPath, szFullDestPath, dwMoveFlags); - else - { /* we are moving source folder to different drive */ - _tcscpy(szMoveDest, szFullDestPath); - _tcscpy(szMoveSrc, szSrcPath); - DeleteFile(szMoveDest); - MoveStatus = CreateDirectory(szMoveDest, NULL); /* we use default security settings */ - if (MoveStatus) - { - _tcscat(szMoveDest,_T("\\")); - _tcscat(szMoveSrc,_T("\\")); - nDirLevel = 0; - pszDestDirPointer = szMoveDest + _tcslen(szMoveDest); - pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc); - _tcscpy(pszSrcDirPointer,_T("*.*")); - hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer); - if (hDestFile == INVALID_HANDLE_VALUE) - MoveStatus = FALSE; - else - { - BOOL FirstTime = TRUE; - FoundFile = TRUE; - MoveStatus = FALSE; - while(FoundFile) - { - if (FirstTime) - FirstTime = FALSE; - else - FoundFile = FindNextFile (hDestFile, &findDestBuffer); - - if (!FoundFile) - { /* Nothing to do in this folder so we stop working on it */ - FindClose(hDestFile); - (pszSrcDirPointer)--; - (pszDestDirPointer)--; - _tcscpy(pszSrcDirPointer,_T("")); - _tcscpy(pszDestDirPointer,_T("")); - if (nDirLevel > 0) - { - TCHAR szTempPath[MAX_PATH]; - INT_PTR nDiff; + hFile = FindFirstFile (arg[i], &findBuffer); + if (hFile == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), arg[i]); + freep (arg); + return 1; + } - FoundFile = TRUE; /* we need to continue our seek for files */ - nDirLevel--; - RemoveDirectory(szMoveSrc); - GetDirectory(szMoveSrc,szTempPath,0); - nDiff = _tcslen(szMoveSrc) - _tcslen(szTempPath); - pszSrcDirPointer = pszSrcDirPointer - nDiff; - _tcscpy(pszSrcDirPointer,_T("")); - GetDirectory(szMoveDest,szTempPath,0); - nDiff = _tcslen(szMoveDest) - _tcslen(szTempPath); - pszDestDirPointer = pszDestDirPointer - nDiff; - _tcscpy(pszDestDirPointer,_T("")); - if(szMoveSrc[_tcslen(szMoveSrc) - 1] != _T('\\')) - _tcscat (szMoveSrc, _T("\\")); - if(szMoveDest[_tcslen(szMoveDest) - 1] != _T('\\')) - _tcscat (szMoveDest, _T("\\")); - pszDestDirPointer = szMoveDest + _tcslen(szMoveDest); - pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc); - _tcscpy(pszSrcDirPointer,_T("*.*")); - hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer); - if (hDestFile == INVALID_HANDLE_VALUE) - continue; - FirstTime = TRUE; - } - else - { - MoveStatus = TRUE; /* we moved everything so lets tell user about it */ - RemoveDirectory(szMoveSrc); - } - continue; - } - - /* if we find "." or ".." we'll skip them */ - if (_tcscmp(findDestBuffer.cFileName,_T(".")) == 0 || - _tcscmp(findDestBuffer.cFileName,_T("..")) == 0) - continue; - - _tcscpy(pszSrcDirPointer, findDestBuffer.cFileName); - _tcscpy(pszDestDirPointer, findDestBuffer.cFileName); - if (IsExistingFile(szMoveSrc)) - { - FoundFile = CopyFile(szMoveSrc, szMoveDest, FALSE); - if (!FoundFile) continue; - DeleteFile(szMoveSrc); - } - else - { - FindClose(hDestFile); - CreateDirectory(szMoveDest, NULL); - _tcscat(szMoveDest,_T("\\")); - _tcscat(szMoveSrc,_T("\\")); - nDirLevel++; - pszDestDirPointer = szMoveDest + _tcslen(szMoveDest); - pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc); - _tcscpy(pszSrcDirPointer,_T("*.*")); - hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer); - if (hDestFile == INVALID_HANDLE_VALUE) - { - FoundFile = FALSE; - continue; - } - FirstTime = TRUE; - } - } - } - } - } - if (MoveStatus) - ConOutResPrintf(STRING_MOVE_ERROR1); - else - ConOutResPrintf(STRING_MOVE_ERROR2); - } - while ((!OnlyOneFile || dwMoveStatusFlags & MOVE_SRC_CURRENT_IS_DIR ) && - !(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) && - FindNextFile (hFile, &findBuffer)); - FindClose (hFile); - - freep (arg); - return 0; + /* check for special cases "." and ".." and if found skip them */ + FoundFile = TRUE; + while(FoundFile && + (_tcscmp(findBuffer.cFileName,_T(".")) == 0 || + _tcscmp(findBuffer.cFileName,_T("..")) == 0)) + FoundFile = FindNextFile (hFile, &findBuffer); + + if (!FoundFile) + { + /* what? we don't have anything to move? */ + error_file_not_found(); + FindClose(hFile); + freep(arg); + return 1; + } + + OnlyOneFile = TRUE; + /* check if there can be found files as files have first priority */ + if (findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + dwMoveStatusFlags |= MOVE_SOURCE_IS_DIR; + else + dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE; + while(OnlyOneFile && FindNextFile(hFile,&findBuffer)) + { + if (!(findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + ConOutPrintf(_T("")); + if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) OnlyOneFile = FALSE; + else + { /* this has been done this way so that we don't disturb other settings if they have been set before this */ + dwMoveStatusFlags |= MOVE_SOURCE_IS_FILE; + dwMoveStatusFlags &= ~MOVE_SOURCE_IS_DIR; + } + } + } + FindClose(hFile); + + TRACE ("Do we have only one file: %s\n", OnlyOneFile ? "TRUE" : "FALSE"); + + /* we have to start again to be sure we don't miss any files or folders*/ + hFile = FindFirstFile (arg[i], &findBuffer); + if (hFile == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), arg[i]); + freep (arg); + return 1; + } + + /* check for special cases "." and ".." and if found skip them */ + FoundFile = TRUE; + while(FoundFile && + (_tcscmp(findBuffer.cFileName,_T(".")) == 0 || + _tcscmp(findBuffer.cFileName,_T("..")) == 0)) + FoundFile = FindNextFile (hFile, &findBuffer); + + if (!FoundFile) + { + /* huh? somebody removed files and/or folders which were there */ + error_file_not_found(); + FindClose(hFile); + freep(arg); + return 1; + } + + /* check if source and destination paths are on different volumes */ + if (szSrcDirPath[0] != szDestPath[0]) + dwMoveStatusFlags |= MOVE_PATHS_ON_DIF_VOL; + + /* move it */ + do + { + TRACE ("Found file/directory: %s\n", debugstr_aw(findBuffer.cFileName)); + nOverwrite = 1; + dwMoveFlags = 0; + dwMoveStatusFlags &= ~MOVE_DEST_IS_FILE & + ~MOVE_DEST_IS_DIR & + ~MOVE_SRC_CURRENT_IS_DIR & + ~MOVE_DEST_EXISTS; + _tcscpy(szFullSrcPath,szSrcDirPath); + if (szFullSrcPath[_tcslen(szFullSrcPath) - 1] != _T('\\')) + _tcscat (szFullSrcPath, _T("\\")); + _tcscat(szFullSrcPath,findBuffer.cFileName); + _tcscpy(szSrcPath, szFullSrcPath); + + if (IsExistingDirectory(szSrcPath)) + { + /* source is directory */ + if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) + { + dwMoveStatusFlags |= MOVE_SRC_CURRENT_IS_DIR; /* source is file but at the current round we found a directory */ + continue; + } + TRACE ("Source is dir: %s\n", debugstr_aw(szSrcPath)); + dwMoveFlags = MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; + } + + /* if source is file we don't need to do anything special */ + if (IsExistingDirectory(szDestPath)) + { + /* destination is existing directory */ + TRACE ("Destination is directory: %s\n", debugstr_aw(szDestPath)); + + dwMoveStatusFlags |= MOVE_DEST_IS_DIR; + + /*build the dest string(accounts for *)*/ + _tcscpy (szFullDestPath, szDestPath); + /*check to see if there is an ending slash, if not add one*/ + if (szFullDestPath[_tcslen(szFullDestPath) - 1] != _T('\\')) + _tcscat (szFullDestPath, _T("\\")); + _tcscat (szFullDestPath, findBuffer.cFileName); + + if (IsExistingFile(szFullDestPath) || IsExistingDirectory(szFullDestPath)) + dwMoveStatusFlags |= MOVE_DEST_EXISTS; + + dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; + } + if (IsExistingFile(szDestPath)) + { + /* destination is a file */ + TRACE ("Destination is file: %s\n", debugstr_aw(szDestPath)); + + dwMoveStatusFlags |= MOVE_DEST_IS_FILE | MOVE_DEST_EXISTS; + _tcscpy (szFullDestPath, szDestPath); + + dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; + } + + TRACE ("Move Status Flags: 0x%X\n",dwMoveStatusFlags); + + if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR && + dwMoveStatusFlags & MOVE_DEST_IS_DIR && + dwMoveStatusFlags & MOVE_SOURCE_HAS_WILD) + { + /* We are not allowed to have existing source and destination dir when there is wildcard in source */ + error_syntax(NULL); + FindClose(hFile); + freep(arg); + return 1; + } + if (!(dwMoveStatusFlags & (MOVE_DEST_IS_FILE | MOVE_DEST_IS_DIR))) + { + /* destination doesn't exist */ + _tcscpy (szFullDestPath, szDestPath); + if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE) dwMoveStatusFlags |= MOVE_DEST_IS_FILE; + if (dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) dwMoveStatusFlags |= MOVE_DEST_IS_DIR; + + dwMoveFlags |= MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | MOVEFILE_COPY_ALLOWED; + } + + if (dwMoveStatusFlags & MOVE_SOURCE_IS_FILE && + dwMoveStatusFlags & MOVE_DEST_IS_FILE && + !OnlyOneFile) + { + /*source has many files but there is only one destination file*/ + error_invalid_parameter_format(pszDest); + FindClose(hFile); + freep (arg); + return 1; + } + + /*checks to make sure user wanted/wants the override*/ + if ((dwFlags & MOVE_OVER_NO) && + (dwMoveStatusFlags & MOVE_DEST_EXISTS)) + continue; + if (!(dwFlags & MOVE_OVER_YES) && + (dwMoveStatusFlags & MOVE_DEST_EXISTS)) + nOverwrite = MoveOverwrite (szFullDestPath); + if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK) + continue; + if (nOverwrite == PROMPT_ALL) + dwFlags |= MOVE_OVER_YES; + + ConOutPrintf (_T("%s => %s "), szSrcPath, szFullDestPath); + + /* are we really supposed to do something */ + if (dwFlags & MOVE_NOTHING) + continue; + + /*move the file*/ + if (!(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR && + dwMoveStatusFlags & MOVE_PATHS_ON_DIF_VOL)) + /* we aren't moving source folder to different drive */ + MoveStatus = MoveFileEx (szSrcPath, szFullDestPath, dwMoveFlags); + else + { /* we are moving source folder to different drive */ + _tcscpy(szMoveDest, szFullDestPath); + _tcscpy(szMoveSrc, szSrcPath); + DeleteFile(szMoveDest); + MoveStatus = CreateDirectory(szMoveDest, NULL); /* we use default security settings */ + if (MoveStatus) + { + _tcscat(szMoveDest,_T("\\")); + _tcscat(szMoveSrc,_T("\\")); + nDirLevel = 0; + pszDestDirPointer = szMoveDest + _tcslen(szMoveDest); + pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc); + _tcscpy(pszSrcDirPointer,_T("*.*")); + hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer); + if (hDestFile == INVALID_HANDLE_VALUE) + MoveStatus = FALSE; + else + { + BOOL FirstTime = TRUE; + FoundFile = TRUE; + MoveStatus = FALSE; + while(FoundFile) + { + if (FirstTime) + FirstTime = FALSE; + else + FoundFile = FindNextFile (hDestFile, &findDestBuffer); + + if (!FoundFile) + { + /* Nothing to do in this folder so we stop working on it */ + FindClose(hDestFile); + (pszSrcDirPointer)--; + (pszDestDirPointer)--; + _tcscpy(pszSrcDirPointer,_T("")); + _tcscpy(pszDestDirPointer,_T("")); + if (nDirLevel > 0) + { + TCHAR szTempPath[MAX_PATH]; + INT_PTR nDiff; + + FoundFile = TRUE; /* we need to continue our seek for files */ + nDirLevel--; + RemoveDirectory(szMoveSrc); + GetDirectory(szMoveSrc,szTempPath,0); + nDiff = _tcslen(szMoveSrc) - _tcslen(szTempPath); + pszSrcDirPointer = pszSrcDirPointer - nDiff; + _tcscpy(pszSrcDirPointer,_T("")); + GetDirectory(szMoveDest,szTempPath,0); + nDiff = _tcslen(szMoveDest) - _tcslen(szTempPath); + pszDestDirPointer = pszDestDirPointer - nDiff; + _tcscpy(pszDestDirPointer,_T("")); + if (szMoveSrc[_tcslen(szMoveSrc) - 1] != _T('\\')) + _tcscat (szMoveSrc, _T("\\")); + if (szMoveDest[_tcslen(szMoveDest) - 1] != _T('\\')) + _tcscat (szMoveDest, _T("\\")); + pszDestDirPointer = szMoveDest + _tcslen(szMoveDest); + pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc); + _tcscpy(pszSrcDirPointer,_T("*.*")); + hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer); + if (hDestFile == INVALID_HANDLE_VALUE) + continue; + FirstTime = TRUE; + } + else + { + MoveStatus = TRUE; /* we moved everything so lets tell user about it */ + RemoveDirectory(szMoveSrc); + } + continue; + } + + /* if we find "." or ".." we'll skip them */ + if (_tcscmp(findDestBuffer.cFileName,_T(".")) == 0 || + _tcscmp(findDestBuffer.cFileName,_T("..")) == 0) + continue; + + _tcscpy(pszSrcDirPointer, findDestBuffer.cFileName); + _tcscpy(pszDestDirPointer, findDestBuffer.cFileName); + if (IsExistingFile(szMoveSrc)) + { + FoundFile = CopyFile(szMoveSrc, szMoveDest, FALSE); + if (!FoundFile) continue; + DeleteFile(szMoveSrc); + } + else + { + FindClose(hDestFile); + CreateDirectory(szMoveDest, NULL); + _tcscat(szMoveDest,_T("\\")); + _tcscat(szMoveSrc,_T("\\")); + nDirLevel++; + pszDestDirPointer = szMoveDest + _tcslen(szMoveDest); + pszSrcDirPointer = szMoveSrc + _tcslen(szMoveSrc); + _tcscpy(pszSrcDirPointer,_T("*.*")); + hDestFile = FindFirstFile(szMoveSrc, &findDestBuffer); + if (hDestFile == INVALID_HANDLE_VALUE) + { + FoundFile = FALSE; + continue; + } + FirstTime = TRUE; + } + } + } + } + } + if (MoveStatus) + ConOutResPrintf(STRING_MOVE_ERROR1); + else + ConOutResPrintf(STRING_MOVE_ERROR2); + } + while ((!OnlyOneFile || dwMoveStatusFlags & MOVE_SRC_CURRENT_IS_DIR ) && + !(dwMoveStatusFlags & MOVE_SOURCE_IS_DIR) && + FindNextFile (hFile, &findBuffer)); + FindClose (hFile); + + freep (arg); + return 0; } #endif /* INCLUDE_CMD_MOVE */ diff --git a/base/shell/cmd/msgbox.c b/base/shell/cmd/msgbox.c index 2e6dbd70480..2e790ad7855 100644 --- a/base/shell/cmd/msgbox.c +++ b/base/shell/cmd/msgbox.c @@ -6,8 +6,8 @@ * 25 Aug 1999 * started - Paolo Pantaleo * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -24,130 +24,128 @@ INT CommandMsgbox (LPTSTR param) { + //used to parse command line + LPTSTR tmp; - //used to parse command line - LPTSTR tmp; + //used to find window title (used as messagebox title) + //and to find window handle to pass to MessageBox + HWND hWnd; + TCHAR buff[128]; - //used to find window title (used as messagebox title) - //and to find window handle to pass to MessageBox - HWND hWnd; - TCHAR buff[128]; + //these are MessabeBox() parameters + LPTSTR title, prompt = ""; + UINT uType = U_TYPE_INIT; - //these are MessabeBox() parameters - LPTSTR title, prompt = ""; - UINT uType = U_TYPE_INIT; + /* set default title to window title */ + GetConsoleTitle(buff, 128); + title = buff; - /* set default title to window title */ - GetConsoleTitle(buff, 128); - title = buff; + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE,STRING_MSGBOX_HELP); + return 0; + } - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE,STRING_MSGBOX_HELP); - return 0; - } + //yes here things are quite massed up :) - //yes here things are quite massed up :) + //skip spaces + while(_istspace(*param)) + param++; - //skip spaces - while(_istspace(*param)) - param++; - - //search for type of messagebox (ok, okcancel, ...) - if (_tcsnicmp(param, _T("ok "), 3) == 0) - { - uType |= MB_ICONEXCLAMATION | MB_OK; - param += 3; - } - else if (_tcsnicmp(param, _T("okcancel "), 9) == 0) - { - uType |= MB_ICONQUESTION | MB_OKCANCEL; - param += 9; - } - else if (_tcsnicmp(param, _T("yesno "), 6) == 0) - { - uType |= MB_ICONQUESTION | MB_YESNO; - param += 6; - } - else if (_tcsnicmp(param, _T("yesnocancel "), 12) == 0) - { - uType |= MB_ICONQUESTION | MB_YESNOCANCEL; - param += 12; - } - else - { + //search for type of messagebox (ok, okcancel, ...) + if (_tcsnicmp(param, _T("ok "), 3) == 0) + { + uType |= MB_ICONEXCLAMATION | MB_OK; + param += 3; + } + else if (_tcsnicmp(param, _T("okcancel "), 9) == 0) + { + uType |= MB_ICONQUESTION | MB_OKCANCEL; + param += 9; + } + else if (_tcsnicmp(param, _T("yesno "), 6) == 0) + { + uType |= MB_ICONQUESTION | MB_YESNO; + param += 6; + } + else if (_tcsnicmp(param, _T("yesnocancel "), 12) == 0) + { + uType |= MB_ICONQUESTION | MB_YESNOCANCEL; + param += 12; + } + else + { #ifdef _SYNTAX_CHECK - error_req_param_missing (); - return 1; + error_req_param_missing (); + return 1; #else - uType |= MB_ICONEXCLAMATION | MB_OK; + uType |= MB_ICONEXCLAMATION | MB_OK; #endif - } + } - - //skip spaces - while(_istspace(*param)) - param++; + //skip spaces + while(_istspace(*param)) + param++; #ifdef _SYNTAX_CHECK - //if reached end of string - //it is an error becuase we do not yet have prompt - if (*param == 0) - { - error_req_param_missing (); - return 1; - } + //if reached end of string + //it is an error becuase we do not yet have prompt + if (*param == 0) + { + error_req_param_missing (); + return 1; + } #endif - //search for "title" - tmp = param; + //search for "title" + tmp = param; - if (*param == '"') - { - tmp = _tcschr(param + 1, '"'); - if (tmp) - { - *tmp = 0; - title = param + 1; - tmp++; - param = tmp; - } - } + if (*param == '"') + { + tmp = _tcschr(param + 1, '"'); + if (tmp) + { + *tmp = 0; + title = param + 1; + tmp++; + param = tmp; + } + } - //skip spaces - while(_istspace(*param)) - param++; + //skip spaces + while(_istspace(*param)) + param++; #ifdef _SYNTAX_CHECK - //get prompt - if (*param == 0) - { - error_req_param_missing (); - return 1; - } + //get prompt + if (*param == 0) + { + error_req_param_missing (); + return 1; + } #endif - prompt = param; + prompt = param; - hWnd=GetConsoleWindow (); + hWnd=GetConsoleWindow (); - switch (MessageBox(hWnd, prompt, title, uType)) - { - case IDYES: - case IDOK: - nErrorLevel = 10; - break; + switch (MessageBox(hWnd, prompt, title, uType)) + { + case IDYES: + case IDOK: + nErrorLevel = 10; + break; - case IDNO: - nErrorLevel = 11; - break; + case IDNO: + nErrorLevel = 11; + break; - case IDCANCEL: - nErrorLevel = 12; - break; - } + case IDCANCEL: + nErrorLevel = 12; + break; + } - return 0; + return 0; } #endif /* INCLUDE_CMD_MSGBOX */ diff --git a/base/shell/cmd/parser.c b/base/shell/cmd/parser.c index 8fa8f4da869..426c1ab11a7 100644 --- a/base/shell/cmd/parser.c +++ b/base/shell/cmd/parser.c @@ -1,6 +1,5 @@ /* * PARSER.C - command parsing. - * */ #include "precomp.h" @@ -11,19 +10,20 @@ static const TCHAR OpString[][3] = { _T("&"), _T("||"), _T("&&"), _T("|") }; static const TCHAR RedirString[][3] = { _T("<"), _T(">"), _T(">>") }; -static const TCHAR *const IfOperatorString[] = { - _T("cmdextversion"), - _T("defined"), - _T("errorlevel"), - _T("exist"), +static const TCHAR *const IfOperatorString[] = +{ + _T("cmdextversion"), + _T("defined"), + _T("errorlevel"), + _T("exist"), #define IF_MAX_UNARY IF_EXIST - _T("=="), - _T("equ"), - _T("gtr"), - _T("geq"), - _T("lss"), - _T("leq"), - _T("neq"), + _T("=="), + _T("equ"), + _T("gtr"), + _T("geq"), + _T("lss"), + _T("leq"), + _T("neq"), #define IF_MAX_COMPARISON IF_NEQ }; @@ -32,11 +32,18 @@ static const TCHAR *const IfOperatorString[] = { static BOOL IsSeparator(TCHAR Char) { - return _istspace(Char) || (Char && _tcschr(STANDARD_SEPS, Char)); + return _istspace(Char) || (Char && _tcschr(STANDARD_SEPS, Char)); } -enum { TOK_END, TOK_NORMAL, TOK_OPERATOR, TOK_REDIRECTION, - TOK_BEGIN_BLOCK, TOK_END_BLOCK }; +enum +{ + TOK_END, + TOK_NORMAL, + TOK_OPERATOR, + TOK_REDIRECTION, + TOK_BEGIN_BLOCK, + TOK_END_BLOCK +}; static BOOL bParseError; static BOOL bLineContinuations; @@ -50,227 +57,232 @@ static int InsideBlock; static TCHAR ParseChar() { - TCHAR Char; + TCHAR Char; - if (bParseError) - return CurChar = 0; + if (bParseError) + return CurChar = 0; restart: - /* Although CRs can be injected into a line via an environment - * variable substitution, the parser ignores them - they won't - * even separate tokens. */ - do - Char = *ParsePos++; - while (Char == _T('\r')); + /* + * Although CRs can be injected into a line via an environment + * variable substitution, the parser ignores them - they won't + * even separate tokens. + */ + do + Char = *ParsePos++; + while (Char == _T('\r')); - if (!Char) - { - ParsePos--; - if (bLineContinuations) - { - if (!ReadLine(ParseLine, TRUE)) - { - /* ^C pressed, or line was too long */ - bParseError = TRUE; - } - else if (*(ParsePos = ParseLine)) - { - goto restart; - } - } - } - return CurChar = Char; + if (!Char) + { + ParsePos--; + if (bLineContinuations) + { + if (!ReadLine(ParseLine, TRUE)) + { + /* ^C pressed, or line was too long */ + bParseError = TRUE; + } + else if (*(ParsePos = ParseLine)) + { + goto restart; + } + } + } + return CurChar = Char; } static void ParseError() { - error_syntax(CurrentTokenType != TOK_END ? CurrentToken : NULL); - bParseError = TRUE; + error_syntax(CurrentTokenType != TOK_END ? CurrentToken : NULL); + bParseError = TRUE; } -/* Yes, cmd has a Lexical Analyzer. Whenever the parser gives an "xxx was - * unexpected at this time." message, it shows what the last token read was */ +/* + * Yes, cmd has a Lexical Analyzer. Whenever the parser gives an "xxx was + * unexpected at this time." message, it shows what the last token read was. + */ static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators) { - TCHAR *Out = CurrentToken; - TCHAR Char; - int Type; - BOOL bInQuote = FALSE; + TCHAR *Out = CurrentToken; + TCHAR Char; + int Type; + BOOL bInQuote = FALSE; - for (Char = CurChar; Char && Char != _T('\n'); Char = ParseChar()) - { - bInQuote ^= (Char == _T('"')); - if (!bInQuote) - { - if (Separators != NULL) - { - if (_istspace(Char) || _tcschr(Separators, Char)) - { - /* Skip leading separators */ - if (Out == CurrentToken) - continue; - break; - } - } - - /* Check for numbered redirection */ - if ((Char >= _T('0') && Char <= _T('9') && - (ParsePos == &ParseLine[1] || IsSeparator(ParsePos[-2])) - && (*ParsePos == _T('<') || *ParsePos == _T('>')))) - { - break; - } + for (Char = CurChar; Char && Char != _T('\n'); Char = ParseChar()) + { + bInQuote ^= (Char == _T('"')); + if (!bInQuote) + { + if (Separators != NULL) + { + if (_istspace(Char) || _tcschr(Separators, Char)) + { + /* Skip leading separators */ + if (Out == CurrentToken) + continue; + break; + } + } - if (Char == ExtraEnd) - break; - if (InsideBlock && Char == _T(')')) - break; - if (_tcschr(_T("&|<>"), Char)) - break; + /* Check for numbered redirection */ + if ((Char >= _T('0') && Char <= _T('9') && + (ParsePos == &ParseLine[1] || IsSeparator(ParsePos[-2])) + && (*ParsePos == _T('<') || *ParsePos == _T('>')))) + { + break; + } - if (Char == _T('^')) - { - Char = ParseChar(); - /* Eat up a \n, allowing line continuation */ - if (Char == _T('\n')) - Char = ParseChar(); - /* Next character is a forced literal */ - } - } - if (Out == &CurrentToken[CMDLINE_LENGTH - 1]) - break; - *Out++ = Char; - } + if (Char == ExtraEnd) + break; + if (InsideBlock && Char == _T(')')) + break; + if (_tcschr(_T("&|<>"), Char)) + break; - /* Check if we got at least one character before reaching a special one. - * If so, return them and leave the special for the next call. */ - if (Out != CurrentToken) - { - Type = TOK_NORMAL; - } - else if (Char == _T('(')) - { - Type = TOK_BEGIN_BLOCK; - *Out++ = Char; - ParseChar(); - } - else if (Char == _T(')')) - { - Type = TOK_END_BLOCK; - *Out++ = Char; - ParseChar(); - } - else if (Char == _T('&') || Char == _T('|')) - { - Type = TOK_OPERATOR; - *Out++ = Char; - Char = ParseChar(); - /* check for && or || */ - if (Char == Out[-1]) - { - *Out++ = Char; - ParseChar(); - } - } - else if ((Char >= _T('0') && Char <= _T('9')) - || (Char == _T('<') || Char == _T('>'))) - { - Type = TOK_REDIRECTION; - if (Char >= _T('0') && Char <= _T('9')) - { - *Out++ = Char; - Char = ParseChar(); - } - *Out++ = Char; - Char = ParseChar(); - if (Char == Out[-1]) - { - /* Strangely, the tokenizer allows << as well as >>... (it - * will cause an error when trying to parse it though) */ - *Out++ = Char; - Char = ParseChar(); - } - if (Char == _T('&')) - { - *Out++ = Char; - while (IsSeparator(Char = ParseChar())) - ; - if (Char >= _T('0') && Char <= _T('9')) - { - *Out++ = Char; - ParseChar(); - } - } - } - else - { - Type = TOK_END; - } - *Out = _T('\0'); - return CurrentTokenType = Type; + if (Char == _T('^')) + { + Char = ParseChar(); + /* Eat up a \n, allowing line continuation */ + if (Char == _T('\n')) + Char = ParseChar(); + /* Next character is a forced literal */ + } + } + if (Out == &CurrentToken[CMDLINE_LENGTH - 1]) + break; + *Out++ = Char; + } + + /* Check if we got at least one character before reaching a special one. + * If so, return them and leave the special for the next call. */ + if (Out != CurrentToken) + { + Type = TOK_NORMAL; + } + else if (Char == _T('(')) + { + Type = TOK_BEGIN_BLOCK; + *Out++ = Char; + ParseChar(); + } + else if (Char == _T(')')) + { + Type = TOK_END_BLOCK; + *Out++ = Char; + ParseChar(); + } + else if (Char == _T('&') || Char == _T('|')) + { + Type = TOK_OPERATOR; + *Out++ = Char; + Char = ParseChar(); + /* check for && or || */ + if (Char == Out[-1]) + { + *Out++ = Char; + ParseChar(); + } + } + else if ((Char >= _T('0') && Char <= _T('9')) + || (Char == _T('<') || Char == _T('>'))) + { + Type = TOK_REDIRECTION; + if (Char >= _T('0') && Char <= _T('9')) + { + *Out++ = Char; + Char = ParseChar(); + } + *Out++ = Char; + Char = ParseChar(); + if (Char == Out[-1]) + { + /* Strangely, the tokenizer allows << as well as >>... (it + * will cause an error when trying to parse it though) */ + *Out++ = Char; + Char = ParseChar(); + } + if (Char == _T('&')) + { + *Out++ = Char; + while (IsSeparator(Char = ParseChar())) + ; + if (Char >= _T('0') && Char <= _T('9')) + { + *Out++ = Char; + ParseChar(); + } + } + } + else + { + Type = TOK_END; + } + *Out = _T('\0'); + return CurrentTokenType = Type; } static BOOL ParseRedirection(REDIRECTION **List) { - TCHAR *Tok = CurrentToken; - BYTE Number; - REDIR_MODE RedirMode; - REDIRECTION *Redir; + TCHAR *Tok = CurrentToken; + BYTE Number; + REDIR_MODE RedirMode; + REDIRECTION *Redir; - if (*Tok >= _T('0') && *Tok <= _T('9')) - Number = *Tok++ - _T('0'); - else - Number = *Tok == _T('<') ? 0 : 1; + if (*Tok >= _T('0') && *Tok <= _T('9')) + Number = *Tok++ - _T('0'); + else + Number = *Tok == _T('<') ? 0 : 1; - if (*Tok++ == _T('<')) - { - RedirMode = REDIR_READ; - if (*Tok == _T('<')) - goto fail; - } - else - { - RedirMode = REDIR_WRITE; - if (*Tok == _T('>')) - { - RedirMode = REDIR_APPEND; - Tok++; - } - } + if (*Tok++ == _T('<')) + { + RedirMode = REDIR_READ; + if (*Tok == _T('<')) + goto fail; + } + else + { + RedirMode = REDIR_WRITE; + if (*Tok == _T('>')) + { + RedirMode = REDIR_APPEND; + Tok++; + } + } - if (!*Tok) - { - /* The file name was not part of this token, so it'll be the next one */ - if (ParseToken(0, STANDARD_SEPS) != TOK_NORMAL) - goto fail; - Tok = CurrentToken; - } + if (!*Tok) + { + /* The file name was not part of this token, so it'll be the next one */ + if (ParseToken(0, STANDARD_SEPS) != TOK_NORMAL) + goto fail; + Tok = CurrentToken; + } - /* If a redirection for this handle number already exists, delete it */ - while ((Redir = *List)) - { - if (Redir->Number == Number) - { - *List = Redir->Next; - cmd_free(Redir); - continue; - } - List = &Redir->Next; - } + /* If a redirection for this handle number already exists, delete it */ + while ((Redir = *List)) + { + if (Redir->Number == Number) + { + *List = Redir->Next; + cmd_free(Redir); + continue; + } + List = &Redir->Next; + } + + Redir = cmd_alloc(FIELD_OFFSET(REDIRECTION, Filename[_tcslen(Tok) + 1])); + Redir->Next = NULL; + Redir->OldHandle = INVALID_HANDLE_VALUE; + Redir->Number = Number; + Redir->Mode = RedirMode; + _tcscpy(Redir->Filename, Tok); + *List = Redir; + return TRUE; - Redir = cmd_alloc(FIELD_OFFSET(REDIRECTION, Filename[_tcslen(Tok) + 1])); - Redir->Next = NULL; - Redir->OldHandle = INVALID_HANDLE_VALUE; - Redir->Number = Number; - Redir->Mode = RedirMode; - _tcscpy(Redir->Filename, Tok); - *List = Redir; - return TRUE; fail: - ParseError(); - FreeRedirection(*List); - *List = NULL; - return FALSE; + ParseError(); + FreeRedirection(*List); + *List = NULL; + return FALSE; } static PARSED_COMMAND *ParseCommandOp(int OpType); @@ -278,666 +290,674 @@ static PARSED_COMMAND *ParseCommandOp(int OpType); /* Parse a parenthesized block */ static PARSED_COMMAND *ParseBlock(REDIRECTION *RedirList) { - PARSED_COMMAND *Cmd, *Sub, **NextPtr; - Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); - Cmd->Type = C_BLOCK; - Cmd->Next = NULL; - Cmd->Subcommands = NULL; - Cmd->Redirections = RedirList; + PARSED_COMMAND *Cmd, *Sub, **NextPtr; + Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); + Cmd->Type = C_BLOCK; + Cmd->Next = NULL; + Cmd->Subcommands = NULL; + Cmd->Redirections = RedirList; - /* Read the block contents */ - NextPtr = &Cmd->Subcommands; - InsideBlock++; - while (1) - { - Sub = ParseCommandOp(C_OP_LOWEST); - if (Sub) - { - *NextPtr = Sub; - NextPtr = &Sub->Next; - } - else if (bParseError) - { - InsideBlock--; - FreeCommand(Cmd); - return NULL; - } + /* Read the block contents */ + NextPtr = &Cmd->Subcommands; + InsideBlock++; + while (1) + { + Sub = ParseCommandOp(C_OP_LOWEST); + if (Sub) + { + *NextPtr = Sub; + NextPtr = &Sub->Next; + } + else if (bParseError) + { + InsideBlock--; + FreeCommand(Cmd); + return NULL; + } - if (CurrentTokenType == TOK_END_BLOCK) - break; - /* Skip past the \n */ - ParseChar(); - } - InsideBlock--; + if (CurrentTokenType == TOK_END_BLOCK) + break; + /* Skip past the \n */ + ParseChar(); + } + InsideBlock--; - /* Process any trailing redirections */ - while (ParseToken(0, STANDARD_SEPS) == TOK_REDIRECTION) - { - if (!ParseRedirection(&Cmd->Redirections)) - { - FreeCommand(Cmd); - return NULL; - } - } - return Cmd; + /* Process any trailing redirections */ + while (ParseToken(0, STANDARD_SEPS) == TOK_REDIRECTION) + { + if (!ParseRedirection(&Cmd->Redirections)) + { + FreeCommand(Cmd); + return NULL; + } + } + return Cmd; } /* Parse an IF statement */ static PARSED_COMMAND *ParseIf(void) { - PARSED_COMMAND *Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); - int Type; - memset(Cmd, 0, sizeof(PARSED_COMMAND)); - Cmd->Type = C_IF; + PARSED_COMMAND *Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); + int Type; + memset(Cmd, 0, sizeof(PARSED_COMMAND)); + Cmd->Type = C_IF; - Type = CurrentTokenType; - if (_tcsicmp(CurrentToken, _T("/I")) == 0) - { - Cmd->If.Flags |= IFFLAG_IGNORECASE; - Type = ParseToken(0, STANDARD_SEPS); - } - if (_tcsicmp(CurrentToken, _T("not")) == 0) - { - Cmd->If.Flags |= IFFLAG_NEGATE; - Type = ParseToken(0, STANDARD_SEPS); - } + Type = CurrentTokenType; + if (_tcsicmp(CurrentToken, _T("/I")) == 0) + { + Cmd->If.Flags |= IFFLAG_IGNORECASE; + Type = ParseToken(0, STANDARD_SEPS); + } + if (_tcsicmp(CurrentToken, _T("not")) == 0) + { + Cmd->If.Flags |= IFFLAG_NEGATE; + Type = ParseToken(0, STANDARD_SEPS); + } - if (Type != TOK_NORMAL) - { - FreeCommand(Cmd); - ParseError(); - return NULL; - } + if (Type != TOK_NORMAL) + { + FreeCommand(Cmd); + ParseError(); + return NULL; + } - /* Check for unary operators */ - for (; Cmd->If.Operator <= IF_MAX_UNARY; Cmd->If.Operator++) - { - if (_tcsicmp(CurrentToken, IfOperatorString[Cmd->If.Operator]) == 0) - { - if (ParseToken(0, STANDARD_SEPS) != TOK_NORMAL) - { - FreeCommand(Cmd); - ParseError(); - return NULL; - } - Cmd->If.RightArg = cmd_dup(CurrentToken); - goto condition_done; - } - } + /* Check for unary operators */ + for (; Cmd->If.Operator <= IF_MAX_UNARY; Cmd->If.Operator++) + { + if (_tcsicmp(CurrentToken, IfOperatorString[Cmd->If.Operator]) == 0) + { + if (ParseToken(0, STANDARD_SEPS) != TOK_NORMAL) + { + FreeCommand(Cmd); + ParseError(); + return NULL; + } + Cmd->If.RightArg = cmd_dup(CurrentToken); + goto condition_done; + } + } - /* It must be a two-argument (comparison) operator. It could be ==, so - * the equals sign can't be treated as whitespace here. */ - Cmd->If.LeftArg = cmd_dup(CurrentToken); - ParseToken(0, _T(",;")); + /* It must be a two-argument (comparison) operator. It could be ==, so + * the equals sign can't be treated as whitespace here. */ + Cmd->If.LeftArg = cmd_dup(CurrentToken); + ParseToken(0, _T(",;")); - /* The right argument can come immediately after == */ - if (_tcsnicmp(CurrentToken, _T("=="), 2) == 0 && CurrentToken[2]) - { - Cmd->If.RightArg = cmd_dup(&CurrentToken[2]); - goto condition_done; - } + /* The right argument can come immediately after == */ + if (_tcsnicmp(CurrentToken, _T("=="), 2) == 0 && CurrentToken[2]) + { + Cmd->If.RightArg = cmd_dup(&CurrentToken[2]); + goto condition_done; + } - for (; Cmd->If.Operator <= IF_MAX_COMPARISON; Cmd->If.Operator++) - { - if (_tcsicmp(CurrentToken, IfOperatorString[Cmd->If.Operator]) == 0) - { - if (ParseToken(0, STANDARD_SEPS) != TOK_NORMAL) - break; - Cmd->If.RightArg = cmd_dup(CurrentToken); - goto condition_done; - } - } - FreeCommand(Cmd); - ParseError(); - return NULL; + for (; Cmd->If.Operator <= IF_MAX_COMPARISON; Cmd->If.Operator++) + { + if (_tcsicmp(CurrentToken, IfOperatorString[Cmd->If.Operator]) == 0) + { + if (ParseToken(0, STANDARD_SEPS) != TOK_NORMAL) + break; + Cmd->If.RightArg = cmd_dup(CurrentToken); + goto condition_done; + } + } + FreeCommand(Cmd); + ParseError(); + return NULL; condition_done: - Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST); - if (Cmd->Subcommands == NULL) - { - FreeCommand(Cmd); - return NULL; - } - if (_tcsicmp(CurrentToken, _T("else")) == 0) - { - Cmd->Subcommands->Next = ParseCommandOp(C_OP_LOWEST); - if (Cmd->Subcommands->Next == NULL) - { - FreeCommand(Cmd); - return NULL; - } - } + Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST); + if (Cmd->Subcommands == NULL) + { + FreeCommand(Cmd); + return NULL; + } + if (_tcsicmp(CurrentToken, _T("else")) == 0) + { + Cmd->Subcommands->Next = ParseCommandOp(C_OP_LOWEST); + if (Cmd->Subcommands->Next == NULL) + { + FreeCommand(Cmd); + return NULL; + } + } - return Cmd; + return Cmd; } -/* Parse a FOR command. - * Syntax is: FOR [options] %var IN (list) DO command */ +/* + * Parse a FOR command. + * Syntax is: FOR [options] %var IN (list) DO command + */ static PARSED_COMMAND *ParseFor(void) { - PARSED_COMMAND *Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); - TCHAR List[CMDLINE_LENGTH]; - TCHAR *Pos = List; + PARSED_COMMAND *Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); + TCHAR List[CMDLINE_LENGTH]; + TCHAR *Pos = List; - memset(Cmd, 0, sizeof(PARSED_COMMAND)); - Cmd->Type = C_FOR; + memset(Cmd, 0, sizeof(PARSED_COMMAND)); + Cmd->Type = C_FOR; - while (1) - { - if (_tcsicmp(CurrentToken, _T("/D")) == 0) - Cmd->For.Switches |= FOR_DIRS; - else if (_tcsicmp(CurrentToken, _T("/F")) == 0) - { - Cmd->For.Switches |= FOR_F; - if (!Cmd->For.Params) - { - ParseToken(0, STANDARD_SEPS); - if (CurrentToken[0] == _T('/') || CurrentToken[0] == _T('%')) - break; - Cmd->For.Params = cmd_dup(CurrentToken); - } - } - else if (_tcsicmp(CurrentToken, _T("/L")) == 0) - Cmd->For.Switches |= FOR_LOOP; - else if (_tcsicmp(CurrentToken, _T("/R")) == 0) - { - Cmd->For.Switches |= FOR_RECURSIVE; - if (!Cmd->For.Params) - { - ParseToken(0, STANDARD_SEPS); - if (CurrentToken[0] == _T('/') || CurrentToken[0] == _T('%')) - break; - StripQuotes(CurrentToken); - Cmd->For.Params = cmd_dup(CurrentToken); - } - } - else - break; - ParseToken(0, STANDARD_SEPS); - } + while (1) + { + if (_tcsicmp(CurrentToken, _T("/D")) == 0) + Cmd->For.Switches |= FOR_DIRS; + else if (_tcsicmp(CurrentToken, _T("/F")) == 0) + { + Cmd->For.Switches |= FOR_F; + if (!Cmd->For.Params) + { + ParseToken(0, STANDARD_SEPS); + if (CurrentToken[0] == _T('/') || CurrentToken[0] == _T('%')) + break; + Cmd->For.Params = cmd_dup(CurrentToken); + } + } + else if (_tcsicmp(CurrentToken, _T("/L")) == 0) + Cmd->For.Switches |= FOR_LOOP; + else if (_tcsicmp(CurrentToken, _T("/R")) == 0) + { + Cmd->For.Switches |= FOR_RECURSIVE; + if (!Cmd->For.Params) + { + ParseToken(0, STANDARD_SEPS); + if (CurrentToken[0] == _T('/') || CurrentToken[0] == _T('%')) + break; + StripQuotes(CurrentToken); + Cmd->For.Params = cmd_dup(CurrentToken); + } + } + else + break; + ParseToken(0, STANDARD_SEPS); + } - /* Make sure there aren't two different switches specified - * at the same time, unless they're /D and /R */ - if ((Cmd->For.Switches & (Cmd->For.Switches - 1)) != 0 - && Cmd->For.Switches != (FOR_DIRS | FOR_RECURSIVE)) - { - goto error; - } + /* Make sure there aren't two different switches specified + * at the same time, unless they're /D and /R */ + if ((Cmd->For.Switches & (Cmd->For.Switches - 1)) != 0 + && Cmd->For.Switches != (FOR_DIRS | FOR_RECURSIVE)) + { + goto error; + } - /* Variable name should be % and just one other character */ - if (CurrentToken[0] != _T('%') || _tcslen(CurrentToken) != 2) - goto error; - Cmd->For.Variable = CurrentToken[1]; + /* Variable name should be % and just one other character */ + if (CurrentToken[0] != _T('%') || _tcslen(CurrentToken) != 2) + goto error; + Cmd->For.Variable = CurrentToken[1]; - ParseToken(0, STANDARD_SEPS); - if (_tcsicmp(CurrentToken, _T("in")) != 0) - goto error; + ParseToken(0, STANDARD_SEPS); + if (_tcsicmp(CurrentToken, _T("in")) != 0) + goto error; - if (ParseToken(_T('('), STANDARD_SEPS) != TOK_BEGIN_BLOCK) - goto error; + if (ParseToken(_T('('), STANDARD_SEPS) != TOK_BEGIN_BLOCK) + goto error; - while (1) - { - int Type; + while (1) + { + int Type; - /* Pretend we're inside a block so the tokenizer will stop on ')' */ - InsideBlock++; - Type = ParseToken(0, STANDARD_SEPS); - InsideBlock--; + /* Pretend we're inside a block so the tokenizer will stop on ')' */ + InsideBlock++; + Type = ParseToken(0, STANDARD_SEPS); + InsideBlock--; - if (Type == TOK_END_BLOCK) - break; + if (Type == TOK_END_BLOCK) + break; - if (Type != TOK_NORMAL) - goto error; + if (Type != TOK_NORMAL) + goto error; - if (Pos != List) - *Pos++ = _T(' '); + if (Pos != List) + *Pos++ = _T(' '); - if (Pos + _tcslen(CurrentToken) >= &List[CMDLINE_LENGTH]) - goto error; - Pos = _stpcpy(Pos, CurrentToken); - } - *Pos = _T('\0'); - Cmd->For.List = cmd_dup(List); + if (Pos + _tcslen(CurrentToken) >= &List[CMDLINE_LENGTH]) + goto error; + Pos = _stpcpy(Pos, CurrentToken); + } + *Pos = _T('\0'); + Cmd->For.List = cmd_dup(List); - ParseToken(0, STANDARD_SEPS); - if (_tcsicmp(CurrentToken, _T("do")) != 0) - goto error; + ParseToken(0, STANDARD_SEPS); + if (_tcsicmp(CurrentToken, _T("do")) != 0) + goto error; - Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST); - if (Cmd->Subcommands == NULL) - { - FreeCommand(Cmd); - return NULL; - } + Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST); + if (Cmd->Subcommands == NULL) + { + FreeCommand(Cmd); + return NULL; + } - return Cmd; + return Cmd; error: - FreeCommand(Cmd); - ParseError(); - return NULL; + FreeCommand(Cmd); + ParseError(); + return NULL; } /* Parse a REM command */ static PARSED_COMMAND *ParseRem(void) { - /* Just ignore the rest of the line */ - while (CurChar && CurChar != _T('\n')) - ParseChar(); - return NULL; + /* Just ignore the rest of the line */ + while (CurChar && CurChar != _T('\n')) + ParseChar(); + return NULL; } static DECLSPEC_NOINLINE PARSED_COMMAND *ParseCommandPart(REDIRECTION *RedirList) { - TCHAR ParsedLine[CMDLINE_LENGTH]; - PARSED_COMMAND *Cmd; - PARSED_COMMAND *(*Func)(void); + TCHAR ParsedLine[CMDLINE_LENGTH]; + PARSED_COMMAND *Cmd; + PARSED_COMMAND *(*Func)(void); - TCHAR *Pos = _stpcpy(ParsedLine, CurrentToken) + 1; - DWORD_PTR TailOffset = Pos - ParsedLine; + TCHAR *Pos = _stpcpy(ParsedLine, CurrentToken) + 1; + DWORD_PTR TailOffset = Pos - ParsedLine; - /* Check for special forms */ - if ((Func = ParseFor, _tcsicmp(ParsedLine, _T("for")) == 0) || - (Func = ParseIf, _tcsicmp(ParsedLine, _T("if")) == 0) || - (Func = ParseRem, _tcsicmp(ParsedLine, _T("rem")) == 0)) - { - ParseToken(0, STANDARD_SEPS); - /* Do special parsing only if it's not followed by /? */ - if (_tcscmp(CurrentToken, _T("/?")) != 0) - { - if (RedirList) - { - ParseError(); - FreeRedirection(RedirList); - return NULL; - } - return Func(); - } - Pos = _stpcpy(Pos, _T(" /?")); - } + /* Check for special forms */ + if ((Func = ParseFor, _tcsicmp(ParsedLine, _T("for")) == 0) || + (Func = ParseIf, _tcsicmp(ParsedLine, _T("if")) == 0) || + (Func = ParseRem, _tcsicmp(ParsedLine, _T("rem")) == 0)) + { + ParseToken(0, STANDARD_SEPS); + /* Do special parsing only if it's not followed by /? */ + if (_tcscmp(CurrentToken, _T("/?")) != 0) + { + if (RedirList) + { + ParseError(); + FreeRedirection(RedirList); + return NULL; + } + return Func(); + } + Pos = _stpcpy(Pos, _T(" /?")); + } - /* Now get the tail */ - while (1) - { - int Type = ParseToken(0, NULL); - if (Type == TOK_NORMAL) - { - if (Pos + _tcslen(CurrentToken) >= &ParsedLine[CMDLINE_LENGTH]) - { - ParseError(); - FreeRedirection(RedirList); - return NULL; - } - Pos = _stpcpy(Pos, CurrentToken); - } - else if (Type == TOK_REDIRECTION) - { - if (!ParseRedirection(&RedirList)) - return NULL; - } - else - { - break; - } - } - *Pos++ = _T('\0'); + /* Now get the tail */ + while (1) + { + int Type = ParseToken(0, NULL); + if (Type == TOK_NORMAL) + { + if (Pos + _tcslen(CurrentToken) >= &ParsedLine[CMDLINE_LENGTH]) + { + ParseError(); + FreeRedirection(RedirList); + return NULL; + } + Pos = _stpcpy(Pos, CurrentToken); + } + else if (Type == TOK_REDIRECTION) + { + if (!ParseRedirection(&RedirList)) + return NULL; + } + else + { + break; + } + } + *Pos++ = _T('\0'); - Cmd = cmd_alloc(FIELD_OFFSET(PARSED_COMMAND, Command.First[Pos - ParsedLine])); - Cmd->Type = C_COMMAND; - Cmd->Next = NULL; - Cmd->Subcommands = NULL; - Cmd->Redirections = RedirList; - memcpy(Cmd->Command.First, ParsedLine, (Pos - ParsedLine) * sizeof(TCHAR)); - Cmd->Command.Rest = Cmd->Command.First + TailOffset; - return Cmd; + Cmd = cmd_alloc(FIELD_OFFSET(PARSED_COMMAND, Command.First[Pos - ParsedLine])); + Cmd->Type = C_COMMAND; + Cmd->Next = NULL; + Cmd->Subcommands = NULL; + Cmd->Redirections = RedirList; + memcpy(Cmd->Command.First, ParsedLine, (Pos - ParsedLine) * sizeof(TCHAR)); + Cmd->Command.Rest = Cmd->Command.First + TailOffset; + return Cmd; } static PARSED_COMMAND *ParsePrimary(void) { - REDIRECTION *RedirList = NULL; - int Type; + REDIRECTION *RedirList = NULL; + int Type; - while (IsSeparator(CurChar)) - { - if (CurChar == _T('\n')) - return NULL; - ParseChar(); - } + while (IsSeparator(CurChar)) + { + if (CurChar == _T('\n')) + return NULL; + ParseChar(); + } - if (!CurChar) - return NULL; + if (!CurChar) + return NULL; - if (CurChar == _T(':')) - { - /* "Ignore" the rest of the line. - * (Line continuations will still be parsed, though.) */ - while (ParseToken(0, NULL) != TOK_END) - ; - return NULL; - } + if (CurChar == _T(':')) + { + /* "Ignore" the rest of the line. + * (Line continuations will still be parsed, though.) */ + while (ParseToken(0, NULL) != TOK_END) + ; + return NULL; + } - if (CurChar == _T('@')) - { - PARSED_COMMAND *Cmd; - ParseChar(); - Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); - Cmd->Type = C_QUIET; - Cmd->Next = NULL; - /* @ acts like a unary operator with low precedence, - * so call the top-level parser */ - Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST); - Cmd->Redirections = NULL; - return Cmd; - } + if (CurChar == _T('@')) + { + PARSED_COMMAND *Cmd; + ParseChar(); + Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); + Cmd->Type = C_QUIET; + Cmd->Next = NULL; + /* @ acts like a unary operator with low precedence, + * so call the top-level parser */ + Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST); + Cmd->Redirections = NULL; + return Cmd; + } - /* Process leading redirections and get the head of the command */ - while ((Type = ParseToken(_T('('), STANDARD_SEPS)) == TOK_REDIRECTION) - { - if (!ParseRedirection(&RedirList)) - return NULL; - } + /* Process leading redirections and get the head of the command */ + while ((Type = ParseToken(_T('('), STANDARD_SEPS)) == TOK_REDIRECTION) + { + if (!ParseRedirection(&RedirList)) + return NULL; + } - if (Type == TOK_NORMAL) - return ParseCommandPart(RedirList); - else if (Type == TOK_BEGIN_BLOCK) - return ParseBlock(RedirList); - else if (Type == TOK_END_BLOCK && !RedirList) - return NULL; + if (Type == TOK_NORMAL) + return ParseCommandPart(RedirList); + else if (Type == TOK_BEGIN_BLOCK) + return ParseBlock(RedirList); + else if (Type == TOK_END_BLOCK && !RedirList) + return NULL; - ParseError(); - FreeRedirection(RedirList); - return NULL; + ParseError(); + FreeRedirection(RedirList); + return NULL; } static PARSED_COMMAND *ParseCommandOp(int OpType) { - PARSED_COMMAND *Cmd, *Left, *Right; + PARSED_COMMAND *Cmd, *Left, *Right; - if (OpType == C_OP_HIGHEST) - Cmd = ParsePrimary(); - else - Cmd = ParseCommandOp(OpType + 1); + if (OpType == C_OP_HIGHEST) + Cmd = ParsePrimary(); + else + Cmd = ParseCommandOp(OpType + 1); - if (Cmd && !_tcscmp(CurrentToken, OpString[OpType - C_OP_LOWEST])) - { - Left = Cmd; - Right = ParseCommandOp(OpType); - if (!Right) - { - if (!bParseError) - { - /* & is allowed to have an empty RHS */ - if (OpType == C_MULTI) - return Left; - ParseError(); - } - FreeCommand(Left); - return NULL; - } + if (Cmd && !_tcscmp(CurrentToken, OpString[OpType - C_OP_LOWEST])) + { + Left = Cmd; + Right = ParseCommandOp(OpType); + if (!Right) + { + if (!bParseError) + { + /* & is allowed to have an empty RHS */ + if (OpType == C_MULTI) + return Left; + ParseError(); + } + FreeCommand(Left); + return NULL; + } - Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); - Cmd->Type = OpType; - Cmd->Next = NULL; - Cmd->Redirections = NULL; - Cmd->Subcommands = Left; - Left->Next = Right; - Right->Next = NULL; - } + Cmd = cmd_alloc(sizeof(PARSED_COMMAND)); + Cmd->Type = OpType; + Cmd->Next = NULL; + Cmd->Redirections = NULL; + Cmd->Subcommands = Left; + Left->Next = Right; + Right->Next = NULL; + } - return Cmd; + return Cmd; } PARSED_COMMAND * ParseCommand(LPTSTR Line) { - PARSED_COMMAND *Cmd; + PARSED_COMMAND *Cmd; - if (Line) - { - if (!SubstituteVars(Line, ParseLine, _T('%'))) - return NULL; - bLineContinuations = FALSE; - } - else - { - if (!ReadLine(ParseLine, FALSE)) - return NULL; - bLineContinuations = TRUE; - } - bParseError = FALSE; - ParsePos = ParseLine; - CurChar = _T(' '); + if (Line) + { + if (!SubstituteVars(Line, ParseLine, _T('%'))) + return NULL; + bLineContinuations = FALSE; + } + else + { + if (!ReadLine(ParseLine, FALSE)) + return NULL; + bLineContinuations = TRUE; + } + bParseError = FALSE; + ParsePos = ParseLine; + CurChar = _T(' '); - Cmd = ParseCommandOp(C_OP_LOWEST); - if (Cmd) - { - if (CurrentTokenType != TOK_END) - ParseError(); - if (bParseError) - { - FreeCommand(Cmd); - Cmd = NULL; - } - bIgnoreEcho = FALSE; - } - else - { - bIgnoreEcho = TRUE; - } - return Cmd; + Cmd = ParseCommandOp(C_OP_LOWEST); + if (Cmd) + { + if (CurrentTokenType != TOK_END) + ParseError(); + if (bParseError) + { + FreeCommand(Cmd); + Cmd = NULL; + } + bIgnoreEcho = FALSE; + } + else + { + bIgnoreEcho = TRUE; + } + return Cmd; } -/* Reconstruct a parse tree into text form; used for echoing - * batch file commands and FOR instances. */ +/* + * Reconstruct a parse tree into text form; used for echoing + * batch file commands and FOR instances. + */ VOID EchoCommand(PARSED_COMMAND *Cmd) { - TCHAR Buf[CMDLINE_LENGTH]; - PARSED_COMMAND *Sub; - REDIRECTION *Redir; + TCHAR Buf[CMDLINE_LENGTH]; + PARSED_COMMAND *Sub; + REDIRECTION *Redir; - switch (Cmd->Type) - { - case C_COMMAND: - if (SubstituteForVars(Cmd->Command.First, Buf)) - ConOutPrintf(_T("%s"), Buf); - if (SubstituteForVars(Cmd->Command.Rest, Buf)) - ConOutPrintf(_T("%s"), Buf); - break; - case C_QUIET: - return; - case C_BLOCK: - ConOutChar(_T('(')); - Sub = Cmd->Subcommands; - if (Sub && !Sub->Next) - { - /* Single-command block: display all on one line */ - EchoCommand(Sub); - } - else if (Sub) - { - /* Multi-command block: display parenthesis on separate lines */ - ConOutChar(_T('\n')); - do - { - EchoCommand(Sub); - ConOutChar(_T('\n')); - Sub = Sub->Next; - } while (Sub); - } - ConOutChar(_T(')')); - break; - case C_MULTI: - case C_IFFAILURE: - case C_IFSUCCESS: - case C_PIPE: - Sub = Cmd->Subcommands; - EchoCommand(Sub); - ConOutPrintf(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST]); - EchoCommand(Sub->Next); - break; - case C_IF: - ConOutPrintf(_T("if")); - if (Cmd->If.Flags & IFFLAG_IGNORECASE) - ConOutPrintf(_T(" /I")); - if (Cmd->If.Flags & IFFLAG_NEGATE) - ConOutPrintf(_T(" not")); - if (Cmd->If.LeftArg && SubstituteForVars(Cmd->If.LeftArg, Buf)) - ConOutPrintf(_T(" %s"), Buf); - ConOutPrintf(_T(" %s"), IfOperatorString[Cmd->If.Operator]); - if (SubstituteForVars(Cmd->If.RightArg, Buf)) - ConOutPrintf(_T(" %s "), Buf); - Sub = Cmd->Subcommands; - EchoCommand(Sub); - if (Sub->Next) - { - ConOutPrintf(_T(" else ")); - EchoCommand(Sub->Next); - } - break; - case C_FOR: - ConOutPrintf(_T("for")); - if (Cmd->For.Switches & FOR_DIRS) ConOutPrintf(_T(" /D")); - if (Cmd->For.Switches & FOR_F) ConOutPrintf(_T(" /F")); - if (Cmd->For.Switches & FOR_LOOP) ConOutPrintf(_T(" /L")); - if (Cmd->For.Switches & FOR_RECURSIVE) ConOutPrintf(_T(" /R")); - if (Cmd->For.Params) - ConOutPrintf(_T(" %s"), Cmd->For.Params); - ConOutPrintf(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List); - EchoCommand(Cmd->Subcommands); - break; - } + switch (Cmd->Type) + { + case C_COMMAND: + if (SubstituteForVars(Cmd->Command.First, Buf)) + ConOutPrintf(_T("%s"), Buf); + if (SubstituteForVars(Cmd->Command.Rest, Buf)) + ConOutPrintf(_T("%s"), Buf); + break; + case C_QUIET: + return; + case C_BLOCK: + ConOutChar(_T('(')); + Sub = Cmd->Subcommands; + if (Sub && !Sub->Next) + { + /* Single-command block: display all on one line */ + EchoCommand(Sub); + } + else if (Sub) + { + /* Multi-command block: display parenthesis on separate lines */ + ConOutChar(_T('\n')); + do + { + EchoCommand(Sub); + ConOutChar(_T('\n')); + Sub = Sub->Next; + } while (Sub); + } + ConOutChar(_T(')')); + break; + case C_MULTI: + case C_IFFAILURE: + case C_IFSUCCESS: + case C_PIPE: + Sub = Cmd->Subcommands; + EchoCommand(Sub); + ConOutPrintf(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST]); + EchoCommand(Sub->Next); + break; + case C_IF: + ConOutPrintf(_T("if")); + if (Cmd->If.Flags & IFFLAG_IGNORECASE) + ConOutPrintf(_T(" /I")); + if (Cmd->If.Flags & IFFLAG_NEGATE) + ConOutPrintf(_T(" not")); + if (Cmd->If.LeftArg && SubstituteForVars(Cmd->If.LeftArg, Buf)) + ConOutPrintf(_T(" %s"), Buf); + ConOutPrintf(_T(" %s"), IfOperatorString[Cmd->If.Operator]); + if (SubstituteForVars(Cmd->If.RightArg, Buf)) + ConOutPrintf(_T(" %s "), Buf); + Sub = Cmd->Subcommands; + EchoCommand(Sub); + if (Sub->Next) + { + ConOutPrintf(_T(" else ")); + EchoCommand(Sub->Next); + } + break; + case C_FOR: + ConOutPrintf(_T("for")); + if (Cmd->For.Switches & FOR_DIRS) ConOutPrintf(_T(" /D")); + if (Cmd->For.Switches & FOR_F) ConOutPrintf(_T(" /F")); + if (Cmd->For.Switches & FOR_LOOP) ConOutPrintf(_T(" /L")); + if (Cmd->For.Switches & FOR_RECURSIVE) ConOutPrintf(_T(" /R")); + if (Cmd->For.Params) + ConOutPrintf(_T(" %s"), Cmd->For.Params); + ConOutPrintf(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List); + EchoCommand(Cmd->Subcommands); + break; + } - for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next) - { - if (SubstituteForVars(Redir->Filename, Buf)) - ConOutPrintf(_T(" %c%s%s"), _T('0') + Redir->Number, - RedirString[Redir->Mode], Buf); - } + for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next) + { + if (SubstituteForVars(Redir->Filename, Buf)) + ConOutPrintf(_T(" %c%s%s"), _T('0') + Redir->Number, + RedirString[Redir->Mode], Buf); + } } -/* "Unparse" a command into a text form suitable for passing to CMD /C. +/* + * "Unparse" a command into a text form suitable for passing to CMD /C. * Used for pipes. This is basically the same thing as EchoCommand, but - * writing into a string instead of to standard output. */ + * writing into a string instead of to standard output. + */ TCHAR * Unparse(PARSED_COMMAND *Cmd, TCHAR *Out, TCHAR *OutEnd) { - TCHAR Buf[CMDLINE_LENGTH]; - PARSED_COMMAND *Sub; - REDIRECTION *Redir; + TCHAR Buf[CMDLINE_LENGTH]; + PARSED_COMMAND *Sub; + REDIRECTION *Redir; -/* Since this function has the annoying requirement that it must avoid +/* + * Since this function has the annoying requirement that it must avoid * overflowing the supplied buffer, define some helper macros to make - * this less painful */ + * this less painful. + */ #define CHAR(Char) { \ - if (Out == OutEnd) return NULL; \ - *Out++ = Char; } + if (Out == OutEnd) return NULL; \ + *Out++ = Char; } #define STRING(String) { \ - if (Out + _tcslen(String) > OutEnd) return NULL; \ - Out = _stpcpy(Out, String); } + if (Out + _tcslen(String) > OutEnd) return NULL; \ + Out = _stpcpy(Out, String); } #define PRINTF(Format, ...) { \ - UINT Len = _sntprintf(Out, OutEnd - Out, Format, __VA_ARGS__); \ - if (Len > (UINT)(OutEnd - Out)) return NULL; \ - Out += Len; } + UINT Len = _sntprintf(Out, OutEnd - Out, Format, __VA_ARGS__); \ + if (Len > (UINT)(OutEnd - Out)) return NULL; \ + Out += Len; } #define RECURSE(Subcommand) { \ - Out = Unparse(Subcommand, Out, OutEnd); \ - if (!Out) return NULL; } + Out = Unparse(Subcommand, Out, OutEnd); \ + if (!Out) return NULL; } - switch (Cmd->Type) - { - case C_COMMAND: - /* This is fragile since there could be special characters, but - * Windows doesn't bother escaping them, so for compatibility - * we probably shouldn't do it either */ - if (!SubstituteForVars(Cmd->Command.First, Buf)) return NULL; - STRING(Buf) - if (!SubstituteForVars(Cmd->Command.Rest, Buf)) return NULL; - STRING(Buf) - break; - case C_QUIET: - CHAR(_T('@')) - RECURSE(Cmd->Subcommands) - break; - case C_BLOCK: - CHAR(_T('(')) - for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next) - { - RECURSE(Sub) - if (Sub->Next) - CHAR(_T('&')) - } - CHAR(_T(')')) - break; - case C_MULTI: - case C_IFFAILURE: - case C_IFSUCCESS: - case C_PIPE: - Sub = Cmd->Subcommands; - RECURSE(Sub) - PRINTF(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST]) - RECURSE(Sub->Next) - break; - case C_IF: - STRING(_T("if")) - if (Cmd->If.Flags & IFFLAG_IGNORECASE) - STRING(_T(" /I")) - if (Cmd->If.Flags & IFFLAG_NEGATE) - STRING(_T(" not")) - if (Cmd->If.LeftArg && SubstituteForVars(Cmd->If.LeftArg, Buf)) - PRINTF(_T(" %s"), Buf) - PRINTF(_T(" %s"), IfOperatorString[Cmd->If.Operator]); - if (!SubstituteForVars(Cmd->If.RightArg, Buf)) return NULL; - PRINTF(_T(" %s "), Buf) - Sub = Cmd->Subcommands; - RECURSE(Sub) - if (Sub->Next) - { - STRING(_T(" else ")) - RECURSE(Sub->Next) - } - break; - case C_FOR: - STRING(_T("for")) - if (Cmd->For.Switches & FOR_DIRS) STRING(_T(" /D")) - if (Cmd->For.Switches & FOR_F) STRING(_T(" /F")) - if (Cmd->For.Switches & FOR_LOOP) STRING(_T(" /L")) - if (Cmd->For.Switches & FOR_RECURSIVE) STRING(_T(" /R")) - if (Cmd->For.Params) - PRINTF(_T(" %s"), Cmd->For.Params) - PRINTF(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List) - RECURSE(Cmd->Subcommands) - break; - } + switch (Cmd->Type) + { + case C_COMMAND: + /* This is fragile since there could be special characters, but + * Windows doesn't bother escaping them, so for compatibility + * we probably shouldn't do it either */ + if (!SubstituteForVars(Cmd->Command.First, Buf)) return NULL; + STRING(Buf) + if (!SubstituteForVars(Cmd->Command.Rest, Buf)) return NULL; + STRING(Buf) + break; + case C_QUIET: + CHAR(_T('@')) + RECURSE(Cmd->Subcommands) + break; + case C_BLOCK: + CHAR(_T('(')) + for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next) + { + RECURSE(Sub) + if (Sub->Next) + CHAR(_T('&')) + } + CHAR(_T(')')) + break; + case C_MULTI: + case C_IFFAILURE: + case C_IFSUCCESS: + case C_PIPE: + Sub = Cmd->Subcommands; + RECURSE(Sub) + PRINTF(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST]) + RECURSE(Sub->Next) + break; + case C_IF: + STRING(_T("if")) + if (Cmd->If.Flags & IFFLAG_IGNORECASE) + STRING(_T(" /I")) + if (Cmd->If.Flags & IFFLAG_NEGATE) + STRING(_T(" not")) + if (Cmd->If.LeftArg && SubstituteForVars(Cmd->If.LeftArg, Buf)) + PRINTF(_T(" %s"), Buf) + PRINTF(_T(" %s"), IfOperatorString[Cmd->If.Operator]); + if (!SubstituteForVars(Cmd->If.RightArg, Buf)) return NULL; + PRINTF(_T(" %s "), Buf) + Sub = Cmd->Subcommands; + RECURSE(Sub) + if (Sub->Next) + { + STRING(_T(" else ")) + RECURSE(Sub->Next) + } + break; + case C_FOR: + STRING(_T("for")) + if (Cmd->For.Switches & FOR_DIRS) STRING(_T(" /D")) + if (Cmd->For.Switches & FOR_F) STRING(_T(" /F")) + if (Cmd->For.Switches & FOR_LOOP) STRING(_T(" /L")) + if (Cmd->For.Switches & FOR_RECURSIVE) STRING(_T(" /R")) + if (Cmd->For.Params) + PRINTF(_T(" %s"), Cmd->For.Params) + PRINTF(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List) + RECURSE(Cmd->Subcommands) + break; + } - for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next) - { - if (!SubstituteForVars(Redir->Filename, Buf)) return NULL; - PRINTF(_T(" %c%s%s"), _T('0') + Redir->Number, - RedirString[Redir->Mode], Buf) - } - return Out; + for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next) + { + if (!SubstituteForVars(Redir->Filename, Buf)) return NULL; + PRINTF(_T(" %c%s%s"), _T('0') + Redir->Number, + RedirString[Redir->Mode], Buf) + } + return Out; } VOID FreeCommand(PARSED_COMMAND *Cmd) { - if (Cmd->Subcommands) - FreeCommand(Cmd->Subcommands); - if (Cmd->Next) - FreeCommand(Cmd->Next); - FreeRedirection(Cmd->Redirections); - if (Cmd->Type == C_IF) - { - cmd_free(Cmd->If.LeftArg); - cmd_free(Cmd->If.RightArg); - } - else if (Cmd->Type == C_FOR) - { - cmd_free(Cmd->For.Params); - cmd_free(Cmd->For.List); - } - cmd_free(Cmd); + if (Cmd->Subcommands) + FreeCommand(Cmd->Subcommands); + if (Cmd->Next) + FreeCommand(Cmd->Next); + FreeRedirection(Cmd->Redirections); + if (Cmd->Type == C_IF) + { + cmd_free(Cmd->If.LeftArg); + cmd_free(Cmd->If.RightArg); + } + else if (Cmd->Type == C_FOR) + { + cmd_free(Cmd->For.Params); + cmd_free(Cmd->For.List); + } + cmd_free(Cmd); } diff --git a/base/shell/cmd/path.c b/base/shell/cmd/path.c index 6d765eeb49a..ab29938cd0d 100644 --- a/base/shell/cmd/path.c +++ b/base/shell/cmd/path.c @@ -22,8 +22,8 @@ * 24-Jan-1999 (Eric Kohl) * Fixed Win32 environment handling. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -35,53 +35,52 @@ INT cmd_path (LPTSTR param) { + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_PATH_HELP1); + return 0; + } - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_PATH_HELP1); - return 0; - } + nErrorLevel = 0; - nErrorLevel = 0; + /* if param is empty, display the PATH environment variable */ + if (!param || !*param) + { + DWORD dwBuffer; + LPTSTR pszBuffer; - /* if param is empty, display the PATH environment variable */ - if (!param || !*param) - { - DWORD dwBuffer; - LPTSTR pszBuffer; + pszBuffer = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); + dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE); + if (dwBuffer == 0) + { + cmd_free(pszBuffer); + ConOutResPrintf(STRING_VOL_HELP2, _T("PATH")); + return 0; + } + else if (dwBuffer > ENV_BUFFER_SIZE) + { + pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); + GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer); + } - pszBuffer = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); - dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE); - if (dwBuffer == 0) - { - cmd_free(pszBuffer); - ConOutResPrintf(STRING_VOL_HELP2, _T("PATH")); - return 0; - } - else if (dwBuffer > ENV_BUFFER_SIZE) - { - pszBuffer = (LPTSTR)cmd_realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); - GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer); - } + ConOutPrintf(_T("PATH=%s\n"), pszBuffer); + cmd_free (pszBuffer); - ConOutPrintf (_T("PATH=%s\n"), pszBuffer); - cmd_free (pszBuffer); + return 0; + } - return 0; - } + /* skip leading '=' */ + if (*param == _T('=')) + param++; - /* skip leading '=' */ - if (*param == _T('=')) - param++; + /* set PATH environment variable */ + if (!SetEnvironmentVariable (_T("PATH"), param)) + { + nErrorLevel = 1; + return 1; + } - /* set PATH environment variable */ - if (!SetEnvironmentVariable (_T("PATH"), param)) - { - nErrorLevel = 1; - return 1; - } - - return 0; + return 0; } #endif diff --git a/base/shell/cmd/pause.c b/base/shell/cmd/pause.c index f4a2a0bad85..3d7a3020fc4 100644 --- a/base/shell/cmd/pause.c +++ b/base/shell/cmd/pause.c @@ -30,29 +30,28 @@ * ?? Extend to include functionality of CHOICE if switch chars * specified. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen) + * Remove all hardcoded strings in En.rc */ INT cmd_pause (LPTSTR param) { + TRACE ("cmd_pause: \'%s\')\n", debugstr_aw(param)); - TRACE ("cmd_pause: \'%s\')\n", debugstr_aw(param)); + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_PAUSE_HELP1); + return 0; + } - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_PAUSE_HELP1); - return 0; - } + if (*param) + ConOutPrintf (param); + else + msg_pause (); - if (*param) - ConOutPrintf (param); - else - msg_pause (); + cgetchar (); - cgetchar (); - - return 0; + return 0; } #endif diff --git a/base/shell/cmd/prompt.c b/base/shell/cmd/prompt.c index 893568d629f..da6ea9ddaa0 100644 --- a/base/shell/cmd/prompt.c +++ b/base/shell/cmd/prompt.c @@ -43,186 +43,236 @@ * 24-Jan-1999 (Eric Kohl) * Fixed Win32 environment handling. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" +// FIXME: Localize the information line. +static TCHAR InfoLine[] = _T(" ReactOS Command Prompt Type HELP = Help "); + +/* The default prompt */ +static TCHAR DefaultPrompt[] = _T("$I$P$G"); + + /* - * print the command-line prompt + * Initialize prompt support + */ +VOID InitPrompt(VOID) +{ + TCHAR Buffer[2]; + + /* + * Set the PROMPT environment variable if it doesn't exist already. + * You can change the PROMPT environment variable before cmd starts. + */ + if (GetEnvironmentVariable(_T("PROMPT"), Buffer, sizeof(Buffer) / sizeof(Buffer[0])) == 0) + SetEnvironmentVariable(_T("PROMPT"), DefaultPrompt); +} + +/* + * Print an information line on top of the screen + */ +VOID PrintInfoLine(VOID) +{ +#define FOREGROUND_WHITE (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY) + + HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD coPos; + DWORD dwWritten; + + if (!GetConsoleScreenBufferInfo(hOutput, &csbi)) + { + /* No console */ + return; + } + + coPos.X = 0; + coPos.Y = 0; + FillConsoleOutputAttribute(hOutput, BACKGROUND_BLUE | FOREGROUND_WHITE, + csbi.dwSize.X, + coPos, &dwWritten); + FillConsoleOutputCharacter(hOutput, _T(' '), + csbi.dwSize.X, + coPos, &dwWritten); + + WriteConsoleOutputCharacter(hOutput, InfoLine, + sizeof(InfoLine)/sizeof(TCHAR) - 1, + coPos, &dwWritten); +} + +/* + * Print the command-line prompt */ VOID PrintPrompt(VOID) { - static TCHAR default_pr[] = _T("$P$G"); - TCHAR szPrompt[256]; - LPTSTR pr; + TCHAR szPrompt[256]; + LPTSTR pr; - if (GetEnvironmentVariable (_T("PROMPT"), szPrompt, 256)) - pr = szPrompt; - else - pr = default_pr; + if (GetEnvironmentVariable(_T("PROMPT"), szPrompt, 256)) + pr = szPrompt; + else + pr = DefaultPrompt; - while (*pr) - { - if (*pr != _T('$')) - { - ConOutChar (*pr); - } - else - { - pr++; + while (*pr) + { + if (*pr != _T('$')) + { + ConOutChar(*pr); + } + else + { + pr++; - switch (_totupper (*pr)) - { - case _T('A'): - ConOutChar (_T('&')); - break; + switch (_totupper(*pr)) + { + case _T('A'): + ConOutChar(_T('&')); + break; - case _T('B'): - ConOutChar (_T('|')); - break; + case _T('B'): + ConOutChar(_T('|')); + break; - case _T('C'): - ConOutChar (_T('(')); - break; + case _T('C'): + ConOutChar(_T('(')); + break; - case _T('D'): - ConOutPrintf(_T("%s"), GetDateString()); - break; + case _T('D'): + ConOutPrintf(_T("%s"), GetDateString()); + break; - case _T('E'): - ConOutChar (_T('\x1B')); - break; + case _T('E'): + ConOutChar(_T('\x1B')); + break; - case _T('F'): - ConOutChar (_T(')')); - break; + case _T('F'): + ConOutChar(_T(')')); + break; - case _T('G'): - ConOutChar (_T('>')); - break; + case _T('G'): + ConOutChar(_T('>')); + break; - case _T('H'): - ConOutChar (_T('\x08')); - ConOutChar (_T(' ')); - ConOutChar (_T('\x08')); - break; + case _T('H'): + ConOutChar(_T('\x08')); + ConOutChar(_T(' ')); + ConOutChar(_T('\x08')); + break; - case _T('L'): - ConOutChar (_T('<')); - break; + case _T('I'): + PrintInfoLine(); + break; - case _T('N'): - { - TCHAR szPath[MAX_PATH]; - GetCurrentDirectory (MAX_PATH, szPath); - ConOutChar (szPath[0]); - } - break; + case _T('L'): + ConOutChar(_T('<')); + break; - case _T('P'): - { - TCHAR szPath[MAX_PATH]; - GetCurrentDirectory (MAX_PATH, szPath); - ConOutPrintf (_T("%s"), szPath); - } - break; + case _T('N'): + { + TCHAR szPath[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, szPath); + ConOutChar(szPath[0]); + } + break; - case _T('Q'): - ConOutChar (_T('=')); - break; + case _T('P'): + { + TCHAR szPath[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, szPath); + ConOutPrintf(_T("%s"), szPath); + } + break; - case _T('S'): - ConOutChar (_T(' ')); - break; + case _T('Q'): + ConOutChar(_T('=')); + break; - case _T('T'): - ConOutPrintf(_T("%s"), GetTimeString()); - break; + case _T('S'): + ConOutChar(_T(' ')); + break; - case _T('V'): - switch (osvi.dwPlatformId) - { - case VER_PLATFORM_WIN32_WINDOWS: - if (osvi.dwMajorVersion == 4 && - osvi.dwMinorVersion == 1) - ConOutPrintf (_T("Windows 98")); - else - ConOutPrintf (_T("Windows 95")); - break; + case _T('T'): + ConOutPrintf(_T("%s"), GetTimeString()); + break; + + case _T('V'): + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_WINDOWS: + if (osvi.dwMajorVersion == 4 && + osvi.dwMinorVersion == 1) + ConOutPrintf(_T("Windows 98")); + else + ConOutPrintf(_T("Windows 95")); + break; - case VER_PLATFORM_WIN32_NT: - ConOutPrintf (_T("Windows NT Version %lu.%lu"), - osvi.dwMajorVersion, osvi.dwMinorVersion); - break; - } - break; + case VER_PLATFORM_WIN32_NT: + ConOutPrintf(_T("Windows NT Version %lu.%lu"), + osvi.dwMajorVersion, osvi.dwMinorVersion); + break; + } + break; - case _T('_'): - ConOutChar (_T('\n')); - break; + case _T('_'): + ConOutChar(_T('\n')); + break; - case '$': - ConOutChar (_T('$')); - break; + case '$': + ConOutChar(_T('$')); + break; #ifdef FEATURE_DIRECTORY_STACK - case '+': - { - INT i; - for (i = 0; i < GetDirectoryStackDepth (); i++) - ConOutChar (_T('+')); - } - break; + case '+': + { + INT i; + for (i = 0; i < GetDirectoryStackDepth (); i++) + ConOutChar(_T('+')); + } + break; #endif - } - } - pr++; - } + } + } + pr++; + } } #ifdef INCLUDE_CMD_PROMPT -INT cmd_prompt (LPTSTR param) +INT cmd_prompt(LPTSTR param) { - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_PROMPT_HELP1); + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutResPaging(TRUE, STRING_PROMPT_HELP1); #ifdef FEATURE_DIRECTORY_STACK - ConOutResPaging(FALSE,STRING_PROMPT_HELP2); + ConOutResPaging(FALSE, STRING_PROMPT_HELP2); #endif - ConOutResPaging(FALSE,STRING_PROMPT_HELP3); - return 0; - } + ConOutResPaging(FALSE, STRING_PROMPT_HELP3); + return 0; + } - /* if it is null, then it needs to set to default, - because that means the user entered "prompt" only. - so even if param is null you _must_ still set prompt - to the default. There seems to be some kinda difference - between winxp and 2k in this matter and this way will - cover both. Do not use fixed size of szParam for param the buffer are 8192bytes - and will later change to dymatic buffer */ + /* + * If 'param' is NULL, then we need to set it to default, + * because that means the user entered "prompt" only. + * So even if 'param' is null you _must_ still set prompt + * to the default. There seems to be some kind of difference + * between winxp and 2k in this matter and this way will + * cover both. Do not use fixed size of 'szParam' for 'param'; + * the buffers are 8192 bytes and will later change to dynamic buffer. + */ - /* set PROMPT environment variable */ - if (param[0] != _T('\0')) - { - if (!SetEnvironmentVariable (_T("PROMPT"), param)) - return 1; - } - else - { - TCHAR szParam[5]; - _tcscpy(szParam,_T("$P$G")); - if (!SetEnvironmentVariable (_T("PROMPT"),szParam)) - return 1; - } + /* Set the PROMPT environment variable */ + if (!SetEnvironmentVariable(_T("PROMPT"), + (param[0] != _T('\0') ? param : DefaultPrompt))) + { + return 1; + } - - - return 0; + return 0; } #endif diff --git a/base/shell/cmd/readme.txt b/base/shell/cmd/readme.txt index 6597d357e47..9cdb5701d7e 100644 --- a/base/shell/cmd/readme.txt +++ b/base/shell/cmd/readme.txt @@ -47,9 +47,7 @@ ReactOS developers: Brandon Turner - Bugs ~~~~ -There is still many bugs ;) +There are still many bugs ;) Please report bugs to ReactOS team or to JIRA at www.reactos.org - diff --git a/base/shell/cmd/redir.c b/base/shell/cmd/redir.c index c7bbb831ee5..f315a4fc0a7 100644 --- a/base/shell/cmd/redir.c +++ b/base/shell/cmd/redir.c @@ -36,121 +36,120 @@ static HANDLE ExtraHandles[10 - 3]; static HANDLE GetHandle(UINT Number) { - if (Number < 3) - return GetStdHandle(STD_INPUT_HANDLE - Number); - else - return ExtraHandles[Number - 3]; + if (Number < 3) + return GetStdHandle(STD_INPUT_HANDLE - Number); + else + return ExtraHandles[Number - 3]; } static VOID SetHandle(UINT Number, HANDLE Handle) { - if (Number < 3) - SetStdHandle(STD_INPUT_HANDLE - Number, Handle); - else - ExtraHandles[Number - 3] = Handle; + if (Number < 3) + SetStdHandle(STD_INPUT_HANDLE - Number, Handle); + else + ExtraHandles[Number - 3] = Handle; } BOOL PerformRedirection(REDIRECTION *RedirList) { - REDIRECTION *Redir; - LPTSTR Filename; - HANDLE hNew; - UINT DupNumber; + REDIRECTION *Redir; + LPTSTR Filename; + HANDLE hNew; + UINT DupNumber; - static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; - /* Some parameters used for read, write, and append, respectively */ - static - struct REDIR_PARAMS - { - DWORD dwDesiredAccess; - DWORD dwShareMode; - DWORD dwCreationDisposition; - } RedirParams[] = - { - {GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING}, // REDIR_READ - {GENERIC_WRITE, FILE_SHARE_READ , CREATE_ALWAYS}, // REDIR_WRITE - {GENERIC_WRITE, FILE_SHARE_READ , OPEN_ALWAYS } // REDIR_APPEND - }; + /* Some parameters used for read, write, and append, respectively */ + static struct REDIR_PARAMS + { + DWORD dwDesiredAccess; + DWORD dwShareMode; + DWORD dwCreationDisposition; + } RedirParams[] = + { + {GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING}, // REDIR_READ + {GENERIC_WRITE, FILE_SHARE_READ , CREATE_ALWAYS}, // REDIR_WRITE + {GENERIC_WRITE, FILE_SHARE_READ , OPEN_ALWAYS } // REDIR_APPEND + }; - for (Redir = RedirList; Redir; Redir = Redir->Next) - { - Filename = DoDelayedExpansion(Redir->Filename); - if (!Filename) - goto redir_error; - StripQuotes(Filename); + for (Redir = RedirList; Redir; Redir = Redir->Next) + { + Filename = DoDelayedExpansion(Redir->Filename); + if (!Filename) + goto redir_error; + StripQuotes(Filename); - if (*Filename == _T('&')) - { - DupNumber = Filename[1] - _T('0'); - if (DupNumber >= 10 || - !DuplicateHandle(GetCurrentProcess(), - GetHandle(DupNumber), - GetCurrentProcess(), - &hNew, - 0, - TRUE, - DUPLICATE_SAME_ACCESS)) - { - hNew = INVALID_HANDLE_VALUE; - } - } - else - { - hNew = CreateFile(Filename, - RedirParams[Redir->Mode].dwDesiredAccess, - RedirParams[Redir->Mode].dwShareMode, - &SecAttr, - RedirParams[Redir->Mode].dwCreationDisposition, - 0, - NULL); - } + if (*Filename == _T('&')) + { + DupNumber = Filename[1] - _T('0'); + if (DupNumber >= 10 || + !DuplicateHandle(GetCurrentProcess(), + GetHandle(DupNumber), + GetCurrentProcess(), + &hNew, + 0, + TRUE, + DUPLICATE_SAME_ACCESS)) + { + hNew = INVALID_HANDLE_VALUE; + } + } + else + { + hNew = CreateFile(Filename, + RedirParams[Redir->Mode].dwDesiredAccess, + RedirParams[Redir->Mode].dwShareMode, + &SecAttr, + RedirParams[Redir->Mode].dwCreationDisposition, + 0, + NULL); + } - if (hNew == INVALID_HANDLE_VALUE) - { - /* TODO: Print a more detailed message */ - ConErrResPrintf(Redir->Mode == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3, - Filename); - cmd_free(Filename); + if (hNew == INVALID_HANDLE_VALUE) + { + /* TODO: Print a more detailed message */ + ConErrResPrintf(Redir->Mode == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3, + Filename); + cmd_free(Filename); redir_error: - /* Undo all the redirections before this one */ - UndoRedirection(RedirList, Redir); - return FALSE; - } + /* Undo all the redirections before this one */ + UndoRedirection(RedirList, Redir); + return FALSE; + } - if (Redir->Mode == REDIR_APPEND) - SetFilePointer(hNew, 0, NULL, FILE_END); - Redir->OldHandle = GetHandle(Redir->Number); - SetHandle(Redir->Number, hNew); + if (Redir->Mode == REDIR_APPEND) + SetFilePointer(hNew, 0, NULL, FILE_END); + Redir->OldHandle = GetHandle(Redir->Number); + SetHandle(Redir->Number, hNew); - TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename)); - cmd_free(Filename); - } - return TRUE; + TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename)); + cmd_free(Filename); + } + return TRUE; } VOID UndoRedirection(REDIRECTION *Redir, REDIRECTION *End) { - for (; Redir != End; Redir = Redir->Next) - { - CloseHandle(GetHandle(Redir->Number)); - SetHandle(Redir->Number, Redir->OldHandle); - Redir->OldHandle = INVALID_HANDLE_VALUE; - } + for (; Redir != End; Redir = Redir->Next) + { + CloseHandle(GetHandle(Redir->Number)); + SetHandle(Redir->Number, Redir->OldHandle); + Redir->OldHandle = INVALID_HANDLE_VALUE; + } } VOID FreeRedirection(REDIRECTION *Redir) { - REDIRECTION *Next; - for (; Redir; Redir = Next) - { - Next = Redir->Next; - ASSERT(Redir->OldHandle == INVALID_HANDLE_VALUE); - cmd_free(Redir); - } + REDIRECTION *Next; + for (; Redir; Redir = Next) + { + Next = Redir->Next; + ASSERT(Redir->OldHandle == INVALID_HANDLE_VALUE); + cmd_free(Redir); + } } #endif /* FEATURE_REDIRECTION */ diff --git a/base/shell/cmd/ren.c b/base/shell/cmd/ren.c index 89b1cc0aec2..314ba0eee46 100644 --- a/base/shell/cmd/ren.c +++ b/base/shell/cmd/ren.c @@ -17,15 +17,17 @@ * 17-Oct-2001 (Eric Kohl) * Implemented basic rename code. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc - * 25-Nov-2008 (Victor Martinez) Patch dedicated to Myrjala because her comprenhension and love :D - * Fixing following Bugs: - * -Wrong behavior with wildcards when Source and Destiny are Paths(FIXED). - * -Wrong general behavior (MSDN:"Rename cant move files between subdirectories")(FIXED) - * -Wrong behavior when renaming without path in destiny:(i.e) "ren C:\text\as.txt list.txt" it moves as.txt and then rename it(FIXED) - * (MSDN: If there is a Path in Source and no Path in Destiny, then Destiny Path is Source Path,because never Ren has to be used to move.) - * -Implemented checkings if SourcePath and DestinyPath are differents. + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc + * + * 25-Nov-2008 (Victor Martinez ) + * Patch dedicated to Myrjala because her comprenhension and love :D + * Fixing following Bugs: + * -Wrong behavior with wildcards when Source and Destiny are Paths(FIXED). + * -Wrong general behavior (MSDN:"Rename cant move files between subdirectories")(FIXED) + * -Wrong behavior when renaming without path in destiny:(i.e) "ren C:\text\as.txt list.txt" it moves as.txt and then rename it(FIXED) + * (MSDN: If there is a Path in Source and no Path in Destiny, then Destiny Path is Source Path,because never Ren has to be used to move.) + * -Implemented checkings if SourcePath and DestinyPath are differents. * */ @@ -35,343 +37,302 @@ enum { - REN_ATTRIBUTES = 0x001, /* /A : not implemented */ - REN_ERROR = 0x002, /* /E */ - REN_NOTHING = 0x004, /* /N */ - REN_PROMPT = 0x008, /* /P : not implemented */ - REN_QUIET = 0x010, /* /Q */ - REN_SUBDIR = 0x020, /* /S */ - REN_TOTAL = 0x040, /* /T */ + REN_ATTRIBUTES = 0x001, /* /A : not implemented */ + REN_ERROR = 0x002, /* /E */ + REN_NOTHING = 0x004, /* /N */ + REN_PROMPT = 0x008, /* /P : not implemented */ + REN_QUIET = 0x010, /* /Q */ + REN_SUBDIR = 0x020, /* /S */ + REN_TOTAL = 0x040, /* /T */ }; /* * file rename internal command. - * */ INT cmd_rename (LPTSTR param) { - LPTSTR *arg = NULL; - INT args = 0; - INT nSlash = 0; - INT nEvalArgs = 0; /* nunber of evaluated arguments */ - DWORD dwFlags = 0; - DWORD dwFiles = 0; /* number of renamedd files */ - INT i; + LPTSTR *arg = NULL; + INT args = 0; + INT nSlash = 0; + INT nEvalArgs = 0; /* nunber of evaluated arguments */ + DWORD dwFlags = 0; + DWORD dwFiles = 0; /* number of renamedd files */ + INT i; + LPTSTR srcPattern = NULL; /* Source Argument*/ + TCHAR srcPath[MAX_PATH]; /*Source Path Directories*/ + LPTSTR srcFILE = NULL; /*Contains the files name(s)*/ + TCHAR srcFinal[MAX_PATH]; - LPTSTR srcPattern = NULL; /* Source Argument*/ - TCHAR srcPath[MAX_PATH]; /*Source Path Directories*/ - LPTSTR srcFILE = NULL; /*Contains the files name(s)*/ - TCHAR srcFinal[MAX_PATH]; + LPTSTR dstPattern = NULL; /*Destiny Argument*/ + TCHAR dstPath[MAX_PATH]; /*Source Path Directories*/ + LPTSTR dstFILE = NULL; /*Contains the files name(s)*/ + TCHAR dstLast[MAX_PATH]; /*It saves the File name after unmasked with wildcarts*/ + TCHAR dstFinal[MAX_PATH]; /*It saves the Final destiny Path*/ - LPTSTR dstPattern = NULL; /*Destiny Argument*/ - TCHAR dstPath[MAX_PATH]; /*Source Path Directories*/ - LPTSTR dstFILE = NULL; /*Contains the files name(s)*/ + BOOL bDstWildcard = FALSE; + BOOL bPath = FALSE; - TCHAR dstLast[MAX_PATH]; /*It saves the File name after unmasked with wildcarts*/ - TCHAR dstFinal[MAX_PATH]; /*It saves the Final destiny Path*/ + LPTSTR p,q,r; - BOOL bDstWildcard = FALSE; - BOOL bPath = FALSE; - - - - - - - LPTSTR p,q,r; - - HANDLE hFile; - WIN32_FIND_DATA f; - /*If the PARAM=/? then show the help*/ - if (!_tcsncmp(param, _T("/?"), 2)) - { - - - ConOutResPaging(TRUE,STRING_REN_HELP1); - return 0; - } - - nErrorLevel = 0; - - /* Split the argument list.Args will be saved in arg vector*/ - arg = split(param, &args, FALSE, FALSE); - - if (args < 2) + HANDLE hFile; + WIN32_FIND_DATA f; + /*If the PARAM=/? then show the help*/ + if (!_tcsncmp(param, _T("/?"), 2)) { - if (!(dwFlags & REN_ERROR)) - error_req_param_missing(); - freep(arg); - return 1; + ConOutResPaging(TRUE,STRING_REN_HELP1); + return 0; } - /* Read options */ - for (i = 0; i < args; i++) + nErrorLevel = 0; + + /* Split the argument list.Args will be saved in arg vector*/ + arg = split(param, &args, FALSE, FALSE); + + if (args < 2) { - /* Lets check if we have a special option choosen and set the flag(s)*/ - if (*arg[i] == _T('/')) - { - if (_tcslen(arg[i]) >= 2) - { - switch (_totupper(arg[i][1])) - { - case _T('E'): - dwFlags |= REN_ERROR; - break; - - case _T('N'): - dwFlags |= REN_NOTHING; - break; - - case _T('P'): - dwFlags |= REN_PROMPT; - break; - - case _T('Q'): - dwFlags |= REN_QUIET; - break; - - case _T('S'): - dwFlags |= REN_SUBDIR; - break; - - case _T('T'): - dwFlags |= REN_TOTAL; - break; - } - } - nEvalArgs++;//Save the number of the options. - } + if (!(dwFlags & REN_ERROR)) + error_req_param_missing(); + freep(arg); + return 1; } - /* keep quiet within batch files */ - if (bc != NULL) - dwFlags |= REN_QUIET; - - /* there are only options on the command line --> error!!! */ - if (args < nEvalArgs + 2) + /* Read options */ + for (i = 0; i < args; i++) { - if (!(dwFlags & REN_ERROR)) - error_req_param_missing(); - freep(arg); - return 1; + /* Lets check if we have a special option choosen and set the flag(s)*/ + if (*arg[i] == _T('/')) + { + if (_tcslen(arg[i]) >= 2) + { + switch (_totupper(arg[i][1])) + { + case _T('E'): + dwFlags |= REN_ERROR; + break; + + case _T('N'): + dwFlags |= REN_NOTHING; + break; + + case _T('P'): + dwFlags |= REN_PROMPT; + break; + + case _T('Q'): + dwFlags |= REN_QUIET; + break; + + case _T('S'): + dwFlags |= REN_SUBDIR; + break; + + case _T('T'): + dwFlags |= REN_TOTAL; + break; + } + } + nEvalArgs++;//Save the number of the options. + } } + /* keep quiet within batch files */ + if (bc != NULL) + dwFlags |= REN_QUIET; - /* Get destination pattern and source pattern*/ - for (i = 0; i < args; i++) + /* there are only options on the command line --> error!!! */ + if (args < nEvalArgs + 2) { - if (*arg[i] == _T('/'))//We have find an Option.Jump it. - continue; - dstPattern = arg[i]; //we save the Last argument as dstPattern - srcPattern = arg[i-1]; - + if (!(dwFlags & REN_ERROR)) + error_req_param_missing(); + freep(arg); + return 1; } + /* Get destination pattern and source pattern*/ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/'))//We have find an Option.Jump it. + continue; + dstPattern = arg[i]; //we save the Last argument as dstPattern + srcPattern = arg[i-1]; + } - - - - if (_tcschr(srcPattern, _T('\\'))) //Checking if the Source (srcPattern) is a Path to the file - { - - bPath= TRUE; + if (_tcschr(srcPattern, _T('\\'))) //Checking if the Source (srcPattern) is a Path to the file + { + bPath= TRUE; //Splitting srcPath and srcFile. - srcFILE = _tcschr(srcPattern, _T('\\')); - nSlash++; - while(_tcschr(srcFILE, _T('\\'))) - { - srcFILE++; - if(*srcFILE==_T('\\')) nSlash++ ; - if(!_tcschr(srcFILE, _T('\\'))) break; - } - _tcsncpy(srcPath,srcPattern,_tcslen(srcPattern)-_tcslen(srcFILE)); + srcFILE = _tcschr(srcPattern, _T('\\')); + nSlash++; + while(_tcschr(srcFILE, _T('\\'))) + { + srcFILE++; + if (*srcFILE==_T('\\')) nSlash++ ; + if (!_tcschr(srcFILE, _T('\\'))) break; + } + _tcsncpy(srcPath,srcPattern,_tcslen(srcPattern)-_tcslen(srcFILE)); + if (_tcschr(dstPattern, _T('\\'))) //Checking if the Destiny (dstPattern)is also a Path.And splitting dstPattern in dstPath and srcPath. + { + dstFILE = _tcschr(dstPattern, _T('\\')); + nSlash=0; + while(_tcschr(dstFILE, _T('\\'))) + { + dstFILE++; + if (*dstFILE==_T('\\')) nSlash++ ; + if (!_tcschr(dstFILE, _T('\\'))) break; + } + _tcsncpy(dstPath,dstPattern,_tcslen(dstPattern)-_tcslen(dstFILE)); + if ((_tcslen(dstPath)!=_tcslen(srcPath))||(_tcsncmp(srcPath,dstPath,_tcslen(srcPath))!=0)) //If it has a Path,then MUST be equal than srcPath + { + error_syntax(dstPath); + freep(arg); + return 1; + } + } + else + { //If Destiny hasnt a Path,then (MSDN says) srcPath is its Path. + _tcscpy(dstPath,srcPath); + dstFILE=dstPattern; + } + } - if(_tcschr(dstPattern, _T('\\'))) //Checking if the Destiny (dstPattern)is also a Path.And splitting dstPattern in dstPath and srcPath. - { - dstFILE = _tcschr(dstPattern, _T('\\')); - nSlash=0; - while(_tcschr(dstFILE, _T('\\'))) - { - dstFILE++; - if(*dstFILE==_T('\\')) nSlash++ ; - if(!_tcschr(dstFILE, _T('\\'))) break; - } - _tcsncpy(dstPath,dstPattern,_tcslen(dstPattern)-_tcslen(dstFILE)); + if (!_tcschr(srcPattern, _T('\\'))) //If srcPattern isn't a Path but a name: + { + srcFILE=srcPattern; + if (_tcschr(dstPattern, _T('\\'))) + { + error_syntax(dstPattern); + freep(arg); + return 1; + } + else + { + dstFILE=dstPattern; + } + } - if((_tcslen(dstPath)!=_tcslen(srcPath))||(_tcsncmp(srcPath,dstPath,_tcslen(srcPath))!=0)) //If it has a Path,then MUST be equal than srcPath - { - error_syntax(dstPath); - freep(arg); - return 1; - } - }else { //If Destiny hasnt a Path,then (MSDN says) srcPath is its Path. + //Checking Wildcards. + if (_tcschr(dstFILE, _T('*')) || _tcschr(dstFILE, _T('?'))) + bDstWildcard = TRUE; - _tcscpy(dstPath,srcPath); + TRACE("\n\nSourcePattern: %s SourcePath: %s SourceFile: %s", debugstr_aw(srcPattern),debugstr_aw(srcPath),debugstr_aw(srcFILE)); + TRACE("\n\nDestinationPattern: %s Destination Path:%s Destination File: %s\n", debugstr_aw(dstPattern),debugstr_aw(dstPath),debugstr_aw(dstFILE)); - dstFILE=dstPattern; + hFile = FindFirstFile(srcPattern, &f); - } + if (hFile == INVALID_HANDLE_VALUE) + { + if (!(dwFlags & REN_ERROR)) error_file_not_found(); + } + do + { + /* ignore "." and ".." */ + if (!_tcscmp (f.cFileName, _T(".")) || !_tcscmp (f.cFileName, _T(".."))) + continue; + /* do not rename hidden or system files */ + if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) + continue; + /* do not rename directories when the destination pattern contains + * wildcards, unless option /S is used */ + if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + bDstWildcard && !(dwFlags & REN_SUBDIR)) + { + continue; + } - } + TRACE("Found source name: %s\n", debugstr_aw(f.cFileName)); + /* So here we have splitted the dstFILE and we have find a f.cFileName(thanks to srcPattern) + * Now we have to use the mask (dstFILE) (which can have Wildcards) with f.cFileName to find destination file name(dstLast) */ + p = f.cFileName; + q = dstFILE; + r = dstLast; + while(*q != 0) + { + if (*q == '*') + { + q++; + while (*p != 0 && *p != *q) + { + *r = *p; + p++; + r++; + } + } + else if (*q == '?') + { + q++; + if (*p != 0) + { + *r = *p; + p++; + r++; + } + } + else + { + *r = *q; + if (*p != 0) p++; + q++; + r++; + } + } + *r = 0; + //Well we have splitted the Paths,so now we have to paste them again(if needed),thanks bPath. + if (bPath == TRUE) + { + _tcscpy(srcFinal,srcPath); + _tcscat(srcFinal,f.cFileName); + _tcscpy(dstFinal,dstPath); + _tcscat(dstFinal,dstLast); + } + else + { + _tcscpy(srcFinal,f.cFileName); + _tcscpy(dstFinal,dstLast); + } - if (!_tcschr(srcPattern, _T('\\'))) //If srcPattern isn't a Path but a name: - { - srcFILE=srcPattern; - if(_tcschr(dstPattern, _T('\\'))) - { - error_syntax(dstPattern); + TRACE("DestinationPath: %s\n", debugstr_aw(dstFinal)); - freep(arg); - return 1; - }else dstFILE=dstPattern; - } + if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL)) + ConOutPrintf(_T("%s -> %s\n"),srcFinal , dstFinal); - //Checking Wildcards. - if (_tcschr(dstFILE, _T('*')) || _tcschr(dstFILE, _T('?'))) - bDstWildcard = TRUE; + /* Rename the file */ + if (!(dwFlags & REN_NOTHING)) + { + if (MoveFile(srcFinal, dstFinal)) + { + dwFiles++; + } + else + { + if (!(dwFlags & REN_ERROR)) + ConErrResPrintf(STRING_REN_ERROR1, GetLastError()); + } + } + } + while (FindNextFile(hFile, &f)); + //Closing and Printing errors. + FindClose(hFile); + if (!(dwFlags & REN_QUIET)) + { + if (dwFiles == 1) + ConOutResPrintf(STRING_REN_HELP2, dwFiles); + else + ConOutResPrintf(STRING_REN_HELP3, dwFiles); + } - TRACE("\n\nSourcePattern: %s SourcePath: %s SourceFile: %s", debugstr_aw(srcPattern),debugstr_aw(srcPath),debugstr_aw(srcFILE)); - TRACE("\n\nDestinationPattern: %s Destination Path:%s Destination File: %s\n", debugstr_aw(dstPattern),debugstr_aw(dstPath),debugstr_aw(dstFILE)); - - hFile = FindFirstFile(srcPattern, &f); - - if (hFile == INVALID_HANDLE_VALUE) - { - if (!(dwFlags & REN_ERROR)) - error_file_not_found(); - - } - do - { - /* ignore "." and ".." */ - if (!_tcscmp (f.cFileName, _T(".")) || - !_tcscmp (f.cFileName, _T(".."))) - continue; - - /* do not rename hidden or system files */ - if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) - continue; - - /* do not rename directories when the destination pattern contains - * wildcards, unless option /S is used */ - if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - && bDstWildcard - && !(dwFlags & REN_SUBDIR)) - continue; - - TRACE("Found source name: %s\n", debugstr_aw(f.cFileName)); - /* So here we have splitted the dstFILE and we have find a f.cFileName(thanks to srcPattern) - * Now we have to use the mask (dstFILE) (which can have Wildcards) with f.cFileName to find destination file name(dstLast) */ - p = f.cFileName; - q = dstFILE; - r = dstLast; - while(*q != 0) - { - if (*q == '*') - { - q++; - while (*p != 0 && *p != *q) - { - *r = *p; - p++; - r++; - } - } - else if (*q == '?') - { - q++; - if (*p != 0) - { - *r = *p; - p++; - r++; - } - } - else - { - *r = *q; - if (*p != 0) - p++; - q++; - r++; - } - } - *r = 0; - //Well we have splitted the Paths,so now we have to paste them again(if needed),thanks bPath. - if( bPath == TRUE) - { - - _tcscpy(srcFinal,srcPath); - - _tcscat(srcFinal,f.cFileName); - - _tcscpy(dstFinal,dstPath); - _tcscat(dstFinal,dstLast); - - - }else{ - _tcscpy(srcFinal,f.cFileName); - _tcscpy(dstFinal,dstLast); - - } - - - - TRACE("DestinationPath: %s\n", debugstr_aw(dstFinal)); - - - if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL)) - - ConOutPrintf(_T("%s -> %s\n"),srcFinal , dstFinal); - - /* Rename the file */ - if (!(dwFlags & REN_NOTHING)) - { - - - - if (MoveFile(srcFinal, dstFinal)) - { - dwFiles++; - } - else - { - if (!(dwFlags & REN_ERROR)) - { - ConErrResPrintf(STRING_REN_ERROR1, GetLastError()); - } - } - } - } - - while (FindNextFile(hFile, &f)); -//Closing and Printing errors. - - FindClose(hFile); - - - if (!(dwFlags & REN_QUIET)) - { - if (dwFiles == 1) - ConOutResPrintf(STRING_REN_HELP2, dwFiles); - else - ConOutResPrintf(STRING_REN_HELP3, dwFiles); - } - - freep(arg); - - return 0; + freep(arg); + return 0; } #endif diff --git a/base/shell/cmd/ren.txt b/base/shell/cmd/ren.txt index 3cbcec7e98a..72b1aea0d1e 100644 --- a/base/shell/cmd/ren.txt +++ b/base/shell/cmd/ren.txt @@ -47,16 +47,16 @@ dstFILE: here is stored FILE re-name(hi.txt) 2)If srcPattern contains "\" then: - -we activate bPath, since srcPattern has a path inside of it. - -we explit the srcPattern to srcFile and srcPath. - -Now we check the dstPattern does it contain a Path?: - -If does: we divide it in dstPath and dstFile.AND ALSO CHECK THAT dstPath and srcPath its the same(see syntax error).If they aren the same we launch an error. - -If doesnt then we copy srcPath to dstPath(see #way2) and also saving dstPattern as dstFile. + -we activate bPath, since srcPattern has a path inside of it. + -we explit the srcPattern to srcFile and srcPath. + -Now we check the dstPattern does it contain a Path?: + -If does: we divide it in dstPath and dstFile.AND ALSO CHECK THAT dstPath and srcPath its the same(see syntax error).If they aren the same we launch an error. + -If doesnt then we copy srcPath to dstPath(see #way2) and also saving dstPattern as dstFile. 3)If srcPattern doesnt contain "\" then: - -srcPattern is copied in srcFile(we dont need a previous split,because its just a name) - -Now we check the dstPattern does it contains a Path? - -If does: we launch an error (see syntax error 2) - -If doesnt: we copy dstPattern to dstFile(we dont need a previous split because its just a name) + -srcPattern is copied in srcFile(we dont need a previous split,because its just a name) + -Now we check the dstPattern does it contains a Path? + -If does: we launch an error (see syntax error 2) + -If doesnt: we copy dstPattern to dstFile(we dont need a previous split because its just a name) 4)Now we are entering in the do...while: @@ -74,11 +74,11 @@ If we are just renaming one file,then we dont make the while loop.The do..while 5)Now we have to check our Boolean. bPath==TRUE means that Source Argument was a Path so now we have to Join again the Path with the Name File: - -srcFINAL: srcPath+f.cFileName - -dstFINAL: dstPath+dstFile + -srcFINAL: srcPath+f.cFileName + -dstFINAL: dstPath+dstFile bPath==False then Souce wasn a Path an we dont need to join anything. - -srcFINAL:f.cFileName - -dstFINAL:dstFile + -srcFINAL:f.cFileName + -dstFINAL:dstFile At last we just make a MoveFile(srcFinal, dstFinal)): diff --git a/base/shell/cmd/replace.c b/base/shell/cmd/replace.c index 9c941497880..4b139c82e5a 100644 --- a/base/shell/cmd/replace.c +++ b/base/shell/cmd/replace.c @@ -16,549 +16,570 @@ enum { - REPLACE_ADD = 0x001, /* /A */ - REPLACE_CONFIRM = 0x002, /* /P */ - REPLACE_READ_ONLY = 0x004, /* /R */ - REPLACE_SUBDIR = 0x008, /* /S */ - REPLACE_DISK = 0x010, /* /W */ - REPLACE_UPDATE = 0x020, /* /U */ + REPLACE_ADD = 0x001, /* /A */ + REPLACE_CONFIRM = 0x002, /* /P */ + REPLACE_READ_ONLY = 0x004, /* /R */ + REPLACE_SUBDIR = 0x008, /* /S */ + REPLACE_DISK = 0x010, /* /W */ + REPLACE_UPDATE = 0x020, /* /U */ }; /* FUNCTIONS *****************************************************************/ -/*just makes a print out if there is a problem with the switches*/ +/* just makes a print out if there is a problem with the switches */ void invalid_switch(LPTSTR is) { - ConOutResPrintf(STRING_REPLACE_ERROR1,is); - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + ConOutResPrintf(STRING_REPLACE_ERROR1,is); + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); } -/*retrives the pathe dependen om the input file name*/ +/* retrives the pathe dependen om the input file name */ void getPath(TCHAR* out, LPTSTR in) { - if(_tcslen(in) == 2 && in[1] == _T(':')) - GetRootPath(in,out,MAX_PATH); - else - GetFullPathName (in, MAX_PATH, out, NULL); + if (_tcslen(in) == 2 && in[1] == _T(':')) + GetRootPath(in,out,MAX_PATH); + else + GetFullPathName (in, MAX_PATH, out, NULL); } -/*makes the replace*/ +/* makes the replace */ INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore) { - TCHAR d[MAX_PATH]; - TCHAR s[MAX_PATH]; - HANDLE hFileSrc, hFileDest; - DWORD dwAttrib, dwRead, dwWritten; - LPBYTE buffer; - BOOL bEof = FALSE; - FILETIME srcCreationTime, destCreationTime, srcLastAccessTime, destLastAccessTime; - FILETIME srcLastWriteTime, destLastWriteTime; - GetPathCase(source, s); - GetPathCase(dest, d); - s[0] = _totupper(s[0]); - d[0] = _totupper(d[0]); -// ConOutPrintf(_T("old-src: %s\n"), s); -// ConOutPrintf(_T("old-dest: %s\n"), d); -// ConOutPrintf(_T("src: %s\n"), source); -// ConOutPrintf(_T("dest: %s\n"), dest); + TCHAR d[MAX_PATH]; + TCHAR s[MAX_PATH]; + HANDLE hFileSrc, hFileDest; + DWORD dwAttrib, dwRead, dwWritten; + LPBYTE buffer; + BOOL bEof = FALSE; + FILETIME srcCreationTime, destCreationTime, srcLastAccessTime, destLastAccessTime; + FILETIME srcLastWriteTime, destLastWriteTime; + GetPathCase(source, s); + GetPathCase(dest, d); + s[0] = _totupper(s[0]); + d[0] = _totupper(d[0]); + // ConOutPrintf(_T("old-src: %s\n"), s); + // ConOutPrintf(_T("old-dest: %s\n"), d); + // ConOutPrintf(_T("src: %s\n"), source); + // ConOutPrintf(_T("dest: %s\n"), dest); - /* Open up the sourcefile */ - hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, 0, NULL); - if (hFileSrc == INVALID_HANDLE_VALUE) - { - ConOutResPrintf(STRING_COPY_ERROR1, source); - return 0; - } + /* Open up the sourcefile */ + hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, 0, NULL); + if (hFileSrc == INVALID_HANDLE_VALUE) + { + ConOutResPrintf(STRING_COPY_ERROR1, source); + return 0; + } - /* Get the time from source file to be used in the comparison with - dest time if update switch is set */ - GetFileTime (hFileSrc, &srcCreationTime, &srcLastAccessTime, &srcLastWriteTime); + /* + * Get the time from source file to be used in the comparison + * with dest time if update switch is set. + */ + GetFileTime (hFileSrc, &srcCreationTime, &srcLastAccessTime, &srcLastWriteTime); - /* Retrieve the source attributes so that they later on can be - inserted in to the destination */ - dwAttrib = GetFileAttributes (source); + /* + * Retrieve the source attributes so that they later on + * can be inserted in to the destination. + */ + dwAttrib = GetFileAttributes (source); - if(IsExistingFile (dest)) - { - /* Resets the attributes to avoid probles with read only files, - checks for read only has been made earlier */ - SetFileAttributes(dest,FILE_ATTRIBUTE_NORMAL); - /* Is the update flas set? The time has to be controled so that - only older files are replaced */ - if(dwFlags & REPLACE_UPDATE) - { - /* Read destination time */ - hFileDest = CreateFile(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - 0, NULL); + if (IsExistingFile (dest)) + { + /* + * Resets the attributes to avoid probles with read only files, + * checks for read only has been made earlier. + */ + SetFileAttributes(dest,FILE_ATTRIBUTE_NORMAL); + /* + * Is the update flas set? The time has to be controled so that + * only older files are replaced. + */ + if (dwFlags & REPLACE_UPDATE) + { + /* Read destination time */ + hFileDest = CreateFile(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + 0, NULL); - if (hFileSrc == INVALID_HANDLE_VALUE) - { - ConOutResPrintf(STRING_COPY_ERROR1, dest); - return 0; - } + if (hFileSrc == INVALID_HANDLE_VALUE) + { + ConOutResPrintf(STRING_COPY_ERROR1, dest); + return 0; + } - /* Compare time */ - GetFileTime (hFileDest, &destCreationTime, &destLastAccessTime, &destLastWriteTime); - if(!((srcLastWriteTime.dwHighDateTime > destLastWriteTime.dwHighDateTime) || - ( srcLastWriteTime.dwHighDateTime == destLastWriteTime.dwHighDateTime && - srcLastWriteTime.dwLowDateTime > destLastWriteTime.dwLowDateTime))) - { - CloseHandle (hFileSrc); - CloseHandle (hFileDest); - return 0; - } - CloseHandle (hFileDest); - } - /* Delete the old file */ - DeleteFile (dest); - } + /* Compare time */ + GetFileTime (hFileDest, &destCreationTime, &destLastAccessTime, &destLastWriteTime); + if (!((srcLastWriteTime.dwHighDateTime > destLastWriteTime.dwHighDateTime) || + (srcLastWriteTime.dwHighDateTime == destLastWriteTime.dwHighDateTime && + srcLastWriteTime.dwLowDateTime > destLastWriteTime.dwLowDateTime))) + { + CloseHandle (hFileSrc); + CloseHandle (hFileDest); + return 0; + } + CloseHandle (hFileDest); + } + /* Delete the old file */ + DeleteFile (dest); + } - /* Check confirm flag, and take appropriate action */ - if(dwFlags & REPLACE_CONFIRM) - { - /* Output depending on add flag */ - if(dwFlags & REPLACE_ADD) - ConOutResPrintf(STRING_REPLACE_HELP9, dest); - else - ConOutResPrintf(STRING_REPLACE_HELP10, dest); - if( !FilePromptYNA (0)) - return 0; - } + /* Check confirm flag, and take appropriate action */ + if (dwFlags & REPLACE_CONFIRM) + { + /* Output depending on add flag */ + if (dwFlags & REPLACE_ADD) + ConOutResPrintf(STRING_REPLACE_HELP9, dest); + else + ConOutResPrintf(STRING_REPLACE_HELP10, dest); + if ( !FilePromptYNA (0)) + return 0; + } - /* Output depending on add flag */ - if(dwFlags & REPLACE_ADD) - ConOutResPrintf(STRING_REPLACE_HELP11, dest); - else - ConOutResPrintf(STRING_REPLACE_HELP5, dest); + /* Output depending on add flag */ + if (dwFlags & REPLACE_ADD) + ConOutResPrintf(STRING_REPLACE_HELP11, dest); + else + ConOutResPrintf(STRING_REPLACE_HELP5, dest); - /* Make sure source and destination is not the same */ - if(!_tcscmp(s, d)) - { - ConOutResPaging(TRUE, STRING_REPLACE_ERROR7); - CloseHandle (hFileSrc); - *doMore = FALSE; - return 0; - } + /* Make sure source and destination is not the same */ + if (!_tcscmp(s, d)) + { + ConOutResPaging(TRUE, STRING_REPLACE_ERROR7); + CloseHandle (hFileSrc); + *doMore = FALSE; + return 0; + } - /* Open destination file to write to */ - hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - if (hFileDest == INVALID_HANDLE_VALUE) - { - CloseHandle (hFileSrc); - ConOutResPaging(TRUE, STRING_REPLACE_ERROR7); - *doMore = FALSE; - return 0; - } + /* Open destination file to write to */ + hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if (hFileDest == INVALID_HANDLE_VALUE) + { + CloseHandle (hFileSrc); + ConOutResPaging(TRUE, STRING_REPLACE_ERROR7); + *doMore = FALSE; + return 0; + } - /* Get buffer for the copy process */ - buffer = (LPBYTE)VirtualAlloc(NULL, BUFF_SIZE, MEM_COMMIT, PAGE_READWRITE); - if (buffer == NULL) - { - CloseHandle (hFileDest); - CloseHandle (hFileSrc); - ConOutResPaging(TRUE, STRING_ERROR_OUT_OF_MEMORY); - return 0; - } + /* Get buffer for the copy process */ + buffer = (LPBYTE)VirtualAlloc(NULL, BUFF_SIZE, MEM_COMMIT, PAGE_READWRITE); + if (buffer == NULL) + { + CloseHandle (hFileDest); + CloseHandle (hFileSrc); + ConOutResPaging(TRUE, STRING_ERROR_OUT_OF_MEMORY); + return 0; + } - /* Put attribute and time to the new destination file */ - SetFileAttributes (dest, dwAttrib); - SetFileTime (hFileDest, &srcCreationTime, &srcLastAccessTime, &srcLastWriteTime); - do - { - /* Read data from source */ - ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL); + /* Put attribute and time to the new destination file */ + SetFileAttributes (dest, dwAttrib); + SetFileTime (hFileDest, &srcCreationTime, &srcLastAccessTime, &srcLastWriteTime); + do + { + /* Read data from source */ + ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL); - /* Done? */ - if (dwRead == 0) - break; + /* Done? */ + if (dwRead == 0) + break; - /* Write to destination file */ - WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL); + /* Write to destination file */ + WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL); - /* Done! or ctrl break! */ - if (dwWritten != dwRead || CheckCtrlBreak(BREAK_INPUT)) - { - ConOutResPuts(STRING_COPY_ERROR3); - cmd_free (buffer); - CloseHandle (hFileDest); - CloseHandle (hFileSrc); - nErrorLevel = 1; - return 0; - } - } - while (!bEof); + /* Done! or ctrl break! */ + if (dwWritten != dwRead || CheckCtrlBreak(BREAK_INPUT)) + { + ConOutResPuts(STRING_COPY_ERROR3); + cmd_free (buffer); + CloseHandle (hFileDest); + CloseHandle (hFileSrc); + nErrorLevel = 1; + return 0; + } + } + while (!bEof); - /* Return memory and close files */ - VirtualFree (buffer, 0, MEM_RELEASE); - CloseHandle (hFileDest); - CloseHandle (hFileSrc); + /* Return memory and close files */ + VirtualFree (buffer, 0, MEM_RELEASE); + CloseHandle (hFileDest); + CloseHandle (hFileSrc); - /* Return one file replaced */ - return 1; + /* Return one file replaced */ + return 1; } /* Function to iterate over source files and call replace for each of them */ -INT recReplace(DWORD dwFlags, TCHAR szSrcPath[MAX_PATH], TCHAR szDestPath[MAX_PATH], BOOL *doMore) +INT recReplace(DWORD dwFlags, + TCHAR szSrcPath[MAX_PATH], + TCHAR szDestPath[MAX_PATH], + BOOL *doMore) { - TCHAR tmpDestPath[MAX_PATH], tmpSrcPath[MAX_PATH]; - INT filesReplaced=0; - INT_PTR i; - DWORD dwAttrib = 0; - HANDLE hFile; - WIN32_FIND_DATA findBuffer; + TCHAR tmpDestPath[MAX_PATH], tmpSrcPath[MAX_PATH]; + INT filesReplaced=0; + INT_PTR i; + DWORD dwAttrib = 0; + HANDLE hFile; + WIN32_FIND_DATA findBuffer; - /* Get file handel to the sourcefile(s) */ - hFile = FindFirstFile (szSrcPath, &findBuffer); + /* Get file handel to the sourcefile(s) */ + hFile = FindFirstFile (szSrcPath, &findBuffer); - /* Strip the paths back to the folder they are in, so that the diffrent - filenames can be added if more than one */ - for(i = (_tcslen(szSrcPath) - 1); i > -1; i--) - if(szSrcPath[i] != _T('\\')) - szSrcPath[i] = _T('\0'); - else - break; + /* + * Strip the paths back to the folder they are in, so that + * the different filenames can be added if more than one. + */ + for(i = (_tcslen(szSrcPath) - 1); i > -1; i--) + { + if (szSrcPath[i] != _T('\\')) + szSrcPath[i] = _T('\0'); + else + break; + } - /* Go through all the soursfiles and copy/replace them */ - do - { - if(CheckCtrlBreak(BREAK_INPUT)) - { - return filesReplaced; - } + /* Go through all the soursfiles and copy/replace them */ + do + { + if (CheckCtrlBreak(BREAK_INPUT)) + { + return filesReplaced; + } - /* Problem with file handler */ - if(hFile == INVALID_HANDLE_VALUE) - return filesReplaced; + /* Problem with file handler */ + if (hFile == INVALID_HANDLE_VALUE) + return filesReplaced; - /* We do not want to replace any .. . ocr directory */ - if(!_tcscmp (findBuffer.cFileName, _T(".")) || - !_tcscmp (findBuffer.cFileName, _T(".."))|| - findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; + /* We do not want to replace any .. . ocr directory */ + if (!_tcscmp (findBuffer.cFileName, _T(".")) || + !_tcscmp (findBuffer.cFileName, _T(".."))|| + findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; - /* Add filename to destpath */ - _tcscpy(tmpDestPath,szDestPath); - _tcscat (tmpDestPath, findBuffer.cFileName); + /* Add filename to destpath */ + _tcscpy(tmpDestPath,szDestPath); + _tcscat (tmpDestPath, findBuffer.cFileName); - dwAttrib = GetFileAttributes(tmpDestPath); - /* Check add flag */ - if(dwFlags & REPLACE_ADD) - { - if(IsExistingFile(tmpDestPath)) - continue; - else - dwAttrib = 0; - } - else - { - if(!IsExistingFile(tmpDestPath)) - continue; - } + dwAttrib = GetFileAttributes(tmpDestPath); + /* Check add flag */ + if (dwFlags & REPLACE_ADD) + { + if (IsExistingFile(tmpDestPath)) + continue; + else + dwAttrib = 0; + } + else + { + if (!IsExistingFile(tmpDestPath)) + continue; + } - /* Check if file is read only, if so check if that should be ignored */ - if(dwAttrib & FILE_ATTRIBUTE_READONLY) - { - if(!(dwFlags & REPLACE_READ_ONLY)) - { - ConOutResPrintf(STRING_REPLACE_ERROR5, tmpDestPath); - *doMore = FALSE; - break; - } - } + /* Check if file is read only, if so check if that should be ignored */ + if (dwAttrib & FILE_ATTRIBUTE_READONLY) + { + if (!(dwFlags & REPLACE_READ_ONLY)) + { + ConOutResPrintf(STRING_REPLACE_ERROR5, tmpDestPath); + *doMore = FALSE; + break; + } + } - /* Add filename to sourcepath, insted of wildcards */ - _tcscpy(tmpSrcPath,szSrcPath); - _tcscat (tmpSrcPath, findBuffer.cFileName); + /* Add filename to sourcepath, insted of wildcards */ + _tcscpy(tmpSrcPath,szSrcPath); + _tcscat (tmpSrcPath, findBuffer.cFileName); - /* Make the replace */ - if(replace(tmpSrcPath,tmpDestPath, dwFlags, doMore)) - { - filesReplaced++; - } - else if (!*doMore) - { - /* The file to be replaced was the same as the source */ - filesReplaced = -1; - break; - } + /* Make the replace */ + if (replace(tmpSrcPath,tmpDestPath, dwFlags, doMore)) + { + filesReplaced++; + } + else if (!*doMore) + { + /* The file to be replaced was the same as the source */ + filesReplaced = -1; + break; + } - /* Take next sourcefile if any */ - }while(FindNextFile (hFile, &findBuffer)); + /* Take next sourcefile if any */ + } while(FindNextFile (hFile, &findBuffer)); - return filesReplaced; + return filesReplaced; } /* If /s switch is specifyed all subdirs has to be considered */ INT recFindSubDirs(DWORD dwFlags, - TCHAR szSrcPath[MAX_PATH], - TCHAR szDestPath[MAX_PATH], - BOOL *doMore) + TCHAR szSrcPath[MAX_PATH], + TCHAR szDestPath[MAX_PATH], + BOOL *doMore) { - HANDLE hFile; - WIN32_FIND_DATA findBuffer; - TCHAR tmpDestPath[MAX_PATH], tmpSrcPath[MAX_PATH]; - INT filesReplaced = 0; - INT_PTR i; + HANDLE hFile; + WIN32_FIND_DATA findBuffer; + TCHAR tmpDestPath[MAX_PATH], tmpSrcPath[MAX_PATH]; + INT filesReplaced = 0; + INT_PTR i; - /* Add a wildcard to dest end so the it will be easy to itterate - over all the files and directorys in the dest directory */ - _tcscat(szDestPath, _T("*")); + /* + * Add a wildcard to dest end so the it will be easy to iterate + * over all the files and directorys in the dest directory. + */ + _tcscat(szDestPath, _T("*")); - /* Get the first file in the directory */ - hFile = FindFirstFile (szDestPath, &findBuffer); + /* Get the first file in the directory */ + hFile = FindFirstFile (szDestPath, &findBuffer); - /* Remove the star added earlyer to dest path */ - for(i = (_tcslen(szDestPath) - 1); i > -1; i--) - if(szDestPath[i] != _T('\\')) - szDestPath[i] = _T('\0'); - else - break; + /* Remove the star added earlyer to dest path */ + for(i = (_tcslen(szDestPath) - 1); i > -1; i--) + { + if (szDestPath[i] != _T('\\')) + szDestPath[i] = _T('\0'); + else + break; + } - /* Iterate over all filed directories in the dest dir */ - do - { - /* Save the source path so that it will not be wrecked */ - _tcscpy(tmpSrcPath,szSrcPath); - /* Check for reading problems */ - if(hFile == INVALID_HANDLE_VALUE) - { - ConOutFormatMessage (GetLastError(), tmpSrcPath); - return filesReplaced; - } + /* Iterate over all filed directories in the dest dir */ + do + { + /* Save the source path so that it will not be wrecked */ + _tcscpy(tmpSrcPath,szSrcPath); + /* Check for reading problems */ + if (hFile == INVALID_HANDLE_VALUE) + { + ConOutFormatMessage (GetLastError(), tmpSrcPath); + return filesReplaced; + } - /* Check if the we should enter the dir or if it is a file - or . or .. if so thake the next object to process */ - if(!_tcscmp (findBuffer.cFileName, _T(".")) || - !_tcscmp (findBuffer.cFileName, _T(".."))|| - IsExistingFile(findBuffer.cFileName)) - continue; - /* Add the destpath and the new dir path to tempDestPath */ - _tcscpy(tmpDestPath,szDestPath); - _tcscat (tmpDestPath, findBuffer.cFileName); - /* Make sure that we have a directory */ - if(IsExistingDirectory(tmpDestPath)) - { - /* Add a \ to the end or the path */ - if(szDestPath[_tcslen(tmpDestPath) - 1] != _T('\\')) - _tcscat(tmpDestPath, _T("\\")); - /* Call the function to replace files in the new directory */ - filesReplaced += recReplace(dwFlags, tmpSrcPath, tmpDestPath, doMore); - /* If there were problems break e.g. read-only file */ - if(!*doMore) - break; - _tcscpy(tmpSrcPath,szSrcPath); - /* Controle the next level of subdirs */ - filesReplaced += recFindSubDirs(dwFlags,tmpSrcPath,tmpDestPath, doMore); - if(!*doMore) - break; - } - /* Get the next handle */ - } while(FindNextFile (hFile, &findBuffer)); + /* + * Check if the we should enter the dir or if it is a file + * or . or .. if so thake the next object to process. + */ + if (!_tcscmp (findBuffer.cFileName, _T(".")) || + !_tcscmp (findBuffer.cFileName, _T(".."))|| + IsExistingFile(findBuffer.cFileName)) + continue; + /* Add the destpath and the new dir path to tempDestPath */ + _tcscpy(tmpDestPath,szDestPath); + _tcscat (tmpDestPath, findBuffer.cFileName); + /* Make sure that we have a directory */ + if (IsExistingDirectory(tmpDestPath)) + { + /* Add a \ to the end or the path */ + if (szDestPath[_tcslen(tmpDestPath) - 1] != _T('\\')) + _tcscat(tmpDestPath, _T("\\")); + /* Call the function to replace files in the new directory */ + filesReplaced += recReplace(dwFlags, tmpSrcPath, tmpDestPath, doMore); + /* If there were problems break e.g. read-only file */ + if (!*doMore) + break; + _tcscpy(tmpSrcPath,szSrcPath); + /* Controle the next level of subdirs */ + filesReplaced += recFindSubDirs(dwFlags,tmpSrcPath,tmpDestPath, doMore); + if (!*doMore) + break; + } + /* Get the next handle */ + } while(FindNextFile (hFile, &findBuffer)); - return filesReplaced; + return filesReplaced; } INT cmd_replace (LPTSTR param) { - LPTSTR *arg; - INT argc, i,filesReplaced = 0, nFiles, srcIndex = -1, destIndex = -1; - DWORD dwFlags = 0; - TCHAR szDestPath[MAX_PATH], szSrcPath[MAX_PATH], tmpSrcPath[MAX_PATH]; - BOOL doMore = TRUE; + LPTSTR *arg; + INT argc, i,filesReplaced = 0, nFiles, srcIndex = -1, destIndex = -1; + DWORD dwFlags = 0; + TCHAR szDestPath[MAX_PATH], szSrcPath[MAX_PATH], tmpSrcPath[MAX_PATH]; + BOOL doMore = TRUE; - /* Help wanted? */ - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_REPLACE_HELP1); - return 0; - } + /* Help wanted? */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_REPLACE_HELP1); + return 0; + } - /* Divide the argument in to an array of c-strings */ - arg = split (param, &argc, FALSE, FALSE); - nFiles = argc; + /* Divide the argument in to an array of c-strings */ + arg = split (param, &argc, FALSE, FALSE); + nFiles = argc; - /* Read options */ - for (i = 0; i < argc; i++) - { - if (arg[i][0] == _T('/')) - { - if (_tcslen(arg[i]) == 2) - { - switch (_totupper(arg[i][1])) - { - case _T('A'): - dwFlags |= REPLACE_ADD; - break; - case _T('P'): - dwFlags |= REPLACE_CONFIRM; - break; - case _T('R'): - dwFlags |= REPLACE_READ_ONLY; - break; - case _T('S'): - dwFlags |= REPLACE_SUBDIR; - break; - case _T('W'): - dwFlags |= REPLACE_DISK; - break; - case _T('U'): - dwFlags |= REPLACE_UPDATE; - break; - default: - invalid_switch(arg[i]); - return 0; - } - } - else - { - invalid_switch(arg[i]); - freep(arg); - return 0; - } - nFiles--; - } - else - { - if(srcIndex == -1) - { - srcIndex = i; - } - else if(destIndex == -1) - { - destIndex = i; - } - else - { - invalid_switch(arg[i]); - freep(arg); - return 0; - } - } - } + /* Read options */ + for (i = 0; i < argc; i++) + { + if (arg[i][0] == _T('/')) + { + if (_tcslen(arg[i]) == 2) + { + switch (_totupper(arg[i][1])) + { + case _T('A'): + dwFlags |= REPLACE_ADD; + break; + case _T('P'): + dwFlags |= REPLACE_CONFIRM; + break; + case _T('R'): + dwFlags |= REPLACE_READ_ONLY; + break; + case _T('S'): + dwFlags |= REPLACE_SUBDIR; + break; + case _T('W'): + dwFlags |= REPLACE_DISK; + break; + case _T('U'): + dwFlags |= REPLACE_UPDATE; + break; + default: + invalid_switch(arg[i]); + return 0; + } + } + else + { + invalid_switch(arg[i]); + freep(arg); + return 0; + } + nFiles--; + } + else + { + if (srcIndex == -1) + { + srcIndex = i; + } + else if (destIndex == -1) + { + destIndex = i; + } + else + { + invalid_switch(arg[i]); + freep(arg); + return 0; + } + } + } - /* See so that at least source is there */ - if (nFiles < 1) - { - ConOutResPaging(TRUE,STRING_REPLACE_HELP2); - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); - freep(arg); - return 1; - } - /* Check so that not both update and add switch is added and subdir */ - if((dwFlags & REPLACE_UPDATE || dwFlags & REPLACE_SUBDIR) && (dwFlags & REPLACE_ADD)) - { - ConOutResPaging(TRUE,STRING_REPLACE_ERROR4); - ConOutResPaging(TRUE,STRING_REPLACE_HELP7); - freep(arg); - return 1; - } + /* See so that at least source is there */ + if (nFiles < 1) + { + ConOutResPaging(TRUE,STRING_REPLACE_HELP2); + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + freep(arg); + return 1; + } + /* Check so that not both update and add switch is added and subdir */ + if ((dwFlags & REPLACE_UPDATE || dwFlags & REPLACE_SUBDIR) && (dwFlags & REPLACE_ADD)) + { + ConOutResPaging(TRUE,STRING_REPLACE_ERROR4); + ConOutResPaging(TRUE,STRING_REPLACE_HELP7); + freep(arg); + return 1; + } - /* If we have a destination get the full path */ - if(destIndex != -1) - { - if(_tcslen(arg[destIndex]) == 2 && arg[destIndex][1] == ':') - GetRootPath(arg[destIndex],szDestPath,MAX_PATH); - else - { - /* Check for wildcards in destination directory */ - if (_tcschr (arg[destIndex], _T('*')) != NULL || - _tcschr (arg[destIndex], _T('?')) != NULL) - { - ConOutResPrintf(STRING_REPLACE_ERROR2,arg[destIndex]); - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); - freep(arg); - return 1; - } - getPath(szDestPath, arg[destIndex]); - /* Make sure that destination exists */ - if(!IsExistingDirectory(szDestPath)) - { - ConOutResPrintf(STRING_REPLACE_ERROR2, szDestPath); - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); - freep(arg); - return 1; - } - } - } - else - { - /* Dest is current dir */ - GetCurrentDirectory(MAX_PATH,szDestPath); - } + /* If we have a destination get the full path */ + if (destIndex != -1) + { + if (_tcslen(arg[destIndex]) == 2 && arg[destIndex][1] == ':') + GetRootPath(arg[destIndex],szDestPath,MAX_PATH); + else + { + /* Check for wildcards in destination directory */ + if (_tcschr (arg[destIndex], _T('*')) != NULL || + _tcschr (arg[destIndex], _T('?')) != NULL) + { + ConOutResPrintf(STRING_REPLACE_ERROR2,arg[destIndex]); + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + freep(arg); + return 1; + } + getPath(szDestPath, arg[destIndex]); + /* Make sure that destination exists */ + if (!IsExistingDirectory(szDestPath)) + { + ConOutResPrintf(STRING_REPLACE_ERROR2, szDestPath); + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + freep(arg); + return 1; + } + } + } + else + { + /* Dest is current dir */ + GetCurrentDirectory(MAX_PATH,szDestPath); + } - /* Get the full source path */ - if(!(_tcslen(arg[srcIndex]) == 2 && arg[srcIndex][1] == ':')) - getPath(szSrcPath, arg[srcIndex]); - else - _tcscpy(szSrcPath,arg[srcIndex]); + /* Get the full source path */ + if (!(_tcslen(arg[srcIndex]) == 2 && arg[srcIndex][1] == ':')) + getPath(szSrcPath, arg[srcIndex]); + else + _tcscpy(szSrcPath,arg[srcIndex]); - /* Source does not have wildcards */ - if (_tcschr (arg[srcIndex], _T('*')) == NULL && - _tcschr (arg[srcIndex], _T('?')) == NULL) - { - /* Check so that source is not a directory, because that is not allowed */ - if(IsExistingDirectory(szSrcPath)) - { - ConOutResPrintf(STRING_REPLACE_ERROR6, szSrcPath); - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); - freep(arg); - return 1; - } - /* Check if the file exists */ - if(!IsExistingFile(szSrcPath)) - { - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); - freep(arg); - return 1; - } - } - /* /w switch is set so wait for any key to be pressed */ - if(dwFlags & REPLACE_DISK) - { - msg_pause(); - cgetchar(); - } + /* Source does not have wildcards */ + if (_tcschr (arg[srcIndex], _T('*')) == NULL && + _tcschr (arg[srcIndex], _T('?')) == NULL) + { + /* Check so that source is not a directory, because that is not allowed */ + if (IsExistingDirectory(szSrcPath)) + { + ConOutResPrintf(STRING_REPLACE_ERROR6, szSrcPath); + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + freep(arg); + return 1; + } + /* Check if the file exists */ + if (!IsExistingFile(szSrcPath)) + { + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + freep(arg); + return 1; + } + } + /* /w switch is set so wait for any key to be pressed */ + if (dwFlags & REPLACE_DISK) + { + msg_pause(); + cgetchar(); + } - /* Add an extra \ to the destination path if needed */ - if(szDestPath[_tcslen(szDestPath) - 1] != _T('\\')) - _tcscat(szDestPath, _T("\\")); + /* Add an extra \ to the destination path if needed */ + if (szDestPath[_tcslen(szDestPath) - 1] != _T('\\')) + _tcscat(szDestPath, _T("\\")); - /* Save source path */ - _tcscpy(tmpSrcPath,szSrcPath); - /* Replace in dest dir */ - filesReplaced += recReplace(dwFlags, tmpSrcPath, szDestPath, &doMore); - /* If subdir switch is set replace in the subdirs to */ - if(dwFlags & REPLACE_SUBDIR && doMore) - { - filesReplaced += recFindSubDirs(dwFlags, szSrcPath, szDestPath, &doMore); - } + /* Save source path */ + _tcscpy(tmpSrcPath,szSrcPath); + /* Replace in dest dir */ + filesReplaced += recReplace(dwFlags, tmpSrcPath, szDestPath, &doMore); + /* If subdir switch is set replace in the subdirs to */ + if (dwFlags & REPLACE_SUBDIR && doMore) + { + filesReplaced += recFindSubDirs(dwFlags, szSrcPath, szDestPath, &doMore); + } - /* If source == dest write no more */ - if(filesReplaced != -1) - { - /* No files replaced */ - if(filesReplaced==0) - { - /* Add switch dependent output */ - if(dwFlags & REPLACE_ADD) - ConOutResPaging(TRUE,STRING_REPLACE_HELP7); - else - ConOutResPaging(TRUE,STRING_REPLACE_HELP3); - } - /* Some files replaced */ - else - { - /* Add switch dependent output */ - if(dwFlags & REPLACE_ADD) - ConOutResPrintf(STRING_REPLACE_HELP8, filesReplaced); - else - ConOutResPrintf(STRING_REPLACE_HELP4, filesReplaced); - } - } - /* Return memory */ - freep(arg); - return 1; + /* If source == dest write no more */ + if (filesReplaced != -1) + { + /* No files replaced */ + if (filesReplaced==0) + { + /* Add switch dependent output */ + if (dwFlags & REPLACE_ADD) + ConOutResPaging(TRUE,STRING_REPLACE_HELP7); + else + ConOutResPaging(TRUE,STRING_REPLACE_HELP3); + } + /* Some files replaced */ + else + { + /* Add switch dependent output */ + if (dwFlags & REPLACE_ADD) + ConOutResPrintf(STRING_REPLACE_HELP8, filesReplaced); + else + ConOutResPrintf(STRING_REPLACE_HELP4, filesReplaced); + } + } + /* Return memory */ + freep(arg); + return 1; } #endif /* INCLUDE_CMD_REPLACE */ diff --git a/base/shell/cmd/resource.h b/base/shell/cmd/resource.h index c089a49b826..c44ccddb59f 100644 --- a/base/shell/cmd/resource.h +++ b/base/shell/cmd/resource.h @@ -137,72 +137,74 @@ #define STRING_GOTO_HELP1 659 -#define STRING_LABEL_HELP1 660 -#define STRING_LABEL_HELP2 661 -#define STRING_LABEL_HELP3 662 -#define STRING_LABEL_HELP4 663 -#define STRING_LABEL_HELP5 664 +#define STRING_HELP_HELP1 660 -#define STRING_LOCALE_HELP1 665 +#define STRING_LABEL_HELP1 661 +#define STRING_LABEL_HELP2 662 +#define STRING_LABEL_HELP3 663 +#define STRING_LABEL_HELP4 664 +#define STRING_LABEL_HELP5 665 -#define STRING_MKDIR_HELP 666 +#define STRING_LOCALE_HELP1 666 -#define STRING_MEMMORY_HELP1 667 -#define STRING_MEMMORY_HELP2 668 +#define STRING_MKDIR_HELP 667 -#define STRING_MISC_HELP1 669 +#define STRING_MEMMORY_HELP1 668 +#define STRING_MEMMORY_HELP2 669 -#define STRING_MOVE_HELP1 670 -#define STRING_MOVE_HELP2 671 +#define STRING_MISC_HELP1 670 -#define STRING_MSGBOX_HELP 672 +#define STRING_MOVE_HELP1 671 +#define STRING_MOVE_HELP2 672 -#define STRING_PATH_HELP1 673 +#define STRING_MSGBOX_HELP 673 -#define STRING_PAUSE_HELP1 674 +#define STRING_PATH_HELP1 674 -#define STRING_PROMPT_HELP1 675 -#define STRING_PROMPT_HELP2 676 -#define STRING_PROMPT_HELP3 677 +#define STRING_PAUSE_HELP1 675 -#define STRING_REM_HELP 678 +#define STRING_PROMPT_HELP1 676 +#define STRING_PROMPT_HELP2 677 +#define STRING_PROMPT_HELP3 678 -#define STRING_REN_HELP1 679 -#define STRING_REN_HELP2 680 -#define STRING_REN_HELP3 681 +#define STRING_REM_HELP 679 -#define STRING_RMDIR_HELP 682 +#define STRING_REN_HELP1 680 +#define STRING_REN_HELP2 681 +#define STRING_REN_HELP3 682 -#define STRING_SCREEN_HELP 683 +#define STRING_RMDIR_HELP 683 -#define STRING_SHIFT_HELP 684 +#define STRING_SCREEN_HELP 684 -#define STRING_SET_HELP 685 +#define STRING_SHIFT_HELP 685 -#define STRING_START_HELP1 686 +#define STRING_SET_HELP 686 -#define STRING_TITLE_HELP 687 +#define STRING_START_HELP1 687 -#define STRING_TIME_HELP1 688 -#define STRING_TIME_HELP2 689 +#define STRING_TITLE_HELP 688 -#define STRING_TIMER_HELP1 690 -#define STRING_TIMER_HELP2 691 -#define STRING_TIMER_HELP3 692 +#define STRING_TIME_HELP1 689 +#define STRING_TIME_HELP2 690 -#define STRING_TYPE_HELP1 693 +#define STRING_TIMER_HELP1 691 +#define STRING_TIMER_HELP2 692 +#define STRING_TIMER_HELP3 693 -#define STRING_VERIFY_HELP1 694 -#define STRING_VERIFY_HELP2 695 -#define STRING_VERIFY_HELP3 696 +#define STRING_TYPE_HELP1 694 -#define STRING_VERSION_HELP1 697 -#define STRING_VERSION_HELP2 698 -#define STRING_VERSION_HELP3 699 -#define STRING_VERSION_HELP4 700 -#define STRING_VERSION_HELP5 701 -#define STRING_VERSION_HELP6 702 -#define STRING_VERSION_HELP7 703 +#define STRING_VERIFY_HELP1 695 +#define STRING_VERIFY_HELP2 696 +#define STRING_VERIFY_HELP3 697 + +#define STRING_VERSION_HELP1 698 +#define STRING_VERSION_HELP2 699 +#define STRING_VERSION_HELP3 700 +#define STRING_VERSION_HELP4 701 +#define STRING_VERSION_HELP5 702 +#define STRING_VERSION_HELP6 703 +#define STRING_VERSION_HELP7 704 #define STRING_VERSION_RUNVER 705 #define STRING_VOL_HELP1 706 diff --git a/base/shell/cmd/screen.c b/base/shell/cmd/screen.c index 0db3ab46c1c..b45d9da974b 100644 --- a/base/shell/cmd/screen.c +++ b/base/shell/cmd/screen.c @@ -6,8 +6,8 @@ * 30 Aug 1999 * started - Paolo Pantaleo * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc * */ @@ -18,86 +18,86 @@ INT CommandScreen (LPTSTR param) { - SHORT x,y; - BOOL bSkipText = FALSE; + SHORT x,y; + BOOL bSkipText = FALSE; - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE,STRING_SCREEN_HELP); - return 0; - } + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE,STRING_SCREEN_HELP); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - //get row - while(_istspace(*param)) - param++; + //get row + while(_istspace(*param)) + param++; - if(!(*param)) - { - error_req_param_missing (); - return 1; - } + if (!(*param)) + { + error_req_param_missing (); + return 1; + } - y = _ttoi(param); - if (y<0 || y>(maxy-1)) - { - ConOutResPuts(STRING_SCREEN_ROW); + y = _ttoi(param); + if (y<0 || y>(maxy-1)) + { + ConOutResPuts(STRING_SCREEN_ROW); - return 1; - } + return 1; + } - //get col - if(!(param = _tcschr(param,_T(' ')))) - { - error_req_param_missing (); - return 1; - } + //get col + if (!(param = _tcschr(param,_T(' ')))) + { + error_req_param_missing (); + return 1; + } - while(_istspace(*param)) - param++; + while(_istspace(*param)) + param++; - if(!(*param)) - { - error_req_param_missing (); - return 1; - } + if (!(*param)) + { + error_req_param_missing (); + return 1; + } - x = _ttoi(param); - if (x<0 || x>(maxx-1)) - { - ConErrResPuts(STRING_SCREEN_COL); - return 1; - } + x = _ttoi(param); + if (x<0 || x>(maxx-1)) + { + ConErrResPuts(STRING_SCREEN_COL); + return 1; + } - //get text - if(!(param = _tcschr(param,_T(' ')))) - { - bSkipText = TRUE; - } - else - { - while(_istspace(*param)) - param++; + //get text + if (!(param = _tcschr(param,_T(' ')))) + { + bSkipText = TRUE; + } + else + { + while(_istspace(*param)) + param++; - if(!(*param)) - { - bSkipText = TRUE; - } - } + if (!(*param)) + { + bSkipText = TRUE; + } + } - bIgnoreEcho = TRUE; + bIgnoreEcho = TRUE; - if(bSkipText) - x=0; + if (bSkipText) + x=0; - SetCursorXY(x,y); + SetCursorXY(x,y); - if(!(bSkipText)) - ConOutPuts(param); + if (!(bSkipText)) + ConOutPuts(param); - return 0; + return 0; } #endif /* INCLUDE_CMD_SCREEN */ diff --git a/base/shell/cmd/set.c b/base/shell/cmd/set.c index 486e46a22e9..9bac134a7a0 100644 --- a/base/shell/cmd/set.c +++ b/base/shell/cmd/set.c @@ -30,8 +30,8 @@ * 25-Feb-1999 (Eric Kohl) * Fixed little bug. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -48,9 +48,9 @@ seta_eval ( LPCTSTR expr ); static LPCTSTR skip_ws ( LPCTSTR p ) { - while (*p && *p <= _T(' ')) - p++; - return p; + while (*p && *p <= _T(' ')) + p++; + return p; } /* Used to check for and handle: @@ -58,485 +58,485 @@ skip_ws ( LPCTSTR p ) static LPTSTR GetQuotedString(TCHAR *p) { - TCHAR *end; - if (*p == _T('"')) - { - p = (LPTSTR)skip_ws(p + 1); - /* If a matching quote is found, truncate the string */ - end = _tcsrchr(p, _T('"')); - if (end) - *end = _T('\0'); - } - return p; + TCHAR *end; + if (*p == _T('"')) + { + p = (LPTSTR)skip_ws(p + 1); + /* If a matching quote is found, truncate the string */ + end = _tcsrchr(p, _T('"')); + if (end) + *end = _T('\0'); + } + return p; } INT cmd_set (LPTSTR param) { - LPTSTR p; - LPTSTR lpEnv; - LPTSTR lpOutput; + LPTSTR p; + LPTSTR lpEnv; + LPTSTR lpOutput; - if ( !_tcsncmp (param, _T("/?"), 2) ) - { - ConOutResPaging(TRUE,STRING_SET_HELP); - return 0; - } + if ( !_tcsncmp (param, _T("/?"), 2) ) + { + ConOutResPaging(TRUE,STRING_SET_HELP); + return 0; + } - param = (LPTSTR)skip_ws(param); + param = (LPTSTR)skip_ws(param); - /* if no parameters, show the environment */ - if (param[0] == _T('\0')) - { - lpEnv = (LPTSTR)GetEnvironmentStrings (); - if (lpEnv) - { - lpOutput = lpEnv; - while (*lpOutput) - { - if (*lpOutput != _T('=')) - ConOutPuts(lpOutput); - lpOutput += _tcslen(lpOutput) + 1; - ConOutPuts(_T("\r\n")); - } - FreeEnvironmentStrings (lpEnv); - } + /* if no parameters, show the environment */ + if (param[0] == _T('\0')) + { + lpEnv = (LPTSTR)GetEnvironmentStrings (); + if (lpEnv) + { + lpOutput = lpEnv; + while (*lpOutput) + { + if (*lpOutput != _T('=')) + ConOutPuts(lpOutput); + lpOutput += _tcslen(lpOutput) + 1; + ConOutChar(_T('\n')); + } + FreeEnvironmentStrings (lpEnv); + } - return 0; - } + return 0; + } - /* the /A does *NOT* have to be followed by a whitespace */ - if ( !_tcsnicmp (param, _T("/A"), 2) ) - { - BOOL Success; - StripQuotes(param); - Success = seta_eval ( skip_ws(param+2) ); - if(!Success) - { - /*might seem random but this is what windows xp does */ - nErrorLevel = 9165; - } - return !Success; - } + /* the /A does *NOT* have to be followed by a whitespace */ + if ( !_tcsnicmp (param, _T("/A"), 2) ) + { + BOOL Success; + StripQuotes(param); + Success = seta_eval ( skip_ws(param+2) ); + if (!Success) + { + /* might seem random but this is what windows xp does */ + nErrorLevel = 9165; + } + return !Success; + } - if (!_tcsnicmp(param, _T("/P"), 2)) - { - TCHAR value[1023]; - param = GetQuotedString((LPTSTR)skip_ws(param + 2)); - p = _tcschr(param, _T('=')); - if (!p) - { - ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT); - nErrorLevel = 1; - return 1; - } + if (!_tcsnicmp(param, _T("/P"), 2)) + { + TCHAR value[1023]; + param = GetQuotedString((LPTSTR)skip_ws(param + 2)); + p = _tcschr(param, _T('=')); + if (!p) + { + ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT); + nErrorLevel = 1; + return 1; + } - *p++ = _T('\0'); - ConOutPrintf(_T("%s"), GetQuotedString(p)); - ConInString(value, 1023); + *p++ = _T('\0'); + ConOutPrintf(_T("%s"), GetQuotedString(p)); + ConInString(value, 1023); - if (!*value || !SetEnvironmentVariable(param, value)) - { - nErrorLevel = 1; - return 1; - } - return 0; - } + if (!*value || !SetEnvironmentVariable(param, value)) + { + nErrorLevel = 1; + return 1; + } + return 0; + } - param = GetQuotedString(param); + param = GetQuotedString(param); - p = _tcschr (param, _T('=')); - if (p) - { - /* set or remove environment variable */ - if (p == param) - { - /* handle set =val case */ - ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT); - nErrorLevel = 1; - return 1; - } + p = _tcschr (param, _T('=')); + if (p) + { + /* set or remove environment variable */ + if (p == param) + { + /* handle set =val case */ + ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT); + nErrorLevel = 1; + return 1; + } - *p++ = _T('\0'); - if (!SetEnvironmentVariable(param, *p ? p : NULL)) - { - nErrorLevel = 1; - return 1; - } - } - else - { - /* display all environment variable with the given prefix */ - BOOL bFound = FALSE; + *p++ = _T('\0'); + if (!SetEnvironmentVariable(param, *p ? p : NULL)) + { + nErrorLevel = 1; + return 1; + } + } + else + { + /* display all environment variable with the given prefix */ + BOOL bFound = FALSE; - while (_istspace(*param) || *param == _T(',') || *param == _T(';')) - param++; + while (_istspace(*param) || *param == _T(',') || *param == _T(';')) + param++; - p = _tcsrchr(param, _T(' ')); - if (!p) - p = param + _tcslen(param); - *p = _T('\0'); + p = _tcsrchr(param, _T(' ')); + if (!p) + p = param + _tcslen(param); + *p = _T('\0'); - lpEnv = GetEnvironmentStrings(); - if (lpEnv) - { - lpOutput = lpEnv; - while (*lpOutput) - { - if (!_tcsnicmp(lpOutput, param, p - param)) - { - ConOutPuts(lpOutput); - ConOutPuts(_T("\r\n")); - bFound = TRUE; - } - lpOutput += _tcslen(lpOutput) + 1; - } - FreeEnvironmentStrings(lpEnv); - } + lpEnv = GetEnvironmentStrings(); + if (lpEnv) + { + lpOutput = lpEnv; + while (*lpOutput) + { + if (!_tcsnicmp(lpOutput, param, p - param)) + { + ConOutPuts(lpOutput); + ConOutChar(_T('\n')); + bFound = TRUE; + } + lpOutput += _tcslen(lpOutput) + 1; + } + FreeEnvironmentStrings(lpEnv); + } - if (!bFound) - { - ConErrResPrintf (STRING_PATH_ERROR, param); - nErrorLevel = 1; - return 1; - } - } + if (!bFound) + { + ConErrResPrintf (STRING_PATH_ERROR, param); + nErrorLevel = 1; + return 1; + } + } - return 0; + return 0; } static INT -ident_len ( LPCTSTR p ) +ident_len(LPCTSTR p) { - LPCTSTR p2 = p; - if ( __iscsymf(*p) ) - { - ++p2; - while ( __iscsym(*p2) ) - ++p2; - } - return (INT)(p2-p); + LPCTSTR p2 = p; + if ( __iscsymf(*p) ) + { + ++p2; + while ( __iscsym(*p2) ) + ++p2; + } + return (INT)(p2-p); } #define PARSE_IDENT(ident,identlen,p) \ - identlen = ident_len(p); \ - ident = (LPTSTR)alloca ( ( identlen + 1 ) * sizeof(TCHAR) ); \ - memmove ( ident, p, identlen * sizeof(TCHAR) ); \ - ident[identlen] = 0; \ - p += identlen; + identlen = ident_len(p); \ + ident = (LPTSTR)alloca ( ( identlen + 1 ) * sizeof(TCHAR) ); \ + memmove ( ident, p, identlen * sizeof(TCHAR) ); \ + ident[identlen] = 0; \ + p += identlen; static BOOL -seta_identval ( LPCTSTR ident, INT* result ) +seta_identval(LPCTSTR ident, INT* result) { - LPCTSTR identVal = GetEnvVarOrSpecial ( ident ); - if ( !identVal ) - { - /* TODO FIXME - what to do upon failure? */ - *result = 0; - return FALSE; - } - *result = _tcstol ( identVal, NULL, 0 ); - return TRUE; + LPCTSTR identVal = GetEnvVarOrSpecial ( ident ); + if ( !identVal ) + { + /* TODO FIXME - what to do upon failure? */ + *result = 0; + return FALSE; + } + *result = _tcstol ( identVal, NULL, 0 ); + return TRUE; } static BOOL -calc ( INT* lval, TCHAR op, INT rval ) +calc(INT* lval, TCHAR op, INT rval) { - switch ( op ) - { - case '*': - *lval *= rval; - break; - case '/': - *lval /= rval; - break; - case '%': - *lval %= rval; - break; - case '+': - *lval += rval; - break; - case '-': - *lval -= rval; - break; - case '&': - *lval &= rval; - break; - case '^': - *lval ^= rval; - break; - case '|': - *lval |= rval; - break; - default: - ConErrResPuts ( STRING_INVALID_OPERAND ); - return FALSE; - } - return TRUE; + switch ( op ) + { + case '*': + *lval *= rval; + break; + case '/': + *lval /= rval; + break; + case '%': + *lval %= rval; + break; + case '+': + *lval += rval; + break; + case '-': + *lval -= rval; + break; + case '&': + *lval &= rval; + break; + case '^': + *lval ^= rval; + break; + case '|': + *lval |= rval; + break; + default: + ConErrResPuts ( STRING_INVALID_OPERAND ); + return FALSE; + } + return TRUE; } static BOOL -seta_stmt ( LPCTSTR* p_, INT* result ); +seta_stmt (LPCTSTR* p_, INT* result); static BOOL -seta_unaryTerm ( LPCTSTR* p_, INT* result ) +seta_unaryTerm(LPCTSTR* p_, INT* result) { - LPCTSTR p = *p_; - if ( *p == _T('(') ) - { - INT rval; - p = skip_ws ( p + 1 ); - if ( !seta_stmt ( &p, &rval ) ) - return FALSE; - if ( *p++ != _T(')') ) - { - ConErrResPuts ( STRING_EXPECTED_CLOSE_PAREN ); - return FALSE; - } - *result = rval; - } - else if ( isdigit(*p) ) - { - *result = _tcstol ( p, (LPTSTR *)&p, 0 ); - } - else if ( __iscsymf(*p) ) - { - LPTSTR ident; - INT identlen; - PARSE_IDENT(ident,identlen,p); - if ( !seta_identval ( ident, result ) ) - return FALSE; - } - else - { - ConErrResPuts ( STRING_EXPECTED_NUMBER_OR_VARIABLE ); - return FALSE; - } - *p_ = skip_ws ( p ); - return TRUE; + LPCTSTR p = *p_; + if ( *p == _T('(') ) + { + INT rval; + p = skip_ws ( p + 1 ); + if ( !seta_stmt ( &p, &rval ) ) + return FALSE; + if ( *p++ != _T(')') ) + { + ConErrResPuts ( STRING_EXPECTED_CLOSE_PAREN ); + return FALSE; + } + *result = rval; + } + else if ( isdigit(*p) ) + { + *result = _tcstol ( p, (LPTSTR *)&p, 0 ); + } + else if ( __iscsymf(*p) ) + { + LPTSTR ident; + INT identlen; + PARSE_IDENT(ident,identlen,p); + if ( !seta_identval ( ident, result ) ) + return FALSE; + } + else + { + ConErrResPuts ( STRING_EXPECTED_NUMBER_OR_VARIABLE ); + return FALSE; + } + *p_ = skip_ws ( p ); + return TRUE; } static BOOL -seta_mulTerm ( LPCTSTR* p_, INT* result ) +seta_mulTerm(LPCTSTR* p_, INT* result) { - LPCTSTR p = *p_; - TCHAR op = 0; - INT rval; - if ( _tcschr(_T("!~-"),*p) ) - { - op = *p; - p = skip_ws ( p + 1 ); - } - if ( !seta_unaryTerm ( &p, &rval ) ) - return FALSE; - switch ( op ) - { - case '!': - rval = !rval; - break; - case '~': - rval = ~rval; - break; - case '-': - rval = -rval; - break; - } + LPCTSTR p = *p_; + TCHAR op = 0; + INT rval; + if ( _tcschr(_T("!~-"),*p) ) + { + op = *p; + p = skip_ws ( p + 1 ); + } + if ( !seta_unaryTerm ( &p, &rval ) ) + return FALSE; + switch ( op ) + { + case '!': + rval = !rval; + break; + case '~': + rval = ~rval; + break; + case '-': + rval = -rval; + break; + } - *result = rval; - *p_ = p; - return TRUE; + *result = rval; + *p_ = p; + return TRUE; } static BOOL -seta_ltorTerm ( LPCTSTR* p_, INT* result, LPCTSTR ops, BOOL (*subTerm)(LPCTSTR*,INT*) ) +seta_ltorTerm(LPCTSTR* p_, INT* result, LPCTSTR ops, BOOL (*subTerm)(LPCTSTR*,INT*)) { - LPCTSTR p = *p_; - INT lval; - if ( !subTerm ( &p, &lval ) ) - return FALSE; - while ( *p && _tcschr(ops,*p) ) - { - INT rval; - TCHAR op = *p; + LPCTSTR p = *p_; + INT lval; + if ( !subTerm ( &p, &lval ) ) + return FALSE; + while ( *p && _tcschr(ops,*p) ) + { + INT rval; + TCHAR op = *p; - p = skip_ws ( p+1 ); + p = skip_ws ( p+1 ); - if ( !subTerm ( &p, &rval ) ) - return FALSE; + if ( !subTerm ( &p, &rval ) ) + return FALSE; - if ( !calc ( &lval, op, rval ) ) - return FALSE; - } + if ( !calc ( &lval, op, rval ) ) + return FALSE; + } - *result = lval; - *p_ = p; - return TRUE; + *result = lval; + *p_ = p; + return TRUE; } static BOOL -seta_addTerm ( LPCTSTR* p_, INT* result ) +seta_addTerm(LPCTSTR* p_, INT* result) { - return seta_ltorTerm ( p_, result, _T("*/%"), seta_mulTerm ); + return seta_ltorTerm ( p_, result, _T("*/%"), seta_mulTerm ); } static BOOL -seta_logShiftTerm ( LPCTSTR* p_, INT* result ) +seta_logShiftTerm(LPCTSTR* p_, INT* result) { - return seta_ltorTerm ( p_, result, _T("+-"), seta_addTerm ); + return seta_ltorTerm ( p_, result, _T("+-"), seta_addTerm ); } static BOOL -seta_bitAndTerm ( LPCTSTR* p_, INT* result ) +seta_bitAndTerm(LPCTSTR* p_, INT* result) { - LPCTSTR p = *p_; - INT lval; - if ( !seta_logShiftTerm ( &p, &lval ) ) - return FALSE; - while ( *p && _tcschr(_T("<>"),*p) && p[0] == p[1] ) - { - INT rval; - TCHAR op = *p; + LPCTSTR p = *p_; + INT lval; + if ( !seta_logShiftTerm ( &p, &lval ) ) + return FALSE; + while ( *p && _tcschr(_T("<>"),*p) && p[0] == p[1] ) + { + INT rval; + TCHAR op = *p; - p = skip_ws ( p+2 ); + p = skip_ws ( p+2 ); - if ( !seta_logShiftTerm ( &p, &rval ) ) - return FALSE; + if ( !seta_logShiftTerm ( &p, &rval ) ) + return FALSE; - switch ( op ) - { - case '<': - lval <<= rval; - break; - case '>': - lval >>= rval; - break; - default: - ConErrResPuts ( STRING_INVALID_OPERAND ); - return FALSE; - } - } + switch ( op ) + { + case '<': + lval <<= rval; + break; + case '>': + lval >>= rval; + break; + default: + ConErrResPuts ( STRING_INVALID_OPERAND ); + return FALSE; + } + } - *result = lval; - *p_ = p; - return TRUE; + *result = lval; + *p_ = p; + return TRUE; } static BOOL -seta_bitExclOrTerm ( LPCTSTR* p_, INT* result ) +seta_bitExclOrTerm(LPCTSTR* p_, INT* result) { - return seta_ltorTerm ( p_, result, _T("&"), seta_bitAndTerm ); + return seta_ltorTerm ( p_, result, _T("&"), seta_bitAndTerm ); } static BOOL -seta_bitOrTerm ( LPCTSTR* p_, INT* result ) +seta_bitOrTerm(LPCTSTR* p_, INT* result) { - return seta_ltorTerm ( p_, result, _T("^"), seta_bitExclOrTerm ); + return seta_ltorTerm ( p_, result, _T("^"), seta_bitExclOrTerm ); } static BOOL -seta_expr ( LPCTSTR* p_, INT* result ) +seta_expr(LPCTSTR* p_, INT* result) { - return seta_ltorTerm ( p_, result, _T("|"), seta_bitOrTerm ); + return seta_ltorTerm ( p_, result, _T("|"), seta_bitOrTerm ); } static BOOL -seta_assignment ( LPCTSTR* p_, INT* result ) +seta_assignment(LPCTSTR* p_, INT* result) { - LPCTSTR p = *p_; - LPTSTR ident; - TCHAR op = 0; - INT identlen, exprval; + LPCTSTR p = *p_; + LPTSTR ident; + TCHAR op = 0; + INT identlen, exprval; - PARSE_IDENT(ident,identlen,p); - if ( identlen ) - { - p = skip_ws(p); - if ( *p == _T('=') ) - op = *p, p = skip_ws(p+1); - else if ( _tcschr ( _T("*/%+-&^|"), *p ) && p[1] == _T('=') ) - op = *p, p = skip_ws(p+2); - else if ( _tcschr ( _T("<>"), *p ) && *p == p[1] && p[2] == _T('=') ) - op = *p, p = skip_ws(p+3); - } + PARSE_IDENT(ident,identlen,p); + if ( identlen ) + { + p = skip_ws(p); + if ( *p == _T('=') ) + op = *p, p = skip_ws(p+1); + else if ( _tcschr ( _T("*/%+-&^|"), *p ) && p[1] == _T('=') ) + op = *p, p = skip_ws(p+2); + else if ( _tcschr ( _T("<>"), *p ) && *p == p[1] && p[2] == _T('=') ) + op = *p, p = skip_ws(p+3); + } - /* allow to chain multiple assignments, such as: a=b=1 */ - if ( ident && op ) - { - INT identval; - LPTSTR buf; + /* allow to chain multiple assignments, such as: a=b=1 */ + if ( ident && op ) + { + INT identval; + LPTSTR buf; - if ( !seta_assignment ( &p, &exprval ) ) - return FALSE; + if ( !seta_assignment ( &p, &exprval ) ) + return FALSE; - if ( !seta_identval ( ident, &identval ) ) - identval = 0; - switch ( op ) - { - case '=': - identval = exprval; - break; - case '<': - identval <<= exprval; - break; - case '>': - identval >>= exprval; - break; - default: - if ( !calc ( &identval, op, exprval ) ) - return FALSE; - } - buf = (LPTSTR)alloca ( 32 * sizeof(TCHAR) ); - _sntprintf ( buf, 32, _T("%i"), identval ); - SetEnvironmentVariable ( ident, buf ); // TODO FIXME - check return value - exprval = identval; - } - else - { - /* restore p in case we found an ident but not an op */ - p = *p_; - if ( !seta_expr ( &p, &exprval ) ) - return FALSE; - } + if ( !seta_identval ( ident, &identval ) ) + identval = 0; + switch ( op ) + { + case '=': + identval = exprval; + break; + case '<': + identval <<= exprval; + break; + case '>': + identval >>= exprval; + break; + default: + if ( !calc ( &identval, op, exprval ) ) + return FALSE; + } + buf = (LPTSTR)alloca ( 32 * sizeof(TCHAR) ); + _sntprintf ( buf, 32, _T("%i"), identval ); + SetEnvironmentVariable ( ident, buf ); // TODO FIXME - check return value + exprval = identval; + } + else + { + /* restore p in case we found an ident but not an op */ + p = *p_; + if ( !seta_expr ( &p, &exprval ) ) + return FALSE; + } - *result = exprval; - *p_ = p; - return TRUE; + *result = exprval; + *p_ = p; + return TRUE; } static BOOL -seta_stmt ( LPCTSTR* p_, INT* result ) +seta_stmt(LPCTSTR* p_, INT* result) { - LPCTSTR p = *p_; - INT rval; + LPCTSTR p = *p_; + INT rval; - if ( !seta_assignment ( &p, &rval ) ) - return FALSE; - while ( *p == _T(',') ) - { - p = skip_ws ( p+1 ); + if ( !seta_assignment ( &p, &rval ) ) + return FALSE; + while ( *p == _T(',') ) + { + p = skip_ws ( p+1 ); - if ( !seta_assignment ( &p, &rval ) ) - return FALSE; - } + if ( !seta_assignment ( &p, &rval ) ) + return FALSE; + } - *result = rval; - *p_ = p; - return TRUE; + *result = rval; + *p_ = p; + return TRUE; } static BOOL -seta_eval ( LPCTSTR p ) +seta_eval(LPCTSTR p) { - INT rval; - if ( !*p ) - { - ConErrResPuts ( STRING_SYNTAX_COMMAND_INCORRECT ); - return FALSE; - } - if ( !seta_stmt ( &p, &rval ) ) - return FALSE; - if ( !bc ) - ConOutPrintf ( _T("%i"), rval ); - return TRUE; + INT rval; + if ( !*p ) + { + ConErrResPuts ( STRING_SYNTAX_COMMAND_INCORRECT ); + return FALSE; + } + if ( !seta_stmt ( &p, &rval ) ) + return FALSE; + if ( !bc ) + ConOutPrintf ( _T("%i"), rval ); + return TRUE; } #endif diff --git a/base/shell/cmd/setlocal.c b/base/shell/cmd/setlocal.c index 85397bab2a0..5ad2e417682 100644 --- a/base/shell/cmd/setlocal.c +++ b/base/shell/cmd/setlocal.c @@ -5,125 +5,128 @@ * * 1 Feb 2008 (Christoph von Wittich) * started. -*/ +*/ #include "precomp.h" -typedef struct _SETLOCAL { - struct _SETLOCAL *Prev; - BOOL DelayedExpansion; - LPTSTR Environment; +typedef struct _SETLOCAL +{ + struct _SETLOCAL *Prev; + BOOL DelayedExpansion; + LPTSTR Environment; } SETLOCAL; /* Create a copy of the current environment */ LPTSTR DuplicateEnvironment(VOID) { - LPTSTR Environ = GetEnvironmentStrings(); - LPTSTR End, EnvironCopy; - if (!Environ) - return NULL; - for (End = Environ; *End; End += _tcslen(End) + 1) - ; - EnvironCopy = cmd_alloc((End + 1 - Environ) * sizeof(TCHAR)); - if (EnvironCopy) - memcpy(EnvironCopy, Environ, (End + 1 - Environ) * sizeof(TCHAR)); - FreeEnvironmentStrings(Environ); - return EnvironCopy; + LPTSTR Environ = GetEnvironmentStrings(); + LPTSTR End, EnvironCopy; + + if (!Environ) return NULL; + + for (End = Environ; *End; End += _tcslen(End) + 1) ; + EnvironCopy = cmd_alloc((End + 1 - Environ) * sizeof(TCHAR)); + + if (EnvironCopy) + memcpy(EnvironCopy, Environ, (End + 1 - Environ) * sizeof(TCHAR)); + + FreeEnvironmentStrings(Environ); + return EnvironCopy; } INT cmd_setlocal(LPTSTR param) { - SETLOCAL *Saved; - LPTSTR *arg; - INT argc, i; + SETLOCAL *Saved; + LPTSTR *arg; + INT argc, i; - /* SETLOCAL only works inside a batch file */ - if (!bc) - return 0; + /* SETLOCAL only works inside a batch file */ + if (!bc) + return 0; - Saved = cmd_alloc(sizeof(SETLOCAL)); - if (!Saved) - { - error_out_of_memory(); - return 1; - } - Saved->Prev = bc->setlocal; - Saved->DelayedExpansion = bDelayedExpansion; - Saved->Environment = DuplicateEnvironment(); - if (!Saved->Environment) - { - error_out_of_memory(); - cmd_free(Saved); - return 1; - } - bc->setlocal = Saved; + Saved = cmd_alloc(sizeof(SETLOCAL)); + if (!Saved) + { + error_out_of_memory(); + return 1; + } + Saved->Prev = bc->setlocal; + Saved->DelayedExpansion = bDelayedExpansion; + Saved->Environment = DuplicateEnvironment(); + if (!Saved->Environment) + { + error_out_of_memory(); + cmd_free(Saved); + return 1; + } + bc->setlocal = Saved; - nErrorLevel = 0; + nErrorLevel = 0; - arg = splitspace(param, &argc); - for (i = 0; i < argc; i++) - { - if (!_tcsicmp(arg[i], _T("enableextensions"))) - /* not implemented, ignore */; - else if (!_tcsicmp(arg[i], _T("disableextensions"))) - /* not implemented, ignore */; - else if (!_tcsicmp(arg[i], _T("enabledelayedexpansion"))) - bDelayedExpansion = TRUE; - else if (!_tcsicmp(arg[i], _T("disabledelayedexpansion"))) - bDelayedExpansion = FALSE; - else - { - error_invalid_parameter_format(arg[i]); - break; - } - } - freep(arg); + arg = splitspace(param, &argc); + for (i = 0; i < argc; i++) + { + if (!_tcsicmp(arg[i], _T("enableextensions"))) + /* not implemented, ignore */; + else if (!_tcsicmp(arg[i], _T("disableextensions"))) + /* not implemented, ignore */; + else if (!_tcsicmp(arg[i], _T("enabledelayedexpansion"))) + bDelayedExpansion = TRUE; + else if (!_tcsicmp(arg[i], _T("disabledelayedexpansion"))) + bDelayedExpansion = FALSE; + else + { + error_invalid_parameter_format(arg[i]); + break; + } + } + freep(arg); - return nErrorLevel; + return nErrorLevel; } /* endlocal doesn't take any params */ INT cmd_endlocal(LPTSTR param) { - LPTSTR Environ, Name, Value; - SETLOCAL *Saved; + LPTSTR Environ, Name, Value; + SETLOCAL *Saved; - /* Pop a SETLOCAL struct off of this batch file's stack */ - if (!bc || !(Saved = bc->setlocal)) - return 0; - bc->setlocal = Saved->Prev; + /* Pop a SETLOCAL struct off of this batch file's stack */ + if (!bc || !(Saved = bc->setlocal)) + return 0; + bc->setlocal = Saved->Prev; - bDelayedExpansion = Saved->DelayedExpansion; + bDelayedExpansion = Saved->DelayedExpansion; - /* First, clear out the environment. Since making any changes to the - * environment invalidates pointers obtained from GetEnvironmentStrings(), - * we must make a copy of it and get the variable names from that */ - Environ = DuplicateEnvironment(); - if (Environ) - { - for (Name = Environ; *Name; Name += _tcslen(Name) + 1) - { - if (!(Value = _tcschr(Name + 1, _T('=')))) - continue; - *Value++ = _T('\0'); - SetEnvironmentVariable(Name, NULL); - Name = Value; - } - cmd_free(Environ); - } + /* First, clear out the environment. Since making any changes to the + * environment invalidates pointers obtained from GetEnvironmentStrings(), + * we must make a copy of it and get the variable names from that */ + Environ = DuplicateEnvironment(); + if (Environ) + { + for (Name = Environ; *Name; Name += _tcslen(Name) + 1) + { + if (!(Value = _tcschr(Name + 1, _T('=')))) + continue; + *Value++ = _T('\0'); + SetEnvironmentVariable(Name, NULL); + Name = Value; + } + cmd_free(Environ); + } - /* Now, restore variables from the copy saved by cmd_setlocal */ - for (Name = Saved->Environment; *Name; Name += _tcslen(Name) + 1) - { - if (!(Value = _tcschr(Name + 1, _T('=')))) - continue; - *Value++ = _T('\0'); - SetEnvironmentVariable(Name, Value); - Name = Value; - } + /* Now, restore variables from the copy saved by cmd_setlocal */ + for (Name = Saved->Environment; *Name; Name += _tcslen(Name) + 1) + { + if (!(Value = _tcschr(Name + 1, _T('=')))) + continue; + *Value++ = _T('\0'); + SetEnvironmentVariable(Name, Value); + Name = Value; + } - cmd_free(Saved->Environment); - cmd_free(Saved); - return 0; + cmd_free(Saved->Environment); + cmd_free(Saved); + return 0; } diff --git a/base/shell/cmd/shift.c b/base/shell/cmd/shift.c index 9497e74e215..e3ce5b106d9 100644 --- a/base/shell/cmd/shift.c +++ b/base/shell/cmd/shift.c @@ -19,8 +19,8 @@ * 20-Jan-1999 (Eric Kohl) * Unicode and redirection safe! * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -37,48 +37,48 @@ INT cmd_shift (LPTSTR param) { - INT i = 0; - TRACE ("cmd_shift: (\'%s\')\n", debugstr_aw(param)); + INT i = 0; + TRACE ("cmd_shift: (\'%s\')\n", debugstr_aw(param)); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_SHIFT_HELP); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_SHIFT_HELP); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - if (bc == NULL) - { - /* not in batch - error!! */ - nErrorLevel = 1; - return 1; - } + if (bc == NULL) + { + /* not in batch - error!! */ + nErrorLevel = 1; + return 1; + } - if (!_tcsicmp (param, _T("down"))) - { - if (bc->shiftlevel[0]) - for (; i <= 9; i++) - bc->shiftlevel[i]--; - } - else /* shift up */ - { - if (*param == _T('/')) - { - if (param[1] < '0' || param[1] > '9') - { - error_invalid_switch(param[1]); - return 1; - } - i = param[1] - '0'; - } + if (!_tcsicmp (param, _T("down"))) + { + if (bc->shiftlevel[0]) + for (; i <= 9; i++) + bc->shiftlevel[i]--; + } + else /* shift up */ + { + if (*param == _T('/')) + { + if (param[1] < '0' || param[1] > '9') + { + error_invalid_switch(param[1]); + return 1; + } + i = param[1] - '0'; + } - for (; i < 9; i++) - bc->shiftlevel[i] = bc->shiftlevel[i + 1]; - bc->shiftlevel[i]++; - } + for (; i < 9; i++) + bc->shiftlevel[i] = bc->shiftlevel[i + 1]; + bc->shiftlevel[i]++; + } - return 0; + return 0; } /* EOF */ diff --git a/base/shell/cmd/start.c b/base/shell/cmd/start.c index e5d52dae685..de1b78f2fdf 100644 --- a/base/shell/cmd/start.c +++ b/base/shell/cmd/start.c @@ -7,8 +7,8 @@ * 24-Jul-1999 (Eric Kohl) * Started. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -19,303 +19,302 @@ * in place. (It's moved back one character, to make room for the nul) */ static TCHAR *GetParameter(TCHAR **pPointer) { - BOOL bInQuote = FALSE; - TCHAR *start = *pPointer; - TCHAR *p; - for (p = start; *p; p++) - { - if (!bInQuote && (*p == _T('/') || _istspace(*p))) - break; - bInQuote ^= (*p == _T('"')); - p[-1] = *p; - } - p[-1] = _T('\0'); - *pPointer = p; - return start - 1; + BOOL bInQuote = FALSE; + TCHAR *start = *pPointer; + TCHAR *p; + for (p = start; *p; p++) + { + if (!bInQuote && (*p == _T('/') || _istspace(*p))) + break; + bInQuote ^= (*p == _T('"')); + p[-1] = *p; + } + p[-1] = _T('\0'); + *pPointer = p; + return start - 1; } INT cmd_start (LPTSTR Rest) { - TCHAR szFullName[CMDLINE_LENGTH]; - TCHAR szUnquotedName[CMDLINE_LENGTH]; - TCHAR *param = NULL; - TCHAR *dot; - INT size; - LPTSTR comspec; - BOOL bWait = FALSE; - BOOL bBat = FALSE; - BOOL bCreate = FALSE; - TCHAR szFullCmdLine [CMDLINE_LENGTH]; - PROCESS_INFORMATION prci; - STARTUPINFO stui; + TCHAR szFullName[CMDLINE_LENGTH]; + TCHAR szUnquotedName[CMDLINE_LENGTH]; + TCHAR *param = NULL; + TCHAR *dot; + INT size; + LPTSTR comspec; + BOOL bWait = FALSE; + BOOL bBat = FALSE; + BOOL bCreate = FALSE; + TCHAR szFullCmdLine [CMDLINE_LENGTH]; + PROCESS_INFORMATION prci; + STARTUPINFO stui; #ifdef UNICODE - DWORD dwCreationFlags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT; + DWORD dwCreationFlags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT; #else - DWORD dwCreationFlags = CREATE_NEW_CONSOLE; + DWORD dwCreationFlags = CREATE_NEW_CONSOLE; #endif - DWORD dwAffinityMask = 0; - LPTSTR lpTitle = NULL; - LPTSTR lpDirectory = NULL; - LPTSTR lpEnvironment = NULL; - WORD wShowWindow = SW_SHOWNORMAL; + DWORD dwAffinityMask = 0; + LPTSTR lpTitle = NULL; + LPTSTR lpDirectory = NULL; + LPTSTR lpEnvironment = NULL; + WORD wShowWindow = SW_SHOWNORMAL; - while (1) - { - if (_istspace(*Rest)) - { - Rest++; - } - else if (*Rest == _T('"') && !lpTitle) - { - lpTitle = GetParameter(&Rest); - StripQuotes(lpTitle); - } - else if (*Rest == L'/') - { - LPTSTR option; - Rest++; - option = GetParameter(&Rest); - if (*option == _T('?')) - { - ConOutResPaging(TRUE,STRING_START_HELP1); - return 0; - } - else if (_totupper(*option) == _T('D')) - { - lpDirectory = option + 1; - if (!*lpDirectory) - { - while (_istspace(*Rest)) - Rest++; - lpDirectory = GetParameter(&Rest); - } - StripQuotes(lpDirectory); - } - else if (_totupper(*option) == _T('I')) - { - /* rest of the option is apparently ignored */ - lpEnvironment = lpOriginalEnvironment; - } - else if (!_tcsicmp(option, _T("MIN"))) - { - wShowWindow = SW_MINIMIZE; - } - else if (!_tcsicmp(option, _T("MAX"))) - { - wShowWindow = SW_MAXIMIZE; - } - else if (!_tcsicmp(option, _T("AFFINITY"))) - { - TCHAR *end; - while (_istspace(*Rest)) - Rest++; - option = GetParameter(&Rest); - /* Affinity mask is given in hexadecimal */ - dwAffinityMask = _tcstoul(option, &end, 16); - if (*end != _T('\0') || dwAffinityMask == 0 || - dwAffinityMask == (DWORD)-1) - { - ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, option); - return 1; - } - dwCreationFlags |= CREATE_SUSPENDED; - } - else if (!_tcsicmp(option, _T("B"))) - { - dwCreationFlags &= ~CREATE_NEW_CONSOLE; - dwCreationFlags |= CREATE_NEW_PROCESS_GROUP; - } - else if (!_tcsicmp(option, _T("LOW"))) - { - dwCreationFlags |= IDLE_PRIORITY_CLASS; - } - else if (!_tcsicmp(option, _T("NORMAL"))) - { - dwCreationFlags |= NORMAL_PRIORITY_CLASS; - } - else if (!_tcsicmp(option, _T("HIGH"))) - { - dwCreationFlags |= HIGH_PRIORITY_CLASS; - } - else if (!_tcsicmp(option, _T("REALTIME"))) - { - dwCreationFlags |= REALTIME_PRIORITY_CLASS; - } - else if (!_tcsicmp(option, _T("ABOVENORMAL"))) - { - dwCreationFlags |= ABOVE_NORMAL_PRIORITY_CLASS; - } - else if (!_tcsicmp(option, _T("BELOWNORMAL"))) - { - dwCreationFlags |= BELOW_NORMAL_PRIORITY_CLASS; - } - else if (!_tcsicmp(option, _T("SEPARATE"))) - { - dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; - } - else if (!_tcsicmp(option, _T("SHARED"))) - { - dwCreationFlags |= CREATE_SHARED_WOW_VDM; - } - else if (!_tcsicmp(option, _T("W")) || - !_tcsicmp(option, _T("WAIT"))) - { - bWait = TRUE; - } - else - { - ConErrResPrintf(STRING_TYPE_ERROR1, option); - return 0; - } - } - else - { - /* It's not an option - must be the beginning of - * the actual command. Leave the loop. */ - break; - } - } + while (1) + { + if (_istspace(*Rest)) + { + Rest++; + } + else if (*Rest == _T('"') && !lpTitle) + { + lpTitle = GetParameter(&Rest); + StripQuotes(lpTitle); + } + else if (*Rest == L'/') + { + LPTSTR option; + Rest++; + option = GetParameter(&Rest); + if (*option == _T('?')) + { + ConOutResPaging(TRUE,STRING_START_HELP1); + return 0; + } + else if (_totupper(*option) == _T('D')) + { + lpDirectory = option + 1; + if (!*lpDirectory) + { + while (_istspace(*Rest)) + Rest++; + lpDirectory = GetParameter(&Rest); + } + StripQuotes(lpDirectory); + } + else if (_totupper(*option) == _T('I')) + { + /* rest of the option is apparently ignored */ + lpEnvironment = lpOriginalEnvironment; + } + else if (!_tcsicmp(option, _T("MIN"))) + { + wShowWindow = SW_MINIMIZE; + } + else if (!_tcsicmp(option, _T("MAX"))) + { + wShowWindow = SW_MAXIMIZE; + } + else if (!_tcsicmp(option, _T("AFFINITY"))) + { + TCHAR *end; + while (_istspace(*Rest)) + Rest++; + option = GetParameter(&Rest); + /* Affinity mask is given in hexadecimal */ + dwAffinityMask = _tcstoul(option, &end, 16); + if (*end != _T('\0') || dwAffinityMask == 0 || + dwAffinityMask == (DWORD)-1) + { + ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, option); + return 1; + } + dwCreationFlags |= CREATE_SUSPENDED; + } + else if (!_tcsicmp(option, _T("B"))) + { + dwCreationFlags &= ~CREATE_NEW_CONSOLE; + dwCreationFlags |= CREATE_NEW_PROCESS_GROUP; + } + else if (!_tcsicmp(option, _T("LOW"))) + { + dwCreationFlags |= IDLE_PRIORITY_CLASS; + } + else if (!_tcsicmp(option, _T("NORMAL"))) + { + dwCreationFlags |= NORMAL_PRIORITY_CLASS; + } + else if (!_tcsicmp(option, _T("HIGH"))) + { + dwCreationFlags |= HIGH_PRIORITY_CLASS; + } + else if (!_tcsicmp(option, _T("REALTIME"))) + { + dwCreationFlags |= REALTIME_PRIORITY_CLASS; + } + else if (!_tcsicmp(option, _T("ABOVENORMAL"))) + { + dwCreationFlags |= ABOVE_NORMAL_PRIORITY_CLASS; + } + else if (!_tcsicmp(option, _T("BELOWNORMAL"))) + { + dwCreationFlags |= BELOW_NORMAL_PRIORITY_CLASS; + } + else if (!_tcsicmp(option, _T("SEPARATE"))) + { + dwCreationFlags |= CREATE_SEPARATE_WOW_VDM; + } + else if (!_tcsicmp(option, _T("SHARED"))) + { + dwCreationFlags |= CREATE_SHARED_WOW_VDM; + } + else if (!_tcsicmp(option, _T("W")) || + !_tcsicmp(option, _T("WAIT"))) + { + bWait = TRUE; + } + else + { + ConErrResPrintf(STRING_TYPE_ERROR1, option); + return 0; + } + } + else + { + /* It's not an option - must be the beginning of + * the actual command. Leave the loop. */ + break; + } + } - /* get comspec */ - comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR)); - if (comspec == NULL) - { - error_out_of_memory(); - return 1; - } - SetLastError(0); - size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH); - if(GetLastError() == ERROR_ENVVAR_NOT_FOUND) - { - _tcscpy(comspec, _T("cmd")); - } - else - { - if (size > MAX_PATH) - { - LPTSTR Oldcomspec = comspec; - comspec = cmd_realloc(comspec,size * sizeof(TCHAR) ); - if (comspec==NULL) - { - cmd_free(Oldcomspec); - return 1; - } - size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size); - } - } + /* get comspec */ + comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR)); + if (comspec == NULL) + { + error_out_of_memory(); + return 1; + } + SetLastError(0); + size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH); + if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) + { + _tcscpy(comspec, _T("cmd")); + } + else + { + if (size > MAX_PATH) + { + LPTSTR Oldcomspec = comspec; + comspec = cmd_realloc(comspec,size * sizeof(TCHAR) ); + if (comspec==NULL) + { + cmd_free(Oldcomspec); + return 1; + } + size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size); + } + } - nErrorLevel = 0; + nErrorLevel = 0; - if (!*Rest) - { - Rest = _T("cmd.exe"); - } - else - /* Parsing the command that gets called by start, and it's parameters */ - { - BOOL bInside = FALSE; - INT i; - /* find the end of the command and put the arguments in param */ - for (i = 0; Rest[i]; i++) - { - if (Rest[i] == _T('\"')) - bInside = !bInside; - if (_istspace(Rest[i]) && !bInside) - { - param = &Rest[i+1]; - Rest[i] = _T('\0'); - break; - } - } - } + if (!*Rest) + { + Rest = _T("cmd.exe"); + } + else + /* Parsing the command that gets called by start, and it's parameters */ + { + BOOL bInside = FALSE; + INT i; + /* find the end of the command and put the arguments in param */ + for (i = 0; Rest[i]; i++) + { + if (Rest[i] == _T('\"')) + bInside = !bInside; + if (_istspace(Rest[i]) && !bInside) + { + param = &Rest[i+1]; + Rest[i] = _T('\0'); + break; + } + } + } - _tcscpy(szUnquotedName, Rest); - StripQuotes(szUnquotedName); + _tcscpy(szUnquotedName, Rest); + StripQuotes(szUnquotedName); - /* get the PATH environment variable and parse it */ - /* search the PATH environment variable for the binary */ - if (SearchForExecutable(szUnquotedName, szFullName)) - { - /* check if this is a .BAT or .CMD file */ - dot = _tcsrchr(szFullName, _T('.')); - if (dot && (!_tcsicmp(dot, _T(".bat")) || !_tcsicmp(dot, _T(".cmd")))) - { - bBat = TRUE; - _stprintf(szFullCmdLine, _T("\"%s\" /K %s"), comspec, Rest); - TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest)); - } - else - { - TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest)); - _tcscpy(szFullCmdLine, szFullName); - } + /* get the PATH environment variable and parse it */ + /* search the PATH environment variable for the binary */ + if (SearchForExecutable(szUnquotedName, szFullName)) + { + /* check if this is a .BAT or .CMD file */ + dot = _tcsrchr(szFullName, _T('.')); + if (dot && (!_tcsicmp(dot, _T(".bat")) || !_tcsicmp(dot, _T(".cmd")))) + { + bBat = TRUE; + _stprintf(szFullCmdLine, _T("\"%s\" /K %s"), comspec, Rest); + TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest)); + } + else + { + TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest)); + _tcscpy(szFullCmdLine, szFullName); + } - /* build command line for CreateProcess() */ - if (param != NULL) - { - _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - _tcsncat(szFullCmdLine, param, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - } + /* build command line for CreateProcess() */ + if (param != NULL) + { + _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + _tcsncat(szFullCmdLine, param, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + } - /* fill startup info */ - memset (&stui, 0, sizeof (STARTUPINFO)); - stui.cb = sizeof (STARTUPINFO); - stui.dwFlags = STARTF_USESHOWWINDOW; - stui.lpTitle = lpTitle; - stui.wShowWindow = wShowWindow; + /* fill startup info */ + memset (&stui, 0, sizeof (STARTUPINFO)); + stui.cb = sizeof (STARTUPINFO); + stui.dwFlags = STARTF_USESHOWWINDOW; + stui.lpTitle = lpTitle; + stui.wShowWindow = wShowWindow; - bCreate = CreateProcess(bBat ? comspec : szFullName, - szFullCmdLine, NULL, NULL, TRUE, dwCreationFlags, - lpEnvironment, lpDirectory, &stui, &prci); - if (bCreate) - { - if (dwAffinityMask) - { - SetProcessAffinityMask(prci.hProcess, dwAffinityMask); - ResumeThread(prci.hThread); - } - CloseHandle(prci.hThread); - } - } - else - { - /* The file name did not seem to be valid, but maybe it's actually a - * directory or URL, so we still want to pass it to ShellExecute. */ - _tcscpy(szFullName, szUnquotedName); - } + bCreate = CreateProcess(bBat ? comspec : szFullName, + szFullCmdLine, NULL, NULL, TRUE, dwCreationFlags, + lpEnvironment, lpDirectory, &stui, &prci); + if (bCreate) + { + if (dwAffinityMask) + { + SetProcessAffinityMask(prci.hProcess, dwAffinityMask); + ResumeThread(prci.hThread); + } + CloseHandle(prci.hThread); + } + } + else + { + /* The file name did not seem to be valid, but maybe it's actually a + * directory or URL, so we still want to pass it to ShellExecute. */ + _tcscpy(szFullName, szUnquotedName); + } - if (!bCreate) - { - /* CreateProcess didn't work; try ShellExecute */ - DWORD flags = SEE_MASK_NOCLOSEPROCESS; - if (!(dwCreationFlags & CREATE_NEW_CONSOLE)) - flags |= SEE_MASK_NO_CONSOLE; - prci.hProcess = RunFile(flags, szFullName, param, lpDirectory, wShowWindow); - } + if (!bCreate) + { + /* CreateProcess didn't work; try ShellExecute */ + DWORD flags = SEE_MASK_NOCLOSEPROCESS; + if (!(dwCreationFlags & CREATE_NEW_CONSOLE)) + flags |= SEE_MASK_NO_CONSOLE; + prci.hProcess = RunFile(flags, szFullName, param, lpDirectory, wShowWindow); + } - if (prci.hProcess != NULL) - { - if (bWait) - { - DWORD dwExitCode; - WaitForSingleObject (prci.hProcess, INFINITE); - GetExitCodeProcess (prci.hProcess, &dwExitCode); - nErrorLevel = (INT)dwExitCode; - } - CloseHandle (prci.hProcess); - /* Get New code page if it has change */ - InputCodePage= GetConsoleCP(); + if (prci.hProcess != NULL) + { + if (bWait) + { + DWORD dwExitCode; + WaitForSingleObject (prci.hProcess, INFINITE); + GetExitCodeProcess (prci.hProcess, &dwExitCode); + nErrorLevel = (INT)dwExitCode; + } + CloseHandle (prci.hProcess); + /* Get New code page if it has change */ + InputCodePage= GetConsoleCP(); OutputCodePage = GetConsoleOutputCP(); - } - else - { - ErrorMessage(GetLastError (), - _T("Error executing CreateProcess()!!\n")); - } + } + else + { + ErrorMessage(GetLastError (), + _T("Error executing CreateProcess()!!\n")); + } - - cmd_free(comspec); - return 0; + cmd_free(comspec); + return 0; } #endif diff --git a/base/shell/cmd/strtoclr.c b/base/shell/cmd/strtoclr.c index f3b1fcf17ae..be7af272385 100644 --- a/base/shell/cmd/strtoclr.c +++ b/base/shell/cmd/strtoclr.c @@ -7,7 +7,6 @@ * 07-Oct-1999 (Paolo Pantaleo) * Started. * - * */ /* @@ -37,52 +36,52 @@ typedef struct _CLRTABLE { - LPTSTR name; - WORD val; + LPTSTR name; + WORD val; } CLRTABLE; CLRTABLE clrtable[] = { - {_T("bla"), 0 }, - {_T("blu"), _B }, - {_T("gre"), _G }, - {_T("cya"), _B|_G }, - {_T("red"), _R }, - {_T("mag"), _B|_R }, - {_T("yel"), _R|_G }, - {_T("whi"), _R|_G|_B }, - {_T("gra"), _I }, + {_T("bla"), 0 }, + {_T("blu"), _B }, + {_T("gre"), _G }, + {_T("cya"), _B|_G }, + {_T("red"), _R }, + {_T("mag"), _B|_R }, + {_T("yel"), _R|_G }, + {_T("whi"), _R|_G|_B }, + {_T("gra"), _I }, - {_T("0") , 0 }, - {_T("2") , _G }, - {_T("3") , _B|_G }, - {_T("4") , _R }, - {_T("5") , _B|_R }, - {_T("6") , _R|_G }, - {_T("7") , _R|_G|_B }, + {_T("0") , 0 }, + {_T("2") , _G }, + {_T("3") , _B|_G }, + {_T("4") , _R }, + {_T("5") , _B|_R }, + {_T("6") , _R|_G }, + {_T("7") , _R|_G|_B }, - {_T("8") , _I }, - {_T("9") , _I|_B }, - {_T("10") , _I|_G }, - {_T("11") , _I|_B|_G }, - {_T("12") , _I|_R }, - {_T("13") , _I|_B|_R }, - {_T("14") , _I|_R|_G }, - {_T("15") , _I|_R|_G|_B }, + {_T("8") , _I }, + {_T("9") , _I|_B }, + {_T("10") , _I|_G }, + {_T("11") , _I|_B|_G }, + {_T("12") , _I|_R }, + {_T("13") , _I|_B|_R }, + {_T("14") , _I|_R|_G }, + {_T("15") , _I|_R|_G|_B }, - /* + /* * Note that 1 is at the end of list - * to avoid to confuse it with 10-15 + * to avoid to confuse it with 10-15 */ - {_T("1") , _B }, + {_T("1") , _B }, - /* Cyan synonym */ - {_T("aqu"), _B|_G }, - /* Magenta synonym */ - {_T("pur"), _B|_R }, + /* Cyan synonym */ + {_T("aqu"), _B|_G }, + /* Magenta synonym */ + {_T("pur"), _B|_R }, - {_T("") ,0}, + {_T("") ,0}, }; @@ -93,28 +92,28 @@ CLRTABLE clrtable[] = static INT chop_blank(LPTSTR *arg_str) { - LPTSTR str; - str = _tcschr(*arg_str,_T(' ')); - if(!str) - { - str = _tcschr (*arg_str, _T('\0')); - if(str != NULL) - *arg_str=str; - return CP_BLANK_NOT_FOUND; - } + LPTSTR str; + str = _tcschr(*arg_str,_T(' ')); + if (!str) + { + str = _tcschr (*arg_str, _T('\0')); + if (str != NULL) + *arg_str=str; + return CP_BLANK_NOT_FOUND; + } - while(_istspace(*str)) - str++; + while(_istspace(*str)) + str++; - if (*str == _T('\0')) - { - *arg_str=str; - return CP_END_OF_STRING; - } + if (*str == _T('\0')) + { + *arg_str=str; + return CP_END_OF_STRING; + } - *arg_str = str; + *arg_str = str; - return CP_OK; + return CP_OK; } @@ -125,38 +124,38 @@ INT chop_blank(LPTSTR *arg_str) static WORD hex_clr(LPTSTR str) { - WORD ret= (WORD)-1; - TCHAR ch; + WORD ret= (WORD)-1; + TCHAR ch; - ch = str[1]; + ch = str[1]; - if(_istdigit(ch)) - ret = ch-_T('0'); - else - { - ch=_totupper(ch); + if (_istdigit(ch)) + ret = ch-_T('0'); + else + { + ch=_totupper(ch); - if( ch >= _T('A') && ch <= _T('F') ) - ret = ch-_T('A')+10; - else - return (WORD)-1; - } + if ( ch >= _T('A') && ch <= _T('F') ) + ret = ch-_T('A')+10; + else + return (WORD)-1; + } - ch = str[0]; + ch = str[0]; - if(_istdigit(ch)) - ret |= (ch-_T('0')) << 4; - else - { - ch=_totupper(ch); + if (_istdigit(ch)) + ret |= (ch-_T('0')) << 4; + else + { + ch=_totupper(ch); - if( ch >= _T('A') && ch <= _T('F') ) - ret |= (ch-_T('A')+10) <<4; - else - return (WORD)-1; - } + if ( ch >= _T('A') && ch <= _T('F') ) + ret |= (ch-_T('A')+10) <<4; + else + return (WORD)-1; + } - return ret; + return ret; } @@ -167,13 +166,13 @@ WORD hex_clr(LPTSTR str) static WORD txt_clr(LPTSTR str) { - INT i; + INT i; - for(i = 0; *(clrtable[i].name); i++) - if (_tcsnicmp(str, clrtable[i].name, _tcslen(clrtable[i].name)) == 0) - return clrtable[i].val; + for(i = 0; *(clrtable[i].name); i++) + if (_tcsnicmp(str, clrtable[i].name, _tcslen(clrtable[i].name)) == 0) + return clrtable[i].val; - return (WORD)-1; + return (WORD)-1; } @@ -181,58 +180,58 @@ WORD txt_clr(LPTSTR str) static WORD str_to_color(LPTSTR* arg_str) { - LPTSTR str; - BOOL bBri; + LPTSTR str; + BOOL bBri; - WORD tmp_clr,ret_clr; + WORD tmp_clr,ret_clr; - str = *arg_str; + str = *arg_str; - if (!(*str)) - return (WORD)-1; + if (!(*str)) + return (WORD)-1; - /* foreground */ - bBri = FALSE; + /* foreground */ + bBri = FALSE; - if (_tcsnicmp(str,_T("bri"),3) == 0) - { - bBri = TRUE; + if (_tcsnicmp(str,_T("bri"),3) == 0) + { + bBri = TRUE; - if (chop_blank(&str)) - return (WORD)-1; - } + if (chop_blank(&str)) + return (WORD)-1; + } - if ((tmp_clr = txt_clr(str)) == (WORD)-1) - { - return (WORD)-1; - } + if ((tmp_clr = txt_clr(str)) == (WORD)-1) + { + return (WORD)-1; + } - /* skip spaces and "on" keyword */ - if (chop_blank(&str) || chop_blank(&str)) - return (WORD)-1; + /* skip spaces and "on" keyword */ + if (chop_blank(&str) || chop_blank(&str)) + return (WORD)-1; - ret_clr = tmp_clr | (bBri << 3); + ret_clr = tmp_clr | (bBri << 3); - /* background */ - bBri = FALSE; + /* background */ + bBri = FALSE; - if(_tcsnicmp(str,_T("bri"),3) == 0 ) - { - bBri = TRUE; + if (_tcsnicmp(str,_T("bri"),3) == 0 ) + { + bBri = TRUE; - if(chop_blank(&str)) - return (WORD)-1; - } + if (chop_blank(&str)) + return (WORD)-1; + } - if( (tmp_clr = txt_clr(str)) == (WORD)-1 ) - return (WORD)-1; + if ( (tmp_clr = txt_clr(str)) == (WORD)-1 ) + return (WORD)-1; - chop_blank(&str); + chop_blank(&str); - *arg_str = str; + *arg_str = str; - /* NOTE: See the note on SC_HEX in the StringToColor()'s description */ - return /* SC_HEX | */ ret_clr | tmp_clr << 4 | bBri << 7; + /* NOTE: See the note on SC_HEX in the StringToColor()'s description */ + return /* SC_HEX | */ ret_clr | tmp_clr << 4 | bBri << 7; } @@ -255,20 +254,20 @@ WORD str_to_color(LPTSTR* arg_str) */ BOOL StringToColor(LPWORD lpColor, LPTSTR*str) { - WORD wRet; + WORD wRet; - wRet = str_to_color (str); - if (wRet == (WORD)-1) - { - wRet=hex_clr (*str); - chop_blank (str); - if (wRet == (WORD)-1) - return FALSE; - } + wRet = str_to_color (str); + if (wRet == (WORD)-1) + { + wRet=hex_clr (*str); + chop_blank (str); + if (wRet == (WORD)-1) + return FALSE; + } - *lpColor = wRet; + *lpColor = wRet; - return TRUE; + return TRUE; } /* EOF */ diff --git a/base/shell/cmd/time.c b/base/shell/cmd/time.c index c673818d14f..9ce3cc26ce4 100644 --- a/base/shell/cmd/time.c +++ b/base/shell/cmd/time.c @@ -20,8 +20,8 @@ * 04-Feb-1999 (Eric Kohl) * Fixed time input bug. * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc. + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc. */ #include "precomp.h" @@ -31,187 +31,187 @@ static BOOL ParseTime (LPTSTR s) { - SYSTEMTIME t; - LPTSTR p = s; + SYSTEMTIME t; + LPTSTR p = s; - if (!*s) - return TRUE; + if (!*s) + return TRUE; - GetLocalTime (&t); - t.wHour = 0; - t.wMinute = 0; - t.wSecond = 0; - t.wMilliseconds = 0; + GetLocalTime (&t); + t.wHour = 0; + t.wMinute = 0; + t.wSecond = 0; + t.wMilliseconds = 0; - // first get hour - if (_istdigit(*p)) - { - while (_istdigit(*p)) - { - t.wHour = t.wHour * 10 + *p - _T('0'); - p++; - } - } - else - return FALSE; + // first get hour + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + t.wHour = t.wHour * 10 + *p - _T('0'); + p++; + } + } + else + return FALSE; - // get time separator - if (*p != cTimeSeparator) - return FALSE; - p++; + // get time separator + if (*p != cTimeSeparator) + return FALSE; + p++; - // now get minutes - if (_istdigit(*p)) - { - while (_istdigit(*p)) - { - t.wMinute = t.wMinute * 10 + *p - _T('0'); - p++; - } - } - else - return FALSE; + // now get minutes + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + t.wMinute = t.wMinute * 10 + *p - _T('0'); + p++; + } + } + else + return FALSE; - // get time separator - if (*p != cTimeSeparator) - return FALSE; - p++; + // get time separator + if (*p != cTimeSeparator) + return FALSE; + p++; - // now get seconds - if (_istdigit(*p)) - { - while (_istdigit(*p)) - { - t.wSecond = t.wSecond * 10 + *p - _T('0'); - p++; - } - } - else - return FALSE; + // now get seconds + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + t.wSecond = t.wSecond * 10 + *p - _T('0'); + p++; + } + } + else + return FALSE; - // get decimal separator - if (*p == cDecimalSeparator) - { - p++; + // get decimal separator + if (*p == cDecimalSeparator) + { + p++; - // now get hundreths - if (_istdigit(*p)) - { - while (_istdigit(*p)) - { -// t.wMilliseconds = t.wMilliseconds * 10 + *p - _T('0'); - p++; - } -// t.wMilliseconds *= 10; - } - } + // now get hundreths + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + // t.wMilliseconds = t.wMilliseconds * 10 + *p - _T('0'); + p++; + } + // t.wMilliseconds *= 10; + } + } - /* special case: 12 hour format */ - if (nTimeFormat == 0) - { - if (_totupper(*s) == _T('P')) - { - t.wHour += 12; - } + /* special case: 12 hour format */ + if (nTimeFormat == 0) + { + if (_totupper(*s) == _T('P')) + { + t.wHour += 12; + } - if ((_totupper(*s) == _T('A')) && (t.wHour == 12)) - { - t.wHour = 0; - } - } + if ((_totupper(*s) == _T('A')) && (t.wHour == 12)) + { + t.wHour = 0; + } + } - if (t.wHour > 23 || t.wMinute > 60 || t.wSecond > 60 || t.wMilliseconds > 999) - return FALSE; + if (t.wHour > 23 || t.wMinute > 60 || t.wSecond > 60 || t.wMilliseconds > 999) + return FALSE; - SetLocalTime (&t); + SetLocalTime (&t); - return TRUE; + return TRUE; } INT cmd_time (LPTSTR param) { - LPTSTR *arg; - INT argc; - INT i; - INT nTimeString = -1; + LPTSTR *arg; + INT argc; + INT i; + INT nTimeString = -1; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_TIME_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_TIME_HELP1); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - /* build parameter array */ - arg = split (param, &argc, FALSE, FALSE); + /* build parameter array */ + arg = split (param, &argc, FALSE, FALSE); - /* check for options */ - for (i = 0; i < argc; i++) - { - if (_tcsicmp (arg[i], _T("/t")) == 0) - { - /* Display current time in short format */ - SYSTEMTIME st; - TCHAR szTime[20]; - GetLocalTime(&st); - FormatTime(szTime, &st); - ConOutPuts(szTime); - freep(arg); - return 0; - } + /* check for options */ + for (i = 0; i < argc; i++) + { + if (_tcsicmp (arg[i], _T("/t")) == 0) + { + /* Display current time in short format */ + SYSTEMTIME st; + TCHAR szTime[20]; + GetLocalTime(&st); + FormatTime(szTime, &st); + ConOutPuts(szTime); + freep(arg); + return 0; + } - if ((*arg[i] != _T('/')) && (nTimeString == -1)) - nTimeString = i; - } + if ((*arg[i] != _T('/')) && (nTimeString == -1)) + nTimeString = i; + } - if (nTimeString == -1) - { - ConOutResPrintf(STRING_LOCALE_HELP1); - ConOutPrintf(_T(": %s\n"), GetTimeString()); - } + if (nTimeString == -1) + { + ConOutResPrintf(STRING_LOCALE_HELP1); + ConOutPrintf(_T(": %s\n"), GetTimeString()); + } - while (1) - { - if (nTimeString == -1) - { - TCHAR s[40]; + while (1) + { + if (nTimeString == -1) + { + TCHAR s[40]; - ConOutResPuts(STRING_TIME_HELP2); + ConOutResPuts(STRING_TIME_HELP2); - ConInString (s, 40); + ConInString (s, 40); - TRACE ("\'%s\'\n", debugstr_aw(s)); + TRACE ("\'%s\'\n", debugstr_aw(s)); - while (*s && s[_tcslen (s) - 1] < _T(' ')) - s[_tcslen(s) - 1] = _T('\0'); + while (*s && s[_tcslen (s) - 1] < _T(' ')) + s[_tcslen(s) - 1] = _T('\0'); - if (ParseTime (s)) - { - freep (arg); - return 0; - } - } - else - { - if (ParseTime (arg[nTimeString])) - { - freep (arg); - return 0; - } + if (ParseTime (s)) + { + freep (arg); + return 0; + } + } + else + { + if (ParseTime (arg[nTimeString])) + { + freep (arg); + return 0; + } - /* force input the next time around. */ - nTimeString = -1; - } + /* force input the next time around. */ + nTimeString = -1; + } - ConErrResPuts(STRING_TIME_ERROR1); + ConErrResPuts(STRING_TIME_ERROR1); nErrorLevel = 1; - } + } - freep (arg); + freep (arg); - return 0; + return 0; } #endif diff --git a/base/shell/cmd/timer.c b/base/shell/cmd/timer.c index 02a2b2b786e..d1051b97874 100644 --- a/base/shell/cmd/timer.c +++ b/base/shell/cmd/timer.c @@ -30,189 +30,189 @@ static VOID PrintElapsedTime (DWORD time,INT format) { - DWORD h,m,s,ms; + DWORD h,m,s,ms; - TRACE ("PrintElapsedTime(%d,%d)",time,format); + TRACE ("PrintElapsedTime(%d,%d)",time,format); - switch (format) - { - case 0: - ConOutResPrintf(STRING_TIMER_HELP1, time); - break; + switch (format) + { + case 0: + ConOutResPrintf(STRING_TIMER_HELP1, time); + break; - case 1: - ms = time % 1000; - time /= 1000; - s = time % 60; - time /=60; - m = time % 60; - h = time / 60; - ConOutResPrintf(STRING_TIMER_HELP2, - h, cTimeSeparator, - m, cTimeSeparator, - s, cDecimalSeparator, ms/10); - break; - } + case 1: + ms = time % 1000; + time /= 1000; + s = time % 60; + time /=60; + m = time % 60; + h = time / 60; + ConOutResPrintf(STRING_TIMER_HELP2, + h, cTimeSeparator, + m, cTimeSeparator, + s, cDecimalSeparator, ms/10); + break; + } } INT CommandTimer (LPTSTR param) { - // all timers are kept - static DWORD clksT[10]; + // all timers are kept + static DWORD clksT[10]; - // timers status - // set all the clocks off by default - static BOOL clksS[10]={FALSE,FALSE,FALSE,FALSE, - FALSE,FALSE,FALSE,FALSE,FALSE,FALSE}; + // timers status + // set all the clocks off by default + static BOOL clksS[10]={FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE}; - // TRUE if /S in command line - BOOL bS = FALSE; + // TRUE if /S in command line + BOOL bS = FALSE; - // avoid to set clk_n more than once - BOOL bCanNSet = TRUE; + // avoid to set clk_n more than once + BOOL bCanNSet = TRUE; - INT NewClkStatus = NCS_NOT_SPECIFIED; + INT NewClkStatus = NCS_NOT_SPECIFIED; - // the clock number specified on the command line - // 1 by default - INT clk_n=1; + // the clock number specified on the command line + // 1 by default + INT clk_n=1; - // output format - INT iFormat=1; + // output format + INT iFormat=1; - // command line parsing variables - INT argc; - LPTSTR *p; + // command line parsing variables + INT argc; + LPTSTR *p; - INT i; + INT i; - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPrintf(STRING_TIMER_HELP3, cTimeSeparator, cTimeSeparator, cDecimalSeparator); - return 0; - } + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPrintf(STRING_TIMER_HELP3, cTimeSeparator, cTimeSeparator, cDecimalSeparator); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - p = split (param, &argc, FALSE, FALSE); + p = split (param, &argc, FALSE, FALSE); - //read options - for (i = 0; i < argc; i++) - { - //set timer on - if (!(_tcsicmp(&p[i][0],_T("on"))) && NewClkStatus == NCS_NOT_SPECIFIED) - { - NewClkStatus = NCS_ON; - continue; - } + //read options + for (i = 0; i < argc; i++) + { + //set timer on + if (!(_tcsicmp(&p[i][0],_T("on"))) && NewClkStatus == NCS_NOT_SPECIFIED) + { + NewClkStatus = NCS_ON; + continue; + } - //set timer off - if (!(_tcsicmp(&p[i][0],_T("off"))) && NewClkStatus == NCS_NOT_SPECIFIED) - { - NewClkStatus = NCS_OFF; - continue; - } + //set timer off + if (!(_tcsicmp(&p[i][0],_T("off"))) && NewClkStatus == NCS_NOT_SPECIFIED) + { + NewClkStatus = NCS_OFF; + continue; + } - // other options - if (p[i][0] == _T('/')) - { - // set timer number - if (_istdigit(p[i][1]) && bCanNSet) - { - clk_n = p[i][1] - _T('0'); - bCanNSet = FALSE; - continue; - } + // other options + if (p[i][0] == _T('/')) + { + // set timer number + if (_istdigit(p[i][1]) && bCanNSet) + { + clk_n = p[i][1] - _T('0'); + bCanNSet = FALSE; + continue; + } - // set s(plit) option - if (_totupper(p[i][1]) == _T('S')) - { - bS = TRUE; - continue; - } + // set s(plit) option + if (_totupper(p[i][1]) == _T('S')) + { + bS = TRUE; + continue; + } - // specify format - if (_totupper(p[i][1]) == _T('F')) - { - iFormat = p[i][2] - _T('0'); - continue; - } - } - } + // specify format + if (_totupper(p[i][1]) == _T('F')) + { + iFormat = p[i][2] - _T('0'); + continue; + } + } + } - // do stuff (start/stop/read timer) - if(NewClkStatus == NCS_ON) - { - cT=GetTickCount(); - cS=TRUE; + // do stuff (start/stop/read timer) + if (NewClkStatus == NCS_ON) + { + cT=GetTickCount(); + cS=TRUE; ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPuts(GetTimeString()); - freep(p); - return 0; - } + ConOutPuts(GetTimeString()); + freep(p); + return 0; + } - if(bS) - { - if(cS) - { + if (bS) + { + if (cS) + { ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPrintf(_T("%s\n"), GetTimeString()); - PrintElapsedTime(GetTickCount()-cT, iFormat); - freep(p); - return 0; - } + ConOutPrintf(_T("%s\n"), GetTimeString()); + PrintElapsedTime(GetTickCount()-cT, iFormat); + freep(p); + return 0; + } - cT=GetTickCount(); - cS=TRUE; - ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPuts(GetTimeString()); - freep(p); - return 0; - } + cT=GetTickCount(); + cS=TRUE; + ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); + ConOutPuts(GetTimeString()); + freep(p); + return 0; + } - if (NewClkStatus == NCS_NOT_SPECIFIED) - { - if (cS) - { - cS=FALSE; - ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPrintf(_T("%s\n"), GetTimeString()); - PrintElapsedTime(GetTickCount()-cT, iFormat); - freep(p); - return 0; - } + if (NewClkStatus == NCS_NOT_SPECIFIED) + { + if (cS) + { + cS=FALSE; + ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); + ConOutPrintf(_T("%s\n"), GetTimeString()); + PrintElapsedTime(GetTickCount()-cT, iFormat); + freep(p); + return 0; + } - cT=GetTickCount(); - cS=TRUE; - ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPuts(GetTimeString()); - freep(p); - return 0; - } + cT=GetTickCount(); + cS=TRUE; + ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); + ConOutPuts(GetTimeString()); + freep(p); + return 0; + } - if (NewClkStatus == NCS_OFF) - { - if (cS) - { - cS=FALSE; - ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPrintf(_T("%s\n"), GetTimeString()); - PrintElapsedTime(GetTickCount()-cT, iFormat); - freep(p); - return 0; - } - ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); - ConOutPuts(GetTimeString()); - freep(p); - return 0; - } + if (NewClkStatus == NCS_OFF) + { + if (cS) + { + cS=FALSE; + ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); + ConOutPrintf(_T("%s\n"), GetTimeString()); + PrintElapsedTime(GetTickCount()-cT, iFormat); + freep(p); + return 0; + } + ConOutResPrintf (STRING_TIMER_TIME,clk_n,cS?_T("ON"):_T("OFF")); + ConOutPuts(GetTimeString()); + freep(p); + return 0; + } - freep(p); - return 0; + freep(p); + return 0; } #endif /* INCLUDE_CMD_TIMER */ diff --git a/base/shell/cmd/title.c b/base/shell/cmd/title.c index 7eddaa2ab97..1fa9179fe3e 100644 --- a/base/shell/cmd/title.c +++ b/base/shell/cmd/title.c @@ -3,10 +3,10 @@ * * * History: - * 1999-02-11 Emanuele Aliberti + * 1999-02-11 Emanuele Aliberti * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -16,19 +16,18 @@ INT cmd_title (LPTSTR param) { + /* Do nothing if no args */ + if (*param == _T('\0')) + return 0; - /* Do nothing if no args */ - if (*param == _T('\0')) - return 0; + /* Asking help? */ + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_TITLE_HELP); + return 0; + } - /* Asking help? */ - if (!_tcsncmp(param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_TITLE_HELP); - return 0; - } - - return SetConsoleTitle (param); + return SetConsoleTitle (param); } #endif /* def INCLUDE_CMD_TITLE */ diff --git a/base/shell/cmd/todo.txt b/base/shell/cmd/todo.txt index a67a2b55a4c..f73d70591b5 100644 --- a/base/shell/cmd/todo.txt +++ b/base/shell/cmd/todo.txt @@ -1,21 +1,21 @@ Things to do ~~~~~~~~~~~~ -*Implmenet Set /P -This is pretty straight forward. When doing this make sure to take into account the way MS handles "set /A /P foo=5" compared to "set /P /A foo=5". +*Implement Set /P +This is pretty straightforward. When doing this, make sure to take into account the way MS handles "set /A /P foo=5" compared to "set /P /A foo=5". *Compile as unicode -Not sure what is wrong with it, put probably more then just one thing blocking this. For sure pipes break when it is compiled as unicode. +Not sure what is wrong with it, but probably more than just one thing blocking this. For sure pipes break when it is compiled as unicode. *Move.c code clean up -It works, but it needs to be cleaned up, the code is long and overly complex for what it needs to do. Also, we can remove the hack to cover for MoveFileEx bug as it isn't a bug anymore. +It works, but it needs to be cleaned up, the code is long and overly complex for what it needs to do. Also, we can remove the hack to cover for MoveFileEx bug as it isn't a bug anymore. *If rewrite -It works decent but looks _awful_. Very hard to maintain and/or understand what the hell is going on. +It works decent but looks _awful_. Very hard to maintain and/or understand what the hell is going on. *Remove Hardcoded buffers -This is mostly done thanks to Greatlord(cmd.c is the hardest spot that is left). ANytime when you are handling a string that is taken from the commandline there should be no limit to the size. +This is mostly done thanks to Greatlord (cmd.c is the hardest spot that is left). Anytime when you are handling a string that is taken from the commandline there should be no limit to the size. -*Implment & and && +*Implement & and && & runs two commands no matter what. && runs the 2nd command only if the first was a success Not sure where to put this code even diff --git a/base/shell/cmd/type.c b/base/shell/cmd/type.c index ddf6d8a4f7b..6b26eb54bd3 100644 --- a/base/shell/cmd/type.c +++ b/base/shell/cmd/type.c @@ -22,8 +22,8 @@ * 19-Jan-1999 (Paolo Pantaleo ) * Added multiple file support (copied from y.c) * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -33,108 +33,106 @@ INT cmd_type (LPTSTR param) { - TCHAR buff[256]; - HANDLE hFile, hConsoleOut; - DWORD dwRet; - INT argc,i; - LPTSTR *argv; - LPTSTR errmsg; - BOOL bPaging = FALSE; - BOOL bFirstTime = TRUE; + TCHAR buff[256]; + HANDLE hFile, hConsoleOut; + DWORD dwRet; + INT argc,i; + LPTSTR *argv; + LPTSTR errmsg; + BOOL bPaging = FALSE; + BOOL bFirstTime = TRUE; - hConsoleOut=GetStdHandle (STD_OUTPUT_HANDLE); + hConsoleOut=GetStdHandle (STD_OUTPUT_HANDLE); - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_TYPE_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_TYPE_HELP1); + return 0; + } - if (!*param) - { - error_req_param_missing (); - return 1; - } + if (!*param) + { + error_req_param_missing (); + return 1; + } - argv = split (param, &argc, TRUE, FALSE); + argv = split (param, &argc, TRUE, FALSE); - for(i = 0; i < argc; i++) - { - if(*argv[i] == _T('/') && _tcslen(argv[i]) >= 2 && _totupper(argv[i][1]) == _T('P')) - { - bPaging = TRUE; - } - } + for(i = 0; i < argc; i++) + { + if(*argv[i] == _T('/') && _tcslen(argv[i]) >= 2 && _totupper(argv[i][1]) == _T('P')) + { + bPaging = TRUE; + } + } - for (i = 0; i < argc; i++) - { - if (_T('/') == argv[i][0] && _totupper(argv[i][1]) != _T('P')) - { - ConErrResPrintf(STRING_TYPE_ERROR1, argv[i] + 1); - continue; - } + for (i = 0; i < argc; i++) + { + if (_T('/') == argv[i][0] && _totupper(argv[i][1]) != _T('P')) + { + ConErrResPrintf(STRING_TYPE_ERROR1, argv[i] + 1); + continue; + } - nErrorLevel = 0; + nErrorLevel = 0; - hFile = CreateFile(argv[i], - GENERIC_READ, - FILE_SHARE_READ,NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL,NULL); + hFile = CreateFile(argv[i], + GENERIC_READ, + FILE_SHARE_READ,NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL,NULL); - if(hFile == INVALID_HANDLE_VALUE) - { - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &errmsg, - 0, - NULL); - ConErrPrintf (_T("%s - %s"), argv[i], errmsg); - LocalFree (errmsg); - nErrorLevel = 1; - continue; - } + if(hFile == INVALID_HANDLE_VALUE) + { + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &errmsg, + 0, + NULL); + ConErrPrintf (_T("%s - %s"), argv[i], errmsg); + LocalFree (errmsg); + nErrorLevel = 1; + continue; + } - if (bPaging) - { - while (FileGetString (hFile, buff, sizeof(buff) / sizeof(TCHAR))) - { - if (ConOutPrintfPaging(bFirstTime, _T("%s"), buff) == 1) - { - bCtrlBreak = FALSE; - CloseHandle(hFile); - freep(argv); - return 0; - } - bFirstTime = FALSE; - } - } - else - { - while (ReadFile(hFile, buff, sizeof(buff), &dwRet, NULL) && dwRet > 0) - { - WriteFile(hConsoleOut, buff, dwRet, &dwRet, NULL); - if (bCtrlBreak) - { - bCtrlBreak = FALSE; - CloseHandle(hFile); - freep(argv); - return 0; - } - } - } + if (bPaging) + { + while (FileGetString (hFile, buff, sizeof(buff) / sizeof(TCHAR))) + { + if (ConOutPrintfPaging(bFirstTime, _T("%s"), buff) == 1) + { + bCtrlBreak = FALSE; + CloseHandle(hFile); + freep(argv); + return 0; + } + bFirstTime = FALSE; + } + } + else + { + while (ReadFile(hFile, buff, sizeof(buff), &dwRet, NULL) && dwRet > 0) + { + WriteFile(hConsoleOut, buff, dwRet, &dwRet, NULL); + if (bCtrlBreak) + { + bCtrlBreak = FALSE; + CloseHandle(hFile); + freep(argv); + return 0; + } + } + } - ConOutPuts(_T("\n")); - CloseHandle(hFile); - } + CloseHandle(hFile); + } - freep (argv); - - return 0; + freep(argv); + return 0; } #endif diff --git a/base/shell/cmd/ver.c b/base/shell/cmd/ver.c index fa70c57dc43..931e406f26b 100644 --- a/base/shell/cmd/ver.c +++ b/base/shell/cmd/ver.c @@ -27,101 +27,98 @@ VOID ShortVersion (VOID) { - OSVERSIONINFO VersionInfo; + OSVERSIONINFO VersionInfo; - ConOutResPrintf(STRING_CMD_SHELLINFO, _T(KERNEL_RELEASE_STR), _T(KERNEL_VERSION_BUILD_STR)); - VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + ConOutResPrintf(STRING_CMD_SHELLINFO, _T(KERNEL_RELEASE_STR), _T(KERNEL_VERSION_BUILD_STR)); + VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - memset(VersionInfo.szCSDVersion, 0, sizeof(VersionInfo.szCSDVersion)); - if (GetVersionEx(&VersionInfo)) - { - LPTSTR RosVersion; - SIZE_T RosVersionLen; + memset(VersionInfo.szCSDVersion, 0, sizeof(VersionInfo.szCSDVersion)); + if (GetVersionEx(&VersionInfo)) + { + LPTSTR RosVersion; + SIZE_T RosVersionLen; - RosVersion = VersionInfo.szCSDVersion + _tcslen(VersionInfo.szCSDVersion) + 1; - RosVersionLen = sizeof(VersionInfo.szCSDVersion) / sizeof(VersionInfo.szCSDVersion[0]) - - (RosVersion - VersionInfo.szCSDVersion); - if (7 <= RosVersionLen && 0 == _tcsnicmp(RosVersion, _T("ReactOS"), 7)) - { - ConOutResPrintf(STRING_VERSION_RUNVER, RosVersion); - } - } - ConOutPuts (_T("\n")); + RosVersion = VersionInfo.szCSDVersion + _tcslen(VersionInfo.szCSDVersion) + 1; + RosVersionLen = sizeof(VersionInfo.szCSDVersion) / sizeof(VersionInfo.szCSDVersion[0]) - + (RosVersion - VersionInfo.szCSDVersion); + if (7 <= RosVersionLen && 0 == _tcsnicmp(RosVersion, _T("ReactOS"), 7)) + { + ConOutResPrintf(STRING_VERSION_RUNVER, RosVersion); + } + } + ConOutChar(_T('\n')); } #ifdef INCLUDE_CMD_VER /* - * display shell version info internal command. - * - * + * display shell version info internal command. */ INT cmd_ver (LPTSTR param) { - INT i; + INT i; - nErrorLevel = 0; + nErrorLevel = 0; - if (_tcsstr (param, _T("/?")) != NULL) - { - ConOutResPaging(TRUE,STRING_VERSION_HELP1); - return 0; - } + if (_tcsstr (param, _T("/?")) != NULL) + { + ConOutResPaging(TRUE,STRING_VERSION_HELP1); + return 0; + } - ShortVersion(); + ShortVersion(); - /* Basic copyright notice */ - if (param[0] != _T('\0')) - { + /* Basic copyright notice */ + if (param[0] != _T('\0')) + { + ConOutPuts(_T("Copyright (C) 1994-1998 Tim Norman and others.\n")); + ConOutPuts(_T("Copyright (C) 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team\n")); - ConOutPuts (_T("Copyright (C) 1994-1998 Tim Norman and others.")); - ConOutPuts (_T("Copyright (C) 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team")); + for (i = 0; param[i]; i++) + { + /* skip spaces */ + if (param[i] == _T(' ')) + continue; - for (i = 0; param[i]; i++) - { - /* skip spaces */ - if (param[i] == _T(' ')) - continue; + if (param[i] == _T('/')) + { + /* is this a lone '/' ? */ + if (param[i + 1] == 0) + { + error_invalid_switch (_T(' ')); + return 1; + } + continue; + } - if (param[i] == _T('/')) - { - /* is this a lone '/' ? */ - if (param[i + 1] == 0) - { - error_invalid_switch (_T(' ')); - return 1; - } - continue; - } - - if (_totupper (param[i]) == _T('W')) - { - /* Warranty notice */ - ConOutResPuts(STRING_VERSION_HELP3); - } - else if (_totupper (param[i]) == _T('R')) - { - /* Redistribution notice */ - ConOutResPuts(STRING_VERSION_HELP4); - } - else if (_totupper (param[i]) == _T('C')) - { - /* Developer listing */ - ConOutResPuts(STRING_VERSION_HELP6); - ConOutResPuts(STRING_FREEDOS_DEV); - ConOutResPuts(STRING_VERSION_HELP7); + if (_totupper (param[i]) == _T('W')) + { + /* Warranty notice */ + ConOutResPuts(STRING_VERSION_HELP3); + } + else if (_totupper (param[i]) == _T('R')) + { + /* Redistribution notice */ + ConOutResPuts(STRING_VERSION_HELP4); + } + else if (_totupper (param[i]) == _T('C')) + { + /* Developer listing */ + ConOutResPuts(STRING_VERSION_HELP6); + ConOutResPuts(STRING_FREEDOS_DEV); + ConOutResPuts(STRING_VERSION_HELP7); ConOutResPuts(STRING_REACTOS_DEV); - } - else - { - error_invalid_switch ((TCHAR)_totupper (param[i])); - return 1; - } - } - ConOutResPuts(STRING_VERSION_HELP5); - } - return 0; + } + else + { + error_invalid_switch ((TCHAR)_totupper (param[i])); + return 1; + } + } + ConOutResPuts(STRING_VERSION_HELP5); + } + return 0; } #endif diff --git a/base/shell/cmd/verify.c b/base/shell/cmd/verify.c index bebb7559094..eabb03bdfe3 100644 --- a/base/shell/cmd/verify.c +++ b/base/shell/cmd/verify.c @@ -14,8 +14,8 @@ * 20-Jan-1999 (Eric Kohl) * Unicode and redirection ready! * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" @@ -29,19 +29,19 @@ static BOOL bVerify = FALSE; INT cmd_verify (LPTSTR param) { - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_VERIFY_HELP1); - return 0; - } + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_VERIFY_HELP1); + return 0; + } - if (!OnOffCommand(param, &bVerify, STRING_VERIFY_HELP2)) - { - ConErrResPuts(STRING_VERIFY_HELP3); - return nErrorLevel = 1; - } + if (!OnOffCommand(param, &bVerify, STRING_VERIFY_HELP2)) + { + ConErrResPuts(STRING_VERIFY_HELP3); + return nErrorLevel = 1; + } - return nErrorLevel = 0; + return nErrorLevel = 0; } #endif diff --git a/base/shell/cmd/vol.c b/base/shell/cmd/vol.c index d7b5e07b5ec..eed27c9dd57 100644 --- a/base/shell/cmd/vol.c +++ b/base/shell/cmd/vol.c @@ -28,85 +28,87 @@ static INT PrintVolumeHeader (LPTSTR pszRootPath) { - TCHAR szVolName[80]; - DWORD dwSerialNr; + TCHAR szVolName[80]; + DWORD dwSerialNr; - /* get the volume information of the drive */ - if(!GetVolumeInformation (pszRootPath, - szVolName, - 80, - &dwSerialNr, - NULL, - NULL, - NULL, - 0)) - { - ErrorMessage (GetLastError (), _T("")); - return 1; - } + /* get the volume information of the drive */ + if (!GetVolumeInformation(pszRootPath, + szVolName, + 80, + &dwSerialNr, + NULL, + NULL, + NULL, + 0)) + { + ErrorMessage(GetLastError (), _T("")); + return 1; + } - /* print drive info */ - if (szVolName[0] != '\0') - { - ConOutResPrintf(STRING_VOL_HELP1, pszRootPath[0],szVolName); - } - else - { - ConOutResPrintf(STRING_VOL_HELP2, pszRootPath[0]); - } + /* print drive info */ + if (szVolName[0] != '\0') + { + ConOutResPrintf(STRING_VOL_HELP1, pszRootPath[0],szVolName); + } + else + { + ConOutResPrintf(STRING_VOL_HELP2, pszRootPath[0]); + } - /* print the volume serial number */ - ConOutResPrintf(STRING_VOL_HELP3, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); - return 0; + /* print the volume serial number */ + ConOutResPrintf(STRING_VOL_HELP3, HIWORD(dwSerialNr), LOWORD(dwSerialNr)); + return 0; } INT cmd_vol (LPTSTR param) { - TCHAR szRootPath[] = _T("A:\\"); - TCHAR szPath[MAX_PATH]; + TCHAR szRootPath[] = _T("A:\\"); + TCHAR szPath[MAX_PATH]; - if (!_tcsncmp (param, _T("/?"), 2)) - { - ConOutResPaging(TRUE,STRING_VOL_HELP4); - return 0; - } + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutResPaging(TRUE,STRING_VOL_HELP4); + return 0; + } - nErrorLevel = 0; + nErrorLevel = 0; - if (param[0] == _T('\0')) - { - GetCurrentDirectory (MAX_PATH, szPath); - szRootPath[0] = szPath[0]; - } - else - { - _tcsupr (param); - if (param[1] == _T(':')) - szRootPath[0] = param[0]; - else - { - error_invalid_drive (); - nErrorLevel = 1; - return 1; - } - } + if (param[0] == _T('\0')) + { + GetCurrentDirectory(MAX_PATH, szPath); + szRootPath[0] = szPath[0]; + } + else + { + _tcsupr (param); + if (param[1] == _T(':')) + { + szRootPath[0] = param[0]; + } + else + { + error_invalid_drive (); + nErrorLevel = 1; + return 1; + } + } - if (!IsValidPathName (szRootPath)) - { - error_invalid_drive (); - nErrorLevel = 1; - return 1; - } + if (!IsValidPathName (szRootPath)) + { + error_invalid_drive (); + nErrorLevel = 1; + return 1; + } - /* print the header */ - if (!PrintVolumeHeader (szRootPath)) - { - nErrorLevel = 1; - return 1; - } + /* print the header */ + if (!PrintVolumeHeader (szRootPath)) + { + nErrorLevel = 1; + return 1; + } - return 0; + return 0; } #endif diff --git a/base/shell/cmd/where.c b/base/shell/cmd/where.c index 99463571d5b..dfe4d6d2ffb 100644 --- a/base/shell/cmd/where.c +++ b/base/shell/cmd/where.c @@ -69,7 +69,7 @@ * Some minor changes and improvements. * * 10-Jul-2004 (Jens Collin ) - * Fixed searxhing for files with specific extensions in PATHEXT order.. + * Fixed searching for files with specific extensions in PATHEXT order. * */ @@ -85,127 +85,127 @@ BOOL SearchForExecutableSingle (LPCTSTR pFileName, LPTSTR pFullName, LPTSTR pPathExt, LPTSTR pDirectory) { - TCHAR szPathBuffer[CMDLINE_LENGTH], *pszPathEnd; - LPTSTR s,f; - /* initialize full name buffer */ - *pFullName = _T('\0'); + TCHAR szPathBuffer[CMDLINE_LENGTH], *pszPathEnd; + LPTSTR s,f; + /* initialize full name buffer */ + *pFullName = _T('\0'); - TRACE ("SearchForExecutableSingle: \'%s\' in dir: \'%s\'\n", - debugstr_aw(pFileName), debugstr_aw(pDirectory)); + TRACE ("SearchForExecutableSingle: \'%s\' in dir: \'%s\'\n", + debugstr_aw(pFileName), debugstr_aw(pDirectory)); - pszPathEnd = szPathBuffer; - if (pDirectory != NULL) - { - _tcscpy(szPathBuffer, pDirectory); - pszPathEnd += _tcslen(pszPathEnd); - *pszPathEnd++ = _T('\\'); - } - _tcscpy(pszPathEnd, pFileName); - pszPathEnd += _tcslen(pszPathEnd); + pszPathEnd = szPathBuffer; + if (pDirectory != NULL) + { + _tcscpy(szPathBuffer, pDirectory); + pszPathEnd += _tcslen(pszPathEnd); + *pszPathEnd++ = _T('\\'); + } + _tcscpy(pszPathEnd, pFileName); + pszPathEnd += _tcslen(pszPathEnd); - if (IsExistingFile (szPathBuffer)) - { - TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer)); - _tcscpy (pFullName, szPathBuffer); - return TRUE; - } + if (IsExistingFile (szPathBuffer)) + { + TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer)); + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } - s = pPathExt; - while (s && *s) - { - f = _tcschr (s, _T(';')); + s = pPathExt; + while (s && *s) + { + f = _tcschr (s, _T(';')); - if (f) - { - _tcsncpy (pszPathEnd, s, (size_t)(f-s)); - pszPathEnd[f-s] = _T('\0'); - s = f + 1; - } - else - { - _tcscpy (pszPathEnd, s); - s = NULL; - } + if (f) + { + _tcsncpy (pszPathEnd, s, (size_t)(f-s)); + pszPathEnd[f-s] = _T('\0'); + s = f + 1; + } + else + { + _tcscpy (pszPathEnd, s); + s = NULL; + } - if (IsExistingFile (szPathBuffer)) - { - TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer)); - _tcscpy (pFullName, szPathBuffer); - return TRUE; - } - } - return FALSE; + if (IsExistingFile (szPathBuffer)) + { + TRACE ("Found: \'%s\'\n", debugstr_aw(szPathBuffer)); + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } + } + return FALSE; } BOOL SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName) { - static TCHAR pszDefaultPathExt[] = _T(".com;.exe;.bat;.cmd"); - LPTSTR pszPathExt, pszPath; - LPTSTR pCh; - DWORD dwBuffer; - TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName)); + static TCHAR pszDefaultPathExt[] = _T(".com;.exe;.bat;.cmd"); + LPTSTR pszPathExt, pszPath; + LPTSTR pCh; + DWORD dwBuffer; + TRACE ("SearchForExecutable: \'%s\'\n", debugstr_aw(pFileName)); - /* load environment varable PATHEXT */ - pszPathExt = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); - dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, ENV_BUFFER_SIZE); - if (dwBuffer > ENV_BUFFER_SIZE) - { - pszPathExt = (LPTSTR)cmd_realloc (pszPathExt, dwBuffer * sizeof (TCHAR)); - GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, dwBuffer); - _tcslwr(pszPathExt); - } - else if (0 == dwBuffer) - { - _tcscpy(pszPathExt, pszDefaultPathExt); - } - else - { - _tcslwr(pszPathExt); - } + /* load environment varable PATHEXT */ + pszPathExt = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); + dwBuffer = GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, ENV_BUFFER_SIZE); + if (dwBuffer > ENV_BUFFER_SIZE) + { + pszPathExt = (LPTSTR)cmd_realloc (pszPathExt, dwBuffer * sizeof (TCHAR)); + GetEnvironmentVariable (_T("PATHEXT"), pszPathExt, dwBuffer); + _tcslwr(pszPathExt); + } + else if (0 == dwBuffer) + { + _tcscpy(pszPathExt, pszDefaultPathExt); + } + else + { + _tcslwr(pszPathExt); + } - /* Check if valid directly on specified path */ - if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, NULL)) - { - cmd_free(pszPathExt); - return TRUE; - } + /* Check if valid directly on specified path */ + if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, NULL)) + { + cmd_free(pszPathExt); + return TRUE; + } - /* If an explicit directory was given, stop here - no need to search PATH. */ - if (pFileName[1] == _T(':') || _tcschr(pFileName, _T('\\'))) - { - cmd_free(pszPathExt); - return FALSE; - } + /* If an explicit directory was given, stop here - no need to search PATH. */ + if (pFileName[1] == _T(':') || _tcschr(pFileName, _T('\\'))) + { + cmd_free(pszPathExt); + return FALSE; + } - /* load environment varable PATH into buffer */ - pszPath = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); - dwBuffer = GetEnvironmentVariable (_T("PATH"), pszPath, ENV_BUFFER_SIZE); - if (dwBuffer > ENV_BUFFER_SIZE) - { - pszPath = (LPTSTR)cmd_realloc (pszPath, dwBuffer * sizeof (TCHAR)); - GetEnvironmentVariable (_T("PATH"), pszPath, dwBuffer); - } + /* load environment varable PATH into buffer */ + pszPath = (LPTSTR)cmd_alloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); + dwBuffer = GetEnvironmentVariable (_T("PATH"), pszPath, ENV_BUFFER_SIZE); + if (dwBuffer > ENV_BUFFER_SIZE) + { + pszPath = (LPTSTR)cmd_realloc (pszPath, dwBuffer * sizeof (TCHAR)); + GetEnvironmentVariable (_T("PATH"), pszPath, dwBuffer); + } - TRACE ("SearchForExecutable(): Loaded PATH: %s\n", debugstr_aw(pszPath)); + TRACE ("SearchForExecutable(): Loaded PATH: %s\n", debugstr_aw(pszPath)); - /* search in PATH */ - pCh = _tcstok(pszPath, _T(";")); - while (pCh) - { - if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, pCh)) - { - cmd_free(pszPath); - cmd_free(pszPathExt); - return TRUE; - } - pCh = _tcstok(NULL, _T(";")); - } + /* search in PATH */ + pCh = _tcstok(pszPath, _T(";")); + while (pCh) + { + if (SearchForExecutableSingle(pFileName, pFullName, pszPathExt, pCh)) + { + cmd_free(pszPath); + cmd_free(pszPathExt); + return TRUE; + } + pCh = _tcstok(NULL, _T(";")); + } - cmd_free(pszPath); - cmd_free(pszPathExt); - return FALSE; + cmd_free(pszPath); + cmd_free(pszPathExt); + return FALSE; } /* EOF */ diff --git a/base/shell/cmd/window.c b/base/shell/cmd/window.c index 42771d572c3..45a7d758471 100644 --- a/base/shell/cmd/window.c +++ b/base/shell/cmd/window.c @@ -3,170 +3,168 @@ * * clone from 4nt activate command * - * 10 Sep 1999 (Paolo Pantaleo) + * 10 Sep 1999 (Paolo Pantaleo) * started (window command in WINDOW.c) * - * 29 Sep 1999 (Paolo Pantaleo) + * 29 Sep 1999 (Paolo Pantaleo) * activate and window in a single file using mainly the same code * (nice size optimization :) * - * 30-Apr-2005 (Magnus Olsen) ) - * Remove all hardcode string to En.rc + * 30-Apr-2005 (Magnus Olsen ) + * Remove all hardcoded strings in En.rc */ #include "precomp.h" -#if ( defined(INCLUDE_CMD_WINDOW) || defined(INCLUDE_CMD_ACTIVATE) ) +#if defined(INCLUDE_CMD_WINDOW) || defined(INCLUDE_CMD_ACTIVATE) -#define A_MIN 0x01 -#define A_MAX 0x02 -#define A_RESTORE 0x04 -#define A_POS 0x08 -#define A_SIZE 0x10 -#define A_CLOSE 0x20 +#define A_MIN 0x01 +#define A_MAX 0x02 +#define A_RESTORE 0x04 +#define A_POS 0x08 +#define A_SIZE 0x10 +#define A_CLOSE 0x20 -/*service funciton to perform actions on windows - - param is a string to parse for options/actions - hWnd is the handle of window on wich perform actions - -*/ - +/* + * service function to perform actions on windows + * + * param is a string to parse for options/actions + * hWnd is the handle of window on which to perform actions + */ static INT ServiceActivate (LPTSTR param, HWND hWnd) { - LPTSTR *p = 0, p_tmp; - INT argc = 0, i; - INT iAction = 0; - LPTSTR title = 0; - WINDOWPLACEMENT wp; - RECT pos; - LPTSTR tmp; + LPTSTR *p = 0, p_tmp; + INT argc = 0, i; + INT iAction = 0; + LPTSTR title = 0; + WINDOWPLACEMENT wp; + RECT pos; + LPTSTR tmp; + if (*param) + p = split(param, &argc, FALSE); - if (*param) - p = split(param, &argc, FALSE); + for (i = 0; i < argc; i++) + { + p_tmp = p[i]; + if (*p_tmp == _T('/')) + p_tmp++; - for (i = 0; i < argc; i++) - { - p_tmp = p[i]; - if (*p_tmp == _T('/')) - p_tmp++; + if (_tcsicmp(p_tmp, _T("min")) == 0) + { + iAction |= A_MIN; + continue; + } - if (_tcsicmp(p_tmp, _T("min")) == 0) - { - iAction |= A_MIN; - continue; - } + if (_tcsicmp(p_tmp, _T("max")) == 0) + { + iAction |= A_MAX; + continue; + } - if (_tcsicmp(p_tmp, _T("max")) == 0) - { - iAction |= A_MAX; - continue; - } + if (_tcsicmp(p_tmp, _T("restore")) == 0) + { + iAction |= A_RESTORE; + continue; + } - if (_tcsicmp(p_tmp, _T("restore")) == 0) - { - iAction |= A_RESTORE; - continue; - } + if (_tcsicmp(p_tmp, _T("close")) == 0) + { + iAction |= A_CLOSE; + continue; + } - if (_tcsicmp(p_tmp, _T("close")) == 0) - { - iAction |= A_CLOSE; - continue; - } + if (_tcsnicmp(p_tmp, _T("pos"), 3) == 0) + { + iAction |= A_POS; + tmp = p_tmp+3; + if (*tmp == _T('=')) + tmp++; - if (_tcsnicmp(p_tmp, _T("pos"), 3) == 0) - { - iAction |= A_POS; - tmp = p_tmp+3; - if (*tmp == _T('=')) - tmp++; + pos.left= _ttoi(tmp); + if (!(tmp=_tcschr(tmp, _T(',')))) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } - pos.left= _ttoi(tmp); - if(!(tmp=_tcschr(tmp, _T(',')))) - { - error_invalid_parameter_format(p[i]); - freep(p); - return 1; - } + pos.top = _ttoi (++tmp); + if (!(tmp=_tcschr(tmp, _T(',')))) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } - pos.top = _ttoi (++tmp); - if(!(tmp=_tcschr(tmp, _T(',')))) - { - error_invalid_parameter_format(p[i]); - freep(p); - return 1; - } + pos.right = _ttoi(++tmp) + pos.left; + if (!(tmp = _tcschr(tmp, _T(',')))) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } + pos.bottom = _ttoi(++tmp) + pos.top; + continue; + } - pos.right = _ttoi(++tmp) + pos.left; - if (!(tmp = _tcschr(tmp, _T(',')))) - { - error_invalid_parameter_format(p[i]); - freep(p); - return 1; - } - pos.bottom = _ttoi(++tmp) + pos.top; - continue; - } + if (_tcsnicmp(p_tmp, _T("size"), 4)==0) + { + iAction |=A_SIZE; + continue; + } - if (_tcsnicmp(p_tmp, _T("size"), 4)==0) - { - iAction |=A_SIZE; - continue; - } + /* none of them=window title */ + if (title) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } - /* none of them=window title */ - if (title) - { - error_invalid_parameter_format(p[i]); - freep(p); - return 1; - } + if (p_tmp[0] == _T('"')) + { + title = (p_tmp + 1); + *_tcschr(p_tmp + 1, _T('"')) = 0; + continue; + } + title = p_tmp; + } - if (p_tmp[0] == _T('"')) - { - title = (p_tmp + 1); - *_tcschr(p_tmp + 1, _T('"')) = 0; - continue; - } - title = p_tmp; - } + if (title) + SetWindowText(hWnd, title); - if (title) - SetWindowText(hWnd, title); + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(hWnd, &wp); - wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(hWnd, &wp); + if (iAction & A_POS) + wp.rcNormalPosition = pos; - if (iAction & A_POS) - wp.rcNormalPosition = pos; + if (iAction & A_MIN) + wp.showCmd = SW_MINIMIZE; - if (iAction & A_MIN) - wp.showCmd = SW_MINIMIZE; + if (iAction & A_MAX) + wp.showCmd = SW_SHOWMAXIMIZED; - if (iAction & A_MAX) - wp.showCmd = SW_SHOWMAXIMIZED; + /* if no actions are specified default is SW_RESTORE */ + if ((iAction & A_RESTORE) || (!iAction)) + wp.showCmd = SW_RESTORE; - /*if no actions are specified default is SW_RESTORE*/ - if ((iAction & A_RESTORE) || (!iAction)) - wp.showCmd = SW_RESTORE; + if (iAction & A_CLOSE) + { + FIXME("!!!FIXME: CLOSE Not implemented!!!\n"); + } - if (iAction & A_CLOSE) - { - FIXME("!!!FIXME: CLOSE Not implemented!!!\n"); - } + wp.length = sizeof(WINDOWPLACEMENT); + SetWindowPlacement(hWnd, &wp); - wp.length = sizeof(WINDOWPLACEMENT); - SetWindowPlacement(hWnd, &wp); + if (p) + freep(p); - if (p) - freep(p); - - return 0; + return 0; } @@ -174,54 +172,54 @@ static INT ServiceActivate (LPTSTR param, HWND hWnd) INT CommandWindow (LPTSTR param) { - HWND hwnd; + HWND hwnd; - if (_tcsncmp (param, _T("/?"), 2) == 0) - { + if (_tcsncmp (param, _T("/?"), 2) == 0) + { ConOutResPaging(TRUE,STRING_WINDOW_HELP1); - return 0; - } + return 0; + } - hwnd = GetConsoleWindow(); - Sleep(0); - return ServiceActivate(param, hwnd); + hwnd = GetConsoleWindow(); + Sleep(0); + return ServiceActivate(param, hwnd); } INT CommandActivate (LPTSTR param) { - HWND hwnd; - LPTSTR *arg; - INT argc; + HWND hwnd; + LPTSTR *arg; + INT argc; - if (_tcsncmp (param, _T("/?"), 2) == 0) - { - ConOutResPaging(TRUE,STRING_WINDOW_HELP2); - return 0; - } + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutResPaging(TRUE,STRING_WINDOW_HELP2); + return 0; + } - if(!(*param)) - return 1; + if (!(*param)) + return 1; - /*Split the user input into array*/ - arg = split (param, &argc, FALSE); - if(argc < 2) - { - if(arg != NULL) - freep(arg); - } - hwnd = FindWindow(NULL, arg[0]); - if (hwnd == NULL) - { - if(arg != NULL) - freep(arg); - ConErrResPuts(STRING_WINDOW_ERROR1); - return 1; - } - if(arg != NULL) - freep(arg); + /* Split the user input into array */ + arg = split (param, &argc, FALSE); + if (argc < 2) + { + if (arg != NULL) + freep(arg); + } + hwnd = FindWindow(NULL, arg[0]); + if (hwnd == NULL) + { + if (arg != NULL) + freep(arg); + ConErrResPuts(STRING_WINDOW_ERROR1); + return 1; + } + if (arg != NULL) + freep(arg); - return ServiceActivate(param, hwnd); + return ServiceActivate(param, hwnd); } -#endif /* ( defined(INCLUDE_CMD_WINDOW) || defined(INCLUDE_CMD_ACTIVATE) ) */ +#endif /* defined(INCLUDE_CMD_WINDOW) || defined(INCLUDE_CMD_ACTIVATE) */ diff --git a/base/shell/explorer/CMakeLists.txt b/base/shell/explorer/CMakeLists.txt index 395ea5c5e79..3b5b54c4e0f 100644 --- a/base/shell/explorer/CMakeLists.txt +++ b/base/shell/explorer/CMakeLists.txt @@ -1,10 +1,11 @@ add_subdirectory(notifyhook) -set_cpp() +set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL) add_definitions( -DWIN32 + -D__MINGW32__ -D__WINDRES__) #add_pch(explorer precomp.h) diff --git a/boot/bootdata/hivesys.inf b/boot/bootdata/hivesys.inf index d13c18a24c9..b027a70a8ce 100644 --- a/boot/bootdata/hivesys.inf +++ b/boot/bootdata/hivesys.inf @@ -1248,7 +1248,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems","Kmode",0x000 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems","Optional",0x00010000,"Posix" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems","Posix",0x00020000,"%SystemRoot%\system32\psxss.exe" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems","Required",0x00010000,"Debug","Windows" -HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems","Windows",0x00020000,"%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=consrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems","Windows",0x00020000,"%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,12288,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16" ; WOW Support HKLM,"SYSTEM\CurrentControlSet\Control\Wow","",0x00000000,"" diff --git a/boot/bootdata/packages/reactos.dff.in b/boot/bootdata/packages/reactos.dff.in index fe25c3b36df..9a2c54c5813 100644 --- a/boot/bootdata/packages/reactos.dff.in +++ b/boot/bootdata/packages/reactos.dff.in @@ -30,6 +30,7 @@ Signature = "$ReactOS$" 14 = Microsoft.NET\Framework\v2.0.50727 15 = Resources 16 = Resources\Themes +17 = system32\wbem .InfEnd diff --git a/boot/freeldr/freeldr/ui/tui.c b/boot/freeldr/freeldr/ui/tui.c index 1c07665313f..29e9bc65014 100644 --- a/boot/freeldr/freeldr/ui/tui.c +++ b/boot/freeldr/freeldr/ui/tui.c @@ -952,29 +952,29 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length) MachBeep(); } } - else if (key == KEY_HOME) // Go to the start of the buffer + else if (Extended && key == KEY_HOME) // Go to the start of the buffer { EditBoxTextPosition = 0; } - else if (key == KEY_END) // Go to the end of the buffer + else if (Extended && key == KEY_END) // Go to the end of the buffer { EditBoxTextPosition = EditBoxTextLength; } - else if (key == KEY_RIGHT) // Go right + else if (Extended && key == KEY_RIGHT) // Go right { if (EditBoxTextPosition < EditBoxTextLength) EditBoxTextPosition++; else MachBeep(); } - else if (key == KEY_LEFT) // Go left + else if (Extended && key == KEY_LEFT) // Go left { if (EditBoxTextPosition > 0) EditBoxTextPosition--; else MachBeep(); } - else // Add this key to the buffer + else if (!Extended) // Add this key to the buffer { if ( (EditBoxTextLength < Length - 1) && (EditBoxTextPosition < Length - 1) ) @@ -992,6 +992,10 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length) MachBeep(); } } + else + { + MachBeep(); + } } // Draw the edit box background diff --git a/cmake/CMakeMacros.cmake b/cmake/CMakeMacros.cmake index 5d7c6e1a018..6d58334da36 100644 --- a/cmake/CMakeMacros.cmake +++ b/cmake/CMakeMacros.cmake @@ -1,9 +1,81 @@ +# set_cpp +# Marks the current folder as containing C++ modules, additionally enabling +# specific C++ language features as specified (all of these default to off): +# +# WITH_RUNTIME +# Links with the C++ runtime. Enable this for modules which use new/delete or +# RTTI, but do not require STL. This is the right choice if you see undefined +# references to operator new/delete, vector constructor/destructor iterator, +# type_info::vtable, ... +# Note: this only affects linking, so cannot be used for static libraries. +# WITH_RTTI +# Enables run-time type information. Enable this if the module uses typeid or +# dynamic_cast. You will probably need to enable WITH_RUNTIME as well, if +# you're not already using STL. +# WITH_EXCEPTIONS +# Enables C++ exception handling. Enable this if the module uses try/catch or +# throw. You might also need this if you use a standard operator new (the one +# without nothrow). +# WITH_STL +# Enables standard C++ headers and links to the Standard Template Library. +# Use this for modules using anything from the std:: namespace, e.g. maps, +# strings, vectors, etc. +# Note: this affects both compiling (via include directories) and +# linking (by adding STL). Implies WITH_RUNTIME. +# FIXME: WITH_STL is currently also required for runtime headers such as +# and . This is not a big issue because in stl-less +# environments you usually don't want those anyway; but we might want +# to have modules like this in the future. +# +# Examples: +# set_cpp() +# Enables the C++ language, but will cause errors if any runtime or standard +# library features are used. This should be the default for C++ in kernel +# mode or otherwise restricted environments. +# Note: this is required to get libgcc (for multiplication/division) linked +# in for C++ modules, and to set the correct language for precompiled +# header files, so it IS required even with no features specified. +# set_cpp(WITH_RUNTIME) +# Links with the C++ runtime, so that e.g. custom operator new implementations +# can be used in a restricted environment. This is also required for linking +# with libraries (such as ATL) which have RTTI enabled, even if the module in +# question does not use WITH_RTTI. +# set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL) +# The full package. This will adjust compiler and linker so that all C++ +# features can be used. macro(set_cpp) - set(IS_CPP 1) - if(MSVC) - include_directories(${REACTOS_SOURCE_DIR}/include/c++) + cmake_parse_arguments(__cppopts "WITH_RUNTIME;WITH_RTTI;WITH_EXCEPTIONS;WITH_STL" "" "" ${ARGN}) + if(__cppopts_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "set_cpp: unparsed arguments ${__cppopts_UNPARSED_ARGUMENTS}") endif() + + if(__cppopts_WITH_RUNTIME) + set(CPP_USE_RT 1) + endif() + if(__cppopts_WITH_RTTI) + if(MSVC) + replace_compile_flags("/GR-" "/GR") + else() + replace_compile_flags_language("-fno-rtti" "-frtti" "CXX") + endif() + endif() + if(__cppopts_WITH_EXCEPTIONS) + if(MSVC) + replace_compile_flags("/EHs-c-" "/EHsc") + else() + replace_compile_flags_language("-fno-exceptions" "-fexceptions" "CXX") + endif() + endif() + if(__cppopts_WITH_STL) + set(CPP_USE_STL 1) + if(MSVC) + add_definitions(-DNATIVE_CPP_INCLUDE=${REACTOS_SOURCE_DIR}/include/c++) + include_directories(${REACTOS_SOURCE_DIR}/include/c++/stlport) + endif() + endif() + + set(IS_CPP 1) endmacro() function(add_dependency_node _node) @@ -115,7 +187,9 @@ macro(dir_to_num dir var) set(${var} 15) elseif(${dir} STREQUAL reactos/Resources/Themes) set(${var} 16) - else() + elseif(${dir} STREQUAL reactos/system32/wbem) + set(${var} 17) + else() message(FATAL_ERROR "Wrong destination: ${dir}") endif() endmacro() diff --git a/cmake/compilerflags.cmake b/cmake/compilerflags.cmake index 1b3ad21ca13..3928b793f36 100644 --- a/cmake/compilerflags.cmake +++ b/cmake/compilerflags.cmake @@ -31,40 +31,20 @@ endfunction() # arguments, all of which will be added to the list # # Examples: -# add_compile_flags("-pedantic -O5") -# add_target_link_flags(mymodule "-s --fatal-warnings") # add_target_compile_flags(mymodule "-pedantic -O5") +# add_target_link_flags(mymodule "-s --fatal-warnings") # add_target_compile_definitions(mymodule WIN32 _WIN32 INLINE=inline) # add_target_include_directories(mymodule include ../include) -# add_compile_flags_language("-std=gnu99" "C") -function(add_compile_flags _flags) - if(${ARGC} GREATER 1) - message(STATUS "Excess arguments to add_compile_flags! Args ${ARGN}") - endif() - # Adds the compiler flag to both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flags}" PARENT_SCOPE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flags}" PARENT_SCOPE) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${_flags}" PARENT_SCOPE) -endfunction() - -function(add_compile_flags_language _flags _lang) - if(NOT ${ARGC} EQUAL 2) - message(STATUS "Wrong arguments to add_compile_flags_language! Args ${ARGN}") - endif() - # Adds the compiler flag to both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS - set(CMAKE_${_lang}_FLAGS "${CMAKE_${_lang}_FLAGS} ${_flags}" PARENT_SCOPE) -endfunction() - function(add_target_compile_flags _module _flags) if(${ARGC} GREATER 2) - message(STATUS "Excess arguments to add_target_compile_flags! Module ${_module}, args ${ARGN}") + message(FATAL_ERROR "Excess arguments to add_target_compile_flags! Module ${_module}, args ${ARGN}") endif() add_target_property(${_module} COMPILE_FLAGS ${_flags}) endfunction() function(add_target_link_flags _module _flags) if(${ARGC} GREATER 2) - message(STATUS "Excess arguments to add_target_link_flags! Module ${_module}, args ${ARGN}") + message(FATAL_ERROR "Excess arguments to add_target_link_flags! Module ${_module}, args ${ARGN}") endif() add_target_property(${_module} LINK_FLAGS ${_flags}) endfunction() @@ -76,3 +56,70 @@ endfunction() function(add_target_include_directories _module) add_target_property(${_module} INCLUDE_DIRECTORIES ${ARGN}) endfunction() + +# replace_compiler_option +# (taken from LLVM) +# Replaces a compiler option or switch `_old' in `_var' by `_new'. +# If `_old' is not in `_var', appends `_new' to `_var'. +# +# Example: +# replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "-O2") +macro(replace_compiler_option _var _old _new) + # If the option already is on the variable, don't add it: + if("${${_var}}" MATCHES "(^| )${_new}($| )") + set(__n "") + else() + set(__n "${_new}") + endif() + if("${${_var}}" MATCHES "(^| )${_old}($| )") + string(REGEX REPLACE "(^| )${_old}($| )" " ${__n} " ${_var} "${${_var}}") + else() + set(${_var} "${${_var}} ${__n}") + endif() +endmacro(replace_compiler_option) + +# add_compile_flags +# add_compile_flags_language +# replace_compile_flags +# replace_compile_flags_language +# Add or replace compiler flags in the global scope for either all source +# files or only those of the specified language. +# +# Examples: +# add_compile_flags("-pedantic -O5") +# add_compile_flags_language("-std=gnu99" "C") +# replace_compile_flags("-O5" "-O3") +# replace_compile_flags_language("-fno-exceptions" "-fexceptions" "CXX") +function(add_compile_flags _flags) + if(${ARGC} GREATER 1) + message(FATAL_ERROR "Excess arguments to add_compile_flags! Args ${ARGN}") + endif() + # Adds the compiler flag for all code files: C, C++, and assembly + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flags}" PARENT_SCOPE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flags}" PARENT_SCOPE) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${_flags}" PARENT_SCOPE) +endfunction() + +function(add_compile_flags_language _flags _lang) + if(NOT ${ARGC} EQUAL 2) + message(FATAL_ERROR "Wrong arguments to add_compile_flags_language! Args ${ARGN}") + endif() + # Adds the compiler flag for the specified language only, e.g. CMAKE_C_FLAGS + set(CMAKE_${_lang}_FLAGS "${CMAKE_${_lang}_FLAGS} ${_flags}" PARENT_SCOPE) +endfunction() + +macro(replace_compile_flags _oldflags _newflags) + if(NOT ${ARGC} EQUAL 2) + message(FATAL_ERROR "Wrong arguments to replace_compile_flags! Args ${ARGN}") + endif() + replace_compiler_option(CMAKE_C_FLAGS ${_oldflags} ${_newflags}) + replace_compiler_option(CMAKE_CXX_FLAGS ${_oldflags} ${_newflags}) + replace_compiler_option(CMAKE_ASM_FLAGS ${_oldflags} ${_newflags}) +endmacro() + +macro(replace_compile_flags_language _oldflags _newflags _lang) + if(NOT ${ARGC} EQUAL 3) + message(FATAL_ERROR "Wrong arguments to replace_compile_flags_language! Args ${ARGN}") + endif() + replace_compiler_option(CMAKE_${_lang}_FLAGS ${_oldflags} ${_newflags}) +endmacro() diff --git a/cmake/gcc.cmake b/cmake/gcc.cmake index 1229b789749..6559071f1ac 100644 --- a/cmake/gcc.cmake +++ b/cmake/gcc.cmake @@ -15,6 +15,8 @@ if(GCC_VERSION VERSION_GREATER 4.7) add_compile_flags("-mstackrealign") endif() +add_compile_flags_language("-fno-rtti -fno-exceptions" "CXX") + #bug #file(TO_NATIVE_PATH ${REACTOS_SOURCE_DIR} REACTOS_SOURCE_DIR_NATIVE) #workaround @@ -190,12 +192,15 @@ function(set_image_base MODULE IMAGE_BASE) endfunction() function(set_module_type_toolchain MODULE TYPE) - if(IS_CPP) + if(CPP_USE_STL) if((${TYPE} STREQUAL "kernelmodedriver") OR (${TYPE} STREQUAL "wdmdriver")) - target_link_libraries(${MODULE} -lgcc) - else() - target_link_libraries(${MODULE} -lstdc++ -lsupc++ -lgcc -lmingwex) + message(FATAL_ERROR "Use of STL in kernelmodedriver or wdmdriver type module prohibited") endif() + target_link_libraries(${MODULE} -lstdc++ -lsupc++ -lgcc -lmingwex) + elseif(CPP_USE_RT) + target_link_libraries(${MODULE} -lsupc++ -lgcc) + elseif(IS_CPP) + target_link_libraries(${MODULE} -lgcc) endif() if((${TYPE} STREQUAL "kernelmodedriver") OR (${TYPE} STREQUAL "wdmdriver")) diff --git a/cmake/msvc.cmake b/cmake/msvc.cmake index 67ebd2264d9..0258ed5b6dc 100644 --- a/cmake/msvc.cmake +++ b/cmake/msvc.cmake @@ -20,7 +20,7 @@ endif() add_definitions(/Dinline=__inline /D__STDC__=1) -add_compile_flags("/X /GR- /GS- /Zl /W3") +add_compile_flags("/X /GR- /EHs-c- /GS- /Zl /W3") # HACK: for VS 11+ we need to explicitly disable SSE, which is off by # default for older compilers. See bug #7174 @@ -108,6 +108,14 @@ function(set_image_base MODULE IMAGE_BASE) endfunction() function(set_module_type_toolchain MODULE TYPE) + if(CPP_USE_STL) + if((${TYPE} STREQUAL "kernelmodedriver") OR (${TYPE} STREQUAL "wdmdriver")) + message(FATAL_ERROR "Use of STL in kernelmodedriver or wdmdriver type module prohibited") + endif() + target_link_libraries(${MODULE} cpprt stlport oldnames) + elseif(CPP_USE_RT) + target_link_libraries(${MODULE} cpprt) + endif() if((${TYPE} STREQUAL "win32dll") OR (${TYPE} STREQUAL "win32ocx") OR (${TYPE} STREQUAL "cpl")) add_target_link_flags(${MODULE} "/DLL") elseif(${TYPE} STREQUAL "kernelmodedriver") diff --git a/configure.cmd b/configure.cmd index 6a74cc0487b..bd1ce26cf68 100755 --- a/configure.cmd +++ b/configure.cmd @@ -21,7 +21,7 @@ if /I "%1" == "arm_hosttools" ( :: Get the source root directory set REACTOS_SOURCE_DIR=%~dp0 -set USE_NMAKE=0 +set USE_VSCMD=0 :: Detect presence of cmake cmd /c cmake --version 2>&1 | find "cmake version" > NUL || goto cmake_notfound @@ -49,7 +49,7 @@ if defined ROS_ARCH ( ) else if "%_BUILDARCH%" == "AMD64" ( set ARCH=amd64 ) - set USE_NMAKE=1 + set USE_VSCMD=1 set USE_WDK_HEADERS=0 ) else if defined VCINSTALLDIR ( @@ -57,10 +57,11 @@ if defined ROS_ARCH ( cl 2>&1 | find "x86" > NUL && set ARCH=i386 cl 2>&1 | find "x64" > NUL && set ARCH=amd64 cl 2>&1 | find "ARM" > NUL && set ARCH=arm - cl 2>&1 | find "14." > NUL && set BUILD_ENVIRONMENT=VS8 - cl 2>&1 | find "15." > NUL && set BUILD_ENVIRONMENT=VS9 - cl 2>&1 | find "16." > NUL && set BUILD_ENVIRONMENT=VS10 - cl 2>&1 | find "17." > NUL && set BUILD_ENVIRONMENT=VS11 + cl 2>&1 | find "14.00." > NUL && set BUILD_ENVIRONMENT=VS8 + cl 2>&1 | find "15.00." > NUL && set BUILD_ENVIRONMENT=VS9 + cl 2>&1 | find "16.00." > NUL && set BUILD_ENVIRONMENT=VS10 + cl 2>&1 | find "17.00." > NUL && set BUILD_ENVIRONMENT=VS11 + ::cl 2>&1 | find "18.00." > NUL && set BUILD_ENVIRONMENT=VS12 if not defined BUILD_ENVIRONMENT ( echo Error: Visual Studio version too old or version detection failed. exit /b @@ -96,8 +97,8 @@ if defined ROS_ARCH ( ) ) ) else ( - set USE_NMAKE=1 - echo This script defaults to nmake. To use Visual Studio GUI specify "VSSolution" as a parameter. + set USE_VSCMD=1 + echo This script defaults to Ninja. To use Visual Studio GUI specify "VSSolution" as a parameter. ) ) else if defined sdkdir ( @@ -109,7 +110,7 @@ if defined ROS_ARCH ( ) set BUILD_ENVIRONMENT=SDK - set USE_NMAKE=1 + set USE_VSCMD=1 ) else ( echo Error: Unable to detect build environment. Configure script failure. @@ -122,8 +123,8 @@ if not defined ARCH ( exit /b ) -:: Detect nmake generator -if %USE_NMAKE% == 1 ( +:: Detect VS command line generator +if %USE_VSCMD% == 1 ( if /I "%1" == "CodeBlocks" ( set CMAKE_GENERATOR="CodeBlocks - NMake Makefiles" ) else if /I "%1" == "Eclipse" ( @@ -186,9 +187,9 @@ if "%BUILD_ENVIRONMENT%" == "MinGW" ( cd.. -echo Configure script complete! Enter directories and execute appropriate build commands(ex: ninja, make, nmake, etc...). +echo Configure script complete^^! Enter directories and execute appropriate build commands (ex: ninja, make, nmake, etc...). exit /b :cmake_notfound - echo Unable to find cmake, if it is installed, check your PATH variable. - exit /b +echo Unable to find cmake, if it is installed, check your PATH variable. +exit /b diff --git a/configure.sh b/configure.sh index ee6e54bc354..e8595b7dd54 100755 --- a/configure.sh +++ b/configure.sh @@ -1,8 +1,8 @@ #!/bin/sh if [ "x$ROS_ARCH" = "x" ]; then - echo Could not detect RosBE. - exit 1 + echo Could not detect RosBE. + exit 1 fi BUILD_ENVIRONMENT=MinGW @@ -11,24 +11,24 @@ REACTOS_SOURCE_DIR=$(cd `dirname $0` && pwd) REACTOS_OUTPUT_PATH=output-$BUILD_ENVIRONMENT-$ARCH usage() { -echo Invalid parameter given. -exit 1 + echo Invalid parameter given. + exit 1 } CMAKE_GENERATOR="Ninja" -for (( i=1; i<=$#; i++ )); do - case ${!i} in +while [ $# -gt 0 ]; do + case $1 in -D) - ((i++)) - if [[ "x${!i}" == x?*=* ]] ; then - ROS_CMAKEOPTS+=" -D ${!i}" + shift + if echo "x$1" | grep 'x?*=*' > /dev/null; then + ROS_CMAKEOPTS+=" -D $1" else usage fi ;; - -D?*=*) - ROS_CMAKEOPTS+=" ${!i}" + -D?*=*|-D?*) + ROS_CMAKEOPTS+=" $1" ;; makefiles|Makefiles) CMAKE_GENERATOR="Unix Makefiles" @@ -36,12 +36,14 @@ for (( i=1; i<=$#; i++ )); do *) usage esac + + shift done if [ "$REACTOS_SOURCE_DIR" = "$PWD" ]; then - echo Creating directories in $REACTOS_OUTPUT_PATH - mkdir -p "$REACTOS_OUTPUT_PATH" - cd "$REACTOS_OUTPUT_PATH" + echo Creating directories in $REACTOS_OUTPUT_PATH + mkdir -p "$REACTOS_OUTPUT_PATH" + cd "$REACTOS_OUTPUT_PATH" fi mkdir -p host-tools reactos @@ -59,4 +61,4 @@ rm -f CMakeCache.txt cmake -G "$CMAKE_GENERATOR" -DENABLE_CCACHE=0 -DPCH=0 -DCMAKE_TOOLCHAIN_FILE=toolchain-gcc.cmake -DARCH=$ARCH -DREACTOS_BUILD_TOOLS_DIR="$REACTOS_BUILD_TOOLS_DIR" $ROS_CMAKEOPTS "$REACTOS_SOURCE_DIR" -echo Configure script complete! Enter directories and execute appropriate build commands\(ex: ninja, make, makex, etc...\). +echo Configure script complete! Enter directories and execute appropriate build commands \(ex: ninja, make, makex, etc...\). diff --git a/dll/cpl/console/CMakeLists.txt b/dll/cpl/console/CMakeLists.txt index 063a1bfdf13..303dc2af29f 100644 --- a/dll/cpl/console/CMakeLists.txt +++ b/dll/cpl/console/CMakeLists.txt @@ -1,7 +1,7 @@ include_directories( - ${REACTOS_SOURCE_DIR}/win32ss/user/consrv - ${REACTOS_SOURCE_DIR}/win32ss/user/consrv/frontends/gui) + ${REACTOS_SOURCE_DIR}/win32ss/user/winsrv/consrv + ${REACTOS_SOURCE_DIR}/win32ss/user/winsrv/consrv/frontends/gui) spec2def(console.dll console.spec) diff --git a/dll/cpl/desk/general.c b/dll/cpl/desk/general.c index 57bd8337645..b84592efef4 100644 --- a/dll/cpl/desk/general.c +++ b/dll/cpl/desk/general.c @@ -30,12 +30,13 @@ InitFontSizeList(HWND hWnd) 0, KEY_READ, &hKey) == ERROR_SUCCESS) for (;;) { + TCHAR Buffer[LINE_LEN]; TCHAR Desc[LINE_LEN]; - if (SetupGetStringField(&Context, 0, Desc, sizeof(Desc), NULL) && + if (SetupGetStringField(&Context, 0, Buffer, sizeof(Buffer), NULL) && SetupGetIntField(&Context, 1, &ci)) { - _stprintf(Desc, _T("%s (%d DPI)"), Desc, ci); + _stprintf(Desc, _T("%s (%d DPI)"), Buffer, ci); i = SendMessage(hFontSize, CB_ADDSTRING, 0, (LPARAM)Desc); if (i != CB_ERR) SendMessage(hFontSize, CB_SETITEMDATA, (WPARAM)i, (LPARAM)ci); diff --git a/dll/cpl/desk/lang/bg-BG.rc b/dll/cpl/desk/lang/bg-BG.rc index ffbf3290d91..2e8f960675d 100644 --- a/dll/cpl/desk/lang/bg-BG.rc +++ b/dll/cpl/desk/lang/bg-BG.rc @@ -14,10 +14,10 @@ BEGIN WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Изберете изображение за украса на работната си площ", IDC_STATIC, 8, 103, 230, 9 - PUSHBUTTON "&Обзор...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Цвят...", IDC_COLOR_BUTTON, 188, 177, 50, 15 + PUSHBUTTON "&Обзор...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Цвят...", IDC_COLOR_BUTTON, 188, 177, 55, 15 LTEXT "Разположение", IDC_STATIC, 188, 138, 55, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -33,16 +33,16 @@ BEGIN PUSHBUTTON "На&стройки",IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Пре&глед",IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Изчакване",IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "",IDC_SCREENS_TIME ,UPDOWN_CLASS,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "минути", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "Искане на парола при изход",IDC_SCREENS_USEPASSCHK,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Енергоспестяващи възможности на монитора", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "За настройка захранването на монитора, натиснете „Захранване...“.", - IDC_STATIC, 14, 166, 158 ,20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "Захранване...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -53,11 +53,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Разцветка", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Разцветка", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Ефекти", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Още", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -75,7 +75,7 @@ BEGIN LTEXT "Част", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Размер", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 35, 9 + LTEXT "&Размер", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -85,13 +85,13 @@ BEGIN LTEXT "Цвят &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Шрифт", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Шрифт", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Размер на шрифта", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Размер на шрифта", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Цвят", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Цвят", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "Ч", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -108,19 +108,19 @@ CAPTION "Ефекти" FONT 8, "MS Shell Dlg" BEGIN CONTROL "Из&ползване на следните преходни ефекти за изборниците и подсказките",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "&Използване на следния похват за изглаждане ръбовете на екранните шрифтове",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Използван&е на големи значета",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Изобразяване на &сенки под изборницте",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Показване на съдържанието на &прозорците по време на влачене",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "С&криване на подчертаването за клавиатурното насочване, до натискане на Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Отказ", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "Добре", IDOK, 172, 165, 50, 14 END @@ -130,15 +130,15 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Настройки" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Завлачете значетата на мониторите така, че да отговарят на действителното разположение на мониторите ви.",-1,3,3,240,16 + LTEXT "Завлачете значетата на мониторите така, че да отговарят на действителното разположение на мониторите ви.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Екран",1820,3,107,30,8 - LTEXT "<няма>",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Екран",1820,3,107,70,9 + LTEXT "<няма>",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Разделителна способност",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Малка",1815,9,137,22,8,NOT WS_GROUP - LTEXT "Голяма",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Малка",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Голяма",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Цветове",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -153,14 +153,14 @@ CAPTION "Общи" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Екран", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Размер на шрифта", -1, 14, 20, 222, 8 + LTEXT "Размер на шрифта", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Съвместимост", -1, 7, 67, 237, 97 LTEXT "Някои приложения няма да работят правилно, ако не презапуснете компютъра, след като промените цветовите настройки.\r\nСлед като променя цветовите настройки", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Презапуск преди прилагане на новите цветови настройки.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Прилагане на новите настройки без презапуск.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Питане преди прилагане на новите настройки", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Презапуск преди прилагане на новите цветови настройки.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Прилагане на новите настройки без презапуск.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Питане преди прилагане на новите настройки", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/cs-CZ.rc b/dll/cpl/desk/lang/cs-CZ.rc index 0559ceb8a23..32626ffcce3 100644 --- a/dll/cpl/desk/lang/cs-CZ.rc +++ b/dll/cpl/desk/lang/cs-CZ.rc @@ -17,11 +17,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Vyberte obrázek, který chcete použít jako pozadí", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Vybrat...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Barva...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Umístění", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Vybrat...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Barva...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Umístění", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -37,16 +37,16 @@ BEGIN PUSHBUTTON "&Nastavení", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Ná&hled", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "Č&ekat", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minut", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "Chránit &heslem", IDC_SCREENS_USEPASSCHK, "button", - BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 104, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "Napájení monitoru", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Pro nastavení napájení Vašeho monitoru, klikněte na Napájení", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "Na&pájení...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -57,11 +57,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Styl", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Styl", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Schéma", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Schéma", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Velikost", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Velikost", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efekty...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Upřesnit", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -89,13 +89,13 @@ BEGIN LTEXT "&2. barva", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Písmo", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Písmo", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Velikost", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Velikost", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Barva", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Barva", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -112,19 +112,19 @@ CAPTION "Efekty" FONT 8, "MS Shell Dlg" BEGIN CONTROL "Použít následující &efekt přechodu pro nabídky a popisky",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "Použít následující metodu vyhlazování &hran obrazovkových písem",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Použít velké &ikony",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Zobrazovat &stíny pod nabídkami",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Zobrazovat &obsah okna během přesouvání",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Nezobrazovat podtržení písmen u klávesových zkratek, dokud nestisknu klávesu Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Storno", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -136,13 +136,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Tažením nastavte ikony monitorů, aby odpovídaly fyzickému uspořádání vašich monitorů.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Obrazovka",1820,3,107,38,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Obrazovka",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Velikost obrazovky",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Menší",1815,9,137,18,8,NOT WS_GROUP - LTEXT "Větší",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Menší",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Větší",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Počet barev",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -157,14 +157,14 @@ CAPTION "Obecné" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Obrazovka", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Velikost písma", -1, 14, 20, 222, 8 + LTEXT "Velikost písma", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Kompatibilita", -1, 7, 67, 237, 97 LTEXT "Některé programy nefungují správně, pokud není počítač restartován po změně nastavení barev.\r\n\nPo změnění nastavení barev", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restartovat počítač před aplikováním nového nastavení barev.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Aplikovat nové nastavení barev bez restartování.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Zeptat se před aplikováním nového nastavení barev.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restartovat počítač před aplikováním nového nastavení barev.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Aplikovat nové nastavení barev bez restartování.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Zeptat se před aplikováním nového nastavení barev.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/de-DE.rc b/dll/cpl/desk/lang/de-DE.rc index d64fe944fd9..0b7f41881cb 100644 --- a/dll/cpl/desk/lang/de-DE.rc +++ b/dll/cpl/desk/lang/de-DE.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Hintergrundbild", - IDC_STATIC, 8, 103, 180, 9 + IDC_STATIC, 8, 103, 230, 9 PUSHBUTTON "&Durchsuchen...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 PUSHBUTTON "&Farbe...", IDC_COLOR_BUTTON, 188, 177, 55, 15 - LTEXT "&Ausrichtung", IDC_STATIC, 188, 140, 50, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + LTEXT "&Ausrichtung", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "Eins&tellungen", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Vorschau", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Warte", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "Minuten", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "&Passwort nach Reaktivierung", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Enerigesparfunktionen des Monitors", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Um die Energieeinstellungen des Monitors zu editieren, wählen Sie Energieeinstellungen.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "Energieoptionen", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Fenster und Schaltflächen", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Fenster und Schaltflächen", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Farbschema", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Farbschema", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Schriftgröße", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Schriftgröße", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effekte...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Erweitert", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Größe", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Größe", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "&2. Farbe", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Schriftart", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Schriftart", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Schriftgra&d", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Schriftgra&d", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Fa&rbe", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Fa&rbe", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "F", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Effekte" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Verwende folgenden Übergangseffekt für Menüs und Tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "V&erwende folgende Kantenglättungsmethode für Bildschirmschriften",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Ve&rwende große Icons",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Zeige Menüsch&atten",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Zeige &Fensterinhalt beim Verschieben",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "Ver&stecke Unterstrich der Tastaturnavigation bis zum Druck der Alt-Taste",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 250, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Abbrechen", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Verschieben Sie die Monitor-Symbole, so dass sie der physikalischen Anordnung Ihrer Monitore entsprechen.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Anzeige",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Anzeige",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "Bi&ldschirmauflösung",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Niedrig",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Hoch",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Niedrig",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Hoch",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Farbqualität",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "Allgemein" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Anzeige", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Schriftgröße", -1, 14, 20, 222, 8 + LTEXT "Schriftgröße", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Kompatibilität", -1, 7, 67, 237, 97 LTEXT "Einige Programme könnten fehlerhaft arbeiten, wenn nach Änderung der Farbeinstellungen nicht neugestartet wird.\r\n\nNach Änderung der Farbeinstellungen", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Computer vor dem Anwenden der Farbeinstellungen neustarten.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Farbeinstellungen ohne Neustart übernehmen.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Vor dem Anwenden der neuen Farbeinstellungen nachfragen.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Computer vor dem Anwenden der Farbeinstellungen neustarten.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Farbeinstellungen ohne Neustart übernehmen.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Vor dem Anwenden der neuen Farbeinstellungen nachfragen.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/el-GR.rc b/dll/cpl/desk/lang/el-GR.rc index dd7aa32556f..c87919a3ea3 100644 --- a/dll/cpl/desk/lang/el-GR.rc +++ b/dll/cpl/desk/lang/el-GR.rc @@ -9,13 +9,13 @@ BEGIN 70, 10, 105, 80, 0 CONTROL "", IDC_BACKGROUND_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | - WS_BORDER | WS_TABSTOP, 7, 114, 174, 78 + WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Επιλέξτε Φόντο", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Αναζήτηση...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Χρώμα...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Θέση", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Αναζήτηση...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Χρώμα...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Θέση", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "Ρυθμίσεις", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Προεπισκόπηση", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "Αναμονή", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP - CONTROL "", IDC_SCREENS_TIME ,UPDOWN_CLASS, UDS_SETBUDDYINT | + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP + CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "λεπτά", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "Κατά τη συνέχιση, προστασία με κωδικό πρόσβασης.", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "Ενέργεια οθόνης", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Για ρύθμιση των χαρακτηριστικών εξοικονόμησης ενέργειας, κάντε κλικ στο κουμπί 'Ενέργεια'.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "Ενέργεια...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Συνδυασμός χρωμάτων", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Συνδυασμός χρωμάτων", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Μέγεθος", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Μέγεθος", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effects...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Για προχωρημένους", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Αντικείμενο", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "Μέγεθος", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "Μέγεθος", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "Χρώμα 2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Γραμματοσειρά", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Γραμματοσειρά", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Μέγεθος", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Μέγεθος", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Χρώμα", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Χρώμα", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Effects" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Use the following transition effect for menus and tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&se the following method to smooth edges of screen fonts",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Us&e large icons",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Σύρετε τα εικονίδια της οθόνης, ώστε να ταιριάξουν με τη φυσική διάταξη των οθονών σας.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Εμφάνιση",1820,3,107,30,8 - LTEXT "<κανένα>",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Εμφάνιση",1820,3,107,70,9 + LTEXT "<κανένα>",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Ανάλυση οθόνης",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Μικρότερη",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Μεγαλύτερη",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Μικρότερη",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Μεγαλύτερη",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Ποιότητα χρώματος",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Display", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Font Size", -1, 14, 20, 222, 8 + LTEXT "Font Size", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibility", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/en-US.rc b/dll/cpl/desk/lang/en-US.rc index f083021b804..54b7c08d074 100644 --- a/dll/cpl/desk/lang/en-US.rc +++ b/dll/cpl/desk/lang/en-US.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Select an image to use as your desktop wallpaper", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Browse...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Color...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Placement", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Browse...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Color...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Placement", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "Se&ttings", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Pre&view", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Wait", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutes", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Ask for &password on resume.", IDC_SCREENS_USEPASSCHK, "button", - BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 104, 19 + CONTROL "Ask for &password on resume", IDC_SCREENS_USEPASSCHK, "button", + BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Energy Saving features of monitor", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "To adjust the power settings for your monitor, click on Power Settings.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "P&ower...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Colorscheme", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Colorscheme", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effects...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Ad&vanced...", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Size", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Size", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "&2nd Color", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Fontsize", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Fontsize", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Color", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Color", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Effects" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Use the following transition effect for menus and tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&se the following method to smooth edges of screen fonts",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Us&e large icons",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Drag the monitor icons to match the physical arrangement of your monitors.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Display",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Display",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Screen area",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Less",1815,9,137,15,8,NOT WS_GROUP - LTEXT "More",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Less",1815,9,137,25,9,NOT WS_GROUP + LTEXT "More",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Colors",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Display", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Font Size", -1, 14, 20, 222, 8 + LTEXT "Font Size", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibility", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/es-ES.rc b/dll/cpl/desk/lang/es-ES.rc index 3ca528aafe4..6952225cbcd 100644 --- a/dll/cpl/desk/lang/es-ES.rc +++ b/dll/cpl/desk/lang/es-ES.rc @@ -17,13 +17,13 @@ BEGIN 70, 10, 105, 80, 0 CONTROL "",IDC_BACKGROUND_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | - WS_BORDER | WS_TABSTOP, 7, 114, 174, 78 + WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "&Fondo", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "E&xaminar...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "C&olor...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Po&sición", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "E&xaminar...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "C&olor...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Po&sición", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -39,16 +39,16 @@ BEGIN PUSHBUTTON "C&onfiguración", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Vista previa", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Esperar", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP - CONTROL "", IDC_SCREENS_TIME ,UPDOWN_CLASS,UDS_SETBUDDYINT | + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP + CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 61, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutos", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "Pr&oteger con contraseña al reanudar",IDC_SCREENS_USEPASSCHK,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 // 104 + BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "Energía del monitor ", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Para ajustar la configuración de energía del monitor y ahorrar energía, haga clic en Energía.", - IDC_STATIC, 14, 166, 146, 24 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "E&nergía...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -59,11 +59,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Com&binación de colores", IDC_STATIC, 7, 160, 90, 7 // 64 + LTEXT "Com&binación de colores", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efectos...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Opciones &avanzadas", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -91,13 +91,13 @@ BEGIN LTEXT "Color &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "&Fuente", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "&Fuente", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Ta&maño", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Ta&maño", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Colo&r", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Colo&r", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -114,19 +114,19 @@ CAPTION "Efectos" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Usar el efecto de transición siguiente para menús e información sobre herramientas",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&sar el siguiente método para suavizar los bordes de las fuentes de pantalla",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Usar i&conos grandes",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Mostrar som&bras bajo los menús",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "&Mostrar el contenido de la ventana mientras se arrastra",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Ocultar las letrar subrayadas de acceso rápido hasta que presione la tecla Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Cancelar", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "Aceptar", IDOK, 172, 165, 50, 14 END @@ -138,13 +138,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Arrastre los iconos para ajustar el orden físico de sus monitores.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "Mostrar",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "Mostrar",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Resolución de pantalla ",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Menor",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Mayor",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Menor",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Mayor",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Calidad de color ",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -159,14 +159,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Pantalla ", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Tamaño de la fuente", -1, 14, 20, 222, 8 + LTEXT "Tamaño de la fuente", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibilidad ", -1, 7, 67, 237, 97 LTEXT "Es posible que algunos programas no funcionen correctamente si no reinicia el equipo después de cambiar la configuración de pantalla", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Reiniciar el equipo antes de aplicar la nueva configuración.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "&Aplicar la nueva configuración de pantalla sin reiniciar.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Pregu&ntar antes de aplicar la nueva configuración de pantalla.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Reiniciar el equipo antes de aplicar la nueva configuración.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "&Aplicar la nueva configuración de pantalla sin reiniciar.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Pregu&ntar antes de aplicar la nueva configuración de pantalla.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/fr-FR.rc b/dll/cpl/desk/lang/fr-FR.rc index 9c4a78a18ce..126a059857f 100644 --- a/dll/cpl/desk/lang/fr-FR.rc +++ b/dll/cpl/desk/lang/fr-FR.rc @@ -12,13 +12,13 @@ BEGIN 70, 10, 105, 80, 0 CONTROL "", IDC_BACKGROUND_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | - WS_BORDER | WS_TABSTOP, 7, 114, 174, 71 + WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Sélectionnez une image à utiliser comme fond d'écran", - IDC_STATIC, 8, 103, 180, 8 - PUSHBUTTON "&Parcourir...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Couleur...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Position", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Parcourir...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Couleur...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Position", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -34,16 +34,16 @@ BEGIN PUSHBUTTON "Paramè&tres", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Aperçu", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "Dé&lai ", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP - CONTROL "", IDC_SCREENS_TIME ,UPDOWN_CLASS,UDS_SETBUDDYINT | + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP + CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutes", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "À la reprise, demander un mot de &passe.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "À la reprise, demander un mot de &passe", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "G&estion de l'alimentation du moniteur", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Pour modifier les paramètres de l'alimentation du moniteur, cliquez sur Gestion de l'alimentation.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "&Gestion de l'alimentation...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -54,11 +54,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Modèle de couleurs", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Modèle de couleurs", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effets...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Avancé", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -76,7 +76,7 @@ BEGIN LTEXT "Élément", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Taille", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Taille", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -86,13 +86,13 @@ BEGIN LTEXT "&2ème Couleur", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Police", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Police", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Taille", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Taille", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Couleur", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Couleur", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "G", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -109,19 +109,19 @@ CAPTION "Effets" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Utilisez l'effet de transition suivant pour les menus et les bulles d'aides",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 330, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&tilisez la méthode suivante pour aplanir les bords des polices d'écran",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 330, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Uti&liser de grandes icones",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 330, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "&Montrer ombrage sous les menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 330, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Montrer contenu des fenêtres lorsqu'elles sont bougés",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 330, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Cacher les lettres soulignées pour la navigation du clavier jusqu'à ce que j'appuie sur la touche Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 330, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Annuler", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "Accepter", IDOK, 172, 165, 50, 14 END @@ -133,13 +133,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Déplacez les icônes de moniteur pour qu'elles correspondent à l'arragement physique de vos moniteurs.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Affichage",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Affichage",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Résolution de l'affichage",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Moins",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Plus",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Moins",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Plus",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Couleurs",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -154,14 +154,14 @@ CAPTION "Général" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Affichage", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Taille de la police", -1, 14, 20, 222, 8 + LTEXT "Taille de la police", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibilité", -1, 7, 67, 237, 97 - LTEXT "Quelques programmes peuvent mal fonctionner si vous ne redémarrez pas votre ordinateur après que vous ayiez changé les paramètres des couleurs.\r\n\nAprès que j'ai changé les paramètres des couleurs", -1, 12, 78, 274, 34 - AUTORADIOBUTTON "&Redémarrer l'ordinateur avant d'appliquer les nouveaux paramètres des couleurs.", IDC_RESTART_RB, 14, 116, 274, 10 - AUTORADIOBUTTON "Appliquer les nouveaux paramètres des couleurs sans redémarrer.", IDC_WITHOUTREBOOT_RB, 14, 131, 274, 10 - AUTORADIOBUTTON "Me demander avant d'appliquer les nouveaux paramètres des couleurs.", IDC_ASKME_RB, 14, 146, 274, 10 + LTEXT "Quelques programmes peuvent mal fonctionner si vous ne redémarrez pas votre ordinateur après que vous ayiez changé les paramètres des couleurs.\r\n\nAprès que j'ai changé les paramètres des couleurs", -1, 12, 78, 228, 34 + AUTORADIOBUTTON "&Redémarrer l'ordinateur avant d'appliquer les nouveaux paramètres des couleurs.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Appliquer les nouveaux paramètres des couleurs sans redémarrer.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Me demander avant d'appliquer les nouveaux paramètres des couleurs.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/he-IL.rc b/dll/cpl/desk/lang/he-IL.rc index 983dd853183..bee14812ff6 100644 --- a/dll/cpl/desk/lang/he-IL.rc +++ b/dll/cpl/desk/lang/he-IL.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "בחר תמונה שתשמש כרקע שולחן העבודה שלך:", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "סייר...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "צבע...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "מיקום", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "סייר...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "צבע...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "מיקום", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "הגדרות", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "תצוגה מקדימה", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "חכה", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "דקות", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "שאל לסיסמה בעת חידוש", IDC_SCREENS_USEPASSCHK, "button", - BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 104, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Energy Saving features of monitor", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "To adjust the power settings for your monitor, click on Power Settings.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "P&ower...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "סגנון חזותי", IDC_STATIC, 7, 130, 64, 7 + LTEXT "סגנון חזותי", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "ערכת צבעים", IDC_STATIC, 7, 160, 64, 7 + LTEXT "ערכת צבעים", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "אפקטים...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "מתקדם...", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "גודל", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "גודל", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "צבע שני", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "גופן", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "גופן", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "גודל גופן", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "גודל גופן", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "צבע", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "צבע", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "אפקטים" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Use the following transition effect for menus and tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&se the following method to smooth edges of screen fonts",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "השתמש בסמלים גדולים",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "ביטול", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "אישור", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Drag the monitor icons to match the physical arrangement of your monitors.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "תצוגה:",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "תצוגה:",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "גודל תצוגה:",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "פחות",1815,9,137,15,8,NOT WS_GROUP - LTEXT "יותר",1816,93,137,21,8,NOT WS_GROUP + LTEXT "פחות",1815,9,137,25,9,NOT WS_GROUP + LTEXT "יותר",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "צבעים",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "כללי" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "תצוגה", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "גודל גופן", -1, 14, 20, 222, 8 + LTEXT "גודל גופן", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "תאימות", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/hu-HU.rc b/dll/cpl/desk/lang/hu-HU.rc index 03ee031d7a4..35071b13903 100644 --- a/dll/cpl/desk/lang/hu-HU.rc +++ b/dll/cpl/desk/lang/hu-HU.rc @@ -10,13 +10,13 @@ BEGIN 70, 10, 105, 80, 0 CONTROL "", IDC_BACKGROUND_LIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | - WS_BORDER | WS_TABSTOP, 7, 99, 174, 71 + WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Válasszon ki egy képet az asztala hátterének", - IDC_STATIC, 8, 103, 180, 8 - PUSHBUTTON "&Kiválasztás...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Színek...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Elrendezés", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Kiválasztás...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Színek...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Elrendezés", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -32,16 +32,16 @@ BEGIN PUSHBUTTON "Se&ttings", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Pre&view", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Wait", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutes", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Ask for &password on resume.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Ask for &password on resume", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Energy Saving features of monitor", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "To adjust the power settings for your monitor, click on Power Settings.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "P&ower...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -52,11 +52,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Colorscheme", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Colorscheme", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effects...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Advanced", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -74,7 +74,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Size", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Size", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -84,13 +84,13 @@ BEGIN LTEXT "&2nd Color", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Fontsize", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Fontsize", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Color", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Color", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -107,19 +107,19 @@ CAPTION "Effects" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Use the following transition effect for menus and tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&se the following method to smooth edges of screen fonts",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Us&e large icons",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -131,13 +131,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Drag the monitor icons to match the physical arrangement of your monitors.",-1,3,3,240,10 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Képernyő",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Képernyő",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "Ké&pméret",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Kisebb",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Nagyobb",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Kisebb",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Nagyobb",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Színek",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -152,14 +152,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Display", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Font Size", -1, 14, 20, 222, 8 + LTEXT "Font Size", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibility", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/id-ID.rc b/dll/cpl/desk/lang/id-ID.rc index 3fda1e855db..d3718658059 100644 --- a/dll/cpl/desk/lang/id-ID.rc +++ b/dll/cpl/desk/lang/id-ID.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Pilih gambar untuk dipakai sebagai desktop wallpaper anda", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Lihat...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Warna...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Penempatan", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Lihat...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Warna...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Penempatan", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "Se&ttings", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Pre&view", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Wait", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutes", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Ask for &password on resume.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Ask for &password on resume", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Energy Saving features of monitor", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "To adjust the power settings for your monitor, click on Power Settings.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "P&ower...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "SkemaWarna", IDC_STATIC, 7, 160, 64, 7 + LTEXT "SkemaWarna", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effects...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Lanjutan", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Elemen", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Ukuran", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Ukuran", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "Warna ke-&2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Besar Font", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Besar Font", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Warna", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Warna", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Effects" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Use the following transition effect for menus and tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&se the following method to smooth edges of screen fonts",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Us&e large icons",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Drag the monitor icons to match the physical arrangement of your monitors.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Tampilan",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Tampilan",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "Area &Layar",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Kurang",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Lebih",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Kurang",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Lebih",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Warna",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Display", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Font Size", -1, 14, 20, 222, 8 + LTEXT "Font Size", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibility", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/it-IT.rc b/dll/cpl/desk/lang/it-IT.rc index b84b27b1e0f..8a9871c9f91 100644 --- a/dll/cpl/desk/lang/it-IT.rc +++ b/dll/cpl/desk/lang/it-IT.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Selezionare un'immagine da usare come sfondo per il desktop", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Esplora...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Colore...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Posizione", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Esplora...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Colore...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Posizione", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "&Impostazioni", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Anteprima", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Attesa", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minuti", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Chiedere la &password al ripristino.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Chiedere la &password al ripristino", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Funzioni di risparmio energetico del monitor", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Per regolare le impostazioni premere Alimentazione.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "Alim&entazione...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Schema dei colori", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Schema dei colori", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Dimensione", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Dimensione", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effetti...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "A&vanzato...", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Elemento", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Dimensione", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Dimensione", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "&Secondo colore", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Carattere", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Carattere", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Dimensione del carattere", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Dimensione del carattere", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Colore", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Colore", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "G", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Effetti" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Usare il seguente effetto per le transizioni in menu e tooltip",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&sare il seguente metodo per arrotondare i bordi dei font per lo schermo",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Usare le icone grandi",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "&Ombreggiatura sotto i menu",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Mostrare il contenuto delle finestr mentre le si trascina",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Nascondere la sottolineatura delle lettere di navigazione finche non è premuto il tasto Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Annulla", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Trascinare le icone dei monitor in modo corrispondente alla disposizione fisica dei vostri monitor.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Schermo",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Schermo",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Risoluzione dello schermo",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Min",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Max",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Min",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Max",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Colori",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "Generale" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Monitor", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Dimensione font", -1, 14, 20, 222, 8 + LTEXT "Dimensione font", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibilità", -1, 7, 67, 237, 97 LTEXT "Alcuni programmi potrebbero funzionare in modo irregolare se non riavviate il computer dopo una modifica delle impostazioni dei colori.\r\n\nDopo la modifica delle impostazioni dei colori", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Riavviare il computer prima di applicare le nuove impostazioni.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Applicare le nuove impostazioni dei colori senza riavviare.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Chiedere prima di applicare le nuove impostazioni dei colori.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Riavviare il computer prima di applicare le nuove impostazioni.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Applicare le nuove impostazioni dei colori senza riavviare.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Chiedere prima di applicare le nuove impostazioni dei colori.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/ja-JP.rc b/dll/cpl/desk/lang/ja-JP.rc index 9e1c84fdfe0..023743cb064 100644 --- a/dll/cpl/desk/lang/ja-JP.rc +++ b/dll/cpl/desk/lang/ja-JP.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "デスクトップの壁紙として使う画像を選択してください:", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "参照(&B)...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "色(&C)...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "表示位置:", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "参照(&B)...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "色(&C)...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "表示位置:", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "設定(&T)", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "プレビュー(&V)", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "待ち時間(&W)", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "分間", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "レジューム時にパスワードを確認する(&P)",IDC_SCREENS_USEPASSCHK,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "モニタの省電力機能(&E)", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "モニタの電源設定を変更するには、[電源] を クリックしてください。", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "電源(&O)...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 9, "MS UI Gothic" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "配色", IDC_STATIC, 7, 160, 64, 7 + LTEXT "配色", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "効果(&E)...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "詳細設定(&V)...", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "設定要素:", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "サイズ(&S)", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "サイズ(&S)", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "色 2(&2):", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "フォント:", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "フォント:", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "サイズ:", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "サイズ:", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "色:", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "色:", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "効果" FONT 9, "MS UI Gothic" BEGIN CONTROL "次のアニメーション効果をメニューとツール チップに使用する(&U):",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "次の方法でスクリーン フォントの縁を滑らかにする(&S):",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "大きいアイコンを使用する(&E)",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "メニューの下に影を表示する(&A)",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "ドラッグ中にウィンドウの内容を表示する(&W)",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "Alt キーを押すまでキーボード ナビゲーションの下線を隠しておく(&H)",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "キャンセル", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 9, "MS UI Gothic" BEGIN LTEXT "モニタのアイコンを実際のモニタの配列と一致するように移動してください。",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "ディスプレイ(&D):",1820,3,107,30,8 - LTEXT "<なし>",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "ディスプレイ(&D):",1820,3,107,70,9 + LTEXT "<なし>",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "画面の解像度(&S)",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "小",1815,9,137,15,8,NOT WS_GROUP - LTEXT "大",1816,93,137,21,8,NOT WS_GROUP + LTEXT "小",1815,9,137,25,9,NOT WS_GROUP + LTEXT "大",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "色(&C)",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "全般" FONT 9, "MS UI Gothic" BEGIN GROUPBOX "表示", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "フォント サイズ:", -1, 14, 20, 222, 8 + LTEXT "フォント サイズ:", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "互換性", -1, 7, 67, 237, 97 LTEXT "色の設定を変更した後にコンピュータを再起動しないと、プログラムが正常に動作しないことがあります。\r\n\n色の設定を変更した後の動作:", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "新しい色の設定を適用する前に、コンピュータを再起動する(&R)", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "再起動せずに、新しい色の設定を適用する", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "新しい色の設定を適用する前に確認する", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "新しい色の設定を適用する前に、コンピュータを再起動する(&R)", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "再起動せずに、新しい色の設定を適用する", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "新しい色の設定を適用する前に確認する", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/nl-NL.rc b/dll/cpl/desk/lang/nl-NL.rc index ab9516ae4a4..958ce93f7c6 100644 --- a/dll/cpl/desk/lang/nl-NL.rc +++ b/dll/cpl/desk/lang/nl-NL.rc @@ -13,11 +13,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Kies een afbeelding als bureaublad achtergrond", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Bladeren...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Kleur...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "&Weergave", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Bladeren...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Kleur...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "&Weergave", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -33,16 +33,16 @@ BEGIN PUSHBUTTON "&Instellingen", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Voorbeeld", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Wacht", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minuten", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Ask for &password on resume.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Ask for &password on resume", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Energie van het beeldscherm", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Om de energie instellingen van uw monitor in te stellen, klik op Energie.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "&Energie...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -53,11 +53,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Kleurenschema", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Kleurenschema", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effecten...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Geavan&ceerd...", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -75,7 +75,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Grootte", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Grootte", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -85,13 +85,13 @@ BEGIN LTEXT "Kleur &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "&Lettertype", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "&Lettertype", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Grootte", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Grootte", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Kleur", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Kleur", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -108,19 +108,19 @@ CAPTION "Effecten" FONT 8, "MS Shell Dlg" BEGIN CONTROL "De volgende overgangseffecten voor men&u's en knopinfo gebruiken",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 - COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 + COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "Randen van letter&s vloeiend op het scherm weergeven, en wel als volgt",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "&Grote pictogrammen gebruiken",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Sch&aduw onder menu's weergeven",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "De in&houd van het venster tijdens het slepen weergeven",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "Onderstreepte letters voor toetsenbordnavigatie &verbergen tot ALT wordt ingedrukt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Annuleren", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -132,13 +132,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Drag the monitor icons to match the physical arrangement of your monitors.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Scherm",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,1116,224,8 + LTEXT "&Scherm",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Schermresolutie",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Minder",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Meer",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Minder",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Meer",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Kleuren",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -153,14 +153,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Display", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Font Size", -1, 14, 20, 222, 8 + LTEXT "Font Size", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibility", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/no-NO.rc b/dll/cpl/desk/lang/no-NO.rc index 1805f18f3f7..ab87d4ce520 100644 --- a/dll/cpl/desk/lang/no-NO.rc +++ b/dll/cpl/desk/lang/no-NO.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Velg et bilde som du vil bruke som skrivebordbakgrunn", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Bla gjennom...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Farger...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Plassering", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Bla gjennom...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Farger...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Plassering", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "Inn&stillinger", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Forhånds&visning ", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Vent",IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME ,UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutter", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Krev &passord ved gjenopptakelse.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Krev &passord ved gjenopptakelse", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Strømsparing funksjon", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "For å tilpasse strøminnstillingene for din skjerm, klikk på strøm innstillingene.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "S&trøm...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Fargevalg", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Fargevalg", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effekter...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Avansert", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Størrelse", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 64, 9 + LTEXT "&Størrelse", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "&Farge 2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Skrift", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Skrift", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Størrelse", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Størrelse", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Farger", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Farger", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Effekter" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Bruk følgende overgang effekter for menyer og verktøytips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "B&ruk følgende metode for kantutjevning av skjerm skifter",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Br&uk store ikoner",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Vis sk&ygger under menyer",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Vis &vindu innholdet ved flytting",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Skjul visning av understrekning for tastatur hurtigtast til jeg trykker på Alt tasten",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Avbryt", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Dra skjermikonene for å tilpasse fysisk til din skjerm.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Skjerm",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Skjerm",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Skjermområde",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Mindre",1815,9,137,21,8,NOT WS_GROUP - LTEXT "Større",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Mindre",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Større",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Farger",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "Generielt" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Vis", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Skriftstørrelse", -1, 14, 20, 222, 8 + LTEXT "Skriftstørrelse", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Kompatibilitet", -1, 7, 67, 237, 97 LTEXT "Noen programmer fungerer kanskje ikke skikkelig hvis du ikke starter datamaskinen på nytt etter å ha endret skjerminnstillingene.\r\n\nGjør følgende etter at skjerminnstillingene er endret", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Start maskinen på nytt før de nye skjerminnstillingene tas i bruk.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Bruk de nye skjerminnstillingene uten å starte på nytt.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Spør før de nye skjerminnstillingene tas i bruk.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Start maskinen på nytt før de nye skjerminnstillingene tas i bruk.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Bruk de nye skjerminnstillingene uten å starte på nytt.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Spør før de nye skjerminnstillingene tas i bruk.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/pl-PL.rc b/dll/cpl/desk/lang/pl-PL.rc index 46d6e7d4964..1960205e384 100644 --- a/dll/cpl/desk/lang/pl-PL.rc +++ b/dll/cpl/desk/lang/pl-PL.rc @@ -20,11 +20,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Wybierz obraz do użycia jako tapeta pulpitu", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Przeglądaj...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Kolor...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Położenie", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Przeglądaj...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Kolor...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Położenie", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -40,16 +40,16 @@ BEGIN PUSHBUTTON "&Ustawienia", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Podgląd", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Czekaj", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 35, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME ,UPDOWN_CLASS,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 55, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minut", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "Po wznowieniu chroń &hasłem", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Zasilanie monitora", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Kliknij przycisk Zasilanie, aby dopasować ustawienia zasilania dla monitora i oszczędzanie energii.", - IDC_STATIC, 14, 166, 146, 25 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "Z&asilanie...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -60,11 +60,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Motyw graficzny", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Motyw graficzny", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Schemat kolorów", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Schemat kolorów", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Rozmiar", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Rozmiar", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efekty...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Zaawansowane", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -82,7 +82,7 @@ BEGIN LTEXT "&Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Rozmiar", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Rozmiar", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -92,13 +92,13 @@ BEGIN LTEXT "Kolor &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "&Czcionka", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "&Czcionka", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Roz&miar", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Roz&miar", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Kol&or", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Kol&or", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -115,19 +115,19 @@ CAPTION "Efekty" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Użyj następującego efektu przejścia dla menu i etykiet narzędzi",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "Uż&yj następującej metody wygładzania krawędzi czcionek ekranowych",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Uży&j dużych ikon",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Pok&aż cienie pod menu",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Pokaż za&wartość okna podczas przeciągania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "U&kryj podkreślenie liter do nawigacji klawiaturą o ile klawisz Alt nie jest wciśnięty",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Anuluj", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -139,13 +139,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Przeciągnij ikony monitorów tak, by przedstawiały fizyczne rozmieszczenie twoich monitorów.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Ekran",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Ekran",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Rozdzielczość ekranu",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Mniej",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Więcej",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Mniej",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Więcej",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Ilość kolorów",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -160,14 +160,14 @@ CAPTION "Ogólne" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Ekran", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Rozmiar czcionek", -1, 14, 20, 222, 8 + LTEXT "Rozmiar czcionek", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Tryb zgodności", -1, 7, 67, 237, 97 LTEXT "Niektóre programy mogą działać niepoprawnie, jeśli po zmianie ustawień ekranu nie zrestartujesz systemu.\r\n\nPo zmianie ustawień ekranu", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Zrestartuj system przed wprowadzeniem zmian.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Zastosuj nowe ustawienia ekranu bez restartu systemu.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Zapytaj mnie przed wprowadzeniem zmian w ustawieniach ekranu.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Zrestartuj system przed wprowadzeniem zmian.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Zastosuj nowe ustawienia ekranu bez restartu systemu.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Zapytaj mnie przed wprowadzeniem zmian w ustawieniach ekranu.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/ro-RO.rc b/dll/cpl/desk/lang/ro-RO.rc index bcf43ee8d95..9e67376ab59 100644 --- a/dll/cpl/desk/lang/ro-RO.rc +++ b/dll/cpl/desk/lang/ro-RO.rc @@ -12,11 +12,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Alegeți o imagine pentru a o folosi ca decor de birou.", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Răsfoire…", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "C&uloare…", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Amplasament", IDC_STATIC, 188, 138, 46, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Răsfoire…", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "C&uloare…", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Amplasament", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,17 +31,17 @@ BEGIN COMBOBOX IDC_SCREENS_LIST, 14, 103, 100, 100, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Opțiuni", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Pre&vizionare", IDC_SCREENS_TESTSC, 175, 103, 50, 13 - LTEXT "În vigoare &după:", IDC_WAITTEXT, 14, 125, 56, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 70, 123, 32, 13, ES_RIGHT | WS_GROUP + LTEXT "În vigoare &după:", IDC_WAITTEXT, 14, 125, 20, 9 + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 90, 123, 12, 13 - LTEXT "minute", IDC_MINTEXT, 106, 125, 26, 9 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 + LTEXT "minute", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "&Solicită parolă la revenire", IDC_SCREENS_USEPASSCHK, "button", - BS_AUTOCHECKBOX | WS_TABSTOP | BS_MULTILINE, 170, 120, 60, 22 + BS_AUTOCHECKBOX | WS_TABSTOP | BS_MULTILINE, 108, 120, 117, 19 GROUPBOX "Me&canisme de gestiune a consumului", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Aici veți putea ajusta parametrii actuali pentru gestiunea consumului de energie.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "&Energie…", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -52,11 +52,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Stil vizual", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Stil vizual", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Colorit", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Colorit", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efecte…", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "A&vansate…", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -74,7 +74,7 @@ BEGIN LTEXT "&Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Mărime", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 30, 9 + LTEXT "&Mărime", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -84,13 +84,13 @@ BEGIN LTEXT "Culoare &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "F&ont", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "F&ont", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Măr&ime", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Măr&ime", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "&Culoare", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 30, 9 + LTEXT "&Culoare", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "A", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -100,26 +100,26 @@ BEGIN DEFPUSHBUTTON "Con&firmă", IDOK, 137, 220, 50, 14 END -IDD_EFFAPPEARANCE DIALOGEX DISCARDABLE 0, 0, 190, 185 +IDD_EFFAPPEARANCE DIALOGEX DISCARDABLE 0, 0, 285, 185 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE CAPTION "Efecte vizuale" FONT 8, "MS Shell Dlg" BEGIN CONTROL "Aplică &efect de tranziție pentru meniuri și ponturi:",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 210, 19 - COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 33, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 + COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "&Rotunjește marginile de text folosind metoda:",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 210, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "&Pictograme mari",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 210, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Afișează &umbre sub meniuri",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 210, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Afișează ferestrele și în timpul &mișcării lor",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 210, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Amână sublinierea literelor navigării din tastatură până la apăsarea tastei «Alt»",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | BS_MULTILINE, 10, 125, 170, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | BS_MULTILINE, 10, 125, 267, 19 PUSHBUTTON "A&nulează", IDCANCEL, 130, 165, 50, 14 DEFPUSHBUTTON "Con&firmă", IDOK, 77, 165, 50, 14 END @@ -131,13 +131,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Mișcați miniaturile ecranelor până vor corespunde cu amplasamentul fizic al ecranelor (opțiune pentru ecrane multiple).",-1,3,3,240,20 CONTROL "", IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Dispozitive de afișare",1820,3,107,100,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Dispozitive de afișare",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "Re&zoluție ecran",1818,3,127,115,43 CONTROL "", IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "Mică", 1815,9,137,15,8,NOT WS_GROUP - LTEXT "Mare", 1816,93,137,21,8,NOT WS_GROUP + LTEXT "Mică", 1815,9,137,25,9,NOT WS_GROUP + LTEXT "Mare", 1816,93,137,25,9,NOT WS_GROUP LTEXT "", IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "Amplitudine &culoare",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -152,14 +152,14 @@ CAPTION "Generale" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Afișare", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Mărime font", -1, 14, 20, 222, 8 + LTEXT "Mărime font", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibilitate", -1, 7, 67, 237, 97 LTEXT "Unele programe pot funcționa anormal dacă sunt aduse modificări în configurația culorilor fără a reporni apoi calculatorul.\r\n\nDupă efectuarea unor modificări:", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Repornește calculatorul pentru a aplica noua configurație", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Aplică noua &configurație fără a reporni calculatorul", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Solicită-mi &decizia la momentul aplicării noii configurații", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Repornește calculatorul pentru a aplica noua configurație", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Aplică noua &configurație fără a reporni calculatorul", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Solicită-mi &decizia la momentul aplicării noii configurații", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/ru-RU.rc b/dll/cpl/desk/lang/ru-RU.rc index 573f3e6bfa4..6ce0a9224f2 100644 --- a/dll/cpl/desk/lang/ru-RU.rc +++ b/dll/cpl/desk/lang/ru-RU.rc @@ -11,11 +11,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Выберите изображение для рабочего стола", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Обзор...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Цвет...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Расположение", IDC_STATIC, 188, 138, 50, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Обзор...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Цвет...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Расположение", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -31,16 +31,16 @@ BEGIN PUSHBUTTON "&Параметры", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "П&росмотр", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "И&нтервал", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "мин.", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "На&чинать с экрана приветствия", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Энергосбережение", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Для изменения параметров питания монитора нажмите кнопку ""Питание"".", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "П&итание...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -51,11 +51,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Цветовая схема", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Цветовая схема", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Эффекты...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Дополнительно", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -73,7 +73,7 @@ BEGIN LTEXT "Элемент", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Размер", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Размер", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -83,13 +83,13 @@ BEGIN LTEXT "Цвет &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Шрифт", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Шрифт", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Размер", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Размер", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Цвет", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Цвет", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "Ж", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -106,19 +106,19 @@ CAPTION "Эффекты" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Применять следующий переходный эффект для меню и подсказок",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "Пр&именять следующий метод сглаживания для экранных шрифтов",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Применять &крупные значки",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Отображать &тени, отбрасываемые меню",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "&Отображать содержимое окна при перетаскивании",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "Скр&ывать указатели вызова с клавиатуры до нажатия ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Отмена", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -130,13 +130,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Разместите значки мониторов в соответствии с их расположением.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Дисплей",1820,3,107,30,8 - LTEXT "<нет>",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Дисплей",1820,3,107,70,9 + LTEXT "<нет>",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Разрешение экрана",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "мен.",1815,9,137,15,8,NOT WS_GROUP - LTEXT "бол.",1816,93,137,21,8,NOT WS_GROUP + LTEXT "мен.",1815,9,137,25,9,NOT WS_GROUP + LTEXT "бол.",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Качество цветопередачи",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -151,14 +151,14 @@ CAPTION "Общие" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Экран", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Размер шрифта", -1, 14, 20, 222, 8 + LTEXT "Размер шрифта", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Совместимость", -1, 7, 67, 237, 97 LTEXT "Некоторые программы могут работать неправильно, если вы не перезагрузите компьютер после изменения параметров экрана.\r\n\nПосле изменения параметров экрана следует", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "Пере&загрузить компьютер с новыми параметрами экрана", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "&Применить новые параметры экрана без перезагрузки", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "З&апросить перед применением новых параметров экрана", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "Пере&загрузить компьютер с новыми параметрами экрана", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "&Применить новые параметры экрана без перезагрузки", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "З&апросить перед применением новых параметров экрана", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/sk-SK.rc b/dll/cpl/desk/lang/sk-SK.rc index 05575c09982..c95b1f46fa0 100644 --- a/dll/cpl/desk/lang/sk-SK.rc +++ b/dll/cpl/desk/lang/sk-SK.rc @@ -19,11 +19,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Vyberte obrázok, ktorý chcete použiť ako pozadie pracovnej plochy", - IDC_STATIC, 8, 103, 220, 9 - PUSHBUTTON "&Prehľadávať...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Farba...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "&Umiestnenie", IDC_STATIC, 188, 138, 50, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Prehľadávať...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Farba...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "&Umiestnenie", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -39,12 +39,12 @@ BEGIN PUSHBUTTON "&Nastavenie", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Ukážka", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Počkať", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minút", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Pri obnovení chrániť &heslom.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Pri obnovení chrániť &heslom", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "Napájani&e monitora", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Ak chcete upraviť nastavenie napájania monitora a ušetriť energiu, kliknite na tlačidlo Napájanie.", @@ -59,11 +59,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "&Farebná schéma", IDC_STATIC, 7, 160, 64, 7 + LTEXT "&Farebná schéma", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efekty...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "&Spresniť", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -91,13 +91,13 @@ BEGIN LTEXT "Far&ba 2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "&Písmo", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "&Písmo", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "V&eľkosť", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "V&eľkosť", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Fa&rba", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Fa&rba", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -114,19 +114,19 @@ CAPTION "Efekty" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Používať nasledovný efekt prechodu pre ponuky a názvy tlačidiel",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "Po&užívať nasledovnú metódu vyhladenia okrajov zobrazeného písma",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Používať &veľké ikony",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "&Zobrazovať tiene pod ponukami",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Zobrazovať &obsah okna počas presúvania",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Skrývať podčiarknuté písmená (klávesové skratky) až do stlačenia klávesu Alt",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Zrušiť", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -138,13 +138,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Ťahaním zoraďte ikony podľa fyzického rozmiestnenia monitorov.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Monitor",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Monitor",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Rozlíšenie obrazovky",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "nižšie",1815,9,137,20,8,NOT WS_GROUP - LTEXT "vyššie",1816,93,137,21,8,NOT WS_GROUP + LTEXT "nižšie",1815,9,137,25,9,NOT WS_GROUP + LTEXT "vyššie",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Farby",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -159,14 +159,14 @@ CAPTION "Všeobecné" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Zobrazenie", -1, 7, 6, 237, 56, WS_GROUP // Display=viac významov - LTEXT "Veľkosť písma", -1, 14, 20, 222, 8 + LTEXT "Veľkosť písma", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Kompatibilita", -1, 7, 67, 237, 97 LTEXT "Niektoré programy nemusia pracovať správne, ak po zmene nastavení farieb nereštartujete počítač.\r\n\nPo zmene nastavení farieb", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Reštartovať počítač pred použitím nových nastavení farieb.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Použiť &nové nastavenia farieb bez reštartovania.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "&Opýtať sa pred použitím nových nastavení farieb.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Reštartovať počítač pred použitím nových nastavení farieb.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Použiť &nové nastavenia farieb bez reštartovania.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "&Opýtať sa pred použitím nových nastavení farieb.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/sv-SE.rc b/dll/cpl/desk/lang/sv-SE.rc index eb2f1e597bf..4876c5f4a20 100644 --- a/dll/cpl/desk/lang/sv-SE.rc +++ b/dll/cpl/desk/lang/sv-SE.rc @@ -14,11 +14,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Välj en bild du vill ha som skrivbordsunderlägg", - IDC_STATIC, 8, 103, 180, 8 - PUSHBUTTON "&Bläddra...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Färg...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Placering", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "&Bläddra...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Färg...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Placering", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -34,16 +34,16 @@ BEGIN PUSHBUTTON "Se&ttings", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "Pre&view", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Wait", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "minutes", IDC_MINTEXT, 70, 125, 26, 9 - CONTROL "Ask for &password on resume.", IDC_SCREENS_USEPASSCHK, "button", + CONTROL "Ask for &password on resume", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Energy Saving features of monitor", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "To adjust the power settings for your monitor, click on Power Settings.", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "P&ower...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -54,11 +54,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Item", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Item", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Effects...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Advanced", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -76,7 +76,7 @@ BEGIN LTEXT "Element", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Size", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Size", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -86,13 +86,13 @@ BEGIN LTEXT "&2nd Color", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Font", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Fontsize", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Fontsize", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Color", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Color", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -109,19 +109,19 @@ CAPTION "Effects" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Use the following transition effect for menus and tooltips",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "U&se the following method to smooth edges of screen fonts",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Us&e large icons",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Show sh&adows under menus",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Show &window contents while dragging",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Hide underlined letters for keyboard navigation until I press the Alt key",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Cancel", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -133,13 +133,13 @@ FONT 8, "MS Shell Dlg" BEGIN LTEXT "Drag the monitor icons to match the physical arrangement of your monitors.",-1,3,3,240,10 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Bild",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Bild",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Bildyta",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30,137,58,17 - LTEXT "Lägre",1815,9,137,15,8,NOT WS_GROUP - LTEXT "Högre",1816,93,137,21,8,NOT WS_GROUP + LTEXT "Lägre",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Högre",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "&Färger",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -154,14 +154,14 @@ CAPTION "General" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Display", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Font Size", -1, 14, 20, 222, 8 + LTEXT "Font Size", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Compatibility", -1, 7, 67, 237, 97 LTEXT "Some programs operate improperly if you do not restart your computer after you change color settings.\r\n\nAfter I change color settings", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Restart the computer before applying the new color settings.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "Apply the new color settings without restarting.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Ask me before applying the new color settings.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/uk-UA.rc b/dll/cpl/desk/lang/uk-UA.rc index c5cb1404c1b..937c57cdc14 100644 --- a/dll/cpl/desk/lang/uk-UA.rc +++ b/dll/cpl/desk/lang/uk-UA.rc @@ -19,11 +19,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "Виберіть зображення для шпалер робочого столу", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "&Огляд...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "&Колір...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "Розташування", IDC_STATIC, 188, 138, 51, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 2380, 9 + PUSHBUTTON "&Огляд...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "&Колір...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "Розташування", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -39,16 +39,16 @@ BEGIN PUSHBUTTON "П&араметри", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "&Перегляд", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "&Інтервал", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "",IDC_SCREENS_TIME ,UPDOWN_CLASS,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "хв", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "За&хист паролем", IDC_SCREENS_USEPASSCHK,"button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "&Енергозбереження", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "Щоб змінити параметри живлення монітора, натисніть кнопку ""Живлення"".", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "&Живлення...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -59,11 +59,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Колірна схема", IDC_STATIC, 7, 160, 64, 7 + LTEXT "Колірна схема", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Ефекти...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "Додатково", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -81,7 +81,7 @@ BEGIN LTEXT "Елемент", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "&Розмір", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "&Розмір", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -91,13 +91,13 @@ BEGIN LTEXT "Колір &2", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "Шрифт", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "Шрифт", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Розмір", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "Розмір", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "Колір", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "Колір", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "Ж", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -114,19 +114,19 @@ CAPTION "Ефекти" FONT 8, "MS Shell Dlg" BEGIN CONTROL "&Застосовувати наступний перехідний ефект для меню та підказок",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "З&астосовувати наступний метод згладжування для екранних шрифтів",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "Застосовувати &великі значки",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "Відображати тіні від меню",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "Показати &вміст вікна під час перетягування",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "&Приховувати покажчики виклику з клавіатури до натиснення ",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "Скасувати", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "OK", IDOK, 172, 165, 50, 14 END @@ -136,15 +136,15 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Параметри" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Розташуйте значки моніторів відповідно до фактичного розташування моніторів.",-1,3,1,240,20 + LTEXT "Розташуйте значки моніторів відповідно до фактичного розташування моніторів.",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "&Дисплей",1820,3,107,30,8 - LTEXT "<немає>",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "&Дисплей",1820,3,107,70,9 + LTEXT "<немає>",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "&Область екрану",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30,137,58,17 - LTEXT "Менше",1815,9,137,24,8,NOT WS_GROUP - LTEXT "Більше",1816,93,137,24,8,NOT WS_GROUP + LTEXT "Менше",1815,9,137,25,9,NOT WS_GROUP + LTEXT "Більше",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10, NOT WS_GROUP | SS_CENTER GROUPBOX "&Якість кольоропередачі",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -159,14 +159,14 @@ CAPTION "Загальні" FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Екран", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "Розмір шрифту", -1, 14, 20, 222, 8 + LTEXT "Розмір шрифту", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "Сумісність", -1, 7, 67, 237, 97 LTEXT "Деякі програми працюватимуть неправильно, якщо ви не перезавантажите комп'ютер після зміни параметрів кольору.\r\n\nПісля зміни параметрів кольору слід", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "&Перезавантажити комп'ютер із новими параметрами кольору.", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "&Застосувати нові параметри кольору без перезавантаження.", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "Запитати перед застосуванням нових параметрів кольору.", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "&Перезавантажити комп'ютер із новими параметрами кольору.", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "&Застосувати нові параметри кольору без перезавантаження.", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "Запитати перед застосуванням нових параметрів кольору.", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/desk/lang/zh-CN.rc b/dll/cpl/desk/lang/zh-CN.rc index 12131d68fec..0e049f36456 100644 --- a/dll/cpl/desk/lang/zh-CN.rc +++ b/dll/cpl/desk/lang/zh-CN.rc @@ -18,11 +18,11 @@ BEGIN LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, 8, 114, 174, 78 LTEXT "墙纸:", - IDC_STATIC, 8, 103, 180, 9 - PUSHBUTTON "浏览(&B)...", IDC_BROWSE_BUTTON, 188, 114, 50, 15 - PUSHBUTTON "颜色(&C)...", IDC_COLOR_BUTTON, 188, 177, 50, 15 - LTEXT "位置:", IDC_STATIC, 188, 138, 36, 9 - COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 50, 54, + IDC_STATIC, 8, 103, 230, 9 + PUSHBUTTON "浏览(&B)...", IDC_BROWSE_BUTTON, 188, 114, 55, 15 + PUSHBUTTON "颜色(&C)...", IDC_COLOR_BUTTON, 188, 177, 55, 15 + LTEXT "位置:", IDC_STATIC, 188, 138, 55, 9 + COMBOBOX IDC_PLACEMENT_COMBO, 188, 149, 55, 54, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -38,16 +38,16 @@ BEGIN PUSHBUTTON "设置(&T)...", IDC_SCREENS_SETTINGS, 120, 103, 50, 13, WS_GROUP PUSHBUTTON "预览(&V)", IDC_SCREENS_TESTSC, 175, 103, 50, 13 LTEXT "等待(&W):", IDC_WAITTEXT, 14, 125, 20, 9 - EDITTEXT IDC_SCREENS_TIMEDELAY, 34, 123, 32, 13, ES_RIGHT | WS_GROUP + EDITTEXT IDC_SCREENS_TIMEDELAY, 36, 123, 32, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_SCREENS_TIME, UPDOWN_CLASS, UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - WS_BORDER | WS_GROUP, 54, 123, 12, 13 + WS_BORDER | WS_GROUP, 56, 123, 12, 13 LTEXT "分钟", IDC_MINTEXT, 70, 125, 26, 9 CONTROL "密码保护(&P)", IDC_SCREENS_USEPASSCHK, "button", BS_AUTOCHECKBOX | WS_TABSTOP, 108, 120, 117, 19 GROUPBOX "监视器的节能特征(&E)", IDC_SCREENS_DUMMY2, 6, 155, 232, 41 LTEXT "要修改监视器的电源设置,请单击“电源”。", - IDC_STATIC, 14, 166, 146, 20 + IDC_STATIC, 14, 166, 146, 27 PUSHBUTTON "电源(&O)...", IDC_SCREENS_POWER_BUTTON, 165, 171, 61, 13 END @@ -58,11 +58,11 @@ FONT 9, "MS Shell Dlg" BEGIN CONTROL "", IDC_APPEARANCE_PREVIEW, "PreviewWndClass", WS_VISIBLE | WS_BORDER, 7, 7, 232, 120 - LTEXT "Visual Style", IDC_STATIC, 7, 130, 64, 7 + LTEXT "Visual Style", IDC_STATIC, 7, 130, 104, 9 COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "色彩方案", IDC_STATIC, 7, 160, 64, 7 + LTEXT "色彩方案", IDC_STATIC, 7, 160, 104, 9 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90 , CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Size", IDC_STATIC, 7, 190, 104, 9 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "效果(&E)...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "高级(&D)", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -80,7 +80,7 @@ BEGIN LTEXT "项目:", 8, 5, 160, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_ELEMENT, 5, 170, 130, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_CHILD | WS_VSCROLL | WS_TABSTOP - LTEXT "大小(&S)", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 21, 9 + LTEXT "大小(&S)", IDC_ADVAPPEARANCE_SIZE_T, 142, 160, 39, 9 EDITTEXT IDC_ADVAPPEARANCE_SIZE_E, 142, 170, 38, 13, ES_RIGHT | WS_GROUP CONTROL "", IDC_ADVAPPEARANCE_SIZE_UD, UPDOWN_CLASS, UDS_AUTOBUDDY | WS_BORDER | WS_GROUP | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | WS_CHILD | WS_VISIBLE, 172, 170, 10, 13 @@ -90,13 +90,13 @@ BEGIN LTEXT "颜色1 (&2):", IDC_ADVAPPEARANCE_COLOR2_T, 216, 160, 40, 9 CHECKBOX "-", IDC_ADVAPPEARANCE_COLOR2_B, 216, 170, 28, 13, BS_PUSHLIKE | BS_BITMAP - LTEXT "字体:", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 8 + LTEXT "字体:", IDC_ADVAPPEARANCE_FONT_T, 5, 190, 50, 9 COMBOBOX IDC_ADVAPPEARANCE_FONT_C, 5, 200, 130, 90, CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "大小:", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 8 + LTEXT "大小:", IDC_ADVAPPEARANCE_FONTSIZE_T, 142, 190, 39, 9 COMBOBOX IDC_ADVAPPEARANCE_FONTSIZE_E, 142, 200, 38, 200, CBS_DROPDOWN | WS_VSCROLL - LTEXT "颜色:", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 20, 9 + LTEXT "颜色:", IDC_ADVAPPEARANCE_FONTCOLOR_T, 184, 190, 28, 9 CHECKBOX "", IDC_ADVAPPEARANCE_FONTCOLOR_B, 184, 200, 28, 13, BS_PUSHLIKE | BS_BITMAP AUTOCHECKBOX "B", IDC_ADVAPPEARANCE_FONTBOLD, 216, 200, 14, 13, BS_PUSHLIKE @@ -113,19 +113,19 @@ CAPTION "效果" FONT 8, "MS Shell Dlg" BEGIN CONTROL "为菜单和工具提示使用以下过渡效果(&U):",IDC_EFFAPPEARANCE_ANIMATION,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 5, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_ANIMATIONTYPE, 20, 25, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VSCROLL | WS_TABSTOP CONTROL "使用下列方式使屏幕字体的边缘平滑(&S)",IDC_EFFAPPEARANCE_SMOOTHING,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 42, 267, 19 COMBOBOX IDC_EFFAPPEARANCE_SMOOTHINGTYPE, 20, 62, 80, 19, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP | WS_DISABLED CONTROL "使用大图标(&E)",IDC_EFFAPPEARANCE_LARGEICONS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 80, 267, 19 CONTROL "在菜单下显示阴影(&A)",IDC_EFFAPPEARANCE_SETDROPSHADOW,"button", - BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED, 10, 95, 267, 19 CONTROL "拖动时显示窗口内容(&W)",IDC_EFFAPPEARANCE_DRAGFULLWINDOWS,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 110, 267, 19 CONTROL "直到我按 Alt 键之前,请隐藏有下划线的字母供键盘使用",IDC_EFFAPPEARANCE_KEYBOARDCUES,"button", - BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 285, 19 + BS_AUTOCHECKBOX | WS_TABSTOP, 10, 125, 267, 19 PUSHBUTTON "取消", IDCANCEL, 226, 165, 50, 14 DEFPUSHBUTTON "确定", IDOK, 172, 165, 50, 14 END @@ -137,13 +137,13 @@ FONT 9, "MS Shell Dlg" BEGIN LTEXT "拖动监视器图标以便与监视器的物理设置匹配。",-1,3,3,240,20 CONTROL "",IDC_SETTINGS_MONSEL,"MONITORSELWNDCLASS",WS_CHILD|WS_VISIBLE|WS_TABSTOP,3,23,240,82,WS_EX_CLIENTEDGE - LTEXT "显示(&D):",1820,3,107,30,8 - LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,8 + LTEXT "显示(&D):",1820,3,107,70,9 + LTEXT "",IDC_SETTINGS_DEVICE,9,116,224,9 GROUPBOX "屏幕区域(&S)",1818,3,127,115,43 CONTROL "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32", TBS_AUTOTICKS | WS_TABSTOP, 30, 137, 58, 17 - LTEXT "小",1815,9,137,15,8,NOT WS_GROUP - LTEXT "大",1816,93,137,21,8,NOT WS_GROUP + LTEXT "小",1815,9,137,25,9,NOT WS_GROUP + LTEXT "大",1816,93,137,25,9,NOT WS_GROUP LTEXT "",IDC_SETTINGS_RESOLUTION_TEXT,10,157,100,10,NOT WS_GROUP | SS_CENTER GROUPBOX "颜色(&C)",1817,125,127,115,43 COMBOBOX IDC_SETTINGS_BPP,131,137,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | @@ -158,14 +158,14 @@ CAPTION "常规" FONT 9, "MS Shell Dlg" BEGIN GROUPBOX "显示", -1, 7, 6, 237, 56, WS_GROUP - LTEXT "字体大小:", -1, 14, 20, 222, 8 + LTEXT "字体大小:", -1, 14, 20, 222, 9 COMBOBOX IDC_FONTSIZE_COMBO, 14, 30, 223, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "", IDC_FONTSIZE_COSTOM, 14, 46, 223, 12 GROUPBOX "兼容性", -1, 7, 67, 237, 97 LTEXT "如果在更改颜色设置后不立即重新启动计算机,某些程序可能无法正常工作。\r\n\n更改显示设置后:", -1, 12, 78, 228, 34 - AUTORADIOBUTTON "在应用新的显示设置之前重新启动计算机(&R)", IDC_RESTART_RB, 14, 116, 224, 10 - AUTORADIOBUTTON "应用新的显示设置而不重新启动计算机(&P)", IDC_WITHOUTREBOOT_RB, 14, 131, 224, 10 - AUTORADIOBUTTON "在应用新的显示设置之前询问(&K)", IDC_ASKME_RB, 14, 146, 224, 10 + AUTORADIOBUTTON "在应用新的显示设置之前重新启动计算机(&R)", IDC_RESTART_RB, 14, 116, 228, 10 + AUTORADIOBUTTON "应用新的显示设置而不重新启动计算机(&P)", IDC_WITHOUTREBOOT_RB, 14, 131, 228, 10 + AUTORADIOBUTTON "在应用新的显示设置之前询问(&K)", IDC_ASKME_RB, 14, 146, 228, 10 END IDR_PREVIEW_MENU MENU diff --git a/dll/cpl/usrmgr/lang/de-DE.rc b/dll/cpl/usrmgr/lang/de-DE.rc index 1c9d304f058..d803ab17356 100644 --- a/dll/cpl/usrmgr/lang/de-DE.rc +++ b/dll/cpl/usrmgr/lang/de-DE.rc @@ -14,11 +14,11 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_USERS_LIST, "SysListView32", LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 7, 7, 238, 85, WS_EX_CLIENTEDGE - PUSHBUTTON "A&dd...", IDC_USERS_ADD, 87, 98, 50, 14 - PUSHBUTTON "&Remove", IDC_USERS_REMOVE, 141, 98, 50, 14 - PUSHBUTTON "Pr&operties", IDC_USERS_PROPERTIES, 195, 98, 50, 14 - AUTOCHECKBOX "Require user name and password on system startup.", IDC_USERS_STARTUP_REQUIRE, 10, 118, 200, 14, WS_DISABLED - PUSHBUTTON "Reset Administrator Password", IDC_USERS_ADMIN_RESET, 142, 200, 103, 14, WS_DISABLED, 100, 16 + PUSHBUTTON "&Hinzufgen...", IDC_USERS_ADD, 87, 98, 50, 14 + PUSHBUTTON "&Entfernen", IDC_USERS_REMOVE, 141, 98, 50, 14 + PUSHBUTTON "E&igenschaften", IDC_USERS_PROPERTIES, 195, 98, 50, 14 + AUTOCHECKBOX "Benut&zer mssen Benutzername und Kennwort zum Starten eingeben", IDC_USERS_STARTUP_REQUIRE, 10, 118, 235, 14, WS_DISABLED + PUSHBUTTON "Administrator Kenn&wort zurcksetzen", IDC_USERS_ADMIN_RESET, 120, 200, 125, 14, WS_DISABLED, 100, 16 END @@ -29,9 +29,9 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "", IDC_GROUPS_LIST, "SysListView32", LVS_REPORT | LVS_EDITLABELS | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 7, 7, 238, 85, WS_EX_CLIENTEDGE - PUSHBUTTON "A&dd...", IDC_GROUPS_ADD, 87, 98, 50, 14 - PUSHBUTTON "&Remove", IDC_GROUPS_REMOVE, 141, 98, 50, 14 - PUSHBUTTON "Pr&operties", IDC_GROUPS_PROPERTIES, 195, 98, 50, 14 + PUSHBUTTON "&Hinzufgen...", IDC_GROUPS_ADD, 87, 98, 50, 14 + PUSHBUTTON "&Entfernen", IDC_GROUPS_REMOVE, 141, 98, 50, 14 + PUSHBUTTON "E&igenschaften", IDC_GROUPS_PROPERTIES, 195, 98, 50, 14 END @@ -70,8 +70,8 @@ BEGIN LTEXT "Mitglied von:", -1, 7, 7, 56, 8 CONTROL "", IDC_USER_MEMBERSHIP_LIST, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 7, 18, 238, 173, WS_EX_CLIENTEDGE - PUSHBUTTON "Hzfg...", IDC_USER_MEMBERSHIP_ADD, 7, 197, 50, 14 - PUSHBUTTON "Entfernen", IDC_USER_MEMBERSHIP_REMOVE, 61, 197, 50, 14, WS_DISABLED + PUSHBUTTON "&Hinzufgen...", IDC_USER_MEMBERSHIP_ADD, 7, 197, 50, 14 + PUSHBUTTON "&Entfernen", IDC_USER_MEMBERSHIP_REMOVE, 61, 197, 50, 14, WS_DISABLED END @@ -91,7 +91,7 @@ BEGIN AUTORADIOBUTTON "Verbinden:", IDC_USER_PROFILE_REMOTE, 16, 100, 60, 10 EDITTEXT IDC_USER_PROFILE_LOCAL_PATH, 78, 81, 160, 13, ES_AUTOHSCROLL COMBOBOX IDC_USER_PROFILE_DRIVE, 78, 99, 26, 160, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL - LTEXT "to:", -1, 112, 101, 12, 8 + LTEXT "mit:", -1, 112, 101, 12, 8 EDITTEXT IDC_USER_PROFILE_REMOTE_PATH, 130, 99, 108, 13, ES_AUTOHSCROLL END @@ -107,8 +107,8 @@ BEGIN LTEXT "Mitglieder:", -1, 7, 63, 45, 8 CONTROL "", IDC_GROUP_GENERAL_MEMBERS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, 7, 74, 238, 117, WS_EX_CLIENTEDGE - PUSHBUTTON "Hzfg...", IDC_GROUP_GENERAL_ADD, 7, 197, 50, 14 - PUSHBUTTON "Entfernen", IDC_GROUP_GENERAL_REMOVE, 61, 197, 50, 14, WS_DISABLED + PUSHBUTTON "&Hinzufgen...", IDC_GROUP_GENERAL_ADD, 7, 197, 50, 14 + PUSHBUTTON "&Entfernen", IDC_GROUP_GENERAL_REMOVE, 61, 197, 50, 14, WS_DISABLED END @@ -118,7 +118,7 @@ CAPTION "Passwort FONT 8, "MS Shell Dlg" BEGIN EDITTEXT IDC_EDIT_PASSWORD1,107,7,153,14,ES_AUTOHSCROLL | ES_PASSWORD - RTEXT "Neues Passwort!", -1,7,10,96,8 + RTEXT "Neues Passwort:", -1,7,10,96,8 EDITTEXT IDC_EDIT_PASSWORD2,107,25,153,14,ES_AUTOHSCROLL | ES_PASSWORD RTEXT "Passwort wiederholen:", -1,7,28,96,8 DEFPUSHBUTTON "OK",IDOK,156,53,50,14 diff --git a/dll/directx/CMakeLists.txt b/dll/directx/CMakeLists.txt index b121b7cabc0..578e4f426c6 100644 --- a/dll/directx/CMakeLists.txt +++ b/dll/directx/CMakeLists.txt @@ -14,6 +14,7 @@ add_subdirectory(dplayx) add_subdirectory(dsound) #add_subdirectory(dsound_new) #disabled in trunk add_subdirectory(dxdiagn) +add_subdirectory(dxgi) #add_subdirectory(ksproxy) Not needed at the moment add_subdirectory(ksuser) add_subdirectory(msdmo) diff --git a/dll/directx/devenum/createdevenum.c b/dll/directx/devenum/createdevenum.c index 936ba4d07de..bbe93523ddb 100644 --- a/dll/directx/devenum/createdevenum.c +++ b/dll/directx/devenum/createdevenum.c @@ -258,7 +258,7 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2) WCHAR wszPinName[MAX_PATH]; DWORD cName = sizeof(wszPinName) / sizeof(WCHAR); DWORD Type, cbData; - REGFILTERPINS *rgPin = &rgPins[rgf2->u.s.cPins]; + REGFILTERPINS *rgPin = &rgPins[rgf2->u.s1.cPins]; LONG lRet; rgPin->strName = NULL; @@ -298,7 +298,7 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2) DEVENUM_ReadPinTypes(hkeyPinKey, rgPin); - ++rgf2->u.s.cPins; + ++rgf2->u.s1.cPins; continue; error_cleanup: @@ -309,13 +309,13 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2) RegCloseKey(hkeyPins); - if (rgPins && !rgf2->u.s.cPins) + if (rgPins && !rgf2->u.s1.cPins) { CoTaskMemFree(rgPins); rgPins = NULL; } - rgf2->u.s.rgPins = rgPins; + rgf2->u.s1.rgPins = rgPins; } static HRESULT DEVENUM_RegisterLegacyAmFilters(void) @@ -387,8 +387,8 @@ static HRESULT DEVENUM_RegisterLegacyAmFilters(void) rgf2.dwVersion = 1; rgf2.dwMerit = 0; - rgf2.u.s.cPins = 0; - rgf2.u.s.rgPins = NULL; + rgf2.u.s1.cPins = 0; + rgf2.u.s1.rgPins = NULL; cbData = sizeof(wszFilterName); if (RegQueryValueExW(hkeyFilterClass, NULL, NULL, &Type, (LPBYTE)wszFilterName, &cbData) != ERROR_SUCCESS || @@ -414,29 +414,29 @@ static HRESULT DEVENUM_RegisterLegacyAmFilters(void) if (hkeyFilterClass) RegCloseKey(hkeyFilterClass); - if (rgf2.u.s.rgPins) + if (rgf2.u.s1.rgPins) { UINT iPin; - for (iPin = 0; iPin < rgf2.u.s.cPins; iPin++) + for (iPin = 0; iPin < rgf2.u.s1.cPins; iPin++) { - CoTaskMemFree(rgf2.u.s.rgPins[iPin].strName); + CoTaskMemFree(rgf2.u.s1.rgPins[iPin].strName); - if (rgf2.u.s.rgPins[iPin].lpMediaType) + if (rgf2.u.s1.rgPins[iPin].lpMediaType) { UINT iType; - for (iType = 0; iType < rgf2.u.s.rgPins[iPin].nMediaTypes; iType++) + for (iType = 0; iType < rgf2.u.s1.rgPins[iPin].nMediaTypes; iType++) { - CoTaskMemFree((void*)rgf2.u.s.rgPins[iPin].lpMediaType[iType].clsMajorType); - CoTaskMemFree((void*)rgf2.u.s.rgPins[iPin].lpMediaType[iType].clsMinorType); + CoTaskMemFree((void*)rgf2.u.s1.rgPins[iPin].lpMediaType[iType].clsMajorType); + CoTaskMemFree((void*)rgf2.u.s1.rgPins[iPin].lpMediaType[iType].clsMinorType); } - CoTaskMemFree((void*)rgf2.u.s.rgPins[iPin].lpMediaType); + CoTaskMemFree((void*)rgf2.u.s1.rgPins[iPin].lpMediaType); } } - CoTaskMemFree((void*)rgf2.u.s.rgPins); + CoTaskMemFree((void*)rgf2.u.s1.rgPins); } } } @@ -606,8 +606,8 @@ static HRESULT DEVENUM_CreateSpecialCategories(void) rf2.dwVersion = 2; rf2.dwMerit = MERIT_PREFERRED; - rf2.u.s1.cPins2 = 1; - rf2.u.s1.rgPins2 = &rfp2; + rf2.u.s2.cPins2 = 1; + rf2.u.s2.rgPins2 = &rfp2; rfp2.cInstances = 1; rfp2.nMediums = 0; rfp2.lpMedium = NULL; diff --git a/dll/directx/dxgi/CMakeLists.txt b/dll/directx/dxgi/CMakeLists.txt new file mode 100644 index 00000000000..10ce18f8bc6 --- /dev/null +++ b/dll/directx/dxgi/CMakeLists.txt @@ -0,0 +1,23 @@ + +add_definitions(-D__WINESRC__) +include_directories(BEFORE ${REACTOS_SOURCE_DIR}/include/reactos/wine) + +spec2def(dxgi.dll dxgi.spec ADD_IMPORTLIB) + +list(APPEND SOURCE + adapter.c + device.c + dxgi_main.c + factory.c + output.c + surface.c + swapchain.c + utils.c + ${CMAKE_CURRENT_BINARY_DIR}/dxgi.def) + +add_library(dxgi SHARED ${SOURCE} version.rc) +set_module_type(dxgi win32dll) +target_link_libraries(dxgi uuid dxgi_uuids wine) +add_importlibs(dxgi wined3d msvcrt kernel32 ntdll) +add_dependencies(dxgi wineheaders) +add_cd_file(TARGET dxgi DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/dxgi/adapter.c b/dll/directx/dxgi/adapter.c new file mode 100644 index 00000000000..87d886b1995 --- /dev/null +++ b/dll/directx/dxgi/adapter.c @@ -0,0 +1,239 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_adapter *impl_from_IWineDXGIAdapter(IWineDXGIAdapter *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_adapter, IWineDXGIAdapter_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryInterface(IWineDXGIAdapter *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IDXGIAdapter) + || IsEqualGUID(riid, &IID_IWineDXGIAdapter)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_adapter_AddRef(IWineDXGIAdapter *iface) +{ + struct dxgi_adapter *This = impl_from_IWineDXGIAdapter(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IWineDXGIAdapter *iface) +{ + struct dxgi_adapter *This = impl_from_IWineDXGIAdapter(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + IDXGIOutput_Release(This->output); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetPrivateData(IWineDXGIAdapter *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetPrivateDataInterface(IWineDXGIAdapter *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetPrivateData(IWineDXGIAdapter *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetParent(IWineDXGIAdapter *iface, REFIID riid, void **parent) +{ + struct dxgi_adapter *This = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, riid %s, parent %p\n", iface, debugstr_guid(riid), parent); + + return IWineDXGIFactory_QueryInterface(This->parent, riid, parent); +} + +/* IDXGIAdapter methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IWineDXGIAdapter *iface, + UINT output_idx, IDXGIOutput **output) +{ + struct dxgi_adapter *This = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, output_idx %u, output %p.\n", iface, output_idx, output); + + if (output_idx > 0) + { + *output = NULL; + return DXGI_ERROR_NOT_FOUND; + } + + *output = This->output; + IDXGIOutput_AddRef(*output); + + TRACE("Returning output %p.\n", output); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC *desc) +{ + struct dxgi_adapter *This = impl_from_IWineDXGIAdapter(iface); + struct wined3d_adapter_identifier adapter_id; + char description[128]; + struct wined3d *wined3d; + HRESULT hr; + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (!desc) return E_INVALIDARG; + + wined3d = IWineDXGIFactory_get_wined3d(This->parent); + adapter_id.driver_size = 0; + adapter_id.description = description; + adapter_id.description_size = sizeof(description); + adapter_id.device_name_size = 0; + + EnterCriticalSection(&dxgi_cs); + hr = wined3d_get_adapter_identifier(wined3d, This->ordinal, 0, &adapter_id); + wined3d_decref(wined3d); + LeaveCriticalSection(&dxgi_cs); + + if (SUCCEEDED(hr)) + { + if (!MultiByteToWideChar(CP_ACP, 0, description, -1, desc->Description, 128)) + { + DWORD err = GetLastError(); + ERR("Failed to translate description %s (%#x).\n", debugstr_a(description), err); + hr = E_FAIL; + } + + desc->VendorId = adapter_id.vendor_id; + desc->DeviceId = adapter_id.device_id; + desc->SubSysId = adapter_id.subsystem_id; + desc->Revision = adapter_id.revision; + desc->DedicatedVideoMemory = adapter_id.video_memory; + desc->DedicatedSystemMemory = 0; /* FIXME */ + desc->SharedSystemMemory = 0; /* FIXME */ + memcpy(&desc->AdapterLuid, &adapter_id.adapter_luid, sizeof(desc->AdapterLuid)); + } + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IWineDXGIAdapter *iface, + REFGUID guid, LARGE_INTEGER *umd_version) +{ + FIXME("iface %p, guid %s, umd_version %p stub!\n", iface, debugstr_guid(guid), umd_version); + + return E_NOTIMPL; +} + +/* IWineDXGIAdapter methods */ + +static UINT STDMETHODCALLTYPE dxgi_adapter_get_ordinal(IWineDXGIAdapter *iface) +{ + struct dxgi_adapter *This = impl_from_IWineDXGIAdapter(iface); + + TRACE("iface %p, returning %u\n", iface, This->ordinal); + + return This->ordinal; +} + +static const struct IWineDXGIAdapterVtbl dxgi_adapter_vtbl = +{ + /* IUnknown methods */ + dxgi_adapter_QueryInterface, + dxgi_adapter_AddRef, + dxgi_adapter_Release, + /* IDXGIObject methods */ + dxgi_adapter_SetPrivateData, + dxgi_adapter_SetPrivateDataInterface, + dxgi_adapter_GetPrivateData, + dxgi_adapter_GetParent, + /* IDXGIAdapter methods */ + dxgi_adapter_EnumOutputs, + dxgi_adapter_GetDesc, + dxgi_adapter_CheckInterfaceSupport, + /* IWineDXGIAdapter methods */ + dxgi_adapter_get_ordinal, +}; + +HRESULT dxgi_adapter_init(struct dxgi_adapter *adapter, IWineDXGIFactory *parent, UINT ordinal) +{ + struct dxgi_output *output; + + adapter->IWineDXGIAdapter_iface.lpVtbl = &dxgi_adapter_vtbl; + adapter->parent = parent; + adapter->refcount = 1; + adapter->ordinal = ordinal; + + output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*output)); + if (!output) + { + return E_OUTOFMEMORY; + } + dxgi_output_init(output, adapter); + adapter->output = &output->IDXGIOutput_iface; + + return S_OK; +} diff --git a/dll/directx/dxgi/device.c b/dll/directx/dxgi/device.c new file mode 100644 index 00000000000..b8e6692c3d0 --- /dev/null +++ b/dll/directx/dxgi/device.c @@ -0,0 +1,429 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_device *impl_from_IWineDXGIDevice(IWineDXGIDevice *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_device, IWineDXGIDevice_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_QueryInterface(IWineDXGIDevice *iface, REFIID riid, void **object) +{ + struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IDXGIDevice) + || IsEqualGUID(riid, &IID_IWineDXGIDevice)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + if (This->child_layer) + { + TRACE("forwarding to child layer %p\n", This->child_layer); + return IUnknown_QueryInterface(This->child_layer, riid, object); + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_device_AddRef(IWineDXGIDevice *iface) +{ + struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_device_Release(IWineDXGIDevice *iface) +{ + struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + if (This->child_layer) IUnknown_Release(This->child_layer); + EnterCriticalSection(&dxgi_cs); + wined3d_device_decref(This->wined3d_device); + LeaveCriticalSection(&dxgi_cs); + IWineDXGIFactory_Release(This->factory); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateData(IWineDXGIDevice *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetPrivateDataInterface(IWineDXGIDevice *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetPrivateData(IWineDXGIDevice *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetParent(IWineDXGIDevice *iface, REFIID riid, void **parent) +{ + IDXGIAdapter *adapter; + HRESULT hr; + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + hr = IWineDXGIDevice_GetAdapter(iface, &adapter); + if (FAILED(hr)) + { + ERR("Failed to get adapter, hr %#x.\n", hr); + return hr; + } + + hr = IDXGIAdapter_QueryInterface(adapter, riid, parent); + IDXGIAdapter_Release(adapter); + + return hr; +} + +/* IDXGIDevice methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetAdapter(IWineDXGIDevice *iface, IDXGIAdapter **adapter) +{ + struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); + struct wined3d_device_creation_parameters create_parameters; + + TRACE("iface %p, adapter %p\n", iface, adapter); + + EnterCriticalSection(&dxgi_cs); + wined3d_device_get_creation_parameters(This->wined3d_device, &create_parameters); + LeaveCriticalSection(&dxgi_cs); + + return IWineDXGIFactory_EnumAdapters(This->factory, create_parameters.adapter_idx, adapter); +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *iface, + const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage, + const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface) +{ + struct wined3d_device_parent *device_parent; + IWineDXGIDeviceParent *dxgi_device_parent; + HRESULT hr; + UINT i; + UINT j; + + TRACE("iface %p, desc %p, surface_count %u, usage %#x, shared_resource %p, surface %p\n", + iface, desc, surface_count, usage, shared_resource, surface); + + hr = IWineDXGIDevice_QueryInterface(iface, &IID_IWineDXGIDeviceParent, (void **)&dxgi_device_parent); + if (FAILED(hr)) + { + ERR("Device should implement IWineD3DDeviceParent\n"); + return E_FAIL; + } + + device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); + + FIXME("Implement DXGI<->wined3d usage conversion\n"); + + memset(surface, 0, surface_count * sizeof(*surface)); + for (i = 0; i < surface_count; ++i) + { + struct wined3d_surface *wined3d_surface; + IUnknown *parent; + + hr = device_parent->ops->create_swapchain_surface(device_parent, NULL, + desc->Width, desc->Height, wined3dformat_from_dxgi_format(desc->Format), usage, + desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE, + desc->SampleDesc.Quality, &wined3d_surface); + if (FAILED(hr)) + { + ERR("CreateSurface failed, returning %#x\n", hr); + goto fail; + } + + parent = wined3d_surface_get_parent(wined3d_surface); + hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]); + wined3d_surface_decref(wined3d_surface); + if (FAILED(hr)) + { + ERR("Surface should implement IDXGISurface\n"); + goto fail; + } + + TRACE("Created IDXGISurface %p (%u/%u)\n", surface[i], i + 1, surface_count); + } + IWineDXGIDeviceParent_Release(dxgi_device_parent); + + return S_OK; + +fail: + for (j = 0; j < i; ++j) + { + IDXGISurface_Release(surface[i]); + } + IWineDXGIDeviceParent_Release(dxgi_device_parent); + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_QueryResourceResidency(IWineDXGIDevice *iface, + IUnknown *const *resources, DXGI_RESIDENCY *residency, UINT resource_count) +{ + FIXME("iface %p, resources %p, residency %p, resource_count %u stub!\n", + iface, resources, residency, resource_count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_SetGPUThreadPriority(IWineDXGIDevice *iface, INT priority) +{ + FIXME("iface %p, priority %d stub!\n", iface, priority); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_GetGPUThreadPriority(IWineDXGIDevice *iface, INT *priority) +{ + FIXME("iface %p, priority %p stub!\n", iface, priority); + + return E_NOTIMPL; +} + +/* IWineDXGIDevice methods */ + +static struct wined3d_device * STDMETHODCALLTYPE dxgi_device_get_wined3d_device(IWineDXGIDevice *iface) +{ + struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); + + TRACE("iface %p\n", iface); + + EnterCriticalSection(&dxgi_cs); + wined3d_device_incref(This->wined3d_device); + LeaveCriticalSection(&dxgi_cs); + return This->wined3d_device; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_create_surface(IWineDXGIDevice *iface, const DXGI_SURFACE_DESC *desc, + DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IUnknown *outer, void **surface) +{ + struct dxgi_surface *object; + HRESULT hr; + + FIXME("iface %p, desc %p, usage %#x, shared_resource %p, outer %p, surface %p partial stub!\n", + iface, desc, usage, shared_resource, outer, surface); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate DXGI surface object memory\n"); + return E_OUTOFMEMORY; + } + + hr = dxgi_surface_init(object, (IDXGIDevice *)iface, outer); + if (FAILED(hr)) + { + WARN("Failed to initialize surface, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created IDXGISurface %p\n", object); + *surface = outer ? &object->IUnknown_iface : (IUnknown *)&object->IDXGISurface_iface; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_device_create_swapchain(IWineDXGIDevice *iface, + struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **wined3d_swapchain) +{ + struct dxgi_device *This = impl_from_IWineDXGIDevice(iface); + struct dxgi_swapchain *object; + HRESULT hr; + + TRACE("iface %p, desc %p, wined3d_swapchain %p.\n", + iface, desc, wined3d_swapchain); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate DXGI swapchain object memory\n"); + return E_OUTOFMEMORY; + } + + hr = dxgi_swapchain_init(object, This, desc); + if (FAILED(hr)) + { + WARN("Failed to initialize swapchain, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created IDXGISwapChain %p\n", object); + *wined3d_swapchain = object->wined3d_swapchain; + + return S_OK; +} + +static const struct IWineDXGIDeviceVtbl dxgi_device_vtbl = +{ + /* IUnknown methods */ + dxgi_device_QueryInterface, + dxgi_device_AddRef, + dxgi_device_Release, + /* IDXGIObject methods */ + dxgi_device_SetPrivateData, + dxgi_device_SetPrivateDataInterface, + dxgi_device_GetPrivateData, + dxgi_device_GetParent, + /* IDXGIDevice methods */ + dxgi_device_GetAdapter, + dxgi_device_CreateSurface, + dxgi_device_QueryResourceResidency, + dxgi_device_SetGPUThreadPriority, + dxgi_device_GetGPUThreadPriority, + /* IWineDXGIAdapter methods */ + dxgi_device_get_wined3d_device, + dxgi_device_create_surface, + dxgi_device_create_swapchain, +}; + +HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer, + IDXGIFactory *factory, IDXGIAdapter *adapter) +{ + struct wined3d_device_parent *wined3d_device_parent; + IWineDXGIDeviceParent *dxgi_device_parent; + IWineDXGIAdapter *wine_adapter; + UINT adapter_ordinal; + struct wined3d *wined3d; + void *layer_base; + HRESULT hr; + WINED3DCAPS caps; + + device->IWineDXGIDevice_iface.lpVtbl = &dxgi_device_vtbl; + device->refcount = 1; + + layer_base = device + 1; + + hr = layer->create(layer->id, &layer_base, 0, + device, &IID_IUnknown, (void **)&device->child_layer); + if (FAILED(hr)) + { + WARN("Failed to create device, returning %#x.\n", hr); + goto fail; + } + + hr = IDXGIFactory_QueryInterface(factory, &IID_IWineDXGIFactory, (void **)&device->factory); + if (FAILED(hr)) + { + WARN("This is not the factory we're looking for, returning %#x.\n", hr); + goto fail; + } + wined3d = IWineDXGIFactory_get_wined3d(device->factory); + + hr = IDXGIAdapter_QueryInterface(adapter, &IID_IWineDXGIAdapter, (void **)&wine_adapter); + if (FAILED(hr)) + { + WARN("This is not the adapter we're looking for, returning %#x.\n", hr); + EnterCriticalSection(&dxgi_cs); + wined3d_decref(wined3d); + LeaveCriticalSection(&dxgi_cs); + goto fail; + } + adapter_ordinal = IWineDXGIAdapter_get_ordinal(wine_adapter); + IWineDXGIAdapter_Release(wine_adapter); + + hr = IWineDXGIDevice_QueryInterface(&device->IWineDXGIDevice_iface, &IID_IWineDXGIDeviceParent, + (void **)&dxgi_device_parent); + if (FAILED(hr)) + { + ERR("DXGI device should implement IWineD3DDeviceParent.\n"); + goto fail; + } + + wined3d_device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); + + FIXME("Ignoring adapter type.\n"); + + hr = wined3d_get_device_caps(wined3d, adapter_ordinal, WINED3D_DEVICE_TYPE_HAL, &caps); + if (FAILED(hr) || caps.VertexShaderVersion < 4 || caps.PixelShaderVersion < 4) + { + WARN("Direct3D 10 is not supported on this GPU with the current shader backend.\n"); + if (SUCCEEDED(hr)) + hr = E_FAIL; + goto fail; + } + + EnterCriticalSection(&dxgi_cs); + hr = wined3d_device_create(wined3d, adapter_ordinal, WINED3D_DEVICE_TYPE_HAL, NULL, 0, 4, + wined3d_device_parent, &device->wined3d_device); + IWineDXGIDeviceParent_Release(dxgi_device_parent); + wined3d_decref(wined3d); + LeaveCriticalSection(&dxgi_cs); + if (FAILED(hr)) + { + WARN("Failed to create a wined3d device, returning %#x.\n", hr); + goto fail; + } + + return S_OK; + +fail: + if (device->wined3d_device) + { + EnterCriticalSection(&dxgi_cs); + wined3d_device_decref(device->wined3d_device); + LeaveCriticalSection(&dxgi_cs); + } + if (device->factory) IWineDXGIFactory_Release(device->factory); + if (device->child_layer) IUnknown_Release(device->child_layer); + return hr; +} diff --git a/dll/directx/dxgi/dxgi.spec b/dll/directx/dxgi/dxgi.spec new file mode 100644 index 00000000000..853d8e28d13 --- /dev/null +++ b/dll/directx/dxgi/dxgi.spec @@ -0,0 +1,3 @@ +@ stdcall CreateDXGIFactory(ptr ptr) +@ stdcall DXGID3D10CreateDevice(ptr ptr ptr long ptr ptr) +@ stdcall DXGID3D10RegisterLayers(ptr long) diff --git a/dll/directx/dxgi/dxgi_main.c b/dll/directx/dxgi/dxgi_main.c new file mode 100644 index 00000000000..c9d6f2e6845 --- /dev/null +++ b/dll/directx/dxgi/dxgi_main.c @@ -0,0 +1,272 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#define DXGI_INIT_GUID +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static CRITICAL_SECTION_DEBUG dxgi_cs_debug = +{ + 0, 0, &dxgi_cs, + {&dxgi_cs_debug.ProcessLocksList, + &dxgi_cs_debug.ProcessLocksList}, + 0, 0, {(DWORD_PTR)(__FILE__ ": dxgi_cs")} +}; +CRITICAL_SECTION dxgi_cs = {&dxgi_cs_debug, -1, 0, 0, 0, 0}; + +struct dxgi_main +{ + HMODULE d3d10core; + struct dxgi_device_layer *device_layers; + UINT layer_count; +}; +static struct dxgi_main dxgi_main; + +static void dxgi_main_cleanup(void) +{ + EnterCriticalSection(&dxgi_cs); + + HeapFree(GetProcessHeap(), 0, dxgi_main.device_layers); + dxgi_main.device_layers = NULL; + dxgi_main.layer_count = 0; + + FreeLibrary(dxgi_main.d3d10core); + dxgi_main.d3d10core = NULL; + + LeaveCriticalSection(&dxgi_cs); + DeleteCriticalSection(&dxgi_cs); +} + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +{ + TRACE("fdwReason %u\n", fdwReason); + + switch(fdwReason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hInstDLL); + break; + + case DLL_PROCESS_DETACH: + dxgi_main_cleanup(); + break; + } + + return TRUE; +} + +HRESULT WINAPI CreateDXGIFactory(REFIID riid, void **factory) +{ + struct dxgi_factory *object; + HRESULT hr; + + TRACE("riid %s, factory %p\n", debugstr_guid(riid), factory); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate DXGI factory object memory\n"); + *factory = NULL; + return E_OUTOFMEMORY; + } + + hr = dxgi_factory_init(object); + if (FAILED(hr)) + { + WARN("Failed to initialize swapchain, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + *factory = NULL; + return hr; + } + + TRACE("Created IDXGIFactory %p\n", object); + + hr = IDXGIFactory_QueryInterface((IDXGIFactory *)object, riid, factory); + IDXGIFactory_Release((IDXGIFactory *)object); + + return hr; +} + +static BOOL get_layer(enum dxgi_device_layer_id id, struct dxgi_device_layer *layer) +{ + UINT i; + + EnterCriticalSection(&dxgi_cs); + + for (i = 0; i < dxgi_main.layer_count; ++i) + { + if (dxgi_main.device_layers[i].id == id) + { + *layer = dxgi_main.device_layers[i]; + LeaveCriticalSection(&dxgi_cs); + return TRUE; + } + } + + LeaveCriticalSection(&dxgi_cs); + return FALSE; +} + +static HRESULT register_d3d10core_layers(HMODULE d3d10core) +{ + EnterCriticalSection(&dxgi_cs); + + if (!dxgi_main.d3d10core) + { + HRESULT hr; + HRESULT (WINAPI *d3d10core_register_layers)(void); + HMODULE mod; + BOOL ret; + + ret = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)d3d10core, &mod); + if (!ret) + { + LeaveCriticalSection(&dxgi_cs); + return E_FAIL; + } + + d3d10core_register_layers = (void *)GetProcAddress(mod, "D3D10CoreRegisterLayers"); + hr = d3d10core_register_layers(); + if (FAILED(hr)) + { + ERR("Failed to register d3d10core layers, returning %#x\n", hr); + LeaveCriticalSection(&dxgi_cs); + return hr; + } + + dxgi_main.d3d10core = mod; + } + + LeaveCriticalSection(&dxgi_cs); + + return S_OK; +} + +HRESULT WINAPI DXGID3D10CreateDevice(HMODULE d3d10core, IDXGIFactory *factory, IDXGIAdapter *adapter, + UINT flags, void *unknown0, void **device) +{ + struct layer_get_size_args get_size_args; + struct dxgi_device *dxgi_device; + struct dxgi_device_layer d3d10_layer; + UINT device_size; + DWORD count; + HRESULT hr; + + TRACE("d3d10core %p, factory %p, adapter %p, flags %#x, unknown0 %p, device %p.\n", + d3d10core, factory, adapter, flags, unknown0, device); + + hr = register_d3d10core_layers(d3d10core); + if (FAILED(hr)) + { + ERR("Failed to register d3d10core layers, returning %#x\n", hr); + return hr; + } + + if (!get_layer(DXGI_DEVICE_LAYER_D3D10_DEVICE, &d3d10_layer)) + { + ERR("Failed to get D3D10 device layer\n"); + return E_FAIL; + } + + count = 0; + hr = d3d10_layer.init(d3d10_layer.id, &count, NULL); + if (FAILED(hr)) + { + WARN("Failed to initialize D3D10 device layer\n"); + return E_FAIL; + } + + get_size_args.unknown0 = 0; + get_size_args.unknown1 = 0; + get_size_args.unknown2 = NULL; + get_size_args.unknown3 = NULL; + get_size_args.adapter = adapter; + get_size_args.interface_major = 10; + get_size_args.interface_minor = 1; + get_size_args.version_build = 4; + get_size_args.version_revision = 6000; + + device_size = d3d10_layer.get_size(d3d10_layer.id, &get_size_args, 0); + device_size += sizeof(*dxgi_device); + + dxgi_device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, device_size); + if (!dxgi_device) + { + ERR("Failed to allocate device memory\n"); + return E_OUTOFMEMORY; + } + + hr = dxgi_device_init(dxgi_device, &d3d10_layer, factory, adapter); + if (FAILED(hr)) + { + WARN("Failed to initialize device, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, dxgi_device); + *device = NULL; + return hr; + } + + TRACE("Created device %p.\n", dxgi_device); + *device = dxgi_device; + + return S_OK; +} + +HRESULT WINAPI DXGID3D10RegisterLayers(const struct dxgi_device_layer *layers, UINT layer_count) +{ + UINT i; + struct dxgi_device_layer *new_layers; + + TRACE("layers %p, layer_count %u\n", layers, layer_count); + + EnterCriticalSection(&dxgi_cs); + + if (!dxgi_main.layer_count) + new_layers = HeapAlloc(GetProcessHeap(), 0, layer_count * sizeof(*new_layers)); + else + new_layers = HeapReAlloc(GetProcessHeap(), 0, dxgi_main.device_layers, + (dxgi_main.layer_count + layer_count) * sizeof(*new_layers)); + + if (!new_layers) + { + LeaveCriticalSection(&dxgi_cs); + ERR("Failed to allocate layer memory\n"); + return E_OUTOFMEMORY; + } + + for (i = 0; i < layer_count; ++i) + { + const struct dxgi_device_layer *layer = &layers[i]; + + TRACE("layer %d: id %#x, init %p, get_size %p, create %p\n", + i, layer->id, layer->init, layer->get_size, layer->create); + + new_layers[dxgi_main.layer_count + i] = *layer; + } + + dxgi_main.device_layers = new_layers; + dxgi_main.layer_count += layer_count; + + LeaveCriticalSection(&dxgi_cs); + + return S_OK; +} diff --git a/dll/directx/dxgi/dxgi_private.h b/dll/directx/dxgi/dxgi_private.h new file mode 100644 index 00000000000..565e448ae7d --- /dev/null +++ b/dll/directx/dxgi/dxgi_private.h @@ -0,0 +1,152 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + */ + +#ifndef __WINE_DXGI_PRIVATE_H +#define __WINE_DXGI_PRIVATE_H + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include "wine/debug.h" + +#define COBJMACROS +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "objbase.h" +#include "winnls.h" + +#include "dxgi.h" +#ifdef DXGI_INIT_GUID +#include "initguid.h" +#endif +#include "wine/wined3d.h" +#include + +extern CRITICAL_SECTION dxgi_cs DECLSPEC_HIDDEN; + +/* Layered device */ +enum dxgi_device_layer_id +{ + DXGI_DEVICE_LAYER_DEBUG1 = 0x8, + DXGI_DEVICE_LAYER_THREAD_SAFE = 0x10, + DXGI_DEVICE_LAYER_DEBUG2 = 0x20, + DXGI_DEVICE_LAYER_SWITCH_TO_REF = 0x30, + DXGI_DEVICE_LAYER_D3D10_DEVICE = 0xffffffff, +}; + +struct layer_get_size_args +{ + DWORD unknown0; + DWORD unknown1; + DWORD *unknown2; + DWORD *unknown3; + IDXGIAdapter *adapter; + WORD interface_major; + WORD interface_minor; + WORD version_build; + WORD version_revision; +}; + +struct dxgi_device_layer +{ + enum dxgi_device_layer_id id; + HRESULT (WINAPI *init)(enum dxgi_device_layer_id id, DWORD *count, DWORD *values); + UINT (WINAPI *get_size)(enum dxgi_device_layer_id id, struct layer_get_size_args *args, DWORD unknown0); + HRESULT (WINAPI *create)(enum dxgi_device_layer_id id, void **layer_base, DWORD unknown0, + void *device_object, REFIID riid, void **device_layer); +}; + +/* TRACE helper functions */ +const char *debug_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; + +DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN; +enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) DECLSPEC_HIDDEN; + +/* IDXGIFactory */ +struct dxgi_factory +{ + IWineDXGIFactory IWineDXGIFactory_iface; + LONG refcount; + struct wined3d *wined3d; + UINT adapter_count; + IDXGIAdapter **adapters; +}; + +HRESULT dxgi_factory_init(struct dxgi_factory *factory) DECLSPEC_HIDDEN; + +/* IDXGIDevice */ +struct dxgi_device +{ + IWineDXGIDevice IWineDXGIDevice_iface; + IUnknown *child_layer; + LONG refcount; + struct wined3d_device *wined3d_device; + IWineDXGIFactory *factory; +}; + +HRESULT dxgi_device_init(struct dxgi_device *device, struct dxgi_device_layer *layer, + IDXGIFactory *factory, IDXGIAdapter *adapter) DECLSPEC_HIDDEN; + +/* IDXGIOutput */ +struct dxgi_output +{ + IDXGIOutput IDXGIOutput_iface; + LONG refcount; + struct dxgi_adapter *adapter; +}; + +void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter) DECLSPEC_HIDDEN; + +/* IDXGIAdapter */ +struct dxgi_adapter +{ + IWineDXGIAdapter IWineDXGIAdapter_iface; + IWineDXGIFactory *parent; + LONG refcount; + UINT ordinal; + IDXGIOutput *output; +}; + +HRESULT dxgi_adapter_init(struct dxgi_adapter *adapter, IWineDXGIFactory *parent, UINT ordinal) DECLSPEC_HIDDEN; + +/* IDXGISwapChain */ +struct dxgi_swapchain +{ + IDXGISwapChain IDXGISwapChain_iface; + LONG refcount; + struct wined3d_swapchain *wined3d_swapchain; +}; + +HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device, + struct wined3d_swapchain_desc *desc) DECLSPEC_HIDDEN; + +/* IDXGISurface */ +struct dxgi_surface +{ + IDXGISurface IDXGISurface_iface; + IUnknown IUnknown_iface; + IUnknown *outer_unknown; + LONG refcount; + IDXGIDevice *device; +}; + +HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, IUnknown *outer) DECLSPEC_HIDDEN; + +#endif /* __WINE_DXGI_PRIVATE_H */ diff --git a/dll/directx/dxgi/factory.c b/dll/directx/dxgi/factory.c new file mode 100644 index 00000000000..72927c53639 --- /dev/null +++ b/dll/directx/dxgi/factory.c @@ -0,0 +1,370 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_factory *impl_from_IWineDXGIFactory(IWineDXGIFactory *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_factory, IWineDXGIFactory_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_factory_QueryInterface(IWineDXGIFactory *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IDXGIFactory) + || IsEqualGUID(riid, &IID_IWineDXGIFactory)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_factory_AddRef(IWineDXGIFactory *iface) +{ + struct dxgi_factory *This = impl_from_IWineDXGIFactory(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_factory_Release(IWineDXGIFactory *iface) +{ + struct dxgi_factory *This = impl_from_IWineDXGIFactory(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + UINT i; + + for (i = 0; i < This->adapter_count; ++i) + { + IDXGIAdapter_Release(This->adapters[i]); + } + HeapFree(GetProcessHeap(), 0, This->adapters); + + EnterCriticalSection(&dxgi_cs); + wined3d_decref(This->wined3d); + LeaveCriticalSection(&dxgi_cs); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_factory_SetPrivateData(IWineDXGIFactory *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_SetPrivateDataInterface(IWineDXGIFactory *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetPrivateData(IWineDXGIFactory *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetParent(IWineDXGIFactory *iface, REFIID riid, void **parent) +{ + WARN("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + *parent = NULL; + + return E_NOINTERFACE; +} + +/* IDXGIFactory methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters(IWineDXGIFactory *iface, + UINT adapter_idx, IDXGIAdapter **adapter) +{ + struct dxgi_factory *This = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p, adapter_idx %u, adapter %p\n", iface, adapter_idx, adapter); + + if (!adapter) return DXGI_ERROR_INVALID_CALL; + + if (adapter_idx >= This->adapter_count) + { + *adapter = NULL; + return DXGI_ERROR_NOT_FOUND; + } + + *adapter = This->adapters[adapter_idx]; + IDXGIAdapter_AddRef(*adapter); + + TRACE("Returning adapter %p\n", *adapter); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_MakeWindowAssociation(IWineDXGIFactory *iface, HWND window, UINT flags) +{ + FIXME("iface %p, window %p, flags %#x stub!\n\n", iface, window, flags); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_GetWindowAssociation(IWineDXGIFactory *iface, HWND *window) +{ + FIXME("iface %p, window %p stub!\n", iface, window); + + return E_NOTIMPL; +} + +static UINT dxgi_rational_to_uint(const DXGI_RATIONAL *rational) +{ + if (rational->Denominator) + return rational->Numerator / rational->Denominator; + else + return rational->Numerator; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IWineDXGIFactory *iface, + IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) +{ + struct wined3d_swapchain *wined3d_swapchain; + struct wined3d_swapchain_desc wined3d_desc; + struct wined3d_device *wined3d_device; + IWineDXGIDevice *dxgi_device; + UINT count; + HRESULT hr; + + FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); + + hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); + if (FAILED(hr)) + { + ERR("This is not the device we're looking for\n"); + return hr; + } + + wined3d_device = IWineDXGIDevice_get_wined3d_device(dxgi_device); + IWineDXGIDevice_Release(dxgi_device); + + count = wined3d_device_get_swapchain_count(wined3d_device); + if (count) + { + FIXME("Only a single swapchain supported.\n"); + wined3d_device_decref(wined3d_device); + return E_FAIL; + } + + if (!desc->OutputWindow) + { + FIXME("No output window, should use factory output window\n"); + } + + FIXME("Ignoring SwapEffect and Flags\n"); + + wined3d_desc.backbuffer_width = desc->BufferDesc.Width; + wined3d_desc.backbuffer_height = desc->BufferDesc.Height; + wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); + wined3d_desc.backbuffer_count = desc->BufferCount; + if (desc->SampleDesc.Count > 1) + { + wined3d_desc.multisample_type = desc->SampleDesc.Count; + wined3d_desc.multisample_quality = desc->SampleDesc.Quality; + } + else + { + wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; + wined3d_desc.multisample_quality = 0; + } + wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; + wined3d_desc.device_window = desc->OutputWindow; + wined3d_desc.windowed = desc->Windowed; + wined3d_desc.enable_auto_depth_stencil = FALSE; + wined3d_desc.auto_depth_stencil_format = 0; + wined3d_desc.flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ + wined3d_desc.refresh_rate = dxgi_rational_to_uint(&desc->BufferDesc.RefreshRate); + wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT; + + hr = wined3d_device_init_3d(wined3d_device, &wined3d_desc); + if (FAILED(hr)) + { + WARN("Failed to initialize 3D, returning %#x\n", hr); + wined3d_device_decref(wined3d_device); + return hr; + } + + wined3d_swapchain = wined3d_device_get_swapchain(wined3d_device, 0); + wined3d_device_decref(wined3d_device); + if (!wined3d_swapchain) + { + WARN("Failed to get swapchain.\n"); + return E_FAIL; + } + + *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); + + /* FIXME? The swapchain is created with refcount 1 by the wined3d device, + * but the wined3d device can't hold a real reference. */ + + TRACE("Created IDXGISwapChain %p\n", *swapchain); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSoftwareAdapter(IWineDXGIFactory *iface, + HMODULE swrast, IDXGIAdapter **adapter) +{ + FIXME("iface %p, swrast %p, adapter %p stub!\n", iface, swrast, adapter); + + return E_NOTIMPL; +} + +/* IWineDXGIFactory methods */ + +static struct wined3d * STDMETHODCALLTYPE dxgi_factory_get_wined3d(IWineDXGIFactory *iface) +{ + struct dxgi_factory *This = impl_from_IWineDXGIFactory(iface); + + TRACE("iface %p\n", iface); + + EnterCriticalSection(&dxgi_cs); + wined3d_incref(This->wined3d); + LeaveCriticalSection(&dxgi_cs); + return This->wined3d; +} + +static const struct IWineDXGIFactoryVtbl dxgi_factory_vtbl = +{ + /* IUnknown methods */ + dxgi_factory_QueryInterface, + dxgi_factory_AddRef, + dxgi_factory_Release, + /* IDXGIObject methods */ + dxgi_factory_SetPrivateData, + dxgi_factory_SetPrivateDataInterface, + dxgi_factory_GetPrivateData, + dxgi_factory_GetParent, + /* IDXGIFactory methods */ + dxgi_factory_EnumAdapters, + dxgi_factory_MakeWindowAssociation, + dxgi_factory_GetWindowAssociation, + dxgi_factory_CreateSwapChain, + dxgi_factory_CreateSoftwareAdapter, + /* IWineDXGIFactory methods */ + dxgi_factory_get_wined3d, +}; + +HRESULT dxgi_factory_init(struct dxgi_factory *factory) +{ + HRESULT hr; + UINT i; + + factory->IWineDXGIFactory_iface.lpVtbl = &dxgi_factory_vtbl; + factory->refcount = 1; + + EnterCriticalSection(&dxgi_cs); + factory->wined3d = wined3d_create(10, 0); + if (!factory->wined3d) + { + LeaveCriticalSection(&dxgi_cs); + return DXGI_ERROR_UNSUPPORTED; + } + + factory->adapter_count = wined3d_get_adapter_count(factory->wined3d); + LeaveCriticalSection(&dxgi_cs); + factory->adapters = HeapAlloc(GetProcessHeap(), 0, factory->adapter_count * sizeof(*factory->adapters)); + if (!factory->adapters) + { + ERR("Failed to allocate DXGI adapter array memory.\n"); + hr = E_OUTOFMEMORY; + goto fail; + } + + for (i = 0; i < factory->adapter_count; ++i) + { + struct dxgi_adapter *adapter = HeapAlloc(GetProcessHeap(), 0, sizeof(*adapter)); + if (!adapter) + { + UINT j; + + ERR("Failed to allocate DXGI adapter memory.\n"); + + for (j = 0; j < i; ++j) + { + IDXGIAdapter_Release(factory->adapters[j]); + } + hr = E_OUTOFMEMORY; + goto fail; + } + + hr = dxgi_adapter_init(adapter, &factory->IWineDXGIFactory_iface, i); + if (FAILED(hr)) + { + UINT j; + + ERR("Failed to initialize adapter, hr %#x.\n", hr); + + HeapFree(GetProcessHeap(), 0, adapter); + for (j = 0; j < i; ++j) + { + IDXGIAdapter_Release(factory->adapters[j]); + } + goto fail; + } + + factory->adapters[i] = (IDXGIAdapter *)adapter; + } + + return S_OK; + +fail: + HeapFree(GetProcessHeap(), 0, factory->adapters); + EnterCriticalSection(&dxgi_cs); + wined3d_decref(factory->wined3d); + LeaveCriticalSection(&dxgi_cs); + return hr; +} diff --git a/dll/directx/dxgi/output.c b/dll/directx/dxgi/output.c new file mode 100644 index 00000000000..4cdd06b2480 --- /dev/null +++ b/dll/directx/dxgi/output.c @@ -0,0 +1,292 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * 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 + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_output *impl_from_IDXGIOutput(IDXGIOutput *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_output, IDXGIOutput_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_QueryInterface(IDXGIOutput *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IDXGIOutput) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_output_AddRef(IDXGIOutput *iface) +{ + struct dxgi_output *This = impl_from_IDXGIOutput(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u.\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_output_Release(IDXGIOutput *iface) +{ + struct dxgi_output *This = impl_from_IDXGIOutput(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u.\n", This, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetPrivateData(IDXGIOutput *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetPrivateDataInterface(IDXGIOutput *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetPrivateData(IDXGIOutput *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetParent(IDXGIOutput *iface, + REFIID riid, void **parent) +{ + struct dxgi_output *This = impl_from_IDXGIOutput(iface); + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + return IDXGIAdapter_QueryInterface((IDXGIAdapter *)This->adapter, riid, parent); +} + +/* IDXGIOutput methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput *iface, DXGI_OUTPUT_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *iface, + DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *desc) +{ + struct dxgi_output *This = impl_from_IDXGIOutput(iface); + enum wined3d_format_id wined3d_format; + struct wined3d *wined3d; + UINT i; + UINT max_count; + + FIXME("iface %p, format %s, flags %#x, mode_count %p, desc %p partial stub!\n", + iface, debug_dxgi_format(format), flags, mode_count, desc); + + if (!mode_count) + { + return S_OK; + } + + if (format == DXGI_FORMAT_UNKNOWN) + { + *mode_count = 0; + return S_OK; + } + + wined3d = IWineDXGIFactory_get_wined3d(This->adapter->parent); + wined3d_format = wined3dformat_from_dxgi_format(format); + + EnterCriticalSection(&dxgi_cs); + max_count = wined3d_get_adapter_mode_count(wined3d, This->adapter->ordinal, + wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN); + + if (!desc) + { + wined3d_decref(wined3d); + LeaveCriticalSection(&dxgi_cs); + *mode_count = max_count; + return S_OK; + } + + *mode_count = min(*mode_count,max_count); + + for (i = 0; i < *mode_count; ++i) + { + struct wined3d_display_mode mode; + HRESULT hr; + + hr = wined3d_enum_adapter_modes(wined3d, This->adapter->ordinal, wined3d_format, + WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode); + if (FAILED(hr)) + { + WARN("EnumAdapterModes failed, hr %#x.\n", hr); + wined3d_decref(wined3d); + LeaveCriticalSection(&dxgi_cs); + return hr; + } + + desc[i].Width = mode.width; + desc[i].Height = mode.height; + desc[i].RefreshRate.Numerator = mode.refresh_rate; + desc[i].RefreshRate.Denominator = 1; + desc[i].Format = format; + desc[i].ScanlineOrdering = mode.scanline_ordering; + desc[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ + } + wined3d_decref(wined3d); + LeaveCriticalSection(&dxgi_cs); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput *iface, + const DXGI_MODE_DESC *mode, DXGI_MODE_DESC *closest_match, IUnknown *device) +{ + FIXME("iface %p, mode %p, closest_match %p, device %p stub!\n", iface, mode, closest_match, device); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_WaitForVBlank(IDXGIOutput *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput *iface, IUnknown *device, BOOL exclusive) +{ + FIXME("iface %p, device %p, exclusive %d stub!\n", iface, device, exclusive); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput *iface, + DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps) +{ + FIXME("iface %p, gamma_caps %p stub!\n", iface, gamma_caps); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetGammaControl(IDXGIOutput *iface, + const DXGI_GAMMA_CONTROL *gamma_control) +{ + FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControl(IDXGIOutput *iface, DXGI_GAMMA_CONTROL *gamma_control) +{ + FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetDisplaySurface(IDXGIOutput *iface, IDXGISurface *surface) +{ + FIXME("iface %p, surface %p stub!\n", iface, surface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplaySurfaceData(IDXGIOutput *iface, IDXGISurface *surface) +{ + FIXME("iface %p, surface %p stub!\n", iface, surface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetFrameStatistics(IDXGIOutput *iface, DXGI_FRAME_STATISTICS *stats) +{ + FIXME("iface %p, stats %p stub!\n", iface, stats); + + return E_NOTIMPL; +} + +static const struct IDXGIOutputVtbl dxgi_output_vtbl = +{ + dxgi_output_QueryInterface, + dxgi_output_AddRef, + dxgi_output_Release, + /* IDXGIObject methods */ + dxgi_output_SetPrivateData, + dxgi_output_SetPrivateDataInterface, + dxgi_output_GetPrivateData, + dxgi_output_GetParent, + /* IDXGIOutput methods */ + dxgi_output_GetDesc, + dxgi_output_GetDisplayModeList, + dxgi_output_FindClosestMatchingMode, + dxgi_output_WaitForVBlank, + dxgi_output_TakeOwnership, + dxgi_output_ReleaseOwnership, + dxgi_output_GetGammaControlCapabilities, + dxgi_output_SetGammaControl, + dxgi_output_GetGammaControl, + dxgi_output_SetDisplaySurface, + dxgi_output_GetDisplaySurfaceData, + dxgi_output_GetFrameStatistics, +}; + +void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter) +{ + output->IDXGIOutput_iface.lpVtbl = &dxgi_output_vtbl; + output->refcount = 1; + output->adapter = adapter; +} diff --git a/dll/directx/dxgi/surface.c b/dll/directx/dxgi/surface.c new file mode 100644 index 00000000000..f7fa93176ce --- /dev/null +++ b/dll/directx/dxgi/surface.c @@ -0,0 +1,216 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +/* Inner IUnknown methods */ + +static inline struct dxgi_surface *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_surface, IUnknown_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_inner_QueryInterface(IUnknown *iface, REFIID riid, void **out) +{ + struct dxgi_surface *surface = impl_from_IUnknown(iface); + + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IDXGISurface) + || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IDXGISurface_AddRef(&surface->IDXGISurface_iface); + *out = &surface->IDXGISurface_iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_inner_AddRef(IUnknown *iface) +{ + struct dxgi_surface *surface = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&surface->refcount); + + TRACE("%p increasing refcount to %u.\n", surface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_inner_Release(IUnknown *iface) +{ + struct dxgi_surface *surface = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&surface->refcount); + + TRACE("%p decreasing refcount to %u.\n", surface, refcount); + + if (!refcount) + { + IDXGIDevice_Release(surface->device); + HeapFree(GetProcessHeap(), 0, surface); + } + + return refcount; +} + +static inline struct dxgi_surface *impl_from_IDXGISurface(IDXGISurface *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_surface, IDXGISurface_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_QueryInterface(IDXGISurface *iface, REFIID riid, + void **object) +{ + struct dxgi_surface *This = impl_from_IDXGISurface(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_QueryInterface(This->outer_unknown, riid, object); +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_AddRef(IDXGISurface *iface) +{ + struct dxgi_surface *This = impl_from_IDXGISurface(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_AddRef(This->outer_unknown); +} + +static ULONG STDMETHODCALLTYPE dxgi_surface_Release(IDXGISurface *iface) +{ + struct dxgi_surface *This = impl_from_IDXGISurface(iface); + TRACE("Forwarding to outer IUnknown\n"); + return IUnknown_Release(This->outer_unknown); +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateData(IDXGISurface *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_SetPrivateDataInterface(IDXGISurface *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetPrivateData(IDXGISurface *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetParent(IDXGISurface *iface, REFIID riid, void **parent) +{ + struct dxgi_surface *This = impl_from_IDXGISurface(iface); + + TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent); + + return IDXGIDevice_QueryInterface(This->device, riid, parent); +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDevice(IDXGISurface *iface, REFIID riid, void **device) +{ + struct dxgi_surface *This = impl_from_IDXGISurface(iface); + + TRACE("iface %p, riid %s, device %p.\n", iface, debugstr_guid(riid), device); + + return IDXGIDevice_QueryInterface(This->device, riid, device); +} + +/* IDXGISurface methods */ +static HRESULT STDMETHODCALLTYPE dxgi_surface_GetDesc(IDXGISurface *iface, DXGI_SURFACE_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_Map(IDXGISurface *iface, DXGI_MAPPED_RECT *mapped_rect, UINT flags) +{ + FIXME("iface %p, mapped_rect %p, flags %#x stub!\n", iface, mapped_rect, flags); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_surface_Unmap(IDXGISurface *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static const struct IDXGISurfaceVtbl dxgi_surface_vtbl = +{ + /* IUnknown methods */ + dxgi_surface_QueryInterface, + dxgi_surface_AddRef, + dxgi_surface_Release, + /* IDXGIObject methods */ + dxgi_surface_SetPrivateData, + dxgi_surface_SetPrivateDataInterface, + dxgi_surface_GetPrivateData, + dxgi_surface_GetParent, + /* IDXGIDeviceSubObject methods */ + dxgi_surface_GetDevice, + /* IDXGISurface methods */ + dxgi_surface_GetDesc, + dxgi_surface_Map, + dxgi_surface_Unmap, +}; + +static const struct IUnknownVtbl dxgi_surface_inner_unknown_vtbl = +{ + /* IUnknown methods */ + dxgi_surface_inner_QueryInterface, + dxgi_surface_inner_AddRef, + dxgi_surface_inner_Release, +}; + +HRESULT dxgi_surface_init(struct dxgi_surface *surface, IDXGIDevice *device, IUnknown *outer) +{ + surface->IDXGISurface_iface.lpVtbl = &dxgi_surface_vtbl; + surface->IUnknown_iface.lpVtbl = &dxgi_surface_inner_unknown_vtbl; + surface->refcount = 1; + surface->outer_unknown = outer ? outer : &surface->IUnknown_iface; + surface->device = device; + IDXGIDevice_AddRef(device); + + return S_OK; +} diff --git a/dll/directx/dxgi/swapchain.c b/dll/directx/dxgi/swapchain.c new file mode 100644 index 00000000000..0c27007eda7 --- /dev/null +++ b/dll/directx/dxgi/swapchain.c @@ -0,0 +1,315 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +static inline struct dxgi_swapchain *impl_from_IDXGISwapChain(IDXGISwapChain *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_swapchain, IDXGISwapChain_iface); +} + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_QueryInterface(IDXGISwapChain *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IDXGIDeviceSubObject) + || IsEqualGUID(riid, &IID_IDXGISwapChain)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface) +{ + struct dxgi_swapchain *This = impl_from_IDXGISwapChain(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + if (refcount == 1) + wined3d_swapchain_incref(This->wined3d_swapchain); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface) +{ + struct dxgi_swapchain *This = impl_from_IDXGISwapChain(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + struct wined3d_device *wined3d_device; + HRESULT hr; + + FIXME("Only a single swapchain is supported\n"); + + wined3d_device = wined3d_swapchain_get_device(This->wined3d_swapchain); + hr = wined3d_device_uninit_3d(wined3d_device); + if (FAILED(hr)) + { + ERR("Uninit3D failed, hr %#x\n", hr); + } + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_SetPrivateData(IDXGISwapChain *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_SetPrivateDataInterface(IDXGISwapChain *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetPrivateData(IDXGISwapChain *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetParent(IDXGISwapChain *iface, REFIID riid, void **parent) +{ + FIXME("iface %p, riid %s, parent %p stub!\n", iface, debugstr_guid(riid), parent); + + return E_NOTIMPL; +} + +/* IDXGIDeviceSubObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDevice(IDXGISwapChain *iface, REFIID riid, void **device) +{ + FIXME("iface %p, riid %s, device %p stub!\n", iface, debugstr_guid(riid), device); + + return E_NOTIMPL; +} + +/* IDXGISwapChain methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_Present(IDXGISwapChain *iface, UINT sync_interval, UINT flags) +{ + struct dxgi_swapchain *This = impl_from_IDXGISwapChain(iface); + + TRACE("iface %p, sync_interval %u, flags %#x\n", iface, sync_interval, flags); + + if (sync_interval) FIXME("Unimplemented sync interval %u\n", sync_interval); + if (flags) FIXME("Unimplemented flags %#x\n", flags); + + return wined3d_swapchain_present(This->wined3d_swapchain, NULL, NULL, NULL, NULL, 0); +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetBuffer(IDXGISwapChain *iface, + UINT buffer_idx, REFIID riid, void **surface) +{ + struct dxgi_swapchain *This = impl_from_IDXGISwapChain(iface); + struct wined3d_surface *backbuffer; + IUnknown *parent; + HRESULT hr; + + TRACE("iface %p, buffer_idx %u, riid %s, surface %p\n", + iface, buffer_idx, debugstr_guid(riid), surface); + + EnterCriticalSection(&dxgi_cs); + + if (!(backbuffer = wined3d_swapchain_get_back_buffer(This->wined3d_swapchain, + buffer_idx, WINED3D_BACKBUFFER_TYPE_MONO))) + { + LeaveCriticalSection(&dxgi_cs); + return DXGI_ERROR_INVALID_CALL; + } + + parent = wined3d_surface_get_parent(backbuffer); + hr = IUnknown_QueryInterface(parent, riid, surface); + LeaveCriticalSection(&dxgi_cs); + + return hr; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_SetFullscreenState(IDXGISwapChain *iface, + BOOL fullscreen, IDXGIOutput *target) +{ + FIXME("iface %p, fullscreen %u, target %p stub!\n", iface, fullscreen, target); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetFullscreenState(IDXGISwapChain *iface, + BOOL *fullscreen, IDXGIOutput **target) +{ + FIXME("iface %p, fullscreen %p, target %p stub!\n", iface, fullscreen, target); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetDesc(IDXGISwapChain *iface, DXGI_SWAP_CHAIN_DESC *desc) +{ + struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface); + struct wined3d_swapchain_desc wined3d_desc; + + FIXME("iface %p, desc %p partial stub!\n", iface, desc); + + if (desc == NULL) + return E_INVALIDARG; + + EnterCriticalSection(&dxgi_cs); + wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); + LeaveCriticalSection(&dxgi_cs); + + FIXME("Ignoring ScanlineOrdering, Scaling, SwapEffect and Flags\n"); + + desc->BufferDesc.Width = wined3d_desc.backbuffer_width; + desc->BufferDesc.Height = wined3d_desc.backbuffer_height; + desc->BufferDesc.RefreshRate.Numerator = wined3d_desc.refresh_rate; + desc->BufferDesc.RefreshRate.Denominator = 1; + desc->BufferDesc.Format = dxgi_format_from_wined3dformat(wined3d_desc.backbuffer_format); + desc->BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + desc->BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + desc->SampleDesc.Count = wined3d_desc.multisample_type; + desc->SampleDesc.Quality = wined3d_desc.multisample_quality; + desc->BufferCount = wined3d_desc.backbuffer_count; + desc->OutputWindow = wined3d_desc.device_window; + desc->Windowed = wined3d_desc.windowed; + desc->SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + desc->Flags = 0; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_ResizeBuffers(IDXGISwapChain *iface, + UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags) +{ + FIXME("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x stub!\n", + iface, buffer_count, width, height, debug_dxgi_format(format), flags); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_ResizeTarget(IDXGISwapChain *iface, + const DXGI_MODE_DESC *target_mode_desc) +{ + FIXME("iface %p, target_mode_desc %p stub!\n", iface, target_mode_desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetContainingOutput(IDXGISwapChain *iface, IDXGIOutput **output) +{ + FIXME("iface %p, output %p stub!\n", iface, output); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetFrameStatistics(IDXGISwapChain *iface, DXGI_FRAME_STATISTICS *stats) +{ + FIXME("iface %p, stats %p stub!\n", iface, stats); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_swapchain_GetLastPresentCount(IDXGISwapChain *iface, UINT *last_present_count) +{ + FIXME("iface %p, last_present_count %p stub!\n", iface, last_present_count); + + return E_NOTIMPL; +} + +static const struct IDXGISwapChainVtbl dxgi_swapchain_vtbl = +{ + /* IUnknown methods */ + dxgi_swapchain_QueryInterface, + dxgi_swapchain_AddRef, + dxgi_swapchain_Release, + /* IDXGIObject methods */ + dxgi_swapchain_SetPrivateData, + dxgi_swapchain_SetPrivateDataInterface, + dxgi_swapchain_GetPrivateData, + dxgi_swapchain_GetParent, + /* IDXGIDeviceSubObject methods */ + dxgi_swapchain_GetDevice, + /* IDXGISwapChain methods */ + dxgi_swapchain_Present, + dxgi_swapchain_GetBuffer, + dxgi_swapchain_SetFullscreenState, + dxgi_swapchain_GetFullscreenState, + dxgi_swapchain_GetDesc, + dxgi_swapchain_ResizeBuffers, + dxgi_swapchain_ResizeTarget, + dxgi_swapchain_GetContainingOutput, + dxgi_swapchain_GetFrameStatistics, + dxgi_swapchain_GetLastPresentCount, +}; + +static void STDMETHODCALLTYPE dxgi_swapchain_wined3d_object_released(void *parent) +{ + HeapFree(GetProcessHeap(), 0, parent); +} + +static const struct wined3d_parent_ops dxgi_swapchain_wined3d_parent_ops = +{ + dxgi_swapchain_wined3d_object_released, +}; + +HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device, + struct wined3d_swapchain_desc *desc) +{ + HRESULT hr; + + swapchain->IDXGISwapChain_iface.lpVtbl = &dxgi_swapchain_vtbl; + swapchain->refcount = 1; + + if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain, + &dxgi_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain))) + { + WARN("Failed to create wined3d swapchain, hr %#x.\n", hr); + return hr; + } + + return S_OK; +} diff --git a/dll/directx/dxgi/utils.c b/dll/directx/dxgi/utils.c new file mode 100644 index 00000000000..979c9721e66 --- /dev/null +++ b/dll/directx/dxgi/utils.c @@ -0,0 +1,326 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +#define WINE_DXGI_TO_STR(x) case x: return #x + +const char *debug_dxgi_format(DXGI_FORMAT format) +{ + switch(format) + { + WINE_DXGI_TO_STR(DXGI_FORMAT_UNKNOWN); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32A32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32B32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16B16A16_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32G8X24_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10A2_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10A2_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R10G10B10A2_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R11G11B10_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8B8A8_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16G16_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_D32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R32_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R24G8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_D24_UNORM_S8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_X24_TYPELESS_G8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_FLOAT); + WINE_DXGI_TO_STR(DXGI_FORMAT_D16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R16_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_UINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8_SINT); + WINE_DXGI_TO_STR(DXGI_FORMAT_A8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R1_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); + WINE_DXGI_TO_STR(DXGI_FORMAT_R8G8_B8G8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_G8R8_G8B8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC1_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC1_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC1_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC2_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC2_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC2_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC3_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC3_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC3_UNORM_SRGB); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC4_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC4_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC4_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC5_TYPELESS); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC5_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_BC5_SNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B5G6R5_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B5G5R5A1_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8A8_UNORM); + WINE_DXGI_TO_STR(DXGI_FORMAT_B8G8R8X8_UNORM); + default: + FIXME("Unrecognized DXGI_FORMAT %#x\n", format); + return "unrecognized"; + } +} + +#undef WINE_DXGI_TO_STR + +DXGI_FORMAT dxgi_format_from_wined3dformat(enum wined3d_format_id format) +{ + switch(format) + { + case WINED3DFMT_UNKNOWN: return DXGI_FORMAT_UNKNOWN; + case WINED3DFMT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS; + case WINED3DFMT_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case WINED3DFMT_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT; + case WINED3DFMT_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_SINT; + case WINED3DFMT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_TYPELESS; + case WINED3DFMT_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT; + case WINED3DFMT_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_UINT; + case WINED3DFMT_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_SINT; + case WINED3DFMT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_TYPELESS; + case WINED3DFMT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case WINED3DFMT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case WINED3DFMT_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_UINT; + case WINED3DFMT_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM; + case WINED3DFMT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SINT; + case WINED3DFMT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_TYPELESS; + case WINED3DFMT_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT; + case WINED3DFMT_R32G32_UINT: return DXGI_FORMAT_R32G32_UINT; + case WINED3DFMT_R32G32_SINT: return DXGI_FORMAT_R32G32_SINT; + case WINED3DFMT_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS; + case WINED3DFMT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case WINED3DFMT_R32_FLOAT_X8X24_TYPELESS: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + case WINED3DFMT_X32_TYPELESS_G8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case WINED3DFMT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_TYPELESS; + case WINED3DFMT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM; + case WINED3DFMT_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UINT; + case WINED3DFMT_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT; + case WINED3DFMT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS; + case WINED3DFMT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + case WINED3DFMT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + case WINED3DFMT_R8G8B8A8_UINT: return DXGI_FORMAT_R8G8B8A8_UINT; + case WINED3DFMT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM; + case WINED3DFMT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SINT; + case WINED3DFMT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_TYPELESS; + case WINED3DFMT_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT; + case WINED3DFMT_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM; + case WINED3DFMT_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT; + case WINED3DFMT_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM; + case WINED3DFMT_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT; + case WINED3DFMT_R32_TYPELESS: return DXGI_FORMAT_R32_TYPELESS; + case WINED3DFMT_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT; + case WINED3DFMT_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT; + case WINED3DFMT_R32_UINT: return DXGI_FORMAT_R32_UINT; + case WINED3DFMT_R32_SINT: return DXGI_FORMAT_R32_SINT; + case WINED3DFMT_R24G8_TYPELESS: return DXGI_FORMAT_R24G8_TYPELESS; + case WINED3DFMT_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case WINED3DFMT_R24_UNORM_X8_TYPELESS: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case WINED3DFMT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + case WINED3DFMT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_TYPELESS; + case WINED3DFMT_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM; + case WINED3DFMT_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT; + case WINED3DFMT_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM; + case WINED3DFMT_R8G8_SINT: return DXGI_FORMAT_R8G8_SINT; + case WINED3DFMT_R16_TYPELESS: return DXGI_FORMAT_R16_TYPELESS; + case WINED3DFMT_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case WINED3DFMT_D16_UNORM: return DXGI_FORMAT_D16_UNORM; + case WINED3DFMT_R16_UNORM: return DXGI_FORMAT_R16_UNORM; + case WINED3DFMT_R16_UINT: return DXGI_FORMAT_R16_UINT; + case WINED3DFMT_R16_SNORM: return DXGI_FORMAT_R16_SNORM; + case WINED3DFMT_R16_SINT: return DXGI_FORMAT_R16_SINT; + case WINED3DFMT_R8_TYPELESS: return DXGI_FORMAT_R8_TYPELESS; + case WINED3DFMT_R8_UNORM: return DXGI_FORMAT_R8_UNORM; + case WINED3DFMT_R8_UINT: return DXGI_FORMAT_R8_UINT; + case WINED3DFMT_R8_SNORM: return DXGI_FORMAT_R8_SNORM; + case WINED3DFMT_R8_SINT: return DXGI_FORMAT_R8_SINT; + case WINED3DFMT_A8_UNORM: return DXGI_FORMAT_A8_UNORM; + case WINED3DFMT_R1_UNORM: return DXGI_FORMAT_R1_UNORM; + case WINED3DFMT_R9G9B9E5_SHAREDEXP: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + case WINED3DFMT_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM; + case WINED3DFMT_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM; + case WINED3DFMT_BC1_TYPELESS: return DXGI_FORMAT_BC1_TYPELESS; + case WINED3DFMT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM; + case WINED3DFMT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB; + case WINED3DFMT_BC2_TYPELESS: return DXGI_FORMAT_BC2_TYPELESS; + case WINED3DFMT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM; + case WINED3DFMT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB; + case WINED3DFMT_BC3_TYPELESS: return DXGI_FORMAT_BC3_TYPELESS; + case WINED3DFMT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM; + case WINED3DFMT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB; + case WINED3DFMT_BC4_TYPELESS: return DXGI_FORMAT_BC4_TYPELESS; + case WINED3DFMT_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM; + case WINED3DFMT_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM; + case WINED3DFMT_BC5_TYPELESS: return DXGI_FORMAT_BC5_TYPELESS; + case WINED3DFMT_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM; + case WINED3DFMT_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM; + case WINED3DFMT_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM; + case WINED3DFMT_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM; + case WINED3DFMT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM; + case WINED3DFMT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM; + default: + FIXME("Unhandled wined3d format %#x.\n", format); + return DXGI_FORMAT_UNKNOWN; + } +} + +enum wined3d_format_id wined3dformat_from_dxgi_format(DXGI_FORMAT format) +{ + switch(format) + { + case DXGI_FORMAT_UNKNOWN: return WINED3DFMT_UNKNOWN; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: return WINED3DFMT_R32G32B32A32_TYPELESS; + case DXGI_FORMAT_R32G32B32A32_FLOAT: return WINED3DFMT_R32G32B32A32_FLOAT; + case DXGI_FORMAT_R32G32B32A32_UINT: return WINED3DFMT_R32G32B32A32_UINT; + case DXGI_FORMAT_R32G32B32A32_SINT: return WINED3DFMT_R32G32B32A32_SINT; + case DXGI_FORMAT_R32G32B32_TYPELESS: return WINED3DFMT_R32G32B32_TYPELESS; + case DXGI_FORMAT_R32G32B32_FLOAT: return WINED3DFMT_R32G32B32_FLOAT; + case DXGI_FORMAT_R32G32B32_UINT: return WINED3DFMT_R32G32B32_UINT; + case DXGI_FORMAT_R32G32B32_SINT: return WINED3DFMT_R32G32B32_SINT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: return WINED3DFMT_R16G16B16A16_TYPELESS; + case DXGI_FORMAT_R16G16B16A16_FLOAT: return WINED3DFMT_R16G16B16A16_FLOAT; + case DXGI_FORMAT_R16G16B16A16_UNORM: return WINED3DFMT_R16G16B16A16_UNORM; + case DXGI_FORMAT_R16G16B16A16_UINT: return WINED3DFMT_R16G16B16A16_UINT; + case DXGI_FORMAT_R16G16B16A16_SNORM: return WINED3DFMT_R16G16B16A16_SNORM; + case DXGI_FORMAT_R16G16B16A16_SINT: return WINED3DFMT_R16G16B16A16_SINT; + case DXGI_FORMAT_R32G32_TYPELESS: return WINED3DFMT_R32G32_TYPELESS; + case DXGI_FORMAT_R32G32_FLOAT: return WINED3DFMT_R32G32_FLOAT; + case DXGI_FORMAT_R32G32_UINT: return WINED3DFMT_R32G32_UINT; + case DXGI_FORMAT_R32G32_SINT: return WINED3DFMT_R32G32_SINT; + case DXGI_FORMAT_R32G8X24_TYPELESS: return WINED3DFMT_R32G8X24_TYPELESS; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return WINED3DFMT_D32_FLOAT_S8X24_UINT; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return WINED3DFMT_R32_FLOAT_X8X24_TYPELESS; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return WINED3DFMT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: return WINED3DFMT_R10G10B10A2_TYPELESS; + case DXGI_FORMAT_R10G10B10A2_UNORM: return WINED3DFMT_R10G10B10A2_UNORM; + case DXGI_FORMAT_R10G10B10A2_UINT: return WINED3DFMT_R10G10B10A2_UINT; + case DXGI_FORMAT_R11G11B10_FLOAT: return WINED3DFMT_R11G11B10_FLOAT; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: return WINED3DFMT_R8G8B8A8_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_UNORM: return WINED3DFMT_R8G8B8A8_UNORM; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return WINED3DFMT_R8G8B8A8_UNORM_SRGB; + case DXGI_FORMAT_R8G8B8A8_UINT: return WINED3DFMT_R8G8B8A8_UINT; + case DXGI_FORMAT_R8G8B8A8_SNORM: return WINED3DFMT_R8G8B8A8_SNORM; + case DXGI_FORMAT_R8G8B8A8_SINT: return WINED3DFMT_R8G8B8A8_SINT; + case DXGI_FORMAT_R16G16_TYPELESS: return WINED3DFMT_R16G16_TYPELESS; + case DXGI_FORMAT_R16G16_FLOAT: return WINED3DFMT_R16G16_FLOAT; + case DXGI_FORMAT_R16G16_UNORM: return WINED3DFMT_R16G16_UNORM; + case DXGI_FORMAT_R16G16_UINT: return WINED3DFMT_R16G16_UINT; + case DXGI_FORMAT_R16G16_SNORM: return WINED3DFMT_R16G16_SNORM; + case DXGI_FORMAT_R16G16_SINT: return WINED3DFMT_R16G16_SINT; + case DXGI_FORMAT_R32_TYPELESS: return WINED3DFMT_R32_TYPELESS; + case DXGI_FORMAT_D32_FLOAT: return WINED3DFMT_D32_FLOAT; + case DXGI_FORMAT_R32_FLOAT: return WINED3DFMT_R32_FLOAT; + case DXGI_FORMAT_R32_UINT: return WINED3DFMT_R32_UINT; + case DXGI_FORMAT_R32_SINT: return WINED3DFMT_R32_SINT; + case DXGI_FORMAT_R24G8_TYPELESS: return WINED3DFMT_R24G8_TYPELESS; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return WINED3DFMT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return WINED3DFMT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return WINED3DFMT_X24_TYPELESS_G8_UINT; + case DXGI_FORMAT_R8G8_TYPELESS: return WINED3DFMT_R8G8_TYPELESS; + case DXGI_FORMAT_R8G8_UNORM: return WINED3DFMT_R8G8_UNORM; + case DXGI_FORMAT_R8G8_UINT: return WINED3DFMT_R8G8_UINT; + case DXGI_FORMAT_R8G8_SNORM: return WINED3DFMT_R8G8_SNORM; + case DXGI_FORMAT_R8G8_SINT: return WINED3DFMT_R8G8_SINT; + case DXGI_FORMAT_R16_TYPELESS: return WINED3DFMT_R16_TYPELESS; + case DXGI_FORMAT_R16_FLOAT: return WINED3DFMT_R16_FLOAT; + case DXGI_FORMAT_D16_UNORM: return WINED3DFMT_D16_UNORM; + case DXGI_FORMAT_R16_UNORM: return WINED3DFMT_R16_UNORM; + case DXGI_FORMAT_R16_UINT: return WINED3DFMT_R16_UINT; + case DXGI_FORMAT_R16_SNORM: return WINED3DFMT_R16_SNORM; + case DXGI_FORMAT_R16_SINT: return WINED3DFMT_R16_SINT; + case DXGI_FORMAT_R8_TYPELESS: return WINED3DFMT_R8_TYPELESS; + case DXGI_FORMAT_R8_UNORM: return WINED3DFMT_R8_UNORM; + case DXGI_FORMAT_R8_UINT: return WINED3DFMT_R8_UINT; + case DXGI_FORMAT_R8_SNORM: return WINED3DFMT_R8_SNORM; + case DXGI_FORMAT_R8_SINT: return WINED3DFMT_R8_SINT; + case DXGI_FORMAT_A8_UNORM: return WINED3DFMT_A8_UNORM; + case DXGI_FORMAT_R1_UNORM: return WINED3DFMT_R1_UNORM; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return WINED3DFMT_R9G9B9E5_SHAREDEXP; + case DXGI_FORMAT_R8G8_B8G8_UNORM: return WINED3DFMT_R8G8_B8G8_UNORM; + case DXGI_FORMAT_G8R8_G8B8_UNORM: return WINED3DFMT_G8R8_G8B8_UNORM; + case DXGI_FORMAT_BC1_TYPELESS: return WINED3DFMT_BC1_TYPELESS; + case DXGI_FORMAT_BC1_UNORM: return WINED3DFMT_BC1_UNORM; + case DXGI_FORMAT_BC1_UNORM_SRGB: return WINED3DFMT_BC1_UNORM_SRGB; + case DXGI_FORMAT_BC2_TYPELESS: return WINED3DFMT_BC2_TYPELESS; + case DXGI_FORMAT_BC2_UNORM: return WINED3DFMT_BC2_UNORM; + case DXGI_FORMAT_BC2_UNORM_SRGB: return WINED3DFMT_BC2_UNORM_SRGB; + case DXGI_FORMAT_BC3_TYPELESS: return WINED3DFMT_BC3_TYPELESS; + case DXGI_FORMAT_BC3_UNORM: return WINED3DFMT_BC3_UNORM; + case DXGI_FORMAT_BC3_UNORM_SRGB: return WINED3DFMT_BC3_UNORM_SRGB; + case DXGI_FORMAT_BC4_TYPELESS: return WINED3DFMT_BC4_TYPELESS; + case DXGI_FORMAT_BC4_UNORM: return WINED3DFMT_BC4_UNORM; + case DXGI_FORMAT_BC4_SNORM: return WINED3DFMT_BC4_SNORM; + case DXGI_FORMAT_BC5_TYPELESS: return WINED3DFMT_BC5_TYPELESS; + case DXGI_FORMAT_BC5_UNORM: return WINED3DFMT_BC5_UNORM; + case DXGI_FORMAT_BC5_SNORM: return WINED3DFMT_BC5_SNORM; + case DXGI_FORMAT_B5G6R5_UNORM: return WINED3DFMT_B5G6R5_UNORM; + case DXGI_FORMAT_B5G5R5A1_UNORM: return WINED3DFMT_B5G5R5A1_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM: return WINED3DFMT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_UNORM: return WINED3DFMT_B8G8R8X8_UNORM; + default: + FIXME("Unhandled DXGI_FORMAT %#x\n", format); + return WINED3DFMT_UNKNOWN; + } +} diff --git a/dll/directx/dxgi/version.rc b/dll/directx/dxgi/version.rc new file mode 100644 index 00000000000..bd51eb8c55b --- /dev/null +++ b/dll/directx/dxgi/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + */ + +#define WINE_FILEDESCRIPTION_STR "Wine DXGI" +#define WINE_FILENAME_STR "dxgi.dll" +#define WINE_FILEVERSION 6,0,6000,16386 +#define WINE_FILEVERSION_STR "6.0.6000.16386" +#define WINE_PRODUCTVERSION 6,0,6000,16386 +#define WINE_PRODUCTVERSION_STR "6.0.6000.16386" + +#include "wine/wine_common_ver.rc" diff --git a/dll/directx/ksproxy/CMakeLists.txt b/dll/directx/ksproxy/CMakeLists.txt index b8fdd3d1563..e3ca96fcf58 100644 --- a/dll/directx/ksproxy/CMakeLists.txt +++ b/dll/directx/ksproxy/CMakeLists.txt @@ -1,5 +1,5 @@ -set_cpp() +set_cpp(WITH_STL) spec2def(ksproxy.ax ksproxy.spec) @@ -27,14 +27,6 @@ add_library(ksproxy SHARED ${SOURCE} ksproxy.rc) set_module_type(ksproxy win32dll) set_target_properties(ksproxy PROPERTIES SUFFIX ".ax") -if(MSVC) - add_target_compile_flags(ksproxy "/GR-") -else() - # FIXME: http://www.cmake.org/Bug/view.php?id=12998 - #add_target_compile_flags(ksproxy "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") -endif() - target_link_libraries(ksproxy strmiids) add_importlibs(ksproxy advapi32 ole32 setupapi ksuser msvcrt kernel32 ntdll) add_dependencies(ksproxy dxsdk) diff --git a/dll/directx/quartz/CMakeLists.txt b/dll/directx/quartz/CMakeLists.txt index f0f6a57e050..11092724cfe 100644 --- a/dll/directx/quartz/CMakeLists.txt +++ b/dll/directx/quartz/CMakeLists.txt @@ -5,49 +5,57 @@ add_definitions(-D_WIN32_WINNT=0x600) add_definitions( -D__WINESRC__ -DENTRY_PREFIX=QUARTZ_ - -DREGISTER_PROXY_DLL + -DWINE_REGISTER_DLL -DPROXY_DELEGATION) include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) - spec2def(quartz.dll quartz.spec) - add_rpcproxy_files(quartz_strmif.idl) list(APPEND SOURCE - avidec.c acmwrapper.c - waveparser.c - videorenderer.c - transform.c - systemclock.c - regsvr.c - pin.c - parser.c - nullrenderer.c - mpegsplit.c - memallocator.c - main.c - filtermapper.c - filtergraph.c - filesource.c - enumregfilters.c - enumpins.c - enummoniker.c - enumfilters.c - dsoundrender.c - enummedia.c - control.c + avidec.c avisplit.c + dsoundrender.c + enumfilters.c + enummedia.c + enummoniker.c + enumregfilters.c + filesource.c + filtergraph.c + filtermapper.c + main.c + memallocator.c + mpegsplit.c + nullrenderer.c + parser.c + pin.c + regsvr.c + systemclock.c + videorenderer.c + vmr9.c + waveparser.c ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c ${CMAKE_CURRENT_BINARY_DIR}/quartz_strmif_p.c ${CMAKE_CURRENT_BINARY_DIR}/quartz.def) add_library(quartz SHARED ${SOURCE} version.rc) + +add_idl_headers(quartz_idlheader fil_data.idl) + +add_typelib(control_tlb.idl) + +list(APPEND quartz_rc_deps + ${CMAKE_CURRENT_BINARY_DIR}/control_tlb.tlb + ${CMAKE_CURRENT_SOURCE_DIR}/control_tlb.rgs + ${CMAKE_CURRENT_SOURCE_DIR}/quartz_strmif.rgs) + +set_source_files_properties(version.rc PROPERTIES OBJECT_DEPENDS "${quartz_rc_deps}") + set_module_type(quartz win32dll) -target_link_libraries(quartz strmiids uuid wine ${PSEH_LIB}) -add_importlibs(quartz dsound ole32 oleaut32 shlwapi user32 gdi32 advapi32 msvfw32 msacm32 rpcrt4 msvcrt kernel32 ntdll) -add_dependencies(quartz dxsdk) +target_link_libraries(quartz strmbase strmiids uuid dxguid wine ${PSEH_LIB}) +add_importlibs(quartz dsound msacm32 msvfw32 ole32 oleaut32 shlwapi rpcrt4 user32 gdi32 advapi32 msvcrt kernel32 ntdll) +add_dependencies(quartz dxsdk quartz_idlheader stdole2) add_pch(quartz quartz_private.h) add_cd_file(TARGET quartz DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/quartz/acmwrapper.c b/dll/directx/quartz/acmwrapper.c index e40cfeca0fe..8c036d2f0e0 100644 --- a/dll/directx/quartz/acmwrapper.c +++ b/dll/directx/quartz/acmwrapper.c @@ -37,13 +37,12 @@ //#include "wine/unicode.h" #include -#include "transform.h" - WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct ACMWrapperImpl { - TransformFilterImpl tf; + TransformFilter tf; + HACMSTREAM has; LPWAVEFORMATEX pWfIn; LPWAVEFORMATEX pWfOut; @@ -52,9 +51,21 @@ typedef struct ACMWrapperImpl LONGLONG lasttime_sent; } ACMWrapperImpl; -static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample) +static const IBaseFilterVtbl ACMWrapper_Vtbl; + +static inline ACMWrapperImpl *impl_from_TransformFilter( TransformFilter *iface ) { - ACMWrapperImpl* This = (ACMWrapperImpl*)pin->pin.pinInfo.pFilter; + return CONTAINING_RECORD(iface, ACMWrapperImpl, tf.filter); +} + +static inline ACMWrapperImpl *impl_from_IBaseFilter( IBaseFilter *iface ) +{ + return CONTAINING_RECORD(iface, ACMWrapperImpl, tf.filter.IBaseFilter_iface); +} + +static HRESULT WINAPI ACMWrapper_Receive(TransformFilter *tf, IMediaSample *pSample) +{ + ACMWrapperImpl* This = impl_from_TransformFilter(tf); AM_MEDIA_TYPE amt; IMediaSample* pOutSample = NULL; DWORD cbDstStream, cbSrcStream; @@ -65,31 +76,22 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample MMRESULT res; HRESULT hr; LONGLONG tStart = -1, tStop = -1, tMed; + LONGLONG mtStart = -1, mtStop = -1, mtMed; - EnterCriticalSection(&This->tf.csFilter); - if (This->tf.state == State_Stopped) - { - LeaveCriticalSection(&This->tf.csFilter); - return VFW_E_WRONG_STATE; - } - - if (pin->end_of_stream || pin->flushing) - { - LeaveCriticalSection(&This->tf.csFilter); - return S_FALSE; - } - + EnterCriticalSection(&This->tf.csReceive); hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); - LeaveCriticalSection(&This->tf.csFilter); + LeaveCriticalSection(&This->tf.csReceive); return hr; } preroll = (IMediaSample_IsPreroll(pSample) == S_OK); IMediaSample_GetTime(pSample, &tStart, &tStop); + if (IMediaSample_GetMediaTime(pSample, &mtStart, &mtStop) != S_OK) + mtStart = mtStop = -1; cbSrcStream = IMediaSample_GetActualDataLength(pSample); /* Prevent discontinuities when codecs 'absorb' data but not give anything back in return */ @@ -104,6 +106,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample WARN("Discontinuity\n"); tMed = tStart; + mtMed = mtStart; TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); @@ -111,7 +114,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample if (FAILED(hr)) { ERR("Unable to retrieve media type\n"); - LeaveCriticalSection(&This->tf.csFilter); + LeaveCriticalSection(&This->tf.csReceive); return hr; } @@ -120,11 +123,11 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample while(hr == S_OK && ash.cbSrcLength) { - hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); + hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Unable to get delivery buffer (%x)\n", hr); - LeaveCriticalSection(&This->tf.csFilter); + LeaveCriticalSection(&This->tf.csReceive); return hr; } IMediaSample_SetPreroll(pOutSample, preroll); @@ -176,7 +179,7 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed); assert(hr == S_OK); - /* Bug in acm codecs? It apparantly uses the input, but doesn't necessarily output immediately kl*/ + /* Bug in acm codecs? It apparently uses the input, but doesn't necessarily output immediately */ if (!ash.cbSrcLengthUsed) { WARN("Sample was skipped? Outputted: %u\n", ash.cbDstLengthUsed); @@ -202,11 +205,26 @@ static HRESULT ACMWrapper_ProcessSampleData(InputPin *pin, IMediaSample *pSample ERR("No valid timestamp found\n"); IMediaSample_SetTime(pOutSample, NULL, NULL); } + + if (mtStart < 0) { + IMediaSample_SetMediaTime(pOutSample, NULL, NULL); + } else if (ash.cbSrcLengthUsed == cbSrcStream) { + IMediaSample_SetMediaTime(pOutSample, &mtStart, &mtStop); + mtStart = mtMed = mtStop; + } else if (mtStop >= mtStart) { + mtMed = mtStop - mtStart; + mtMed = mtStart + mtMed * ash.cbSrcLengthUsed / cbSrcStream; + IMediaSample_SetMediaTime(pOutSample, &mtStart, &mtMed); + mtStart = mtMed; + } else { + IMediaSample_SetMediaTime(pOutSample, NULL, NULL); + } + TRACE("Sample stop time: %u.%03u\n", (DWORD)(tStart/10000000), (DWORD)((tStart/10000)%1000)); - LeaveCriticalSection(&This->tf.csFilter); - hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pOutSample); - EnterCriticalSection(&This->tf.csFilter); + LeaveCriticalSection(&This->tf.csReceive); + hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample); + EnterCriticalSection(&This->tf.csReceive); if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) { if (FAILED(hr)) @@ -221,8 +239,7 @@ error: ash.pbSrc += ash.cbSrcLengthUsed; ash.cbSrcLength -= ash.cbSrcLengthUsed; - if (pOutSample) - IMediaSample_Release(pOutSample); + IMediaSample_Release(pOutSample); pOutSample = NULL; } @@ -230,16 +247,19 @@ error: This->lasttime_real = tStop; This->lasttime_sent = tMed; - LeaveCriticalSection(&This->tf.csFilter); + LeaveCriticalSection(&This->tf.csReceive); return hr; } -static HRESULT ACMWrapper_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI ACMWrapper_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt) { - ACMWrapperImpl* This = (ACMWrapperImpl *)pin->pin.pinInfo.pFilter; + ACMWrapperImpl* This = impl_from_TransformFilter(tf); MMRESULT res; - TRACE("(%p)->(%p)\n", This, pmt); + TRACE("(%p)->(%i %p)\n", This, dir, pmt); + + if (dir != PINDIR_INPUT) + return S_OK; /* Check root (GUID w/o FOURCC) */ if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio)) && @@ -247,7 +267,11 @@ static HRESULT ACMWrapper_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) (IsEqualIID(&pmt->formattype, &FORMAT_WaveFormatEx))) { HACMSTREAM drv; + WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat; AM_MEDIA_TYPE* outpmt = &This->tf.pmt; + + if (!wfx || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + return VFW_E_TYPE_NOT_ACCEPTED; FreeMediaType(outpmt); This->pWfIn = (LPWAVEFORMATEX)pmt->pbFormat; @@ -271,8 +295,6 @@ static HRESULT ACMWrapper_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) { This->has = drv; - /* Update buffer size of media samples in output */ - ((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pWfOut->nAvgBytesPerSec / 2; TRACE("Connection accepted\n"); return S_OK; } @@ -286,28 +308,78 @@ static HRESULT ACMWrapper_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) return VFW_E_TYPE_NOT_ACCEPTED; } -static HRESULT ACMWrapper_Cleanup(InputPin *pin) +static HRESULT WINAPI ACMWrapper_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin) { - ACMWrapperImpl *This = (ACMWrapperImpl *)pin->pin.pinInfo.pFilter; + ACMWrapperImpl* This = impl_from_TransformFilter(tf); + MMRESULT res; + HACMSTREAM drv; - TRACE("(%p)->()\n", This); + TRACE("(%p)\n", This); - if (This->has) - acmStreamClose(This->has, 0); + if (dir != PINDIR_INPUT) + return S_OK; - This->has = 0; - This->lasttime_real = This->lasttime_sent = -1; + if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0))) + { + This->has = drv; + + TRACE("Connection accepted\n"); + return S_OK; + } + + FIXME("acmStreamOpen returned %d\n", res); + TRACE("Unable to find a suitable ACM decompressor\n"); + return VFW_E_TYPE_NOT_ACCEPTED; +} + +static HRESULT WINAPI ACMWrapper_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir) +{ + ACMWrapperImpl *This = impl_from_TransformFilter(tf); + + TRACE("(%p)->(%i)\n", This,dir); + + if (dir == PINDIR_INPUT) + { + if (This->has) + acmStreamClose(This->has, 0); + + This->has = 0; + This->lasttime_real = This->lasttime_sent = -1; + } return S_OK; } -static const TransformFuncsTable ACMWrapper_FuncsTable = { +static HRESULT WINAPI ACMWrapper_DecideBufferSize(TransformFilter *tf, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + ACMWrapperImpl *pACM = impl_from_TransformFilter(tf); + ALLOCATOR_PROPERTIES actual; + + if (!ppropInputRequest->cbAlign) + ppropInputRequest->cbAlign = 1; + + if (ppropInputRequest->cbBuffer < pACM->pWfOut->nAvgBytesPerSec / 2) + ppropInputRequest->cbBuffer = pACM->pWfOut->nAvgBytesPerSec / 2; + + if (!ppropInputRequest->cBuffers) + ppropInputRequest->cBuffers = 1; + + return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual); +} + +static const TransformFilterFuncTable ACMWrapper_FuncsTable = { + ACMWrapper_DecideBufferSize, NULL, - ACMWrapper_ProcessSampleData, + ACMWrapper_Receive, NULL, NULL, - ACMWrapper_ConnectInput, - ACMWrapper_Cleanup + ACMWrapper_SetMediaType, + ACMWrapper_CompleteConnect, + ACMWrapper_BreakConnect, + NULL, + NULL, + NULL, + NULL }; HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv) @@ -322,11 +394,7 @@ HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv) if (pUnkOuter) return CLASS_E_NOAGGREGATION; - /* Note: This memory is managed by the transform filter once created */ - This = CoTaskMemAlloc(sizeof(ACMWrapperImpl)); - ZeroMemory(This, sizeof(ACMWrapperImpl)); - - hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, &ACMWrapper_FuncsTable, NULL, NULL, NULL); + hr = TransformFilter_Construct(&ACMWrapper_Vtbl, sizeof(ACMWrapperImpl), &CLSID_ACMWrapper, &ACMWrapper_FuncsTable, (IBaseFilter**)&This); if (FAILED(hr)) return hr; @@ -336,3 +404,22 @@ HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv) return hr; } + +static const IBaseFilterVtbl ACMWrapper_Vtbl = +{ + TransformFilterImpl_QueryInterface, + BaseFilterImpl_AddRef, + TransformFilterImpl_Release, + BaseFilterImpl_GetClassID, + TransformFilterImpl_Stop, + TransformFilterImpl_Pause, + TransformFilterImpl_Run, + BaseFilterImpl_GetState, + BaseFilterImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + TransformFilterImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo +}; diff --git a/dll/directx/quartz/avidec.c b/dll/directx/quartz/avidec.c index a4f997c9233..0e110d5707d 100644 --- a/dll/directx/quartz/avidec.c +++ b/dll/directx/quartz/avidec.c @@ -38,24 +38,37 @@ //#include #include -#include "transform.h" - WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct AVIDecImpl { - TransformFilterImpl tf; + TransformFilter tf; + HIC hvid; BITMAPINFOHEADER* pBihIn; BITMAPINFOHEADER* pBihOut; + REFERENCE_TIME late; } AVIDecImpl; -static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter) +static const IBaseFilterVtbl AVIDec_Vtbl; + +static inline AVIDecImpl *impl_from_IBaseFilter( IBaseFilter *iface ) { - AVIDecImpl* This = (AVIDecImpl*)pTransformFilter; + return CONTAINING_RECORD(iface, AVIDecImpl, tf.filter.IBaseFilter_iface); +} + +static inline AVIDecImpl *impl_from_TransformFilter( TransformFilter *iface ) +{ + return CONTAINING_RECORD(iface, AVIDecImpl, tf.filter); +} + +static HRESULT WINAPI AVIDec_StartStreaming(TransformFilter* pTransformFilter) +{ + AVIDecImpl* This = impl_from_TransformFilter(pTransformFilter); DWORD result; TRACE("(%p)->()\n", This); + This->late = -1; result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut); if (result != ICERR_OK) @@ -66,9 +79,39 @@ static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter) return S_OK; } -static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) +static HRESULT WINAPI AVIDec_EndFlush(TransformFilter *pTransformFilter) { + AVIDecImpl* This = impl_from_TransformFilter(pTransformFilter); + This->late = -1; + return S_OK; +} + +static HRESULT WINAPI AVIDec_NotifyDrop(TransformFilter *pTransformFilter, IBaseFilter *sender, Quality qm) { + AVIDecImpl *This = impl_from_TransformFilter(pTransformFilter); + + EnterCriticalSection(&This->tf.filter.csFilter); + if (qm.Late > 0) + This->late = qm.Late + qm.TimeStamp; + else + This->late = -1; + LeaveCriticalSection(&This->tf.filter.csFilter); + return S_OK; +} + +static int AVIDec_DropSample(AVIDecImpl *This, REFERENCE_TIME tStart) { + if (This->late < 0) + return 0; + + if (tStart < This->late) { + TRACE("Dropping sample\n"); + return 1; + } + This->late = -1; + return 0; +} + +static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample) { - AVIDecImpl* This = (AVIDecImpl *)pin->pin.pinInfo.pFilter; + AVIDecImpl* This = impl_from_TransformFilter(tf); AM_MEDIA_TYPE amt; HRESULT hr; DWORD res; @@ -78,20 +121,9 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) DWORD cbSrcStream; LPBYTE pbSrcStream; LONGLONG tStart, tStop; + DWORD flags = 0; - EnterCriticalSection(&This->tf.csFilter); - if (This->tf.state == State_Stopped) - { - LeaveCriticalSection(&This->tf.csFilter); - return VFW_E_WRONG_STATE; - } - - if (pin->end_of_stream || pin->flushing) - { - LeaveCriticalSection(&This->tf.csFilter); - return S_FALSE; - } - + EnterCriticalSection(&This->tf.csReceive); hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { @@ -112,7 +144,7 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) /* Update input size to match sample size */ This->pBihIn->biSizeImage = cbSrcStream; - hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); + hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Unable to get delivery buffer (%x)\n", hr); goto error; @@ -133,39 +165,59 @@ static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) goto error; } - res = ICDecompress(This->hvid, 0, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream); + if (IMediaSample_IsPreroll(pSample) == S_OK) + flags |= ICDECOMPRESS_PREROLL; + if (IMediaSample_IsSyncPoint(pSample) != S_OK) + flags |= ICDECOMPRESS_NOTKEYFRAME; + hr = IMediaSample_GetTime(pSample, &tStart, &tStop); + if (hr == S_OK && AVIDec_DropSample(This, tStart)) + flags |= ICDECOMPRESS_HURRYUP; + + res = ICDecompress(This->hvid, flags, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream); if (res != ICERR_OK) ERR("Error occurred during the decompression (%x)\n", res); + /* Drop sample if its intended to be dropped */ + if (flags & ICDECOMPRESS_HURRYUP) { + hr = S_OK; + goto error; + } + IMediaSample_SetActualDataLength(pOutSample, This->pBihOut->biSizeImage); IMediaSample_SetPreroll(pOutSample, (IMediaSample_IsPreroll(pSample) == S_OK)); IMediaSample_SetDiscontinuity(pOutSample, (IMediaSample_IsDiscontinuity(pSample) == S_OK)); IMediaSample_SetSyncPoint(pOutSample, (IMediaSample_IsSyncPoint(pSample) == S_OK)); - if (IMediaSample_GetTime(pSample, &tStart, &tStop) == S_OK) + if (hr == S_OK) IMediaSample_SetTime(pOutSample, &tStart, &tStop); + else if (hr == VFW_S_NO_STOP_TIME) + IMediaSample_SetTime(pOutSample, &tStart, NULL); else IMediaSample_SetTime(pOutSample, NULL, NULL); - LeaveCriticalSection(&This->tf.csFilter); - hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pOutSample); + if (IMediaSample_GetMediaTime(pSample, &tStart, &tStop) == S_OK) + IMediaSample_SetMediaTime(pOutSample, &tStart, &tStop); + else + IMediaSample_SetMediaTime(pOutSample, NULL, NULL); + + LeaveCriticalSection(&This->tf.csReceive); + hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample); + EnterCriticalSection(&This->tf.csReceive); if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) ERR("Error sending sample (%x)\n", hr); - IMediaSample_Release(pOutSample); - return hr; error: if (pOutSample) IMediaSample_Release(pOutSample); - LeaveCriticalSection(&This->tf.csFilter); + LeaveCriticalSection(&This->tf.csReceive); return hr; } -static HRESULT AVIDec_ProcessEnd(TransformFilterImpl* pTransformFilter) +static HRESULT WINAPI AVIDec_StopStreaming(TransformFilter* pTransformFilter) { - AVIDecImpl* This = (AVIDecImpl*)pTransformFilter; + AVIDecImpl* This = impl_from_TransformFilter(pTransformFilter); DWORD result; TRACE("(%p)->()\n", This); @@ -182,13 +234,16 @@ static HRESULT AVIDec_ProcessEnd(TransformFilterImpl* pTransformFilter) return S_OK; } -static HRESULT AVIDec_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI AVIDec_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt) { - AVIDecImpl* This = (AVIDecImpl*)pin->pin.pinInfo.pFilter; + AVIDecImpl* This = impl_from_TransformFilter(tf); HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED; TRACE("(%p)->(%p)\n", This, pmt); + if (dir != PINDIR_INPUT) + return S_OK; + /* Check root (GUID w/o FOURCC) */ if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) && (!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Video)+4, sizeof(GUID)-4))) @@ -268,9 +323,6 @@ static HRESULT AVIDec_ConnectInput(InputPin *pin, const AM_MEDIA_TYPE * pmt) else assert(0); - /* Update buffer size of media samples in output */ - ((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pBihOut->biSizeImage; - TRACE("Connection accepted\n"); return S_OK; } @@ -283,33 +335,69 @@ failed: return hr; } -static HRESULT AVIDec_Cleanup(InputPin *pin) +static HRESULT WINAPI AVIDec_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin) { - AVIDecImpl *This = (AVIDecImpl *)pin->pin.pinInfo.pFilter; + AVIDecImpl* This = impl_from_TransformFilter(tf); - TRACE("(%p)->()\n", This); - - if (This->hvid) - ICClose(This->hvid); - if (This->pBihIn) - CoTaskMemFree(This->pBihIn); - if (This->pBihOut) - CoTaskMemFree(This->pBihOut); - - This->hvid = NULL; - This->pBihIn = NULL; - This->pBihOut = NULL; + TRACE("(%p)\n", This); return S_OK; } -static const TransformFuncsTable AVIDec_FuncsTable = { - AVIDec_ProcessBegin, - AVIDec_ProcessSampleData, - AVIDec_ProcessEnd, +static HRESULT WINAPI AVIDec_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir) +{ + AVIDecImpl *This = impl_from_TransformFilter(tf); + + TRACE("(%p)->()\n", This); + + if (dir == PINDIR_INPUT) + { + if (This->hvid) + ICClose(This->hvid); + if (This->pBihIn) + CoTaskMemFree(This->pBihIn); + if (This->pBihOut) + CoTaskMemFree(This->pBihOut); + + This->hvid = NULL; + This->pBihIn = NULL; + This->pBihOut = NULL; + } + + return S_OK; +} + +static HRESULT WINAPI AVIDec_DecideBufferSize(TransformFilter *tf, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + AVIDecImpl *pAVI = impl_from_TransformFilter(tf); + ALLOCATOR_PROPERTIES actual; + + if (!ppropInputRequest->cbAlign) + ppropInputRequest->cbAlign = 1; + + if (ppropInputRequest->cbBuffer < pAVI->pBihOut->biSizeImage) + ppropInputRequest->cbBuffer = pAVI->pBihOut->biSizeImage; + + if (!ppropInputRequest->cBuffers) + ppropInputRequest->cBuffers = 1; + + return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual); +} + +static const TransformFilterFuncTable AVIDec_FuncsTable = { + AVIDec_DecideBufferSize, + AVIDec_StartStreaming, + AVIDec_Receive, + AVIDec_StopStreaming, NULL, - AVIDec_ConnectInput, - AVIDec_Cleanup + AVIDec_SetMediaType, + AVIDec_CompleteConnect, + AVIDec_BreakConnect, + NULL, + NULL, + AVIDec_EndFlush, + NULL, + AVIDec_NotifyDrop }; HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv) @@ -324,19 +412,35 @@ HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv) if (pUnkOuter) return CLASS_E_NOAGGREGATION; - /* Note: This memory is managed by the transform filter once created */ - This = CoTaskMemAlloc(sizeof(AVIDecImpl)); + hr = TransformFilter_Construct(&AVIDec_Vtbl, sizeof(AVIDecImpl), &CLSID_AVIDec, &AVIDec_FuncsTable, (IBaseFilter**)&This); + + if (FAILED(hr)) + return hr; This->hvid = NULL; This->pBihIn = NULL; This->pBihOut = NULL; - hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, &AVIDec_FuncsTable, NULL, NULL, NULL); - - if (FAILED(hr)) - return hr; - *ppv = This; return hr; } + +static const IBaseFilterVtbl AVIDec_Vtbl = +{ + TransformFilterImpl_QueryInterface, + BaseFilterImpl_AddRef, + TransformFilterImpl_Release, + BaseFilterImpl_GetClassID, + TransformFilterImpl_Stop, + TransformFilterImpl_Pause, + TransformFilterImpl_Run, + BaseFilterImpl_GetState, + BaseFilterImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + TransformFilterImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo +}; diff --git a/dll/directx/quartz/avisplit.c b/dll/directx/quartz/avisplit.c index ef28e3bb63e..8e673418074 100644 --- a/dll/directx/quartz/avisplit.c +++ b/dll/directx/quartz/avisplit.c @@ -30,7 +30,6 @@ */ #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "uuids.h" @@ -101,6 +100,11 @@ struct thread_args { DWORD stream; }; +static inline AVISplitterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) +{ + return CONTAINING_RECORD(iface, AVISplitterImpl, Parser.sourceSeeking.IMediaSeeking_iface); +} + /* The threading stuff cries for an explanation * * PullPin starts processing and calls AVISplitter_first_request @@ -284,9 +288,9 @@ static HRESULT AVISplitter_next_request(AVISplitterImpl *This, DWORD streamnumbe static HRESULT AVISplitter_Receive(AVISplitterImpl *This, IMediaSample *sample, DWORD streamnumber) { - Parser_OutputPin *pin = (Parser_OutputPin *)This->Parser.ppPins[1+streamnumber]; + Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1+streamnumber]); HRESULT hr; - LONGLONG start, stop; + LONGLONG start, stop, rtstart, rtstop; StreamData *stream = &This->streams[streamnumber]; start = pin->dwSamplesProcessed; @@ -309,9 +313,31 @@ static HRESULT AVISplitter_Receive(AVISplitterImpl *This, IMediaSample *sample, stop *= 10000000; stop /= stream->streamheader.dwRate; - IMediaSample_SetTime(sample, &start, &stop); + if (IMediaSample_IsDiscontinuity(sample) == S_OK) { + IPin *victim; + EnterCriticalSection(&This->Parser.filter.csFilter); + pin->pin.pin.tStart = start; + pin->pin.pin.dRate = This->Parser.sourceSeeking.dRate; + hr = IPin_ConnectedTo(&pin->pin.pin.IPin_iface, &victim); + if (hr == S_OK) + { + hr = IPin_NewSegment(victim, start, This->Parser.sourceSeeking.llStop, + This->Parser.sourceSeeking.dRate); + if (hr != S_OK) + FIXME("NewSegment returns %08x\n", hr); + IPin_Release(victim); + } + LeaveCriticalSection(&This->Parser.filter.csFilter); + if (hr != S_OK) + return hr; + } + rtstart = (double)(start - pin->pin.pin.tStart) / pin->pin.pin.dRate; + rtstop = (double)(stop - pin->pin.pin.tStart) / pin->pin.pin.dRate; + hr = IMediaSample_SetMediaTime(sample, &start, &stop); + IMediaSample_SetTime(sample, &rtstart, &rtstop); + IMediaSample_SetMediaTime(sample, &start, &stop); - hr = OutputPin_SendSample(&pin->pin, sample); + hr = BaseOutputPinImpl_Deliver(&pin->pin, sample); /* Uncomment this if you want to debug the time differences between the * different streams, it is useful for that @@ -373,7 +399,7 @@ static HRESULT AVISplitter_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PT return S_OK; } - /* Send the sample to whatever thread is appropiate + /* Send the sample to whatever thread is appropriate * That thread should also not have a sample queued at the moment */ /* Debugging */ @@ -421,6 +447,9 @@ static HRESULT AVISplitter_first_request(LPVOID iface) stream->pos_next = stream->pos; stream->index_next = stream->index; + /* This was sent after stopped->paused or stopped->playing, so set seek */ + stream->seek = 1; + /* There should be a packet queued from AVISplitter_next_request last time * It needs to be done now because this is the only way to ensure that every * stream will have at least 1 packet processed @@ -530,13 +559,13 @@ static HRESULT AVISplitter_ProcessIndex(AVISplitterImpl *This, AVISTDINDEX **ind if (!pIndex) return E_OUTOFMEMORY; - IAsyncReader_SyncRead(((PullPin *)This->Parser.ppPins[0])->pReader, qwOffset, cb, (BYTE *)pIndex); + IAsyncReader_SyncRead((impl_PullPin_from_IPin(This->Parser.ppPins[0]))->pReader, qwOffset, cb, (BYTE *)pIndex); rest = cb - sizeof(AVISUPERINDEX) + sizeof(RIFFCHUNK) + sizeof(pIndex->aIndex); TRACE("FOURCC: %s\n", debugstr_an((char *)&pIndex->fcc, 4)); TRACE("wLongsPerEntry: %hd\n", pIndex->wLongsPerEntry); - TRACE("bIndexSubType: %hd\n", pIndex->bIndexSubType); - TRACE("bIndexType: %hd\n", pIndex->bIndexType); + TRACE("bIndexSubType: %u\n", pIndex->bIndexSubType); + TRACE("bIndexType: %u\n", pIndex->bIndexType); TRACE("nEntriesInUse: %u\n", pIndex->nEntriesInUse); TRACE("dwChunkId: %.4s\n", (char *)&pIndex->dwChunkId); TRACE("qwBaseOffset: %x%08x\n", (DWORD)(pIndex->qwBaseOffset >> 32), (DWORD)pIndex->qwBaseOffset); @@ -785,8 +814,8 @@ static HRESULT AVISplitter_ProcessStreamList(AVISplitterImpl * This, const BYTE } TRACE("wLongsPerEntry: %hd\n", pIndex->wLongsPerEntry); - TRACE("bIndexSubType: %hd\n", pIndex->bIndexSubType); - TRACE("bIndexType: %hd\n", pIndex->bIndexType); + TRACE("bIndexSubType: %u\n", pIndex->bIndexSubType); + TRACE("bIndexType: %u\n", pIndex->bIndexType); TRACE("nEntriesInUse: %u\n", pIndex->nEntriesInUse); TRACE("dwChunkId: %.4s\n", (const char *)&pIndex->dwChunkId); if (pIndex->dwReserved[0]) @@ -899,7 +928,7 @@ static HRESULT AVISplitter_InitializeStreams(AVISplitterImpl *This) nMax = This->oldindex->cb / sizeof(This->oldindex->aIndex[0]); - /* Ok, maybe this is more of an excercise to see if I interpret everything correctly or not, but that is useful for now. */ + /* Ok, maybe this is more of an exercise to see if I interpret everything correctly or not, but that is useful for now. */ for (n = 0; n < nMax; ++n) { DWORD streamId = StreamFromFOURCC(This->oldindex->aIndex[n].dwChunkId); @@ -970,16 +999,16 @@ static HRESULT AVISplitter_InitializeStreams(AVISplitterImpl *This) frames *= stream->streamheader.dwScale; /* Keep accuracy as high as possible for duration */ - This->Parser.mediaSeeking.llDuration = frames * 10000000; - This->Parser.mediaSeeking.llDuration /= stream->streamheader.dwRate; - This->Parser.mediaSeeking.llStop = This->Parser.mediaSeeking.llDuration; - This->Parser.mediaSeeking.llCurrent = 0; + This->Parser.sourceSeeking.llDuration = frames * 10000000; + This->Parser.sourceSeeking.llDuration /= stream->streamheader.dwRate; + This->Parser.sourceSeeking.llStop = This->Parser.sourceSeeking.llDuration; + This->Parser.sourceSeeking.llCurrent = 0; frames /= stream->streamheader.dwRate; TRACE("Duration: %d days, %d hours, %d minutes and %d.%03u seconds\n", (DWORD)(frames / 86400), (DWORD)((frames % 86400) / 3600), (DWORD)((frames % 3600) / 60), (DWORD)(frames % 60), - (DWORD)(This->Parser.mediaSeeking.llDuration/10000) % 1000); + (DWORD)(This->Parser.sourceSeeking.llDuration/10000) % 1000); } return S_OK; @@ -990,7 +1019,7 @@ static HRESULT AVISplitter_Disconnect(LPVOID iface); /* FIXME: fix leaks on failure here */ static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props) { - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); HRESULT hr; RIFFLIST list; LONGLONG pos = 0; /* in bytes */ @@ -1239,7 +1268,7 @@ static ULONG WINAPI AVISplitter_Release(IBaseFilter *iface) AVISplitterImpl *This = (AVISplitterImpl *)iface; ULONG ref; - ref = InterlockedDecrement(&This->Parser.refCount); + ref = InterlockedDecrement(&This->Parser.filter.refCount); TRACE("(%p)->() Release from %d\n", This, ref + 1); @@ -1252,15 +1281,15 @@ static ULONG WINAPI AVISplitter_Release(IBaseFilter *iface) return ref; } -static HRESULT AVISplitter_seek(IBaseFilter *iface) +static HRESULT WINAPI AVISplitter_seek(IMediaSeeking *iface) { - AVISplitterImpl *This = (AVISplitterImpl *)iface; + AVISplitterImpl *This = impl_from_IMediaSeeking(iface); PullPin *pPin = This->Parser.pInputPin; LONGLONG newpos, endpos; DWORD x; - newpos = This->Parser.mediaSeeking.llCurrent; - endpos = This->Parser.mediaSeeking.llDuration; + newpos = This->Parser.sourceSeeking.llCurrent; + endpos = This->Parser.sourceSeeking.llDuration; if (newpos > endpos) { @@ -1272,15 +1301,14 @@ static HRESULT AVISplitter_seek(IBaseFilter *iface) EnterCriticalSection(&pPin->thread_lock); /* Send a flush to all output pins */ - IPin_BeginFlush((IPin *)pPin); + IPin_BeginFlush(&pPin->pin.IPin_iface); /* Make sure this is done while stopped, BeginFlush takes care of this */ - EnterCriticalSection(&This->Parser.csFilter); + EnterCriticalSection(&This->Parser.filter.csFilter); for (x = 0; x < This->Parser.cStreams; ++x) { - Parser_OutputPin *pin = (Parser_OutputPin *)This->Parser.ppPins[1+x]; + Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1+x]); StreamData *stream = This->streams + x; - IPin *victim = NULL; LONGLONG wanted_frames; DWORD last_keyframe = 0, last_keyframeidx = 0, preroll = 0; @@ -1289,13 +1317,6 @@ static HRESULT AVISplitter_seek(IBaseFilter *iface) wanted_frames /= 10000000; wanted_frames /= stream->streamheader.dwScale; - IPin_ConnectedTo((IPin *)pin, &victim); - if (victim) - { - IPin_NewSegment(victim, newpos, endpos, pPin->dRate); - IPin_Release(victim); - } - pin->dwSamplesProcessed = 0; stream->index = 0; stream->pos = 0; @@ -1377,10 +1398,10 @@ static HRESULT AVISplitter_seek(IBaseFilter *iface) stream->preroll = preroll; stream->seek = 1; } - LeaveCriticalSection(&This->Parser.csFilter); + LeaveCriticalSection(&This->Parser.filter.csFilter); TRACE("Done flushing\n"); - IPin_EndFlush((IPin *)pPin); + IPin_EndFlush(&pPin->pin.IPin_iface); LeaveCriticalSection(&pPin->thread_lock); return S_OK; diff --git a/dll/directx/quartz/control.c b/dll/directx/quartz/control.c deleted file mode 100644 index 03f87bbe6dc..00000000000 --- a/dll/directx/quartz/control.c +++ /dev/null @@ -1,921 +0,0 @@ -/* - * Filter Seeking and Control Interfaces - * - * Copyright 2003 Robert Shearman - * - * 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 - */ -/* FIXME: critical sections */ - -#include "quartz_private.h" -#include "control_private.h" - -//#include "uuids.h" -#include - -#include - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl; - -typedef struct PassThruImpl { - const ISeekingPassThruVtbl *IPassThru_vtbl; - const IUnknownVtbl *IInner_vtbl; - const IMediaSeekingVtbl *IMediaSeeking_vtbl; - - LONG ref; - IUnknown * pUnkOuter; - IPin * pin; - BOOL bUnkOuterValid; - BOOL bAggregatable; - BOOL renderer; -} PassThruImpl; - -static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface, - REFIID riid, - LPVOID *ppvObj) { - ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface); - TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj); - - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (IsEqualGUID(&IID_IUnknown, riid)) - { - *ppvObj = &(This->IInner_vtbl); - TRACE(" returning IUnknown interface (%p)\n", *ppvObj); - } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) { - *ppvObj = &(This->IPassThru_vtbl); - TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj); - } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) { - *ppvObj = &(This->IMediaSeeking_vtbl); - TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj); - } else { - *ppvObj = NULL; - FIXME("unknown interface %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown *)(*ppvObj)); - return S_OK; -} - -static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) { - ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(): new ref = %d\n", This, ref); - - return ref; -} - -static ULONG WINAPI SeekInner_Release(IUnknown * iface) { - ICOM_THIS_MULTI(PassThruImpl, IInner_vtbl, iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(): new ref = %d\n", This, ref); - - if (ref == 0) - { - CoTaskMemFree(This); - } - return ref; -} - -static const IUnknownVtbl IInner_VTable = -{ - SeekInner_QueryInterface, - SeekInner_AddRef, - SeekInner_Release -}; - -/* Generic functions for aggregation */ -static HRESULT SeekOuter_QueryInterface(PassThruImpl *This, REFIID riid, LPVOID *ppv) -{ - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (This->pUnkOuter) - { - if (This->bAggregatable) - return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - { - HRESULT hr; - - IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); - hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); - IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); - This->bAggregatable = TRUE; - return hr; - } - - *ppv = NULL; - return E_NOINTERFACE; - } - - return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); -} - -static ULONG SeekOuter_AddRef(PassThruImpl *This) -{ - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_AddRef(This->pUnkOuter); - return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); -} - -static ULONG SeekOuter_Release(PassThruImpl *This) -{ - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_Release(This->pUnkOuter); - return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); -} - -static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID riid, LPVOID *ppvObj) -{ - ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface); - - TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - - return SeekOuter_QueryInterface(This, riid, ppvObj); -} - -static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface) -{ - ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface); - - TRACE("(%p/%p)->()\n", This, iface); - - return SeekOuter_AddRef(This); -} - -static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface) -{ - ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface); - - TRACE("(%p/%p)->()\n", This, iface); - - return SeekOuter_Release(This); -} - -static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin) -{ - ICOM_THIS_MULTI(PassThruImpl, IPassThru_vtbl, iface); - - TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin); - - if (This->pin) - FIXME("Re-initializing?\n"); - - This->renderer = renderer; - This->pin = pin; - - return S_OK; -} - -static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl = -{ - SeekingPassThru_QueryInterface, - SeekingPassThru_AddRef, - SeekingPassThru_Release, - SeekingPassThru_Init -}; - -HRESULT SeekingPassThru_create(IUnknown *pUnkOuter, LPVOID *ppObj) -{ - PassThruImpl *fimpl; - - TRACE("(%p,%p)\n", pUnkOuter, ppObj); - - *ppObj = fimpl = CoTaskMemAlloc(sizeof(*fimpl)); - if (!fimpl) - return E_OUTOFMEMORY; - - fimpl->pUnkOuter = pUnkOuter; - fimpl->bUnkOuterValid = FALSE; - fimpl->bAggregatable = FALSE; - fimpl->IInner_vtbl = &IInner_VTable; - fimpl->IPassThru_vtbl = &ISeekingPassThru_Vtbl; - fimpl->IMediaSeeking_vtbl = &IMediaSeekingPassThru_Vtbl; - fimpl->ref = 1; - fimpl->pin = NULL; - return S_OK; -} - -typedef HRESULT (*SeekFunc)( IMediaSeeking *to, LPVOID arg ); - -static HRESULT ForwardCmdSeek( PCRITICAL_SECTION crit_sect, IBaseFilter* from, SeekFunc fnSeek, LPVOID arg ) -{ - HRESULT hr = S_OK; - HRESULT hr_return = S_OK; - IEnumPins *enumpins = NULL; - BOOL foundend = FALSE, allnotimpl = TRUE; - - hr = IBaseFilter_EnumPins( from, &enumpins ); - if (FAILED(hr)) - goto out; - - hr = IEnumPins_Reset( enumpins ); - while (hr == S_OK) { - IPin *pin = NULL; - hr = IEnumPins_Next( enumpins, 1, &pin, NULL ); - if (hr == VFW_E_ENUM_OUT_OF_SYNC) - { - hr = IEnumPins_Reset( enumpins ); - continue; - } - if (pin) - { - PIN_DIRECTION dir; - - IPin_QueryDirection( pin, &dir ); - if (dir == PINDIR_INPUT) - { - IPin *connected = NULL; - - IPin_ConnectedTo( pin, &connected ); - if (connected) - { - HRESULT hr_local; - IMediaSeeking *seek = NULL; - - hr_local = IPin_QueryInterface( connected, &IID_IMediaSeeking, (void**)&seek ); - if (hr_local == S_OK) - { - foundend = TRUE; - if (crit_sect) - { - LeaveCriticalSection( crit_sect ); - hr_local = fnSeek( seek , arg ); - EnterCriticalSection( crit_sect ); - } - else - hr_local = fnSeek( seek , arg ); - - if (hr_local != E_NOTIMPL) - allnotimpl = FALSE; - - hr_return = updatehres( hr_return, hr_local ); - IMediaSeeking_Release( seek ); - } - IPin_Release(connected); - } - } - IPin_Release( pin ); - } - } - IEnumPins_Release( enumpins ); - - if (foundend && allnotimpl) - hr = E_NOTIMPL; - else - hr = hr_return; - -out: - TRACE("Returning: %08x\n", hr); - return hr; -} - - -HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeCurrent, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking, PCRITICAL_SECTION crit_sect) -{ - assert(fnChangeStop && fnChangeCurrent && fnChangeRate); - - pSeeking->refCount = 1; - pSeeking->pUserData = pUserData; - pSeeking->fnChangeRate = fnChangeRate; - pSeeking->fnChangeStop = fnChangeStop; - pSeeking->fnChangeCurrent = fnChangeCurrent; - pSeeking->dwCapabilities = AM_SEEKING_CanSeekForwards | - AM_SEEKING_CanSeekBackwards | - AM_SEEKING_CanSeekAbsolute | - AM_SEEKING_CanGetStopPos | - AM_SEEKING_CanGetDuration; - pSeeking->llCurrent = 0; - pSeeking->llStop = ((ULONGLONG)0x80000000) << 32; - pSeeking->llDuration = pSeeking->llStop; - pSeeking->dRate = 1.0; - pSeeking->timeformat = TIME_FORMAT_MEDIA_TIME; - pSeeking->crst = crit_sect; - - return S_OK; -} - -struct pos_args { - LONGLONG* current, *stop; - DWORD curflags, stopflags; -}; - -static HRESULT fwd_setposition(IMediaSeeking *seek, LPVOID pargs) -{ - struct pos_args *args = (void*)pargs; - - return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags); -} - -static HRESULT fwd_checkcaps(IMediaSeeking *iface, LPVOID pcaps) -{ - DWORD *caps = pcaps; - return IMediaSeeking_CheckCapabilities(iface, caps); -} - -static HRESULT fwd_settimeformat(IMediaSeeking *iface, LPVOID pformat) -{ - const GUID *format = pformat; - return IMediaSeeking_SetTimeFormat(iface, format); -} - -static HRESULT fwd_getduration(IMediaSeeking *iface, LPVOID pdur) -{ - LONGLONG *duration = pdur; - LONGLONG mydur = *duration; - HRESULT hr; - - hr = IMediaSeeking_GetDuration(iface, &mydur); - if (FAILED(hr)) - return hr; - - if ((mydur < *duration) || (*duration < 0 && mydur > 0)) - *duration = mydur; - return hr; -} - -static HRESULT fwd_getstopposition(IMediaSeeking *iface, LPVOID pdur) -{ - LONGLONG *duration = pdur; - LONGLONG mydur = *duration; - HRESULT hr; - - hr = IMediaSeeking_GetStopPosition(iface, &mydur); - if (FAILED(hr)) - return hr; - - if ((mydur < *duration) || (*duration < 0 && mydur > 0)) - *duration = mydur; - return hr; -} - -static HRESULT fwd_getcurposition(IMediaSeeking *iface, LPVOID pdur) -{ - LONGLONG *duration = pdur; - LONGLONG mydur = *duration; - HRESULT hr; - - hr = IMediaSeeking_GetCurrentPosition(iface, &mydur); - if (FAILED(hr)) - return hr; - - if ((mydur < *duration) || (*duration < 0 && mydur > 0)) - *duration = mydur; - return hr; -} - -static HRESULT fwd_setrate(IMediaSeeking *iface, LPVOID prate) -{ - double *rate = prate; - - HRESULT hr; - - hr = IMediaSeeking_SetRate(iface, *rate); - if (FAILED(hr)) - return hr; - - return hr; -} - - -HRESULT WINAPI MediaSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p)\n", pCapabilities); - - *pCapabilities = This->dwCapabilities; - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - HRESULT hr; - DWORD dwCommonCaps; - - TRACE("(%p)\n", pCapabilities); - - if (!pCapabilities) - return E_POINTER; - - EnterCriticalSection(This->crst); - hr = ForwardCmdSeek(This->crst, This->pUserData, fwd_checkcaps, pCapabilities); - LeaveCriticalSection(This->crst); - if (FAILED(hr) && hr != E_NOTIMPL) - return hr; - - dwCommonCaps = *pCapabilities & This->dwCapabilities; - - if (!dwCommonCaps) - hr = E_FAIL; - else - hr = (*pCapabilities == dwCommonCaps) ? S_OK : S_FALSE; - *pCapabilities = dwCommonCaps; - - return hr; -} - -HRESULT WINAPI MediaSeekingImpl_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat) -{ - TRACE("(%s)\n", qzdebugstr_guid(pFormat)); - - return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE); -} - -HRESULT WINAPI MediaSeekingImpl_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat) -{ - TRACE("(%s)\n", qzdebugstr_guid(pFormat)); - - *pFormat = TIME_FORMAT_MEDIA_TIME; - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - TRACE("(%s)\n", qzdebugstr_guid(pFormat)); - - EnterCriticalSection(This->crst); - *pFormat = This->timeformat; - LeaveCriticalSection(This->crst); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - HRESULT hr = S_OK; - - TRACE("(%s)\n", qzdebugstr_guid(pFormat)); - - EnterCriticalSection(This->crst); - if (!IsEqualIID(pFormat, &This->timeformat)) - hr = S_FALSE; - LeaveCriticalSection(This->crst); - - return hr; -} - - -HRESULT WINAPI MediaSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - TRACE("(%s)\n", qzdebugstr_guid(pFormat)); - - EnterCriticalSection(This->crst); - ForwardCmdSeek(This->crst, This->pUserData, fwd_settimeformat, (LPVOID)pFormat); - LeaveCriticalSection(This->crst); - - return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE); -} - - -HRESULT WINAPI MediaSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p)\n", pDuration); - - EnterCriticalSection(This->crst); - *pDuration = This->llDuration; - ForwardCmdSeek(This->crst, This->pUserData, fwd_getduration, pDuration); - LeaveCriticalSection(This->crst); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p)\n", pStop); - - EnterCriticalSection(This->crst); - *pStop = This->llStop; - ForwardCmdSeek(This->crst, This->pUserData, fwd_getstopposition, pStop); - LeaveCriticalSection(This->crst); - - return S_OK; -} - -/* FIXME: Make use of the info the filter should expose */ -HRESULT WINAPI MediaSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p)\n", pCurrent); - - EnterCriticalSection(This->crst); - *pCurrent = This->llCurrent; - ForwardCmdSeek(This->crst, This->pUserData, fwd_getcurposition, pCurrent); - LeaveCriticalSection(This->crst); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat) -{ - if (IsEqualIID(pTargetFormat, &TIME_FORMAT_MEDIA_TIME) && IsEqualIID(pSourceFormat, &TIME_FORMAT_MEDIA_TIME)) - { - *pTarget = Source; - return S_OK; - } - /* FIXME: clear pTarget? */ - return E_INVALIDARG; -} - -static inline LONGLONG Adjust(LONGLONG value, const LONGLONG * pModifier, DWORD dwFlags) -{ - switch (dwFlags & AM_SEEKING_PositioningBitsMask) - { - case AM_SEEKING_NoPositioning: - return value; - case AM_SEEKING_AbsolutePositioning: - return *pModifier; - case AM_SEEKING_RelativePositioning: - case AM_SEEKING_IncrementalPositioning: - return value + *pModifier; - default: - assert(FALSE); - return 0; - } -} - -HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - BOOL bChangeCurrent = FALSE, bChangeStop = FALSE; - LONGLONG llNewCurrent, llNewStop; - struct pos_args args; - - TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags); - - args.current = pCurrent; - args.stop = pStop; - args.curflags = dwCurrentFlags; - args.stopflags = dwStopFlags; - - EnterCriticalSection(This->crst); - - llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags); - llNewStop = Adjust(This->llStop, pStop, dwStopFlags); - - if (pCurrent) - bChangeCurrent = TRUE; - if (llNewStop != This->llStop) - bChangeStop = TRUE; - - TRACE("Old: %u, New: %u\n", (DWORD)(This->llCurrent/10000000), (DWORD)(llNewCurrent/10000000)); - - This->llCurrent = llNewCurrent; - This->llStop = llNewStop; - - if (pCurrent && (dwCurrentFlags & AM_SEEKING_ReturnTime)) - *pCurrent = llNewCurrent; - if (pStop && (dwStopFlags & AM_SEEKING_ReturnTime)) - *pStop = llNewStop; - - ForwardCmdSeek(This->crst, This->pUserData, fwd_setposition, &args); - LeaveCriticalSection(This->crst); - - if (bChangeCurrent) - This->fnChangeCurrent(This->pUserData); - if (bChangeStop) - This->fnChangeStop(This->pUserData); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p, %p)\n", pCurrent, pStop); - - EnterCriticalSection(This->crst); - *pCurrent = This->llCurrent; - *pStop = This->llStop; - LeaveCriticalSection(This->crst); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p, %p)\n", pEarliest, pLatest); - - EnterCriticalSection(This->crst); - *pEarliest = 0; - *pLatest = This->llDuration; - LeaveCriticalSection(This->crst); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_SetRate(IMediaSeeking * iface, double dRate) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - BOOL bChangeRate = (dRate != This->dRate); - HRESULT hr = S_OK; - - TRACE("(%e)\n", dRate); - - if (dRate > 100 || dRate < .001) - { - FIXME("Excessive rate %e, ignoring\n", dRate); - return VFW_E_UNSUPPORTED_AUDIO; - } - - EnterCriticalSection(This->crst); - This->dRate = dRate; - if (bChangeRate) - hr = This->fnChangeRate(This->pUserData); - ForwardCmdSeek(This->crst, This->pUserData, fwd_setrate, &dRate); - LeaveCriticalSection(This->crst); - - return hr; -} - -HRESULT WINAPI MediaSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate) -{ - MediaSeekingImpl *This = (MediaSeekingImpl *)iface; - - TRACE("(%p)\n", dRate); - - EnterCriticalSection(This->crst); - /* Forward? */ - *dRate = This->dRate; - LeaveCriticalSection(This->crst); - - return S_OK; -} - -HRESULT WINAPI MediaSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll) -{ - TRACE("(%p)\n", pPreroll); - - *pPreroll = 0; - return S_OK; -} - -static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID riid, LPVOID *ppvObj) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - - return SeekOuter_QueryInterface(This, riid, ppvObj); -} - -static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->()\n", iface, This); - - return SeekOuter_AddRef(This); -} - -static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->()\n", iface, This); - - return SeekOuter_Release(This); -} - -static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities); - - if (!pCapabilities) - return E_POINTER; - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - TRACE("(%p/%p)->(%s)\n", iface, This, qzdebugstr_guid(pFormat)); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - TRACE("(%p/%p)->(%p)\n", iface, This, pFormat); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - TRACE("(%p/%p)->(%p)\n", iface, This, pFormat); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%s)\n", iface, This, qzdebugstr_guid(pFormat)); - - FIXME("stub\n"); - return E_NOTIMPL; -} - - -static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - TRACE("(%p/%p)->(%s)\n", iface, This, qzdebugstr_guid(pFormat)); - - FIXME("stub\n"); - return E_NOTIMPL; -} - - -static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - PIN_INFO info; - HRESULT hr; - - TRACE("(%p/%p)->(%p)\n", iface, This, pDuration); - - IPin_QueryPinInfo(This->pin, &info); - - hr = ForwardCmdSeek(NULL, info.pFilter, fwd_getduration, pDuration); - IBaseFilter_Release(info.pFilter); - - return hr; -} - -static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", iface, This, pStop); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -/* FIXME: Make use of the info the filter should expose */ -static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface, This, pTarget, debugstr_guid(pTargetFormat), (DWORD)(Source>>32), (DWORD)Source, debugstr_guid(pSourceFormat)); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - struct pos_args args; - PIN_INFO info; - HRESULT hr; - - TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop); - args.current = pCurrent; - args.stop = pStop; - args.curflags = dwCurrentFlags; - args.stopflags = dwStopFlags; - - IPin_QueryPinInfo(This->pin, &info); - - hr = ForwardCmdSeek(NULL, info.pFilter, fwd_setposition, &args); - IBaseFilter_Release(info.pFilter); - return hr; -} - -static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%e)\n", iface, This, dRate); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate) -{ - ICOM_THIS_MULTI(PassThruImpl, IMediaSeeking_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", iface, This, dRate); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll) -{ - TRACE("(%p)\n", pPreroll); - - FIXME("stub\n"); - return E_NOTIMPL; -} - -static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl = -{ - MediaSeekingPassThru_QueryInterface, - MediaSeekingPassThru_AddRef, - MediaSeekingPassThru_Release, - MediaSeekingPassThru_GetCapabilities, - MediaSeekingPassThru_CheckCapabilities, - MediaSeekingPassThru_IsFormatSupported, - MediaSeekingPassThru_QueryPreferredFormat, - MediaSeekingPassThru_GetTimeFormat, - MediaSeekingPassThru_IsUsingTimeFormat, - MediaSeekingPassThru_SetTimeFormat, - MediaSeekingPassThru_GetDuration, - MediaSeekingPassThru_GetStopPosition, - MediaSeekingPassThru_GetCurrentPosition, - MediaSeekingPassThru_ConvertTimeFormat, - MediaSeekingPassThru_SetPositions, - MediaSeekingPassThru_GetPositions, - MediaSeekingPassThru_GetAvailable, - MediaSeekingPassThru_SetRate, - MediaSeekingPassThru_GetRate, - MediaSeekingPassThru_GetPreroll -}; diff --git a/dll/directx/quartz/control_private.h b/dll/directx/quartz/control_private.h deleted file mode 100644 index b5e3997e716..00000000000 --- a/dll/directx/quartz/control_private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Filter Seeking and Control Interfaces - * - * Copyright 2003 Robert Shearman - * - * 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 - */ - -#ifndef QUARTZ_CONTROL_H -#define QUARTZ_CONTROL_H - -typedef HRESULT (* CHANGEPROC)(IBaseFilter *pUserData); - -typedef struct MediaSeekingImpl -{ - const IMediaSeekingVtbl * lpVtbl; - - ULONG refCount; - IBaseFilter *pUserData; - CHANGEPROC fnChangeStop; - CHANGEPROC fnChangeCurrent; - CHANGEPROC fnChangeRate; - DWORD dwCapabilities; - double dRate; - LONGLONG llCurrent, llStop, llDuration; - GUID timeformat; - PCRITICAL_SECTION crst; -} MediaSeekingImpl; - -HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeCurrent, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking, PCRITICAL_SECTION crit_sect); - -HRESULT WINAPI MediaSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities); -HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities); -HRESULT WINAPI MediaSeekingImpl_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat); -HRESULT WINAPI MediaSeekingImpl_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat); -HRESULT WINAPI MediaSeekingImpl_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat); -HRESULT WINAPI MediaSeekingImpl_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat); -HRESULT WINAPI MediaSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat); -HRESULT WINAPI MediaSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration); -HRESULT WINAPI MediaSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop); -HRESULT WINAPI MediaSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent); -HRESULT WINAPI MediaSeekingImpl_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat); -HRESULT WINAPI MediaSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags); -HRESULT WINAPI MediaSeekingImpl_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop); -HRESULT WINAPI MediaSeekingImpl_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest); -HRESULT WINAPI MediaSeekingImpl_SetRate(IMediaSeeking * iface, double dRate); -HRESULT WINAPI MediaSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate); -HRESULT WINAPI MediaSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll); - -#endif /*QUARTZ_CONTROL_H*/ diff --git a/include/dxsdk/strmif.idl b/dll/directx/quartz/control_tlb.idl similarity index 77% rename from include/dxsdk/strmif.idl rename to dll/directx/quartz/control_tlb.idl index a1cad6ba00e..6d1855252a7 100644 --- a/include/dxsdk/strmif.idl +++ b/dll/directx/quartz/control_tlb.idl @@ -1,6 +1,4 @@ /* - * Copyright (C) 2002 Robert Shearman - * * 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 @@ -16,15 +14,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -import "objidl.idl"; - -#include - -#include - -#include - -#include - -/* TODO: #include */ -#include +#include "control.idl" diff --git a/dll/directx/quartz/control_tlb.rgs b/dll/directx/quartz/control_tlb.rgs new file mode 100644 index 00000000000..25e21d609e0 --- /dev/null +++ b/dll/directx/quartz/control_tlb.rgs @@ -0,0 +1,20 @@ +HKCR +{ + NoRemove Typelib + { + NoRemove '{56A868B0-0AD4-11CE-B03A-0020AF0BA770}' + { + '1.0' = s 'QuartzTypeLib' + { + '0' { win32 = s '%MODULE%' } + FLAGS = s '0' + } + } + } + NoRemove Interface + { + } + NoRemove CLSID + { + } +} diff --git a/dll/directx/quartz/dsoundrender.c b/dll/directx/quartz/dsoundrender.c index ddeb3b17e1e..9c4c38b12a9 100644 --- a/dll/directx/quartz/dsoundrender.c +++ b/dll/directx/quartz/dsoundrender.c @@ -21,7 +21,6 @@ #include #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "uuids.h" @@ -39,233 +38,299 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); -static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; +/* NOTE: buffer can still be filled completely, + * but we start waiting until only this amount is buffered + */ +static const REFERENCE_TIME DSoundRenderer_Max_Fill = 150 * 10000; static const IBaseFilterVtbl DSoundRender_Vtbl; -static const IPinVtbl DSoundRender_InputPin_Vtbl; static const IBasicAudioVtbl IBasicAudio_Vtbl; static const IReferenceClockVtbl IReferenceClock_Vtbl; static const IMediaSeekingVtbl IMediaSeeking_Vtbl; static const IAMDirectSoundVtbl IAMDirectSound_Vtbl; +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl; typedef struct DSoundRenderImpl { - const IBaseFilterVtbl * lpVtbl; - const IBasicAudioVtbl *IBasicAudio_vtbl; - const IReferenceClockVtbl *IReferenceClock_vtbl; - const IAMDirectSoundVtbl *IAMDirectSound_vtbl; + BaseRenderer renderer; + BasicAudio basicAudio; - LONG refCount; - CRITICAL_SECTION csFilter; - FILTER_STATE state; - REFERENCE_TIME rtStreamStart, rtLastStop; - IReferenceClock * pClock; - FILTER_INFO filterInfo; - - InputPin * pInputPin; + IReferenceClock IReferenceClock_iface; + IAMDirectSound IAMDirectSound_iface; + IAMFilterMiscFlags IAMFilterMiscFlags_iface; IDirectSound8 *dsound; LPDIRECTSOUNDBUFFER dsbuffer; DWORD buf_size; - DWORD write_pos; - DWORD write_loops; - - DWORD last_play_pos; - DWORD play_loops; + DWORD in_loop; + DWORD last_playpos, writepos; REFERENCE_TIME play_time; - MediaSeekingImpl mediaSeeking; - HANDLE state_change, blocked; + HANDLE blocked; LONG volume; LONG pan; + + DWORD threadid; + HANDLE advisethread, thread_wait; } DSoundRenderImpl; -/* Seeking is not needed for a renderer, rely on newsegment for the appropriate changes */ -static HRESULT sound_mod_stop(IBaseFilter *iface) +static inline DSoundRenderImpl *impl_from_BaseRenderer(BaseRenderer *iface) { - TRACE("(%p)\n", iface); + return CONTAINING_RECORD(iface, DSoundRenderImpl, renderer); +} + +static inline DSoundRenderImpl *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, DSoundRenderImpl, renderer.filter.IBaseFilter_iface); +} + +static inline DSoundRenderImpl *impl_from_IBasicAudio(IBasicAudio *iface) +{ + return CONTAINING_RECORD(iface, DSoundRenderImpl, basicAudio.IBasicAudio_iface); +} + +static inline DSoundRenderImpl *impl_from_IReferenceClock(IReferenceClock *iface) +{ + return CONTAINING_RECORD(iface, DSoundRenderImpl, IReferenceClock_iface); +} + +static inline DSoundRenderImpl *impl_from_IAMDirectSound(IAMDirectSound *iface) +{ + return CONTAINING_RECORD(iface, DSoundRenderImpl, IAMDirectSound_iface); +} + +static inline DSoundRenderImpl *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) +{ + return CONTAINING_RECORD(iface, DSoundRenderImpl, IAMFilterMiscFlags_iface); +} + +static REFERENCE_TIME time_from_pos(DSoundRenderImpl *This, DWORD pos) { + WAVEFORMATEX *wfx = (WAVEFORMATEX*)This->renderer.pInputPin->pin.mtCurrent.pbFormat; + REFERENCE_TIME ret = 10000000; + ret = ret * pos / wfx->nAvgBytesPerSec; + return ret; +} + +static DWORD pos_from_time(DSoundRenderImpl *This, REFERENCE_TIME time) { + WAVEFORMATEX *wfx = (WAVEFORMATEX*)This->renderer.pInputPin->pin.mtCurrent.pbFormat; + REFERENCE_TIME ret = time; + ret *= wfx->nSamplesPerSec; + ret /= 10000000; + ret *= wfx->nBlockAlign; + return ret; +} + +static void DSoundRender_UpdatePositions(DSoundRenderImpl *This, DWORD *seqwritepos, DWORD *minwritepos) { + WAVEFORMATEX *wfx = (WAVEFORMATEX*)This->renderer.pInputPin->pin.mtCurrent.pbFormat; + BYTE *buf1, *buf2; + DWORD size1, size2, playpos, writepos, old_writepos, old_playpos, adv; + BOOL writepos_set = This->writepos < This->buf_size; + + /* Update position and zero */ + old_writepos = This->writepos; + old_playpos = This->last_playpos; + if (old_writepos <= old_playpos) + old_writepos += This->buf_size; + + IDirectSoundBuffer_GetCurrentPosition(This->dsbuffer, &playpos, &writepos); + if (old_playpos > playpos) { + adv = This->buf_size + playpos - old_playpos; + This->play_time += time_from_pos(This, This->buf_size); + } else + adv = playpos - old_playpos; + This->last_playpos = playpos; + if (adv) { + TRACE("Moving from %u to %u: clearing %u bytes\n", old_playpos, playpos, adv); + IDirectSoundBuffer_Lock(This->dsbuffer, old_playpos, adv, (void**)&buf1, &size1, (void**)&buf2, &size2, 0); + memset(buf1, wfx->wBitsPerSample == 8 ? 128 : 0, size1); + memset(buf2, wfx->wBitsPerSample == 8 ? 128 : 0, size2); + IDirectSoundBuffer_Unlock(This->dsbuffer, buf1, size1, buf2, size2); + } + *minwritepos = writepos; + if (!writepos_set || old_writepos < writepos) { + if (writepos_set) { + This->writepos = This->buf_size; + FIXME("Underrun of data occurred!\n"); + } + *seqwritepos = writepos; + } else + *seqwritepos = This->writepos; +} + +static HRESULT DSoundRender_GetWritePos(DSoundRenderImpl *This, DWORD *ret_writepos, REFERENCE_TIME write_at, DWORD *pfree, DWORD *skip) +{ + WAVEFORMATEX *wfx = (WAVEFORMATEX*)This->renderer.pInputPin->pin.mtCurrent.pbFormat; + DWORD writepos, min_writepos, playpos; + REFERENCE_TIME max_lag = 50 * 10000; + REFERENCE_TIME min_lag = 25 * 10000; + REFERENCE_TIME cur, writepos_t, delta_t; + + DSoundRender_UpdatePositions(This, &writepos, &min_writepos); + playpos = This->last_playpos; + if (This->renderer.filter.pClock == &This->IReferenceClock_iface) { + max_lag = min_lag; + cur = This->play_time + time_from_pos(This, playpos); + cur -= This->renderer.filter.rtStreamStart; + } else if (This->renderer.filter.pClock) { + IReferenceClock_GetTime(This->renderer.filter.pClock, &cur); + cur -= This->renderer.filter.rtStreamStart; + } else + write_at = -1; + + if (writepos == min_writepos) + max_lag = 0; + + *skip = 0; + if (write_at < 0) { + *ret_writepos = writepos; + goto end; + } + + if (writepos >= playpos) + writepos_t = cur + time_from_pos(This, writepos - playpos); + else + writepos_t = cur + time_from_pos(This, This->buf_size + writepos - playpos); + + /* write_at: Starting time of sample */ + /* cur: current time of play position */ + /* writepos_t: current time of our pointer play position */ + delta_t = write_at - writepos_t; + if (delta_t >= -max_lag && delta_t <= max_lag) { + TRACE("Continuing from old position\n"); + *ret_writepos = writepos; + } else if (delta_t < 0) { + REFERENCE_TIME past, min_writepos_t; + WARN("Delta too big %i/%i, overwriting old data or even skipping\n", (int)delta_t / 10000, (int)max_lag / 10000); + if (min_writepos >= playpos) + min_writepos_t = cur + time_from_pos(This, min_writepos - playpos); + else + min_writepos_t = cur + time_from_pos(This, This->buf_size - playpos + min_writepos); + past = min_writepos_t - write_at; + if (past >= 0) { + DWORD skipbytes = pos_from_time(This, past); + WARN("Skipping %u bytes\n", skipbytes); + *skip = skipbytes; + *ret_writepos = min_writepos; + } else { + DWORD aheadbytes = pos_from_time(This, -past); + WARN("Advancing %u bytes\n", aheadbytes); + *ret_writepos = (min_writepos + aheadbytes) % This->buf_size; + } + } else /* delta_t > 0 */ { + DWORD aheadbytes; + WARN("Delta too big %i/%i, too far ahead\n", (int)delta_t / 10000, (int)max_lag / 10000); + aheadbytes = pos_from_time(This, delta_t); + WARN("Advancing %u bytes\n", aheadbytes); + if (delta_t >= DSoundRenderer_Max_Fill) + return S_FALSE; + *ret_writepos = (min_writepos + aheadbytes) % This->buf_size; + } +end: + if (playpos > *ret_writepos) + *pfree = playpos - *ret_writepos; + else if (playpos == *ret_writepos) + *pfree = This->buf_size - wfx->nBlockAlign; + else + *pfree = This->buf_size + playpos - *ret_writepos; + if (time_from_pos(This, This->buf_size - *pfree) >= DSoundRenderer_Max_Fill) { + TRACE("Blocked: too full %i / %i\n", (int)(time_from_pos(This, This->buf_size - *pfree)/10000), (int)(DSoundRenderer_Max_Fill / 10000)); + return S_FALSE; + } return S_OK; } -static HRESULT sound_mod_start(IBaseFilter *iface) +static HRESULT DSoundRender_HandleEndOfStream(DSoundRenderImpl *This) { - TRACE("(%p)\n", iface); + while (1) + { + DWORD pos1, pos2; + DSoundRender_UpdatePositions(This, &pos1, &pos2); + if (pos1 == pos2) + break; + + This->in_loop = 1; + LeaveCriticalSection(&This->renderer.filter.csFilter); + LeaveCriticalSection(&This->renderer.csRenderLock); + WaitForSingleObject(This->blocked, 10); + EnterCriticalSection(&This->renderer.filter.csFilter); + EnterCriticalSection(&This->renderer.csRenderLock); + This->in_loop = 0; + } return S_OK; } -static HRESULT sound_mod_rate(IBaseFilter *iface) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - WAVEFORMATEX *format = (WAVEFORMATEX*)This->pInputPin->pin.mtCurrent.pbFormat; - DWORD freq = format->nSamplesPerSec; - double rate = This->mediaSeeking.dRate; - - freq = (DWORD)((double)freq * rate); - - TRACE("(%p)\n", iface); - - if (freq > DSBFREQUENCY_MAX) - return VFW_E_UNSUPPORTED_AUDIO; - - if (freq < DSBFREQUENCY_MIN) - return VFW_E_UNSUPPORTED_AUDIO; - - return S_OK; -} - -static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPos, REFERENCE_TIME *pRefTime) +static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, REFERENCE_TIME tStart, REFERENCE_TIME tStop, const BYTE *data, DWORD size) { HRESULT hr; - EnterCriticalSection(&This->csFilter); - { - DWORD state; - DWORD write_pos; + while (size && This->renderer.filter.state != State_Stopped) { + DWORD writepos, skip = 0, free, size1, size2, ret; + BYTE *buf1, *buf2; - hr = IDirectSoundBuffer_GetStatus(This->dsbuffer, &state); - if (SUCCEEDED(hr) && !(state & DSBSTATUS_PLAYING) && This->state == State_Running) - { - TRACE("Not playing, kickstarting the engine\n"); - - hr = IDirectSoundBuffer_Play(This->dsbuffer, 0, 0, DSBPLAY_LOOPING); - if (FAILED(hr)) - ERR("Can't play sound buffer (%x)\n", hr); - } - - if (SUCCEEDED(hr)) - hr = IDirectSoundBuffer_GetCurrentPosition(This->dsbuffer, pPlayPos, &write_pos); - if (hr == S_OK) - { - DWORD play_pos = *pPlayPos; - - if (play_pos < This->last_play_pos) - This->play_loops++; - This->last_play_pos = play_pos; - - /* If we really fell behind, start at the next possible position - * Also happens when just starting playback for the first time, - * or when flushing - */ - if ((This->play_loops*This->buf_size)+play_pos >= - (This->write_loops*This->buf_size)+This->write_pos) - This->write_pos = write_pos; - - if (pRefTime) - { - REFERENCE_TIME play_time; - play_time = ((REFERENCE_TIME)This->play_loops*10000000) + - ((REFERENCE_TIME)play_pos*10000000/This->buf_size); - - /* Don't let time run backwards */ - if(play_time-This->play_time > 0) - This->play_time = play_time; - else - hr = S_FALSE; - - *pRefTime = This->play_time; - } - } - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *data, DWORD size) -{ - HRESULT hr = S_OK; - LPBYTE lpbuf1 = NULL; - LPBYTE lpbuf2 = NULL; - DWORD dwsize1 = 0; - DWORD dwsize2 = 0; - DWORD size2; - DWORD play_pos,buf_free; - - do { - - hr = DSoundRender_GetPos(This, &play_pos, NULL); - if (hr != DS_OK) - { - ERR("GetPos returned error: %x\n", hr); - break; - } - if (This->write_pos <= play_pos) - buf_free = play_pos-This->write_pos; + if (This->renderer.filter.state == State_Running) + hr = DSoundRender_GetWritePos(This, &writepos, tStart, &free, &skip); else - buf_free = This->buf_size - This->write_pos + play_pos; + hr = S_FALSE; - /* Wait for enough of the buffer to empty before filling it */ - if(buf_free < This->buf_size/4) - { - Sleep(50); + if (hr != S_OK) { + This->in_loop = 1; + LeaveCriticalSection(&This->renderer.csRenderLock); + ret = WaitForSingleObject(This->blocked, 10); + EnterCriticalSection(&This->renderer.csRenderLock); + This->in_loop = 0; + if (This->renderer.pInputPin->flushing || + This->renderer.filter.state == State_Stopped) { + return This->renderer.filter.state == State_Paused ? S_OK : VFW_E_WRONG_STATE; + } + if (ret != WAIT_TIMEOUT) + ERR("%x\n", ret); continue; } + tStart = -1; - size2 = min(buf_free, size); - hr = IDirectSoundBuffer_Lock(This->dsbuffer, This->write_pos, size2, (LPVOID *)&lpbuf1, &dwsize1, (LPVOID *)&lpbuf2, &dwsize2, 0); + if (skip) + FIXME("Sample dropped %u of %u bytes\n", skip, size); + if (skip >= size) + return S_OK; + data += skip; + size -= skip; + + hr = IDirectSoundBuffer_Lock(This->dsbuffer, writepos, min(free, size), (void**)&buf1, &size1, (void**)&buf2, &size2, 0); if (hr != DS_OK) { ERR("Unable to lock sound buffer! (%x)\n", hr); break; } - /* TRACE("write_pos=%d, size=%d, sz1=%d, sz2=%d\n", This->write_pos, size2, dwsize1, dwsize2); */ - - memcpy(lpbuf1, data, dwsize1); - if (dwsize2) - memcpy(lpbuf2, data + dwsize1, dwsize2); - - hr = IDirectSoundBuffer_Unlock(This->dsbuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); - if (hr != DS_OK) - ERR("Unable to unlock sound buffer! (%x)\n", hr); - - size -= dwsize1 + dwsize2; - data += dwsize1 + dwsize2; - This->write_pos += dwsize1 + dwsize2; - if (This->write_pos >= This->buf_size) - { - This->write_pos -= This->buf_size; - This->write_loops++; - } - } while (size && This->state == State_Running); - - return hr; + memcpy(buf1, data, size1); + if (size2) + memcpy(buf2, data+size1, size2); + IDirectSoundBuffer_Unlock(This->dsbuffer, buf1, size1, buf2, size2); + This->writepos = (writepos + size1 + size2) % This->buf_size; + TRACE("Wrote %u bytes at %u, next at %u - (%u/%u)\n", size1+size2, writepos, This->writepos, free, size); + data += size1 + size2; + size -= size1 + size2; + } + return S_OK; } -static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) +static HRESULT WINAPI DSoundRender_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pMediaSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime) { - DSoundRenderImpl *This = iface; - LPBYTE pbSrcStream = NULL; - LONG cbSrcStream = 0; - REFERENCE_TIME tStart, tStop; + /* We time ourselves do not use the base renderers timing */ + return S_OK; +} + + +static HRESULT WINAPI DSoundRender_PrepareReceive(BaseRenderer *iface, IMediaSample *pSample) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); HRESULT hr; AM_MEDIA_TYPE *amt; - TRACE("%p %p\n", iface, pSample); - - /* Slightly incorrect, Pause completes when a frame is received so we should signal - * pause completion here, but for sound playing a single frame doesn't make sense - */ - - EnterCriticalSection(&This->csFilter); - - if (This->pInputPin->end_of_stream || This->pInputPin->flushing) - { - LeaveCriticalSection(&This->csFilter); - return S_FALSE; - } - - if (This->state == State_Stopped) - { - LeaveCriticalSection(&This->csFilter); - return VFW_E_WRONG_STATE; - } - if (IMediaSample_GetMediaType(pSample, &amt) == S_OK) { - AM_MEDIA_TYPE *orig = &This->pInputPin->pin.mtCurrent; + AM_MEDIA_TYPE *orig = &This->renderer.pInputPin->pin.mtCurrent; WAVEFORMATEX *origfmt = (WAVEFORMATEX *)orig->pbFormat; WAVEFORMATEX *newfmt = (WAVEFORMATEX *)amt->pbFormat; @@ -280,91 +345,76 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) hr = IDirectSoundBuffer_SetFrequency(This->dsbuffer, newfmt->nSamplesPerSec); if (FAILED(hr)) - { - LeaveCriticalSection(&This->csFilter); return VFW_E_TYPE_NOT_ACCEPTED; - } FreeMediaType(orig); CopyMediaType(orig, amt); IMediaSample_SetMediaType(pSample, NULL); } } else - { - LeaveCriticalSection(&This->csFilter); return VFW_E_TYPE_NOT_ACCEPTED; - } } + return S_OK; +} - SetEvent(This->state_change); +static HRESULT WINAPI DSoundRender_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + LPBYTE pbSrcStream = NULL; + LONG cbSrcStream = 0; + REFERENCE_TIME tStart, tStop; + HRESULT hr; + + TRACE("%p %p\n", iface, pSample); + + /* Slightly incorrect, Pause completes when a frame is received so we should signal + * pause completion here, but for sound playing a single frame doesn't make sense + */ hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); - LeaveCriticalSection(&This->csFilter); return hr; } hr = IMediaSample_GetTime(pSample, &tStart, &tStop); - if (FAILED(hr)) + if (FAILED(hr)) { ERR("Cannot get sample time (%x)\n", hr); + tStart = tStop = -1; + } - if (This->rtLastStop != tStart && (IMediaSample_IsDiscontinuity(pSample) == S_FALSE)) - WARN("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n", - (DWORD)(This->rtLastStop / 10000000), (DWORD)((This->rtLastStop / 10000)%1000), - (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000)); - This->rtLastStop = tStop; + IMediaSample_IsDiscontinuity(pSample); if (IMediaSample_IsPreroll(pSample) == S_OK) { TRACE("Preroll!\n"); - LeaveCriticalSection(&This->csFilter); return S_OK; } - if (This->state == State_Paused) - { - LeaveCriticalSection(&This->csFilter); - WaitForSingleObject(This->blocked, INFINITE); - EnterCriticalSection(&This->csFilter); - if (This->state == State_Stopped) - { - LeaveCriticalSection(&This->csFilter); - return VFW_E_WRONG_STATE; - } - - if (This->state == State_Paused) - { - /* Assuming we return because of flushing */ - TRACE("Flushing\n"); - LeaveCriticalSection(&This->csFilter); - return S_OK; - } - } - cbSrcStream = IMediaSample_GetActualDataLength(pSample); TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); -#if 0 /* For debugging purpose */ - { - int i; - for(i = 0; i < cbSrcStream; i++) - { - if ((i!=0) && !(i%16)) - TRACE("\n"); - TRACE("%02x ", pbSrcStream[i]); - } - TRACE("\n"); + hr = DSoundRender_SendSampleData(This, tStart, tStop, pbSrcStream, cbSrcStream); + if (This->renderer.filter.state == State_Running && This->renderer.filter.pClock && tStart >= 0) { + REFERENCE_TIME jitter, now = 0; + Quality q; + IReferenceClock_GetTime(This->renderer.filter.pClock, &now); + jitter = now - This->renderer.filter.rtStreamStart - tStart; + if (jitter <= -DSoundRenderer_Max_Fill) + jitter += DSoundRenderer_Max_Fill; + else if (jitter < 0) + jitter = 0; + q.Type = (jitter > 0 ? Famine : Flood); + q.Proportion = 1.; + q.Late = jitter; + q.TimeStamp = tStart; + IQualityControl_Notify((IQualityControl *)This->renderer.qcimpl, (IBaseFilter*)This, q); } -#endif - - hr = DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream); - LeaveCriticalSection(&This->csFilter); return hr; } -static HRESULT DSoundRender_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI DSoundRender_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) { WAVEFORMATEX* format; @@ -386,10 +436,189 @@ static HRESULT DSoundRender_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) return S_OK; } +static VOID WINAPI DSoundRender_OnStopStreaming(BaseRenderer * iface) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + IDirectSoundBuffer_Stop(This->dsbuffer); + This->writepos = This->buf_size; + SetEvent(This->blocked); +} + +static VOID WINAPI DSoundRender_OnStartStreaming(BaseRenderer * iface) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + + TRACE("(%p)\n", This); + + if (This->renderer.pInputPin->pin.pConnectedTo) + { + if (This->renderer.filter.state == State_Paused) + { + /* Unblock our thread, state changing from paused to running doesn't need a reset for state change */ + SetEvent(This->blocked); + } + IDirectSoundBuffer_Play(This->dsbuffer, 0, 0, DSBPLAY_LOOPING); + ResetEvent(This->blocked); + } +} + +static HRESULT WINAPI DSoundRender_CompleteConnect(BaseRenderer * iface, IPin * pReceivePin) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + const AM_MEDIA_TYPE * pmt = &This->renderer.pInputPin->pin.mtCurrent; + HRESULT hr = S_OK; + WAVEFORMATEX *format; + DSBUFFERDESC buf_desc; + + TRACE("(%p)->(%p)\n", This, pReceivePin); + dump_AM_MEDIA_TYPE(pmt); + + TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype)); + TRACE("SubType %s\n", debugstr_guid(&pmt->subtype)); + TRACE("Format %s\n", debugstr_guid(&pmt->formattype)); + TRACE("Size %d\n", pmt->cbFormat); + + format = (WAVEFORMATEX*)pmt->pbFormat; + + This->buf_size = format->nAvgBytesPerSec; + + memset(&buf_desc,0,sizeof(DSBUFFERDESC)); + buf_desc.dwSize = sizeof(DSBUFFERDESC); + buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | + DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS | + DSBCAPS_GETCURRENTPOSITION2; + buf_desc.dwBufferBytes = This->buf_size; + buf_desc.lpwfxFormat = format; + hr = IDirectSound_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL); + This->writepos = This->buf_size; + if (FAILED(hr)) + ERR("Can't create sound buffer (%x)\n", hr); + + if (SUCCEEDED(hr)) + { + hr = IDirectSoundBuffer_SetVolume(This->dsbuffer, This->volume); + if (FAILED(hr)) + ERR("Can't set volume to %d (%x)\n", This->volume, hr); + + hr = IDirectSoundBuffer_SetPan(This->dsbuffer, This->pan); + if (FAILED(hr)) + ERR("Can't set pan to %d (%x)\n", This->pan, hr); + hr = S_OK; + } + + if (FAILED(hr) && hr != VFW_E_ALREADY_CONNECTED) + { + if (This->dsbuffer) + IDirectSoundBuffer_Release(This->dsbuffer); + This->dsbuffer = NULL; + } + + return hr; +} + +static HRESULT WINAPI DSoundRender_BreakConnect(BaseRenderer* iface) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + + TRACE("(%p)->()\n", iface); + + if (This->threadid) { + PostThreadMessageW(This->threadid, WM_APP, 0, 0); + LeaveCriticalSection(This->renderer.pInputPin->pin.pCritSec); + WaitForSingleObject(This->advisethread, INFINITE); + EnterCriticalSection(This->renderer.pInputPin->pin.pCritSec); + CloseHandle(This->advisethread); + } + if (This->dsbuffer) + IDirectSoundBuffer_Release(This->dsbuffer); + This->dsbuffer = NULL; + + return S_OK; +} + +static HRESULT WINAPI DSoundRender_EndOfStream(BaseRenderer* iface) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + HRESULT hr; + + TRACE("(%p)->()\n",iface); + + hr = BaseRendererImpl_EndOfStream(iface); + if (hr != S_OK) + { + ERR("%08x\n", hr); + return hr; + } + + hr = DSoundRender_HandleEndOfStream(This); + + return hr; +} + +static HRESULT WINAPI DSoundRender_BeginFlush(BaseRenderer* iface) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + + TRACE("\n"); + BaseRendererImpl_BeginFlush(iface); + SetEvent(This->blocked); + + return S_OK; +} + +static HRESULT WINAPI DSoundRender_EndFlush(BaseRenderer* iface) +{ + DSoundRenderImpl *This = impl_from_BaseRenderer(iface); + + TRACE("\n"); + + BaseRendererImpl_EndFlush(iface); + if (This->renderer.filter.state != State_Stopped) + ResetEvent(This->blocked); + + if (This->dsbuffer) + { + LPBYTE buffer; + DWORD size; + + /* Force a reset */ + IDirectSoundBuffer_Lock(This->dsbuffer, 0, 0, (LPVOID *)&buffer, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER); + memset(buffer, 0, size); + IDirectSoundBuffer_Unlock(This->dsbuffer, buffer, size, NULL, 0); + This->writepos = This->buf_size; + } + + return S_OK; +} + +static const BaseRendererFuncTable BaseFuncTable = { + DSoundRender_CheckMediaType, + DSoundRender_DoRenderSample, + /**/ + NULL, + NULL, + NULL, + DSoundRender_OnStartStreaming, + DSoundRender_OnStopStreaming, + NULL, + NULL, + NULL, + DSoundRender_ShouldDrawSampleNow, + DSoundRender_PrepareReceive, + /**/ + DSoundRender_CompleteConnect, + DSoundRender_BreakConnect, + DSoundRender_EndOfStream, + DSoundRender_BeginFlush, + DSoundRender_EndFlush, +}; + HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) { HRESULT hr; - PIN_INFO piInput; DSoundRenderImpl * pDSoundRender; TRACE("(%p, %p)\n", pUnkOuter, ppv); @@ -398,26 +627,18 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) if (pUnkOuter) return CLASS_E_NOAGGREGATION; - + pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl)); if (!pDSoundRender) return E_OUTOFMEMORY; ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl)); - pDSoundRender->lpVtbl = &DSoundRender_Vtbl; - pDSoundRender->IBasicAudio_vtbl = &IBasicAudio_Vtbl; - pDSoundRender->IReferenceClock_vtbl = &IReferenceClock_Vtbl; - pDSoundRender->IAMDirectSound_vtbl = &IAMDirectSound_Vtbl; - pDSoundRender->refCount = 1; - InitializeCriticalSection(&pDSoundRender->csFilter); - pDSoundRender->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"); - pDSoundRender->state = State_Stopped; + hr = BaseRenderer_Init(&pDSoundRender->renderer, &DSoundRender_Vtbl, (IUnknown*)pDSoundRender, &CLSID_DSoundRender, (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"), &BaseFuncTable); - /* construct input pin */ - piInput.dir = PINDIR_INPUT; - piInput.pFilter = (IBaseFilter *)pDSoundRender; - lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); - hr = InputPin_Construct(&DSoundRender_InputPin_Vtbl, &piInput, DSoundRender_Sample, pDSoundRender, DSoundRender_QueryAccept, NULL, &pDSoundRender->csFilter, NULL, (IPin **)&pDSoundRender->pInputPin); + BasicAudio_Init(&pDSoundRender->basicAudio,&IBasicAudio_Vtbl); + pDSoundRender->IReferenceClock_iface.lpVtbl = &IReferenceClock_Vtbl; + pDSoundRender->IAMDirectSound_iface.lpVtbl = &IAMDirectSound_Vtbl; + pDSoundRender->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl; if (SUCCEEDED(hr)) { @@ -425,18 +646,27 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) if (FAILED(hr)) ERR("Cannot create Direct Sound object (%x)\n", hr); else - IDirectSound_SetCooperativeLevel(pDSoundRender->dsound, GetDesktopWindow(), DSSCL_PRIORITY); + hr = IDirectSound_SetCooperativeLevel(pDSoundRender->dsound, GetDesktopWindow(), DSSCL_PRIORITY); + if (SUCCEEDED(hr)) { + IDirectSoundBuffer *buf; + DSBUFFERDESC buf_desc; + memset(&buf_desc,0,sizeof(DSBUFFERDESC)); + buf_desc.dwSize = sizeof(DSBUFFERDESC); + buf_desc.dwFlags = DSBCAPS_PRIMARYBUFFER; + hr = IDirectSound_CreateSoundBuffer(pDSoundRender->dsound, &buf_desc, &buf, NULL); + if (SUCCEEDED(hr)) { + IDirectSoundBuffer_Play(buf, 0, 0, DSBPLAY_LOOPING); + IDirectSoundBuffer_Release(buf); + } + hr = S_OK; + } } if (SUCCEEDED(hr)) { - MediaSeekingImpl_Init((IBaseFilter*)pDSoundRender, sound_mod_stop, sound_mod_start, sound_mod_rate, &pDSoundRender->mediaSeeking, &pDSoundRender->csFilter); - pDSoundRender->mediaSeeking.lpVtbl = &IMediaSeeking_Vtbl; + pDSoundRender->blocked = CreateEventW(NULL, TRUE, TRUE, NULL); - pDSoundRender->state_change = CreateEventW(NULL, TRUE, TRUE, NULL); - pDSoundRender->blocked = CreateEventW(NULL, FALSE, FALSE, NULL); - - if (!pDSoundRender->state_change || !pDSoundRender->blocked) + if (!pDSoundRender->blocked || FAILED(hr)) { IUnknown_Release((IUnknown *)pDSoundRender); return HRESULT_FROM_WIN32(GetLastError()); @@ -446,10 +676,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) } else { - if (pDSoundRender->pInputPin) - IPin_Release((IPin*)pDSoundRender->pInputPin); - pDSoundRender->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&pDSoundRender->csFilter); + BaseRendererImpl_Release(&pDSoundRender->renderer.filter.IBaseFilter_iface); CoTaskMemFree(pDSoundRender); } @@ -458,27 +685,26 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) { - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; + DSoundRenderImpl *This = impl_from_IBaseFilter(iface); TRACE("(%p, %p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); *ppv = NULL; - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IPersist)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IBaseFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IBasicAudio)) - *ppv = &This->IBasicAudio_vtbl; + if (IsEqualIID(riid, &IID_IBasicAudio)) + *ppv = &This->basicAudio.IBasicAudio_iface; else if (IsEqualIID(riid, &IID_IReferenceClock)) - *ppv = &This->IReferenceClock_vtbl; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &This->mediaSeeking.lpVtbl; + *ppv = &This->IReferenceClock_iface; else if (IsEqualIID(riid, &IID_IAMDirectSound)) - *ppv = &This->IAMDirectSound_vtbl; + *ppv = &This->IAMDirectSound_iface; + else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) + *ppv = &This->IAMFilterMiscFlags_iface; + else + { + HRESULT hr; + hr = BaseRendererImpl_QueryInterface(iface, riid, ppv); + if (SUCCEEDED(hr)) + return hr; + } if (*ppv) { @@ -492,29 +718,20 @@ static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID ri return E_NOINTERFACE; } -static ULONG WINAPI DSoundRender_AddRef(IBaseFilter * iface) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); - - return refCount; -} - static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface) { - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); + DSoundRenderImpl *This = impl_from_IBaseFilter(iface); + ULONG refCount = BaseRendererImpl_Release(iface); TRACE("(%p)->() Release from %d\n", This, refCount + 1); if (!refCount) { - IPin *pConnectedTo; - - if (This->pClock) - IReferenceClock_Release(This->pClock); + if (This->threadid) { + PostThreadMessageW(This->threadid, WM_APP, 0, 0); + WaitForSingleObject(This->advisethread, INFINITE); + CloseHandle(This->advisethread); + } if (This->dsbuffer) IDirectSoundBuffer_Release(This->dsbuffer); @@ -522,599 +739,99 @@ static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface) if (This->dsound) IDirectSound_Release(This->dsound); This->dsound = NULL; - - if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo))) - { - IPin_Disconnect(pConnectedTo); - IPin_Release(pConnectedTo); - } - IPin_Disconnect((IPin *)This->pInputPin); - IPin_Release((IPin *)This->pInputPin); - - This->lpVtbl = NULL; - This->IBasicAudio_vtbl = NULL; - - This->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csFilter); - - CloseHandle(This->state_change); + BasicAudio_Destroy(&This->basicAudio); CloseHandle(This->blocked); TRACE("Destroying Audio Renderer\n"); CoTaskMemFree(This); - + return 0; } else return refCount; } -/** IPersist methods **/ - -static HRESULT WINAPI DSoundRender_GetClassID(IBaseFilter * iface, CLSID * pClsid) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, pClsid); - - *pClsid = CLSID_DSoundRender; - - return S_OK; -} - -/** IMediaFilter methods **/ - -static HRESULT WINAPI DSoundRender_Stop(IBaseFilter * iface) -{ - HRESULT hr = S_OK; - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(&This->csFilter); - { - DWORD state = 0; - if (This->dsbuffer) - { - hr = IDirectSoundBuffer_GetStatus(This->dsbuffer, &state); - if (SUCCEEDED(hr)) - { - if (state & DSBSTATUS_PLAYING) - hr = IDirectSoundBuffer_Stop(This->dsbuffer); - } - } - if (SUCCEEDED(hr)) - This->state = State_Stopped; - - /* Complete our transition */ - SetEvent(This->state_change); - SetEvent(This->blocked); - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface) { HRESULT hr = S_OK; DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - + TRACE("(%p/%p)->()\n", This, iface); - EnterCriticalSection(&This->csFilter); - if (This->state != State_Paused) + EnterCriticalSection(&This->renderer.csRenderLock); + if (This->renderer.filter.state != State_Paused) { - DWORD state = 0; - if (This->state == State_Stopped) + if (This->renderer.filter.state == State_Stopped) { - This->pInputPin->end_of_stream = 0; + if (This->renderer.pInputPin->pin.pConnectedTo) + ResetEvent(This->renderer.evComplete); + This->renderer.pInputPin->end_of_stream = 0; } - if (This->dsbuffer) - { - hr = IDirectSoundBuffer_GetStatus(This->dsbuffer, &state); - if (SUCCEEDED(hr)) - { - if (state & DSBSTATUS_PLAYING) - hr = IDirectSoundBuffer_Stop(This->dsbuffer); - } - } + hr = IDirectSoundBuffer_Stop(This->dsbuffer); if (SUCCEEDED(hr)) - This->state = State_Paused; + This->renderer.filter.state = State_Paused; ResetEvent(This->blocked); - ResetEvent(This->state_change); + ResetEvent(This->renderer.RenderEvent); } - LeaveCriticalSection(&This->csFilter); + ResetEvent(This->renderer.ThreadSignal); + LeaveCriticalSection(&This->renderer.csRenderLock); return hr; } -static HRESULT WINAPI DSoundRender_Run(IBaseFilter * iface, REFERENCE_TIME tStart) -{ - HRESULT hr = S_OK; - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); - - EnterCriticalSection(&This->csFilter); - { - This->rtStreamStart = tStart; - if (This->state == State_Paused) - { - /* Unblock our thread, state changing from paused to running doesn't need a reset for state change */ - SetEvent(This->blocked); - } - else if (This->state == State_Stopped) - { - ResetEvent(This->state_change); - This->pInputPin->end_of_stream = 0; - } - - This->state = State_Running; - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI DSoundRender_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - HRESULT hr; - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState); - - if (WaitForSingleObject(This->state_change, dwMilliSecsTimeout) == WAIT_TIMEOUT) - hr = VFW_S_STATE_INTERMEDIATE; - else - hr = S_OK; - - EnterCriticalSection(&This->csFilter); - { - *pState = This->state; - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI DSoundRender_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClock); - - EnterCriticalSection(&This->csFilter); - { - if (This->pClock) - IReferenceClock_Release(This->pClock); - This->pClock = pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI DSoundRender_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppClock); - - EnterCriticalSection(&This->csFilter); - { - *ppClock = This->pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -/** IBaseFilter implementation **/ - -static HRESULT DSoundRender_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - /* Our pins are static, not changing so setting static tick count is ok */ - *lastsynctick = 0; - - if (pos >= 1) - return S_FALSE; - - *pin = (IPin *)This->pInputPin; - IPin_AddRef(*pin); - return S_OK; -} - -static HRESULT WINAPI DSoundRender_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return IEnumPinsImpl_Construct(ppEnum, DSoundRender_GetPin, iface); -} - -static HRESULT WINAPI DSoundRender_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_w(Id), ppPin); - - FIXME("DSoundRender::FindPin(...)\n"); - - /* FIXME: critical section */ - - return E_NOTIMPL; -} - -static HRESULT WINAPI DSoundRender_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); - - strcpyW(pInfo->achName, This->filterInfo.achName); - pInfo->pGraph = This->filterInfo.pGraph; - - if (pInfo->pGraph) - IFilterGraph_AddRef(pInfo->pGraph); - - return S_OK; -} - -static HRESULT WINAPI DSoundRender_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - - TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName)); - - EnterCriticalSection(&This->csFilter); - { - if (pName) - strcpyW(This->filterInfo.achName, pName); - else - *This->filterInfo.achName = '\0'; - This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI DSoundRender_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) -{ - DSoundRenderImpl *This = (DSoundRenderImpl *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo); - return E_NOTIMPL; -} - static const IBaseFilterVtbl DSoundRender_Vtbl = { DSoundRender_QueryInterface, - DSoundRender_AddRef, + BaseFilterImpl_AddRef, DSoundRender_Release, - DSoundRender_GetClassID, - DSoundRender_Stop, + BaseFilterImpl_GetClassID, + BaseRendererImpl_Stop, DSoundRender_Pause, - DSoundRender_Run, - DSoundRender_GetState, - DSoundRender_SetSyncSource, - DSoundRender_GetSyncSource, - DSoundRender_EnumPins, - DSoundRender_FindPin, - DSoundRender_QueryFilterInfo, - DSoundRender_JoinFilterGraph, - DSoundRender_QueryVendorInfo -}; - -static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - InputPin *This = (InputPin *)iface; - PIN_DIRECTION pindirReceive; - DSoundRenderImpl *DSImpl; - HRESULT hr = S_OK; - - TRACE("(%p)->(%p, %p)\n", This, pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - EnterCriticalSection(This->pin.pCritSec); - { - DSImpl = (DSoundRenderImpl*)This->pin.pinInfo.pFilter; - DSImpl->rtLastStop = -1; - - if (This->pin.pConnectedTo) - hr = VFW_E_ALREADY_CONNECTED; - - if (SUCCEEDED(hr) && This->pin.fnQueryAccept(This->pin.pUserData, pmt) != S_OK) - hr = VFW_E_TYPE_NOT_ACCEPTED; - - if (SUCCEEDED(hr)) - { - IPin_QueryDirection(pReceivePin, &pindirReceive); - - if (pindirReceive != PINDIR_OUTPUT) - { - ERR("Can't connect from non-output pin\n"); - hr = VFW_E_INVALID_DIRECTION; - } - } - - if (SUCCEEDED(hr)) - { - WAVEFORMATEX *format; - DSBUFFERDESC buf_desc; - - TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype)); - TRACE("SubType %s\n", debugstr_guid(&pmt->subtype)); - TRACE("Format %s\n", debugstr_guid(&pmt->formattype)); - TRACE("Size %d\n", pmt->cbFormat); - - format = (WAVEFORMATEX*)pmt->pbFormat; - - DSImpl->buf_size = format->nAvgBytesPerSec; - - memset(&buf_desc,0,sizeof(DSBUFFERDESC)); - buf_desc.dwSize = sizeof(DSBUFFERDESC); - buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | - DSBCAPS_CTRLFREQUENCY | - DSBCAPS_GETCURRENTPOSITION2; - buf_desc.dwBufferBytes = DSImpl->buf_size; - buf_desc.lpwfxFormat = format; - hr = IDirectSound_CreateSoundBuffer(DSImpl->dsound, &buf_desc, &DSImpl->dsbuffer, NULL); - if (FAILED(hr)) - ERR("Can't create sound buffer (%x)\n", hr); - } - - if (SUCCEEDED(hr)) - { - hr = IDirectSoundBuffer_SetVolume(DSImpl->dsbuffer, DSImpl->volume); - if (FAILED(hr)) - ERR("Can't set volume to %d (%x)\n", DSImpl->volume, hr); - - hr = IDirectSoundBuffer_SetPan(DSImpl->dsbuffer, DSImpl->pan); - if (FAILED(hr)) - ERR("Can't set pan to %d (%x)\n", DSImpl->pan, hr); - - DSImpl->write_pos = 0; - hr = S_OK; - } - - if (SUCCEEDED(hr)) - { - CopyMediaType(&This->pin.mtCurrent, pmt); - This->pin.pConnectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - } - else if (hr != VFW_E_ALREADY_CONNECTED) - { - if (DSImpl->dsbuffer) - IDirectSoundBuffer_Release(DSImpl->dsbuffer); - DSImpl->dsbuffer = NULL; - } - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static HRESULT WINAPI DSoundRender_InputPin_Disconnect(IPin * iface) -{ - IPinImpl *This = (IPinImpl*)iface; - DSoundRenderImpl *DSImpl; - - TRACE("(%p)->()\n", iface); - - DSImpl = (DSoundRenderImpl*)This->pinInfo.pFilter; - if (DSImpl->dsbuffer) - IDirectSoundBuffer_Release(DSImpl->dsbuffer); - DSImpl->dsbuffer = NULL; - - return IPinImpl_Disconnect(iface); -} - -static HRESULT WINAPI DSoundRender_InputPin_EndOfStream(IPin * iface) -{ - InputPin* This = (InputPin*)iface; - DSoundRenderImpl *me = (DSoundRenderImpl*)This->pin.pinInfo.pFilter; - IMediaEventSink* pEventSink; - HRESULT hr; - - EnterCriticalSection(This->pin.pCritSec); - - TRACE("(%p/%p)->()\n", This, iface); - hr = InputPin_EndOfStream(iface); - if (hr != S_OK) - { - ERR("%08x\n", hr); - LeaveCriticalSection(This->pin.pCritSec); - return hr; - } - - hr = IFilterGraph_QueryInterface(me->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); - if (SUCCEEDED(hr)) - { - BYTE * silence; - - silence = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, me->buf_size); - if (silence) - { - memset(silence, 0, me->buf_size); - DSoundRender_SendSampleData((DSoundRenderImpl*)This->pin.pinInfo.pFilter, silence, me->buf_size); - HeapFree(GetProcessHeap(), 0, silence); - } - - hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0); - IMediaEventSink_Release(pEventSink); - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static HRESULT WINAPI DSoundRender_InputPin_BeginFlush(IPin * iface) -{ - InputPin *This = (InputPin *)iface; - DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; - HRESULT hr; - LPBYTE buffer; - DWORD size; - - TRACE("\n"); - - EnterCriticalSection(This->pin.pCritSec); - hr = InputPin_BeginFlush(iface); - - if (pFilter->dsbuffer) - { - IDirectSoundBuffer_Stop(pFilter->dsbuffer); - - /* Force a reset */ - IDirectSoundBuffer_SetCurrentPosition(pFilter->dsbuffer, 0); - pFilter->write_pos = pFilter->last_play_pos = 0; - ++pFilter->play_loops; - pFilter->write_loops = pFilter->play_loops; - - IDirectSoundBuffer_Lock(pFilter->dsbuffer, 0, 0, (LPVOID *)&buffer, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER); - memset(buffer, 0, size); - IDirectSoundBuffer_Unlock(pFilter->dsbuffer, buffer, size, NULL, 0); - } - - if (pFilter->state == State_Paused) - SetEvent(pFilter->blocked); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface) -{ - InputPin *This = (InputPin *)iface; - DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; - HRESULT hr; - - TRACE("\n"); - - EnterCriticalSection(This->pin.pCritSec); - hr = InputPin_EndFlush(iface); - - if (pFilter->state == State_Paused) - SetEvent(pFilter->blocked); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static const IPinVtbl DSoundRender_InputPin_Vtbl = -{ - InputPin_QueryInterface, - IPinImpl_AddRef, - InputPin_Release, - InputPin_Connect, - DSoundRender_InputPin_ReceiveConnection, - DSoundRender_InputPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - DSoundRender_InputPin_EndOfStream, - DSoundRender_InputPin_BeginFlush, - DSoundRender_InputPin_EndFlush, - InputPin_NewSegment + BaseRendererImpl_Run, + BaseRendererImpl_GetState, + BaseRendererImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + BaseRendererImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo }; /*** IUnknown methods ***/ static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface, REFIID riid, LPVOID*ppvObj) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return DSoundRender_QueryInterface((IBaseFilter*)This, riid, ppvObj); + return DSoundRender_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); } static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->()\n", This, iface); - return DSoundRender_AddRef((IBaseFilter*)This); + return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); } static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->()\n", This, iface); - return DSoundRender_Release((IBaseFilter*)This); -} - -/*** IDispatch methods ***/ -static HRESULT WINAPI Basicaudio_GetTypeInfoCount(IBasicAudio *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); - - TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); - - return S_OK; -} - -static HRESULT WINAPI Basicaudio_GetTypeInfo(IBasicAudio *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); - - TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); - - return S_OK; -} - -static HRESULT WINAPI Basicaudio_GetIDsOfNames(IBasicAudio *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); - - TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); - - return S_OK; -} - -static HRESULT WINAPI Basicaudio_Invoke(IBasicAudio *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); - - TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); - - return S_OK; + return DSoundRender_Release(&This->renderer.filter.IBaseFilter_iface); } /*** IBasicAudio methods ***/ static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface, LONG lVolume) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->(%d)\n", This, iface, lVolume); @@ -1132,7 +849,7 @@ static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface, static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface, LONG *plVolume) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->(%p)\n", This, iface, plVolume); @@ -1145,7 +862,7 @@ static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface, static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface, LONG lBalance) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->(%d)\n", This, iface, lBalance); @@ -1163,7 +880,7 @@ static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface, static HRESULT WINAPI Basicaudio_get_Balance(IBasicAudio *iface, LONG *plBalance) { - ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface); + DSoundRenderImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->(%p)\n", This, iface, plBalance); @@ -1179,61 +896,163 @@ static const IBasicAudioVtbl IBasicAudio_Vtbl = Basicaudio_QueryInterface, Basicaudio_AddRef, Basicaudio_Release, - Basicaudio_GetTypeInfoCount, - Basicaudio_GetTypeInfo, - Basicaudio_GetIDsOfNames, - Basicaudio_Invoke, + BasicAudioImpl_GetTypeInfoCount, + BasicAudioImpl_GetTypeInfo, + BasicAudioImpl_GetIDsOfNames, + BasicAudioImpl_Invoke, Basicaudio_put_Volume, Basicaudio_get_Volume, Basicaudio_put_Balance, Basicaudio_get_Balance }; +struct dsoundrender_timer { + struct dsoundrender_timer *next; + REFERENCE_TIME start; + REFERENCE_TIME periodicity; + HANDLE handle; + DWORD cookie; +}; +static LONG cookie_counter = 1; + +static DWORD WINAPI DSoundAdviseThread(LPVOID lpParam) { + DSoundRenderImpl *This = lpParam; + struct dsoundrender_timer head = {0}; + MSG msg; + + TRACE("(%p): Main Loop\n", This); + + PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + SetEvent(This->thread_wait); + + while (1) + { + HRESULT hr; + REFERENCE_TIME curtime = 0; + BOOL ret; + struct dsoundrender_timer *prev = &head, *cur; + + hr = IReferenceClock_GetTime(&This->IReferenceClock_iface, &curtime); + if (SUCCEEDED(hr)) { + TRACE("Time: %s\n", wine_dbgstr_longlong(curtime)); + while (prev->next) { + cur = prev->next; + if (cur->start > curtime) { + TRACE("Skipping %p\n", cur); + prev = cur; + } else if (cur->periodicity) { + while (cur->start <= curtime) { + cur->start += cur->periodicity; + ReleaseSemaphore(cur->handle, 1, NULL); + } + prev = cur; + } else { + struct dsoundrender_timer *next = cur->next; + TRACE("Firing %p %s < %s\n", cur, wine_dbgstr_longlong(cur->start), wine_dbgstr_longlong(curtime)); + SetEvent(cur->handle); + HeapFree(GetProcessHeap(), 0, cur); + prev->next = next; + } + } + } + if (!head.next) + ret = GetMessageW(&msg, INVALID_HANDLE_VALUE, WM_APP, WM_APP + 4); + else + ret = PeekMessageW(&msg, INVALID_HANDLE_VALUE, WM_APP, WM_APP + 4, PM_REMOVE); + while (ret) { + switch (LOWORD(msg.message) - WM_APP) { + case 0: TRACE("Exiting\n"); return 0; + case 1: + case 2: { + struct dsoundrender_timer *t = (struct dsoundrender_timer *)msg.wParam; + if (LOWORD(msg.message) - WM_APP == 1) + TRACE("Adding one-shot timer %p\n", t); + else + TRACE("Adding periodic timer %p\n", t); + t->next = head.next; + head.next = t; + break; + } + case 3: + prev = &head; + while (prev->next) { + cur = prev->next; + if (cur->cookie == msg.wParam) { + struct dsoundrender_timer *next = cur->next; + HeapFree(GetProcessHeap(), 0, cur); + prev->next = next; + break; + } + prev = cur; + } + break; + } + ret = PeekMessageW(&msg, INVALID_HANDLE_VALUE, WM_APP, WM_APP + 4, PM_REMOVE); + } + MsgWaitForMultipleObjects(0, NULL, 5, QS_POSTMESSAGE, 0); + } + return 0; +} /*** IUnknown methods ***/ static HRESULT WINAPI ReferenceClock_QueryInterface(IReferenceClock *iface, REFIID riid, LPVOID*ppvObj) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return DSoundRender_QueryInterface((IBaseFilter*)This, riid, ppvObj); + return DSoundRender_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); } static ULONG WINAPI ReferenceClock_AddRef(IReferenceClock *iface) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); TRACE("(%p/%p)->()\n", This, iface); - return DSoundRender_AddRef((IBaseFilter*)This); + return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); } static ULONG WINAPI ReferenceClock_Release(IReferenceClock *iface) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); TRACE("(%p/%p)->()\n", This, iface); - return DSoundRender_Release((IBaseFilter*)This); + return DSoundRender_Release(&This->renderer.filter.IBaseFilter_iface); } /*** IReferenceClock methods ***/ static HRESULT WINAPI ReferenceClock_GetTime(IReferenceClock *iface, REFERENCE_TIME *pTime) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); HRESULT hr = E_FAIL; - DWORD play_pos; TRACE("(%p/%p)->(%p)\n", This, iface, pTime); + if (!pTime) + return E_POINTER; - if (This->dsbuffer) - hr = DSoundRender_GetPos(This, &play_pos, pTime); + if (This->dsbuffer) { + DWORD writepos1, writepos2; + EnterCriticalSection(&This->renderer.filter.csFilter); + DSoundRender_UpdatePositions(This, &writepos1, &writepos2); + if (This->renderer.pInputPin && This->renderer.pInputPin->pin.mtCurrent.pbFormat) + { + *pTime = This->play_time + time_from_pos(This, This->last_playpos); + hr = S_OK; + } + else + { + ERR("pInputPin Disconncted\n"); + hr = E_FAIL; + } + LeaveCriticalSection(&This->renderer.filter.csFilter); + } if (FAILED(hr)) - ERR("Could not get reference time (%x)!\n", hr); + WARN("Could not get reference time (%x)!\n", hr); return hr; } @@ -1244,34 +1063,92 @@ static HRESULT WINAPI ReferenceClock_AdviseTime(IReferenceClock *iface, HEVENT hEvent, DWORD_PTR *pdwAdviseCookie) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); + REFERENCE_TIME when = rtBaseTime + rtStreamTime; + REFERENCE_TIME future; + TRACE("(%p/%p)->(%s, %s, %p, %p)\n", This, iface, wine_dbgstr_longlong(rtBaseTime), wine_dbgstr_longlong(rtStreamTime), (void*)hEvent, pdwAdviseCookie); - FIXME("(%p/%p)->(%s, %s, %p, %p): stub!\n", This, iface, wine_dbgstr_longlong(rtBaseTime), wine_dbgstr_longlong(rtStreamTime), (void*)hEvent, pdwAdviseCookie); + if (when <= 0) + return E_INVALIDARG; - return E_NOTIMPL; + if (!pdwAdviseCookie) + return E_POINTER; + + EnterCriticalSection(&This->renderer.filter.csFilter); + future = when - This->play_time; + if (!This->threadid && This->dsbuffer) { + This->thread_wait = CreateEventW(0, 0, 0, 0); + This->advisethread = CreateThread(NULL, 0, DSoundAdviseThread, This, 0, &This->threadid); + WaitForSingleObject(This->thread_wait, INFINITE); + CloseHandle(This->thread_wait); + } + LeaveCriticalSection(&This->renderer.filter.csFilter); + /* If it's in the past or the next millisecond, trigger immediately */ + if (future <= 10000) { + SetEvent((HANDLE)hEvent); + *pdwAdviseCookie = 0; + } else { + struct dsoundrender_timer *t = HeapAlloc(GetProcessHeap(), 0, sizeof(*t)); + t->next = NULL; + t->start = when; + t->periodicity = 0; + t->handle = (HANDLE)hEvent; + t->cookie = InterlockedIncrement(&cookie_counter); + PostThreadMessageW(This->threadid, WM_APP+1, (WPARAM)t, 0); + *pdwAdviseCookie = t->cookie; + } + + return S_OK; } static HRESULT WINAPI ReferenceClock_AdvisePeriodic(IReferenceClock *iface, - REFERENCE_TIME rtBaseTime, - REFERENCE_TIME rtStreamTime, + REFERENCE_TIME rtStartTime, + REFERENCE_TIME rtPeriodTime, HSEMAPHORE hSemaphore, DWORD_PTR *pdwAdviseCookie) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); + struct dsoundrender_timer *t; - FIXME("(%p/%p)->(%s, %s, %p, %p): stub!\n", This, iface, wine_dbgstr_longlong(rtBaseTime), wine_dbgstr_longlong(rtStreamTime), (void*)hSemaphore, pdwAdviseCookie); + TRACE("(%p/%p)->(%s, %s, %p, %p)\n", This, iface, wine_dbgstr_longlong(rtStartTime), wine_dbgstr_longlong(rtPeriodTime), (void*)hSemaphore, pdwAdviseCookie); - return E_NOTIMPL; + if (rtStartTime <= 0 || rtPeriodTime <= 0) + return E_INVALIDARG; + + if (!pdwAdviseCookie) + return E_POINTER; + + EnterCriticalSection(&This->renderer.filter.csFilter); + if (!This->threadid && This->dsbuffer) { + This->thread_wait = CreateEventW(0, 0, 0, 0); + This->advisethread = CreateThread(NULL, 0, DSoundAdviseThread, This, 0, &This->threadid); + WaitForSingleObject(This->thread_wait, INFINITE); + CloseHandle(This->thread_wait); + } + LeaveCriticalSection(&This->renderer.filter.csFilter); + + t = HeapAlloc(GetProcessHeap(), 0, sizeof(*t)); + t->next = NULL; + t->start = rtStartTime; + t->periodicity = rtPeriodTime; + t->handle = (HANDLE)hSemaphore; + t->cookie = InterlockedIncrement(&cookie_counter); + PostThreadMessageW(This->threadid, WM_APP+1, (WPARAM)t, 0); + *pdwAdviseCookie = t->cookie; + + return S_OK; } static HRESULT WINAPI ReferenceClock_Unadvise(IReferenceClock *iface, DWORD_PTR dwAdviseCookie) { - ICOM_THIS_MULTI(DSoundRenderImpl, IReferenceClock_vtbl, iface); + DSoundRenderImpl *This = impl_from_IReferenceClock(iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, (void*)dwAdviseCookie); - - return S_FALSE; + TRACE("(%p/%p)->(%p)\n", This, iface, (void*)dwAdviseCookie); + if (!This->advisethread || !dwAdviseCookie) + return S_FALSE; + PostThreadMessageW(This->threadid, WM_APP+3, dwAdviseCookie, 0); + return S_OK; } static const IReferenceClockVtbl IReferenceClock_Vtbl = @@ -1285,90 +1162,40 @@ static const IReferenceClockVtbl IReferenceClock_Vtbl = ReferenceClock_Unadvise }; -static inline DSoundRenderImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) -{ - return (DSoundRenderImpl *)((char*)iface - FIELD_OFFSET(DSoundRenderImpl, mediaSeeking.lpVtbl)); -} - -static HRESULT WINAPI sound_seek_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) -{ - DSoundRenderImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); -} - -static ULONG WINAPI sound_seek_AddRef(IMediaSeeking * iface) -{ - DSoundRenderImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_AddRef((IUnknown *)This); -} - -static ULONG WINAPI sound_seek_Release(IMediaSeeking * iface) -{ - DSoundRenderImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_Release((IUnknown *)This); -} - -static const IMediaSeekingVtbl IMediaSeeking_Vtbl = -{ - sound_seek_QueryInterface, - sound_seek_AddRef, - sound_seek_Release, - MediaSeekingImpl_GetCapabilities, - MediaSeekingImpl_CheckCapabilities, - MediaSeekingImpl_IsFormatSupported, - MediaSeekingImpl_QueryPreferredFormat, - MediaSeekingImpl_GetTimeFormat, - MediaSeekingImpl_IsUsingTimeFormat, - MediaSeekingImpl_SetTimeFormat, - MediaSeekingImpl_GetDuration, - MediaSeekingImpl_GetStopPosition, - MediaSeekingImpl_GetCurrentPosition, - MediaSeekingImpl_ConvertTimeFormat, - MediaSeekingImpl_SetPositions, - MediaSeekingImpl_GetPositions, - MediaSeekingImpl_GetAvailable, - MediaSeekingImpl_SetRate, - MediaSeekingImpl_GetRate, - MediaSeekingImpl_GetPreroll -}; - /*** IUnknown methods ***/ static HRESULT WINAPI AMDirectSound_QueryInterface(IAMDirectSound *iface, REFIID riid, LPVOID*ppvObj) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return DSoundRender_QueryInterface((IBaseFilter*)This, riid, ppvObj); + return DSoundRender_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); } static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); TRACE("(%p/%p)->()\n", This, iface); - return DSoundRender_AddRef((IBaseFilter*)This); + return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); } static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); TRACE("(%p/%p)->()\n", This, iface); - return DSoundRender_Release((IBaseFilter*)This); + return DSoundRender_Release(&This->renderer.filter.IBaseFilter_iface); } /*** IAMDirectSound methods ***/ static HRESULT WINAPI AMDirectSound_GetDirectSoundInterface(IAMDirectSound *iface, IDirectSound **ds) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, ds); @@ -1377,7 +1204,7 @@ static HRESULT WINAPI AMDirectSound_GetDirectSoundInterface(IAMDirectSound *ifac static HRESULT WINAPI AMDirectSound_GetPrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, buf); @@ -1386,7 +1213,7 @@ static HRESULT WINAPI AMDirectSound_GetPrimaryBufferInterface(IAMDirectSound *if static HRESULT WINAPI AMDirectSound_GetSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, buf); @@ -1395,7 +1222,7 @@ static HRESULT WINAPI AMDirectSound_GetSecondaryBufferInterface(IAMDirectSound * static HRESULT WINAPI AMDirectSound_ReleaseDirectSoundInterface(IAMDirectSound *iface, IDirectSound *ds) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, ds); @@ -1404,7 +1231,7 @@ static HRESULT WINAPI AMDirectSound_ReleaseDirectSoundInterface(IAMDirectSound * static HRESULT WINAPI AMDirectSound_ReleasePrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, buf); @@ -1413,7 +1240,7 @@ static HRESULT WINAPI AMDirectSound_ReleasePrimaryBufferInterface(IAMDirectSound static HRESULT WINAPI AMDirectSound_ReleaseSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, buf); @@ -1422,7 +1249,7 @@ static HRESULT WINAPI AMDirectSound_ReleaseSecondaryBufferInterface(IAMDirectSou static HRESULT WINAPI AMDirectSound_SetFocusWindow(IAMDirectSound *iface, HWND hwnd, BOOL bgsilent) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p,%d): stub\n", This, iface, hwnd, bgsilent); @@ -1431,7 +1258,7 @@ static HRESULT WINAPI AMDirectSound_SetFocusWindow(IAMDirectSound *iface, HWND h static HRESULT WINAPI AMDirectSound_GetFocusWindow(IAMDirectSound *iface, HWND hwnd) { - ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface); + DSoundRenderImpl *This = impl_from_IAMDirectSound(iface); FIXME("(%p/%p)->(%p): stub\n", This, iface, hwnd); @@ -1452,3 +1279,29 @@ static const IAMDirectSoundVtbl IAMDirectSound_Vtbl = AMDirectSound_SetFocusWindow, AMDirectSound_GetFocusWindow }; + +static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) { + DSoundRenderImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_QueryInterface((IUnknown*)This, riid, ppv); +} + +static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) { + DSoundRenderImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_AddRef((IUnknown*)This); +} + +static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) { + DSoundRenderImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_Release((IUnknown*)This); +} + +static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) { + return AM_FILTER_MISC_FLAGS_IS_RENDERER; +} + +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = { + AMFilterMiscFlags_QueryInterface, + AMFilterMiscFlags_AddRef, + AMFilterMiscFlags_Release, + AMFilterMiscFlags_GetMiscFlags +}; diff --git a/dll/directx/quartz/enumfilters.c b/dll/directx/quartz/enumfilters.c index ad80e619564..5182e6a8ddd 100644 --- a/dll/directx/quartz/enumfilters.c +++ b/dll/directx/quartz/enumfilters.c @@ -26,22 +26,31 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct IEnumFiltersImpl { - const IEnumFiltersVtbl * lpVtbl; + IEnumFilters IEnumFilters_iface; LONG refCount; - IBaseFilter ** ppFilters; - int nFilters; + IGraphVersion * pVersionSource; + LONG Version; + IBaseFilter *** pppFilters; + ULONG * pNumFilters; ULONG uIndex; } IEnumFiltersImpl; static const struct IEnumFiltersVtbl IEnumFiltersImpl_Vtbl; -HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum) +static inline IEnumFiltersImpl *impl_from_IEnumFilters(IEnumFilters *iface) +{ + return CONTAINING_RECORD(iface, IEnumFiltersImpl, IEnumFilters_iface); +} + +HRESULT IEnumFiltersImpl_Construct(IGraphVersion * pVersionSource, IBaseFilter *** pppFilters, ULONG * pNumFilters, IEnumFilters ** ppEnum) { /* Note: The incoming IBaseFilter interfaces are not AddRef'd here as in Windows, * they should have been previously AddRef'd. */ IEnumFiltersImpl * pEnumFilters = CoTaskMemAlloc(sizeof(IEnumFiltersImpl)); + HRESULT hr; + LONG currentVersion; - TRACE("(%p, %d, %p)\n", ppFilters, nFilters, ppEnum); + TRACE("(%p, %p, %p)\n", pppFilters, pNumFilters, ppEnum); *ppEnum = NULL; @@ -50,20 +59,19 @@ HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEn return E_OUTOFMEMORY; } - pEnumFilters->lpVtbl = &IEnumFiltersImpl_Vtbl; + pEnumFilters->IEnumFilters_iface.lpVtbl = &IEnumFiltersImpl_Vtbl; pEnumFilters->refCount = 1; pEnumFilters->uIndex = 0; - pEnumFilters->nFilters = nFilters; - pEnumFilters->ppFilters = CoTaskMemAlloc(sizeof(IBaseFilter*) * nFilters); - if (!pEnumFilters->ppFilters) - { - CoTaskMemFree(pEnumFilters); - return E_OUTOFMEMORY; - } + pEnumFilters->pNumFilters = pNumFilters; + pEnumFilters->pppFilters = pppFilters; + IGraphVersion_AddRef(pVersionSource); + pEnumFilters->pVersionSource = pVersionSource; - memcpy(pEnumFilters->ppFilters, ppFilters, nFilters * sizeof(IBaseFilter*)); + /* Store the current version of the graph */ + hr = IGraphVersion_QueryVersion(pVersionSource, ¤tVersion); + pEnumFilters->Version = (hr==S_OK) ? currentVersion : 0; - *ppEnum = (IEnumFilters *)(&pEnumFilters->lpVtbl); + *ppEnum = &pEnumFilters->IEnumFilters_iface; return S_OK; } @@ -91,7 +99,7 @@ static HRESULT WINAPI IEnumFiltersImpl_QueryInterface(IEnumFilters * iface, REFI static ULONG WINAPI IEnumFiltersImpl_AddRef(IEnumFilters * iface) { - IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface; + IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); ULONG refCount = InterlockedIncrement(&This->refCount); TRACE("(%p)->()\n", iface); @@ -101,15 +109,14 @@ static ULONG WINAPI IEnumFiltersImpl_AddRef(IEnumFilters * iface) static ULONG WINAPI IEnumFiltersImpl_Release(IEnumFilters * iface) { - IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface; + IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); ULONG refCount = InterlockedDecrement(&This->refCount); TRACE("(%p)->()\n", iface); if (!refCount) { - CoTaskMemFree(This->ppFilters); - CoTaskMemFree(This); + IGraphVersion_Release(This->pVersionSource); return 0; } else @@ -120,18 +127,26 @@ static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters { ULONG cFetched; ULONG i; - IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface; + LONG currentVersion; + IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); + HRESULT hr; - cFetched = min(This->nFilters, This->uIndex + cFilters) - This->uIndex; + cFetched = min(*This->pNumFilters, This->uIndex + cFilters) - This->uIndex; TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched); + /* First of all check if the graph has changed */ + hr = IGraphVersion_QueryVersion(This->pVersionSource, ¤tVersion); + if (hr==S_OK && This->Version != currentVersion) + return VFW_E_ENUM_OUT_OF_SYNC; + + if (!ppFilters) return E_POINTER; for (i = 0; i < cFetched; i++) { - ppFilters[i] = This->ppFilters[This->uIndex + i]; + ppFilters[i] = (*This->pppFilters)[This->uIndex + i]; IBaseFilter_AddRef(ppFilters[i]); } @@ -147,11 +162,11 @@ static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters) { - IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface; + IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); TRACE("(%p)->(%u)\n", iface, cFilters); - if (This->uIndex + cFilters < This->nFilters) + if (This->uIndex + cFilters < *This->pNumFilters) { This->uIndex += cFilters; return S_OK; @@ -161,22 +176,27 @@ static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters static HRESULT WINAPI IEnumFiltersImpl_Reset(IEnumFilters * iface) { - IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface; + IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); + HRESULT hr; + LONG currentVersion; TRACE("(%p)->()\n", iface); This->uIndex = 0; + hr = IGraphVersion_QueryVersion(This->pVersionSource, ¤tVersion); + if (!hr) + This->Version = currentVersion; return S_OK; } static HRESULT WINAPI IEnumFiltersImpl_Clone(IEnumFilters * iface, IEnumFilters ** ppEnum) { HRESULT hr; - IEnumFiltersImpl *This = (IEnumFiltersImpl *)iface; + IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); TRACE("(%p)->(%p)\n", iface, ppEnum); - hr = IEnumFiltersImpl_Construct(This->ppFilters, This->nFilters, ppEnum); + hr = IEnumFiltersImpl_Construct(This->pVersionSource, This->pppFilters, This->pNumFilters, ppEnum); if (FAILED(hr)) return hr; return IEnumFilters_Skip(*ppEnum, This->uIndex); diff --git a/dll/directx/quartz/enummedia.c b/dll/directx/quartz/enummedia.c index fca46912121..fab473663d8 100644 --- a/dll/directx/quartz/enummedia.c +++ b/dll/directx/quartz/enummedia.c @@ -24,237 +24,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); -HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc) -{ - *pDest = *pSrc; - if (!pSrc->pbFormat) return S_OK; - if (!(pDest->pbFormat = CoTaskMemAlloc(pSrc->cbFormat))) - return E_OUTOFMEMORY; - memcpy(pDest->pbFormat, pSrc->pbFormat, pSrc->cbFormat); - if (pDest->pUnk) - IUnknown_AddRef(pDest->pUnk); - return S_OK; -} - -void FreeMediaType(AM_MEDIA_TYPE * pMediaType) -{ - if (pMediaType->pbFormat) - { - CoTaskMemFree(pMediaType->pbFormat); - pMediaType->pbFormat = NULL; - } - if (pMediaType->pUnk) - { - IUnknown_Release(pMediaType->pUnk); - pMediaType->pUnk = NULL; - } -} - -static AM_MEDIA_TYPE * CreateMediaType(AM_MEDIA_TYPE const * pSrc) -{ - AM_MEDIA_TYPE * pDest; - - pDest = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - if (!pDest) - return NULL; - - if (FAILED(CopyMediaType(pDest, pSrc))) - { - CoTaskMemFree(pDest); - return NULL; - } - - return pDest; -} - -void DeleteMediaType(AM_MEDIA_TYPE * pMediaType) -{ - FreeMediaType(pMediaType); - CoTaskMemFree(pMediaType); -} - -BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards) -{ - TRACE("pmt1: "); - dump_AM_MEDIA_TYPE(pmt1); - TRACE("pmt2: "); - dump_AM_MEDIA_TYPE(pmt2); - return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) && - ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL) || IsEqualGUID(&pmt2->subtype, &GUID_NULL))) || IsEqualGUID(&pmt1->subtype, &pmt2->subtype))); -} - void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt) { if (!pmt) return; TRACE("\t%s\n\t%s\n\t...\n\t%s\n", qzdebugstr_guid(&pmt->majortype), qzdebugstr_guid(&pmt->subtype), qzdebugstr_guid(&pmt->formattype)); } - -typedef struct IEnumMediaTypesImpl -{ - const IEnumMediaTypesVtbl * lpVtbl; - LONG refCount; - ENUMMEDIADETAILS enumMediaDetails; - ULONG uIndex; -} IEnumMediaTypesImpl; - -static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl; - -HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum) -{ - ULONG i; - IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl)); - - if (!pEnumMediaTypes) - { - *ppEnum = NULL; - return E_OUTOFMEMORY; - } - pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl; - pEnumMediaTypes->refCount = 1; - pEnumMediaTypes->uIndex = 0; - pEnumMediaTypes->enumMediaDetails.cMediaTypes = pDetails->cMediaTypes; - pEnumMediaTypes->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * pDetails->cMediaTypes); - for (i = 0; i < pDetails->cMediaTypes; i++) - if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &pDetails->pMediaTypes[i]))) - { - while (i--) - CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat); - CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes); - return E_OUTOFMEMORY; - } - *ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl); - return S_OK; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, REFIID riid, LPVOID * ppv) -{ - TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IEnumMediaTypes)) - *ppv = iface; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1); - - return refCount; -} - -static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("(%p)->() Release from %d\n", iface, refCount + 1); - - if (!refCount) - { - ULONG i; - for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++) - if (This->enumMediaDetails.pMediaTypes[i].pbFormat) - CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat); - CoTaskMemFree(This->enumMediaDetails.pMediaTypes); - CoTaskMemFree(This); - } - return refCount; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched) -{ - ULONG cFetched; - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - cFetched = min(This->enumMediaDetails.cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex; - - TRACE("(%u, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched); - TRACE("Next uIndex: %u, cFetched: %u\n", This->uIndex, cFetched); - - if (cFetched > 0) - { - ULONG i; - for (i = 0; i < cFetched; i++) - if (!(ppMediaTypes[i] = CreateMediaType(&This->enumMediaDetails.pMediaTypes[This->uIndex + i]))) - { - while (i--) - DeleteMediaType(ppMediaTypes[i]); - *pcFetched = 0; - return E_OUTOFMEMORY; - } - } - - if ((cMediaTypes != 1) || pcFetched) - *pcFetched = cFetched; - - This->uIndex += cFetched; - - if (cFetched != cMediaTypes) - return S_FALSE; - return S_OK; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - TRACE("(%u)\n", cMediaTypes); - - if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes) - { - This->uIndex += cMediaTypes; - return S_OK; - } - return S_FALSE; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - TRACE("()\n"); - - This->uIndex = 0; - return S_OK; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum) -{ - HRESULT hr; - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - TRACE("(%p)\n", ppEnum); - - hr = IEnumMediaTypesImpl_Construct(&This->enumMediaDetails, ppEnum); - if (FAILED(hr)) - return hr; - return IEnumMediaTypes_Skip(*ppEnum, This->uIndex); -} - -static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl = -{ - IEnumMediaTypesImpl_QueryInterface, - IEnumMediaTypesImpl_AddRef, - IEnumMediaTypesImpl_Release, - IEnumMediaTypesImpl_Next, - IEnumMediaTypesImpl_Skip, - IEnumMediaTypesImpl_Reset, - IEnumMediaTypesImpl_Clone -}; diff --git a/dll/directx/quartz/enummoniker.c b/dll/directx/quartz/enummoniker.c index 55f4d6a8d03..b3561374e9c 100644 --- a/dll/directx/quartz/enummoniker.c +++ b/dll/directx/quartz/enummoniker.c @@ -3,9 +3,6 @@ * * Copyright 2003 Robert Shearman * - * This file contains the (internal) driver registration functions, - * driver enumeration APIs and DirectDraw creation functions. - * * 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 @@ -31,7 +28,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct EnumMonikerImpl { - const IEnumMonikerVtbl *lpVtbl; + IEnumMoniker IEnumMoniker_iface; LONG ref; IMoniker ** ppMoniker; ULONG nMonikerCount; @@ -40,6 +37,11 @@ typedef struct EnumMonikerImpl static const IEnumMonikerVtbl EnumMonikerImpl_Vtbl; +static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface) +{ + return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface); +} + static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface); HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) @@ -56,14 +58,14 @@ HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnum if (!pemi) return E_OUTOFMEMORY; - pemi->lpVtbl = &EnumMonikerImpl_Vtbl; + pemi->IEnumMoniker_iface.lpVtbl = &EnumMonikerImpl_Vtbl; pemi->ref = 1; pemi->ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker*)); memcpy(pemi->ppMoniker, ppMoniker, nMonikerCount*sizeof(IMoniker*)); pemi->nMonikerCount = nMonikerCount; pemi->index = 0; - *ppEnum = (IEnumMoniker *)pemi; + *ppEnum = &pemi->IEnumMoniker_iface; return S_OK; } @@ -76,7 +78,7 @@ static HRESULT WINAPI EnumMonikerImpl_QueryInterface( REFIID riid, LPVOID *ppvObj) { - EnumMonikerImpl *This = (EnumMonikerImpl *)iface; + EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); TRACE("\n\tIID:\t%s\n",debugstr_guid(riid)); if (This == NULL || ppvObj == NULL) return E_POINTER; @@ -99,7 +101,7 @@ static HRESULT WINAPI EnumMonikerImpl_QueryInterface( */ static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface) { - EnumMonikerImpl *This = (EnumMonikerImpl *)iface; + EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); ULONG ref; if (This == NULL) return E_POINTER; @@ -116,7 +118,7 @@ static ULONG WINAPI EnumMonikerImpl_AddRef(LPENUMMONIKER iface) */ static ULONG WINAPI EnumMonikerImpl_Release(LPENUMMONIKER iface) { - EnumMonikerImpl *This = (EnumMonikerImpl *)iface; + EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->() Release from %d\n", iface, ref + 1); @@ -139,7 +141,7 @@ static ULONG WINAPI EnumMonikerImpl_Release(LPENUMMONIKER iface) static HRESULT WINAPI EnumMonikerImpl_Next(LPENUMMONIKER iface, ULONG celt, IMoniker ** rgelt, ULONG * pceltFetched) { ULONG fetched; - EnumMonikerImpl *This = (EnumMonikerImpl *)iface; + EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched); @@ -164,7 +166,7 @@ static HRESULT WINAPI EnumMonikerImpl_Next(LPENUMMONIKER iface, ULONG celt, IMon static HRESULT WINAPI EnumMonikerImpl_Skip(LPENUMMONIKER iface, ULONG celt) { - EnumMonikerImpl *This = (EnumMonikerImpl *)iface; + EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); TRACE("(%p)->(%d)\n", iface, celt); @@ -175,7 +177,7 @@ static HRESULT WINAPI EnumMonikerImpl_Skip(LPENUMMONIKER iface, ULONG celt) static HRESULT WINAPI EnumMonikerImpl_Reset(LPENUMMONIKER iface) { - EnumMonikerImpl *This = (EnumMonikerImpl *)iface; + EnumMonikerImpl *This = impl_from_IEnumMoniker(iface); TRACE("(%p)->()\n", iface); diff --git a/dll/directx/quartz/enumregfilters.c b/dll/directx/quartz/enumregfilters.c index 7145778b251..b5c92ba4b46 100644 --- a/dll/directx/quartz/enumregfilters.c +++ b/dll/directx/quartz/enumregfilters.c @@ -28,13 +28,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); typedef struct IEnumRegFiltersImpl { - const IEnumRegFiltersVtbl * lpVtbl; + IEnumRegFilters IEnumRegFilters_iface; LONG refCount; ULONG size; REGFILTER* RegFilters; ULONG uIndex; } IEnumRegFiltersImpl; +static inline IEnumRegFiltersImpl *impl_from_IEnumRegFilters(IEnumRegFilters *iface) +{ + return CONTAINING_RECORD(iface, IEnumRegFiltersImpl, IEnumRegFilters_iface); +} + static const struct IEnumRegFiltersVtbl IEnumRegFiltersImpl_Vtbl; HRESULT IEnumRegFiltersImpl_Construct(REGFILTER* pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum) @@ -79,13 +84,13 @@ HRESULT IEnumRegFiltersImpl_Construct(REGFILTER* pInRegFilters, const ULONG size CopyMemory(pRegFilters[i].Name, pInRegFilters[i].Name, (strlenW(pInRegFilters[i].Name)+1)*sizeof(WCHAR)); } - pEnumRegFilters->lpVtbl = &IEnumRegFiltersImpl_Vtbl; + pEnumRegFilters->IEnumRegFilters_iface.lpVtbl = &IEnumRegFiltersImpl_Vtbl; pEnumRegFilters->refCount = 1; pEnumRegFilters->uIndex = 0; pEnumRegFilters->RegFilters = pRegFilters; pEnumRegFilters->size = size; - *ppEnum = (IEnumRegFilters *)(&pEnumRegFilters->lpVtbl); + *ppEnum = &pEnumRegFilters->IEnumRegFilters_iface; return S_OK; } @@ -114,7 +119,7 @@ static HRESULT WINAPI IEnumRegFiltersImpl_QueryInterface(IEnumRegFilters * iface static ULONG WINAPI IEnumRegFiltersImpl_AddRef(IEnumRegFilters * iface) { - IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface; + IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); ULONG refCount = InterlockedIncrement(&This->refCount); TRACE("(%p)\n", iface); @@ -124,7 +129,7 @@ static ULONG WINAPI IEnumRegFiltersImpl_AddRef(IEnumRegFilters * iface) static ULONG WINAPI IEnumRegFiltersImpl_Release(IEnumRegFilters * iface) { - IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface; + IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); ULONG refCount = InterlockedDecrement(&This->refCount); TRACE("(%p)\n", iface); @@ -147,7 +152,7 @@ static ULONG WINAPI IEnumRegFiltersImpl_Release(IEnumRegFilters * iface) static HRESULT WINAPI IEnumRegFiltersImpl_Next(IEnumRegFilters * iface, ULONG cFilters, REGFILTER ** ppRegFilter, ULONG * pcFetched) { ULONG cFetched; - IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface; + IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); unsigned int i; cFetched = min(This->size, This->uIndex + cFilters) - This->uIndex; @@ -193,7 +198,7 @@ static HRESULT WINAPI IEnumRegFiltersImpl_Skip(IEnumRegFilters * iface, ULONG n) static HRESULT WINAPI IEnumRegFiltersImpl_Reset(IEnumRegFilters * iface) { - IEnumRegFiltersImpl *This = (IEnumRegFiltersImpl *)iface; + IEnumRegFiltersImpl *This = impl_from_IEnumRegFilters(iface); TRACE("(%p)\n", iface); diff --git a/dll/directx/quartz/fil_data.idl b/dll/directx/quartz/fil_data.idl new file mode 100644 index 00000000000..93cdf1e43dd --- /dev/null +++ b/dll/directx/quartz/fil_data.idl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2009 Vitaliy Margolen + * + * 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 + */ + +import "objidl.idl"; +import "strmif.idl"; +import "unknwn.idl"; + + +/***************************************************************************** + * IAMFilterData interface + * + * Notes: + * - This interface is deprecated and IFilterMapper2 should be used instead. + * - There is no full replacement for IAMFilterData::ParseFilterData short of manually + * parsing out the REGFILTER2 struct from the binary blob. + */ +[ + object, + uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d), + pointer_default(unique) +] +interface IAMFilterData : IUnknown +{ + typedef [unique] IAMFilterData *LPIAMFILTERDATA; + + HRESULT ParseFilterData( + [in] BYTE * rgbFilterData, + [in] ULONG cb, + [out] BYTE ** prgbRegFilter2); + + HRESULT CreateFilterData( + [in] REGFILTER2 * prf2, + [out] BYTE ** prgbFilterData, + [out] ULONG * pcb); +} diff --git a/dll/directx/quartz/filesource.c b/dll/directx/quartz/filesource.c index 6f1174d5924..75023019409 100644 --- a/dll/directx/quartz/filesource.c +++ b/dll/directx/quartz/filesource.c @@ -39,37 +39,50 @@ static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 }; typedef struct AsyncReader { - const IBaseFilterVtbl * lpVtbl; - const IFileSourceFilterVtbl * lpVtblFSF; - - LONG refCount; - FILTER_INFO filterInfo; - FILTER_STATE state; - CRITICAL_SECTION csFilter; - DWORD lastpinchange; + BaseFilter filter; + IFileSourceFilter IFileSourceFilter_iface; + IAMFilterMiscFlags IAMFilterMiscFlags_iface; IPin * pOutputPin; LPOLESTR pszFileName; AM_MEDIA_TYPE * pmt; } AsyncReader; +static inline AsyncReader *impl_from_BaseFilter(BaseFilter *iface) +{ + return CONTAINING_RECORD(iface, AsyncReader, filter); +} + +static inline AsyncReader *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, AsyncReader, filter.IBaseFilter_iface); +} + +static inline AsyncReader *impl_from_IFileSourceFilter(IFileSourceFilter *iface) +{ + return CONTAINING_RECORD(iface, AsyncReader, IFileSourceFilter_iface); +} + +static inline AsyncReader *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) +{ + return CONTAINING_RECORD(iface, AsyncReader, IAMFilterMiscFlags_iface); +} + static const IBaseFilterVtbl AsyncReader_Vtbl; static const IFileSourceFilterVtbl FileSource_Vtbl; static const IAsyncReaderVtbl FileAsyncReader_Vtbl; +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl; static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); -static inline AsyncReader *impl_from_IFileSourceFilter( IFileSourceFilter *iface ) -{ - return (AsyncReader *)((char*)iface - FIELD_OFFSET(AsyncReader, lpVtblFSF)); -} - -static WCHAR const mediatype_name[11] = { +static const WCHAR mediatype_name[] = { 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 }; -static WCHAR const subtype_name[8] = { +static const WCHAR subtype_name[] = { 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 }; +static const WCHAR source_filter_name[] = { + 'S','o','u','r','c','e',' ','F','i','l','t','e','r',0}; -static HRESULT process_extensions(HKEY hkeyExtensions, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType) +static HRESULT process_extensions(HKEY hkeyExtensions, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType, GUID * sourceFilter) { WCHAR *extension; LONG l; @@ -89,17 +102,31 @@ static HRESULT process_extensions(HKEY hkeyExtensions, LPCOLESTR pszFileName, GU if (l) return E_FAIL; - size = sizeof(keying); - l = RegQueryValueExW(hsub, mediatype_name, NULL, NULL, (LPBYTE)keying, &size); - if (!l) - CLSIDFromString(keying, majorType); + if (majorType) + { + size = sizeof(keying); + l = RegQueryValueExW(hsub, mediatype_name, NULL, NULL, (LPBYTE)keying, &size); + if (!l) + CLSIDFromString(keying, majorType); + } - size = sizeof(keying); - if (!l) - l = RegQueryValueExW(hsub, subtype_name, NULL, NULL, (LPBYTE)keying, &size); + if (minorType) + { + size = sizeof(keying); + if (!l) + l = RegQueryValueExW(hsub, subtype_name, NULL, NULL, (LPBYTE)keying, &size); + if (!l) + CLSIDFromString(keying, minorType); + } - if (!l) - CLSIDFromString(keying, minorType); + if (sourceFilter) + { + size = sizeof(keying); + if (!l) + l = RegQueryValueExW(hsub, source_filter_name, NULL, NULL, (LPBYTE)keying, &size); + if (!l) + CLSIDFromString(keying, sourceFilter); + } RegCloseKey(hsub); @@ -183,8 +210,8 @@ static HRESULT process_pattern_string(LPCWSTR wszPatternString, IAsyncReader * p if (!(wszPatternString = strchrW(wszPatternString, ','))) hr = E_INVALIDARG; - - wszPatternString++; /* skip ',' */ + else + wszPatternString++; /* skip ',' */ } if (hr == S_OK) @@ -227,7 +254,7 @@ static HRESULT process_pattern_string(LPCWSTR wszPatternString, IAsyncReader * p return hr; } -static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType) +HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType, GUID * sourceFilter) { HKEY hkeyMediaType = NULL; LONG lRet; @@ -237,8 +264,12 @@ static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, TRACE("(%p, %s, %p, %p)\n", pReader, debugstr_w(pszFileName), majorType, minorType); - *majorType = GUID_NULL; - *minorType = GUID_NULL; + if(majorType) + *majorType = GUID_NULL; + if(minorType) + *minorType = GUID_NULL; + if(sourceFilter) + *sourceFilter = GUID_NULL; lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszMediaType, 0, KEY_READ, &hkeyMediaType); hr = HRESULT_FROM_WIN32(lRet); @@ -261,10 +292,11 @@ static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, TRACE("%s\n", debugstr_w(wszMajorKeyName)); if (!strcmpW(wszExtensions, wszMajorKeyName)) { - if (process_extensions(hkeyMajor, pszFileName, majorType, minorType) == S_OK) + if (process_extensions(hkeyMajor, pszFileName, majorType, minorType, sourceFilter) == S_OK) bFound = TRUE; } - else + /* We need a reader interface to check bytes */ + else if (pReader) { DWORD indexMinor; @@ -273,6 +305,8 @@ static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, HKEY hkeyMinor; WCHAR wszMinorKeyName[CHARS_IN_GUID]; DWORD dwMinorKeyNameLen = sizeof(wszMinorKeyName) / sizeof(wszMinorKeyName[0]); + WCHAR wszSourceFilterKeyName[CHARS_IN_GUID]; + DWORD dwSourceFilterKeyNameLen = sizeof(wszSourceFilterKeyName); DWORD maxValueLen; DWORD indexValue; @@ -294,26 +328,37 @@ static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, LPWSTR wszPatternString = HeapAlloc(GetProcessHeap(), 0, maxValueLen); DWORD dwValueNameLen = sizeof(wszValueName) / sizeof(wszValueName[0]); /* remember this is in chars */ DWORD dwDataLen = maxValueLen; /* remember this is in bytes */ - static const WCHAR wszSourceFilter[] = {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0}; - LONG temp; - if ((temp = RegEnumValueW(hkeyMinor, indexValue, wszValueName, &dwValueNameLen, NULL, &dwType, (LPBYTE)wszPatternString, &dwDataLen)) != ERROR_SUCCESS) + if (RegEnumValueW(hkeyMinor, indexValue, wszValueName, &dwValueNameLen, NULL, &dwType, (LPBYTE)wszPatternString, &dwDataLen) != ERROR_SUCCESS) { HeapFree(GetProcessHeap(), 0, wszPatternString); break; } - /* if it is not the source filter value */ - if (strcmpW(wszValueName, wszSourceFilter)) - { - if (process_pattern_string(wszPatternString, pReader) == S_OK) - { - if (SUCCEEDED(CLSIDFromString(wszMajorKeyName, majorType)) && - SUCCEEDED(CLSIDFromString(wszMinorKeyName, minorType))) - bFound = TRUE; - } + if (strcmpW(wszValueName, source_filter_name)==0) { + HeapFree(GetProcessHeap(), 0, wszPatternString); + continue; } - HeapFree(GetProcessHeap(), 0, wszPatternString); + + /* if it is not the source filter value */ + if (process_pattern_string(wszPatternString, pReader) == S_OK) + { + HeapFree(GetProcessHeap(), 0, wszPatternString); + if (majorType && FAILED(CLSIDFromString(wszMajorKeyName, majorType))) + break; + if (minorType && FAILED(CLSIDFromString(wszMinorKeyName, minorType))) + break; + if (sourceFilter) + { + /* Look up the source filter key */ + if (RegQueryValueExW(hkeyMinor, source_filter_name, NULL, NULL, (LPBYTE)wszSourceFilterKeyName, &dwSourceFilterKeyNameLen)) + break; + if (FAILED(CLSIDFromString(wszSourceFilterKeyName, sourceFilter))) + break; + } + bFound = TRUE; + } else + HeapFree(GetProcessHeap(), 0, wszPatternString); } CloseHandle(hkeyMinor); } @@ -329,11 +374,45 @@ static HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, hr = E_FAIL; } else if (bFound) - TRACE("Found file's class: major = %s, subtype = %s\n", qzdebugstr_guid(majorType), qzdebugstr_guid(minorType)); + { + TRACE("Found file's class:\n"); + if(majorType) + TRACE("\tmajor = %s\n", qzdebugstr_guid(majorType)); + if(minorType) + TRACE("\tsubtype = %s\n", qzdebugstr_guid(minorType)); + if(sourceFilter) + TRACE("\tsource filter = %s\n", qzdebugstr_guid(sourceFilter)); + } return hr; } +static IPin* WINAPI AsyncReader_GetPin(BaseFilter *iface, int pos) +{ + AsyncReader *This = impl_from_BaseFilter(iface); + + if (pos >= 1 || !This->pOutputPin) + return NULL; + + IPin_AddRef(This->pOutputPin); + return This->pOutputPin; +} + +static LONG WINAPI AsyncReader_GetPinCount(BaseFilter *iface) +{ + AsyncReader *This = impl_from_BaseFilter(iface); + + if (!This->pOutputPin) + return 0; + else + return 1; +} + +static const BaseFilterFuncTable BaseFuncTable = { + AsyncReader_GetPin, + AsyncReader_GetPinCount +}; + HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv) { AsyncReader *pAsyncRead; @@ -346,17 +425,11 @@ HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv) if (!pAsyncRead) return E_OUTOFMEMORY; - pAsyncRead->lpVtbl = &AsyncReader_Vtbl; - pAsyncRead->lpVtblFSF = &FileSource_Vtbl; - pAsyncRead->refCount = 1; - pAsyncRead->filterInfo.achName[0] = '\0'; - pAsyncRead->filterInfo.pGraph = NULL; - pAsyncRead->pOutputPin = NULL; - pAsyncRead->lastpinchange = GetTickCount(); - pAsyncRead->state = State_Stopped; + BaseFilter_Init(&pAsyncRead->filter, &AsyncReader_Vtbl, &CLSID_AsyncReader, (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"), &BaseFuncTable); - InitializeCriticalSection(&pAsyncRead->csFilter); - pAsyncRead->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"); + pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl; + pAsyncRead->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl; + pAsyncRead->pOutputPin = NULL; pAsyncRead->pszFileName = NULL; pAsyncRead->pmt = NULL; @@ -372,7 +445,7 @@ HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv) static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) { - AsyncReader *This = (AsyncReader *)iface; + AsyncReader *This = impl_from_IBaseFilter(iface); TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); @@ -387,7 +460,9 @@ static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter * iface, REFIID rii else if (IsEqualIID(riid, &IID_IBaseFilter)) *ppv = This; else if (IsEqualIID(riid, &IID_IFileSourceFilter)) - *ppv = &This->lpVtblFSF; + *ppv = &This->IFileSourceFilter_iface; + else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) + *ppv = &This->IAMFilterMiscFlags_iface; if (*ppv) { @@ -402,20 +477,10 @@ static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter * iface, REFIID rii return E_NOINTERFACE; } -static ULONG WINAPI AsyncReader_AddRef(IBaseFilter * iface) -{ - AsyncReader *This = (AsyncReader *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p)->() AddRef from %d\n", This, refCount - 1); - - return refCount; -} - static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface) { - AsyncReader *This = (AsyncReader *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); + AsyncReader *This = impl_from_IBaseFilter(iface); + ULONG refCount = BaseFilterImpl_Release(iface); TRACE("(%p)->() Release from %d\n", This, refCount + 1); @@ -432,9 +497,6 @@ static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface) IPin_Disconnect(This->pOutputPin); IPin_Release(This->pOutputPin); } - This->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csFilter); - This->lpVtbl = NULL; CoTaskMemFree(This->pszFileName); if (This->pmt) FreeMediaType(This->pmt); @@ -445,189 +507,100 @@ static ULONG WINAPI AsyncReader_Release(IBaseFilter * iface) return refCount; } -/** IPersist methods **/ - -static HRESULT WINAPI AsyncReader_GetClassID(IBaseFilter * iface, CLSID * pClsid) -{ - TRACE("(%p)\n", pClsid); - - *pClsid = CLSID_AsyncReader; - - return S_OK; -} - /** IMediaFilter methods **/ static HRESULT WINAPI AsyncReader_Stop(IBaseFilter * iface) { - AsyncReader *This = (AsyncReader *)iface; + AsyncReader *This = impl_from_IBaseFilter(iface); TRACE("()\n"); - This->state = State_Stopped; + This->filter.state = State_Stopped; return S_OK; } static HRESULT WINAPI AsyncReader_Pause(IBaseFilter * iface) { - AsyncReader *This = (AsyncReader *)iface; + AsyncReader *This = impl_from_IBaseFilter(iface); TRACE("()\n"); - This->state = State_Paused; + This->filter.state = State_Paused; return S_OK; } static HRESULT WINAPI AsyncReader_Run(IBaseFilter * iface, REFERENCE_TIME tStart) { - AsyncReader *This = (AsyncReader *)iface; + AsyncReader *This = impl_from_IBaseFilter(iface); TRACE("(%x%08x)\n", (ULONG)(tStart >> 32), (ULONG)tStart); - This->state = State_Running; - - return S_OK; -} - -static HRESULT WINAPI AsyncReader_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - AsyncReader *This = (AsyncReader *)iface; - - TRACE("(%u, %p)\n", dwMilliSecsTimeout, pState); - - *pState = This->state; - - return S_OK; -} - -static HRESULT WINAPI AsyncReader_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) -{ -/* AsyncReader *This = (AsyncReader *)iface;*/ - - TRACE("(%p)\n", pClock); - - return S_OK; -} - -static HRESULT WINAPI AsyncReader_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) -{ -/* AsyncReader *This = (AsyncReader *)iface;*/ - - TRACE("(%p)\n", ppClock); + This->filter.state = State_Running; return S_OK; } /** IBaseFilter methods **/ -static HRESULT AsyncReader_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) -{ - AsyncReader *This = (AsyncReader *)iface; - - /* Our pins are almost static, not changing so setting static tick count is ok */ - *lastsynctick = This->lastpinchange; - - if (pos >= 1 || !This->pOutputPin) - return S_FALSE; - - *pin = This->pOutputPin; - IPin_AddRef(*pin); - return S_OK; -} - -static HRESULT WINAPI AsyncReader_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) -{ - AsyncReader *This = (AsyncReader *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return IEnumPinsImpl_Construct(ppEnum, AsyncReader_GetPin, iface); -} - static HRESULT WINAPI AsyncReader_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) { - FIXME("(%s, %p)\n", debugstr_w(Id), ppPin); + AsyncReader *This = impl_from_IBaseFilter(iface); + TRACE("(%s, %p)\n", debugstr_w(Id), ppPin); - return E_NOTIMPL; -} + if (!Id || !ppPin) + return E_POINTER; -static HRESULT WINAPI AsyncReader_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) -{ - AsyncReader *This = (AsyncReader *)iface; + if (strcmpW(Id, wszOutputPinName)) + { + *ppPin = NULL; + return VFW_E_NOT_FOUND; + } - TRACE("(%p)\n", pInfo); - - strcpyW(pInfo->achName, This->filterInfo.achName); - pInfo->pGraph = This->filterInfo.pGraph; - - if (pInfo->pGraph) - IFilterGraph_AddRef(pInfo->pGraph); - + *ppPin = This->pOutputPin; + IPin_AddRef(*ppPin); return S_OK; } -static HRESULT WINAPI AsyncReader_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - AsyncReader *This = (AsyncReader *)iface; - - TRACE("(%p, %s)\n", pGraph, debugstr_w(pName)); - - if (pName) - strcpyW(This->filterInfo.achName, pName); - else - *This->filterInfo.achName = 0; - This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ - - return S_OK; -} - -static HRESULT WINAPI AsyncReader_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) -{ - FIXME("(%p)\n", pVendorInfo); - - return E_NOTIMPL; -} - static const IBaseFilterVtbl AsyncReader_Vtbl = { AsyncReader_QueryInterface, - AsyncReader_AddRef, + BaseFilterImpl_AddRef, AsyncReader_Release, - AsyncReader_GetClassID, + BaseFilterImpl_GetClassID, AsyncReader_Stop, AsyncReader_Pause, AsyncReader_Run, - AsyncReader_GetState, - AsyncReader_SetSyncSource, - AsyncReader_GetSyncSource, - AsyncReader_EnumPins, + BaseFilterImpl_GetState, + BaseFilterImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, AsyncReader_FindPin, - AsyncReader_QueryFilterInfo, - AsyncReader_JoinFilterGraph, - AsyncReader_QueryVendorInfo + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo }; static HRESULT WINAPI FileSource_QueryInterface(IFileSourceFilter * iface, REFIID riid, LPVOID * ppv) { AsyncReader *This = impl_from_IFileSourceFilter(iface); - return IBaseFilter_QueryInterface((IFileSourceFilter*)&This->lpVtbl, riid, ppv); + return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv); } static ULONG WINAPI FileSource_AddRef(IFileSourceFilter * iface) { AsyncReader *This = impl_from_IFileSourceFilter(iface); - return IBaseFilter_AddRef((IFileSourceFilter*)&This->lpVtbl); + return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface); } static ULONG WINAPI FileSource_Release(IFileSourceFilter * iface) { AsyncReader *This = impl_from_IFileSourceFilter(iface); - return IBaseFilter_Release((IFileSourceFilter*)&This->lpVtbl); + return IBaseFilter_Release(&This->filter.IBaseFilter_iface); } static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFileName, const AM_MEDIA_TYPE * pmt) @@ -649,8 +622,8 @@ static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFi } /* create pin */ - hr = FileAsyncReader_Construct(hFile, (IBaseFilter *)&This->lpVtbl, &This->csFilter, &This->pOutputPin); - This->lastpinchange = GetTickCount(); + hr = FileAsyncReader_Construct(hFile, &This->filter.IBaseFilter_iface, &This->filter.csFilter, &This->pOutputPin); + BaseFilterImpl_IncrementPinVersion(&This->filter); if (SUCCEEDED(hr)) hr = IPin_QueryInterface(This->pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader); @@ -675,7 +648,7 @@ static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFi This->pmt->pUnk = NULL; This->pmt->lSampleSize = 0; This->pmt->formattype = FORMAT_None; - hr = GetClassMediaFile(pReader, pszFileName, &This->pmt->majortype, &This->pmt->subtype); + hr = GetClassMediaFile(pReader, pszFileName, &This->pmt->majortype, &This->pmt->subtype, NULL); if (FAILED(hr)) { CoTaskMemFree(This->pmt); @@ -759,9 +732,10 @@ typedef struct DATAREQUEST typedef struct FileAsyncReader { - OutputPin pin; - const struct IAsyncReaderVtbl * lpVtblAR; + BaseOutputPin pin; + IAsyncReader IAsyncReader_iface; + ALLOCATOR_PROPERTIES allocProps; HANDLE hFile; BOOL bFlushing; /* Why would you need more? Every sample has its own handle */ @@ -775,30 +749,62 @@ typedef struct FileAsyncReader HANDLE *handle_list; } FileAsyncReader; -static inline FileAsyncReader *impl_from_IAsyncReader( IAsyncReader *iface ) +static inline FileAsyncReader *impl_from_IPin(IPin *iface) { - return (FileAsyncReader *)((char*)iface - FIELD_OFFSET(FileAsyncReader, lpVtblAR)); + return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin.IPin_iface); } -static HRESULT AcceptProcAFR(LPVOID iface, const AM_MEDIA_TYPE *pmt) +static inline FileAsyncReader *impl_from_BasePin(BasePin *iface) { - AsyncReader *This = iface; + return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin); +} + +static inline FileAsyncReader *impl_from_BaseOutputPin(BaseOutputPin *iface) +{ + return CONTAINING_RECORD(iface, FileAsyncReader, pin); +} + +static inline BaseOutputPin *impl_BaseOututPin_from_BasePin(BasePin *iface) +{ + return CONTAINING_RECORD(iface, BaseOutputPin, pin); +} + +static inline FileAsyncReader *impl_from_IAsyncReader(IAsyncReader *iface) +{ + return CONTAINING_RECORD(iface, FileAsyncReader, IAsyncReader_iface); +} + +static HRESULT WINAPI FileAsyncReaderPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) +{ + FileAsyncReader *This = impl_from_IPin(iface); + AM_MEDIA_TYPE *pmt_filter = impl_from_IBaseFilter(This->pin.pin.pinInfo.pFilter)->pmt; FIXME("(%p, %p)\n", iface, pmt); - if (IsEqualGUID(&pmt->majortype, &This->pmt->majortype) && - IsEqualGUID(&pmt->subtype, &This->pmt->subtype) && + if (IsEqualGUID(&pmt->majortype, &pmt_filter->majortype) && + IsEqualGUID(&pmt->subtype, &pmt_filter->subtype) && IsEqualGUID(&pmt->formattype, &FORMAT_None)) return S_OK; - + return S_FALSE; } +static HRESULT WINAPI FileAsyncReaderPin_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt) +{ + FileAsyncReader *This = impl_from_BasePin(iface); + if (iPosition < 0) + return E_INVALIDARG; + if (iPosition > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(pmt, impl_from_IBaseFilter(This->pin.pin.pinInfo.pFilter)->pmt); + return S_OK; +} + /* overridden pin functions */ static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) { - FileAsyncReader *This = (FileAsyncReader *)iface; + FileAsyncReader *This = impl_from_IPin(iface); TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); *ppv = NULL; @@ -808,7 +814,7 @@ static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID rii else if (IsEqualIID(riid, &IID_IPin)) *ppv = This; else if (IsEqualIID(riid, &IID_IAsyncReader)) - *ppv = &This->lpVtblAR; + *ppv = &This->IAsyncReader_iface; if (*ppv) { @@ -824,7 +830,7 @@ static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID rii static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface) { - FileAsyncReader *This = (FileAsyncReader *)iface; + FileAsyncReader *This = impl_from_IPin(iface); ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount); int x; @@ -848,48 +854,35 @@ static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface) return refCount; } -static HRESULT WINAPI FileAsyncReaderPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum) -{ - ENUMMEDIADETAILS emd; - FileAsyncReader *This = (FileAsyncReader *)iface; - - TRACE("(%p)\n", ppEnum); - - emd.cMediaTypes = 1; - emd.pMediaTypes = ((AsyncReader *)This->pin.pin.pinInfo.pFilter)->pmt; - - return IEnumMediaTypesImpl_Construct(&emd, ppEnum); -} - static const IPinVtbl FileAsyncReaderPin_Vtbl = { FileAsyncReaderPin_QueryInterface, - IPinImpl_AddRef, + BasePinImpl_AddRef, FileAsyncReaderPin_Release, - OutputPin_Connect, - OutputPin_ReceiveConnection, - IPinImpl_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - FileAsyncReaderPin_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - OutputPin_EndOfStream, - OutputPin_BeginFlush, - OutputPin_EndFlush, - OutputPin_NewSegment + BaseOutputPinImpl_Connect, + BaseOutputPinImpl_ReceiveConnection, + BasePinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + FileAsyncReaderPin_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment }; /* Function called as a helper to IPin_Connect */ /* specific AM_MEDIA_TYPE - it cannot be NULL */ -/* this differs from standard OutputPin_ConnectSpecific only in that it +/* this differs from standard OutputPin_AttemptConnection only in that it * doesn't need the IMemInputPin interface on the receiving pin */ -static HRESULT FileAsyncReaderPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI FileAsyncReaderPin_AttemptConnection(BasePin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) { - OutputPin *This = (OutputPin *)iface; + BaseOutputPin *This = impl_BaseOututPin_from_BasePin(iface); HRESULT hr; TRACE("(%p, %p)\n", pReceivePin, pmt); @@ -901,7 +894,7 @@ static HRESULT FileAsyncReaderPin_ConnectSpecific(IPin * iface, IPin * pReceiveP IPin_AddRef(pReceivePin); CopyMediaType(&This->pin.mtCurrent, pmt); - hr = IPin_ReceiveConnection(pReceivePin, iface, pmt); + hr = IPin_ReceiveConnection(pReceivePin, &iface->IPin_iface, pmt); if (FAILED(hr)) { @@ -914,6 +907,36 @@ static HRESULT FileAsyncReaderPin_ConnectSpecific(IPin * iface, IPin * pReceiveP return hr; } +static HRESULT WINAPI FileAsyncReaderPin_DecideBufferSize(BaseOutputPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + FileAsyncReader *This = impl_from_BaseOutputPin(iface); + ALLOCATOR_PROPERTIES actual; + + if (ppropInputRequest->cbAlign && ppropInputRequest->cbAlign != This->allocProps.cbAlign) + FIXME("Requested Buffer cbAlign mismatch %i,%i\n",This->allocProps.cbAlign, ppropInputRequest->cbAlign); + if (ppropInputRequest->cbPrefix) + FIXME("Requested Buffer cbPrefix mismatch %i,%i\n",This->allocProps.cbPrefix, ppropInputRequest->cbPrefix); + if (ppropInputRequest->cbBuffer) + FIXME("Requested Buffer cbBuffer mismatch %i,%i\n",This->allocProps.cbBuffer, ppropInputRequest->cbBuffer); + if (ppropInputRequest->cBuffers) + FIXME("Requested Buffer cBuffers mismatch %i,%i\n",This->allocProps.cBuffers, ppropInputRequest->cBuffers); + + return IMemAllocator_SetProperties(pAlloc, &This->allocProps, &actual); +} + +static const BasePinFuncTable output_BaseFuncTable = { + NULL, + FileAsyncReaderPin_AttemptConnection, + BasePinImpl_GetMediaTypeVersion, + FileAsyncReaderPin_GetMediaType +}; + +static const BaseOutputPinFuncTable output_BaseOutputFuncTable = { + FileAsyncReaderPin_DecideBufferSize, + BaseOutputPinImpl_DecideAllocator, + BaseOutputPinImpl_BreakConnect +}; + static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) { PIN_INFO piOutput; @@ -923,18 +946,17 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter piOutput.dir = PINDIR_OUTPUT; piOutput.pFilter = pBaseFilter; strcpyW(piOutput.achName, wszOutputPinName); - hr = OutputPin_Construct(&FileAsyncReaderPin_Vtbl, sizeof(FileAsyncReader), &piOutput, NULL, pBaseFilter, AcceptProcAFR, pCritSec, ppPin); + hr = BaseOutputPin_Construct(&FileAsyncReaderPin_Vtbl, sizeof(FileAsyncReader), &piOutput, &output_BaseFuncTable, &output_BaseOutputFuncTable, pCritSec, ppPin); if (SUCCEEDED(hr)) { FileAsyncReader *pPinImpl = (FileAsyncReader *)*ppPin; - pPinImpl->lpVtblAR = &FileAsyncReader_Vtbl; + pPinImpl->IAsyncReader_iface.lpVtbl = &FileAsyncReader_Vtbl; pPinImpl->hFile = hFile; pPinImpl->bFlushing = FALSE; pPinImpl->sample_list = NULL; pPinImpl->handle_list = NULL; pPinImpl->queued_number = 0; - pPinImpl->pin.pConnectSpecific = FileAsyncReaderPin_ConnectSpecific; InitializeCriticalSection(&pPinImpl->csList); pPinImpl->csList.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FileAsyncReader.csList"); } @@ -947,21 +969,21 @@ static HRESULT WINAPI FileAsyncReader_QueryInterface(IAsyncReader * iface, REFII { FileAsyncReader *This = impl_from_IAsyncReader(iface); - return IPin_QueryInterface((IPin *)This, riid, ppv); + return IPin_QueryInterface(&This->pin.pin.IPin_iface, riid, ppv); } static ULONG WINAPI FileAsyncReader_AddRef(IAsyncReader * iface) { FileAsyncReader *This = impl_from_IAsyncReader(iface); - return IPin_AddRef((IPin *)This); + return IPin_AddRef(&This->pin.pin.IPin_iface); } static ULONG WINAPI FileAsyncReader_Release(IAsyncReader * iface) { FileAsyncReader *This = impl_from_IAsyncReader(iface); - return IPin_Release((IPin *)This); + return IPin_Release(&This->pin.pin.IPin_iface); } #define DEF_ALIGNMENT 1 @@ -1034,7 +1056,7 @@ done: This->handle_list[This->samples + 1 + x] = This->handle_list[x]; } This->handle_list[This->samples] = CreateEventW(NULL, 1, 0, NULL); - This->pin.allocProps = *pProps; + This->allocProps = *pProps; } else { @@ -1113,8 +1135,8 @@ static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample pDataRq = This->sample_list + x; - pDataRq->ovl.Offset = (DWORD) BYTES_FROM_MEDIATIME(Start); - pDataRq->ovl.OffsetHigh = (DWORD)(BYTES_FROM_MEDIATIME(Start) >> (sizeof(DWORD) * 8)); + pDataRq->ovl.u.s.Offset = (DWORD) BYTES_FROM_MEDIATIME(Start); + pDataRq->ovl.u.s.OffsetHigh = (DWORD)(BYTES_FROM_MEDIATIME(Start) >> (sizeof(DWORD) * 8)); pDataRq->dwUserData = dwUser; /* we violate traditional COM rules here by maintaining @@ -1239,7 +1261,7 @@ static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader * iface, DWORD dw /* Set the time on the sample */ IMediaSample_SetActualDataLength(pDataRq->pSample, dwBytes); - rtStart = (DWORD64)pDataRq->ovl.Offset + ((DWORD64)pDataRq->ovl.OffsetHigh << 32); + rtStart = (DWORD64)pDataRq->ovl.u.s.Offset + ((DWORD64)pDataRq->ovl.u.s.OffsetHigh << 32); rtStart = MEDIATIME_FROM_BYTES(rtStart); rtStop = rtStart + MEDIATIME_FROM_BYTES(dwBytes); @@ -1317,8 +1339,8 @@ static HRESULT WINAPI FileAsyncReader_SyncRead(IAsyncReader * iface, LONGLONG ll ovl.hEvent = CreateEventW(NULL, 0, 0, NULL); /* NOTE: llPosition is the actual byte position to start reading from */ - ovl.Offset = (DWORD) llPosition; - ovl.OffsetHigh = (DWORD) (llPosition >> (sizeof(DWORD) * 8)); + ovl.u.s.Offset = (DWORD) llPosition; + ovl.u.s.OffsetHigh = (DWORD) (llPosition >> (sizeof(DWORD) * 8)); if (!ReadFile(This->hFile, pBuffer, lLength, NULL, &ovl)) hr = HRESULT_FROM_WIN32(GetLastError()); @@ -1406,3 +1428,30 @@ static const IAsyncReaderVtbl FileAsyncReader_Vtbl = FileAsyncReader_BeginFlush, FileAsyncReader_EndFlush, }; + + +static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) { + AsyncReader *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_QueryInterface((IUnknown*)This, riid, ppv); +} + +static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) { + AsyncReader *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_AddRef((IUnknown*)This); +} + +static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) { + AsyncReader *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_Release((IUnknown*)This); +} + +static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) { + return AM_FILTER_MISC_FLAGS_IS_SOURCE; +} + +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = { + AMFilterMiscFlags_QueryInterface, + AMFilterMiscFlags_AddRef, + AMFilterMiscFlags_Release, + AMFilterMiscFlags_GetMiscFlags +}; diff --git a/dll/directx/quartz/filtergraph.c b/dll/directx/quartz/filtergraph.c index 553e026ab65..896762f538f 100644 --- a/dll/directx/quartz/filtergraph.c +++ b/dll/directx/quartz/filtergraph.c @@ -3,9 +3,6 @@ * Copyright 2002 Lionel Ulmer * Copyright 2004 Christian Costa * - * This file contains the (internal) driver registration functions, - * driver enumeration APIs and DirectDraw creation functions. - * * 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 @@ -22,23 +19,23 @@ */ #include -//#include +#include #define COBJMACROS -//#include "windef.h" -//#include "winbase.h" -//#include "winuser.h" -//#include "winreg.h" -//#include "dshow.h" +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "shlwapi.h" +#include "dshow.h" #include #include "quartz_private.h" -#include -//#include "ole2.h" -//#include "olectl.h" -//#include "strmif.h" -//#include "vfwmsgs.h" -//#include "evcode.h" +#include "ole2.h" +#include "olectl.h" +#include +#include "vfwmsgs.h" +#include "evcode.h" #include @@ -94,12 +91,12 @@ static int EventsQueue_Destroy(EventsQueue* omr) static int EventsQueue_PutEvent(EventsQueue* omr, const Event* evt) { EnterCriticalSection(&omr->msg_crst); - if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size))) + if (omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size)) { int old_ring_buffer_size = omr->ring_buffer_size; omr->ring_buffer_size += EVENTS_RING_BUFFER_INCREMENT; TRACE("omr->ring_buffer_size=%d\n",omr->ring_buffer_size); - omr->messages = HeapReAlloc(GetProcessHeap(),0,omr->messages, omr->ring_buffer_size * sizeof(Event)); + omr->messages = CoTaskMemRealloc(omr->messages, omr->ring_buffer_size * sizeof(Event)); /* Now we need to rearrange the ring buffer so that the new buffers just allocated are in between omr->msg_tosave and omr->msg_toget. @@ -152,38 +149,41 @@ typedef struct _ITF_CACHE_ENTRY { } ITF_CACHE_ENTRY; typedef struct _IFilterGraphImpl { - const IFilterGraph2Vtbl *IFilterGraph2_vtbl; - const IMediaControlVtbl *IMediaControl_vtbl; - const IMediaSeekingVtbl *IMediaSeeking_vtbl; - const IBasicAudioVtbl *IBasicAudio_vtbl; - const IBasicVideo2Vtbl *IBasicVideo_vtbl; - const IVideoWindowVtbl *IVideoWindow_vtbl; - const IMediaEventExVtbl *IMediaEventEx_vtbl; - const IMediaFilterVtbl *IMediaFilter_vtbl; - const IMediaEventSinkVtbl *IMediaEventSink_vtbl; - const IGraphConfigVtbl *IGraphConfig_vtbl; - const IMediaPositionVtbl *IMediaPosition_vtbl; - const IUnknownVtbl * IInner_vtbl; + IUnknown IUnknown_inner; + IFilterGraph2 IFilterGraph2_iface; + IMediaControl IMediaControl_iface; + IMediaSeeking IMediaSeeking_iface; + IBasicAudio IBasicAudio_iface; + IBasicVideo2 IBasicVideo2_iface; + IVideoWindow IVideoWindow_iface; + IMediaEventEx IMediaEventEx_iface; + IMediaFilter IMediaFilter_iface; + IMediaEventSink IMediaEventSink_iface; + IGraphConfig IGraphConfig_iface; + IMediaPosition IMediaPosition_iface; + IObjectWithSite IObjectWithSite_iface; + IGraphVersion IGraphVersion_iface; /* IAMGraphStreams */ /* IAMStats */ /* IFilterChain */ /* IFilterMapper2 */ - /* IGraphVersion */ /* IQueueCommand */ /* IRegisterServiceProvider */ /* IResourceMananger */ /* IServiceProvider */ /* IVideoFrameStep */ + IUnknown *outer_unk; LONG ref; IUnknown *punkFilterMapper2; IFilterMapper2 * pFilterMapper2; IBaseFilter ** ppFiltersInGraph; LPWSTR * pFilterNames; - int nFilters; + ULONG nFilters; int filterCapacity; LONG nameIndex; IReferenceClock *refClock; + IBaseFilter *refClockProvider; EventsQueue evqueue; HANDLE hEventCompletion; int CompletionStatus; @@ -197,99 +197,105 @@ typedef struct _IFilterGraphImpl { CRITICAL_SECTION cs; ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES]; int nItfCacheEntries; - IUnknown * pUnkOuter; - BOOL bUnkOuterValid; - BOOL bAggregatable; + BOOL defaultclock; GUID timeformatseek; - LONGLONG start_time; - LONGLONG position; + REFERENCE_TIME start_time; + REFERENCE_TIME pause_time; LONGLONG stop_position; LONG recursioncount; + IUnknown *pSite; + LONG version; } IFilterGraphImpl; -static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This, - REFIID riid, LPVOID * ppv); -static ULONG Filtergraph_AddRef(IFilterGraphImpl *This); -static ULONG Filtergraph_Release(IFilterGraphImpl *This); +static inline IFilterGraphImpl *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IUnknown_inner); +} -static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown * iface, - REFIID riid, - LPVOID *ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface); +static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IUnknown(iface); TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj); - - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; if (IsEqualGUID(&IID_IUnknown, riid)) { - *ppvObj = &(This->IInner_vtbl); + *ppvObj = &This->IUnknown_inner; TRACE(" returning IUnknown interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IFilterGraph, riid) || IsEqualGUID(&IID_IFilterGraph2, riid) || IsEqualGUID(&IID_IGraphBuilder, riid)) { - *ppvObj = &(This->IFilterGraph2_vtbl); + *ppvObj = &This->IFilterGraph2_iface; TRACE(" returning IGraphBuilder interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IMediaControl, riid)) { - *ppvObj = &(This->IMediaControl_vtbl); + *ppvObj = &This->IMediaControl_iface; TRACE(" returning IMediaControl interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) { - *ppvObj = &(This->IMediaSeeking_vtbl); + *ppvObj = &This->IMediaSeeking_iface; TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IBasicAudio, riid)) { - *ppvObj = &(This->IBasicAudio_vtbl); + *ppvObj = &This->IBasicAudio_iface; TRACE(" returning IBasicAudio interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IBasicVideo, riid) || IsEqualGUID(&IID_IBasicVideo2, riid)) { - *ppvObj = &(This->IBasicVideo_vtbl); + *ppvObj = &This->IBasicVideo2_iface; TRACE(" returning IBasicVideo2 interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IVideoWindow, riid)) { - *ppvObj = &(This->IVideoWindow_vtbl); + *ppvObj = &This->IVideoWindow_iface; TRACE(" returning IVideoWindow interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IMediaEvent, riid) || IsEqualGUID(&IID_IMediaEventEx, riid)) { - *ppvObj = &(This->IMediaEventEx_vtbl); + *ppvObj = &This->IMediaEventEx_iface; TRACE(" returning IMediaEvent(Ex) interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IMediaFilter, riid) || IsEqualGUID(&IID_IPersist, riid)) { - *ppvObj = &(This->IMediaFilter_vtbl); + *ppvObj = &This->IMediaFilter_iface; TRACE(" returning IMediaFilter interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IMediaEventSink, riid)) { - *ppvObj = &(This->IMediaEventSink_vtbl); + *ppvObj = &This->IMediaEventSink_iface; TRACE(" returning IMediaEventSink interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IGraphConfig, riid)) { - *ppvObj = &(This->IGraphConfig_vtbl); + *ppvObj = &This->IGraphConfig_iface; TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IMediaPosition, riid)) { - *ppvObj = &(This->IMediaPosition_vtbl); + *ppvObj = &This->IMediaPosition_iface; TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_IObjectWithSite, riid)) { + *ppvObj = &This->IObjectWithSite_iface; + TRACE(" returning IObjectWithSite interface (%p)\n", *ppvObj); } else if (IsEqualGUID(&IID_IFilterMapper, riid)) { TRACE(" requesting IFilterMapper interface from aggregated filtermapper (%p)\n", *ppvObj); return IUnknown_QueryInterface(This->punkFilterMapper2, riid, ppvObj); } else if (IsEqualGUID(&IID_IFilterMapper2, riid)) { *ppvObj = This->pFilterMapper2; TRACE(" returning IFilterMapper2 interface from aggregated filtermapper (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_IFilterMapper3, riid)) { + *ppvObj = This->pFilterMapper2; + TRACE(" returning IFilterMapper3 interface from aggregated filtermapper (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_IGraphVersion, riid)) { + *ppvObj = &This->IGraphConfig_iface; + TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj); } else { *ppvObj = NULL; FIXME("unknown interface %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } - IUnknown_AddRef((IUnknown *)(*ppvObj)); + IUnknown_AddRef((IUnknown *)*ppvObj); return S_OK; } -static ULONG WINAPI FilterGraphInner_AddRef(IUnknown * iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface); +static ULONG WINAPI FilterGraphInner_AddRef(IUnknown *iface) +{ + IFilterGraphImpl *This = impl_from_IUnknown(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->(): new ref = %d\n", This, ref); - + return ref; } -static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) +static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface); + IFilterGraphImpl *This = impl_from_IUnknown(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->(): new ref = %d\n", This, ref); @@ -299,10 +305,10 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) This->ref = 1; /* guard against reentrancy (aggregation). */ - IMediaControl_Stop((IMediaControl*)&(This->IMediaControl_vtbl)); + IMediaControl_Stop(&This->IMediaControl_iface); while (This->nFilters) - IFilterGraph2_RemoveFilter((IFilterGraph2*)This, This->ppFiltersInGraph[0]); + IFilterGraph2_RemoveFilter(&This->IFilterGraph2_iface, This->ppFiltersInGraph[0]); if (This->refClock) IReferenceClock_Release(This->refClock); @@ -313,18 +319,13 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) IUnknown_Release(This->ItfCacheEntries[i].iface); } - /* AddRef on controlling IUnknown, to compensate for Release of cached IFilterMapper2 interface below. - - * NOTE: Filtergraph_AddRef isn't suitable, because bUnkOuterValid may be FALSE but punkOuter non-NULL - * and already passed as punkOuter to filtermapper in FilterGraph_create - this will happen in case of - * CoCreateInstance of filtergraph with non-null pUnkOuter and REFIID other than IID_Unknown that is - * cleaning up after error. */ - if (This->pUnkOuter) IUnknown_AddRef(This->pUnkOuter); - else IUnknown_AddRef((IUnknown*)&This->IInner_vtbl); - + /* AddRef on controlling IUnknown, to compensate for Release of cached IFilterMapper2 */ + IUnknown_AddRef(This->outer_unk); IFilterMapper2_Release(This->pFilterMapper2); IUnknown_Release(This->punkFilterMapper2); + if (This->pSite) IUnknown_Release(This->pSite); + CloseHandle(This->hEventCompletion); EventsQueue_Destroy(&This->evqueue); This->cs.DebugInfo->Spare[0] = 0; @@ -336,38 +337,43 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) return ref; } +static inline IFilterGraphImpl *impl_from_IFilterGraph2(IFilterGraph2 *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IFilterGraph2_iface); +} + +static HRESULT WINAPI FilterGraph2_QueryInterface(IFilterGraph2 *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); -/*** IUnknown methods ***/ -static HRESULT WINAPI FilterGraph2_QueryInterface(IFilterGraph2 *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); - TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI FilterGraph2_AddRef(IFilterGraph2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); - - TRACE("(%p/%p)->() calling FilterGraph AddRef\n", This, iface); - - return Filtergraph_AddRef(This); +static ULONG WINAPI FilterGraph2_AddRef(IFilterGraph2 *iface) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); - - TRACE("(%p/%p)->() calling FilterGraph Release\n", This, iface); +static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); - return Filtergraph_Release(This); + TRACE("(%p/%p)->()\n", This, iface); + + return IUnknown_Release(This->outer_unk); } /*** IFilterGraph methods ***/ -static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, - IBaseFilter *pFilter, - LPCWSTR pName) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, IBaseFilter *pFilter, + LPCWSTR pName) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); HRESULT hr; int i,j; WCHAR* wszFilterName = NULL; @@ -452,20 +458,21 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, This->ppFiltersInGraph[This->nFilters] = pFilter; This->pFilterNames[This->nFilters] = wszFilterName; This->nFilters++; + This->version++; IBaseFilter_SetSyncSource(pFilter, This->refClock); } else - CoTaskMemFree(wszFilterName); + CoTaskMemFree(wszFilterName); if (SUCCEEDED(hr) && duplicate_name) - return VFW_S_DUPLICATE_NAME; - + return VFW_S_DUPLICATE_NAME; + return hr; } static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *pFilter) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); int i; HRESULT hr = E_FAIL; @@ -480,6 +487,12 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte IEnumPins *penumpins = NULL; FILTER_STATE state; + if (This->defaultclock && This->refClockProvider == pFilter) + { + IMediaFilter_SetSyncSource(&This->IMediaFilter_iface, NULL); + This->defaultclock = 1; + } + TRACE("Removing filter %s\n", debugstr_w(This->pFilterNames[i])); IBaseFilter_GetState(pFilter, 0, &state); if (state == State_Running) @@ -531,6 +544,7 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i)); memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i)); This->nFilters--; + This->version++; /* Invalidate interfaces in the cache */ for (i = 0; i < This->nItfCacheEntries; i++) if (pFilter == This->ItfCacheEntries[i].filter) @@ -548,19 +562,19 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte return hr; /* FIXME: check this error code */ } -static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface, - IEnumFilters **ppEnum) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface, IEnumFilters **ppEnum) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum); + return IEnumFiltersImpl_Construct(&This->IGraphVersion_iface, &This->ppFiltersInGraph, &This->nFilters, ppEnum); } -static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface, - LPCWSTR pName, - IBaseFilter **ppFilter) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface, LPCWSTR pName, + IBaseFilter **ppFilter) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); int i; TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_w(pName), pName, ppFilter); @@ -661,15 +675,13 @@ out: /* NOTE: despite the implication, it doesn't matter which * way round you put in the input and output pins */ -static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface, - IPin *ppinIn, - IPin *ppinOut, - const AM_MEDIA_TYPE *pmt) { +static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface, IPin *ppinIn, IPin *ppinOut, + const AM_MEDIA_TYPE *pmt) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); PIN_DIRECTION dir; HRESULT hr; - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); - TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, ppinIn, ppinOut, pmt); /* FIXME: check pins are in graph */ @@ -713,9 +725,9 @@ static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface, return hr; } -static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface, - IPin *ppin) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface, IPin *ppin) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); IPin *pConnectedTo = NULL; HRESULT hr; PIN_DIRECTION pindir; @@ -741,7 +753,7 @@ static HRESULT WINAPI FilterGraph2_Reconnect(IFilterGraph2 *iface, static HRESULT WINAPI FilterGraph2_Disconnect(IFilterGraph2 *iface, IPin *ppin) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(%p)\n", This, iface, ppin); @@ -751,27 +763,53 @@ static HRESULT WINAPI FilterGraph2_Disconnect(IFilterGraph2 *iface, IPin *ppin) return IPin_Disconnect(ppin); } -static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); IReferenceClock *pClock = NULL; - HRESULT hr; + HRESULT hr = S_OK; + int i; - TRACE("(%p/%p)->() semi-stub\n", iface, This); + TRACE("(%p/%p)->() live sources not handled properly!\n", iface, This); - hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&pClock); + EnterCriticalSection(&This->cs); + + for (i = 0; i < This->nFilters; ++i) + { + DWORD miscflags; + IAMFilterMiscFlags *flags = NULL; + IBaseFilter_QueryInterface(This->ppFiltersInGraph[i], &IID_IAMFilterMiscFlags, (void**)&flags); + if (!flags) + continue; + miscflags = IAMFilterMiscFlags_GetMiscFlags(flags); + IAMFilterMiscFlags_Release(flags); + if (miscflags == AM_FILTER_MISC_FLAGS_IS_RENDERER) + IBaseFilter_QueryInterface(This->ppFiltersInGraph[i], &IID_IReferenceClock, (void**)&pClock); + if (pClock) + break; + } + + if (!pClock) + { + hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (LPVOID*)&pClock); + This->refClockProvider = NULL; + } + else + This->refClockProvider = This->ppFiltersInGraph[i]; if (SUCCEEDED(hr)) { - hr = IMediaFilter_SetSyncSource((IMediaFilter*)&(This->IMediaFilter_vtbl), pClock); + hr = IMediaFilter_SetSyncSource(&This->IMediaFilter_iface, pClock); + This->defaultclock = TRUE; IReferenceClock_Release(pClock); } + LeaveCriticalSection(&This->cs); return hr; } -static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar) +static HRESULT GetFilterInfo(IMoniker* pMoniker, VARIANT* pvar) { - static const WCHAR wszClsidName[] = {'C','L','S','I','D',0}; static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; IPropertyBag * pPropBagCat = NULL; HRESULT hr; @@ -780,19 +818,11 @@ static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar) hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat); - if (SUCCEEDED(hr)) - hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL); - - if (SUCCEEDED(hr)) - hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid); - - VariantClear(pvar); - if (SUCCEEDED(hr)) hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL); if (SUCCEEDED(hr)) - TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid), debugstr_w(V_UNION(pvar, bstrVal))); + TRACE("Moniker = %s\n", debugstr_w(V_UNION(pvar, bstrVal))); if (pPropBagCat) IPropertyBag_Release(pPropBagCat); @@ -865,7 +895,7 @@ static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* pinputpin, IPi /*** IGraphBuilder methods ***/ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, IPin *ppinIn) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); HRESULT hr; AM_MEDIA_TYPE* mt = NULL; IEnumMediaTypes* penummt = NULL; @@ -873,12 +903,13 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, IEnumPins* penumpins; IEnumMoniker* pEnumMoniker; GUID tab[2]; - ULONG nb; + ULONG nb = 0; IMoniker* pMoniker; ULONG pin; PIN_INFO PinInfo; CLSID FilterCLSID; PIN_DIRECTION dir; + unsigned int i = 0; TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn); @@ -979,28 +1010,67 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, { VARIANT var; GUID clsid; - IPin** ppins; + IPin** ppins = NULL; IPin* ppinfilter = NULL; IBaseFilter* pfilter = NULL; + IAMGraphBuilderCallback *callback = NULL; - hr = GetFilterInfo(pMoniker, &clsid, &var); - IMoniker_Release(pMoniker); + hr = GetFilterInfo(pMoniker, &var); if (FAILED(hr)) { WARN("Unable to retrieve filter info (%x)\n", hr); goto error; } - if (IsEqualGUID(&clsid, &FilterCLSID)) { - /* Skip filter (same as the one the output pin belongs to) */ - goto error; - } - - hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter); + hr = IMoniker_BindToObject(pMoniker, NULL, NULL, &IID_IBaseFilter, (LPVOID*)&pfilter); + IMoniker_Release(pMoniker); if (FAILED(hr)) { WARN("Unable to create filter (%x), trying next one\n", hr); goto error; } + hr = IBaseFilter_GetClassID(pfilter, &clsid); + if (FAILED(hr)) + { + IBaseFilter_Release(pfilter); + goto error; + } + + if (IsEqualGUID(&clsid, &FilterCLSID)) { + /* Skip filter (same as the one the output pin belongs to) */ + IBaseFilter_Release(pfilter); + goto error; + } + + if (This->pSite) + { + IUnknown_QueryInterface(This->pSite, &IID_IAMGraphBuilderCallback, (LPVOID*)&callback); + if (callback) + { + HRESULT rc; + rc = IAMGraphBuilderCallback_SelectedFilter(callback, pMoniker); + if (FAILED(rc)) + { + TRACE("Filter rejected by IAMGraphBuilderCallback_SelectedFilter\n"); + IAMGraphBuilderCallback_Release(callback); + goto error; + } + } + } + + if (callback) + { + HRESULT rc; + rc = IAMGraphBuilderCallback_CreatedFilter(callback, pfilter); + IAMGraphBuilderCallback_Release(callback); + if (FAILED(rc)) + { + IBaseFilter_Release(pfilter); + pfilter = NULL; + TRACE("Filter rejected by IAMGraphBuilderCallback_CreatedFilter\n"); + goto error; + } + } + hr = IFilterGraph2_AddFilter(iface, pfilter, V_UNION(&var, bstrVal)); if (FAILED(hr)) { WARN("Unable to add filter (%x)\n", hr); @@ -1040,7 +1110,6 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, hr = GetInternalConnections(pfilter, ppinfilter, &ppins, &nb); if (SUCCEEDED(hr)) { - unsigned int i; if (nb == 0) { IPin_Disconnect(ppinfilter); IPin_Disconnect(ppinOut); @@ -1093,6 +1162,8 @@ error: IFilterGraph2_RemoveFilter(iface, pfilter); IBaseFilter_Release(pfilter); } + while (++i < nb) IPin_Release(ppins[i]); + CoTaskMemFree(ppins); } out: @@ -1136,7 +1207,7 @@ static HRESULT FilterGraph2_RenderRecurse(IFilterGraphImpl *This, IPin *ppinOut) if (!out) { HRESULT hr; - hr = IFilterGraph2_Render((IFilterGraph2 *)&This->IFilterGraph2_vtbl, to); + hr = IFilterGraph2_Render(&This->IFilterGraph2_iface, to); if (SUCCEEDED(hr)) renderany = TRUE; else @@ -1180,7 +1251,7 @@ static HRESULT FilterGraph2_RenderRecurse(IFilterGraphImpl *This, IPin *ppinOut) static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); IEnumMediaTypes* penummt; AM_MEDIA_TYPE* mt; ULONG nbmt; @@ -1235,7 +1306,7 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut) if (to == NULL) { - hr = IPin_Connect(ppinOut, pin, NULL); + hr = FilterGraph2_ConnectDirect(iface, ppinOut, pin, NULL); if (SUCCEEDED(hr)) { TRACE("Connected successfully %p/%p, %08x look if we should render more!\n", ppinOut, pin, hr); @@ -1315,20 +1386,19 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut) while (IEnumMoniker_Next(pEnumMoniker, 1, &pMoniker, &nb) == S_OK) { VARIANT var; - GUID clsid; IPin* ppinfilter; IBaseFilter* pfilter = NULL; IEnumPins* penumpins = NULL; ULONG pin; - hr = GetFilterInfo(pMoniker, &clsid, &var); - IMoniker_Release(pMoniker); + hr = GetFilterInfo(pMoniker, &var); if (FAILED(hr)) { WARN("Unable to retrieve filter info (%x)\n", hr); goto error; } - hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter); + hr = IMoniker_BindToObject(pMoniker, NULL, NULL, &IID_IBaseFilter, (LPVOID*)&pfilter); + IMoniker_Release(pMoniker); if (FAILED(hr)) { WARN("Unable to create filter (%x), trying next one\n", hr); @@ -1422,11 +1492,10 @@ error: return hr; } -static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface, - LPCWSTR lpcwstrFile, - LPCWSTR lpcwstrPlayList) +static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface, LPCWSTR lpcwstrFile, + LPCWSTR lpcwstrPlayList) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); static const WCHAR string[] = {'R','e','a','d','e','r',0}; IBaseFilter* preader = NULL; IPin* ppinreader = NULL; @@ -1485,68 +1554,103 @@ static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface, return hr; } -/* Some filters implement their own asynchronous reader (Theoretically they all should, try to load it first */ -static HRESULT GetFileSourceFilter(LPCOLESTR pszFileName, IBaseFilter **filter) +static HRESULT CreateFilterInstanceAndLoadFile(GUID* clsid, LPCOLESTR pszFileName, IBaseFilter **filter) { - static const WCHAR wszReg[] = {'M','e','d','i','a',' ','T','y','p','e','\\','E','x','t','e','n','s','i','o','n','s',0}; - HRESULT hr = S_OK; - HKEY extkey; - LONG lRet; - - lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszReg, 0, KEY_READ, &extkey); - hr = HRESULT_FROM_WIN32(lRet); - - if (SUCCEEDED(hr)) - { - static const WCHAR filtersource[] = {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0}; - WCHAR *ext = PathFindExtensionW(pszFileName); - WCHAR clsid_key[39]; - GUID clsid; - DWORD size = sizeof(clsid_key); - HKEY pathkey; - - if (!ext) - { - CloseHandle(extkey); - return E_FAIL; - } - - lRet = RegOpenKeyExW(extkey, ext, 0, KEY_READ, &pathkey); - hr = HRESULT_FROM_WIN32(lRet); - CloseHandle(extkey); - if (FAILED(hr)) - return hr; - - lRet = RegQueryValueExW(pathkey, filtersource, NULL, NULL, (LPBYTE)clsid_key, &size); - hr = HRESULT_FROM_WIN32(lRet); - CloseHandle(pathkey); - if (FAILED(hr)) - return hr; - - CLSIDFromString(clsid_key, &clsid); - - TRACE("CLSID: %s\n", debugstr_guid(&clsid)); - hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter); - if (SUCCEEDED(hr)) - { - IFileSourceFilter *source = NULL; - hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID*)&source); - if (SUCCEEDED(hr)) - IFileSourceFilter_Release(source); - else - IBaseFilter_Release(*filter); - } - } + IFileSourceFilter *source = NULL; + HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter); + TRACE("CLSID: %s\n", debugstr_guid(clsid)); if (FAILED(hr)) - *filter = NULL; + return hr; + + hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID*)&source); + if (FAILED(hr)) + { + IBaseFilter_Release(*filter); + return hr; + } + + /* Load the file in the file source filter */ + hr = IFileSourceFilter_Load(source, pszFileName, NULL); + IFileSourceFilter_Release(source); + if (FAILED(hr)) { + WARN("Load (%x)\n", hr); + IBaseFilter_Release(*filter); + return hr; + } + return hr; } -static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, - LPCWSTR lpcwstrFileName, - LPCWSTR lpcwstrFilterName, - IBaseFilter **ppFilter) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +/* Some filters implement their own asynchronous reader (Theoretically they all should, try to load it first */ +static HRESULT GetFileSourceFilter(LPCOLESTR pszFileName, IBaseFilter **filter) +{ + HRESULT hr; + GUID clsid; + IAsyncReader * pReader = NULL; + IFileSourceFilter* pSource = NULL; + IPin * pOutputPin = NULL; + static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 }; + + /* Try to find a match without reading the file first */ + hr = GetClassMediaFile(NULL, pszFileName, NULL, NULL, &clsid); + + if (!hr) + return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter); + + /* Now create a AyncReader instance, to check for signature bytes in the file */ + hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)filter); + if (FAILED(hr)) + return hr; + + hr = IBaseFilter_QueryInterface(*filter, &IID_IFileSourceFilter, (LPVOID *)&pSource); + if (FAILED(hr)) + { + IBaseFilter_Release(*filter); + return hr; + } + + hr = IFileSourceFilter_Load(pSource, pszFileName, NULL); + IFileSourceFilter_Release(pSource); + if (FAILED(hr)) + { + IBaseFilter_Release(*filter); + return hr; + } + + hr = IBaseFilter_FindPin(*filter, wszOutputPinName, &pOutputPin); + if (FAILED(hr)) + { + IBaseFilter_Release(*filter); + return hr; + } + + hr = IPin_QueryInterface(pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader); + IPin_Release(pOutputPin); + if (FAILED(hr)) + { + IBaseFilter_Release(*filter); + return hr; + } + + /* Try again find a match */ + hr = GetClassMediaFile(pReader, pszFileName, NULL, NULL, &clsid); + IAsyncReader_Release(pReader); + + if (!hr) + { + /* Release the AsyncReader filter and create the matching one */ + IBaseFilter_Release(*filter); + return CreateFilterInstanceAndLoadFile(&clsid, pszFileName, filter); + } + + /* Return the AsyncReader filter */ + return S_OK; +} + +static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, LPCWSTR lpcwstrFileName, + LPCWSTR lpcwstrFilterName, IBaseFilter **ppFilter) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); HRESULT hr; IBaseFilter* preader; IFileSourceFilter* pfile = NULL; @@ -1557,9 +1661,6 @@ static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, /* Try from file name first, then fall back to default asynchronous reader */ hr = GetFileSourceFilter(lpcwstrFileName, &preader); - - if (FAILED(hr)) - hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&preader); if (FAILED(hr)) { WARN("Unable to create file source filter (%x)\n", hr); return hr; @@ -1578,13 +1679,7 @@ static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, goto error; } - /* Load the file in the file source filter */ - hr = IFileSourceFilter_Load(pfile, lpcwstrFileName, NULL); - if (FAILED(hr)) { - WARN("Load (%x)\n", hr); - goto error; - } - + /* The file has been already loaded */ IFileSourceFilter_GetCurFile(pfile, &filename, &mt); if (FAILED(hr)) { WARN("GetCurFile (%x)\n", hr); @@ -1600,35 +1695,37 @@ static HRESULT WINAPI FilterGraph2_AddSourceFilter(IFilterGraph2 *iface, IFileSourceFilter_Release(pfile); return S_OK; - + error: if (pfile) IFileSourceFilter_Release(pfile); IFilterGraph2_RemoveFilter(iface, preader); IBaseFilter_Release(preader); - + return hr; } -static HRESULT WINAPI FilterGraph2_SetLogFile(IFilterGraph2 *iface, - DWORD_PTR hFile) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_SetLogFile(IFilterGraph2 *iface, DWORD_PTR hFile) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(%08x): stub !!!\n", This, iface, (DWORD) hFile); return S_OK; } -static HRESULT WINAPI FilterGraph2_Abort(IFilterGraph2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_Abort(IFilterGraph2 *iface) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(): stub !!!\n", This, iface); return S_OK; } -static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(): stub !!!\n", This, iface); @@ -1637,32 +1734,29 @@ static HRESULT WINAPI FilterGraph2_ShouldOperationContinue(IFilterGraph2 *iface) /*** IFilterGraph2 methods ***/ static HRESULT WINAPI FilterGraph2_AddSourceFilterForMoniker(IFilterGraph2 *iface, - IMoniker *pMoniker, - IBindCtx *pCtx, - LPCWSTR lpcwstrFilterName, - IBaseFilter **ppFilter) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); + IMoniker *pMoniker, IBindCtx *pCtx, LPCWSTR lpcwstrFilterName, IBaseFilter **ppFilter) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(%p %p %s %p): stub !!!\n", This, iface, pMoniker, pCtx, debugstr_w(lpcwstrFilterName), ppFilter); return S_OK; } -static HRESULT WINAPI FilterGraph2_ReconnectEx(IFilterGraph2 *iface, - IPin *ppin, - const AM_MEDIA_TYPE *pmt) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_ReconnectEx(IFilterGraph2 *iface, IPin *ppin, + const AM_MEDIA_TYPE *pmt) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(%p %p): stub !!!\n", This, iface, ppin, pmt); return S_OK; } -static HRESULT WINAPI FilterGraph2_RenderEx(IFilterGraph2 *iface, - IPin *pPinOut, - DWORD dwFlags, - DWORD *pvContext) { - ICOM_THIS_MULTI(IFilterGraphImpl, IFilterGraph2_vtbl, iface); +static HRESULT WINAPI FilterGraph2_RenderEx(IFilterGraph2 *iface, IPin *pPinOut, DWORD dwFlags, + DWORD *pvContext) +{ + IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); TRACE("(%p/%p)->(%p %08x %p): stub !!!\n", This, iface, pPinOut, dwFlags, pvContext); @@ -1695,78 +1789,74 @@ static const IFilterGraph2Vtbl IFilterGraph2_VTable = FilterGraph2_RenderEx }; -/*** IUnknown methods ***/ -static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static inline IFilterGraphImpl *impl_from_IMediaControl(IMediaControl *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IMediaControl_iface); +} + +static HRESULT WINAPI MediaControl_QueryInterface(IMediaControl *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static ULONG WINAPI MediaControl_AddRef(IMediaControl *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI MediaControl_Release(IMediaControl *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static ULONG WINAPI MediaControl_Release(IMediaControl *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } /*** IDispatch methods ***/ -static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_GetTypeInfoCount(IMediaControl *iface, UINT *pctinfo) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); return S_OK; } -static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_GetTypeInfo(IMediaControl *iface, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); return S_OK; } -static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_GetIDsOfNames(IMediaControl *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); return S_OK; } -static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, + UINT *puArgErr) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); @@ -1810,8 +1900,8 @@ static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundF for(i = 0; i < nb; i++) { /* Explore the graph downstream from this pin - * FIXME: We should prevent exploring from a pin more than once. This can happens when - * several input pins are connected to the same output (a MUX for instance). */ + * FIXME: We should prevent exploring from a pin more than once. This can happens when + * several input pins are connected to the same output (a MUX for instance). */ ExploreGraph(pGraph, ppPins[i], FoundFilter, data); IPin_Release(ppPins[i]); } @@ -1829,21 +1919,7 @@ static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundF static HRESULT WINAPI SendRun(IBaseFilter *pFilter, DWORD_PTR data) { - LONGLONG time = 0; - IReferenceClock *clock = NULL; - - IBaseFilter_GetSyncSource(pFilter, &clock); - if (clock) - { - IReferenceClock_GetTime(clock, &time); - if (time) - /* Add 50 ms */ - time += 500000; - if (time < 0) - time = 0; - IReferenceClock_Release(clock); - } - + REFERENCE_TIME time = *(REFERENCE_TIME*)data; return IBaseFilter_Run(pFilter, time); } @@ -1879,9 +1955,8 @@ static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data) } -static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter, DWORD_PTR data) +static HRESULT SendFilterMessage(IFilterGraphImpl *This, fnFoundFilter FoundFilter, DWORD_PTR data) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); int i; IBaseFilter* pfilter; IEnumPins* pEnum; @@ -1889,7 +1964,8 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter IPin* pPin; DWORD dummy; PIN_DIRECTION dir; - TRACE("(%p/%p)->()\n", This, iface); + + TRACE("(%p)->()\n", This); /* Explorer the graph from source filters to renderers, determine renderers * number and run filters from renderers to source filters */ @@ -1936,77 +2012,82 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter } /*** IMediaControl methods ***/ -static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); + TRACE("(%p/%p)->()\n", This, iface); - if (This->state == State_Running) return S_OK; - EnterCriticalSection(&This->cs); - if (This->state == State_Stopped) - This->EcCompleteCount = 0; + if (This->state == State_Running) + goto out; + This->EcCompleteCount = 0; + + if (This->defaultclock && !This->refClock) + IFilterGraph2_SetDefaultSyncSource(&This->IFilterGraph2_iface); if (This->refClock) { - IReferenceClock_GetTime(This->refClock, &This->start_time); - This->start_time += 500000; + REFERENCE_TIME now; + IReferenceClock_GetTime(This->refClock, &now); + if (This->state == State_Stopped) + This->start_time = now + 500000; + else if (This->pause_time >= 0) + This->start_time += now - This->pause_time; + else + This->start_time = now; } - else This->position = This->start_time = 0; + else This->start_time = 0; - SendFilterMessage(iface, SendRun, 0); + SendFilterMessage(This, SendRun, (DWORD_PTR)&This->start_time); This->state = State_Running; +out: LeaveCriticalSection(&This->cs); return S_FALSE; } -static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); + TRACE("(%p/%p)->()\n", This, iface); - if (This->state == State_Paused) return S_OK; - EnterCriticalSection(&This->cs); - if (This->state == State_Stopped) - This->EcCompleteCount = 0; + if (This->state == State_Paused) + goto out; - if (This->state == State_Running && This->refClock) - { - LONGLONG time = This->start_time; - IReferenceClock_GetTime(This->refClock, &time); - This->position += time - This->start_time; - } + if (This->state == State_Running && This->refClock && This->start_time >= 0) + IReferenceClock_GetTime(This->refClock, &This->pause_time); + else + This->pause_time = -1; - SendFilterMessage(iface, SendPause, 0); + SendFilterMessage(This, SendPause, 0); This->state = State_Paused; +out: LeaveCriticalSection(&This->cs); return S_FALSE; } -static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); + TRACE("(%p/%p)->()\n", This, iface); if (This->state == State_Stopped) return S_OK; EnterCriticalSection(&This->cs); - if (This->state == State_Running && This->refClock) - { - LONGLONG time = This->start_time; - IReferenceClock_GetTime(This->refClock, &time); - This->position += time - This->start_time; - } - - if (This->state == State_Running) SendFilterMessage(iface, SendPause, 0); - SendFilterMessage(iface, SendStop, 0); + if (This->state == State_Running) SendFilterMessage(This, SendPause, 0); + SendFilterMessage(This, SendStop, 0); This->state = State_Stopped; LeaveCriticalSection(&This->cs); return S_OK; } -static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface, - LONG msTimeout, - OAFilterState *pfs) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface, LONG msTimeout, + OAFilterState *pfs) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); DWORD end; TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pfs); @@ -2030,52 +2111,53 @@ static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface, end = 0; } if (end) - SendFilterMessage(iface, SendGetState, end); + SendFilterMessage(This, SendGetState, end); LeaveCriticalSection(&This->cs); return S_OK; } -static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface, - BSTR strFilename) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_RenderFile(IMediaControl *iface, BSTR strFilename) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); - FIXME("(%p/%p)->(%s (%p)): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename); + TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strFilename), strFilename); - return S_OK; + return IFilterGraph2_RenderFile(&This->IFilterGraph2_iface, strFilename, NULL); } -static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface, - BSTR strFilename, - IDispatch **ppUnk) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_AddSourceFilter(IMediaControl *iface, BSTR strFilename, + IDispatch **ppUnk) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); FIXME("(%p/%p)->(%s (%p), %p): stub !!!\n", This, iface, debugstr_w(strFilename), strFilename, ppUnk); return S_OK; } -static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface, - IDispatch **ppUnk) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_get_FilterCollection(IMediaControl *iface, IDispatch **ppUnk) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk); return S_OK; } -static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface, - IDispatch **ppUnk) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface, IDispatch **ppUnk) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, ppUnk); return S_OK; } -static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface); +static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaControl(iface); FIXME("(%p/%p)->(): stub !!!\n", This, iface); @@ -2103,32 +2185,36 @@ static const IMediaControlVtbl IMediaControl_VTable = MediaControl_StopWhenReady }; +static inline IFilterGraphImpl *impl_from_IMediaSeeking(IMediaSeeking *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IMediaSeeking_iface); +} -/*** IUnknown methods ***/ -static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_QueryInterface(IMediaSeeking *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } typedef HRESULT (WINAPI *fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DWORD_PTR arg); @@ -2136,53 +2222,34 @@ typedef HRESULT (WINAPI *fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DW static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek, DWORD_PTR arg) { BOOL allnotimpl = TRUE; int i; - IBaseFilter* pfilter; - IEnumPins* pEnum; HRESULT hr, hr_return = S_OK; - IPin* pPin; - DWORD dummy; - PIN_DIRECTION dir; TRACE("(%p)->(%p %08lx)\n", This, FoundSeek, arg); /* Send a message to all renderers, they are responsible for broadcasting it further */ for(i = 0; i < This->nFilters; i++) { - BOOL renderer = TRUE; - pfilter = This->ppFiltersInGraph[i]; - hr = IBaseFilter_EnumPins(pfilter, &pEnum); - if (hr != S_OK) - { - WARN("Enum pins failed %x\n", hr); + IMediaSeeking *seek = NULL; + IBaseFilter* pfilter = This->ppFiltersInGraph[i]; + IAMFilterMiscFlags *flags = NULL; + ULONG filterflags; + IBaseFilter_QueryInterface(pfilter, &IID_IAMFilterMiscFlags, (void**)&flags); + if (!flags) + continue; + filterflags = IAMFilterMiscFlags_GetMiscFlags(flags); + IAMFilterMiscFlags_Release(flags); + if (filterflags != AM_FILTER_MISC_FLAGS_IS_RENDERER) continue; - } - /* Check if it is a source filter */ - while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK) - { - IPin_QueryDirection(pPin, &dir); - IPin_Release(pPin); - if (dir != PINDIR_INPUT) - { - renderer = FALSE; - break; - } - } - IEnumPins_Release(pEnum); - if (renderer) - { - IMediaSeeking *seek = NULL; - IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek); - if (!seek) - continue; - hr = FoundSeek(This, seek, arg); - - IMediaSeeking_Release(seek); - if (hr_return != E_NOTIMPL) - allnotimpl = FALSE; - if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && SUCCEEDED(hr_return))) - hr_return = hr; - } + IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek); + if (!seek) + continue; + hr = FoundSeek(This, seek, arg); + IMediaSeeking_Release(seek); + if (hr_return != E_NOTIMPL) + allnotimpl = FALSE; + if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && SUCCEEDED(hr_return))) + hr_return = hr; } if (allnotimpl) @@ -2206,10 +2273,11 @@ static HRESULT WINAPI FoundCapabilities(IFilterGraphImpl *This, IMediaSeeking *s } /*** IMediaSeeking methods ***/ -static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface, - DWORD *pCapabilities) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface, DWORD *pCapabilities) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); HRESULT hr; + TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities); if (!pCapabilities) @@ -2224,11 +2292,12 @@ static HRESULT WINAPI MediaSeeking_GetCapabilities(IMediaSeeking *iface, return hr; } -static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface, - DWORD *pCapabilities) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface, DWORD *pCapabilities) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); DWORD originalcaps; HRESULT hr; + TRACE("(%p/%p)->(%p)\n", This, iface, pCapabilities); if (!pCapabilities) @@ -2249,9 +2318,9 @@ static HRESULT WINAPI MediaSeeking_CheckCapabilities(IMediaSeeking *iface, return S_OK; } -static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface, - const GUID *pFormat) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface, const GUID *pFormat) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); if (!pFormat) return E_POINTER; @@ -2267,9 +2336,9 @@ static HRESULT WINAPI MediaSeeking_IsFormatSupported(IMediaSeeking *iface, return S_OK; } -static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface, - GUID *pFormat) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *pFormat) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); if (!pFormat) return E_POINTER; @@ -2280,9 +2349,9 @@ static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(IMediaSeeking *iface, return S_OK; } -static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface, - GUID *pFormat) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface, GUID *pFormat) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); if (!pFormat) return E_POINTER; @@ -2293,9 +2362,9 @@ static HRESULT WINAPI MediaSeeking_GetTimeFormat(IMediaSeeking *iface, return S_OK; } -static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface, - const GUID *pFormat) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *pFormat) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); TRACE("(%p/%p)->(%p)\n", This, iface, pFormat); if (!pFormat) @@ -2307,9 +2376,9 @@ static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(IMediaSeeking *iface, return S_OK; } -static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface, - const GUID *pFormat) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface, const GUID *pFormat) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); if (!pFormat) return E_POINTER; @@ -2337,16 +2406,14 @@ static HRESULT WINAPI FoundDuration(IFilterGraphImpl *This, IMediaSeeking *seek, if (FAILED(hr)) return hr; - /* FIXME: Minimum or maximum duration? Assuming minimum */ - if (duration > 0 && *pdur < duration) + if (*pdur < duration) *pdur = duration; - return hr; } -static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, - LONGLONG *pDuration) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, LONGLONG *pDuration) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pDuration); @@ -2355,7 +2422,7 @@ static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, return E_POINTER; EnterCriticalSection(&This->cs); - *pDuration = -1; + *pDuration = 0; hr = all_renderers_seek(This, FoundDuration, (DWORD_PTR)pDuration); LeaveCriticalSection(&This->cs); @@ -2363,9 +2430,9 @@ static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, return hr; } -static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, - LONGLONG *pStop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *pStop) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); HRESULT hr = S_OK; TRACE("(%p/%p)->(%p)\n", This, iface, pStop); @@ -2379,32 +2446,29 @@ static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, hr = IMediaSeeking_GetDuration(iface, pStop); else *pStop = This->stop_position; - LeaveCriticalSection(&This->cs); return hr; } -static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface, - LONGLONG *pCurrent) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *pCurrent) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); LONGLONG time = 0; if (!pCurrent) return E_POINTER; EnterCriticalSection(&This->cs); - if (This->state == State_Running && This->refClock) + if (This->state == State_Running && This->refClock && This->start_time >= 0) { IReferenceClock_GetTime(This->refClock, &time); if (time) - time += This->position - This->start_time; - if (time < This->position) - time = This->position; - *pCurrent = time; + time -= This->start_time; } - else - *pCurrent = This->position; + if (This->pause_time > 0) + time += This->pause_time; + *pCurrent = time; LeaveCriticalSection(&This->cs); TRACE("Time: %u.%03u\n", (DWORD)(*pCurrent / 10000000), (DWORD)((*pCurrent / 10000)%1000)); @@ -2412,12 +2476,10 @@ static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface, return S_OK; } -static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface, - LONGLONG *pTarget, - const GUID *pTargetFormat, - LONGLONG Source, - const GUID *pSourceFormat) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *pTarget, + const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); FIXME("(%p/%p)->(%p, %p, 0x%s, %p): stub !!!\n", This, iface, pTarget, pTargetFormat, wine_dbgstr_longlong(Source), pSourceFormat); @@ -2437,12 +2499,10 @@ static HRESULT WINAPI found_setposition(IFilterGraphImpl *This, IMediaSeeking *s return IMediaSeeking_SetPositions(seek, args->current, args->curflags, args->stop, args->stopflags); } -static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, - LONGLONG *pCurrent, - DWORD dwCurrentFlags, - LONGLONG *pStop, - DWORD dwStopFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, LONGLONG *pCurrent, + DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); HRESULT hr = S_OK; FILTER_STATE state; struct pos_args args; @@ -2453,11 +2513,8 @@ static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, state = This->state; TRACE("State: %s\n", state == State_Running ? "Running" : (state == State_Paused ? "Paused" : (state == State_Stopped ? "Stopped" : "UNKNOWN"))); - if ((dwCurrentFlags & 0x7) == AM_SEEKING_AbsolutePositioning) - { - This->position = *pCurrent; - } - else if ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning) + if ((dwCurrentFlags & 0x7) != AM_SEEKING_AbsolutePositioning && + (dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning) FIXME("Adjust method %x not handled yet!\n", dwCurrentFlags & 0x7); if ((dwStopFlags & 0x7) == AM_SEEKING_AbsolutePositioning) @@ -2465,26 +2522,27 @@ static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, else if ((dwStopFlags & 0x7) != AM_SEEKING_NoPositioning) FIXME("Stop position not handled yet!\n"); + if (state == State_Running && !(dwCurrentFlags & AM_SEEKING_NoFlush)) + IMediaControl_Pause(&This->IMediaControl_iface); args.current = pCurrent; args.stop = pStop; args.curflags = dwCurrentFlags; args.stopflags = dwStopFlags; hr = all_renderers_seek(This, found_setposition, (DWORD_PTR)&args); - if (This->refClock && ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning)) - { - /* Update start time, prevents weird jumps */ - IReferenceClock_GetTime(This->refClock, &This->start_time); - } + if ((dwCurrentFlags & 0x7) != AM_SEEKING_NoPositioning) + This->pause_time = This->start_time = -1; + if (state == State_Running && !(dwCurrentFlags & AM_SEEKING_NoFlush)) + IMediaControl_Run(&This->IMediaControl_iface); LeaveCriticalSection(&This->cs); return hr; } -static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface, - LONGLONG *pCurrent, - LONGLONG *pStop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface, LONGLONG *pCurrent, + LONGLONG *pStop) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); HRESULT hr; TRACE("(%p/%p)->(%p, %p)\n", This, iface, pCurrent, pStop); @@ -2495,37 +2553,37 @@ static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface, return hr; } -static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface, - LONGLONG *pEarliest, - LONGLONG *pLatest) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface, LONGLONG *pEarliest, + LONGLONG *pLatest) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); FIXME("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pEarliest, pLatest); return S_OK; } -static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface, - double dRate) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface, double dRate) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); FIXME("(%p/%p)->(%f): stub !!!\n", This, iface, dRate); return S_OK; } -static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface, - double *pdRate) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface, double *pdRate) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pdRate); return S_OK; } -static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface, - LONGLONG *pllPreroll) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface); +static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface, LONGLONG *pllPreroll) +{ + IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pllPreroll); @@ -2557,9 +2615,9 @@ static const IMediaSeekingVtbl IMediaSeeking_VTable = MediaSeeking_GetPreroll }; -static inline IFilterGraphImpl *impl_from_IMediaPosition( IMediaPosition *iface ) +static inline IFilterGraphImpl *impl_from_IMediaPosition(IMediaPosition *iface) { - return (IFilterGraphImpl *)((char*)iface - FIELD_OFFSET(IFilterGraphImpl, IMediaPosition_vtbl)); + return CONTAINING_RECORD(iface, IFilterGraphImpl, IMediaPosition_iface); } /*** IUnknown methods ***/ @@ -2568,7 +2626,8 @@ static HRESULT WINAPI MediaPosition_QueryInterface(IMediaPosition* iface, REFIID IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface) @@ -2576,7 +2635,8 @@ static ULONG WINAPI MediaPosition_AddRef(IMediaPosition *iface) IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface) @@ -2584,84 +2644,138 @@ static ULONG WINAPI MediaPosition_Release(IMediaPosition *iface) IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + + return IUnknown_Release(This->outer_unk); } /*** IDispatch methods ***/ -static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo){ +static HRESULT WINAPI MediaPosition_GetTypeInfoCount(IMediaPosition *iface, UINT* pctinfo) +{ FIXME("(%p) stub!\n", iface); return E_NOTIMPL; } -static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo){ +static HRESULT WINAPI MediaPosition_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) +{ FIXME("(%p) stub!\n", iface); return E_NOTIMPL; } -static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId){ +static HRESULT WINAPI MediaPosition_GetIDsOfNames(IMediaPosition* iface, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) +{ FIXME("(%p) stub!\n", iface); return E_NOTIMPL; } -static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr){ +static HRESULT WINAPI MediaPosition_Invoke(IMediaPosition* iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) +{ FIXME("(%p) stub!\n", iface); return E_NOTIMPL; } +static HRESULT ConvertFromREFTIME(IMediaSeeking *seek, REFTIME time_in, LONGLONG *time_out) +{ + GUID time_format; + HRESULT hr; + + hr = MediaSeeking_GetTimeFormat(seek, &time_format); + if (FAILED(hr)) + return hr; + if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, &time_format)) + { + FIXME("Unsupported time format.\n"); + return E_NOTIMPL; + } + + *time_out = (LONGLONG) (time_in * 10000000); /* convert from 1 second intervals to 100 ns intervals */ + return S_OK; +} + +static HRESULT ConvertToREFTIME(IMediaSeeking *seek, LONGLONG time_in, REFTIME *time_out) +{ + GUID time_format; + HRESULT hr; + + hr = MediaSeeking_GetTimeFormat(seek, &time_format); + if (FAILED(hr)) + return hr; + if (!IsEqualGUID(&TIME_FORMAT_MEDIA_TIME, &time_format)) + { + FIXME("Unsupported time format.\n"); + return E_NOTIMPL; + } + + *time_out = (REFTIME)time_in / 10000000; /* convert from 100 ns intervals to 1 second intervals */ + return S_OK; +} + /*** IMediaPosition methods ***/ static HRESULT WINAPI MediaPosition_get_Duration(IMediaPosition * iface, REFTIME *plength) { LONGLONG duration; IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); - HRESULT hr = IMediaSeeking_GetDuration( (IMediaSeeking *)&This->IMediaSeeking_vtbl, &duration ); - if (SUCCEEDED(hr)) *plength = duration; - return hr; + HRESULT hr = IMediaSeeking_GetDuration(&This->IMediaSeeking_iface, &duration); + if (FAILED(hr)) + return hr; + return ConvertToREFTIME(&This->IMediaSeeking_iface, duration, plength); } static HRESULT WINAPI MediaPosition_put_CurrentPosition(IMediaPosition * iface, REFTIME llTime) { IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); - LONGLONG reftime = llTime; + LONGLONG reftime; + HRESULT hr; - return IMediaSeeking_SetPositions((IMediaSeeking *)&This->IMediaSeeking_vtbl, - &reftime, AM_SEEKING_AbsolutePositioning, - NULL, AM_SEEKING_NoPositioning); + hr = ConvertFromREFTIME(&This->IMediaSeeking_iface, llTime, &reftime); + if (FAILED(hr)) + return hr; + return IMediaSeeking_SetPositions(&This->IMediaSeeking_iface, &reftime, + AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); } static HRESULT WINAPI MediaPosition_get_CurrentPosition(IMediaPosition * iface, REFTIME *pllTime) { IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); LONGLONG pos; - HRESULT hr = IMediaSeeking_GetCurrentPosition( (IMediaSeeking *)&This->IMediaSeeking_vtbl, &pos ); - if (SUCCEEDED(hr)) *pllTime = pos; - return hr; + HRESULT hr; + + hr = IMediaSeeking_GetCurrentPosition(&This->IMediaSeeking_iface, &pos); + if (FAILED(hr)) + return hr; + return ConvertToREFTIME(&This->IMediaSeeking_iface, pos, pllTime); } static HRESULT WINAPI MediaPosition_get_StopTime(IMediaPosition * iface, REFTIME *pllTime) { IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); LONGLONG pos; - HRESULT hr = IMediaSeeking_GetStopPosition( (IMediaSeeking *)&This->IMediaSeeking_vtbl, &pos ); - if (SUCCEEDED(hr)) *pllTime = pos; - return hr; + HRESULT hr = IMediaSeeking_GetStopPosition(&This->IMediaSeeking_iface, &pos); + if (FAILED(hr)) + return hr; + return ConvertToREFTIME(&This->IMediaSeeking_iface, pos, pllTime); } static HRESULT WINAPI MediaPosition_put_StopTime(IMediaPosition * iface, REFTIME llTime) { IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); - LONGLONG reftime = llTime; + LONGLONG reftime; + HRESULT hr; - return IMediaSeeking_SetPositions((IMediaSeeking *)&This->IMediaSeeking_vtbl, - NULL, AM_SEEKING_NoPositioning, - &reftime, AM_SEEKING_AbsolutePositioning); + hr = ConvertFromREFTIME(&This->IMediaSeeking_iface, llTime, &reftime); + if (FAILED(hr)) + return hr; + return IMediaSeeking_SetPositions(&This->IMediaSeeking_iface, NULL, AM_SEEKING_NoPositioning, + &reftime, AM_SEEKING_AbsolutePositioning); } -static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime){ +static HRESULT WINAPI MediaPosition_get_PrerollTime(IMediaPosition * iface, REFTIME *pllTime) +{ FIXME("(%p)->(%p) stub!\n", iface, pllTime); return E_NOTIMPL; } -static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime){ +static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFTIME llTime) +{ FIXME("(%p)->(%f) stub!\n", iface, llTime); return E_NOTIMPL; } @@ -2669,21 +2783,23 @@ static HRESULT WINAPI MediaPosition_put_PrerollTime(IMediaPosition * iface, REFT static HRESULT WINAPI MediaPosition_put_Rate(IMediaPosition * iface, double dRate) { IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); - return IMediaSeeking_SetRate((IMediaSeeking *)&This->IMediaSeeking_vtbl, dRate); + return IMediaSeeking_SetRate(&This->IMediaSeeking_iface, dRate); } static HRESULT WINAPI MediaPosition_get_Rate(IMediaPosition * iface, double *pdRate) { IFilterGraphImpl *This = impl_from_IMediaPosition( iface ); - return IMediaSeeking_GetRate((IMediaSeeking *)&This->IMediaSeeking_vtbl, pdRate); + return IMediaSeeking_GetRate(&This->IMediaSeeking_iface, pdRate); } -static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward){ +static HRESULT WINAPI MediaPosition_CanSeekForward(IMediaPosition * iface, LONG *pCanSeekForward) +{ FIXME("(%p)->(%p) stub!\n", iface, pCanSeekForward); return E_NOTIMPL; } -static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward){ +static HRESULT WINAPI MediaPosition_CanSeekBackward(IMediaPosition * iface, LONG *pCanSeekBackward) +{ FIXME("(%p)->(%p) stub!\n", iface, pCanSeekBackward); return E_NOTIMPL; } @@ -2711,6 +2827,74 @@ static const IMediaPositionVtbl IMediaPosition_VTable = MediaPosition_CanSeekBackward }; +static inline IFilterGraphImpl *impl_from_IObjectWithSite(IObjectWithSite *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IObjectWithSite_iface); +} + +/*** IUnknown methods ***/ +static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite* iface, REFIID riid, void** ppvObj) +{ + IFilterGraphImpl *This = impl_from_IObjectWithSite( iface ); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); +} + +static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface) +{ + IFilterGraphImpl *This = impl_from_IObjectWithSite( iface ); + + TRACE("(%p/%p)->()\n", This, iface); + + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface) +{ + IFilterGraphImpl *This = impl_from_IObjectWithSite( iface ); + + TRACE("(%p/%p)->()\n", This, iface); + + return IUnknown_Release(This->outer_unk); +} + +/*** IObjectWithSite methods ***/ + +static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite) +{ + IFilterGraphImpl *This = impl_from_IObjectWithSite( iface ); + + TRACE("(%p/%p)->()\n", This, iface); + if (This->pSite) IUnknown_Release(This->pSite); + This->pSite = pUnkSite; + IUnknown_AddRef(This->pSite); + return S_OK; +} + +static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID riid, PVOID *ppvSite) +{ + IFilterGraphImpl *This = impl_from_IObjectWithSite( iface ); + + TRACE("(%p/%p)->(%s)\n", This, iface,debugstr_guid(riid)); + + *ppvSite = NULL; + if (!This->pSite) + return E_FAIL; + else + return IUnknown_QueryInterface(This->pSite, riid, ppvSite); +} + +static const IObjectWithSiteVtbl IObjectWithSite_VTable = +{ + ObjectWithSite_QueryInterface, + ObjectWithSite_AddRef, + ObjectWithSite_Release, + ObjectWithSite_SetSite, + ObjectWithSite_GetSite, +}; + static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj) { HRESULT hr = E_NOINTERFACE; @@ -2756,37 +2940,42 @@ static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* return hr; } -/*** IUnknown methods ***/ -static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static inline IFilterGraphImpl *impl_from_IBasicAudio(IBasicAudio *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IBasicAudio_iface); +} + +static HRESULT WINAPI BasicAudio_QueryInterface(IBasicAudio *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static ULONG WINAPI BasicAudio_AddRef(IBasicAudio *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static ULONG WINAPI BasicAudio_Release(IBasicAudio *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } /*** IDispatch methods ***/ -static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface, UINT *pctinfo) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2804,11 +2993,10 @@ static HRESULT WINAPI BasicAudio_GetTypeInfoCount(IBasicAudio *iface, return hr; } -static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2826,13 +3014,10 @@ static HRESULT WINAPI BasicAudio_GetTypeInfo(IBasicAudio *iface, return hr; } -static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2850,16 +3035,11 @@ static HRESULT WINAPI BasicAudio_GetIDsOfNames(IBasicAudio *iface, return hr; } -static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, + UINT *puArgErr) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2878,9 +3058,9 @@ static HRESULT WINAPI BasicAudio_Invoke(IBasicAudio *iface, } /*** IBasicAudio methods ***/ -static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface, - LONG lVolume) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface, LONG lVolume) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2898,9 +3078,9 @@ static HRESULT WINAPI BasicAudio_put_Volume(IBasicAudio *iface, return hr; } -static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface, - LONG *plVolume) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface, LONG *plVolume) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2918,9 +3098,9 @@ static HRESULT WINAPI BasicAudio_get_Volume(IBasicAudio *iface, return hr; } -static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface, - LONG lBalance) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface, LONG lBalance) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2938,9 +3118,9 @@ static HRESULT WINAPI BasicAudio_put_Balance(IBasicAudio *iface, return hr; } -static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface, - LONG *plBalance) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicAudio_vtbl, iface); +static HRESULT WINAPI BasicAudio_get_Balance(IBasicAudio *iface, LONG *plBalance) +{ + IFilterGraphImpl *This = impl_from_IBasicAudio(iface); IBasicAudio* pBasicAudio; HRESULT hr; @@ -2973,38 +3153,43 @@ static const IBasicAudioVtbl IBasicAudio_VTable = BasicAudio_get_Balance }; -/*** IUnknown methods ***/ -static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo2 *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); +static inline IFilterGraphImpl *impl_from_IBasicVideo2(IBasicVideo2 *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IBasicVideo2_iface); +} + +static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo2 *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI BasicVideo_AddRef(IBasicVideo2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); +static ULONG WINAPI BasicVideo_AddRef(IBasicVideo2 *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI BasicVideo_Release(IBasicVideo2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); +static ULONG WINAPI BasicVideo_Release(IBasicVideo2 *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } /*** IDispatch methods ***/ -static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo2 *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo2 *iface, UINT *pctinfo) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo); @@ -3021,12 +3206,11 @@ static HRESULT WINAPI BasicVideo_GetTypeInfoCount(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo2 *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo2 *iface, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo); @@ -3043,14 +3227,11 @@ static HRESULT WINAPI BasicVideo_GetTypeInfo(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo2 *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo2 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); @@ -3067,17 +3248,12 @@ static HRESULT WINAPI BasicVideo_GetIDsOfNames(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo2 *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo2 *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, + UINT *puArgErr) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p)\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); @@ -3095,10 +3271,10 @@ static HRESULT WINAPI BasicVideo_Invoke(IBasicVideo2 *iface, } /*** IBasicVideo methods ***/ -static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo2 *iface, - REFTIME *pAvgTimePerFrame) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo2 *iface, REFTIME *pAvgTimePerFrame) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); @@ -3115,10 +3291,10 @@ static HRESULT WINAPI BasicVideo_get_AvgTimePerFrame(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo2 *iface, - LONG *pBitRate) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo2 *iface, LONG *pBitRate) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate); @@ -3135,10 +3311,10 @@ static HRESULT WINAPI BasicVideo_get_BitRate(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo2 *iface, - LONG *pBitErrorRate) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo2 *iface, LONG *pBitErrorRate) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate); @@ -3155,10 +3331,10 @@ static HRESULT WINAPI BasicVideo_get_BitErrorRate(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo2 *iface, - LONG *pVideoWidth) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo2 *iface, LONG *pVideoWidth) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth); @@ -3175,10 +3351,10 @@ static HRESULT WINAPI BasicVideo_get_VideoWidth(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo2 *iface, - LONG *pVideoHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo2 *iface, LONG *pVideoHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight); @@ -3195,10 +3371,10 @@ static HRESULT WINAPI BasicVideo_get_VideoHeight(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo2 *iface, - LONG SourceLeft) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo2 *iface, LONG SourceLeft) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft); @@ -3215,10 +3391,10 @@ static HRESULT WINAPI BasicVideo_put_SourceLeft(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo2 *iface, - LONG *pSourceLeft) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo2 *iface, LONG *pSourceLeft) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft); @@ -3235,10 +3411,10 @@ static HRESULT WINAPI BasicVideo_get_SourceLeft(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo2 *iface, - LONG SourceWidth) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo2 *iface, LONG SourceWidth) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth); @@ -3255,10 +3431,10 @@ static HRESULT WINAPI BasicVideo_put_SourceWidth(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo2 *iface, - LONG *pSourceWidth) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo2 *iface, LONG *pSourceWidth) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth); @@ -3275,10 +3451,10 @@ static HRESULT WINAPI BasicVideo_get_SourceWidth(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo2 *iface, - LONG SourceTop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo2 *iface, LONG SourceTop) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop); @@ -3295,10 +3471,10 @@ static HRESULT WINAPI BasicVideo_put_SourceTop(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo2 *iface, - LONG *pSourceTop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo2 *iface, LONG *pSourceTop) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop); @@ -3315,10 +3491,10 @@ static HRESULT WINAPI BasicVideo_get_SourceTop(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo2 *iface, - LONG SourceHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo2 *iface, LONG SourceHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight); @@ -3335,10 +3511,10 @@ static HRESULT WINAPI BasicVideo_put_SourceHeight(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo2 *iface, - LONG *pSourceHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo2 *iface, LONG *pSourceHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight); @@ -3355,10 +3531,10 @@ static HRESULT WINAPI BasicVideo_get_SourceHeight(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo2 *iface, - LONG DestinationLeft) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo2 *iface, LONG DestinationLeft) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft); @@ -3375,10 +3551,10 @@ static HRESULT WINAPI BasicVideo_put_DestinationLeft(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo2 *iface, - LONG *pDestinationLeft) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo2 *iface, LONG *pDestinationLeft) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft); @@ -3395,10 +3571,10 @@ static HRESULT WINAPI BasicVideo_get_DestinationLeft(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo2 *iface, - LONG DestinationWidth) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo2 *iface, LONG DestinationWidth) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth); @@ -3415,10 +3591,10 @@ static HRESULT WINAPI BasicVideo_put_DestinationWidth(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo2 *iface, - LONG *pDestinationWidth) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo2 *iface, LONG *pDestinationWidth) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth); @@ -3435,10 +3611,10 @@ static HRESULT WINAPI BasicVideo_get_DestinationWidth(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo2 *iface, - LONG DestinationTop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo2 *iface, LONG DestinationTop) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop); @@ -3455,10 +3631,10 @@ static HRESULT WINAPI BasicVideo_put_DestinationTop(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo2 *iface, - LONG *pDestinationTop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo2 *iface, LONG *pDestinationTop) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop); @@ -3475,10 +3651,10 @@ static HRESULT WINAPI BasicVideo_get_DestinationTop(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo2 *iface, - LONG DestinationHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo2 *iface, LONG DestinationHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight); @@ -3496,9 +3672,10 @@ static HRESULT WINAPI BasicVideo_put_DestinationHeight(IBasicVideo2 *iface, } static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo2 *iface, - LONG *pDestinationHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; + LONG *pDestinationHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight); @@ -3515,13 +3692,11 @@ static HRESULT WINAPI BasicVideo_get_DestinationHeight(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo2 *iface, - LONG Left, - LONG Top, - LONG Width, - LONG Height) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo2 *iface, LONG Left, LONG Top, + LONG Width, LONG Height) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); @@ -3538,13 +3713,11 @@ static HRESULT WINAPI BasicVideo_SetSourcePosition(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo2 *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo2 *iface, LONG *pLeft, LONG *pTop, + LONG *pWidth, LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); @@ -3561,9 +3734,10 @@ static HRESULT WINAPI BasicVideo_GetSourcePosition(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo2 *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->()\n", This, iface); @@ -3580,13 +3754,11 @@ static HRESULT WINAPI BasicVideo_SetDefaultSourcePosition(IBasicVideo2 *iface) { return hr; } -static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo2 *iface, - LONG Left, - LONG Top, - LONG Width, - LONG Height) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo2 *iface, LONG Left, LONG Top, + LONG Width, LONG Height) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); @@ -3603,13 +3775,11 @@ static HRESULT WINAPI BasicVideo_SetDestinationPosition(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo2 *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo2 *iface, LONG *pLeft, + LONG *pTop, LONG *pWidth, LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); @@ -3626,9 +3796,10 @@ static HRESULT WINAPI BasicVideo_GetDestinationPosition(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo2 *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->()\n", This, iface); @@ -3645,11 +3816,10 @@ static HRESULT WINAPI BasicVideo_SetDefaultDestinationPosition(IBasicVideo2 *ifa return hr; } -static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo2 *iface, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo2 *iface, LONG *pWidth, LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); @@ -3666,13 +3836,11 @@ static HRESULT WINAPI BasicVideo_GetVideoSize(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo2 *iface, - LONG StartIndex, - LONG Entries, - LONG *pRetrieved, - LONG *pPalette) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo2 *iface, LONG StartIndex, + LONG Entries, LONG *pRetrieved, LONG *pPalette) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette); @@ -3689,11 +3857,11 @@ static HRESULT WINAPI BasicVideo_GetVideoPaletteEntries(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo2 *iface, - LONG *pBufferSize, - LONG *pDIBImage) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo2 *iface, LONG *pBufferSize, + LONG *pDIBImage) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->(%p, %p)\n", This, iface, pBufferSize, pDIBImage); @@ -3710,9 +3878,10 @@ static HRESULT WINAPI BasicVideo_GetCurrentImage(IBasicVideo2 *iface, return hr; } -static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo2 *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->()\n", This, iface); @@ -3729,9 +3898,10 @@ static HRESULT WINAPI BasicVideo_IsUsingDefaultSource(IBasicVideo2 *iface) { return hr; } -static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo2 *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); - IBasicVideo* pBasicVideo; +static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo2 *iface) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); + IBasicVideo *pBasicVideo; HRESULT hr; TRACE("(%p/%p)->()\n", This, iface); @@ -3748,8 +3918,10 @@ static HRESULT WINAPI BasicVideo_IsUsingDefaultDestination(IBasicVideo2 *iface) return hr; } -static HRESULT WINAPI BasicVideo2_GetPreferredAspectRatio(IBasicVideo2 *iface, LONG *plAspectX, LONG *plAspectY) { - ICOM_THIS_MULTI(IFilterGraphImpl, IBasicVideo_vtbl, iface); +static HRESULT WINAPI BasicVideo2_GetPreferredAspectRatio(IBasicVideo2 *iface, LONG *plAspectX, + LONG *plAspectY) +{ + IFilterGraphImpl *This = impl_from_IBasicVideo2(iface); IBasicVideo2 *pBasicVideo2; HRESULT hr; @@ -3811,39 +3983,43 @@ static const IBasicVideo2Vtbl IBasicVideo_VTable = BasicVideo2_GetPreferredAspectRatio }; +static inline IFilterGraphImpl *impl_from_IVideoWindow(IVideoWindow *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IVideoWindow_iface); +} -/*** IUnknown methods ***/ -static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); +static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); +static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); +static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } /*** IDispatch methods ***/ -static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface, UINT *pctinfo) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pctinfo); @@ -3860,12 +4036,11 @@ static HRESULT WINAPI VideoWindow_GetTypeInfoCount(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d, %d, %p)\n", This, iface, iTInfo, lcid, ppTInfo); @@ -3882,14 +4057,11 @@ static HRESULT WINAPI VideoWindow_GetTypeInfo(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p)\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); @@ -3906,17 +4078,12 @@ static HRESULT WINAPI VideoWindow_GetIDsOfNames(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, + UINT*puArgErr) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p)\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); @@ -3935,12 +4102,12 @@ static HRESULT WINAPI VideoWindow_Invoke(IVideoWindow *iface, /*** IVideoWindow methods ***/ -static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface, - BSTR strCaption) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface, BSTR strCaption) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; - + TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption); EnterCriticalSection(&This->cs); @@ -3955,10 +4122,10 @@ static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface, - BSTR *strCaption) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface, BSTR *strCaption) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, strCaption); @@ -3975,10 +4142,10 @@ static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface, - LONG WindowStyle) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface, LONG WindowStyle) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyle); @@ -3995,10 +4162,10 @@ static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface, - LONG *WindowStyle) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface, LONG *WindowStyle) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle); @@ -4015,10 +4182,10 @@ static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface, - LONG WindowStyleEx) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface, LONG WindowStyleEx) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx); @@ -4035,10 +4202,10 @@ static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface, - LONG *WindowStyleEx) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface, LONG *WindowStyleEx) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx); @@ -4055,10 +4222,10 @@ static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface, - LONG AutoShow) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface, LONG AutoShow) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow); @@ -4075,10 +4242,10 @@ static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface, - LONG *AutoShow) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface, LONG *AutoShow) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow); @@ -4095,10 +4262,10 @@ static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface, - LONG WindowState) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface, LONG WindowState) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, WindowState); @@ -4115,10 +4282,10 @@ static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface, - LONG *WindowState) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface, LONG *WindowState) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, WindowState); @@ -4135,10 +4302,10 @@ static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface, - LONG BackgroundPalette) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface, LONG BackgroundPalette) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, BackgroundPalette); @@ -4156,9 +4323,10 @@ static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface, } static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface, - LONG *pBackgroundPalette) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; + LONG *pBackgroundPalette) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pBackgroundPalette); @@ -4175,10 +4343,10 @@ static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface, - LONG Visible) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface, LONG Visible) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Visible); @@ -4195,10 +4363,10 @@ static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface, - LONG *pVisible) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface, LONG *pVisible) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pVisible); @@ -4215,10 +4383,10 @@ static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface, - LONG Left) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface, LONG Left) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Left); @@ -4235,10 +4403,10 @@ static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface, - LONG *pLeft) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface, LONG *pLeft) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pLeft); @@ -4255,10 +4423,10 @@ static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface, - LONG Width) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface, LONG Width) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Width); @@ -4275,10 +4443,10 @@ static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface, - LONG *pWidth) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface, LONG *pWidth) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pWidth); @@ -4295,10 +4463,10 @@ static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface, - LONG Top) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface, LONG Top) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Top); @@ -4315,10 +4483,10 @@ static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface, - LONG *pTop) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface, LONG *pTop) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pTop); @@ -4335,10 +4503,10 @@ static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface, - LONG Height) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface, LONG Height) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Height); @@ -4355,10 +4523,10 @@ static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface, LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, pHeight); @@ -4375,10 +4543,10 @@ static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface, - OAHWND Owner) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface, OAHWND Owner) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner); @@ -4395,10 +4563,10 @@ static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface, - OAHWND *Owner) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface, OAHWND *Owner) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, Owner); @@ -4415,10 +4583,10 @@ static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface, - OAHWND Drain) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface, OAHWND Drain) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain); @@ -4435,10 +4603,10 @@ static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface, - OAHWND *Drain) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface, OAHWND *Drain) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, Drain); @@ -4455,10 +4623,10 @@ static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface, - LONG *Color) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface, LONG *Color) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, Color); @@ -4475,10 +4643,10 @@ static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface, - LONG Color) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface, LONG Color) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Color); @@ -4495,10 +4663,10 @@ static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, - LONG *FullScreenMode) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode); @@ -4515,10 +4683,10 @@ static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, - LONG FullScreenMode) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, LONG FullScreenMode) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, FullScreenMode); @@ -4535,10 +4703,10 @@ static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface, - LONG Focus) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface, LONG Focus) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, Focus); @@ -4555,13 +4723,11 @@ static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface, - OAHWND hwnd, - LONG uMsg, - LONG_PTR wParam, - LONG_PTR lParam) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface, OAHWND hwnd, LONG uMsg, + LONG_PTR wParam, LONG_PTR lParam) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This, iface, hwnd, uMsg, wParam, lParam); @@ -4578,13 +4744,11 @@ static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface, - LONG Left, - LONG Top, - LONG Width, - LONG Height) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface, LONG Left, LONG Top, + LONG Width, LONG Height) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); @@ -4601,13 +4765,11 @@ static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, + LONG *pWidth, LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); @@ -4624,11 +4786,11 @@ static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface, LONG *pWidth, + LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); @@ -4645,11 +4807,11 @@ static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface, LONG *pWidth, + LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); @@ -4666,13 +4828,11 @@ static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, + LONG *pWidth, LONG *pHeight) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); @@ -4689,10 +4849,10 @@ static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface, - LONG HideCursor) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface, LONG HideCursor) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%d)\n", This, iface, HideCursor); @@ -4709,10 +4869,10 @@ static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface, return hr; } -static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface, - LONG *CursorHidden) { - ICOM_THIS_MULTI(IFilterGraphImpl, IVideoWindow_vtbl, iface); - IVideoWindow* pVideoWindow; +static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface, LONG *CursorHidden) +{ + IFilterGraphImpl *This = impl_from_IVideoWindow(iface); + IVideoWindow *pVideoWindow; HRESULT hr; TRACE("(%p/%p)->(%p)\n", This, iface, CursorHidden); @@ -4780,78 +4940,73 @@ static const IVideoWindowVtbl IVideoWindow_VTable = VideoWindow_IsCursorHidden }; +static inline IFilterGraphImpl *impl_from_IMediaEventEx(IMediaEventEx *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IMediaEventEx_iface); +} -/*** IUnknown methods ***/ -static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_QueryInterface(IMediaEventEx *iface, REFIID riid, void **ppvObj) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return Filtergraph_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static ULONG WINAPI MediaEvent_AddRef(IMediaEventEx *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static ULONG WINAPI MediaEvent_Release(IMediaEventEx *iface) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->()\n", This, iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } /*** IDispatch methods ***/ -static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_GetTypeInfoCount(IMediaEventEx *iface, UINT *pctinfo) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); return S_OK; } -static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_GetTypeInfo(IMediaEventEx *iface, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); return S_OK; } -static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_GetIDsOfNames(IMediaEventEx *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); return S_OK; } -static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, + UINT *puArgErr) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); @@ -4859,9 +5014,9 @@ static HRESULT WINAPI MediaEvent_Invoke(IMediaEventEx *iface, } /*** IMediaEvent methods ***/ -static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface, - OAEVENT *hEvent) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface, OAEVENT *hEvent) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%p)\n", This, iface, hEvent); @@ -4870,12 +5025,10 @@ static HRESULT WINAPI MediaEvent_GetEventHandle(IMediaEventEx *iface, return S_OK; } -static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, - LONG *lEventCode, - LONG_PTR *lParam1, - LONG_PTR *lParam2, - LONG msTimeout) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, LONG *lEventCode, LONG_PTR *lParam1, + LONG_PTR *lParam2, LONG msTimeout) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); Event evt; TRACE("(%p/%p)->(%p, %p, %p, %d)\n", This, iface, lEventCode, lParam1, lParam2, msTimeout); @@ -4892,10 +5045,10 @@ static HRESULT WINAPI MediaEvent_GetEvent(IMediaEventEx *iface, return E_ABORT; } -static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface, - LONG msTimeout, - LONG *pEvCode) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface, LONG msTimeout, + LONG *pEvCode) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pEvCode); @@ -4912,9 +5065,9 @@ static HRESULT WINAPI MediaEvent_WaitForCompletion(IMediaEventEx *iface, return E_ABORT; } -static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface, - LONG lEvCode) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface, LONG lEvCode) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d)\n", This, iface, lEvCode); @@ -4930,9 +5083,9 @@ static HRESULT WINAPI MediaEvent_CancelDefaultHandling(IMediaEventEx *iface, return S_OK; } -static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface, - LONG lEvCode) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface, LONG lEvCode) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d)\n", This, iface, lEvCode); @@ -4948,11 +5101,10 @@ static HRESULT WINAPI MediaEvent_RestoreDefaultHandling(IMediaEventEx *iface, return S_OK; } -static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface, - LONG lEvCode, - LONG_PTR lParam1, - LONG_PTR lParam2) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface, LONG lEvCode, + LONG_PTR lParam1, LONG_PTR lParam2) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d, %08lx, %08lx): stub !!!\n", This, iface, lEvCode, lParam1, lParam2); @@ -4960,11 +5112,10 @@ static HRESULT WINAPI MediaEvent_FreeEventParams(IMediaEventEx *iface, } /*** IMediaEventEx methods ***/ -static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface, - OAHWND hwnd, - LONG lMsg, - LONG_PTR lInstanceData) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface, OAHWND hwnd, LONG lMsg, + LONG_PTR lInstanceData) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%08lx, %d, %08lx)\n", This, iface, hwnd, lMsg, lInstanceData); @@ -4975,9 +5126,9 @@ static HRESULT WINAPI MediaEvent_SetNotifyWindow(IMediaEventEx *iface, return S_OK; } -static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface, - LONG lNoNotifyFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface, LONG lNoNotifyFlags) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%d)\n", This, iface, lNoNotifyFlags); @@ -4989,9 +5140,9 @@ static HRESULT WINAPI MediaEvent_SetNotifyFlags(IMediaEventEx *iface, return S_OK; } -static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface, - LONG *lplNoNotifyFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventEx_vtbl, iface); +static HRESULT WINAPI MediaEvent_GetNotifyFlags(IMediaEventEx *iface, LONG *lplNoNotifyFlags) +{ + IFilterGraphImpl *This = impl_from_IMediaEventEx(iface); TRACE("(%p/%p)->(%p)\n", This, iface, lplNoNotifyFlags); @@ -5025,25 +5176,30 @@ static const IMediaEventExVtbl IMediaEventEx_VTable = }; -static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, LPVOID *ppv) +static inline IFilterGraphImpl *impl_from_IMediaFilter(IMediaFilter *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + return CONTAINING_RECORD(iface, IFilterGraphImpl, IMediaFilter_iface); +} - return Filtergraph_QueryInterface(This, riid, ppv); +static HRESULT WINAPI MediaFilter_QueryInterface(IMediaFilter *iface, REFIID riid, void **ppv) +{ + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } static ULONG WINAPI MediaFilter_AddRef(IMediaFilter *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI MediaFilter_Release(IMediaFilter *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClassID) @@ -5055,31 +5211,40 @@ static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClass static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); - return MediaControl_Stop((IMediaControl*)&This->IMediaControl_vtbl); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); + + return MediaControl_Stop(&This->IMediaControl_iface); } static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); - return MediaControl_Pause((IMediaControl*)&This->IMediaControl_vtbl); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); + + return MediaControl_Pause(&This->IMediaControl_iface); } static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME tStart) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); - return MediaControl_Run((IMediaControl*)&This->IMediaControl_vtbl); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); + + if (tStart) + FIXME("Run called with non-null tStart: %x%08x\n", + (int)(tStart>>32), (int)tStart); + + return MediaControl_Run(&This->IMediaControl_iface); } -static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, FILTER_STATE * pState) +static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeout, + FILTER_STATE *pState) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); - return MediaControl_GetState((IMediaControl*)&This->IMediaControl_vtbl, dwMsTimeout, (OAFilterState*)pState); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); + + return MediaControl_GetState(&This->IMediaControl_iface, dwMsTimeout, (OAFilterState*)pState); } static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); HRESULT hr = S_OK; int i; @@ -5106,6 +5271,7 @@ static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceC This->refClock = pClock; if (This->refClock) IReferenceClock_AddRef(This->refClock); + This->defaultclock = FALSE; if (This->HandleEcClockChanged) { @@ -5128,7 +5294,7 @@ static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceC static HRESULT WINAPI MediaFilter_GetSyncSource(IMediaFilter *iface, IReferenceClock **ppClock) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaFilter_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaFilter(iface); TRACE("(%p/%p)->(%p)\n", iface, This, ppClock); @@ -5160,30 +5326,36 @@ static const IMediaFilterVtbl IMediaFilter_VTable = MediaFilter_GetSyncSource }; -static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, LPVOID *ppv) +static inline IFilterGraphImpl *impl_from_IMediaEventSink(IMediaEventSink *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface); + return CONTAINING_RECORD(iface, IFilterGraphImpl, IMediaEventSink_iface); +} - return Filtergraph_QueryInterface(This, riid, ppv); +static HRESULT WINAPI MediaEventSink_QueryInterface(IMediaEventSink *iface, REFIID riid, void **ppv) +{ + IFilterGraphImpl *This = impl_from_IMediaEventSink(iface); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } static ULONG WINAPI MediaEventSink_AddRef(IMediaEventSink *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaEventSink(iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI MediaEventSink_Release(IMediaEventSink *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaEventSink(iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } -static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG EventCode, LONG_PTR EventParam1, LONG_PTR EventParam2) +static HRESULT WINAPI MediaEventSink_Notify(IMediaEventSink *iface, LONG EventCode, + LONG_PTR EventParam1, LONG_PTR EventParam2) { - ICOM_THIS_MULTI(IFilterGraphImpl, IMediaEventSink_vtbl, iface); + IFilterGraphImpl *This = impl_from_IMediaEventSink(iface); Event evt; TRACE("(%p/%p)->(%d, %ld, %ld)\n", This, iface, EventCode, EventParam1, EventParam2); @@ -5236,49 +5408,47 @@ static const IMediaEventSinkVtbl IMediaEventSink_VTable = MediaEventSink_Notify }; -static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, LPVOID *ppv) +static inline IFilterGraphImpl *impl_from_IGraphConfig(IGraphConfig *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + return CONTAINING_RECORD(iface, IFilterGraphImpl, IGraphConfig_iface); +} - return Filtergraph_QueryInterface(This, riid, ppv); +static HRESULT WINAPI GraphConfig_QueryInterface(IGraphConfig *iface, REFIID riid, void **ppv) +{ + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } static ULONG WINAPI GraphConfig_AddRef(IGraphConfig *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); - return Filtergraph_AddRef(This); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI GraphConfig_Release(IGraphConfig *iface) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); - return Filtergraph_Release(This); + return IUnknown_Release(This->outer_unk); } -static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface, - IPin* pOutputPin, - IPin* pInputPin, - const AM_MEDIA_TYPE* pmtFirstConnection, - IBaseFilter* pUsingFilter, - HANDLE hAbortEvent, - DWORD dwFlags) +static HRESULT WINAPI GraphConfig_Reconnect(IGraphConfig *iface, IPin *pOutputPin, IPin *pInputPin, + const AM_MEDIA_TYPE *pmtFirstConnection, IBaseFilter *pUsingFilter, HANDLE hAbortEvent, + DWORD dwFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p, %p, %p, %p, %p, %x): stub!\n", This, pOutputPin, pInputPin, pmtFirstConnection, pUsingFilter, hAbortEvent, dwFlags); return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface, - IGraphConfigCallback* pCallback, - PVOID pvContext, - DWORD dwFlags, - HANDLE hAbortEvent) +static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface, IGraphConfigCallback *pCallback, + void *pvContext, DWORD dwFlags, HANDLE hAbortEvent) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); HRESULT hr; WARN("(%p)->(%p, %p, %x, %p): partial stub!\n", This, pCallback, pvContext, dwFlags, hAbortEvent); @@ -5295,88 +5465,79 @@ static HRESULT WINAPI GraphConfig_Reconfigure(IGraphConfig *iface, return hr; } -static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface, - IBaseFilter* pFilter) +static HRESULT WINAPI GraphConfig_AddFilterToCache(IGraphConfig *iface, IBaseFilter *pFilter) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p): stub!\n", This, pFilter); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface, - IEnumFilters** pEnum) +static HRESULT WINAPI GraphConfig_EnumCacheFilter(IGraphConfig *iface, IEnumFilters **pEnum) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p): stub!\n", This, pEnum); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface, - IBaseFilter* pFilter) +static HRESULT WINAPI GraphConfig_RemoveFilterFromCache(IGraphConfig *iface, IBaseFilter *pFilter) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p): stub!\n", This, pFilter); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface, - REFERENCE_TIME* prtStart) +static HRESULT WINAPI GraphConfig_GetStartTime(IGraphConfig *iface, REFERENCE_TIME *prtStart) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p): stub!\n", This, prtStart); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface, - IPin* pOutputPin, - IPinConnection* pConnection, - HANDLE hEventAbort) +static HRESULT WINAPI GraphConfig_PushThroughData(IGraphConfig *iface, IPin *pOutputPin, + IPinConnection *pConnection, HANDLE hEventAbort) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p, %p, %p): stub!\n", This, pOutputPin, pConnection, hEventAbort); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface, - IBaseFilter* pFilter, - DWORD dwFlags) +static HRESULT WINAPI GraphConfig_SetFilterFlags(IGraphConfig *iface, IBaseFilter *pFilter, + DWORD dwFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface, - IBaseFilter* pFilter, - DWORD* dwFlags) +static HRESULT WINAPI GraphConfig_GetFilterFlags(IGraphConfig *iface, IBaseFilter *pFilter, + DWORD *dwFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p, %p): stub!\n", This, pFilter, dwFlags); - + return E_NOTIMPL; } -static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface, - IBaseFilter* pFilter, - DWORD dwFlags) +static HRESULT WINAPI GraphConfig_RemoveFilterEx(IGraphConfig *iface, IBaseFilter *pFilter, + DWORD dwFlags) { - ICOM_THIS_MULTI(IFilterGraphImpl, IGraphConfig_vtbl, iface); + IFilterGraphImpl *This = impl_from_IGraphConfig(iface); FIXME("(%p)->(%p, %x): stub!\n", This, pFilter, dwFlags); - + return E_NOTIMPL; } @@ -5397,6 +5558,53 @@ static const IGraphConfigVtbl IGraphConfig_VTable = GraphConfig_RemoveFilterEx }; +static inline IFilterGraphImpl *impl_from_IGraphVersion(IGraphVersion *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IGraphVersion_iface); +} + +static HRESULT WINAPI GraphVersion_QueryInterface(IGraphVersion *iface, REFIID riid, void **ppv) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); +} + +static ULONG WINAPI GraphVersion_AddRef(IGraphVersion *iface) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI GraphVersion_Release(IGraphVersion *iface) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + return IUnknown_Release(This->outer_unk); +} + +static HRESULT WINAPI GraphVersion_QueryVersion(IGraphVersion *iface, LONG *pVersion) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + if(!pVersion) + return E_POINTER; + + TRACE("(%p)->(%p): current version %i\n", This, pVersion, This->version); + + *pVersion = This->version; + return S_OK; +} + +static const IGraphVersionVtbl IGraphVersion_VTable = +{ + GraphVersion_QueryInterface, + GraphVersion_AddRef, + GraphVersion_Release, + GraphVersion_QueryVersion, +}; + static const IUnknownVtbl IInner_VTable = { FilterGraphInner_QueryInterface, @@ -5404,47 +5612,6 @@ static const IUnknownVtbl IInner_VTable = FilterGraphInner_Release }; -static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This, - REFIID riid, - LPVOID * ppv) { - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (This->pUnkOuter) - { - if (This->bAggregatable) - return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - { - HRESULT hr; - - IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); - hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); - IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); - This->bAggregatable = TRUE; - return hr; - } - - *ppv = NULL; - return E_NOINTERFACE; - } - - return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); -} - -static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) { - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_AddRef(This->pUnkOuter); - return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); -} - -static ULONG Filtergraph_Release(IFilterGraphImpl *This) { - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_Release(This->pUnkOuter); - return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); -} - /* This is the only function that actually creates a FilterGraph class... */ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) { @@ -5456,21 +5623,21 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) *ppObj = NULL; fimpl = CoTaskMemAlloc(sizeof(*fimpl)); - fimpl->pUnkOuter = pUnkOuter; - fimpl->bUnkOuterValid = FALSE; - fimpl->bAggregatable = FALSE; - fimpl->IInner_vtbl = &IInner_VTable; - fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable; - fimpl->IMediaControl_vtbl = &IMediaControl_VTable; - fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable; - fimpl->IBasicAudio_vtbl = &IBasicAudio_VTable; - fimpl->IBasicVideo_vtbl = &IBasicVideo_VTable; - fimpl->IVideoWindow_vtbl = &IVideoWindow_VTable; - fimpl->IMediaEventEx_vtbl = &IMediaEventEx_VTable; - fimpl->IMediaFilter_vtbl = &IMediaFilter_VTable; - fimpl->IMediaEventSink_vtbl = &IMediaEventSink_VTable; - fimpl->IGraphConfig_vtbl = &IGraphConfig_VTable; - fimpl->IMediaPosition_vtbl = &IMediaPosition_VTable; + fimpl->defaultclock = TRUE; + fimpl->IUnknown_inner.lpVtbl = &IInner_VTable; + fimpl->IFilterGraph2_iface.lpVtbl = &IFilterGraph2_VTable; + fimpl->IMediaControl_iface.lpVtbl = &IMediaControl_VTable; + fimpl->IMediaSeeking_iface.lpVtbl = &IMediaSeeking_VTable; + fimpl->IBasicAudio_iface.lpVtbl = &IBasicAudio_VTable; + fimpl->IBasicVideo2_iface.lpVtbl = &IBasicVideo_VTable; + fimpl->IVideoWindow_iface.lpVtbl = &IVideoWindow_VTable; + fimpl->IMediaEventEx_iface.lpVtbl = &IMediaEventEx_VTable; + fimpl->IMediaFilter_iface.lpVtbl = &IMediaFilter_VTable; + fimpl->IMediaEventSink_iface.lpVtbl = &IMediaEventSink_VTable; + fimpl->IGraphConfig_iface.lpVtbl = &IGraphConfig_VTable; + fimpl->IMediaPosition_iface.lpVtbl = &IMediaPosition_VTable; + fimpl->IObjectWithSite_iface.lpVtbl = &IObjectWithSite_VTable; + fimpl->IGraphVersion_iface.lpVtbl = &IGraphVersion_VTable; fimpl->ref = 1; fimpl->ppFiltersInGraph = NULL; fimpl->pFilterNames = NULL; @@ -5486,30 +5653,36 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) fimpl->notif.disabled = FALSE; fimpl->nRenderers = 0; fimpl->EcCompleteCount = 0; + fimpl->refClockProvider = NULL; fimpl->state = State_Stopped; + fimpl->pSite = NULL; EventsQueue_Init(&fimpl->evqueue); InitializeCriticalSection(&fimpl->cs); fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs"); fimpl->nItfCacheEntries = 0; memcpy(&fimpl->timeformatseek, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID)); - fimpl->start_time = fimpl->position = 0; + fimpl->start_time = fimpl->pause_time = 0; fimpl->stop_position = -1; fimpl->punkFilterMapper2 = NULL; fimpl->recursioncount = 0; + fimpl->version = 0; + + if (pUnkOuter) + fimpl->outer_unk = pUnkOuter; + else + fimpl->outer_unk = &fimpl->IUnknown_inner; /* create Filtermapper aggregated. */ - hr = CoCreateInstance(&CLSID_FilterMapper2, pUnkOuter ? pUnkOuter : (IUnknown*)&fimpl->IInner_vtbl, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (LPVOID*)&fimpl->punkFilterMapper2); + hr = CoCreateInstance(&CLSID_FilterMapper2, fimpl->outer_unk, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void**)&fimpl->punkFilterMapper2); - if (SUCCEEDED(hr)) { - hr = IUnknown_QueryInterface(fimpl->punkFilterMapper2, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2); - } + if (SUCCEEDED(hr)) + hr = IUnknown_QueryInterface(fimpl->punkFilterMapper2, &IID_IFilterMapper2, + (void**)&fimpl->pFilterMapper2); - if (SUCCEEDED(hr)) { + if (SUCCEEDED(hr)) /* Release controlling IUnknown - compensate refcount increase from caching IFilterMapper2 interface. */ - if (pUnkOuter) IUnknown_Release(pUnkOuter); - else IUnknown_Release((IUnknown*)&fimpl->IInner_vtbl); - } + IUnknown_Release(fimpl->outer_unk); if (FAILED(hr)) { ERR("Unable to create filter mapper (%x)\n", hr); @@ -5521,9 +5694,8 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) CoTaskMemFree(fimpl); return hr; } - IFilterGraph2_SetDefaultSyncSource((IFilterGraph2*)fimpl); - *ppObj = fimpl; + *ppObj = &fimpl->IUnknown_inner; return S_OK; } diff --git a/dll/directx/quartz/filtermapper.c b/dll/directx/quartz/filtermapper.c index 5946da86964..f86c88e654f 100644 --- a/dll/directx/quartz/filtermapper.c +++ b/dll/directx/quartz/filtermapper.c @@ -1,5 +1,5 @@ /* - * IFilterMapper & IFilterMapper2 Implementations + * IFilterMapper & IFilterMapper3 Implementations * * Copyright 2003 Robert Shearman * Copyright 2004 Christian Costa @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define NONAMELESSUNION -#define NONAMELESSSTRUCT //#include //#include "windef.h" @@ -36,6 +34,8 @@ //#include "strmif.h" #include //#include "uuids.h" +#include +#include #include @@ -43,79 +43,34 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); #define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0])) -/* Unexposed IAMFilterData interface */ -typedef struct IAMFilterData IAMFilterData; - -typedef struct IAMFilterDataVtbl +typedef struct FilterMapper3Impl { - BEGIN_INTERFACE + IUnknown IUnknown_inner; + IFilterMapper3 IFilterMapper3_iface; + IFilterMapper IFilterMapper_iface; + IAMFilterData IAMFilterData_iface; + IUnknown *outer_unk; + LONG ref; +} FilterMapper3Impl; - /*** IUnknown methods ***/ - HRESULT (STDMETHODCALLTYPE *QueryInterface)( - IAMFilterData *This, - REFIID riid, - void **ppvObject); - - ULONG (STDMETHODCALLTYPE *AddRef)( - IAMFilterData *This); - - ULONG (STDMETHODCALLTYPE *Release)( - IAMFilterData *This); - - /*** IAMFilterData methods ***/ - HRESULT (STDMETHODCALLTYPE *ParseFilterData)( - IAMFilterData *This, - BYTE *pData, - ULONG cb, - BYTE **ppRegFilter2); - - HRESULT (STDMETHODCALLTYPE *CreateFilterData)( - IAMFilterData* This, - REGFILTER2 *prf2, - BYTE **pRegFilterData, - ULONG *pcb); - - END_INTERFACE -} IAMFilterDataVtbl; -struct IAMFilterData +static inline FilterMapper3Impl *impl_from_IFilterMapper3( IFilterMapper3 *iface ) { - const IAMFilterDataVtbl *lpVtbl; -}; -static const GUID IID_IAMFilterData = { - 0x97f7c4d4, 0x547b, 0x4a5f, { 0x83,0x32, 0x53,0x64,0x30,0xad,0x2e,0x4d } -}; - - -typedef struct FilterMapper2Impl -{ - const IFilterMapper2Vtbl *lpVtbl; - const IFilterMapperVtbl *lpVtblFilterMapper; - const IAMFilterDataVtbl *lpVtblAMFilterData; - const IUnknownVtbl *IInner_vtbl; - LONG refCount; - IUnknown * pUnkOuter; - BOOL bUnkOuterValid; - BOOL bAggregatable; -} FilterMapper2Impl; - -static const IUnknownVtbl IInner_VTable; -static const IFilterMapper2Vtbl fm2vtbl; -static const IFilterMapperVtbl fmvtbl; -static const IAMFilterDataVtbl AMFilterDataVtbl; - -static inline FilterMapper2Impl *impl_from_IFilterMapper( IFilterMapper *iface ) -{ - return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblFilterMapper)); + return CONTAINING_RECORD(iface, FilterMapper3Impl, IFilterMapper3_iface); } -static inline FilterMapper2Impl *impl_from_IAMFilterData( IAMFilterData *iface ) +static inline FilterMapper3Impl *impl_from_IFilterMapper( IFilterMapper *iface ) { - return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblAMFilterData)); + return CONTAINING_RECORD(iface, FilterMapper3Impl, IFilterMapper_iface); } -static inline FilterMapper2Impl *impl_from_inner_IUnknown( IUnknown *iface ) +static inline FilterMapper3Impl *impl_from_IAMFilterData( IAMFilterData *iface ) { - return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, IInner_vtbl)); + return CONTAINING_RECORD(iface, FilterMapper3Impl, IAMFilterData_iface); +} + +static inline FilterMapper3Impl *impl_from_IUnknown( IUnknown *iface ) +{ + return CONTAINING_RECORD(iface, FilterMapper3Impl, IUnknown_inner); } static const WCHAR wszClsidSlash[] = {'C','L','S','I','D','\\',0}; @@ -218,68 +173,23 @@ static void delete_vector(struct Vector * v) v->capacity = 0; } -HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj) -{ - FilterMapper2Impl * pFM2impl; - - TRACE("(%p, %p)\n", pUnkOuter, ppObj); - - pFM2impl = CoTaskMemAlloc(sizeof(*pFM2impl)); - if (!pFM2impl) - return E_OUTOFMEMORY; - - pFM2impl->pUnkOuter = pUnkOuter; - pFM2impl->bUnkOuterValid = FALSE; - pFM2impl->bAggregatable = FALSE; - pFM2impl->IInner_vtbl = &IInner_VTable; - pFM2impl->lpVtbl = &fm2vtbl; - pFM2impl->lpVtblFilterMapper = &fmvtbl; - pFM2impl->lpVtblAMFilterData = &AMFilterDataVtbl; - pFM2impl->refCount = 1; - - *ppObj = pFM2impl; - - TRACE("-- created at %p\n", pFM2impl); - - return S_OK; -} - -HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj) -{ - FilterMapper2Impl *pFM2impl; - HRESULT hr; - - TRACE("(%p, %p)\n", pUnkOuter, ppObj); - - hr = FilterMapper2_create(pUnkOuter, (LPVOID*)&pFM2impl); - if (FAILED(hr)) - return hr; - - *ppObj = &pFM2impl->lpVtblFilterMapper; - - return hr; -} - /*** IUnknown (inner) methods ***/ -static HRESULT WINAPI Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) +static HRESULT WINAPI Inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - FilterMapper2Impl *This = impl_from_inner_IUnknown(iface); + FilterMapper3Impl *This = impl_from_IUnknown(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - *ppv = NULL; - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = &This->IInner_vtbl; - else if (IsEqualIID(riid, &IID_IFilterMapper2)) - *ppv = This; + *ppv = &This->IUnknown_inner; + else if (IsEqualIID(riid, &IID_IFilterMapper2) || IsEqualIID(riid, &IID_IFilterMapper3)) + *ppv = &This->IFilterMapper3_iface; else if (IsEqualIID(riid, &IID_IFilterMapper)) - *ppv = &This->lpVtblFilterMapper; + *ppv = &This->IFilterMapper_iface; else if (IsEqualIID(riid, &IID_IAMFilterData)) - *ppv = &This->lpVtblAMFilterData; + *ppv = &This->IAMFilterData_iface; if (*ppv != NULL) { @@ -291,29 +201,27 @@ static HRESULT WINAPI Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID return E_NOINTERFACE; } -static ULONG WINAPI Inner_AddRef(IUnknown * iface) +static ULONG WINAPI Inner_AddRef(IUnknown *iface) { - FilterMapper2Impl *This = impl_from_inner_IUnknown(iface); - ULONG refCount = InterlockedIncrement(&This->refCount); + FilterMapper3Impl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p)->() AddRef from %d\n", This, refCount - 1); + TRACE("(%p)->(): new ref = %d\n", This, ref); - return refCount; + return ref; } -static ULONG WINAPI Inner_Release(IUnknown * iface) +static ULONG WINAPI Inner_Release(IUnknown *iface) { - FilterMapper2Impl *This = impl_from_inner_IUnknown(iface); - ULONG refCount = InterlockedDecrement(&This->refCount); + FilterMapper3Impl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p)->() Release from %d\n", This, refCount + 1); + TRACE("(%p)->(): new ref = %d\n", This, ref); - if (refCount == 0) - { + if (ref == 0) CoTaskMemFree(This); - return 0; - } - return refCount; + + return ref; } static const IUnknownVtbl IInner_VTable = @@ -323,58 +231,31 @@ static const IUnknownVtbl IInner_VTable = Inner_Release }; -static HRESULT WINAPI FilterMapper2_QueryInterface(IFilterMapper2 * iface, REFIID riid, LPVOID *ppv) +static HRESULT WINAPI FilterMapper3_QueryInterface(IFilterMapper3 * iface, REFIID riid, LPVOID *ppv) { - FilterMapper2Impl *This = (FilterMapper2Impl *)iface; + FilterMapper3Impl *This = impl_from_IFilterMapper3(iface); - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (This->pUnkOuter) - { - if (This->bAggregatable) - return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - { - HRESULT hr; - - IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); - hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); - IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); - This->bAggregatable = TRUE; - return hr; - } - - *ppv = NULL; - return E_NOINTERFACE; - } - - return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } -static ULONG WINAPI FilterMapper2_AddRef(IFilterMapper2 * iface) +static ULONG WINAPI FilterMapper3_AddRef(IFilterMapper3 * iface) { - FilterMapper2Impl *This = (FilterMapper2Impl *)iface; + FilterMapper3Impl *This = impl_from_IFilterMapper3(iface); - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_AddRef(This->pUnkOuter); - return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI FilterMapper2_Release(IFilterMapper2 * iface) +static ULONG WINAPI FilterMapper3_Release(IFilterMapper3 * iface) { - FilterMapper2Impl *This = (FilterMapper2Impl *)iface; + FilterMapper3Impl *This = impl_from_IFilterMapper3(iface); - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_Release(This->pUnkOuter); - return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); + return IUnknown_Release(This->outer_unk); } -/*** IFilterMapper2 methods ***/ +/*** IFilterMapper3 methods ***/ -static HRESULT WINAPI FilterMapper2_CreateCategory( - IFilterMapper2 * iface, +static HRESULT WINAPI FilterMapper3_CreateCategory( + IFilterMapper3 * iface, REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR szDescription) @@ -431,8 +312,8 @@ static HRESULT WINAPI FilterMapper2_CreateCategory( return hr; } -static HRESULT WINAPI FilterMapper2_UnregisterFilter( - IFilterMapper2 * iface, +static HRESULT WINAPI FilterMapper3_UnregisterFilter( + IFilterMapper3 * iface, const CLSID *pclsidCategory, const OLECHAR *szInstance, REFCLSID Filter) @@ -520,24 +401,24 @@ static HRESULT FM2_WriteFilterData(const REGFILTER2 * prf2, BYTE **ppData, ULONG rrf.dwVersion = prf2->dwVersion; rrf.dwMerit = prf2->dwMerit; - rrf.dwPins = prf2->u.s1.cPins2; + rrf.dwPins = prf2->cPins2; rrf.dwUnused = 0; add_data(&mainStore, (LPBYTE)&rrf, sizeof(rrf)); - for (i = 0; i < prf2->u.s1.cPins2; i++) + for (i = 0; i < prf2->cPins2; i++) { size += sizeof(struct REG_RFP); - if (prf2->u.s1.rgPins2[i].clsPinCategory) + if (prf2->rgPins2[i].clsPinCategory) size += sizeof(DWORD); - size += prf2->u.s1.rgPins2[i].nMediaTypes * sizeof(struct REG_TYPE); - size += prf2->u.s1.rgPins2[i].nMediums * sizeof(DWORD); + size += prf2->rgPins2[i].nMediaTypes * sizeof(struct REG_TYPE); + size += prf2->rgPins2[i].nMediums * sizeof(DWORD); } - for (i = 0; i < prf2->u.s1.cPins2; i++) + for (i = 0; i < prf2->cPins2; i++) { struct REG_RFP rrfp; - REGFILTERPINS2 rgPin2 = prf2->u.s1.rgPins2[i]; + REGFILTERPINS2 rgPin2 = prf2->rgPins2[i]; unsigned int j; rrfp.signature[0] = '0'; @@ -639,9 +520,9 @@ static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 * prf2) prf2->dwVersion = prrf->dwVersion; prf2->dwMerit = prrf->dwMerit; - prf2->u.s1.cPins2 = prrf->dwPins; + prf2->cPins2 = prrf->dwPins; rgPins2 = CoTaskMemAlloc(prrf->dwPins * sizeof(*rgPins2)); - prf2->u.s1.rgPins2 = rgPins2; + prf2->rgPins2 = rgPins2; pCurrent += sizeof(struct REG_RF); for (i = 0; i < prrf->dwPins; i++) @@ -723,25 +604,25 @@ static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 * prf2) static void FM2_DeleteRegFilter(REGFILTER2 * prf2) { UINT i; - for (i = 0; i < prf2->u.s1.cPins2; i++) + for (i = 0; i < prf2->cPins2; i++) { UINT j; - if (prf2->u.s1.rgPins2[i].clsPinCategory) - CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].clsPinCategory); + if (prf2->rgPins2[i].clsPinCategory) + CoTaskMemFree((LPVOID)prf2->rgPins2[i].clsPinCategory); - for (j = 0; j < prf2->u.s1.rgPins2[i].nMediaTypes; j++) + for (j = 0; j < prf2->rgPins2[i].nMediaTypes; j++) { - CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMediaType[j].clsMajorType); - CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMediaType[j].clsMinorType); + CoTaskMemFree((LPVOID)prf2->rgPins2[i].lpMediaType[j].clsMajorType); + CoTaskMemFree((LPVOID)prf2->rgPins2[i].lpMediaType[j].clsMinorType); } - CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMediaType); - CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2[i].lpMedium); + CoTaskMemFree((LPVOID)prf2->rgPins2[i].lpMediaType); + CoTaskMemFree((LPVOID)prf2->rgPins2[i].lpMedium); } - CoTaskMemFree((LPVOID)prf2->u.s1.rgPins2); + CoTaskMemFree((LPVOID)prf2->rgPins2); } -static HRESULT WINAPI FilterMapper2_RegisterFilter( - IFilterMapper2 * iface, +static HRESULT WINAPI FilterMapper3_RegisterFilter( + IFilterMapper3 * iface, REFCLSID clsidFilter, LPCWSTR szName, IMoniker **ppMoniker, @@ -782,24 +663,24 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter( /* REGFILTER2 structure is converted from version 1 to 2. Tested on Win2k. */ regfilter2.dwVersion = 2; regfilter2.dwMerit = prf2->dwMerit; - regfilter2.u.s1.cPins2 = prf2->u.s.cPins; - pregfp2 = CoTaskMemAlloc(prf2->u.s.cPins * sizeof(REGFILTERPINS2)); - regfilter2.u.s1.rgPins2 = pregfp2; - for (i = 0; i < prf2->u.s.cPins; i++) + regfilter2.cPins2 = prf2->cPins; + pregfp2 = CoTaskMemAlloc(prf2->cPins * sizeof(REGFILTERPINS2)); + regfilter2.rgPins2 = pregfp2; + for (i = 0; i < prf2->cPins; i++) { flags = 0; - if (prf2->u.s.rgPins[i].bRendered) + if (prf2->rgPins[i].bRendered) flags |= REG_PINFLAG_B_RENDERER; - if (prf2->u.s.rgPins[i].bOutput) + if (prf2->rgPins[i].bOutput) flags |= REG_PINFLAG_B_OUTPUT; - if (prf2->u.s.rgPins[i].bZero) + if (prf2->rgPins[i].bZero) flags |= REG_PINFLAG_B_ZERO; - if (prf2->u.s.rgPins[i].bMany) + if (prf2->rgPins[i].bMany) flags |= REG_PINFLAG_B_MANY; pregfp2[i].dwFlags = flags; pregfp2[i].cInstances = 1; - pregfp2[i].nMediaTypes = prf2->u.s.rgPins[i].nMediaTypes; - pregfp2[i].lpMediaType = prf2->u.s.rgPins[i].lpMediaType; + pregfp2[i].nMediaTypes = prf2->rgPins[i].nMediaTypes; + pregfp2[i].lpMediaType = prf2->rgPins[i].lpMediaType; pregfp2[i].nMediums = 0; pregfp2[i].lpMedium = NULL; pregfp2[i].clsPinCategory = NULL; @@ -992,8 +873,8 @@ static int mm_compare(const void * left, const void * right) * meaning match any input/output pin as long as one exists), otherwise match any * filter that meets the rest of the requirements. */ -static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( - IFilterMapper2 * iface, +static HRESULT WINAPI FilterMapper3_EnumMatchingFilters( + IFilterMapper3 * iface, IEnumMoniker **ppEnum, DWORD dwFlags, BOOL bExactMatch, @@ -1141,9 +1022,9 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( /* determine whether filter meets requirements */ if (SUCCEEDED(hrSub) && (rf2.dwMerit >= dwMerit)) { - for (i = 0; (i < rf2.u.s1.cPins2) && (!bInputMatch || !bOutputMatch); i++) + for (i = 0; (i < rf2.cPins2) && (!bInputMatch || !bOutputMatch); i++) { - const REGFILTERPINS2 * rfp2 = rf2.u.s1.rgPins2 + i; + const REGFILTERPINS2 * rfp2 = rf2.rgPins2 + i; bInputMatch = bInputMatch || (!(rfp2->dwFlags & REG_PINFLAG_B_OUTPUT) && (!bRender || (rfp2->dwFlags & REG_PINFLAG_B_RENDERER)) && @@ -1204,42 +1085,51 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( return hr; } -static const IFilterMapper2Vtbl fm2vtbl = +static HRESULT WINAPI FilterMapper3_GetICreateDevEnum(IFilterMapper3 *iface, ICreateDevEnum **ppEnum) +{ + TRACE("(%p, %p)\n", iface, ppEnum); + if (!ppEnum) + return E_POINTER; + return CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void**)ppEnum); +} + +static const IFilterMapper3Vtbl fm3vtbl = { - FilterMapper2_QueryInterface, - FilterMapper2_AddRef, - FilterMapper2_Release, + FilterMapper3_QueryInterface, + FilterMapper3_AddRef, + FilterMapper3_Release, - FilterMapper2_CreateCategory, - FilterMapper2_UnregisterFilter, - FilterMapper2_RegisterFilter, - FilterMapper2_EnumMatchingFilters + FilterMapper3_CreateCategory, + FilterMapper3_UnregisterFilter, + FilterMapper3_RegisterFilter, + FilterMapper3_EnumMatchingFilters, + FilterMapper3_GetICreateDevEnum }; /*** IUnknown methods ***/ static HRESULT WINAPI FilterMapper_QueryInterface(IFilterMapper * iface, REFIID riid, LPVOID *ppv) { - FilterMapper2Impl *This = impl_from_IFilterMapper(iface); + FilterMapper3Impl *This = impl_from_IFilterMapper(iface); TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - return FilterMapper2_QueryInterface((IFilterMapper2*)&This->lpVtbl, riid, ppv); + return FilterMapper3_QueryInterface(&This->IFilterMapper3_iface, riid, ppv); } static ULONG WINAPI FilterMapper_AddRef(IFilterMapper * iface) { - FilterMapper2Impl *This = impl_from_IFilterMapper(iface); + FilterMapper3Impl *This = impl_from_IFilterMapper(iface); - return FilterMapper2_AddRef((IFilterMapper2*)This); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI FilterMapper_Release(IFilterMapper * iface) { - FilterMapper2Impl *This = impl_from_IFilterMapper(iface); + FilterMapper3Impl *This = impl_from_IFilterMapper(iface); - return FilterMapper2_Release((IFilterMapper2*)This); + return IUnknown_Release(This->outer_unk); } /*** IFilterMapper methods ***/ @@ -1256,7 +1146,7 @@ static HRESULT WINAPI FilterMapper_EnumMatchingFilters( CLSID clsOutMaj, CLSID clsOutSub) { - FilterMapper2Impl *This = impl_from_IFilterMapper(iface); + FilterMapper3Impl *This = impl_from_IFilterMapper(iface); GUID InputType[2]; GUID OutputType[2]; IEnumMoniker* ppEnumMoniker; @@ -1285,22 +1175,9 @@ static HRESULT WINAPI FilterMapper_EnumMatchingFilters( *ppEnum = NULL; - hr = IFilterMapper2_EnumMatchingFilters((IFilterMapper2*)This, - &ppEnumMoniker, - 0, - TRUE, - dwMerit, - bInputNeeded, - 1, - InputType, - NULL, - &GUID_NULL, - bRender, - bOutputNeeded, - 1, - OutputType, - NULL, - &GUID_NULL); + hr = IFilterMapper3_EnumMatchingFilters(&This->IFilterMapper3_iface, &ppEnumMoniker, 0, TRUE, + dwMerit, bInputNeeded, 1, InputType, NULL, &GUID_NULL, bRender, bOutputNeeded, 1, + OutputType, NULL, &GUID_NULL); if (FAILED(hr)) return hr; @@ -1745,23 +1622,23 @@ static const IFilterMapperVtbl fmvtbl = /*** IUnknown methods ***/ static HRESULT WINAPI AMFilterData_QueryInterface(IAMFilterData * iface, REFIID riid, LPVOID *ppv) { - FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + FilterMapper3Impl *This = impl_from_IAMFilterData(iface); - return FilterMapper2_QueryInterface((IFilterMapper2*)This, riid, ppv); + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } static ULONG WINAPI AMFilterData_AddRef(IAMFilterData * iface) { - FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + FilterMapper3Impl *This = impl_from_IAMFilterData(iface); - return FilterMapper2_AddRef((IFilterMapper2*)This); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI AMFilterData_Release(IAMFilterData * iface) { - FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + FilterMapper3Impl *This = impl_from_IAMFilterData(iface); - return FilterMapper2_Release((IFilterMapper2*)This); + return IUnknown_Release(This->outer_unk); } /*** IAMFilterData methods ***/ @@ -1769,16 +1646,16 @@ static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData* iface, BYTE *pData, ULONG cb, BYTE **ppRegFilter2) { - FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + FilterMapper3Impl *This = impl_from_IAMFilterData(iface); HRESULT hr = S_OK; - REGFILTER2 *prf2; + static REGFILTER2 *prf2; TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pData, cb, ppRegFilter2); prf2 = CoTaskMemAlloc(sizeof(*prf2)); if (!prf2) return E_OUTOFMEMORY; - *ppRegFilter2 = (BYTE *)prf2; + *ppRegFilter2 = (BYTE *)&prf2; hr = FM2_ReadFilterData(pData, prf2); if (FAILED(hr)) @@ -1795,7 +1672,7 @@ static HRESULT WINAPI AMFilterData_CreateFilterData(IAMFilterData* iface, BYTE **pRegFilterData, ULONG *pcb) { - FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + FilterMapper3Impl *This = impl_from_IAMFilterData(iface); TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, prf2, pRegFilterData, pcb); @@ -1809,3 +1686,47 @@ static const IAMFilterDataVtbl AMFilterDataVtbl = { AMFilterData_ParseFilterData, AMFilterData_CreateFilterData }; + +HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + FilterMapper3Impl * pFM2impl; + + TRACE("(%p, %p)\n", pUnkOuter, ppObj); + + pFM2impl = CoTaskMemAlloc(sizeof(*pFM2impl)); + if (!pFM2impl) + return E_OUTOFMEMORY; + + pFM2impl->IUnknown_inner.lpVtbl = &IInner_VTable; + pFM2impl->IFilterMapper3_iface.lpVtbl = &fm3vtbl; + pFM2impl->IFilterMapper_iface.lpVtbl = &fmvtbl; + pFM2impl->IAMFilterData_iface.lpVtbl = &AMFilterDataVtbl; + pFM2impl->ref = 1; + + if (pUnkOuter) + pFM2impl->outer_unk = pUnkOuter; + else + pFM2impl->outer_unk = &pFM2impl->IUnknown_inner; + + *ppObj = &pFM2impl->IUnknown_inner; + + TRACE("-- created at %p\n", pFM2impl); + + return S_OK; +} + +HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + FilterMapper3Impl *pFM2impl; + HRESULT hr; + + TRACE("(%p, %p)\n", pUnkOuter, ppObj); + + hr = FilterMapper2_create(pUnkOuter, (LPVOID*)&pFM2impl); + if (FAILED(hr)) + return hr; + + *ppObj = &pFM2impl->IFilterMapper_iface; + + return hr; +} diff --git a/dll/directx/quartz/main.c b/dll/directx/quartz/main.c index c3124dd1d53..81844c64296 100644 --- a/dll/directx/quartz/main.c +++ b/dll/directx/quartz/main.c @@ -2,9 +2,6 @@ * * Copyright 2002 Lionel Ulmer * - * This file contains the (internal) driver registration functions, - * driver enumeration APIs and DirectDraw creation functions. - * * 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 @@ -40,16 +37,25 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) return QUARTZ_DllMain( hInstDLL, fdwReason, lpv ); } +static HRESULT SeekingPassThru_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + return PosPassThru_Construct(pUnkOuter,ppObj); /* from strmbase */ +} + /****************************************************************************** * DirectShow ClassFactory */ typedef struct { - IClassFactory ITF_IClassFactory; - + IClassFactory IClassFactory_iface; LONG ref; HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); } IClassFactoryImpl; +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + struct object_creation_info { const CLSID *clsid; @@ -69,6 +75,7 @@ static const struct object_creation_info object_creation[] = { &CLSID_MPEG1Splitter, MPEGSplitter_create }, { &CLSID_VideoRenderer, VideoRenderer_create }, { &CLSID_NullRenderer, NullRenderer_create }, + { &CLSID_VideoMixingRenderer9, VMR9Impl_create }, { &CLSID_VideoRendererDefault, VideoRendererDefault_create }, { &CLSID_DSoundRender, DSoundRender_create }, { &CLSID_AudioRender, DSoundRender_create }, @@ -78,34 +85,30 @@ static const struct object_creation_info object_creation[] = { &CLSID_WAVEParser, WAVEParser_create } }; -static HRESULT WINAPI -DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) +static HRESULT WINAPI DSCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IClassFactory)) { IClassFactory_AddRef(iface); - *ppobj = This; + *ppobj = iface; return S_OK; } *ppobj = NULL; - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj); return E_NOINTERFACE; } -static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface) +static ULONG WINAPI DSCF_AddRef(IClassFactory *iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); return InterlockedIncrement(&This->ref); } -static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface) +static ULONG WINAPI DSCF_Release(IClassFactory *iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; - + IClassFactoryImpl *This = impl_from_IClassFactory(iface); ULONG ref = InterlockedDecrement(&This->ref); if (ref == 0) @@ -115,16 +118,19 @@ static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface) } -static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, - REFIID riid, LPVOID *ppobj) +static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, + REFIID riid, void **ppobj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); HRESULT hres; LPUNKNOWN punk; - + TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); *ppobj = NULL; + if(pOuter && !IsEqualGUID(&IID_IUnknown, riid)) + return E_NOINTERFACE; + hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); if (SUCCEEDED(hres)) { hres = IUnknown_QueryInterface(punk, riid, ppobj); @@ -133,9 +139,9 @@ static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter return hres; } -static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) +static HRESULT WINAPI DSCF_LockServer(IClassFactory *iface, BOOL dolock) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + IClassFactoryImpl *This = impl_from_IClassFactory(iface); FIXME("(%p)->(%d),stub!\n",This,dolock); return S_OK; } @@ -181,12 +187,12 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) IClassFactoryImpl *factory = CoTaskMemAlloc(sizeof(*factory)); if (factory == NULL) return E_OUTOFMEMORY; - factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl; + factory->IClassFactory_iface.lpVtbl = &DSCF_Vtbl; factory->ref = 1; factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; - *ppv = &factory->ITF_IClassFactory; + *ppv = &factory->IClassFactory_iface; return S_OK; } } @@ -295,17 +301,15 @@ LONG WINAPI DBToAmpFactor(LONG db) */ DWORD WINAPI AMGetErrorTextA(HRESULT hr, LPSTR buffer, DWORD maxlen) { - unsigned int len; - static const char format[] = "Error: 0x%x"; - char error[MAX_ERROR_TEXT_LEN]; + DWORD res; + WCHAR errorW[MAX_ERROR_TEXT_LEN]; - FIXME("(%x,%p,%d) stub\n", hr, buffer, maxlen); + TRACE("(%x,%p,%d)\n", hr, buffer, maxlen); + if (!buffer) + return 0; - if (!buffer) return 0; - wsprintfA(error, format, hr); - if ((len = strlen(error)) >= maxlen) return 0; - lstrcpyA(buffer, error); - return len; + res = AMGetErrorTextW(hr, errorW, sizeof(errorW)/sizeof(*errorW)); + return WideCharToMultiByte(CP_ACP, 0, errorW, res, buffer, maxlen, 0, 0); } /*********************************************************************** diff --git a/dll/directx/quartz/memallocator.c b/dll/directx/quartz/memallocator.c index 01a13b359a1..96fdb35ed24 100644 --- a/dll/directx/quartz/memallocator.c +++ b/dll/directx/quartz/memallocator.c @@ -31,9 +31,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); +typedef struct StdMediaSample2 +{ + IMediaSample2 IMediaSample2_iface; + LONG ref; + AM_SAMPLE2_PROPERTIES props; + IMemAllocator * pParent; + struct list listentry; + LONGLONG tMediaStart; + LONGLONG tMediaEnd; +} StdMediaSample2; + typedef struct BaseMemAllocator { - const IMemAllocatorVtbl * lpVtbl; + IMemAllocator IMemAllocator_iface; LONG ref; ALLOCATOR_PROPERTIES props; @@ -52,8 +63,14 @@ typedef struct BaseMemAllocator CRITICAL_SECTION *pCritSect; } BaseMemAllocator; +static inline BaseMemAllocator *impl_from_IMemAllocator(IMemAllocator *iface) +{ + return CONTAINING_RECORD(iface, BaseMemAllocator, IMemAllocator_iface); +} + static const IMemAllocatorVtbl BaseMemAllocator_VTable; static const IMediaSample2Vtbl StdMediaSample2_VTable; +static inline StdMediaSample2 *unsafe_impl_from_IMediaSample(IMediaSample * iface); #define AM_SAMPLE2_PROP_SIZE_WRITABLE FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, pbBuffer) @@ -70,7 +87,7 @@ static HRESULT BaseMemAllocator_Init(HRESULT (* fnAlloc)(IMemAllocator *), { assert(fnAlloc && fnFree && fnDestroyed); - pMemAlloc->lpVtbl = &BaseMemAllocator_VTable; + pMemAlloc->IMemAllocator_iface.lpVtbl = &BaseMemAllocator_VTable; pMemAlloc->ref = 1; ZeroMemory(&pMemAlloc->props, sizeof(pMemAlloc->props)); @@ -93,7 +110,7 @@ static HRESULT BaseMemAllocator_Init(HRESULT (* fnAlloc)(IMemAllocator *), static HRESULT WINAPI BaseMemAllocator_QueryInterface(IMemAllocator * iface, REFIID riid, LPVOID * ppv) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); TRACE("(%p)->(%s, %p)\n", This, qzdebugstr_guid(riid), ppv); *ppv = NULL; @@ -116,7 +133,7 @@ static HRESULT WINAPI BaseMemAllocator_QueryInterface(IMemAllocator * iface, REF static ULONG WINAPI BaseMemAllocator_AddRef(IMemAllocator * iface) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->() AddRef from %d\n", iface, ref - 1); @@ -126,7 +143,7 @@ static ULONG WINAPI BaseMemAllocator_AddRef(IMemAllocator * iface) static ULONG WINAPI BaseMemAllocator_Release(IMemAllocator * iface) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->() Release from %d\n", iface, ref + 1); @@ -145,7 +162,7 @@ static ULONG WINAPI BaseMemAllocator_Release(IMemAllocator * iface) static HRESULT WINAPI BaseMemAllocator_SetProperties(IMemAllocator * iface, ALLOCATOR_PROPERTIES *pRequest, ALLOCATOR_PROPERTIES *pActual) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr; TRACE("(%p)->(%p, %p)\n", This, pRequest, pActual); @@ -178,7 +195,7 @@ static HRESULT WINAPI BaseMemAllocator_SetProperties(IMemAllocator * iface, ALLO static HRESULT WINAPI BaseMemAllocator_GetProperties(IMemAllocator * iface, ALLOCATOR_PROPERTIES *pProps) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr = S_OK; TRACE("(%p)->(%p)\n", This, pProps); @@ -194,7 +211,7 @@ static HRESULT WINAPI BaseMemAllocator_GetProperties(IMemAllocator * iface, ALLO static HRESULT WINAPI BaseMemAllocator_Commit(IMemAllocator * iface) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr; TRACE("(%p)->()\n", This); @@ -238,7 +255,7 @@ static HRESULT WINAPI BaseMemAllocator_Commit(IMemAllocator * iface) static HRESULT WINAPI BaseMemAllocator_Decommit(IMemAllocator * iface) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr; TRACE("(%p)->()\n", This); @@ -279,7 +296,7 @@ static HRESULT WINAPI BaseMemAllocator_Decommit(IMemAllocator * iface) static HRESULT WINAPI BaseMemAllocator_GetBuffer(IMemAllocator * iface, IMediaSample ** pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); HRESULT hr = S_OK; /* NOTE: The pStartTime and pEndTime parameters are not applied to the sample. @@ -319,14 +336,14 @@ static HRESULT WINAPI BaseMemAllocator_GetBuffer(IMemAllocator * iface, IMediaSa hr = VFW_E_TIMEOUT; else { + StdMediaSample2 *ms; struct list * free = list_head(&This->free_list); list_remove(free); list_add_head(&This->used_list, free); - *pSample = (IMediaSample *)LIST_ENTRY(free, StdMediaSample2, listentry); - - assert(((StdMediaSample2 *)*pSample)->ref == 0); - + ms = LIST_ENTRY(free, StdMediaSample2, listentry); + assert(ms->ref == 0); + *pSample = (IMediaSample *)&ms->IMediaSample2_iface; IMediaSample_AddRef(*pSample); } } @@ -339,10 +356,10 @@ static HRESULT WINAPI BaseMemAllocator_GetBuffer(IMemAllocator * iface, IMediaSa static HRESULT WINAPI BaseMemAllocator_ReleaseBuffer(IMemAllocator * iface, IMediaSample * pSample) { - BaseMemAllocator *This = (BaseMemAllocator *)iface; - StdMediaSample2 * pStdSample = (StdMediaSample2 *)pSample; + BaseMemAllocator *This = impl_from_IMemAllocator(iface); + StdMediaSample2 * pStdSample = unsafe_impl_from_IMediaSample(pSample); HRESULT hr = S_OK; - + TRACE("(%p)->(%p)\n", This, pSample); /* FIXME: make sure that sample is currently on the used list */ @@ -408,7 +425,7 @@ static HRESULT StdMediaSample2_Construct(BYTE * pbBuffer, LONG cbBuffer, IMemAll if (!(*ppSample = CoTaskMemAlloc(sizeof(StdMediaSample2)))) return E_OUTOFMEMORY; - (*ppSample)->lpvtbl = &StdMediaSample2_VTable; + (*ppSample)->IMediaSample2_iface.lpVtbl = &StdMediaSample2_VTable; (*ppSample)->ref = 0; ZeroMemory(&(*ppSample)->props, sizeof((*ppSample)->props)); @@ -431,47 +448,45 @@ static void StdMediaSample2_Delete(StdMediaSample2 * This) CoTaskMemFree(This); } -static HRESULT WINAPI StdMediaSample2_QueryInterface(IMediaSample2 * iface, REFIID riid, LPVOID * ppv) +static inline StdMediaSample2 *impl_from_IMediaSample2(IMediaSample2 * iface) +{ + return CONTAINING_RECORD(iface, StdMediaSample2, IMediaSample2_iface); +} + +static HRESULT WINAPI StdMediaSample2_QueryInterface(IMediaSample2 * iface, REFIID riid, void ** ppv) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); *ppv = NULL; - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaSample)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaSample2)) - *ppv = This; - - if (*ppv) + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMediaSample) || + IsEqualIID(riid, &IID_IMediaSample2)) { - IUnknown_AddRef((IUnknown *)(*ppv)); + *ppv = iface; + IMediaSample2_AddRef(iface); return S_OK; } FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - return E_NOINTERFACE; } static ULONG WINAPI StdMediaSample2_AddRef(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p)->() AddRef from %d\n", iface, ref - 1); + TRACE("(%p)->(): new ref = %d\n", This, ref); return ref; } static ULONG WINAPI StdMediaSample2_Release(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p)->() Release from %d\n", iface, ref + 1); + TRACE("(%p)->(): new ref = %d\n", This, ref); if (!ref) { @@ -479,14 +494,13 @@ static ULONG WINAPI StdMediaSample2_Release(IMediaSample2 * iface) IMemAllocator_ReleaseBuffer(This->pParent, (IMediaSample *)iface); else StdMediaSample2_Delete(This); - return 0; } return ref; } static HRESULT WINAPI StdMediaSample2_GetPointer(IMediaSample2 * iface, BYTE ** ppBuffer) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%p)\n", iface, ppBuffer); @@ -503,7 +517,7 @@ static HRESULT WINAPI StdMediaSample2_GetPointer(IMediaSample2 * iface, BYTE ** static LONG WINAPI StdMediaSample2_GetSize(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("StdMediaSample2_GetSize()\n"); @@ -512,8 +526,8 @@ static LONG WINAPI StdMediaSample2_GetSize(IMediaSample2 * iface) static HRESULT WINAPI StdMediaSample2_GetTime(IMediaSample2 * iface, REFERENCE_TIME * pStart, REFERENCE_TIME * pEnd) { + StdMediaSample2 *This = impl_from_IMediaSample2(iface); HRESULT hr; - StdMediaSample2 *This = (StdMediaSample2 *)iface; TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd); @@ -539,7 +553,7 @@ static HRESULT WINAPI StdMediaSample2_GetTime(IMediaSample2 * iface, REFERENCE_T static HRESULT WINAPI StdMediaSample2_SetTime(IMediaSample2 * iface, REFERENCE_TIME * pStart, REFERENCE_TIME * pEnd) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd); @@ -564,7 +578,7 @@ static HRESULT WINAPI StdMediaSample2_SetTime(IMediaSample2 * iface, REFERENCE_T static HRESULT WINAPI StdMediaSample2_IsSyncPoint(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->()\n", iface); @@ -573,7 +587,7 @@ static HRESULT WINAPI StdMediaSample2_IsSyncPoint(IMediaSample2 * iface) static HRESULT WINAPI StdMediaSample2_SetSyncPoint(IMediaSample2 * iface, BOOL bIsSyncPoint) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%s)\n", iface, bIsSyncPoint ? "TRUE" : "FALSE"); @@ -587,7 +601,7 @@ static HRESULT WINAPI StdMediaSample2_SetSyncPoint(IMediaSample2 * iface, BOOL b static HRESULT WINAPI StdMediaSample2_IsPreroll(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->()\n", iface); @@ -596,7 +610,7 @@ static HRESULT WINAPI StdMediaSample2_IsPreroll(IMediaSample2 * iface) static HRESULT WINAPI StdMediaSample2_SetPreroll(IMediaSample2 * iface, BOOL bIsPreroll) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%s)\n", iface, bIsPreroll ? "TRUE" : "FALSE"); @@ -610,7 +624,7 @@ static HRESULT WINAPI StdMediaSample2_SetPreroll(IMediaSample2 * iface, BOOL bIs static LONG WINAPI StdMediaSample2_GetActualDataLength(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->()\n", iface); @@ -619,7 +633,7 @@ static LONG WINAPI StdMediaSample2_GetActualDataLength(IMediaSample2 * iface) static HRESULT WINAPI StdMediaSample2_SetActualDataLength(IMediaSample2 * iface, LONG len) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%d)\n", iface, len); @@ -637,7 +651,7 @@ static HRESULT WINAPI StdMediaSample2_SetActualDataLength(IMediaSample2 * iface, static HRESULT WINAPI StdMediaSample2_GetMediaType(IMediaSample2 * iface, AM_MEDIA_TYPE ** ppMediaType) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%p)\n", iface, ppMediaType); @@ -656,13 +670,18 @@ static HRESULT WINAPI StdMediaSample2_GetMediaType(IMediaSample2 * iface, AM_MED static HRESULT WINAPI StdMediaSample2_SetMediaType(IMediaSample2 * iface, AM_MEDIA_TYPE * pMediaType) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%p)\n", iface, pMediaType); if (This->props.pMediaType) + { FreeMediaType(This->props.pMediaType); - else if (!(This->props.pMediaType = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) + This->props.pMediaType = NULL; + } + if (!pMediaType) + return S_FALSE; + if (!(This->props.pMediaType = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) return E_OUTOFMEMORY; return CopyMediaType(This->props.pMediaType, pMediaType); @@ -670,7 +689,7 @@ static HRESULT WINAPI StdMediaSample2_SetMediaType(IMediaSample2 * iface, AM_MED static HRESULT WINAPI StdMediaSample2_IsDiscontinuity(IMediaSample2 * iface) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->()\n", iface); @@ -679,7 +698,7 @@ static HRESULT WINAPI StdMediaSample2_IsDiscontinuity(IMediaSample2 * iface) static HRESULT WINAPI StdMediaSample2_SetDiscontinuity(IMediaSample2 * iface, BOOL bIsDiscontinuity) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%s)\n", iface, bIsDiscontinuity ? "TRUE" : "FALSE"); @@ -693,7 +712,7 @@ static HRESULT WINAPI StdMediaSample2_SetDiscontinuity(IMediaSample2 * iface, BO static HRESULT WINAPI StdMediaSample2_GetMediaTime(IMediaSample2 * iface, LONGLONG * pStart, LONGLONG * pEnd) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd); @@ -703,12 +722,12 @@ static HRESULT WINAPI StdMediaSample2_GetMediaTime(IMediaSample2 * iface, LONGLO *pStart = This->tMediaStart; *pEnd = This->tMediaEnd; - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI StdMediaSample2_SetMediaTime(IMediaSample2 * iface, LONGLONG * pStart, LONGLONG * pEnd) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%p, %p)\n", iface, pStart, pEnd); @@ -727,7 +746,7 @@ static HRESULT WINAPI StdMediaSample2_SetMediaTime(IMediaSample2 * iface, LONGLO static HRESULT WINAPI StdMediaSample2_GetProperties(IMediaSample2 * iface, DWORD cbProperties, BYTE * pbProperties) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%d, %p)\n", iface, cbProperties, pbProperties); @@ -738,7 +757,7 @@ static HRESULT WINAPI StdMediaSample2_GetProperties(IMediaSample2 * iface, DWORD static HRESULT WINAPI StdMediaSample2_SetProperties(IMediaSample2 * iface, DWORD cbProperties, const BYTE * pbProperties) { - StdMediaSample2 *This = (StdMediaSample2 *)iface; + StdMediaSample2 *This = impl_from_IMediaSample2(iface); TRACE("(%p)->(%d, %p)\n", iface, cbProperties, pbProperties); @@ -773,6 +792,16 @@ static const IMediaSample2Vtbl StdMediaSample2_VTable = StdMediaSample2_SetProperties }; +static inline StdMediaSample2 *unsafe_impl_from_IMediaSample(IMediaSample * iface) +{ + IMediaSample2 *iface2 = (IMediaSample2 *)iface; + + if (!iface) + return NULL; + assert(iface2->lpVtbl == &StdMediaSample2_VTable); + return impl_from_IMediaSample2(iface2); +} + typedef struct StdMemAllocator { BaseMemAllocator base; @@ -780,9 +809,14 @@ typedef struct StdMemAllocator LPVOID pMemory; } StdMemAllocator; +static inline StdMemAllocator *StdMemAllocator_from_IMemAllocator(IMemAllocator * iface) +{ + return CONTAINING_RECORD(iface, StdMemAllocator, base.IMemAllocator_iface); +} + static HRESULT StdMemAllocator_Alloc(IMemAllocator * iface) { - StdMemAllocator *This = (StdMemAllocator *)iface; + StdMemAllocator *This = StdMemAllocator_from_IMemAllocator(iface); StdMediaSample2 * pSample = NULL; SYSTEM_INFO si; LONG i; @@ -802,6 +836,9 @@ static HRESULT StdMemAllocator_Alloc(IMemAllocator * iface) /* allocate memory */ This->pMemory = VirtualAlloc(NULL, (This->base.props.cbBuffer + This->base.props.cbPrefix) * This->base.props.cBuffers, MEM_COMMIT, PAGE_READWRITE); + if (!This->pMemory) + return E_OUTOFMEMORY; + for (i = This->base.props.cBuffers - 1; i >= 0; i--) { /* pbBuffer does not start at the base address, it starts at base + cbPrefix */ @@ -817,7 +854,7 @@ static HRESULT StdMemAllocator_Alloc(IMemAllocator * iface) static HRESULT StdMemAllocator_Free(IMemAllocator * iface) { - StdMemAllocator *This = (StdMemAllocator *)iface; + StdMemAllocator *This = StdMemAllocator_from_IMemAllocator(iface); struct list * cursor; if (!list_empty(&This->base.used_list)) @@ -850,7 +887,7 @@ static HRESULT StdMemAllocator_Free(IMemAllocator * iface) static void StdMemAllocator_Destroy(IMemAllocator *iface) { - StdMemAllocator *This = (StdMemAllocator *)iface; + StdMemAllocator *This = StdMemAllocator_from_IMemAllocator(iface); This->csState.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->csState); diff --git a/dll/directx/quartz/mpegsplit.c b/dll/directx/quartz/mpegsplit.c index 1f002b93f12..9de3f00a343 100644 --- a/dll/directx/quartz/mpegsplit.c +++ b/dll/directx/quartz/mpegsplit.c @@ -25,7 +25,6 @@ //#include #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "uuids.h" @@ -53,30 +52,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); #define MPEG_AUDIO_HEADER 1 #define MPEG_NO_HEADER 0 -#define SEEK_INTERVAL (ULONGLONG)(10 * 10000000) /* Add an entry every 10 seconds */ - -struct seek_entry { - ULONGLONG bytepos; - ULONGLONG timepos; -}; - typedef struct MPEGSplitterImpl { ParserImpl Parser; LONGLONG EndOfFile; - LONGLONG duration; LONGLONG position; DWORD begin_offset; BYTE header[4]; /* Whether we just seeked (or started playing) */ BOOL seek; - - /* Seeking cache */ - ULONG seek_entries; - struct seek_entry *seektable; } MPEGSplitterImpl; +static inline MPEGSplitterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) +{ + return CONTAINING_RECORD(iface, MPEGSplitterImpl, Parser.sourceSeeking.IMediaSeeking_iface); +} + static int MPEGSplitter_head_check(const BYTE *header) { /* If this is a possible start code, check for a system or video header */ @@ -120,15 +112,14 @@ static const DWORD tabsel_123[2][3][16] = { static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration) { + int bitrate_index, freq_index, lsf = 1, mpeg1, layer, padding, bitrate, length; LONGLONG duration; - int bitrate_index, freq_index, lsf = 1, mpeg1, layer, padding, bitrate, length; - if (!(header[0] == 0xff && ((header[1]>>5)&0x7) == 0x7 && - ((header[1]>>1)&0x3) != 0 && ((header[2]>>4)&0xf) != 0xf && - ((header[2]>>2)&0x3) != 0x3)) + ((header[1]>>1)&0x3) != 0 && ((header[2]>>4)&0xf) != 0xf && + ((header[2]>>2)&0x3) != 0x3)) { - FIXME("Not a valid header: %02x:%02x\n", header[0], header[1]); + FIXME("Not a valid header: %02x:%02x:%02x:%02x\n", header[0], header[1], header[2], header[3]); return E_INVALIDARG; } @@ -142,17 +133,23 @@ static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration) padding = ((header[2]>>1)&0x1); bitrate = tabsel_123[lsf][layer-1][bitrate_index] * 1000; - if (!bitrate || layer != 3) + if (!bitrate) { FIXME("Not a valid header: %02x:%02x:%02x:%02x\n", header[0], header[1], header[2], header[3]); return E_INVALIDARG; } - - if (layer == 3 || layer == 2) - length = 144 * bitrate / freqs[freq_index] + padding; - else + if (layer == 1) length = 4 * (12 * bitrate / freqs[freq_index] + padding); + else if (layer == 2) + length = 144 * bitrate / freqs[freq_index] + padding; + else if (layer == 3) + length = 144 * bitrate / (freqs[freq_index]<Parser.ppPins[1]; + Parser_OutputPin * pOutputPin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1]); LONGLONG length = 0; LONGLONG pos = BYTES_FROM_MEDIATIME(This->Parser.pInputPin->rtNext); - LONGLONG time = This->position; + LONGLONG time = This->position, rtstop, rtstart; HRESULT hr; BYTE *fbuf = NULL; DWORD len = IMediaSample_GetActualDataLength(pCurrentSample); @@ -175,7 +172,8 @@ static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample) IMediaSample_GetPointer(pCurrentSample, &fbuf); /* Find the next valid header.. it be right here */ - assert(parse_header(fbuf, &length, &This->position) == S_OK); + hr = parse_header(fbuf, &length, &This->position); + assert(hr == S_OK); IMediaSample_SetActualDataLength(pCurrentSample, length); /* Queue the next sample */ @@ -212,9 +210,14 @@ static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample) IMediaSample_SetPreroll(sample, 0); IMediaSample_SetDiscontinuity(sample, 0); IMediaSample_SetSyncPoint(sample, 1); - pin->rtCurrent = rtSampleStart; - pin->rtNext = rtSampleStop; hr = IAsyncReader_Request(pin->pReader, sample, 0); + if (SUCCEEDED(hr)) + { + pin->rtCurrent = rtSampleStart; + pin->rtNext = rtSampleStop; + } + else + IMediaSample_Release(sample); } if (FAILED(hr)) FIXME("o_Ox%08x\n", hr); @@ -224,9 +227,30 @@ static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample) TRACE("Media time : %u.%03u\n", (DWORD)(This->position/10000000), (DWORD)((This->position/10000)%1000)); - IMediaSample_SetTime(pCurrentSample, &time, &This->position); + if (IMediaSample_IsDiscontinuity(pCurrentSample) == S_OK) { + IPin *victim; + EnterCriticalSection(&This->Parser.filter.csFilter); + pOutputPin->pin.pin.tStart = time; + pOutputPin->pin.pin.dRate = This->Parser.sourceSeeking.dRate; + hr = IPin_ConnectedTo(&pOutputPin->pin.pin.IPin_iface, &victim); + if (hr == S_OK) + { + hr = IPin_NewSegment(victim, time, This->Parser.sourceSeeking.llStop, + This->Parser.sourceSeeking.dRate); + if (hr != S_OK) + FIXME("NewSegment returns %08x\n", hr); + IPin_Release(victim); + } + LeaveCriticalSection(&This->Parser.filter.csFilter); + if (hr != S_OK) + return hr; + } + rtstart = (double)(time - pOutputPin->pin.pin.tStart) / pOutputPin->pin.pin.dRate; + rtstop = (double)(This->position - pOutputPin->pin.pin.tStart) / pOutputPin->pin.pin.dRate; + IMediaSample_SetTime(pCurrentSample, &rtstart, &rtstop); + IMediaSample_SetMediaTime(pCurrentSample, &time, &This->position); - hr = OutputPin_SendSample(&pOutputPin->pin, pCurrentSample); + hr = BaseOutputPinImpl_Deliver(&pOutputPin->pin, pCurrentSample); if (hr != S_OK) { @@ -280,7 +304,7 @@ static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample * pSample, } } - if (BYTES_FROM_MEDIATIME(tStop) >= This->EndOfFile || This->position >= This->Parser.mediaSeeking.llStop) + if (BYTES_FROM_MEDIATIME(tStop) >= This->EndOfFile || This->position >= This->Parser.sourceSeeking.llStop) { unsigned int i; @@ -322,6 +346,7 @@ static HRESULT MPEGSplitter_query_accept(LPVOID iface, const AM_MEDIA_TYPE *pmt) FIXME("MPEG-1 system streams not yet supported.\n"); else if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1VideoCD)) FIXME("MPEG-1 VideoCD streams not yet supported.\n"); + else FIXME("%s\n", debugstr_guid(&pmt->subtype)); return S_FALSE; } @@ -449,7 +474,7 @@ static HRESULT MPEGSplitter_init_audio(MPEGSplitterImpl *This, const BYTE *heade static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props) { - PullPin *pPin = (PullPin *)iface; + PullPin *pPin = impl_PullPin_from_IPin(iface); MPEGSplitterImpl *This = (MPEGSplitterImpl*)pPin->pin.pinInfo.pFilter; HRESULT hr; LONGLONG pos = 0; /* in bytes */ @@ -469,17 +494,23 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO /* Skip ID3 v2 tag, if any */ if (SUCCEEDED(hr) && !memcmp("ID3", header, 3)) do { - UINT length; + UINT length = 0; hr = IAsyncReader_SyncRead(pPin->pReader, pos, 6, header + 4); if (FAILED(hr)) break; pos += 6; TRACE("Found ID3 v2.%d.%d\n", header[3], header[4]); - length = (header[6] & 0x7F) << 21; - length += (header[7] & 0x7F) << 14; - length += (header[8] & 0x7F) << 7; - length += (header[9] & 0x7F); - TRACE("Length: %u\n", length); + if(header[3] <= 4 && header[4] != 0xff && + (header[5]&0x0f) == 0 && (header[6]&0x80) == 0 && + (header[7]&0x80) == 0 && (header[8]&0x80) == 0 && + (header[9]&0x80) == 0) + { + length = (header[6]<<21) | (header[7]<<14) | + (header[8]<< 7) | (header[9] ); + if((header[5]&0x10)) + length += 10; + TRACE("Length: %u\n", length); + } pos += length; /* Read the real header for the mpeg splitter */ @@ -502,22 +533,17 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO This->begin_offset = pos; memcpy(This->header, header, 4); - This->seektable[0].bytepos = pos; - This->seektable[0].timepos = 0; - switch(streamtype) { case MPEG_AUDIO_HEADER: { LONGLONG duration = 0; - DWORD last_entry = 0; - - DWORD ticks = GetTickCount(); + WAVEFORMATEX *format; hr = MPEGSplitter_init_audio(This, header, &piOutput, &amt); if (SUCCEEDED(hr)) { - WAVEFORMATEX *format = (WAVEFORMATEX*)amt.pbFormat; + format = (WAVEFORMATEX*)amt.pbFormat; props->cbAlign = 1; props->cbPrefix = 0; @@ -537,59 +563,20 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO } /* Check for idv1 tag, and remove it from stream if found */ - hr = IAsyncReader_SyncRead(pPin->pReader, This->EndOfFile-128, 3, header+4); + hr = IAsyncReader_SyncRead(pPin->pReader, This->EndOfFile-128, 3, header); if (FAILED(hr)) break; - if (!strncmp((char*)header+4, "TAG", 3)) + if (!strncmp((char*)header, "TAG", 3)) This->EndOfFile -= 128; This->Parser.pInputPin->rtStop = MEDIATIME_FROM_BYTES(This->EndOfFile); This->Parser.pInputPin->rtStart = This->Parser.pInputPin->rtCurrent = MEDIATIME_FROM_BYTES(This->begin_offset); - /* http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm has a whole read up on audio headers */ - while (pos + 3 < This->EndOfFile) - { - LONGLONG length = 0; - hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, header); - if (hr != S_OK) - break; - while (parse_header(header, &length, &duration)) - { - /* No valid header yet; shift by a byte and check again */ - memmove(header, header+1, 3); - hr = IAsyncReader_SyncRead(pPin->pReader, pos++, 1, header + 3); - if (hr != S_OK || This->EndOfFile - pos < 4) - break; - } - pos += length; - - if (This->seektable && (duration / SEEK_INTERVAL) > last_entry) - { - if (last_entry + 1 > duration / SEEK_INTERVAL) - { - ERR("Somehow skipped %d interval lengths instead of 1\n", (DWORD)(duration/SEEK_INTERVAL) - (last_entry + 1)); - } - ++last_entry; - - TRACE("Entry: %u\n", last_entry); - if (last_entry >= This->seek_entries) - { - This->seek_entries += 64; - This->seektable = CoTaskMemRealloc(This->seektable, (This->seek_entries)*sizeof(struct seek_entry)); - } - This->seektable[last_entry].bytepos = pos; - This->seektable[last_entry].timepos = duration; - } - - TRACE("Pos: %x%08x/%x%08x\n", (DWORD)(pos >> 32), (DWORD)pos, (DWORD)(This->EndOfFile>>32), (DWORD)This->EndOfFile); - } - hr = S_OK; + duration = (This->EndOfFile-This->begin_offset) * 10000000 / format->nAvgBytesPerSec; TRACE("Duration: %d seconds\n", (DWORD)(duration / 10000000)); - TRACE("Parsing took %u ms\n", GetTickCount() - ticks); - This->duration = duration; - This->Parser.mediaSeeking.llCurrent = 0; - This->Parser.mediaSeeking.llDuration = duration; - This->Parser.mediaSeeking.llStop = duration; + This->Parser.sourceSeeking.llCurrent = 0; + This->Parser.sourceSeeking.llDuration = duration; + This->Parser.sourceSeeking.llStop = duration; break; } case MPEG_VIDEO_HEADER: @@ -618,80 +605,67 @@ static HRESULT MPEGSplitter_cleanup(LPVOID iface) return S_OK; } -static HRESULT MPEGSplitter_seek(IBaseFilter *iface) +static HRESULT WINAPI MPEGSplitter_seek(IMediaSeeking *iface) { - MPEGSplitterImpl *This = (MPEGSplitterImpl*)iface; + MPEGSplitterImpl *This = impl_from_IMediaSeeking(iface); PullPin *pPin = This->Parser.pInputPin; LONGLONG newpos, timepos, bytepos; - HRESULT hr = S_OK; + HRESULT hr = E_INVALIDARG; BYTE header[4]; - newpos = This->Parser.mediaSeeking.llCurrent; - - if (newpos > This->duration) - { - WARN("Requesting position %x%08x beyond end of stream %x%08x\n", (DWORD)(newpos>>32), (DWORD)newpos, (DWORD)(This->duration>>32), (DWORD)This->duration); - return E_INVALIDARG; - } - + newpos = This->Parser.sourceSeeking.llCurrent; if (This->position/1000000 == newpos/1000000) { TRACE("Requesting position %x%08x same as current position %x%08x\n", (DWORD)(newpos>>32), (DWORD)newpos, (DWORD)(This->position>>32), (DWORD)This->position); return S_OK; } - /* Position, cached */ - bytepos = This->seektable[newpos / SEEK_INTERVAL].bytepos; - timepos = This->seektable[newpos / SEEK_INTERVAL].timepos; - - hr = IAsyncReader_SyncRead(pPin->pReader, bytepos, 4, header); + bytepos = This->begin_offset; + timepos = 0; + /* http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm has a whole read up on audio headers */ while (bytepos + 3 < This->EndOfFile) { + LONGLONG duration = timepos; LONGLONG length = 0; hr = IAsyncReader_SyncRead(pPin->pReader, bytepos, 4, header); - if (hr != S_OK || timepos >= newpos) + if (hr != S_OK) break; - - while (parse_header(header, &length, &timepos) && bytepos + 3 < This->EndOfFile) + while ((hr=parse_header(header, &length, &duration)) != S_OK && + bytepos + 4 < This->EndOfFile) { /* No valid header yet; shift by a byte and check again */ memmove(header, header+1, 3); - hr = IAsyncReader_SyncRead(pPin->pReader, ++bytepos, 1, header + 3); + hr = IAsyncReader_SyncRead(pPin->pReader, ++bytepos + 3, 1, header + 3); if (hr != S_OK) break; - } - bytepos += length; - TRACE("Pos: %x%08x/%x%08x\n", (DWORD)(bytepos >> 32), (DWORD)bytepos, (DWORD)(This->EndOfFile>>32), (DWORD)This->EndOfFile); + } + if (hr != S_OK || duration > newpos) + break; + bytepos += length; + timepos = duration; } if (SUCCEEDED(hr)) { PullPin *pin = This->Parser.pInputPin; - IPin *victim = NULL; TRACE("Moving sound to %08u bytes!\n", (DWORD)bytepos); EnterCriticalSection(&pin->thread_lock); - IPin_BeginFlush((IPin *)pin); + IPin_BeginFlush(&pin->pin.IPin_iface); /* Make sure this is done while stopped, BeginFlush takes care of this */ - EnterCriticalSection(&This->Parser.csFilter); + EnterCriticalSection(&This->Parser.filter.csFilter); memcpy(This->header, header, 4); - IPin_ConnectedTo(This->Parser.ppPins[1], &victim); - if (victim) - { - IPin_NewSegment(victim, newpos, This->duration, pin->dRate); - IPin_Release(victim); - } pin->rtStart = pin->rtCurrent = MEDIATIME_FROM_BYTES(bytepos); pin->rtStop = MEDIATIME_FROM_BYTES((REFERENCE_TIME)This->EndOfFile); This->seek = TRUE; This->position = newpos; - LeaveCriticalSection(&This->Parser.csFilter); + LeaveCriticalSection(&This->Parser.filter.csFilter); TRACE("Done flushing\n"); - IPin_EndFlush((IPin *)pin); + IPin_EndFlush(&pin->pin.IPin_iface); LeaveCriticalSection(&pin->thread_lock); } return hr; @@ -712,7 +686,9 @@ static HRESULT MPEGSplitter_first_request(LPVOID iface) IMediaSample *sample; TRACE("Seeking? %d\n", This->seek); - assert(parse_header(This->header, &length, NULL) == S_OK); + + hr = parse_header(This->header, &length, NULL); + assert(hr == S_OK); if (pin->rtCurrent >= pin->rtStop) { @@ -735,15 +711,19 @@ static HRESULT MPEGSplitter_first_request(LPVOID iface) hr = IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop); - pin->rtCurrent = pin->rtNext; - pin->rtNext = rtSampleStop; - IMediaSample_SetPreroll(sample, FALSE); - IMediaSample_SetDiscontinuity(sample, This->seek); + IMediaSample_SetDiscontinuity(sample, TRUE); IMediaSample_SetSyncPoint(sample, 1); This->seek = 0; hr = IAsyncReader_Request(pin->pReader, sample, 0); + if (SUCCEEDED(hr)) + { + pin->rtCurrent = pin->rtNext; + pin->rtNext = rtSampleStop; + } + else + IMediaSample_Release(sample); } if (FAILED(hr)) ERR("Horsemen of the apocalypse came to bring error 0x%08x\n", hr); @@ -787,14 +767,6 @@ HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv) return E_OUTOFMEMORY; ZeroMemory(This, sizeof(MPEGSplitterImpl)); - This->seektable = CoTaskMemAlloc(sizeof(struct seek_entry) * 64); - if (!This->seektable) - { - CoTaskMemFree(This); - return E_OUTOFMEMORY; - } - This->seek_entries = 64; - hr = Parser_Create(&(This->Parser), &MPEGSplitter_Vtbl, &CLSID_MPEG1Splitter, MPEGSplitter_process_sample, MPEGSplitter_query_accept, MPEGSplitter_pre_connect, MPEGSplitter_cleanup, MPEGSplitter_disconnect, MPEGSplitter_first_request, NULL, NULL, MPEGSplitter_seek, NULL); if (FAILED(hr)) { diff --git a/dll/directx/quartz/nullrenderer.c b/dll/directx/quartz/nullrenderer.c index 1c4311ec40b..af8c48ec39a 100644 --- a/dll/directx/quartz/nullrenderer.c +++ b/dll/directx/quartz/nullrenderer.c @@ -24,7 +24,6 @@ #define NONAMELESSSTRUCT #define NONAMELESSUNION #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "uuids.h" @@ -42,181 +41,75 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); -static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; -static const WCHAR wcsAltInputPinName[] = {'I','n',0}; - -static const IBaseFilterVtbl NullRenderer_Vtbl; -static const IUnknownVtbl IInner_VTable; -static const IPinVtbl NullRenderer_InputPin_Vtbl; - typedef struct NullRendererImpl { - const IBaseFilterVtbl * lpVtbl; - const IUnknownVtbl * IInner_vtbl; - - LONG refCount; - CRITICAL_SECTION csFilter; - FILTER_STATE state; - REFERENCE_TIME rtStreamStart; - IReferenceClock * pClock; - FILTER_INFO filterInfo; - - InputPin *pInputPin; - IUnknown * pUnkOuter; - BOOL bUnkOuterValid; - BOOL bAggregatable; - MediaSeekingImpl mediaSeeking; + BaseRenderer renderer; + IUnknown IUnknown_inner; + IAMFilterMiscFlags IAMFilterMiscFlags_iface; + IUnknown *outer_unk; } NullRendererImpl; -static HRESULT NullRenderer_Sample(LPVOID iface, IMediaSample * pSample) +static HRESULT WINAPI NullRenderer_DoRenderSample(BaseRenderer *iface, IMediaSample *pMediaSample) { - NullRendererImpl *This = iface; - HRESULT hr = S_OK; - - TRACE("%p %p\n", iface, pSample); - - EnterCriticalSection(&This->csFilter); - if (This->pInputPin->flushing || This->pInputPin->end_of_stream) - hr = S_FALSE; - LeaveCriticalSection(&This->csFilter); - - return hr; + return S_OK; } -static HRESULT NullRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI NullRenderer_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) { TRACE("Not a stub!\n"); return S_OK; } -static inline NullRendererImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) -{ - return (NullRendererImpl *)((char*)iface - FIELD_OFFSET(NullRendererImpl, mediaSeeking.lpVtbl)); -} - -static HRESULT WINAPI NullRendererImpl_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) -{ - NullRendererImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); -} - -static ULONG WINAPI NullRendererImpl_Seeking_AddRef(IMediaSeeking * iface) -{ - NullRendererImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_AddRef((IUnknown *)This); -} - -static ULONG WINAPI NullRendererImpl_Seeking_Release(IMediaSeeking * iface) -{ - NullRendererImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_Release((IUnknown *)This); -} - -static const IMediaSeekingVtbl TransformFilter_Seeking_Vtbl = -{ - NullRendererImpl_Seeking_QueryInterface, - NullRendererImpl_Seeking_AddRef, - NullRendererImpl_Seeking_Release, - MediaSeekingImpl_GetCapabilities, - MediaSeekingImpl_CheckCapabilities, - MediaSeekingImpl_IsFormatSupported, - MediaSeekingImpl_QueryPreferredFormat, - MediaSeekingImpl_GetTimeFormat, - MediaSeekingImpl_IsUsingTimeFormat, - MediaSeekingImpl_SetTimeFormat, - MediaSeekingImpl_GetDuration, - MediaSeekingImpl_GetStopPosition, - MediaSeekingImpl_GetCurrentPosition, - MediaSeekingImpl_ConvertTimeFormat, - MediaSeekingImpl_SetPositions, - MediaSeekingImpl_GetPositions, - MediaSeekingImpl_GetAvailable, - MediaSeekingImpl_SetRate, - MediaSeekingImpl_GetRate, - MediaSeekingImpl_GetPreroll +static const BaseRendererFuncTable RendererFuncTable = { + NullRenderer_CheckMediaType, + NullRenderer_DoRenderSample, + /**/ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /**/ + NULL, + NULL, + NULL, + NULL, + NULL, }; -static HRESULT NullRendererImpl_Change(IBaseFilter *iface) +static inline NullRendererImpl *impl_from_IUnknown(IUnknown *iface) { - TRACE("(%p)\n", iface); - return S_OK; + return CONTAINING_RECORD(iface, NullRendererImpl, IUnknown_inner); } -HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) +static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - HRESULT hr; - PIN_INFO piInput; - NullRendererImpl * pNullRenderer; + NullRendererImpl *This = impl_from_IUnknown(iface); - TRACE("(%p, %p)\n", pUnkOuter, ppv); - - *ppv = NULL; - - pNullRenderer = CoTaskMemAlloc(sizeof(NullRendererImpl)); - pNullRenderer->pUnkOuter = pUnkOuter; - pNullRenderer->bUnkOuterValid = FALSE; - pNullRenderer->bAggregatable = FALSE; - pNullRenderer->IInner_vtbl = &IInner_VTable; - - pNullRenderer->lpVtbl = &NullRenderer_Vtbl; - pNullRenderer->refCount = 1; - InitializeCriticalSection(&pNullRenderer->csFilter); - pNullRenderer->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"); - pNullRenderer->state = State_Stopped; - pNullRenderer->pClock = NULL; - ZeroMemory(&pNullRenderer->filterInfo, sizeof(FILTER_INFO)); - - /* construct input pin */ - piInput.dir = PINDIR_INPUT; - piInput.pFilter = (IBaseFilter *)pNullRenderer; - lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); - - hr = InputPin_Construct(&NullRenderer_InputPin_Vtbl, &piInput, NullRenderer_Sample, (LPVOID)pNullRenderer, NullRenderer_QueryAccept, NULL, &pNullRenderer->csFilter, NULL, (IPin **)&pNullRenderer->pInputPin); - - if (SUCCEEDED(hr)) - { - MediaSeekingImpl_Init((IBaseFilter*)pNullRenderer, NullRendererImpl_Change, NullRendererImpl_Change, NullRendererImpl_Change, &pNullRenderer->mediaSeeking, &pNullRenderer->csFilter); - pNullRenderer->mediaSeeking.lpVtbl = &TransformFilter_Seeking_Vtbl; - - *ppv = pNullRenderer; - } - else - { - pNullRenderer->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&pNullRenderer->csFilter); - CoTaskMemFree(pNullRenderer); - } - - return hr; -} - -static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) -{ - ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface); TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - *ppv = NULL; if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = &This->IInner_vtbl; - else if (IsEqualIID(riid, &IID_IPersist)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IBaseFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &This->mediaSeeking; + *ppv = &This->IUnknown_inner; + else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) + *ppv = &This->IAMFilterMiscFlags_iface; + else + { + HRESULT hr; + hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); + if (SUCCEEDED(hr)) + return hr; + } if (*ppv) { - IUnknown_AddRef((IUnknown *)(*ppv)); + IUnknown_AddRef((IUnknown *)*ppv); return S_OK; } @@ -226,49 +119,24 @@ static HRESULT WINAPI NullRendererInner_QueryInterface(IUnknown * iface, REFIID return E_NOINTERFACE; } -static ULONG WINAPI NullRendererInner_AddRef(IUnknown * iface) +static ULONG WINAPI NullRendererInner_AddRef(IUnknown *iface) { - ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface); - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); - - return refCount; + NullRendererImpl *This = impl_from_IUnknown(iface); + return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); } -static ULONG WINAPI NullRendererInner_Release(IUnknown * iface) +static ULONG WINAPI NullRendererInner_Release(IUnknown *iface) { - ICOM_THIS_MULTI(NullRendererImpl, IInner_vtbl, iface); - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); + NullRendererImpl *This = impl_from_IUnknown(iface); + ULONG refCount = BaseFilterImpl_Release(&This->renderer.filter.IBaseFilter_iface); if (!refCount) { - IPin *pConnectedTo; - - if (This->pClock) - IReferenceClock_Release(This->pClock); - - if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo))) - { - IPin_Disconnect(pConnectedTo); - IPin_Release(pConnectedTo); - } - IPin_Disconnect((IPin *)This->pInputPin); - IPin_Release((IPin *)This->pInputPin); - - This->lpVtbl = NULL; - - This->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csFilter); - TRACE("Destroying Null Renderer\n"); CoTaskMemFree(This); - return 0; } - else - return refCount; + + return refCount; } static const IUnknownVtbl IInner_VTable = @@ -278,253 +146,27 @@ static const IUnknownVtbl IInner_VTable = NullRendererInner_Release }; +static inline NullRendererImpl *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, NullRendererImpl, renderer.filter.IBaseFilter_iface); +} + static HRESULT WINAPI NullRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) { - NullRendererImpl *This = (NullRendererImpl *)iface; - - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (This->pUnkOuter) - { - if (This->bAggregatable) - return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - { - HRESULT hr; - - IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); - hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); - IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); - This->bAggregatable = TRUE; - return hr; - } - - *ppv = NULL; - return E_NOINTERFACE; - } - - return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); + NullRendererImpl *This = impl_from_IBaseFilter(iface); + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } static ULONG WINAPI NullRenderer_AddRef(IBaseFilter * iface) { - NullRendererImpl *This = (NullRendererImpl *)iface; - - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_AddRef(This->pUnkOuter); - return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); + NullRendererImpl *This = impl_from_IBaseFilter(iface); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI NullRenderer_Release(IBaseFilter * iface) { - NullRendererImpl *This = (NullRendererImpl *)iface; - - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_Release(This->pUnkOuter); - return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); -} - -/** IPersist methods **/ - -static HRESULT WINAPI NullRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClsid); - - *pClsid = CLSID_NullRenderer; - - return S_OK; -} - -/** IMediaFilter methods **/ - -static HRESULT WINAPI NullRenderer_Stop(IBaseFilter * iface) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(&This->csFilter); - { - This->state = State_Stopped; - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_Pause(IBaseFilter * iface) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(&This->csFilter); - { - if (This->state == State_Stopped) - This->pInputPin->end_of_stream = 0; - This->state = State_Paused; - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); - - EnterCriticalSection(&This->csFilter); - { - This->rtStreamStart = tStart; - This->state = State_Running; - This->pInputPin->end_of_stream = 0; - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState); - - EnterCriticalSection(&This->csFilter); - { - *pState = This->state; - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClock); - - EnterCriticalSection(&This->csFilter); - { - if (This->pClock) - IReferenceClock_Release(This->pClock); - This->pClock = pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppClock); - - EnterCriticalSection(&This->csFilter); - { - *ppClock = This->pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -/** IBaseFilter implementation **/ - -static HRESULT NullRenderer_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - /* Our pins are static, not changing so setting static tick count is ok */ - *lastsynctick = 0; - - if (pos >= 1) - return S_FALSE; - - *pin = (IPin *)This->pInputPin; - IPin_AddRef(*pin); - return S_OK; -} - -static HRESULT WINAPI NullRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return IEnumPinsImpl_Construct(ppEnum, NullRenderer_GetPin, iface); -} - -static HRESULT WINAPI NullRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin); - - if (!Id || !ppPin) - return E_POINTER; - - if (!lstrcmpiW(Id,wcsInputPinName) || !lstrcmpiW(Id,wcsAltInputPinName)) - { - *ppPin = (IPin *)This->pInputPin; - IPin_AddRef(*ppPin); - return S_OK; - } - *ppPin = NULL; - return VFW_E_NOT_FOUND; -} - -static HRESULT WINAPI NullRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); - - strcpyW(pInfo->achName, This->filterInfo.achName); - pInfo->pGraph = This->filterInfo.pGraph; - - if (pInfo->pGraph) - IFilterGraph_AddRef(pInfo->pGraph); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - - TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName)); - - EnterCriticalSection(&This->csFilter); - { - if (pName) - strcpyW(This->filterInfo.achName, pName); - else - *This->filterInfo.achName = '\0'; - This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI NullRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) -{ - NullRendererImpl *This = (NullRendererImpl *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo); - return E_NOTIMPL; + NullRendererImpl *This = impl_from_IBaseFilter(iface); + return IUnknown_Release(This->outer_unk); } static const IBaseFilterVtbl NullRenderer_Vtbl = @@ -532,62 +174,85 @@ static const IBaseFilterVtbl NullRenderer_Vtbl = NullRenderer_QueryInterface, NullRenderer_AddRef, NullRenderer_Release, - NullRenderer_GetClassID, - NullRenderer_Stop, - NullRenderer_Pause, - NullRenderer_Run, - NullRenderer_GetState, - NullRenderer_SetSyncSource, - NullRenderer_GetSyncSource, - NullRenderer_EnumPins, - NullRenderer_FindPin, - NullRenderer_QueryFilterInfo, - NullRenderer_JoinFilterGraph, - NullRenderer_QueryVendorInfo + BaseFilterImpl_GetClassID, + BaseRendererImpl_Stop, + BaseRendererImpl_Pause, + BaseRendererImpl_Run, + BaseRendererImpl_GetState, + BaseRendererImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + BaseRendererImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo }; -static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface) +static NullRendererImpl *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) { - InputPin* This = (InputPin*)iface; - IMediaEventSink* pEventSink; - IFilterGraph *graph; - HRESULT hr = S_OK; - - TRACE("(%p/%p)->()\n", This, iface); - - InputPin_EndOfStream(iface); - graph = ((NullRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph; - if (graph) - { - hr = IFilterGraph_QueryInterface(((NullRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); - if (SUCCEEDED(hr)) - { - hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0); - IMediaEventSink_Release(pEventSink); - } - } - - return hr; + return CONTAINING_RECORD(iface, NullRendererImpl, IAMFilterMiscFlags_iface); } -static const IPinVtbl NullRenderer_InputPin_Vtbl = +static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, + void **ppv) { - InputPin_QueryInterface, - IPinImpl_AddRef, - InputPin_Release, - InputPin_Connect, - InputPin_ReceiveConnection, - IPinImpl_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - NullRenderer_InputPin_EndOfStream, - InputPin_BeginFlush, - InputPin_EndFlush, - InputPin_NewSegment + NullRendererImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); +} + +static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) +{ + NullRendererImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) +{ + NullRendererImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_Release(This->outer_unk); +} + +static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) +{ + return AM_FILTER_MISC_FLAGS_IS_RENDERER; +} + +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = { + AMFilterMiscFlags_QueryInterface, + AMFilterMiscFlags_AddRef, + AMFilterMiscFlags_Release, + AMFilterMiscFlags_GetMiscFlags }; + +HRESULT NullRenderer_create(IUnknown *pUnkOuter, void **ppv) +{ + HRESULT hr; + NullRendererImpl *pNullRenderer; + + TRACE("(%p, %p)\n", pUnkOuter, ppv); + + *ppv = NULL; + + pNullRenderer = CoTaskMemAlloc(sizeof(NullRendererImpl)); + pNullRenderer->IUnknown_inner.lpVtbl = &IInner_VTable; + pNullRenderer->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl; + + if (pUnkOuter) + pNullRenderer->outer_unk = pUnkOuter; + else + pNullRenderer->outer_unk = &pNullRenderer->IUnknown_inner; + + hr = BaseRenderer_Init(&pNullRenderer->renderer, &NullRenderer_Vtbl, pUnkOuter, + &CLSID_NullRenderer, (DWORD_PTR)(__FILE__ ": NullRendererImpl.csFilter"), + &RendererFuncTable); + + if (FAILED(hr)) + { + BaseRendererImpl_Release(&pNullRenderer->renderer.filter.IBaseFilter_iface); + CoTaskMemFree(pNullRenderer); + } + else + *ppv = &pNullRenderer->IUnknown_inner; + + return S_OK; +} diff --git a/dll/directx/quartz/parser.c b/dll/directx/quartz/parser.c index 8fb591d2972..0d731011592 100644 --- a/dll/directx/quartz/parser.c +++ b/dll/directx/quartz/parser.c @@ -20,7 +20,6 @@ */ #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "vfwmsgs.h" @@ -41,44 +40,76 @@ static const IMediaSeekingVtbl Parser_Seeking_Vtbl; static const IPinVtbl Parser_OutputPin_Vtbl; static const IPinVtbl Parser_InputPin_Vtbl; -static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt); -static HRESULT Parser_ChangeCurrent(IBaseFilter *iface); -static HRESULT Parser_ChangeStop(IBaseFilter *iface); -static HRESULT Parser_ChangeRate(IBaseFilter *iface); +static HRESULT WINAPI Parser_ChangeStart(IMediaSeeking *iface); +static HRESULT WINAPI Parser_ChangeStop(IMediaSeeking *iface); +static HRESULT WINAPI Parser_ChangeRate(IMediaSeeking *iface); +static HRESULT WINAPI Parser_OutputPin_DecideBufferSize(BaseOutputPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest); +static HRESULT WINAPI Parser_OutputPin_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt); +static HRESULT WINAPI Parser_OutputPin_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc); +static HRESULT WINAPI Parser_OutputPin_BreakConnect(BaseOutputPin *This); static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) { - return (ParserImpl *)((char*)iface - FIELD_OFFSET(ParserImpl, mediaSeeking.lpVtbl)); + return CONTAINING_RECORD(iface, ParserImpl, sourceSeeking.IMediaSeeking_iface); } +static inline ParserImpl *impl_from_IBaseFilter( IBaseFilter *iface ) +{ + return CONTAINING_RECORD(iface, ParserImpl, filter.IBaseFilter_iface); +} -HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, const CLSID* pClsid, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, STOPPROCESSPROC fnDone, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate) +static inline ParserImpl *impl_from_BaseFilter( BaseFilter *iface ) +{ + return CONTAINING_RECORD(iface, ParserImpl, filter); +} + +/* FIXME: WRONG */ +static IPin* WINAPI Parser_GetPin(BaseFilter *iface, int pos) +{ + ParserImpl *This = impl_from_BaseFilter(iface); + + TRACE("Asking for pos %x\n", pos); + + /* Input pin also has a pin, hence the > and not >= */ + if (pos > This->cStreams || pos < 0) + return NULL; + + IPin_AddRef(This->ppPins[pos]); + return This->ppPins[pos]; +} + +static LONG WINAPI Parser_GetPinCount(BaseFilter *iface) +{ + ParserImpl *This = impl_from_BaseFilter(iface); + + return This->cStreams; +} + +static const BaseFilterFuncTable BaseFuncTable = { + Parser_GetPin, + Parser_GetPinCount +}; + +HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, const CLSID* pClsid, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, STOPPROCESSPROC fnDone, SourceSeeking_ChangeStop stop, SourceSeeking_ChangeStart start, SourceSeeking_ChangeRate rate) { HRESULT hr; PIN_INFO piInput; /* pTransformFilter is already allocated */ - pParser->clsid = *pClsid; - pParser->lpVtbl = Parser_Vtbl; - pParser->refCount = 1; - InitializeCriticalSection(&pParser->csFilter); - pParser->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter"); - pParser->state = State_Stopped; - pParser->pClock = NULL; + BaseFilter_Init(&pParser->filter, Parser_Vtbl, pClsid, (DWORD_PTR)(__FILE__ ": ParserImpl.csFilter"), &BaseFuncTable); + pParser->fnDisconnect = fnDisconnect; - ZeroMemory(&pParser->filterInfo, sizeof(FILTER_INFO)); - pParser->lastpinchange = GetTickCount(); pParser->cStreams = 0; pParser->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *)); /* construct input pin */ piInput.dir = PINDIR_INPUT; - piInput.pFilter = (IBaseFilter *)pParser; + piInput.pFilter = &pParser->filter.IBaseFilter_iface; lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); - if (!current) - current = Parser_ChangeCurrent; + if (!start) + start = Parser_ChangeStart; if (!stop) stop = Parser_ChangeStop; @@ -86,21 +117,19 @@ HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, c if (!rate) rate = Parser_ChangeRate; - MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter); - pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl; + SourceSeeking_Init(&pParser->sourceSeeking, &Parser_Seeking_Vtbl, stop, start, rate, &pParser->filter.csFilter); - hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, fnRequest, fnDone, &pParser->csFilter, (IPin **)&pParser->pInputPin); + hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, fnRequest, fnDone, &pParser->filter.csFilter, (IPin **)&pParser->pInputPin); if (SUCCEEDED(hr)) { - pParser->ppPins[0] = (IPin *)pParser->pInputPin; + pParser->ppPins[0] = &pParser->pInputPin->pin.IPin_iface; pParser->pInputPin->fnPreConnect = fnPreConnect; } else { CoTaskMemFree(pParser->ppPins); - pParser->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&pParser->csFilter); + BaseFilterImpl_Release(&pParser->filter.IBaseFilter_iface); CoTaskMemFree(pParser); } @@ -109,21 +138,16 @@ HRESULT Parser_Create(ParserImpl* pParser, const IBaseFilterVtbl *Parser_Vtbl, c HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) { - ParserImpl *This = (ParserImpl *)iface; + ParserImpl *This = impl_from_IBaseFilter(iface); TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); *ppv = NULL; - if (IsEqualIID(riid, &IID_IUnknown)) + if ( IsEqualIID(riid, &IID_IUnknown) + || IsEqualIID(riid, &IID_IPersist) + || IsEqualIID(riid, &IID_IMediaFilter) + || IsEqualIID(riid, &IID_IBaseFilter) ) *ppv = This; - else if (IsEqualIID(riid, &IID_IPersist)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IBaseFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &This->mediaSeeking; if (*ppv) { @@ -139,12 +163,7 @@ HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ULONG WINAPI Parser_AddRef(IBaseFilter * iface) { - ParserImpl *This = (ParserImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); - - return refCount; + return BaseFilterImpl_AddRef(iface); } void Parser_Destroy(ParserImpl *This) @@ -152,21 +171,18 @@ void Parser_Destroy(ParserImpl *This) IPin *connected = NULL; ULONG pinref; - assert(!This->refCount); + assert(!This->filter.refCount); PullPin_WaitForStateChange(This->pInputPin, INFINITE); - if (This->pClock) - IReferenceClock_Release(This->pClock); - /* Don't need to clean up output pins, freeing input pin will do that */ - IPin_ConnectedTo((IPin *)This->pInputPin, &connected); + IPin_ConnectedTo(&This->pInputPin->pin.IPin_iface, &connected); if (connected) { assert(IPin_Disconnect(connected) == S_OK); IPin_Release(connected); - assert(IPin_Disconnect((IPin *)This->pInputPin) == S_OK); + assert(IPin_Disconnect(&This->pInputPin->pin.IPin_iface) == S_OK); } - pinref = IPin_Release((IPin *)This->pInputPin); + pinref = IPin_Release(&This->pInputPin->pin.IPin_iface); if (pinref) { /* Valgrind could find this, if I kill it here */ @@ -174,14 +190,10 @@ void Parser_Destroy(ParserImpl *This) assert((LONG)pinref > 0); while (pinref) - pinref = IPin_Release((IPin *)This->pInputPin); + pinref = IPin_Release(&This->pInputPin->pin.IPin_iface); } CoTaskMemFree(This->ppPins); - This->lpVtbl = NULL; - - This->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csFilter); TRACE("Destroying parser\n"); CoTaskMemFree(This); @@ -189,8 +201,8 @@ void Parser_Destroy(ParserImpl *This) ULONG WINAPI Parser_Release(IBaseFilter * iface) { - ParserImpl *This = (ParserImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); + ParserImpl *This = impl_from_IBaseFilter(iface); + ULONG refCount = BaseFilterImpl_Release(iface); TRACE("(%p)->() Release from %d\n", This, refCount + 1); @@ -204,11 +216,11 @@ ULONG WINAPI Parser_Release(IBaseFilter * iface) HRESULT WINAPI Parser_GetClassID(IBaseFilter * iface, CLSID * pClsid) { - ParserImpl *This = (ParserImpl *)iface; + ParserImpl *This = impl_from_IBaseFilter(iface); TRACE("(%p)\n", pClsid); - *pClsid = This->clsid; + *pClsid = This->filter.clsid; return S_OK; } @@ -217,8 +229,8 @@ HRESULT WINAPI Parser_GetClassID(IBaseFilter * iface, CLSID * pClsid) HRESULT WINAPI Parser_Stop(IBaseFilter * iface) { - ParserImpl *This = (ParserImpl *)iface; - PullPin *pin = (PullPin *)This->ppPins[0]; + ParserImpl *This = impl_from_IBaseFilter(iface); + PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]); ULONG i; TRACE("()\n"); @@ -226,24 +238,24 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface) EnterCriticalSection(&pin->thread_lock); IAsyncReader_BeginFlush(This->pInputPin->pReader); - EnterCriticalSection(&This->csFilter); + EnterCriticalSection(&This->filter.csFilter); - if (This->state == State_Stopped) + if (This->filter.state == State_Stopped) { - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); IAsyncReader_EndFlush(This->pInputPin->pReader); LeaveCriticalSection(&pin->thread_lock); return S_OK; } - This->state = State_Stopped; + This->filter.state = State_Stopped; for (i = 1; i < (This->cStreams + 1); i++) { - OutputPin_DecommitAllocator((OutputPin *)This->ppPins[i]); + BaseOutputPinImpl_Inactive((BaseOutputPin *)This->ppPins[i]); } - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); PullPin_PauseProcessing(This->pInputPin); PullPin_WaitForStateChange(This->pInputPin, INFINITE); @@ -256,32 +268,32 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface) HRESULT WINAPI Parser_Pause(IBaseFilter * iface) { HRESULT hr = S_OK; - ParserImpl *This = (ParserImpl *)iface; - PullPin *pin = (PullPin *)This->ppPins[0]; + ParserImpl *This = impl_from_IBaseFilter(iface); + PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]); TRACE("()\n"); EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->csFilter); + EnterCriticalSection(&This->filter.csFilter); - if (This->state == State_Paused) + if (This->filter.state == State_Paused) { - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); LeaveCriticalSection(&pin->thread_lock); return S_OK; } - if (This->state == State_Stopped) + if (This->filter.state == State_Stopped) { - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); hr = IBaseFilter_Run(iface, -1); - EnterCriticalSection(&This->csFilter); + EnterCriticalSection(&This->filter.csFilter); } if (SUCCEEDED(hr)) - This->state = State_Paused; + This->filter.state = State_Paused; - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); LeaveCriticalSection(&pin->thread_lock); return hr; @@ -290,31 +302,30 @@ HRESULT WINAPI Parser_Pause(IBaseFilter * iface) HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart) { HRESULT hr = S_OK; - ParserImpl *This = (ParserImpl *)iface; - PullPin *pin = (PullPin *)This->ppPins[0]; + ParserImpl *This = impl_from_IBaseFilter(iface); + PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]); ULONG i; TRACE("(%s)\n", wine_dbgstr_longlong(tStart)); EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->csFilter); + EnterCriticalSection(&This->filter.csFilter); { HRESULT hr_any = VFW_E_NOT_CONNECTED; - if (This->state == State_Running || This->state == State_Paused) + This->filter.rtStreamStart = tStart; + if (This->filter.state == State_Running || This->filter.state == State_Paused) { - This->state = State_Running; - LeaveCriticalSection(&This->csFilter); + This->filter.state = State_Running; + LeaveCriticalSection(&This->filter.csFilter); LeaveCriticalSection(&pin->thread_lock); return S_OK; } - This->rtStreamStart = tStart; - for (i = 1; i < (This->cStreams + 1); i++) { - hr = OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]); + hr = BaseOutputPinImpl_Active((BaseOutputPin *)This->ppPins[i]); if (SUCCEEDED(hr)) hr_any = hr; } @@ -322,15 +333,15 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart) hr = hr_any; if (SUCCEEDED(hr)) { - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); hr = PullPin_StartProcessing(This->pInputPin); - EnterCriticalSection(&This->csFilter); + EnterCriticalSection(&This->filter.csFilter); } if (SUCCEEDED(hr)) - This->state = State_Running; + This->filter.state = State_Running; } - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); LeaveCriticalSection(&pin->thread_lock); return hr; @@ -338,18 +349,18 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart) HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) { - ParserImpl *This = (ParserImpl *)iface; - PullPin *pin = (PullPin *)This->ppPins[0]; + ParserImpl *This = impl_from_IBaseFilter(iface); + PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]); HRESULT hr = S_OK; TRACE("(%d, %p)\n", dwMilliSecsTimeout, pState); EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->csFilter); + EnterCriticalSection(&This->filter.csFilter); { - *pState = This->state; + *pState = This->filter.state; } - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->filter.csFilter); if (This->pInputPin && (PullPin_WaitForStateChange(This->pInputPin, dwMilliSecsTimeout) == S_FALSE)) hr = VFW_S_STATE_INTERMEDIATE; @@ -360,21 +371,13 @@ HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FI HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) { - ParserImpl *This = (ParserImpl *)iface; - PullPin *pin = (PullPin *)This->ppPins[0]; + ParserImpl *This = impl_from_IBaseFilter(iface); + PullPin *pin = impl_PullPin_from_IPin(This->ppPins[0]); TRACE("(%p)\n", pClock); EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->csFilter); - { - if (This->pClock) - IReferenceClock_Release(This->pClock); - This->pClock = pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); + BaseFilterImpl_SetSyncSource(iface,pClock); LeaveCriticalSection(&pin->thread_lock); return S_OK; @@ -382,48 +385,14 @@ HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock HRESULT WINAPI Parser_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) { - ParserImpl *This = (ParserImpl *)iface; - - TRACE("(%p)\n", ppClock); - - EnterCriticalSection(&This->csFilter); - { - *ppClock = This->pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; + return BaseFilterImpl_GetSyncSource(iface, ppClock); } /** IBaseFilter implementation **/ -/* FIXME: WRONG */ -static HRESULT Parser_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) -{ - ParserImpl *This = (ParserImpl *)iface; - - *lastsynctick = This->lastpinchange; - - TRACE("Asking for pos %x\n", pos); - - /* Input pin also has a pin, hence the > and not >= */ - if (pos > This->cStreams) - return S_FALSE; - - *pin = This->ppPins[pos]; - IPin_AddRef(*pin); - return S_OK; -} - HRESULT WINAPI Parser_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) { - ParserImpl *This = (ParserImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return IEnumPinsImpl_Construct(ppEnum, Parser_GetPin, iface); + return BaseFilterImpl_EnumPins(iface,ppEnum); } HRESULT WINAPI Parser_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) @@ -437,45 +406,32 @@ HRESULT WINAPI Parser_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) { - ParserImpl *This = (ParserImpl *)iface; - - TRACE("(%p)\n", pInfo); - - strcpyW(pInfo->achName, This->filterInfo.achName); - pInfo->pGraph = This->filterInfo.pGraph; - - if (pInfo->pGraph) - IFilterGraph_AddRef(pInfo->pGraph); - - return S_OK; + return BaseFilterImpl_QueryFilterInfo(iface, pInfo); } HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) { - HRESULT hr = S_OK; - ParserImpl *This = (ParserImpl *)iface; - - TRACE("(%p, %s)\n", pGraph, debugstr_w(pName)); - - EnterCriticalSection(&This->csFilter); - { - if (pName) - strcpyW(This->filterInfo.achName, pName); - else - *This->filterInfo.achName = '\0'; - This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ - } - LeaveCriticalSection(&This->csFilter); - - return hr; + return BaseFilterImpl_JoinFilterGraph(iface, pGraph, pName); } HRESULT WINAPI Parser_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) { - TRACE("(%p)\n", pVendorInfo); - return E_NOTIMPL; + return BaseFilterImpl_QueryVendorInfo(iface, pVendorInfo); } +static const BasePinFuncTable output_BaseFuncTable = { + NULL, + BaseOutputPinImpl_AttemptConnection, + BasePinImpl_GetMediaTypeVersion, + Parser_OutputPin_GetMediaType +}; + +static const BaseOutputPinFuncTable output_BaseOutputFuncTable = { + Parser_OutputPin_DecideBufferSize, + Parser_OutputPin_DecideAllocator, + Parser_OutputPin_BreakConnect +}; + HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt) { IPin ** ppOldPins; @@ -486,21 +442,20 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *)); memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *)); - hr = OutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, props, NULL, Parser_OutputPin_QueryAccept, &This->csFilter, This->ppPins + (This->cStreams + 1)); + hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, &output_BaseFuncTable, &output_BaseOutputFuncTable, &This->filter.csFilter, This->ppPins + (This->cStreams + 1)); if (SUCCEEDED(hr)) { IPin *pPin = This->ppPins[This->cStreams + 1]; - Parser_OutputPin *pin = (Parser_OutputPin *)pPin; + Parser_OutputPin *pin = unsafe_impl_Parser_OutputPin_from_IPin(pPin); pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pin->pmt, amt); pin->dwSamplesProcessed = 0; - pin->pin.pin.pUserData = This->ppPins[This->cStreams + 1]; pin->pin.pin.pinInfo.pFilter = (LPVOID)This; - pin->pin.custom_allocator = 1; + pin->allocProps = *props; This->cStreams++; - This->lastpinchange = GetTickCount(); + BaseFilterImpl_IncrementPinVersion(&This->filter); CoTaskMemFree(ppOldPins); } else @@ -528,31 +483,31 @@ static HRESULT Parser_RemoveOutputPins(ParserImpl * This) for (i = 0; i < This->cStreams; i++) { - hr = OutputPin_DeliverDisconnect((OutputPin *)ppOldPins[i + 1]); + hr = ((BaseOutputPin *)ppOldPins[i + 1])->pFuncsTable->pfnBreakConnect((BaseOutputPin *)ppOldPins[i + 1]); TRACE("Disconnect: %08x\n", hr); IPin_Release(ppOldPins[i + 1]); } - This->lastpinchange = GetTickCount(); + BaseFilterImpl_IncrementPinVersion(&This->filter); This->cStreams = 0; CoTaskMemFree(ppOldPins); return S_OK; } -static HRESULT Parser_ChangeCurrent(IBaseFilter *iface) +static HRESULT WINAPI Parser_ChangeStart(IMediaSeeking *iface) { - FIXME("(%p) filter hasn't implemented current position change!\n", iface); + FIXME("(%p) filter hasn't implemented start position change!\n", iface); return S_OK; } -static HRESULT Parser_ChangeStop(IBaseFilter *iface) +static HRESULT WINAPI Parser_ChangeStop(IMediaSeeking *iface) { FIXME("(%p) filter hasn't implemented stop position change!\n", iface); return S_OK; } -static HRESULT Parser_ChangeRate(IBaseFilter *iface) +static HRESULT WINAPI Parser_ChangeRate(IMediaSeeking *iface) { FIXME("(%p) filter hasn't implemented rate change!\n", iface); return S_OK; @@ -585,28 +540,98 @@ static const IMediaSeekingVtbl Parser_Seeking_Vtbl = Parser_Seeking_QueryInterface, Parser_Seeking_AddRef, Parser_Seeking_Release, - MediaSeekingImpl_GetCapabilities, - MediaSeekingImpl_CheckCapabilities, - MediaSeekingImpl_IsFormatSupported, - MediaSeekingImpl_QueryPreferredFormat, - MediaSeekingImpl_GetTimeFormat, - MediaSeekingImpl_IsUsingTimeFormat, - MediaSeekingImpl_SetTimeFormat, - MediaSeekingImpl_GetDuration, - MediaSeekingImpl_GetStopPosition, - MediaSeekingImpl_GetCurrentPosition, - MediaSeekingImpl_ConvertTimeFormat, - MediaSeekingImpl_SetPositions, - MediaSeekingImpl_GetPositions, - MediaSeekingImpl_GetAvailable, - MediaSeekingImpl_SetRate, - MediaSeekingImpl_GetRate, - MediaSeekingImpl_GetPreroll + SourceSeekingImpl_GetCapabilities, + SourceSeekingImpl_CheckCapabilities, + SourceSeekingImpl_IsFormatSupported, + SourceSeekingImpl_QueryPreferredFormat, + SourceSeekingImpl_GetTimeFormat, + SourceSeekingImpl_IsUsingTimeFormat, + SourceSeekingImpl_SetTimeFormat, + SourceSeekingImpl_GetDuration, + SourceSeekingImpl_GetStopPosition, + SourceSeekingImpl_GetCurrentPosition, + SourceSeekingImpl_ConvertTimeFormat, + SourceSeekingImpl_SetPositions, + SourceSeekingImpl_GetPositions, + SourceSeekingImpl_GetAvailable, + SourceSeekingImpl_SetRate, + SourceSeekingImpl_GetRate, + SourceSeekingImpl_GetPreroll }; +static HRESULT WINAPI Parser_OutputPin_DecideBufferSize(BaseOutputPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + Parser_OutputPin *This = (Parser_OutputPin*)iface; + ALLOCATOR_PROPERTIES actual; + + if (ppropInputRequest->cbAlign && ppropInputRequest->cbAlign != This->allocProps.cbAlign) + FIXME("Requested Buffer cbAlign mismatch %i,%i\n",This->allocProps.cbAlign, ppropInputRequest->cbAlign); + if (ppropInputRequest->cbPrefix) + FIXME("Requested Buffer cbPrefix mismatch %i,%i\n",This->allocProps.cbPrefix, ppropInputRequest->cbPrefix); + if (ppropInputRequest->cbBuffer) + FIXME("Requested Buffer cbBuffer mismatch %i,%i\n",This->allocProps.cbBuffer, ppropInputRequest->cbBuffer); + if (ppropInputRequest->cBuffers) + FIXME("Requested Buffer cBuffers mismatch %i,%i\n",This->allocProps.cBuffers, ppropInputRequest->cBuffers); + + return IMemAllocator_SetProperties(pAlloc, &This->allocProps, &actual); +} + +static HRESULT WINAPI Parser_OutputPin_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt) +{ + Parser_OutputPin *This = (Parser_OutputPin*)iface; + if (iPosition < 0) + return E_INVALIDARG; + if (iPosition > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(pmt, This->pmt); + return S_OK; +} + +static HRESULT WINAPI Parser_OutputPin_DecideAllocator(BaseOutputPin *iface, IMemInputPin *pPin, IMemAllocator **pAlloc) +{ + Parser_OutputPin *This = (Parser_OutputPin*)iface; + HRESULT hr; + + *pAlloc = NULL; + + if (This->alloc) + { + hr = IMemInputPin_NotifyAllocator(pPin, This->alloc, This->readonly); + if (SUCCEEDED(hr)) + { + *pAlloc = This->alloc; + IMemAllocator_AddRef(*pAlloc); + } + } + else + hr = VFW_E_NO_ALLOCATOR; + + return hr; +} + +static HRESULT WINAPI Parser_OutputPin_BreakConnect(BaseOutputPin *This) +{ + HRESULT hr; + + TRACE("(%p)->()\n", This); + + EnterCriticalSection(This->pin.pCritSec); + if (!This->pin.pConnectedTo || !This->pMemInputPin) + hr = VFW_E_NOT_CONNECTED; + else + { + hr = IPin_Disconnect(This->pin.pConnectedTo); + IPin_Disconnect(&This->pin.IPin_iface); + } + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + + static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) { - Parser_OutputPin *This = (Parser_OutputPin *)iface; + Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); @@ -616,10 +641,9 @@ static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, *ppv = iface; else if (IsEqualIID(riid, &IID_IPin)) *ppv = iface; + /* The Parser filter does not support querying IMediaSeeking, return it directly */ else if (IsEqualIID(riid, &IID_IMediaSeeking)) - { - return IBaseFilter_QueryInterface(This->pin.pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv); - } + *ppv = &impl_from_IBaseFilter(This->pin.pin.pinInfo.pFilter)->sourceSeeking; if (*ppv) { @@ -634,7 +658,7 @@ static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, static ULONG WINAPI Parser_OutputPin_Release(IPin * iface) { - Parser_OutputPin *This = (Parser_OutputPin *)iface; + Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount); TRACE("(%p)->() Release from %d\n", iface, refCount + 1); @@ -644,42 +668,30 @@ static ULONG WINAPI Parser_OutputPin_Release(IPin * iface) FreeMediaType(This->pmt); CoTaskMemFree(This->pmt); FreeMediaType(&This->pin.pin.mtCurrent); + if (This->pin.pAllocator) + IMemAllocator_Release(This->pin.pAllocator); CoTaskMemFree(This); return 0; } return refCount; } -static HRESULT WINAPI Parser_OutputPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum) -{ - ENUMMEDIADETAILS emd; - Parser_OutputPin *This = (Parser_OutputPin *)iface; - - TRACE("(%p)\n", ppEnum); - - /* override this method to allow enumeration of your types */ - emd.cMediaTypes = 1; - emd.pMediaTypes = This->pmt; - - return IEnumMediaTypesImpl_Construct(&emd, ppEnum); -} - static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) { - Parser_OutputPin *This = (Parser_OutputPin *)iface; - ParserImpl *parser = (ParserImpl *)This->pin.pin.pinInfo.pFilter; + Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); + ParserImpl *parser = impl_from_IBaseFilter(This->pin.pin.pinInfo.pFilter); /* Set the allocator to our input pin's */ EnterCriticalSection(This->pin.pin.pCritSec); - This->pin.alloc = parser->pInputPin->pAlloc; + This->alloc = parser->pInputPin->pAlloc; LeaveCriticalSection(This->pin.pin.pCritSec); - return OutputPin_Connect(iface, pReceivePin, pmt); + return BaseOutputPinImpl_Connect(iface, pReceivePin, pmt); } -static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI Parser_OutputPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE * pmt) { - Parser_OutputPin *This = iface; + Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); TRACE("()\n"); dump_AM_MEDIA_TYPE(pmt); @@ -690,29 +702,54 @@ static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * static const IPinVtbl Parser_OutputPin_Vtbl = { Parser_OutputPin_QueryInterface, - IPinImpl_AddRef, + BasePinImpl_AddRef, Parser_OutputPin_Release, Parser_OutputPin_Connect, - OutputPin_ReceiveConnection, - OutputPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - Parser_OutputPin_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - OutputPin_EndOfStream, - OutputPin_BeginFlush, - OutputPin_EndFlush, - OutputPin_NewSegment + BaseOutputPinImpl_ReceiveConnection, + BaseOutputPinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + Parser_OutputPin_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment }; +static HRESULT WINAPI Parser_PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) +{ + PullPin *This = impl_PullPin_from_IPin(iface); + + TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); + + *ppv = NULL; + + /* + * It is important to capture the request for the IMediaSeeking interface before it is passed + * on to PullPin_QueryInterface, this is necessary since the Parser filter does not support + * querying IMediaSeeking + */ + if (IsEqualIID(riid, &IID_IMediaSeeking)) + *ppv = &impl_from_IBaseFilter(This->pin.pinInfo.pFilter)->sourceSeeking; + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + return PullPin_QueryInterface(iface, riid, ppv); +} + static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface) { HRESULT hr; - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); TRACE("()\n"); @@ -722,7 +759,7 @@ static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface) if (This->pin.pConnectedTo) { FILTER_STATE state; - ParserImpl *Parser = (ParserImpl *)This->pin.pinInfo.pFilter; + ParserImpl *Parser = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); LeaveCriticalSection(This->pin.pCritSec); hr = IBaseFilter_GetState(This->pin.pinInfo.pFilter, INFINITE, &state); @@ -733,7 +770,7 @@ static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface) LeaveCriticalSection(This->pin.pCritSec); PullPin_Disconnect(iface); EnterCriticalSection(This->pin.pCritSec); - hr = Parser_RemoveOutputPins((ParserImpl *)This->pin.pinInfo.pFilter); + hr = Parser_RemoveOutputPins(impl_from_IBaseFilter(This->pin.pinInfo.pFilter)); } else hr = VFW_E_NOT_STOPPED; @@ -756,32 +793,41 @@ static HRESULT WINAPI Parser_PullPin_ReceiveConnection(IPin * iface, IPin * pRec hr = PullPin_ReceiveConnection(iface, pReceivePin, pmt); if (FAILED(hr)) { - IPinImpl *This = (IPinImpl *)iface; + BasePin *This = (BasePin *)iface; EnterCriticalSection(This->pCritSec); - Parser_RemoveOutputPins((ParserImpl *)This->pinInfo.pFilter); + Parser_RemoveOutputPins(impl_from_IBaseFilter(This->pinInfo.pFilter)); LeaveCriticalSection(This->pCritSec); } return hr; } +static HRESULT WINAPI Parser_PullPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum) +{ + BasePin *This = (BasePin *)iface; + + TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); + + return EnumMediaTypes_Construct(This, BasePinImpl_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum); +} + static const IPinVtbl Parser_InputPin_Vtbl = { - PullPin_QueryInterface, - IPinImpl_AddRef, + Parser_PullPin_QueryInterface, + BasePinImpl_AddRef, PullPin_Release, - InputPin_Connect, + BaseInputPinImpl_Connect, Parser_PullPin_ReceiveConnection, Parser_PullPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + PullPin_QueryAccept, + Parser_PullPin_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, PullPin_EndOfStream, PullPin_BeginFlush, PullPin_EndFlush, diff --git a/dll/directx/quartz/parser.h b/dll/directx/quartz/parser.h index b5423885400..996415a40df 100644 --- a/dll/directx/quartz/parser.h +++ b/dll/directx/quartz/parser.h @@ -28,37 +28,33 @@ typedef HRESULT (*PFN_DISCONNECT) (LPVOID iface); struct ParserImpl { - const IBaseFilterVtbl *lpVtbl; + BaseFilter filter; - LONG refCount; - CRITICAL_SECTION csFilter; - FILTER_STATE state; - REFERENCE_TIME rtStreamStart; - IReferenceClock * pClock; PFN_CLEANUP fnCleanup; PFN_DISCONNECT fnDisconnect; - FILTER_INFO filterInfo; - CLSID clsid; PullPin * pInputPin; IPin ** ppPins; ULONG cStreams; - DWORD lastpinchange; - MediaSeekingImpl mediaSeeking; + SourceSeeking sourceSeeking; }; typedef struct Parser_OutputPin { - OutputPin pin; + BaseOutputPin pin; AM_MEDIA_TYPE * pmt; LONGLONG dwSamplesProcessed; + ALLOCATOR_PROPERTIES allocProps; + + IMemAllocator *alloc; + BOOL readonly; } Parser_OutputPin; extern HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt); extern HRESULT Parser_Create(ParserImpl*, const IBaseFilterVtbl *, const CLSID*, PFN_PROCESS_SAMPLE, PFN_QUERY_ACCEPT, PFN_PRE_CONNECT, - PFN_CLEANUP, PFN_DISCONNECT, REQUESTPROC, STOPPROCESSPROC, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate); + PFN_CLEANUP, PFN_DISCONNECT, REQUESTPROC, STOPPROCESSPROC, SourceSeeking_ChangeStop stop, SourceSeeking_ChangeStart start, SourceSeeking_ChangeRate rate); /* Override the _Release function and call this when releasing */ extern void Parser_Destroy(ParserImpl *This); @@ -78,3 +74,9 @@ extern HRESULT WINAPI Parser_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppP extern HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo); extern HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName); extern HRESULT WINAPI Parser_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo); + +/* COM helpers */ +static inline Parser_OutputPin *unsafe_impl_Parser_OutputPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, Parser_OutputPin, pin.pin.IPin_iface); +} diff --git a/dll/directx/quartz/pin.c b/dll/directx/quartz/pin.c index 20d7aedde9b..0d8edb0a491 100644 --- a/dll/directx/quartz/pin.c +++ b/dll/directx/quartz/pin.c @@ -29,9 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); -static const IPinVtbl InputPin_Vtbl; -static const IPinVtbl OutputPin_Vtbl; -static const IMemInputPinVtbl MemInputPin_Vtbl; static const IPinVtbl PullPin_Vtbl; #define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary)) @@ -45,7 +42,7 @@ typedef HRESULT (*SendPinFunc)( IPin *to, LPVOID arg ); * Return the first received error code (E_NOTIMPL is ignored) * If no errors occur: return the first received non-error-code that isn't S_OK */ -HRESULT updatehres( HRESULT original, HRESULT new ) +static HRESULT updatehres( HRESULT original, HRESULT new ) { if (FAILED( original ) || new == E_NOTIMPL) return original; @@ -137,6 +134,8 @@ static HRESULT SendFurther( IPin *from, SendPinFunc fnMiddle, LPVOID arg, SendPi } out: + if (enumpins) + IEnumPins_Release( enumpins ); if (pin_info.pFilter) IBaseFilter_Release( pin_info.pFilter ); return hr; @@ -154,333 +153,21 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc) pDest->pFilter = pSrc->pFilter; } -/*** Common pin functions ***/ - -ULONG WINAPI IPinImpl_AddRef(IPin * iface) -{ - IPinImpl *This = (IPinImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1); - - return refCount; -} - -HRESULT WINAPI IPinImpl_Disconnect(IPin * iface) -{ - HRESULT hr; - IPinImpl *This = (IPinImpl *)iface; - - TRACE("()\n"); - - EnterCriticalSection(This->pCritSec); - { - if (This->pConnectedTo) - { - IPin_Release(This->pConnectedTo); - This->pConnectedTo = NULL; - FreeMediaType(&This->mtCurrent); - ZeroMemory(&This->mtCurrent, sizeof(This->mtCurrent)); - hr = S_OK; - } - else - hr = S_FALSE; - } - LeaveCriticalSection(This->pCritSec); - - return hr; -} - -HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin) -{ - HRESULT hr; - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p)\n", ppPin); - - EnterCriticalSection(This->pCritSec); - { - if (This->pConnectedTo) - { - *ppPin = This->pConnectedTo; - IPin_AddRef(*ppPin); - hr = S_OK; - } - else - { - hr = VFW_E_NOT_CONNECTED; - *ppPin = NULL; - } - } - LeaveCriticalSection(This->pCritSec); - - return hr; -} - -HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt) -{ - HRESULT hr; - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pmt); - - EnterCriticalSection(This->pCritSec); - { - if (This->pConnectedTo) - { - CopyMediaType(pmt, &This->mtCurrent); - hr = S_OK; - } - else - { - ZeroMemory(pmt, sizeof(*pmt)); - hr = VFW_E_NOT_CONNECTED; - } - } - LeaveCriticalSection(This->pCritSec); - - return hr; -} - -HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); - - Copy_PinInfo(pInfo, &This->pinInfo); - IBaseFilter_AddRef(pInfo->pFilter); - - return S_OK; -} - -HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pPinDir); - - *pPinDir = This->pinInfo.dir; - - return S_OK; -} - -HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, Id); - - *Id = CoTaskMemAlloc((strlenW(This->pinInfo.achName) + 1) * sizeof(WCHAR)); - if (!*Id) - return E_OUTOFMEMORY; - - strcpyW(*Id, This->pinInfo.achName); - - return S_OK; -} - -HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pmt); - - return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE); -} - -HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum) -{ - IPinImpl *This = (IPinImpl *)iface; - ENUMMEDIADETAILS emd; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - /* override this method to allow enumeration of your types */ - emd.cMediaTypes = 0; - emd.pMediaTypes = NULL; - - return IEnumMediaTypesImpl_Construct(&emd, ppEnum); -} - -HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p, %p)\n", This, iface, apPin, cPin); - - return E_NOTIMPL; /* to tell caller that all input pins connected to all output pins */ -} - -/*** IPin implementation for an input pin ***/ - -HRESULT WINAPI InputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) -{ - InputPin *This = (InputPin *)iface; - - TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IPin)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IMemInputPin)) - *ppv = &This->lpVtblMemInput; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - { - return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv); - } - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -ULONG WINAPI InputPin_Release(IPin * iface) -{ - InputPin *This = (InputPin *)iface; - ULONG refCount = InterlockedDecrement(&This->pin.refCount); - - TRACE("(%p)->() Release from %d\n", iface, refCount + 1); - - if (!refCount) - { - FreeMediaType(&This->pin.mtCurrent); - if (This->pAllocator) - IMemAllocator_Release(This->pAllocator); - This->pAllocator = NULL; - This->pin.lpVtbl = NULL; - CoTaskMemFree(This); - return 0; - } - else - return refCount; -} - -HRESULT WINAPI InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt) -{ - ERR("Outgoing connection on an input pin! (%p, %p)\n", pConnector, pmt); - - return E_UNEXPECTED; -} - - -HRESULT WINAPI InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - InputPin *This = (InputPin *)iface; - PIN_DIRECTION pindirReceive; - HRESULT hr = S_OK; - - TRACE("(%p, %p)\n", pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - EnterCriticalSection(This->pin.pCritSec); - { - if (This->pin.pConnectedTo) - hr = VFW_E_ALREADY_CONNECTED; - - if (SUCCEEDED(hr) && This->pin.fnQueryAccept(This->pin.pUserData, pmt) != S_OK) - hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto - * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */ - - if (SUCCEEDED(hr)) - { - IPin_QueryDirection(pReceivePin, &pindirReceive); - - if (pindirReceive != PINDIR_OUTPUT) - { - ERR("Can't connect from non-output pin\n"); - hr = VFW_E_INVALID_DIRECTION; - } - } - - if (SUCCEEDED(hr)) - { - CopyMediaType(&This->pin.mtCurrent, pmt); - This->pin.pConnectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - static HRESULT deliver_endofstream(IPin* pin, LPVOID unused) { return IPin_EndOfStream( pin ); } -HRESULT WINAPI InputPin_EndOfStream(IPin * iface) -{ - HRESULT hr = S_OK; - InputPin *This = (InputPin *)iface; - - TRACE("(%p)\n", This); - - EnterCriticalSection(This->pin.pCritSec); - if (This->flushing) - hr = S_FALSE; - else - This->end_of_stream = 1; - LeaveCriticalSection(This->pin.pCritSec); - - if (hr == S_OK) - hr = SendFurther( iface, deliver_endofstream, NULL, NULL ); - return hr; -} - static HRESULT deliver_beginflush(IPin* pin, LPVOID unused) { return IPin_BeginFlush( pin ); } -HRESULT WINAPI InputPin_BeginFlush(IPin * iface) -{ - InputPin *This = (InputPin *)iface; - HRESULT hr; - TRACE("() semi-stub\n"); - - EnterCriticalSection(This->pin.pCritSec); - This->flushing = 1; - - if (This->fnCleanProc) - This->fnCleanProc(This->pin.pUserData); - - hr = SendFurther( iface, deliver_beginflush, NULL, NULL ); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - static HRESULT deliver_endflush(IPin* pin, LPVOID unused) { return IPin_EndFlush( pin ); } -HRESULT WINAPI InputPin_EndFlush(IPin * iface) -{ - InputPin *This = (InputPin *)iface; - HRESULT hr; - TRACE("(%p)\n", This); - - EnterCriticalSection(This->pin.pCritSec); - This->flushing = This->end_of_stream = 0; - - hr = SendFurther( iface, deliver_endflush, NULL, NULL ); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - typedef struct newsegmentargs { REFERENCE_TIME tStart, tStop; @@ -493,578 +180,28 @@ static HRESULT deliver_newsegment(IPin *pin, LPVOID data) return IPin_NewSegment(pin, args->tStart, args->tStop, args->rate); } -HRESULT WINAPI InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - InputPin *This = (InputPin *)iface; - newsegmentargs args; - - TRACE("(%x%08x, %x%08x, %e)\n", (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate); - - args.tStart = This->tStart = tStart; - args.tStop = This->tStop = tStop; - args.rate = This->dRate = dRate; - - return SendFurther( iface, deliver_newsegment, &args, NULL ); -} - -static const IPinVtbl InputPin_Vtbl = -{ - InputPin_QueryInterface, - IPinImpl_AddRef, - InputPin_Release, - InputPin_Connect, - InputPin_ReceiveConnection, - IPinImpl_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - InputPin_EndOfStream, - InputPin_BeginFlush, - InputPin_EndFlush, - InputPin_NewSegment -}; - -/*** IMemInputPin implementation ***/ - -static inline InputPin *impl_from_IMemInputPin( IMemInputPin *iface ) -{ - return (InputPin *)((char*)iface - FIELD_OFFSET(InputPin, lpVtblMemInput)); -} - -static HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - return IPin_QueryInterface((IPin *)&This->pin, riid, ppv); -} - -static ULONG WINAPI MemInputPin_AddRef(IMemInputPin * iface) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - return IPin_AddRef((IPin *)&This->pin); -} - -static ULONG WINAPI MemInputPin_Release(IMemInputPin * iface) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - return IPin_Release((IPin *)&This->pin); -} - -static HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocator ** ppAllocator) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, ppAllocator); - - *ppAllocator = This->pAllocator; - if (*ppAllocator) - IMemAllocator_AddRef(*ppAllocator); - - return *ppAllocator ? S_OK : VFW_E_NO_ALLOCATOR; -} - -static HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllocator * pAllocator, BOOL bReadOnly) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - TRACE("(%p/%p)->(%p, %d)\n", This, iface, pAllocator, bReadOnly); - - if (bReadOnly) - FIXME("Read only flag not handled yet!\n"); - - /* FIXME: Should we release the allocator on disconnection? */ - if (!pAllocator) - { - WARN("Null allocator\n"); - return E_POINTER; - } - - if (This->preferred_allocator && pAllocator != This->preferred_allocator) - return E_FAIL; - - if (This->pAllocator) - IMemAllocator_Release(This->pAllocator); - This->pAllocator = pAllocator; - if (This->pAllocator) - IMemAllocator_AddRef(This->pAllocator); - - return S_OK; -} - -static HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface, ALLOCATOR_PROPERTIES * pProps) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pProps); - - /* override this method if you have any specific requirements */ - - return E_NOTIMPL; -} - -static HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * pSample) -{ - InputPin *This = impl_from_IMemInputPin(iface); - HRESULT hr; - - /* this trace commented out for performance reasons */ - /*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/ - hr = This->fnSampleProc(This->pin.pUserData, pSample); - return hr; -} - -static HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, LONG nSamples, LONG *nSamplesProcessed) -{ - HRESULT hr = S_OK; - InputPin *This = impl_from_IMemInputPin(iface); - - TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pSamples, nSamples, nSamplesProcessed); - - for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; (*nSamplesProcessed)++) - { - hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]); - if (hr != S_OK) - break; - } - - return hr; -} - -static HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface) -{ - InputPin *This = impl_from_IMemInputPin(iface); - - TRACE("(%p/%p)->()\n", This, iface); - - return S_OK; -} - -static const IMemInputPinVtbl MemInputPin_Vtbl = -{ - MemInputPin_QueryInterface, - MemInputPin_AddRef, - MemInputPin_Release, - MemInputPin_GetAllocator, - MemInputPin_NotifyAllocator, - MemInputPin_GetAllocatorRequirements, - MemInputPin_Receive, - MemInputPin_ReceiveMultiple, - MemInputPin_ReceiveCanBlock -}; - -/*** OutputPin implementation ***/ - -HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) -{ - OutputPin *This = (OutputPin *)iface; - - TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IPin)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - { - return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv); - } - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -ULONG WINAPI OutputPin_Release(IPin * iface) -{ - OutputPin *This = (OutputPin *)iface; - ULONG refCount = InterlockedDecrement(&This->pin.refCount); - - TRACE("(%p)->() Release from %d\n", iface, refCount + 1); - - if (!refCount) - { - FreeMediaType(&This->pin.mtCurrent); - CoTaskMemFree(This); - return 0; - } - return refCount; -} - -HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - HRESULT hr; - OutputPin *This = (OutputPin *)iface; - - TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - /* If we try to connect to ourself, we will definitely deadlock. - * There are other cases where we could deadlock too, but this - * catches the obvious case */ - assert(pReceivePin != iface); - - EnterCriticalSection(This->pin.pCritSec); - { - /* if we have been a specific type to connect with, then we can either connect - * with that or fail. We cannot choose different AM_MEDIA_TYPE */ - if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL)) - hr = This->pConnectSpecific(iface, pReceivePin, pmt); - else - { - /* negotiate media type */ - - IEnumMediaTypes * pEnumCandidates; - AM_MEDIA_TYPE * pmtCandidate = NULL; /* Candidate media type */ - - if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates))) - { - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - /* try this filter's media types first */ - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - assert(pmtCandidate); - dump_AM_MEDIA_TYPE(pmtCandidate); - if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype) - && !IsEqualGUID(&GUID_NULL, &pmtCandidate->formattype)) - assert(pmtCandidate->pbFormat); - if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && - (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) - { - hr = S_OK; - DeleteMediaType(pmtCandidate); - break; - } - DeleteMediaType(pmtCandidate); - pmtCandidate = NULL; - } - IEnumMediaTypes_Release(pEnumCandidates); - } - - /* then try receiver filter's media types */ - if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */ - { - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - assert(pmtCandidate); - dump_AM_MEDIA_TYPE(pmtCandidate); - if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && - (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) - { - hr = S_OK; - DeleteMediaType(pmtCandidate); - break; - } - DeleteMediaType(pmtCandidate); - pmtCandidate = NULL; - } /* while */ - IEnumMediaTypes_Release(pEnumCandidates); - } /* if not found */ - } /* if negotiate media type */ - } /* if succeeded */ - LeaveCriticalSection(This->pin.pCritSec); - - TRACE(" -- %x\n", hr); - return hr; -} - -HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - ERR("Incoming connection on an output pin! (%p, %p)\n", pReceivePin, pmt); - - return E_UNEXPECTED; -} - -HRESULT WINAPI OutputPin_Disconnect(IPin * iface) -{ - HRESULT hr; - OutputPin *This = (OutputPin *)iface; - - TRACE("()\n"); - - EnterCriticalSection(This->pin.pCritSec); - { - if (This->pMemInputPin) - { - IMemInputPin_Release(This->pMemInputPin); - This->pMemInputPin = NULL; - } - if (This->pin.pConnectedTo) - { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - FreeMediaType(&This->pin.mtCurrent); - ZeroMemory(&This->pin.mtCurrent, sizeof(This->pin.mtCurrent)); - hr = S_OK; - } - else - hr = S_FALSE; - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -HRESULT WINAPI OutputPin_EndOfStream(IPin * iface) -{ - TRACE("()\n"); - - /* not supposed to do anything in an output pin */ - - return E_UNEXPECTED; -} - -HRESULT WINAPI OutputPin_BeginFlush(IPin * iface) -{ - TRACE("(%p)->()\n", iface); - - /* not supposed to do anything in an output pin */ - - return E_UNEXPECTED; -} - -HRESULT WINAPI OutputPin_EndFlush(IPin * iface) -{ - TRACE("(%p)->()\n", iface); - - /* not supposed to do anything in an output pin */ - - return E_UNEXPECTED; -} - -HRESULT WINAPI OutputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - TRACE("(%p)->(%x%08x, %x%08x, %e)\n", iface, (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate); - - /* not supposed to do anything in an output pin */ - - return E_UNEXPECTED; -} - -static const IPinVtbl OutputPin_Vtbl = -{ - OutputPin_QueryInterface, - IPinImpl_AddRef, - OutputPin_Release, - OutputPin_Connect, - OutputPin_ReceiveConnection, - OutputPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - OutputPin_EndOfStream, - OutputPin_BeginFlush, - OutputPin_EndFlush, - OutputPin_NewSegment -}; - -HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags) -{ - HRESULT hr; - - TRACE("(%p, %p, %p, %x)\n", ppSample, tStart, tStop, dwFlags); - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo) - hr = VFW_E_NOT_CONNECTED; - else - { - IMemAllocator * pAlloc = NULL; - - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_GetBuffer(pAlloc, ppSample, tStart, tStop, dwFlags); - - if (SUCCEEDED(hr)) - hr = IMediaSample_SetTime(*ppSample, tStart, tStop); - - if (pAlloc) - IMemAllocator_Release(pAlloc); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample) -{ - HRESULT hr = S_OK; - IMemInputPin * pMemConnected = NULL; - PIN_INFO pinInfo; - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo || !This->pMemInputPin) - hr = VFW_E_NOT_CONNECTED; - else - { - /* we don't have the lock held when using This->pMemInputPin, - * so we need to AddRef it to stop it being deleted while we are - * using it. Same with its filter. */ - pMemConnected = This->pMemInputPin; - IMemInputPin_AddRef(pMemConnected); - hr = IPin_QueryPinInfo(This->pin.pConnectedTo, &pinInfo); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - if (SUCCEEDED(hr)) - { - /* NOTE: if we are in a critical section when Receive is called - * then it causes some problems (most notably with the native Video - * Renderer) if we are re-entered for whatever reason */ - hr = IMemInputPin_Receive(pMemConnected, pSample); - - /* If the filter's destroyed, tell upstream to stop sending data */ - if(IBaseFilter_Release(pinInfo.pFilter) == 0 && SUCCEEDED(hr)) - hr = S_FALSE; - } - if (pMemConnected) - IMemInputPin_Release(pMemConnected); - - return hr; -} - -HRESULT OutputPin_CommitAllocator(OutputPin * This) -{ - HRESULT hr = S_OK; - - TRACE("(%p)->()\n", This); - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo || !This->pMemInputPin) - hr = VFW_E_NOT_CONNECTED; - else - { - IMemAllocator * pAlloc = NULL; - - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_Commit(pAlloc); - - if (pAlloc) - IMemAllocator_Release(pAlloc); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - TRACE("--> %08x\n", hr); - return hr; -} - -HRESULT OutputPin_DecommitAllocator(OutputPin * This) -{ - HRESULT hr = S_OK; - - TRACE("(%p)->()\n", This); - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo || !This->pMemInputPin) - hr = VFW_E_NOT_CONNECTED; - else - { - IMemAllocator * pAlloc = NULL; - - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_Decommit(pAlloc); - - if (pAlloc) - IMemAllocator_Release(pAlloc); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - TRACE("--> %08x\n", hr); - return hr; -} - -HRESULT OutputPin_DeliverDisconnect(OutputPin * This) -{ - HRESULT hr; - - TRACE("(%p)->()\n", This); - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo || !This->pMemInputPin) - hr = VFW_E_NOT_CONNECTED; - else if (!This->custom_allocator) - { - IMemAllocator * pAlloc = NULL; - - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_Decommit(pAlloc); - - if (pAlloc) - IMemAllocator_Release(pAlloc); - - if (SUCCEEDED(hr)) - hr = IPin_Disconnect(This->pin.pConnectedTo); - } - else /* Kill the allocator! */ - { - hr = IPin_Disconnect(This->pin.pConnectedTo); - } - IPin_Disconnect((IPin *)This); - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - /*** PullPin implementation ***/ static HRESULT PullPin_Init(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl) { /* Common attributes */ - pPinImpl->pin.lpVtbl = PullPin_Vtbl; + pPinImpl->pin.IPin_iface.lpVtbl = PullPin_Vtbl; pPinImpl->pin.refCount = 1; pPinImpl->pin.pConnectedTo = NULL; - pPinImpl->pin.fnQueryAccept = pQueryAccept; - pPinImpl->pin.pUserData = pUserData; pPinImpl->pin.pCritSec = pCritSec; Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo); ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); /* Input pin attributes */ + pPinImpl->pUserData = pUserData; + pPinImpl->fnQueryAccept = pQueryAccept; pPinImpl->fnSampleProc = pSampleProc; pPinImpl->fnCleanProc = pCleanUp; pPinImpl->fnDone = pDone; pPinImpl->fnPreConnect = NULL; pPinImpl->pAlloc = NULL; + pPinImpl->prefAlloc = NULL; pPinImpl->pReader = NULL; pPinImpl->hThread = NULL; pPinImpl->hEventStateChanged = CreateEventW(NULL, TRUE, TRUE, NULL); @@ -1103,7 +240,7 @@ HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInf if (SUCCEEDED(PullPin_Init(PullPin_Vtbl, pPinInfo, pSampleProc, pUserData, pQueryAccept, pCleanUp, pCustomRequest, pDone, pCritSec, pPinImpl))) { - *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl); + *ppPin = &pPinImpl->pin.IPin_iface; return S_OK; } @@ -1117,7 +254,7 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const { PIN_DIRECTION pindirReceive; HRESULT hr = S_OK; - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt); dump_AM_MEDIA_TYPE(pmt); @@ -1132,7 +269,7 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const props.cbAlign = 1; props.cbPrefix = 0; - if (SUCCEEDED(hr) && (This->pin.fnQueryAccept(This->pin.pUserData, pmt) != S_OK)) + if (SUCCEEDED(hr) && (This->fnQueryAccept(This->pUserData, pmt) != S_OK)) hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */ @@ -1149,6 +286,7 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const This->pReader = NULL; This->pAlloc = NULL; + This->prefAlloc = NULL; if (SUCCEEDED(hr)) { hr = IPin_QueryInterface(pReceivePin, &IID_IAsyncReader, (LPVOID *)&This->pReader); @@ -1159,9 +297,19 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const hr = This->fnPreConnect(iface, pReceivePin, &props); } + /* + * Some custom filters (such as the one used by Fallout 3 + * and Fallout: New Vegas) expect to be passed a non-NULL + * preferred allocator. + */ if (SUCCEEDED(hr)) { - hr = IAsyncReader_RequestAllocator(This->pReader, NULL, &props, &This->pAlloc); + hr = StdMemAllocator_create(NULL, (LPVOID *) &This->prefAlloc); + } + + if (SUCCEEDED(hr)) + { + hr = IAsyncReader_RequestAllocator(This->pReader, This->prefAlloc, &props, &This->pAlloc); } if (SUCCEEDED(hr)) @@ -1180,6 +328,9 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const if (This->pReader) IAsyncReader_Release(This->pReader); This->pReader = NULL; + if (This->prefAlloc) + IMemAllocator_Release(This->prefAlloc); + This->prefAlloc = NULL; if (This->pAlloc) IMemAllocator_Release(This->pAlloc); This->pAlloc = NULL; @@ -1193,7 +344,7 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) { - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); @@ -1203,9 +354,10 @@ HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) *ppv = iface; else if (IsEqualIID(riid, &IID_IPin)) *ppv = iface; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) + else if (IsEqualIID(riid, &IID_IMediaSeeking) || + IsEqualIID(riid, &IID_IQualityControl)) { - return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv); + return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, riid, ppv); } if (*ppv) @@ -1221,7 +373,7 @@ HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) ULONG WINAPI PullPin_Release(IPin *iface) { - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); ULONG refCount = InterlockedDecrement(&This->pin.refCount); TRACE("(%p)->() Release from %d\n", This, refCount + 1); @@ -1231,6 +383,8 @@ ULONG WINAPI PullPin_Release(IPin *iface) WaitForSingleObject(This->hEventStateChanged, INFINITE); assert(!This->hThread); + if(This->prefAlloc) + IMemAllocator_Release(This->prefAlloc); if(This->pAlloc) IMemAllocator_Release(This->pAlloc); if(This->pReader) @@ -1252,6 +406,9 @@ static void PullPin_Flush(PullPin *This) if (This->pReader) { + /* Do not allow state to change while flushing */ + EnterCriticalSection(This->pin.pCritSec); + /* Flush outstanding samples */ IAsyncReader_BeginFlush(This->pReader); @@ -1270,6 +427,8 @@ static void PullPin_Flush(PullPin *This) } IAsyncReader_EndFlush(This->pReader); + + LeaveCriticalSection(This->pin.pCritSec); } } @@ -1290,12 +449,12 @@ static void PullPin_Thread_Process(PullPin *This) if (This->rtCurrent >= This->rtStop) { - IPin_EndOfStream((IPin *)This); + IPin_EndOfStream(&This->pin.IPin_iface); return; } /* There is no sample in our buffer */ - hr = This->fnCustomRequest(This->pin.pUserData); + hr = This->fnCustomRequest(This->pUserData); if (FAILED(hr)) ERR("Request error: %x\n", hr); @@ -1317,18 +476,19 @@ static void PullPin_Thread_Process(PullPin *This) /* Return an empty sample on error to the implementation in case it does custom parsing, so it knows it's gone */ if (SUCCEEDED(hr)) { - hr = This->fnSampleProc(This->pin.pUserData, pSample, dwUser); + hr = This->fnSampleProc(This->pUserData, pSample, dwUser); } else { - /* FIXME: This is not well handled yet! */ - ERR("Processing error: %x\n", hr); if (hr == VFW_E_TIMEOUT) { - assert(!pSample); + if (pSample != NULL) + WARN("Non-NULL sample returned with VFW_E_TIMEOUT.\n"); hr = S_OK; - continue; } + /* FIXME: Errors are not well handled yet! */ + else + ERR("Processing error: %x\n", hr); } if (pSample) @@ -1338,17 +498,29 @@ static void PullPin_Thread_Process(PullPin *This) } } while (This->rtCurrent < This->rtStop && hr == S_OK && !This->stop_playback); - /* Sample was rejected, and we are asked to terminate */ - if (pSample) + /* + * Sample was rejected, and we are asked to terminate. When there is more than one buffer + * it is possible for a filter to have several queued samples, making it necessary to + * release all of these pending samples. + */ + if (This->stop_playback || FAILED(hr)) { - IMediaSample_Release(pSample); + DWORD_PTR dwUser; + + do + { + if (pSample) + IMediaSample_Release(pSample); + pSample = NULL; + IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser); + } while(pSample); } /* Can't reset state to Sleepy here because that might race, instead PauseProcessing will do that for us * Flush remaining samples */ if (This->fnDone) - This->fnDone(This->pin.pUserData); + This->fnDone(This->pUserData); TRACE("End: %08x, %d\n", hr, This->stop_playback); } @@ -1490,11 +662,27 @@ HRESULT PullPin_PauseProcessing(PullPin * This) assert(This->state == Req_Run|| This->state == Req_Sleepy); assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT); + This->state = Req_Pause; This->stop_playback = 1; ResetEvent(This->hEventStateChanged); SetEvent(This->thread_sleepy); + /* Release any outstanding samples */ + if (This->pReader) + { + IMediaSample *pSample; + DWORD_PTR dwUser; + + do + { + pSample = NULL; + IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser); + if (pSample) + IMediaSample_Release(pSample); + } while(pSample); + } + LeaveCriticalSection(This->pin.pCritSec); } @@ -1527,16 +715,33 @@ HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds) return S_OK; } +HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt) +{ + PullPin *This = impl_PullPin_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pmt); + + return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE); +} + HRESULT WINAPI PullPin_EndOfStream(IPin * iface) { - FIXME("(%p)->() stub\n", iface); + PullPin *This = impl_PullPin_from_IPin(iface); + HRESULT hr = S_FALSE; - return SendFurther( iface, deliver_endofstream, NULL, NULL ); + TRACE("(%p)->()\n", iface); + + EnterCriticalSection(This->pin.pCritSec); + hr = SendFurther( iface, deliver_endofstream, NULL, NULL ); + SetEvent(This->hEventStateChanged); + LeaveCriticalSection(This->pin.pCritSec); + + return hr; } HRESULT WINAPI PullPin_BeginFlush(IPin * iface) { - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); TRACE("(%p)->()\n", This); EnterCriticalSection(This->pin.pCritSec); @@ -1561,7 +766,7 @@ HRESULT WINAPI PullPin_BeginFlush(IPin * iface) EnterCriticalSection(This->pin.pCritSec); { - This->fnCleanProc(This->pin.pUserData); + This->fnCleanProc(This->pUserData); } LeaveCriticalSection(This->pin.pCritSec); @@ -1570,7 +775,7 @@ HRESULT WINAPI PullPin_BeginFlush(IPin * iface) HRESULT WINAPI PullPin_EndFlush(IPin * iface) { - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); TRACE("(%p)->()\n", iface); @@ -1601,7 +806,7 @@ HRESULT WINAPI PullPin_EndFlush(IPin * iface) HRESULT WINAPI PullPin_Disconnect(IPin *iface) { HRESULT hr; - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); TRACE("()\n"); @@ -1643,222 +848,21 @@ HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE static const IPinVtbl PullPin_Vtbl = { PullPin_QueryInterface, - IPinImpl_AddRef, + BasePinImpl_AddRef, PullPin_Release, - InputPin_Connect, + BaseInputPinImpl_Connect, PullPin_ReceiveConnection, PullPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + PullPin_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, PullPin_EndOfStream, PullPin_BeginFlush, PullPin_EndFlush, PullPin_NewSegment }; - -/*** The Construct functions ***/ - -/* Function called as a helper to IPin_Connect */ -/* specific AM_MEDIA_TYPE - it cannot be NULL */ -/* NOTE: not part of standard interface */ -static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - OutputPin *This = (OutputPin *)iface; - HRESULT hr; - IMemAllocator * pMemAlloc = NULL; - ALLOCATOR_PROPERTIES actual; /* FIXME: should we put the actual props back in to This? */ - - TRACE("(%p, %p)\n", pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - /* FIXME: call queryacceptproc */ - - This->pin.pConnectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - CopyMediaType(&This->pin.mtCurrent, pmt); - - hr = IPin_ReceiveConnection(pReceivePin, iface, pmt); - - /* get the IMemInputPin interface we will use to deliver samples to the - * connected pin */ - if (SUCCEEDED(hr)) - { - This->pMemInputPin = NULL; - hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin); - - if (SUCCEEDED(hr) && !This->custom_allocator) - { - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pMemAlloc); - - if (hr == VFW_E_NO_ALLOCATOR) - /* Input pin provides no allocator, use standard memory allocator */ - hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual); - - if (SUCCEEDED(hr)) - hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, This->readonly); - - if (pMemAlloc) - IMemAllocator_Release(pMemAlloc); - } - else if (SUCCEEDED(hr)) - { - if (This->alloc) - { - hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, This->alloc, This->readonly); - } - else - hr = VFW_E_NO_ALLOCATOR; - } - - /* break connection if we couldn't get the allocator */ - if (FAILED(hr)) - { - if (This->pMemInputPin) - IMemInputPin_Release(This->pMemInputPin); - This->pMemInputPin = NULL; - - IPin_Disconnect(pReceivePin); - } - } - - if (FAILED(hr)) - { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - FreeMediaType(&This->pin.mtCurrent); - } - - TRACE(" -- %x\n", hr); - return hr; -} - -static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, - QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, InputPin * pPinImpl) -{ - TRACE("\n"); - - /* Common attributes */ - pPinImpl->pin.refCount = 1; - pPinImpl->pin.pConnectedTo = NULL; - pPinImpl->pin.fnQueryAccept = pQueryAccept; - pPinImpl->pin.pUserData = pUserData; - pPinImpl->pin.pCritSec = pCritSec; - Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo); - ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); - - /* Input pin attributes */ - pPinImpl->fnSampleProc = pSampleProc; - pPinImpl->fnCleanProc = pCleanUp; - pPinImpl->pAllocator = pPinImpl->preferred_allocator = allocator; - if (pPinImpl->preferred_allocator) - IMemAllocator_AddRef(pPinImpl->preferred_allocator); - pPinImpl->tStart = 0; - pPinImpl->tStop = 0; - pPinImpl->dRate = 1.0; - pPinImpl->pin.lpVtbl = InputPin_Vtbl; - pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl; - pPinImpl->flushing = pPinImpl->end_of_stream = 0; - - return S_OK; -} - -static HRESULT OutputPin_Init(const IPinVtbl *OutputPin_Vtbl, const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * props, LPVOID pUserData, - QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl) -{ - TRACE("\n"); - - /* Common attributes */ - pPinImpl->pin.lpVtbl = OutputPin_Vtbl; - pPinImpl->pin.refCount = 1; - pPinImpl->pin.pConnectedTo = NULL; - pPinImpl->pin.fnQueryAccept = pQueryAccept; - pPinImpl->pin.pUserData = pUserData; - pPinImpl->pin.pCritSec = pCritSec; - Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo); - ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); - - /* Output pin attributes */ - pPinImpl->pMemInputPin = NULL; - pPinImpl->pConnectSpecific = OutputPin_ConnectSpecific; - /* If custom_allocator is set, you will need to specify an allocator - * in the alloc member of the struct before an output pin can connect - */ - pPinImpl->custom_allocator = 0; - pPinImpl->alloc = NULL; - pPinImpl->readonly = FALSE; - if (props) - { - pPinImpl->allocProps = *props; - if (pPinImpl->allocProps.cbAlign == 0) - pPinImpl->allocProps.cbAlign = 1; - } - else - ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps)); - - return S_OK; -} - -HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, IPin ** ppPin) -{ - InputPin * pPinImpl; - - *ppPin = NULL; - - if (pPinInfo->dir != PINDIR_INPUT) - { - ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir); - return E_INVALIDARG; - } - - pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl)); - - if (!pPinImpl) - return E_OUTOFMEMORY; - - if (SUCCEEDED(InputPin_Init(InputPin_Vtbl, pPinInfo, pSampleProc, pUserData, pQueryAccept, pCleanUp, pCritSec, allocator, pPinImpl))) - { - *ppPin = (IPin *)pPinImpl; - return S_OK; - } - - CoTaskMemFree(pPinImpl); - return E_FAIL; -} - -HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) -{ - OutputPin * pPinImpl; - - *ppPin = NULL; - - if (pPinInfo->dir != PINDIR_OUTPUT) - { - ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir); - return E_INVALIDARG; - } - - assert(outputpin_size >= sizeof(OutputPin)); - - pPinImpl = CoTaskMemAlloc(outputpin_size); - - if (!pPinImpl) - return E_OUTOFMEMORY; - - if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl))) - { - *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl); - return S_OK; - } - - CoTaskMemFree(pPinImpl); - return E_FAIL; -} diff --git a/dll/directx/quartz/pin.h b/dll/directx/quartz/pin.h index e356ef32f53..428fa6fe8e4 100644 --- a/dll/directx/quartz/pin.h +++ b/dll/directx/quartz/pin.h @@ -24,7 +24,6 @@ * Cookie is the cookie that was set when requesting the buffer, if you don't * implement custom requesting, you can safely ignore this */ -typedef HRESULT (* SAMPLEPROC_PUSH)(LPVOID userdata, IMediaSample * pSample); typedef HRESULT (* SAMPLEPROC_PULL)(LPVOID userdata, IMediaSample * pSample, DWORD_PTR cookie); /* This function will determine whether a type is supported or not. @@ -66,56 +65,17 @@ typedef HRESULT (* STOPPROCESSPROC) (LPVOID userdata); #define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary)) #define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary))) -typedef struct IPinImpl -{ - const struct IPinVtbl * lpVtbl; - LONG refCount; - LPCRITICAL_SECTION pCritSec; - PIN_INFO pinInfo; - IPin * pConnectedTo; - AM_MEDIA_TYPE mtCurrent; - ENUMMEDIADETAILS enumMediaDetails; - QUERYACCEPTPROC fnQueryAccept; - LPVOID pUserData; -} IPinImpl; - -typedef struct InputPin -{ - /* inheritance C style! */ - IPinImpl pin; - - const IMemInputPinVtbl * lpVtblMemInput; - IMemAllocator * pAllocator; - SAMPLEPROC_PUSH fnSampleProc; - CLEANUPPROC fnCleanProc; - REFERENCE_TIME tStart; - REFERENCE_TIME tStop; - double dRate; - BOOL flushing, end_of_stream; - IMemAllocator *preferred_allocator; -} InputPin; - -typedef struct OutputPin -{ - /* inheritance C style! */ - IPinImpl pin; - - IMemInputPin * pMemInputPin; - HRESULT (* pConnectSpecific)(IPin * iface, IPin * pReceiver, const AM_MEDIA_TYPE * pmt); - BOOL custom_allocator; - IMemAllocator *alloc; - BOOL readonly; - ALLOCATOR_PROPERTIES allocProps; -} OutputPin; - typedef struct PullPin { /* inheritance C style! */ - IPinImpl pin; + BasePin pin; + LPVOID pUserData; REFERENCE_TIME rtStart, rtCurrent, rtNext, rtStop; IAsyncReader * pReader; + IMemAllocator * prefAlloc; IMemAllocator * pAlloc; + QUERYACCEPTPROC fnQueryAccept; SAMPLEPROC_PULL fnSampleProc; PRECONNECTPROC fnPreConnect; REQUESTPROC fnCustomRequest; @@ -142,58 +102,18 @@ typedef struct PullPin #define Req_Pause 3 /*** Constructors ***/ -HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *, IPin ** ppPin); -HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, STOPPROCESSPROC, REQUESTPROC pCustomRequest, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); /**************************/ /*** Pin Implementation ***/ -/* Common */ -ULONG WINAPI IPinImpl_AddRef(IPin * iface); -HRESULT WINAPI IPinImpl_Disconnect(IPin * iface); -HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin); -HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt); -HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo); -HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir); -HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id); -HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum); -HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin); - -/* Input Pin */ -HRESULT WINAPI InputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); -ULONG WINAPI InputPin_Release(IPin * iface); -HRESULT WINAPI InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI InputPin_EndOfStream(IPin * iface); -HRESULT WINAPI InputPin_BeginFlush(IPin * iface); -HRESULT WINAPI InputPin_EndFlush(IPin * iface); -HRESULT WINAPI InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); - -/* Output Pin */ -HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); -ULONG WINAPI OutputPin_Release(IPin * iface); -HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI OutputPin_Disconnect(IPin * iface); -HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI OutputPin_EndOfStream(IPin * iface); -HRESULT WINAPI OutputPin_BeginFlush(IPin * iface); -HRESULT WINAPI OutputPin_EndFlush(IPin * iface); -HRESULT WINAPI OutputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); - -HRESULT OutputPin_CommitAllocator(OutputPin * This); -HRESULT OutputPin_DecommitAllocator(OutputPin * This); -HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags); -HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample); -HRESULT OutputPin_DeliverDisconnect(OutputPin * This); - /* Pull Pin */ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); HRESULT WINAPI PullPin_Disconnect(IPin * iface); HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); ULONG WINAPI PullPin_Release(IPin * iface); HRESULT WINAPI PullPin_EndOfStream(IPin * iface); +HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); HRESULT WINAPI PullPin_BeginFlush(IPin * iface); HRESULT WINAPI PullPin_EndFlush(IPin * iface); HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); @@ -202,3 +122,9 @@ HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE HRESULT PullPin_StartProcessing(PullPin * This); HRESULT PullPin_PauseProcessing(PullPin * This); HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds); + +/* COM helpers */ +static inline PullPin *impl_PullPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, PullPin, pin.IPin_iface); +} diff --git a/dll/directx/quartz/quartz_private.h b/dll/directx/quartz/quartz_private.h index a5073a7ff2a..3fb620484dc 100644 --- a/dll/directx/quartz/quartz_private.h +++ b/dll/directx/quartz/quartz_private.h @@ -2,9 +2,6 @@ * * Copyright 2002 Lionel Ulmer * - * This file contains the (internal) driver registration functions, - * driver enumeration APIs and DirectDraw creation functions. - * * 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 @@ -39,6 +36,7 @@ #include #include #include +#include #include #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000) @@ -46,60 +44,35 @@ #define BYTES_FROM_MEDIATIME(time) SEC_FROM_MEDIATIME(time) #define MSEC_FROM_MEDIATIME(time) ((time) / 10000) -#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) +HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; +HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; +HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; +HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; +HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT StdMemAllocator_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT QUARTZ_CreateSystemClock(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv) DECLSPEC_HIDDEN; +HRESULT VMR9Impl_create(IUnknown *pUnkOuter, LPVOID *ppv) DECLSPEC_HIDDEN; -HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj); -HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj); -HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj); -HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj); -HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT StdMemAllocator_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT AVISplitter_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT MPEGSplitter_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT QUARTZ_CreateSystemClock(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv); -HRESULT SeekingPassThru_create(IUnknown *pUnkOuter, LPVOID *ppObj); +HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) DECLSPEC_HIDDEN; -HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum); +HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum) DECLSPEC_HIDDEN; +HRESULT IEnumFiltersImpl_Construct(IGraphVersion * pVersionSource, IBaseFilter *** pppFilters, ULONG * pNumFilters, IEnumFilters ** ppEnum) DECLSPEC_HIDDEN; -typedef struct tagENUMEDIADETAILS -{ - ULONG cMediaTypes; - AM_MEDIA_TYPE * pMediaTypes; -} ENUMMEDIADETAILS; +extern const char * qzdebugstr_guid(const GUID * id) DECLSPEC_HIDDEN; +extern void video_unregister_windowclass(void) DECLSPEC_HIDDEN; -typedef HRESULT (* FNOBTAINPIN)(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick); - -HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base); -HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum); -HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum); -HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum); - -extern const char * qzdebugstr_guid(const GUID * id); - -HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc); -void FreeMediaType(AM_MEDIA_TYPE * pmt); -void DeleteMediaType(AM_MEDIA_TYPE * pmt); BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards); -void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt); -HRESULT updatehres( HRESULT original, HRESULT new ); +void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt) DECLSPEC_HIDDEN; -typedef struct StdMediaSample2 -{ - const IMediaSample2Vtbl * lpvtbl; - - LONG ref; - AM_SAMPLE2_PROPERTIES props; - IMemAllocator * pParent; - struct list listentry; - LONGLONG tMediaStart; - LONGLONG tMediaEnd; -} StdMediaSample2; +HRESULT GetClassMediaFile(IAsyncReader * pReader, LPCOLESTR pszFileName, GUID * majorType, GUID * minorType, GUID * sourceFilter); #endif /* __QUARTZ_PRIVATE_INCLUDED__ */ diff --git a/dll/directx/quartz/quartz_strmif.idl b/dll/directx/quartz/quartz_strmif.idl index aad62321f27..ed7abe6b21a 100644 --- a/dll/directx/quartz/quartz_strmif.idl +++ b/dll/directx/quartz/quartz_strmif.idl @@ -16,7 +16,144 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* just a wrapper for strmif.idl */ - cpp_quote("#include ") #include "strmif.idl" + +[ + threading(both), + uuid(670d1d20-a068-11d0-b3f0-00aa003761c5) /* IAMCopyCaptureFileProgress */ +] +coclass PSFactoryBuffer { interface IFactoryBuffer; } + +[ + helpstring("Filter Graph"), + threading(both), + uuid(e436ebb3-524f-11ce-9f53-0020af0ba770) +] +coclass FilterGraph { interface IFilterGraph2; } + +[ + helpstring("Filter Graph no thread"), + threading(both), + uuid(e436ebb8-524f-11ce-9f53-0020af0ba770) +] +coclass FilterGraphNoThread { interface IFilterGraph2; } + +[ + helpstring("Filter Mapper"), + threading(both), + uuid(e436ebb2-524f-11ce-9f53-0020af0ba770) +] +coclass FilterMapper { interface IFilterMapper; } + +[ + helpstring("Filter Mapper2"), + threading(both), + uuid(cda42200-bd88-11d0-bd4e-00a0c911ce86) +] +coclass FilterMapper2 { interface IFilterMapper3; } + +[ + helpstring("System Clock"), + threading(both), + uuid(e436ebb1-524f-11ce-9f53-0020af0ba770) +] +coclass SystemClock { interface IReferenceClock; } + +[ + helpstring("Memory Allocator"), + threading(both), + uuid(1e651cc0-b199-11d0-8212-00c04fc32c45) +] +coclass MemoryAllocator { interface IMemAllocator; } + +[ + helpstring("Seeking"), + threading(both), + uuid(060af76c-68dd-11d0-8fc1-00c04fd9189d) +] +coclass SeekingPassThru { interface ISeekingPassThru; } + +[ + helpstring("File Source Filter"), + threading(both), + uuid(e436ebb5-524f-11ce-9f53-0020af0ba770) +] +coclass AsyncReader { interface IBaseFilter; } + +[ + helpstring("AVI Splitter"), + threading(both), + uuid(1b544c20-fd0b-11ce-8c63-00aa0044b51e) +] +coclass AviSplitter { interface IBaseFilter; } + +[ + helpstring("MPEG-I Stream Splitter"), + threading(both), + uuid(336475d0-942a-11ce-a870-00aa002feab5) +] +coclass MPEG1Splitter { interface IBaseFilter; } + +[ + helpstring("AVI Decompressor"), + threading(both), + uuid(cf49d4e0-1115-11ce-b03a-0020af0ba770) +] +coclass AVIDec { interface IBaseFilter; } + +[ + helpstring("DirectSound Audio Renderer"), + threading(both), + uuid(79376820-07d0-11cf-a24d-0020afd79767) +] +coclass DSoundRender { interface IBaseFilter; } + +[ + helpstring("Wave Audio Renderer"), + threading(both), + uuid(e30629d1-27e5-11ce-875d-00608cb78066) +] +coclass AudioRender { interface IBaseFilter; } + +[ + helpstring("Null Renderer"), + threading(both), + uuid(c1f400a4-3f08-11d3-9f0b-006008039e37) +] +coclass NullRenderer { interface IBaseFilter; } + +[ + helpstring("Video Renderer"), + threading(both), + uuid(70e102b0-5556-11ce-97c0-00aa0055595a) +] +coclass VideoRenderer { interface IBaseFilter; } + +[ + helpstring("Default Video Renderer"), + threading(both), + uuid(6bc1cffa-8fc1-4261-ac22-cfb4cc38db50) +] +coclass VideoRendererDefault { interface IBaseFilter; } + +[ + helpstring("ACM wrapper"), + threading(both), + uuid(6a08cf80-0e18-11cf-a24d-0020afd79767) +] +coclass ACMWrapper { interface IBaseFilter; } + +[ + helpstring("Wave Parser"), + threading(both), + uuid(d51bd5a1-7548-11cf-a520-0080c77ef58a) +] +coclass WAVEParser { interface IBaseFilter; } + +[ + helpstring("Video Mixing Renderer 9"), + threading(both), + uuid(51b4abf3-748f-4e3b-a276-c828330e926a) +] +coclass VideoMixingRenderer9 { interface IBaseFilter; } diff --git a/dll/directx/quartz/quartz_strmif.rgs b/dll/directx/quartz/quartz_strmif.rgs new file mode 100644 index 00000000000..69c6a05c7fa --- /dev/null +++ b/dll/directx/quartz/quartz_strmif.rgs @@ -0,0 +1,269 @@ +HKCR +{ + NoRemove Interface + { + '{29840822-5B84-11D0-BD3B-00A0C911CE86}' = s 'ICreateDevEnum' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A86891-0AD4-11CE-B03A-0020AF0BA770}' = s 'IPin' + { + NumMethods = s 18 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A86892-0AD4-11CE-B03A-0020AF0BA770}' = s 'IEnumPins' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{89C31040-846B-11CE-97D3-00AA0055595A}' = s 'IEnumMediaTypes' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A8689F-0AD4-11CE-B03A-0020AF0BA770}' = s 'IFilterGraph' + { + NumMethods = s 11 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A86893-0AD4-11CE-B03A-0020AF0BA770}' = s 'IEnumFilters' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A86899-0AD4-11CE-B03A-0020AF0BA770}' = s 'IMediaFilter' + { + NumMethods = s 10 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A86895-0AD4-11CE-B03A-0020AF0BA770}' = s 'IBaseFilter' + { + NumMethods = s 15 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A86897-0AD4-11CE-B03A-0020AF0BA770}' = s 'IReferenceClock' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A8689C-0AD4-11CE-B03A-0020AF0BA770}' = s 'IMemAllocator' + { + NumMethods = s 9 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{379A0CF0-C1DE-11D2-ABF5-00A0C905F375}' = s 'IMemAllocatorCallbackTemp' + { + NumMethods = s 11 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{92980B30-C1DE-11D2-ABF5-00A0C905F375}' = s 'IMemAllocatorNotifyCallbackTemp' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A8689D-0AD4-11CE-B03A-0020AF0BA770}' = s 'IMemInputPin' + { + NumMethods = s 9 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{A3D8CEC0-7E5A-11CF-BBC5-00805F6CEF20}' = s 'IAMovieSetup' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{36B73880-C2C8-11CF-8B46-00805F6CEF60}' = s 'IMediaSeeking' + { + NumMethods = s 20 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868A4-0AD4-11CE-B03A-0020AF0BA770}' = s 'IEnumRegFilters' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868A3-0AD4-11CE-B03A-0020AF0BA770}' = s 'IFilterMapper' + { + NumMethods = s 11 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{B79BB0B0-33C1-11D1-ABE1-00A0C905F375}' = s 'IFilterMapper2' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{B79BB0B1-33C1-11D1-ABE1-00A0C905F375}' = s 'IFilterMapper3' + { + NumMethods = s 8 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868A5-0AD4-11CE-B03A-0020AF0BA770}' = s 'IQualityControl' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868A2-0AD4-11CE-B03A-0020AF0BA770}' = s 'IMediaEventSink' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868A6-0AD4-11CE-B03A-0020AF0BA770}' = s 'IFileSourceFilter' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{A2104830-7C70-11CF-8BCE-00AA00A3F1A6}' = s 'IFileSinkFilter' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{00855B90-CE1B-11D0-BD4F-00A0C911CE86}' = s 'IFileSinkFilter2' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868A9-0AD4-11CE-B03A-0020AF0BA770}' = s 'IGraphBuilder' + { + NumMethods = s 18 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{BF87B6E0-8C27-11D0-B3F0-00AA003761C5}' = s 'ICaptureGraphBuilder' + { + NumMethods = s 11 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{670D1D20-A068-11D0-B3F0-00AA003761C5}' = s 'IAMCopyCaptureFileProgress' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{93E5A4E0-2D50-11D2-ABFA-00A0C9C6E38D}' = s 'ICaptureGraphBuilder2' + { + NumMethods = s 12 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{36B73882-C2C8-11CF-8B46-00805F6CEF60}' = s 'IFilterGraph2' + { + NumMethods = s 21 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{C6E13340-30AC-11D0-A18C-00A0C9118956}' = s 'IAMStreamConfig' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{C6E13360-30AC-11D0-A18C-00A0C9118956}' = s 'IAMVideoProcAmp' + { + NumMethods = s 6 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868AA-0AD4-11CE-B03A-0020AF0BA770}' = s 'IAsyncReader' + { + NumMethods = s 11 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868AB-0AD4-11CE-B03A-0020AF0BA770}' = s 'IGraphVersion' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868AD-0AD4-11CE-B03A-0020AF0BA770}' = s 'IResourceConsumer' + { + NumMethods = s 5 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{56A868AC-0AD4-11CE-B03A-0020AF0BA770}' = s 'IResourceManager' + { + NumMethods = s 11 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + '{36B73883-C2C8-11CF-8B46-00805F6CEF60}' = s 'ISeekingPassThru' + { + NumMethods = s 4 + ProxyStubClsid32 = s '{670D1D20-A068-11D0-B3F0-00AA003761C5}' + } + } + NoRemove CLSID + { + '{670D1D20-A068-11D0-B3F0-00AA003761C5}' = s 'PSFactoryBuffer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{E436EBB3-524F-11CE-9F53-0020AF0BA770}' = s 'Filter Graph' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{E436EBB8-524F-11CE-9F53-0020AF0BA770}' = s 'Filter Graph no thread' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{E436EBB2-524F-11CE-9F53-0020AF0BA770}' = s 'Filter Mapper' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{CDA42200-BD88-11D0-BD4E-00A0C911CE86}' = s 'Filter Mapper2' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{E436EBB1-524F-11CE-9F53-0020AF0BA770}' = s 'System Clock' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{1E651CC0-B199-11D0-8212-00C04FC32C45}' = s 'Memory Allocator' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{060AF76C-68DD-11D0-8FC1-00C04FD9189D}' = s 'Seeking' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{E436EBB5-524F-11CE-9F53-0020AF0BA770}' = s 'File Source Filter' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{1B544C20-FD0B-11CE-8C63-00AA0044B51E}' = s 'AVI Splitter' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{336475D0-942A-11CE-A870-00AA002FEAB5}' = s 'MPEG-I Stream Splitter' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{CF49D4E0-1115-11CE-B03A-0020AF0BA770}' = s 'AVI Decompressor' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{79376820-07D0-11CF-A24D-0020AFD79767}' = s 'DirectSound Audio Renderer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{E30629D1-27E5-11CE-875D-00608CB78066}' = s 'Wave Audio Renderer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{C1F400A4-3F08-11D3-9F0B-006008039E37}' = s 'Null Renderer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{70E102B0-5556-11CE-97C0-00AA0055595A}' = s 'Video Renderer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{6BC1CFFA-8FC1-4261-AC22-CFB4CC38DB50}' = s 'Default Video Renderer' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{6A08CF80-0E18-11CF-A24D-0020AFD79767}' = s 'ACM wrapper' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{D51BD5A1-7548-11CF-A520-0080C77EF58A}' = s 'Wave Parser' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{51B4ABF3-748F-4E3B-A276-C828330E926A}' = s 'Video Mixing Renderer 9' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } +} diff --git a/dll/directx/quartz/regsvr.c b/dll/directx/quartz/regsvr.c index b5ec6ea7674..1b802c8af93 100644 --- a/dll/directx/quartz/regsvr.c +++ b/dll/directx/quartz/regsvr.c @@ -129,43 +129,43 @@ static HRESULT unregister_filters(struct regsvr_filter const *list); /*********************************************************************** * static string constants */ -static WCHAR const interface_keyname[10] = { +static const WCHAR interface_keyname[] = { 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; -static WCHAR const base_ifa_keyname[14] = { +static const WCHAR base_ifa_keyname[] = { 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; -static WCHAR const num_methods_keyname[11] = { +static const WCHAR num_methods_keyname[] = { 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; -static WCHAR const ps_clsid_keyname[15] = { +static const WCHAR ps_clsid_keyname[] = { 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', 'i', 'd', 0 }; -static WCHAR const ps_clsid32_keyname[17] = { +static const WCHAR ps_clsid32_keyname[] = { 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', 'i', 'd', '3', '2', 0 }; -static WCHAR const clsid_keyname[6] = { +static const WCHAR clsid_keyname[] = { 'C', 'L', 'S', 'I', 'D', 0 }; -static WCHAR const curver_keyname[7] = { +static const WCHAR curver_keyname[] = { 'C', 'u', 'r', 'V', 'e', 'r', 0 }; -static WCHAR const ips_keyname[13] = { +static const WCHAR ips_keyname[] = { 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 0 }; -static WCHAR const ips32_keyname[15] = { +static const WCHAR ips32_keyname[] = { 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', '3', '2', 0 }; -static WCHAR const progid_keyname[7] = { +static const WCHAR progid_keyname[] = { 'P', 'r', 'o', 'g', 'I', 'D', 0 }; -static WCHAR const viprogid_keyname[25] = { +static const WCHAR viprogid_keyname[] = { 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', 0 }; -static char const tmodel_valuename[] = "ThreadingModel"; -static WCHAR const mediatype_name[11] = { +static const char tmodel_valuename[] = "ThreadingModel"; +static const WCHAR mediatype_name[] = { 'M', 'e', 'd', 'i', 'a', ' ', 'T', 'y', 'p', 'e', 0 }; -static WCHAR const subtype_valuename[8] = { +static const WCHAR subtype_valuename[] = { 'S', 'u', 'b', 't', 'y', 'p', 'e', 0 }; -static WCHAR const sourcefilter_valuename[14] = { +static const WCHAR sourcefilter_valuename[] = { 'S', 'o', 'u', 'r', 'c', 'e', ' ', 'F', 'i', 'l', 't', 'e', 'r', 0 }; -static WCHAR const extensions_keyname[11] = { +static const WCHAR extensions_keyname[] = { 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', 0 }; /*********************************************************************** @@ -214,7 +214,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list) } if (0 <= list->num_methods) { - static WCHAR const fmt[3] = { '%', 'd', 0 }; + static const WCHAR fmt[] = { '%', 'd', 0 }; HKEY key; res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, @@ -595,8 +595,8 @@ static HRESULT register_filters(struct regsvr_filter const *list) for (i = 0; list->pins[i].flags != 0xFFFFFFFF; i++) ; rf2.dwVersion = 2; rf2.dwMerit = list->merit; - rf2.u.s1.cPins2 = i; - rf2.u.s1.rgPins2 = prfp2 = CoTaskMemAlloc(i*sizeof(REGFILTERPINS2)); + rf2.u.s2.cPins2 = i; + rf2.u.s2.rgPins2 = prfp2 = CoTaskMemAlloc(i*sizeof(REGFILTERPINS2)); if (!prfp2) { hr = E_OUTOFMEMORY; break; @@ -783,121 +783,10 @@ error_close_progid_key: return res; } -static GUID const CLSID_PSFactoryBuffer = { - 0x92a3a302, 0xda7c, 0x4a1f, {0xba,0x7e,0x18,0x02,0xbb,0x5d,0x2d,0x02} }; - /*********************************************************************** * coclass list */ static struct regsvr_coclass const coclass_list[] = { - { &CLSID_FilterGraph, - "Filter Graph", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_FilterGraphNoThread, - "Filter Graph", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_FilterMapper, - "Filter Mapper", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_FilterMapper2, - "Filter Mapper2", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_SystemClock, - "System Clock", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_MemoryAllocator, - "Memory Allocator", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_SeekingPassThru, - "Seeking", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_AsyncReader, - "File Source Filter", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_AviSplitter, - "AVI Splitter", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_MPEG1Splitter, - "MPEG-I Stream Splitter", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_AVIDec, - "AVI Decompressor", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_DSoundRender, - "DirectSound Audio Renderer", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_AudioRender, - "Wave Audio Renderer", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_NullRenderer, - "Null Renderer", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_VideoRenderer, - "Video Renderer", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_VideoRendererDefault, - "Default Video Renderer", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_ACMWrapper, - "ACM wrapper", - NULL, - "quartz.dll", - "Both" - }, - { &CLSID_WAVEParser, - "Wave Parser", - NULL, - "quartz.dll", - "Both" - }, { NULL } /* list terminator */ }; @@ -997,7 +886,7 @@ static struct regsvr_filter const filter_list[] = { { &CLSID_AviSplitter, &CLSID_LegacyAmFilterCategory, {'A','V','I',' ','S','p','l','i','t','t','e','r',0}, - 0x600000, + 0x5ffff0, { { 0, { { &MEDIATYPE_Stream, &MEDIASUBTYPE_Avi }, { NULL } @@ -1014,7 +903,7 @@ static struct regsvr_filter const filter_list[] = { { &CLSID_MPEG1Splitter, &CLSID_LegacyAmFilterCategory, {'M','P','E','G','-','I',' ','S','t','r','e','a','m',' ','S','p','l','i','t','t','e','r',0}, - 0x600000, + 0x5ffff0, { { 0, { { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio }, { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Video }, @@ -1074,6 +963,18 @@ static struct regsvr_filter const filter_list[] = { { 0xFFFFFFFF }, } }, + { &CLSID_VideoMixingRenderer9, + &CLSID_LegacyAmFilterCategory, + {'V','i','d','e','o',' ','M','i','x','i','n','g',' ','R','e','n','d','e','r','e','r',' ','9',0}, + 0x200000, + { { REG_PINFLAG_B_RENDERER, + { { &MEDIATYPE_Video, &GUID_NULL }, + { NULL } + }, + }, + { 0xFFFFFFFF }, + } + }, { &CLSID_DSoundRender, &CLSID_LegacyAmFilterCategory, {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r',0}, @@ -1103,7 +1004,7 @@ static struct regsvr_filter const filter_list[] = { { &CLSID_AVIDec, &CLSID_LegacyAmFilterCategory, {'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0}, - 0x600000, + 0x5ffff0, { { 0, { { &MEDIATYPE_Video, &GUID_NULL }, { NULL } @@ -1132,7 +1033,7 @@ static struct regsvr_filter const filter_list[] = { { &CLSID_ACMWrapper, &CLSID_LegacyAmFilterCategory, {'A','C','M',' ','W','r','a','p','p','e','r',0}, - 0x600000, + 0x5ffff0, { { 0, { { &MEDIATYPE_Audio, &GUID_NULL }, { NULL } diff --git a/dll/directx/quartz/systemclock.c b/dll/directx/quartz/systemclock.c index a36512e5f56..259c547fccc 100644 --- a/dll/directx/quartz/systemclock.c +++ b/dll/directx/quartz/systemclock.c @@ -37,7 +37,7 @@ struct SystemClockAdviseEntry { }; typedef struct SystemClockImpl { - const IReferenceClockVtbl *lpVtbl; + IReferenceClock IReferenceClock_iface; LONG ref; /** IReferenceClock */ @@ -52,6 +52,11 @@ typedef struct SystemClockImpl { SystemClockAdviseEntry* pPeriodicAdvise; } SystemClockImpl; +static inline SystemClockImpl *impl_from_IReferenceClock(IReferenceClock *iface) +{ + return CONTAINING_RECORD(iface, SystemClockImpl, IReferenceClock_iface); +} + static void QUARTZ_RemoveAviseEntryFromQueue(SystemClockImpl* This, SystemClockAdviseEntry* pEntry) { if (pEntry->prev) pEntry->prev->next = pEntry->next; @@ -104,19 +109,22 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { EnterCriticalSection(&This->safe); /*timeOut = IReferenceClock_OnTimerUpdated(This); */ - hr = IReferenceClock_GetTime((IReferenceClock*) This, &curTime); + hr = IReferenceClock_GetTime(&This->IReferenceClock_iface, &curTime); if (FAILED(hr)) { timeOut = INFINITE; goto outrefresh; } /** First SingleShots Advice: sorted list */ - for (it = This->pSingleShotAdvise; NULL != it && (it->rtBaseTime + it->rtIntervalTime) <= curTime; it = it->next) { + it = This->pSingleShotAdvise; + while ((NULL != it) && (it->rtBaseTime + it->rtIntervalTime) <= curTime) { + SystemClockAdviseEntry* nextit = it->next; /** send event ... */ SetEvent(it->hEvent); /** ... and Release it */ QUARTZ_RemoveAviseEntryFromQueue(This, it); CoTaskMemFree(it); + it = nextit; } if (NULL != it) timeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000; @@ -137,11 +145,11 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { outrefresh: LeaveCriticalSection(&This->safe); - while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) { + while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { /** if hwnd we suppose that is a windows event ... */ if (NULL != msg.hwnd) { TranslateMessage(&msg); - DispatchMessageA(&msg); + DispatchMessageW(&msg); } else { switch (msg.message) { case WM_QUIT: @@ -178,7 +186,7 @@ static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMs SetThreadPriority(This->adviseThread, THREAD_PRIORITY_TIME_CRITICAL); This->adviseThreadActive = TRUE; while(1) { - res = PostThreadMessageA(This->adviseThreadId, iMsg, 0, 0); + res = PostThreadMessageW(This->adviseThreadId, iMsg, 0, 0); /* Let the thread creates its message queue (with MsgWaitForMultipleObjects call) by yielding and retrying */ if (!res && (GetLastError() == ERROR_INVALID_THREAD_ID)) Sleep(0); @@ -187,11 +195,11 @@ static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMs } return res; } - return PostThreadMessageA(This->adviseThreadId, iMsg, 0, 0); + return PostThreadMessageW(This->adviseThreadId, iMsg, 0, 0); } static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock* iface) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p): AddRef from %d\n", This, ref - 1); @@ -200,7 +208,7 @@ static ULONG WINAPI SystemClockImpl_AddRef(IReferenceClock* iface) { } static HRESULT WINAPI SystemClockImpl_QueryInterface(IReferenceClock* iface, REFIID riid, void** ppobj) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); TRACE("(%p, %s,%p)\n", This, debugstr_guid(riid), ppobj); if (IsEqualIID (riid, &IID_IUnknown) || @@ -216,7 +224,7 @@ static HRESULT WINAPI SystemClockImpl_QueryInterface(IReferenceClock* iface, REF } static ULONG WINAPI SystemClockImpl_Release(IReferenceClock* iface) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p): ReleaseRef to %d\n", This, ref); if (ref == 0) { @@ -232,7 +240,7 @@ static ULONG WINAPI SystemClockImpl_Release(IReferenceClock* iface) { } static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock* iface, REFERENCE_TIME* pTime) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); DWORD curTimeTickCount; HRESULT hr = S_OK; @@ -254,7 +262,7 @@ static HRESULT WINAPI SystemClockImpl_GetTime(IReferenceClock* iface, REFERENCE_ } static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock* iface, REFERENCE_TIME rtBaseTime, REFERENCE_TIME rtStreamTime, HEVENT hEvent, DWORD_PTR* pdwAdviseCookie) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); SystemClockAdviseEntry* pEntry = NULL; TRACE("(%p, 0x%s, 0x%s, %ld, %p)\n", This, wine_dbgstr_longlong(rtBaseTime), @@ -290,7 +298,7 @@ static HRESULT WINAPI SystemClockImpl_AdviseTime(IReferenceClock* iface, REFEREN } static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, REFERENCE_TIME rtStartTime, REFERENCE_TIME rtPeriodTime, HSEMAPHORE hSemaphore, DWORD_PTR* pdwAdviseCookie) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); SystemClockAdviseEntry* pEntry = NULL; TRACE("(%p, 0x%s, 0x%s, %ld, %p)\n", This, wine_dbgstr_longlong(rtStartTime), @@ -326,7 +334,7 @@ static HRESULT WINAPI SystemClockImpl_AdvisePeriodic(IReferenceClock* iface, REF } static HRESULT WINAPI SystemClockImpl_Unadvise(IReferenceClock* iface, DWORD_PTR dwAdviseCookie) { - SystemClockImpl *This = (SystemClockImpl *)iface; + SystemClockImpl *This = impl_from_IReferenceClock(iface); SystemClockAdviseEntry* pEntry = NULL; SystemClockAdviseEntry* it = NULL; HRESULT ret = S_OK; @@ -377,12 +385,12 @@ HRESULT QUARTZ_CreateSystemClock(IUnknown * pUnkOuter, LPVOID * ppv) { } ZeroMemory(obj, sizeof(SystemClockImpl)); - obj->lpVtbl = &SystemClock_Vtbl; + obj->IReferenceClock_iface.lpVtbl = &SystemClock_Vtbl; obj->ref = 0; /* will be inited by QueryInterface */ obj->lastTimeTickCount = GetTickCount(); InitializeCriticalSection(&obj->safe); obj->safe.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SystemClockImpl.safe"); - return SystemClockImpl_QueryInterface((IReferenceClock*) obj, &IID_IReferenceClock, ppv); + return SystemClockImpl_QueryInterface(&obj->IReferenceClock_iface, &IID_IReferenceClock, ppv); } diff --git a/dll/directx/quartz/transform.c b/dll/directx/quartz/transform.c deleted file mode 100644 index ceb04c171ed..00000000000 --- a/dll/directx/quartz/transform.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Transform Filter (Base for decoders, etc...) - * - * Copyright 2005 Christian Costa - * - * 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 - */ - -#include - -#include "quartz_private.h" -//#include "control_private.h" -#include "pin.h" - -//#include "amvideo.h" -//#include "windef.h" -//#include "winbase.h" -//#include "dshow.h" -//#include "strmif.h" -//#include "vfw.h" - -//#include - -#include -#include - -#include "transform.h" - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; -static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0}; - -static const IBaseFilterVtbl TransformFilter_Vtbl; -static const IPinVtbl TransformFilter_InputPin_Vtbl; -static const IPinVtbl TransformFilter_OutputPin_Vtbl; - -static HRESULT TransformFilter_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) -{ - TransformFilterImpl* This = (TransformFilterImpl *)((IPinImpl *)iface)->pinInfo.pFilter; - TRACE("%p\n", iface); - dump_AM_MEDIA_TYPE(pmt); - - if (This->pFuncsTable->pfnQueryConnect) - return This->pFuncsTable->pfnQueryConnect(This, pmt); - /* Assume OK if there's no query method (the connection will fail if - needed) */ - return S_OK; -} - - -static HRESULT TransformFilter_Output_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) -{ - TransformFilterImpl* pTransformFilter = iface; - AM_MEDIA_TYPE* outpmt = &pTransformFilter->pmt; - TRACE("%p\n", iface); - - if (IsEqualIID(&pmt->majortype, &outpmt->majortype) - && (IsEqualIID(&pmt->subtype, &outpmt->subtype) || IsEqualIID(&outpmt->subtype, &GUID_NULL))) - return S_OK; - return S_FALSE; -} - - -static inline TransformFilterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) -{ - return (TransformFilterImpl *)((char*)iface - FIELD_OFFSET(TransformFilterImpl, mediaSeeking.lpVtbl)); -} - -static HRESULT WINAPI TransformFilter_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) -{ - TransformFilterImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); -} - -static ULONG WINAPI TransformFilter_Seeking_AddRef(IMediaSeeking * iface) -{ - TransformFilterImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_AddRef((IUnknown *)This); -} - -static ULONG WINAPI TransformFilter_Seeking_Release(IMediaSeeking * iface) -{ - TransformFilterImpl *This = impl_from_IMediaSeeking(iface); - - return IUnknown_Release((IUnknown *)This); -} - -static const IMediaSeekingVtbl TransformFilter_Seeking_Vtbl = -{ - TransformFilter_Seeking_QueryInterface, - TransformFilter_Seeking_AddRef, - TransformFilter_Seeking_Release, - MediaSeekingImpl_GetCapabilities, - MediaSeekingImpl_CheckCapabilities, - MediaSeekingImpl_IsFormatSupported, - MediaSeekingImpl_QueryPreferredFormat, - MediaSeekingImpl_GetTimeFormat, - MediaSeekingImpl_IsUsingTimeFormat, - MediaSeekingImpl_SetTimeFormat, - MediaSeekingImpl_GetDuration, - MediaSeekingImpl_GetStopPosition, - MediaSeekingImpl_GetCurrentPosition, - MediaSeekingImpl_ConvertTimeFormat, - MediaSeekingImpl_SetPositions, - MediaSeekingImpl_GetPositions, - MediaSeekingImpl_GetAvailable, - MediaSeekingImpl_SetRate, - MediaSeekingImpl_GetRate, - MediaSeekingImpl_GetPreroll -}; - -/* These shouldn't be implemented by default. - * Usually only source filters should implement these - * and even it's not needed all of the time - */ -static HRESULT TransformFilter_ChangeCurrent(IBaseFilter *iface) -{ - TRACE("(%p) filter hasn't implemented current position change!\n", iface); - return S_OK; -} - -static HRESULT TransformFilter_ChangeStop(IBaseFilter *iface) -{ - TRACE("(%p) filter hasn't implemented stop position change!\n", iface); - return S_OK; -} - -static HRESULT TransformFilter_ChangeRate(IBaseFilter *iface) -{ - TRACE("(%p) filter hasn't implemented rate change!\n", iface); - return S_OK; -} - -HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, const TransformFuncsTable* pFuncsTable, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate) -{ - HRESULT hr; - PIN_INFO piInput; - PIN_INFO piOutput; - - /* pTransformFilter is already allocated */ - pTransformFilter->clsid = *pClsid; - pTransformFilter->pFuncsTable = pFuncsTable; - - pTransformFilter->lpVtbl = &TransformFilter_Vtbl; - - pTransformFilter->refCount = 1; - InitializeCriticalSection(&pTransformFilter->csFilter); - pTransformFilter->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TransformFilterImpl.csFilter"); - pTransformFilter->state = State_Stopped; - pTransformFilter->pClock = NULL; - ZeroMemory(&pTransformFilter->filterInfo, sizeof(FILTER_INFO)); - ZeroMemory(&pTransformFilter->pmt, sizeof(pTransformFilter->pmt)); - pTransformFilter->npins = 2; - - pTransformFilter->ppPins = CoTaskMemAlloc(2 * sizeof(IPin *)); - - /* construct input pin */ - piInput.dir = PINDIR_INPUT; - piInput.pFilter = (IBaseFilter *)pTransformFilter; - lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); - piOutput.dir = PINDIR_OUTPUT; - piOutput.pFilter = (IBaseFilter *)pTransformFilter; - lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0])); - - hr = InputPin_Construct(&TransformFilter_InputPin_Vtbl, &piInput, (SAMPLEPROC_PUSH)pFuncsTable->pfnProcessSampleData, NULL, TransformFilter_Input_QueryAccept, NULL, &pTransformFilter->csFilter, NULL, &pTransformFilter->ppPins[0]); - - if (SUCCEEDED(hr)) - { - ALLOCATOR_PROPERTIES props; - props.cbAlign = 1; - props.cbPrefix = 0; - props.cbBuffer = 0; /* Will be updated at connection time */ - props.cBuffers = 1; - - ((InputPin *)pTransformFilter->ppPins[0])->pin.pUserData = pTransformFilter->ppPins[0]; - - hr = OutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(OutputPin), &piOutput, &props, pTransformFilter, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]); - - if (FAILED(hr)) - ERR("Cannot create output pin (%x)\n", hr); - else - { - if (!stop) - stop = TransformFilter_ChangeStop; - if (!current) - current = TransformFilter_ChangeCurrent; - if (!rate) - rate = TransformFilter_ChangeRate; - - MediaSeekingImpl_Init((IBaseFilter*)pTransformFilter, stop, current, rate, &pTransformFilter->mediaSeeking, &pTransformFilter->csFilter); - pTransformFilter->mediaSeeking.lpVtbl = &TransformFilter_Seeking_Vtbl; - } - } - else - { - CoTaskMemFree(pTransformFilter->ppPins); - pTransformFilter->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&pTransformFilter->csFilter); - CoTaskMemFree(pTransformFilter); - } - - return hr; -} - -static HRESULT WINAPI TransformFilter_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IPersist)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IBaseFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &This->mediaSeeking; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow)) - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI TransformFilter_AddRef(IBaseFilter * iface) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); - - return refCount; -} - -static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); - - if (!refCount) - { - ULONG i; - - if (This->pClock) - IReferenceClock_Release(This->pClock); - - for (i = 0; i < This->npins; i++) - { - IPin *pConnectedTo; - - if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[i], &pConnectedTo))) - { - IPin_Disconnect(pConnectedTo); - IPin_Release(pConnectedTo); - } - IPin_Disconnect(This->ppPins[i]); - - IPin_Release(This->ppPins[i]); - } - - CoTaskMemFree(This->ppPins); - This->lpVtbl = NULL; - - This->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csFilter); - - TRACE("Destroying transform filter\n"); - FreeMediaType(&This->pmt); - CoTaskMemFree(This); - - return 0; - } - else - return refCount; -} - -/** IPersist methods **/ - -static HRESULT WINAPI TransformFilter_GetClassID(IBaseFilter * iface, CLSID * pClsid) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClsid); - - *pClsid = This->clsid; - - return S_OK; -} - -/** IMediaFilter methods **/ - -static HRESULT WINAPI TransformFilter_Stop(IBaseFilter * iface) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - HRESULT hr = S_OK; - - TRACE("(%p/%p)\n", This, iface); - - EnterCriticalSection(&This->csFilter); - { - This->state = State_Stopped; - if (This->pFuncsTable->pfnProcessEnd) - hr = This->pFuncsTable->pfnProcessEnd(This); - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI TransformFilter_Pause(IBaseFilter * iface) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - HRESULT hr; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(&This->csFilter); - { - if (This->state == State_Stopped) - hr = IBaseFilter_Run(iface, -1); - else - hr = S_OK; - - if (SUCCEEDED(hr)) - This->state = State_Paused; - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tStart) -{ - HRESULT hr = S_OK; - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); - - EnterCriticalSection(&This->csFilter); - { - if (This->state == State_Stopped) - { - ((InputPin *)This->ppPins[0])->end_of_stream = 0; - if (This->pFuncsTable->pfnProcessBegin) - hr = This->pFuncsTable->pfnProcessBegin(This); - if (SUCCEEDED(hr)) - hr = OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]); - } - - if (SUCCEEDED(hr)) - { - This->rtStreamStart = tStart; - This->state = State_Running; - } - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI TransformFilter_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState); - - EnterCriticalSection(&This->csFilter); - { - *pState = This->state; - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI TransformFilter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClock); - - EnterCriticalSection(&This->csFilter); - { - if (This->pClock) - IReferenceClock_Release(This->pClock); - This->pClock = pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI TransformFilter_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppClock); - - EnterCriticalSection(&This->csFilter); - { - *ppClock = This->pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -/** IBaseFilter implementation **/ - -static HRESULT TransformFilter_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - /* Our pins are static, not changing so setting static tick count is ok */ - *lastsynctick = 0; - - if (pos >= This->npins) - return S_FALSE; - - *pin = This->ppPins[pos]; - IPin_AddRef(*pin); - return S_OK; -} - -static HRESULT WINAPI TransformFilter_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return IEnumPinsImpl_Construct(ppEnum, TransformFilter_GetPin, iface); -} - -static HRESULT WINAPI TransformFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin); - - return E_NOTIMPL; -} - -static HRESULT WINAPI TransformFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); - - strcpyW(pInfo->achName, This->filterInfo.achName); - pInfo->pGraph = This->filterInfo.pGraph; - - if (pInfo->pGraph) - IFilterGraph_AddRef(pInfo->pGraph); - - return S_OK; -} - -static HRESULT WINAPI TransformFilter_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - HRESULT hr = S_OK; - TransformFilterImpl *This = (TransformFilterImpl *)iface; - - TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName)); - - EnterCriticalSection(&This->csFilter); - { - if (pName) - strcpyW(This->filterInfo.achName, pName); - else - *This->filterInfo.achName = '\0'; - This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI TransformFilter_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) -{ - TransformFilterImpl *This = (TransformFilterImpl *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo); - return E_NOTIMPL; -} - -static const IBaseFilterVtbl TransformFilter_Vtbl = -{ - TransformFilter_QueryInterface, - TransformFilter_AddRef, - TransformFilter_Release, - TransformFilter_GetClassID, - TransformFilter_Stop, - TransformFilter_Pause, - TransformFilter_Run, - TransformFilter_GetState, - TransformFilter_SetSyncSource, - TransformFilter_GetSyncSource, - TransformFilter_EnumPins, - TransformFilter_FindPin, - TransformFilter_QueryFilterInfo, - TransformFilter_JoinFilterGraph, - TransformFilter_QueryVendorInfo -}; - -static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface) -{ - InputPin* This = (InputPin*) iface; - TransformFilterImpl* pTransform; - IPin* ppin; - HRESULT hr; - - TRACE("(%p)->()\n", iface); - - /* Since we process samples synchronously, just forward notification downstream */ - pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter; - if (!pTransform) - hr = E_FAIL; - else - hr = IPin_ConnectedTo(pTransform->ppPins[1], &ppin); - if (SUCCEEDED(hr)) - { - hr = IPin_EndOfStream(ppin); - IPin_Release(ppin); - } - - if (FAILED(hr)) - ERR("%x\n", hr); - return hr; -} - -static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - InputPin* This = (InputPin*) iface; - TransformFilterImpl* pTransform; - HRESULT hr; - - TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt); - - pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter; - - hr = pTransform->pFuncsTable->pfnConnectInput(This, pmt); - if (SUCCEEDED(hr)) - { - hr = InputPin_ReceiveConnection(iface, pReceivePin, pmt); - if (FAILED(hr)) - pTransform->pFuncsTable->pfnCleanup(This); - } - - return hr; -} - -static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface) -{ - InputPin* This = (InputPin*) iface; - TransformFilterImpl* pTransform; - - TRACE("(%p)->()\n", iface); - - pTransform = (TransformFilterImpl*)This->pin.pinInfo.pFilter; - pTransform->pFuncsTable->pfnCleanup(This); - - return IPinImpl_Disconnect(iface); -} - -static const IPinVtbl TransformFilter_InputPin_Vtbl = -{ - InputPin_QueryInterface, - IPinImpl_AddRef, - InputPin_Release, - InputPin_Connect, - TransformFilter_InputPin_ReceiveConnection, - TransformFilter_InputPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - TransformFilter_InputPin_EndOfStream, - InputPin_BeginFlush, - InputPin_EndFlush, - InputPin_NewSegment -}; - -static HRESULT WINAPI TransformFilter_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum) -{ - IPinImpl *This = (IPinImpl *)iface; - TransformFilterImpl *pTransform = (TransformFilterImpl *)This->pinInfo.pFilter; - ENUMMEDIADETAILS emd; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - emd.cMediaTypes = 1; - emd.pMediaTypes = &pTransform->pmt; - - return IEnumMediaTypesImpl_Construct(&emd, ppEnum); -} - -static const IPinVtbl TransformFilter_OutputPin_Vtbl = -{ - OutputPin_QueryInterface, - IPinImpl_AddRef, - OutputPin_Release, - OutputPin_Connect, - OutputPin_ReceiveConnection, - OutputPin_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - TransformFilter_Output_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - OutputPin_EndOfStream, - OutputPin_BeginFlush, - OutputPin_EndFlush, - OutputPin_NewSegment -}; diff --git a/dll/directx/quartz/transform.h b/dll/directx/quartz/transform.h deleted file mode 100644 index f39ff47846b..00000000000 --- a/dll/directx/quartz/transform.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Transform Filter declarations - * - * Copyright 2005 Christian Costa - * - * 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 - */ - -#include "control_private.h" - -typedef struct TransformFilterImpl TransformFilterImpl; - -typedef struct TransformFuncsTable { - HRESULT (*pfnProcessBegin) (TransformFilterImpl *This); - HRESULT (*pfnProcessSampleData) (InputPin *pin, IMediaSample *pSample); - HRESULT (*pfnProcessEnd) (TransformFilterImpl *This); - HRESULT (*pfnQueryConnect) (TransformFilterImpl *This, const AM_MEDIA_TYPE * pmt); - HRESULT (*pfnConnectInput) (InputPin *pin, const AM_MEDIA_TYPE * pmt); - HRESULT (*pfnCleanup) (InputPin *pin); -} TransformFuncsTable; - -struct TransformFilterImpl -{ - const IBaseFilterVtbl * lpVtbl; - - LONG refCount; - CRITICAL_SECTION csFilter; - FILTER_STATE state; - REFERENCE_TIME rtStreamStart; - IReferenceClock * pClock; - FILTER_INFO filterInfo; - CLSID clsid; - struct MediaSeekingImpl mediaSeeking; - - IPin **ppPins; - ULONG npins; - AM_MEDIA_TYPE pmt; - - const TransformFuncsTable * pFuncsTable; -}; - -HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, const TransformFuncsTable* pFuncsTable, CHANGEPROC stop, CHANGEPROC current, CHANGEPROC rate); diff --git a/dll/directx/quartz/version.rc b/dll/directx/quartz/version.rc index 930039df3fc..a44475bc723 100644 --- a/dll/directx/quartz/version.rc +++ b/dll/directx/quartz/version.rc @@ -16,12 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define WINE_OLESELFREGISTER #define WINE_FILEDESCRIPTION_STR "Wine Quartz dll" #define WINE_FILENAME_STR "quartz.dll" #define WINE_FILEVERSION 6,5,1,902 #define WINE_FILEVERSION_STR "6.5.1.902" #define WINE_PRODUCTVERSION 6,5,1,902 #define WINE_PRODUCTVERSION_STR "6.5" +#define WINE_EXTRAVALUES VALUE "OLESelfRegister","" #include "wine/wine_common_ver.rc" + +1 TYPELIB control_tlb.tlb + +1 WINE_REGISTRY control_tlb.rgs +2 WINE_REGISTRY quartz_strmif.rgs diff --git a/dll/directx/quartz/videorenderer.c b/dll/directx/quartz/videorenderer.c index 17042a7e1e8..c29fbd30885 100644 --- a/dll/directx/quartz/videorenderer.c +++ b/dll/directx/quartz/videorenderer.c @@ -23,7 +23,6 @@ #define NONAMELESSSTRUCT #define NONAMELESSUNION #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "uuids.h" @@ -43,163 +42,58 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); -static BOOL wnd_class_registered = FALSE; - -static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; - -static const IBaseFilterVtbl VideoRenderer_Vtbl; -static const IUnknownVtbl IInner_VTable; -static const IBasicVideoVtbl IBasicVideo_VTable; -static const IVideoWindowVtbl IVideoWindow_VTable; -static const IPinVtbl VideoRenderer_InputPin_Vtbl; - typedef struct VideoRendererImpl { - const IBaseFilterVtbl * lpVtbl; - const IBasicVideoVtbl * IBasicVideo_vtbl; - const IVideoWindowVtbl * IVideoWindow_vtbl; - const IUnknownVtbl * IInner_vtbl; + BaseRenderer renderer; + BaseControlWindow baseControlWindow; + BaseControlVideo baseControlVideo; - LONG refCount; - CRITICAL_SECTION csFilter; - FILTER_STATE state; - REFERENCE_TIME rtStreamStart; - IReferenceClock * pClock; - FILTER_INFO filterInfo; - - InputPin *pInputPin; + IUnknown IUnknown_inner; + IAMFilterMiscFlags IAMFilterMiscFlags_iface; + IUnknown *outer_unk; BOOL init; HANDLE hThread; - HANDLE blocked; DWORD ThreadID; HANDLE hEvent; +/* hEvent == evComplete? */ BOOL ThreadResult; - HWND hWnd; - HWND hWndMsgDrain; - BOOL AutoShow; RECT SourceRect; RECT DestRect; RECT WindowPos; LONG VideoWidth; LONG VideoHeight; - IUnknown * pUnkOuter; - BOOL bUnkOuterValid; - BOOL bAggregatable; - REFERENCE_TIME rtLastStop; - MediaSeekingImpl mediaSeeking; - - /* During pause we can hold a single sample, for use in GetCurrentImage */ - IMediaSample *sample_held; } VideoRendererImpl; -static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +static inline VideoRendererImpl *impl_from_BaseWindow(BaseWindow *iface) { - VideoRendererImpl* pVideoRenderer = (VideoRendererImpl*)GetWindowLongPtrW(hwnd, 0); - LPRECT lprect = (LPRECT)lParam; - - if (pVideoRenderer && pVideoRenderer->hWndMsgDrain) - { - switch(uMsg) - { - case WM_KEYDOWN: - case WM_KEYUP: - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MOUSEACTIVATE: - case WM_MOUSEMOVE: - case WM_NCLBUTTONDBLCLK: - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONUP: - case WM_NCMBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONUP: - case WM_NCMOUSEMOVE: - case WM_NCRBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - PostMessageA(pVideoRenderer->hWndMsgDrain, uMsg, wParam, lParam); - break; - default: - break; - } - } - - switch(uMsg) - { - case WM_SIZING: - /* TRACE("WM_SIZING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); */ - SetWindowPos(hwnd, NULL, lprect->left, lprect->top, lprect->right - lprect->left, lprect->bottom - lprect->top, SWP_NOZORDER); - GetClientRect(hwnd, &pVideoRenderer->DestRect); - TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", - pVideoRenderer->DestRect.left, - pVideoRenderer->DestRect.top, - pVideoRenderer->DestRect.right - pVideoRenderer->DestRect.left, - pVideoRenderer->DestRect.bottom - pVideoRenderer->DestRect.top); - return TRUE; - case WM_SIZE: - TRACE("WM_SIZE %d %d\n", LOWORD(lParam), HIWORD(lParam)); - GetClientRect(hwnd, &pVideoRenderer->DestRect); - TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", - pVideoRenderer->DestRect.left, - pVideoRenderer->DestRect.top, - pVideoRenderer->DestRect.right - pVideoRenderer->DestRect.left, - pVideoRenderer->DestRect.bottom - pVideoRenderer->DestRect.top); - return TRUE; - default: - return DefWindowProcA(hwnd, uMsg, wParam, lParam); - } - return 0; + return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlWindow.baseWindow); } -static BOOL CreateRenderingWindow(VideoRendererImpl* This) +static inline VideoRendererImpl *impl_from_BaseRenderer(BaseRenderer *iface) { - WNDCLASSA winclass; + return CONTAINING_RECORD(iface, VideoRendererImpl, renderer); +} - TRACE("(%p)->()\n", This); - - winclass.style = 0; - winclass.lpfnWndProc = VideoWndProcA; - winclass.cbClsExtra = 0; - winclass.cbWndExtra = sizeof(VideoRendererImpl*); - winclass.hInstance = NULL; - winclass.hIcon = NULL; - winclass.hCursor = NULL; - winclass.hbrBackground = GetStockObject(BLACK_BRUSH); - winclass.lpszMenuName = NULL; - winclass.lpszClassName = "Wine ActiveMovie Class"; +static inline VideoRendererImpl *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, renderer.filter.IBaseFilter_iface); +} - if (!wnd_class_registered) - { - if (!RegisterClassA(&winclass)) - { - ERR("Unable to register window %u\n", GetLastError()); - return FALSE; - } - wnd_class_registered = TRUE; - } +static inline VideoRendererImpl *impl_from_IVideoWindow(IVideoWindow *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlWindow.IVideoWindow_iface); +} - This->hWnd = CreateWindowExA(0, "Wine ActiveMovie Class", "Wine ActiveMovie Window", WS_SIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, - NULL, NULL, NULL); +static inline VideoRendererImpl *impl_from_BaseControlVideo(BaseControlVideo *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlVideo); +} - if (!This->hWnd) - { - ERR("Unable to create window\n"); - return FALSE; - } - - SetWindowLongPtrW(This->hWnd, 0, (LONG_PTR)This); - - return TRUE; +static inline VideoRendererImpl *impl_from_IBasicVideo(IBasicVideo *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, baseControlVideo.IBasicVideo_iface); } static DWORD WINAPI MessageLoop(LPVOID lpParameter) @@ -210,7 +104,7 @@ static DWORD WINAPI MessageLoop(LPVOID lpParameter) TRACE("Starting message loop\n"); - if (!CreateRenderingWindow(This)) + if (FAILED(BaseWindowImpl_PrepareWindow(&This->baseControlWindow.baseWindow))) { This->ThreadResult = FALSE; SetEvent(This->hEvent); @@ -220,10 +114,10 @@ static DWORD WINAPI MessageLoop(LPVOID lpParameter) This->ThreadResult = TRUE; SetEvent(This->hEvent); - while ((fGotMessage = GetMessageA(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1) + while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1) { TranslateMessage(&msg); - DispatchMessageA(&msg); + DispatchMessageW(&msg); } TRACE("End of message loop\n"); @@ -256,18 +150,68 @@ static BOOL CreateRenderingSubsystem(VideoRendererImpl* This) return TRUE; } +static void VideoRenderer_AutoShowWindow(VideoRendererImpl *This) +{ + if (!This->init && (!This->WindowPos.right || !This->WindowPos.top)) + { + DWORD style = GetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE); + DWORD style_ex = GetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_EXSTYLE); + + if (!This->WindowPos.right) + { + if (This->DestRect.right) + { + This->WindowPos.left = This->DestRect.left; + This->WindowPos.right = This->DestRect.right; + } + else + { + This->WindowPos.left = This->SourceRect.left; + This->WindowPos.right = This->SourceRect.right; + } + } + if (!This->WindowPos.bottom) + { + if (This->DestRect.bottom) + { + This->WindowPos.top = This->DestRect.top; + This->WindowPos.bottom = This->DestRect.bottom; + } + else + { + This->WindowPos.top = This->SourceRect.top; + This->WindowPos.bottom = This->SourceRect.bottom; + } + } + + AdjustWindowRectEx(&This->WindowPos, style, FALSE, style_ex); + + TRACE("WindowPos: %d %d %d %d\n", This->WindowPos.left, This->WindowPos.top, This->WindowPos.right, This->WindowPos.bottom); + SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, + This->WindowPos.left, + This->WindowPos.top, + This->WindowPos.right - This->WindowPos.left, + This->WindowPos.bottom - This->WindowPos.top, + SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE); + + GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->DestRect); + } + else if (!This->init) + This->DestRect = This->WindowPos; + This->init = TRUE; + if (This->baseControlWindow.AutoShow) + ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW); +} + static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size) { AM_MEDIA_TYPE amt; HRESULT hr = S_OK; - DDSURFACEDESC sdesc; - HDC hDC; BITMAPINFOHEADER *bmiHeader; TRACE("(%p)->(%p, %d)\n", This, data, size); - sdesc.dwSize = sizeof(sdesc); - hr = IPin_ConnectionMediaType((IPin *)This->pInputPin, &amt); + hr = IPin_ConnectionMediaType(&This->renderer.pInputPin->pin.IPin_iface, &amt); if (FAILED(hr)) { ERR("Unable to retrieve media type\n"); return hr; @@ -295,31 +239,7 @@ static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4)); TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage); - if (!This->init) - { - DWORD style = GetWindowLongW(This->hWnd, GWL_STYLE); - DWORD style_ex = GetWindowLongW(This->hWnd, GWL_EXSTYLE); - - if (!This->WindowPos.right || !This->WindowPos.bottom) - This->WindowPos = This->SourceRect; - - AdjustWindowRectEx(&This->WindowPos, style, TRUE, style_ex); - - TRACE("WindowPos: %d %d %d %d\n", This->WindowPos.left, This->WindowPos.top, This->WindowPos.right, This->WindowPos.bottom); - SetWindowPos(This->hWnd, NULL, - This->WindowPos.left, - This->WindowPos.top, - This->WindowPos.right - This->WindowPos.left, - This->WindowPos.bottom - This->WindowPos.top, - SWP_NOZORDER|SWP_NOMOVE); - - GetClientRect(This->hWnd, &This->DestRect); - This->init = TRUE; - } - - hDC = GetDC(This->hWnd); - - if (!hDC) { + if (!This->baseControlWindow.baseWindow.hDC) { ERR("Cannot get DC from window!\n"); return E_FAIL; } @@ -327,69 +247,35 @@ static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, TRACE("Src Rect: %d %d %d %d\n", This->SourceRect.left, This->SourceRect.top, This->SourceRect.right, This->SourceRect.bottom); TRACE("Dst Rect: %d %d %d %d\n", This->DestRect.left, This->DestRect.top, This->DestRect.right, This->DestRect.bottom); - StretchDIBits(hDC, This->DestRect.left, This->DestRect.top, This->DestRect.right -This->DestRect.left, + StretchDIBits(This->baseControlWindow.baseWindow.hDC, This->DestRect.left, This->DestRect.top, This->DestRect.right -This->DestRect.left, This->DestRect.bottom - This->DestRect.top, This->SourceRect.left, This->SourceRect.top, This->SourceRect.right - This->SourceRect.left, This->SourceRect.bottom - This->SourceRect.top, data, (BITMAPINFO *)bmiHeader, DIB_RGB_COLORS, SRCCOPY); - ReleaseDC(This->hWnd, hDC); - if (This->AutoShow) - ShowWindow(This->hWnd, SW_SHOW); - return S_OK; } -static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) +static HRESULT WINAPI VideoRenderer_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime) { - VideoRendererImpl *This = iface; - LPBYTE pbSrcStream = NULL; - LONG cbSrcStream = 0; - REFERENCE_TIME tStart, tStop; - HRESULT hr; - - TRACE("(%p)->(%p)\n", iface, pSample); - - EnterCriticalSection(&This->csFilter); - - if (This->pInputPin->flushing || This->pInputPin->end_of_stream) - { - LeaveCriticalSection(&This->csFilter); - return S_FALSE; - } - - if (This->state == State_Stopped) - { - LeaveCriticalSection(&This->csFilter); - return VFW_E_WRONG_STATE; - } - - hr = IMediaSample_GetTime(pSample, &tStart, &tStop); - if (FAILED(hr)) - ERR("Cannot get sample time (%x)\n", hr); - - if (This->rtLastStop != tStart) - { - if (IMediaSample_IsDiscontinuity(pSample) == S_FALSE) - ERR("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n", - (DWORD)(This->rtLastStop / 10000000), - (DWORD)((This->rtLastStop / 10000)%1000), - (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000)); - This->rtLastStop = tStart; - } - /* Preroll means the sample isn't shown, this is used for key frames and things like that */ if (IMediaSample_IsPreroll(pSample) == S_OK) - { - This->rtLastStop = tStop; - LeaveCriticalSection(&This->csFilter); - return S_OK; - } + return E_FAIL; + return S_FALSE; +} + +static HRESULT WINAPI VideoRenderer_DoRenderSample(BaseRenderer* iface, IMediaSample * pSample) +{ + VideoRendererImpl *This = impl_from_BaseRenderer(iface); + LPBYTE pbSrcStream = NULL; + LONG cbSrcStream = 0; + HRESULT hr; + + TRACE("(%p)->(%p)\n", This, pSample); hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); - LeaveCriticalSection(&This->csFilter); return hr; } @@ -411,68 +297,29 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample) #endif SetEvent(This->hEvent); - if (This->state == State_Paused) + if (This->renderer.filter.state == State_Paused) { - This->sample_held = pSample; - LeaveCriticalSection(&This->csFilter); - WaitForSingleObject(This->blocked, INFINITE); - EnterCriticalSection(&This->csFilter); - This->sample_held = NULL; - if (This->state == State_Paused) + VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); + SetEvent(This->hEvent); + if (This->renderer.filter.state == State_Paused) { /* Flushing */ - LeaveCriticalSection(&This->csFilter); return S_OK; } - if (This->state == State_Stopped) + if (This->renderer.filter.state == State_Stopped) { - LeaveCriticalSection(&This->csFilter); return VFW_E_WRONG_STATE; } + } else { + VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); } - - if (This->pClock && This->state == State_Running) - { - REFERENCE_TIME time, trefstart, trefstop; - LONG delta; - - /* Perhaps I use the reference clock AdviseTime function here - * I'm not going to! When I tried, it seemed to generate lag and - * it caused instability. - */ - IReferenceClock_GetTime(This->pClock, &time); - - trefstart = This->rtStreamStart; - trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->dRate) + This->rtStreamStart; - delta = (LONG)((trefstart-time)/10000); - This->rtStreamStart = trefstop; - This->rtLastStop = tStop; - - if (delta > 0) - { - TRACE("Sleeping for %u ms\n", delta); - Sleep(delta); - } - else if (time > trefstop) - { - TRACE("Dropping sample: Time: %u.%03u ms trefstop: %u.%03u ms!\n", - (DWORD)(time / 10000000), (DWORD)((time / 10000)%1000), - (DWORD)(trefstop / 10000000), (DWORD)((trefstop / 10000)%1000) ); - This->rtLastStop = tStop; - LeaveCriticalSection(&This->csFilter); - return S_OK; - } - } - This->rtLastStop = tStop; - - VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream); - - LeaveCriticalSection(&This->csFilter); return S_OK; } -static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) +static HRESULT WINAPI VideoRenderer_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) { + VideoRendererImpl *This = impl_from_BaseRenderer(iface); + if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) return S_FALSE; @@ -481,7 +328,6 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565) || IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)) { - VideoRendererImpl* This = iface; LONG height; if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) @@ -519,165 +365,322 @@ static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt return S_FALSE; } -static inline VideoRendererImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) +static HRESULT WINAPI VideoRenderer_EndFlush(BaseRenderer* iface) { - return (VideoRendererImpl *)((char*)iface - FIELD_OFFSET(VideoRendererImpl, mediaSeeking.lpVtbl)); + VideoRendererImpl *This = impl_from_BaseRenderer(iface); + + TRACE("(%p)->()\n", iface); + + if (This->renderer.pMediaSample) { + ResetEvent(This->hEvent); + LeaveCriticalSection(iface->pInputPin->pin.pCritSec); + LeaveCriticalSection(&iface->csRenderLock); + LeaveCriticalSection(&iface->filter.csFilter); + WaitForSingleObject(This->hEvent, INFINITE); + EnterCriticalSection(&iface->filter.csFilter); + EnterCriticalSection(&iface->csRenderLock); + EnterCriticalSection(iface->pInputPin->pin.pCritSec); + } + if (This->renderer.filter.state == State_Paused) { + ResetEvent(This->hEvent); + } + + return BaseRendererImpl_EndFlush(iface); } -static HRESULT WINAPI VideoRendererImpl_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) +static VOID WINAPI VideoRenderer_OnStopStreaming(BaseRenderer* iface) { - VideoRendererImpl *This = impl_from_IMediaSeeking(iface); + VideoRendererImpl *This = impl_from_BaseRenderer(iface); - return IUnknown_QueryInterface((IUnknown *)This, riid, ppv); + TRACE("(%p)->()\n", This); + + SetEvent(This->hEvent); + if (This->baseControlWindow.AutoShow) + /* Black it out */ + RedrawWindow(This->baseControlWindow.baseWindow.hWnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE); } -static ULONG WINAPI VideoRendererImpl_Seeking_AddRef(IMediaSeeking * iface) +static VOID WINAPI VideoRenderer_OnStartStreaming(BaseRenderer* iface) { - VideoRendererImpl *This = impl_from_IMediaSeeking(iface); + VideoRendererImpl *This = impl_from_BaseRenderer(iface); - return IUnknown_AddRef((IUnknown *)This); + TRACE("(%p)\n", This); + + if (This->renderer.pInputPin->pin.pConnectedTo && (This->renderer.filter.state == State_Stopped || !This->renderer.pInputPin->end_of_stream)) + { + if (This->renderer.filter.state == State_Stopped) + { + ResetEvent(This->hEvent); + VideoRenderer_AutoShowWindow(This); + } + } } -static ULONG WINAPI VideoRendererImpl_Seeking_Release(IMediaSeeking * iface) +static LPWSTR WINAPI VideoRenderer_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx) { - VideoRendererImpl *This = impl_from_IMediaSeeking(iface); + static const WCHAR classnameW[] = { 'W','i','n','e',' ','A','c','t','i','v','e','M','o','v','i','e',' ','C','l','a','s','s',0 }; - return IUnknown_Release((IUnknown *)This); + *pClassStyles = 0; + *pWindowStyles = WS_SIZEBOX; + *pWindowStylesEx = 0; + + return (LPWSTR)classnameW; } -static const IMediaSeekingVtbl VideoRendererImpl_Seeking_Vtbl = +static RECT WINAPI VideoRenderer_GetDefaultRect(BaseWindow *iface) { - VideoRendererImpl_Seeking_QueryInterface, - VideoRendererImpl_Seeking_AddRef, - VideoRendererImpl_Seeking_Release, - MediaSeekingImpl_GetCapabilities, - MediaSeekingImpl_CheckCapabilities, - MediaSeekingImpl_IsFormatSupported, - MediaSeekingImpl_QueryPreferredFormat, - MediaSeekingImpl_GetTimeFormat, - MediaSeekingImpl_IsUsingTimeFormat, - MediaSeekingImpl_SetTimeFormat, - MediaSeekingImpl_GetDuration, - MediaSeekingImpl_GetStopPosition, - MediaSeekingImpl_GetCurrentPosition, - MediaSeekingImpl_ConvertTimeFormat, - MediaSeekingImpl_SetPositions, - MediaSeekingImpl_GetPositions, - MediaSeekingImpl_GetAvailable, - MediaSeekingImpl_SetRate, - MediaSeekingImpl_GetRate, - MediaSeekingImpl_GetPreroll + VideoRendererImpl *This = impl_from_BaseWindow(iface); + static RECT defRect; + + defRect.left = defRect.top = 0; + defRect.right = This->VideoWidth; + defRect.bottom = This->VideoHeight; + + return defRect; +} + +static BOOL WINAPI VideoRenderer_OnSize(BaseWindow *iface, LONG Width, LONG Height) +{ + VideoRendererImpl *This = impl_from_BaseWindow(iface); + + TRACE("WM_SIZE %d %d\n", Width, Height); + GetClientRect(iface->hWnd, &This->DestRect); + TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", + This->DestRect.left, + This->DestRect.top, + This->DestRect.right - This->DestRect.left, + This->DestRect.bottom - This->DestRect.top); + return BaseWindowImpl_OnSize(iface, Width, Height); +} + +static const BaseRendererFuncTable BaseFuncTable = { + VideoRenderer_CheckMediaType, + VideoRenderer_DoRenderSample, + /**/ + NULL, + NULL, + NULL, + VideoRenderer_OnStartStreaming, + VideoRenderer_OnStopStreaming, + NULL, + NULL, + NULL, + VideoRenderer_ShouldDrawSampleNow, + NULL, + /**/ + NULL, + NULL, + NULL, + NULL, + VideoRenderer_EndFlush, }; -static HRESULT VideoRendererImpl_Change(IBaseFilter *iface) +static const BaseWindowFuncTable renderer_BaseWindowFuncTable = { + VideoRenderer_GetClassWindowStyles, + VideoRenderer_GetDefaultRect, + NULL, + BaseControlWindowImpl_PossiblyEatMessage, + VideoRenderer_OnSize +}; + +static HRESULT WINAPI VideoRenderer_GetSourceRect(BaseControlVideo* iface, RECT *pSourceRect) { - TRACE("(%p)->()\n", iface); + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + CopyRect(pSourceRect,&This->SourceRect); return S_OK; } -HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) +static HRESULT WINAPI VideoRenderer_GetStaticImage(BaseControlVideo* iface, LONG *pBufferSize, LONG *pDIBImage) { - HRESULT hr; - PIN_INFO piInput; - VideoRendererImpl * pVideoRenderer; + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + BITMAPINFOHEADER *bmiHeader; + LONG needed_size; + AM_MEDIA_TYPE *amt = &This->renderer.pInputPin->pin.mtCurrent; + char *ptr; - TRACE("(%p, %p)\n", pUnkOuter, ppv); + FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage); - *ppv = NULL; + EnterCriticalSection(&This->renderer.filter.csFilter); - pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl)); - pVideoRenderer->pUnkOuter = pUnkOuter; - pVideoRenderer->bUnkOuterValid = FALSE; - pVideoRenderer->bAggregatable = FALSE; - pVideoRenderer->IInner_vtbl = &IInner_VTable; - - pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl; - pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable; - pVideoRenderer->IVideoWindow_vtbl = &IVideoWindow_VTable; - - pVideoRenderer->refCount = 1; - InitializeCriticalSection(&pVideoRenderer->csFilter); - pVideoRenderer->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"); - pVideoRenderer->state = State_Stopped; - pVideoRenderer->pClock = NULL; - pVideoRenderer->init = 0; - pVideoRenderer->AutoShow = 1; - pVideoRenderer->rtLastStop = -1; - ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO)); - ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT)); - ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT)); - ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT)); - pVideoRenderer->hWndMsgDrain = NULL; - - /* construct input pin */ - piInput.dir = PINDIR_INPUT; - piInput.pFilter = (IBaseFilter *)pVideoRenderer; - lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); - - hr = InputPin_Construct(&VideoRenderer_InputPin_Vtbl, &piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, NULL, &pVideoRenderer->csFilter, NULL, (IPin **)&pVideoRenderer->pInputPin); - - if (SUCCEEDED(hr)) + if (!This->renderer.pMediaSample) { - MediaSeekingImpl_Init((IBaseFilter*)pVideoRenderer, VideoRendererImpl_Change, VideoRendererImpl_Change, VideoRendererImpl_Change, &pVideoRenderer->mediaSeeking, &pVideoRenderer->csFilter); - pVideoRenderer->mediaSeeking.lpVtbl = &VideoRendererImpl_Seeking_Vtbl; + LeaveCriticalSection(&This->renderer.filter.csFilter); + return (This->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED); + } - pVideoRenderer->sample_held = NULL; - *ppv = pVideoRenderer; + if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) + { + bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; + } + else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) + { + bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; } else { - pVideoRenderer->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&pVideoRenderer->csFilter); - CoTaskMemFree(pVideoRenderer); + FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); + LeaveCriticalSection(&This->renderer.filter.csFilter); + return VFW_E_RUNTIME_ERROR; } - if (!CreateRenderingSubsystem(pVideoRenderer)) + needed_size = bmiHeader->biSize; + needed_size += IMediaSample_GetActualDataLength(This->renderer.pMediaSample); + + if (!pDIBImage) + { + *pBufferSize = needed_size; + LeaveCriticalSection(&This->renderer.filter.csFilter); + return S_OK; + } + + if (needed_size < *pBufferSize) + { + ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize); + LeaveCriticalSection(&This->renderer.filter.csFilter); + return E_FAIL; + } + *pBufferSize = needed_size; + + memcpy(pDIBImage, bmiHeader, bmiHeader->biSize); + IMediaSample_GetPointer(This->renderer.pMediaSample, (BYTE **)&ptr); + memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->renderer.pMediaSample)); + + LeaveCriticalSection(&This->renderer.filter.csFilter); + return S_OK; +} + +static HRESULT WINAPI VideoRenderer_GetTargetRect(BaseControlVideo* iface, RECT *pTargetRect) +{ + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + CopyRect(pTargetRect,&This->DestRect); + return S_OK; +} + +static VIDEOINFOHEADER* WINAPI VideoRenderer_GetVideoFormat(BaseControlVideo* iface) +{ + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + AM_MEDIA_TYPE *pmt; + + TRACE("(%p/%p)\n", This, iface); + + pmt = &This->renderer.pInputPin->pin.mtCurrent; + if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { + return (VIDEOINFOHEADER*)pmt->pbFormat; + } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { + static VIDEOINFOHEADER vih; + VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat; + memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER)); + memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER)); + return &vih; + } else { + ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); + return NULL; + } +} + +static HRESULT WINAPI VideoRenderer_IsDefaultSourceRect(BaseControlVideo* iface) +{ + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + FIXME("(%p/%p)->(): stub !!!\n", This, iface); + + return S_OK; +} + +static HRESULT WINAPI VideoRenderer_IsDefaultTargetRect(BaseControlVideo* iface) +{ + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + FIXME("(%p/%p)->(): stub !!!\n", This, iface); + + return S_OK; +} + +static HRESULT WINAPI VideoRenderer_SetDefaultSourceRect(BaseControlVideo* iface) +{ + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + + This->SourceRect.left = 0; + This->SourceRect.top = 0; + This->SourceRect.right = This->VideoWidth; + This->SourceRect.bottom = This->VideoHeight; + + return S_OK; +} + +static HRESULT WINAPI VideoRenderer_SetDefaultTargetRect(BaseControlVideo* iface) +{ + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + RECT rect; + + if (!GetClientRect(This->baseControlWindow.baseWindow.hWnd, &rect)) return E_FAIL; - pVideoRenderer->blocked = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!pVideoRenderer->blocked) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - IUnknown_Release((IUnknown *)pVideoRenderer); - } + This->DestRect.left = 0; + This->DestRect.top = 0; + This->DestRect.right = rect.right; + This->DestRect.bottom = rect.bottom; - return hr; + return S_OK; } -HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv) +static HRESULT WINAPI VideoRenderer_SetSourceRect(BaseControlVideo* iface, RECT *pSourceRect) { - /* TODO: Attempt to use the VMR-7 renderer instead when possible */ - return VideoRenderer_create(pUnkOuter, ppv); + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + CopyRect(&This->SourceRect,pSourceRect); + return S_OK; } -static HRESULT WINAPI VideoRendererInner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) +static HRESULT WINAPI VideoRenderer_SetTargetRect(BaseControlVideo* iface, RECT *pTargetRect) { - ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); + VideoRendererImpl *This = impl_from_BaseControlVideo(iface); + CopyRect(&This->DestRect,pTargetRect); + return S_OK; +} + +static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = { + VideoRenderer_GetSourceRect, + VideoRenderer_GetStaticImage, + VideoRenderer_GetTargetRect, + VideoRenderer_GetVideoFormat, + VideoRenderer_IsDefaultSourceRect, + VideoRenderer_IsDefaultTargetRect, + VideoRenderer_SetDefaultSourceRect, + VideoRenderer_SetDefaultTargetRect, + VideoRenderer_SetSourceRect, + VideoRenderer_SetTargetRect +}; + +static inline VideoRendererImpl *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, IUnknown_inner); +} + +static HRESULT WINAPI VideoRendererInner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + VideoRendererImpl *This = impl_from_IUnknown(iface); + TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - *ppv = NULL; if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = &This->IInner_vtbl; - else if (IsEqualIID(riid, &IID_IPersist)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IMediaFilter)) - *ppv = This; - else if (IsEqualIID(riid, &IID_IBaseFilter)) - *ppv = This; + *ppv = &This->IUnknown_inner; else if (IsEqualIID(riid, &IID_IBasicVideo)) - *ppv = &This->IBasicVideo_vtbl; + *ppv = &This->baseControlVideo.IBasicVideo_iface; else if (IsEqualIID(riid, &IID_IVideoWindow)) - *ppv = &This->IVideoWindow_vtbl; - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &This->mediaSeeking; + *ppv = &This->baseControlWindow.IVideoWindow_iface; + else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) + *ppv = &This->IAMFilterMiscFlags_iface; + else + { + HRESULT hr; + hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); + if (SUCCEEDED(hr)) + return hr; + } if (*ppv) { - IUnknown_AddRef((IUnknown *)(*ppv)); + IUnknown_AddRef((IUnknown *)*ppv); return S_OK; } @@ -687,53 +690,35 @@ static HRESULT WINAPI VideoRendererInner_QueryInterface(IUnknown * iface, REFIID return E_NOINTERFACE; } -static ULONG WINAPI VideoRendererInner_AddRef(IUnknown * iface) +static ULONG WINAPI VideoRendererInner_AddRef(IUnknown *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); - ULONG refCount = InterlockedIncrement(&This->refCount); + VideoRendererImpl *This = impl_from_IUnknown(iface); + ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); - TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); + TRACE("(%p)->(): new ref = %d\n", This, refCount); return refCount; } -static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface) +static ULONG WINAPI VideoRendererInner_Release(IUnknown *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); - ULONG refCount = InterlockedDecrement(&This->refCount); + VideoRendererImpl *This = impl_from_IUnknown(iface); + ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface); - TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); + TRACE("(%p)->(): new ref = %d\n", This, refCount); if (!refCount) { - IPin *pConnectedTo; - - DestroyWindow(This->hWnd); - PostThreadMessageA(This->ThreadID, WM_QUIT, 0, 0); + BaseControlWindow_Destroy(&This->baseControlWindow); + BaseControlVideo_Destroy(&This->baseControlVideo); + PostThreadMessageW(This->ThreadID, WM_QUIT, 0, 0); WaitForSingleObject(This->hThread, INFINITE); CloseHandle(This->hThread); CloseHandle(This->hEvent); - if (This->pClock) - IReferenceClock_Release(This->pClock); - - if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo))) - { - IPin_Disconnect(pConnectedTo); - IPin_Release(pConnectedTo); - } - IPin_Disconnect((IPin *)This->pInputPin); - - IPin_Release((IPin *)This->pInputPin); - - This->lpVtbl = NULL; - - This->csFilter.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->csFilter); - TRACE("Destroying Video Renderer\n"); CoTaskMemFree(This); - + return 0; } else @@ -749,1521 +734,348 @@ static const IUnknownVtbl IInner_VTable = static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (This->pUnkOuter) - { - if (This->bAggregatable) - return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - { - HRESULT hr; - - IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); - hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); - IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); - This->bAggregatable = TRUE; - return hr; - } - - *ppv = NULL; - return E_NOINTERFACE; - } - - return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); + VideoRendererImpl *This = impl_from_IBaseFilter(iface); + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); } static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_AddRef(This->pUnkOuter); - return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); + VideoRendererImpl *This = impl_from_IBaseFilter(iface); + return IUnknown_AddRef(This->outer_unk); } static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - if (This->pUnkOuter && This->bUnkOuterValid) - return IUnknown_Release(This->pUnkOuter); - return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); -} - -/** IPersist methods **/ - -static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClsid); - - *pClsid = CLSID_VideoRenderer; - - return S_OK; + VideoRendererImpl *This = impl_from_IBaseFilter(iface); + return IUnknown_Release(This->outer_unk); } /** IMediaFilter methods **/ -static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(&This->csFilter); - { - This->state = State_Stopped; - SetEvent(This->hEvent); - SetEvent(This->blocked); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; - + VideoRendererImpl *This = impl_from_IBaseFilter(iface); + TRACE("(%p/%p)->()\n", This, iface); - EnterCriticalSection(&This->csFilter); - if (This->state != State_Paused) + EnterCriticalSection(&This->renderer.csRenderLock); + if (This->renderer.filter.state != State_Paused) { - if (This->state == State_Stopped) + if (This->renderer.filter.state == State_Stopped) { - This->pInputPin->end_of_stream = 0; + This->renderer.pInputPin->end_of_stream = 0; ResetEvent(This->hEvent); + VideoRenderer_AutoShowWindow(This); } - This->state = State_Paused; - ResetEvent(This->blocked); + ResetEvent(This->renderer.RenderEvent); + This->renderer.filter.state = State_Paused; } - LeaveCriticalSection(&This->csFilter); + LeaveCriticalSection(&This->renderer.csRenderLock); return S_OK; } -static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); - - EnterCriticalSection(&This->csFilter); - if (This->state != State_Running) - { - if (This->state == State_Stopped) - { - This->pInputPin->end_of_stream = 0; - ResetEvent(This->hEvent); - } - SetEvent(This->blocked); - - This->rtStreamStart = tStart; - This->state = State_Running; - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - HRESULT hr; - - TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState); - - if (WaitForSingleObject(This->hEvent, dwMilliSecsTimeout) == WAIT_TIMEOUT) - hr = VFW_S_STATE_INTERMEDIATE; - else - hr = S_OK; - - EnterCriticalSection(&This->csFilter); - { - *pState = This->state; - } - LeaveCriticalSection(&This->csFilter); - - return hr; -} - -static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pClock); - - EnterCriticalSection(&This->csFilter); - { - if (This->pClock) - IReferenceClock_Release(This->pClock); - This->pClock = pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI VideoRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppClock); - - EnterCriticalSection(&This->csFilter); - { - *ppClock = This->pClock; - if (This->pClock) - IReferenceClock_AddRef(This->pClock); - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -/** IBaseFilter implementation **/ - -static HRESULT VideoRenderer_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - /* Our pins are static, not changing so setting static tick count is ok */ - *lastsynctick = 0; - - if (pos >= 1) - return S_FALSE; - - *pin = (IPin *)This->pInputPin; - IPin_AddRef(*pin); - return S_OK; -} - -static HRESULT WINAPI VideoRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return IEnumPinsImpl_Construct(ppEnum, VideoRenderer_GetPin, iface); -} - -static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - FIXME("(%p/%p)->(%p,%p): stub !!!\n", This, iface, debugstr_w(Id), ppPin); - - /* FIXME: critical section */ - - return E_NOTIMPL; -} - -static HRESULT WINAPI VideoRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); - - strcpyW(pInfo->achName, This->filterInfo.achName); - pInfo->pGraph = This->filterInfo.pGraph; - - if (pInfo->pGraph) - IFilterGraph_AddRef(pInfo->pGraph); - - return S_OK; -} - -static HRESULT WINAPI VideoRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - - TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName)); - - EnterCriticalSection(&This->csFilter); - { - if (pName) - strcpyW(This->filterInfo.achName, pName); - else - *This->filterInfo.achName = '\0'; - This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ - } - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI VideoRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) -{ - VideoRendererImpl *This = (VideoRendererImpl *)iface; - TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo); - return E_NOTIMPL; -} - static const IBaseFilterVtbl VideoRenderer_Vtbl = { VideoRenderer_QueryInterface, VideoRenderer_AddRef, VideoRenderer_Release, - VideoRenderer_GetClassID, - VideoRenderer_Stop, + BaseFilterImpl_GetClassID, + BaseRendererImpl_Stop, VideoRenderer_Pause, - VideoRenderer_Run, - VideoRenderer_GetState, - VideoRenderer_SetSyncSource, - VideoRenderer_GetSyncSource, - VideoRenderer_EnumPins, - VideoRenderer_FindPin, - VideoRenderer_QueryFilterInfo, - VideoRenderer_JoinFilterGraph, - VideoRenderer_QueryVendorInfo -}; - -static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface) -{ - InputPin* This = (InputPin*)iface; - IMediaEventSink* pEventSink; - HRESULT hr; - - TRACE("(%p/%p)->()\n", This, iface); - - hr = IFilterGraph_QueryInterface(((VideoRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); - if (SUCCEEDED(hr)) - { - hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0); - IMediaEventSink_Release(pEventSink); - } - - return hr; -} - -static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface) -{ - InputPin* This = (InputPin*)iface; - VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter; - HRESULT hr; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(This->pin.pCritSec); - if (pVideoRenderer->state == State_Paused) - SetEvent(pVideoRenderer->blocked); - - hr = InputPin_BeginFlush(iface); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface) -{ - InputPin* This = (InputPin*)iface; - VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter; - HRESULT hr; - - TRACE("(%p/%p)->()\n", This, iface); - - EnterCriticalSection(This->pin.pCritSec); - if (pVideoRenderer->state == State_Paused) - ResetEvent(pVideoRenderer->blocked); - - hr = InputPin_EndFlush(iface); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static const IPinVtbl VideoRenderer_InputPin_Vtbl = -{ - InputPin_QueryInterface, - IPinImpl_AddRef, - InputPin_Release, - InputPin_Connect, - InputPin_ReceiveConnection, - IPinImpl_Disconnect, - IPinImpl_ConnectedTo, - IPinImpl_ConnectionMediaType, - IPinImpl_QueryPinInfo, - IPinImpl_QueryDirection, - IPinImpl_QueryId, - IPinImpl_QueryAccept, - IPinImpl_EnumMediaTypes, - IPinImpl_QueryInternalConnections, - VideoRenderer_InputPin_EndOfStream, - VideoRenderer_InputPin_BeginFlush, - VideoRenderer_InputPin_EndFlush, - InputPin_NewSegment + BaseRendererImpl_Run, + BaseRendererImpl_GetState, + BaseRendererImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + BaseRendererImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo }; /*** IUnknown methods ***/ -static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); +static HRESULT WINAPI BasicVideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID *ppvObj) +{ + VideoRendererImpl *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); +static ULONG WINAPI BasicVideo_AddRef(IBasicVideo *iface) +{ + VideoRendererImpl *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->()\n", This, iface); - return VideoRenderer_AddRef((IBaseFilter*)This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); +static ULONG WINAPI BasicVideo_Release(IBasicVideo *iface) +{ + VideoRendererImpl *This = impl_from_IBasicVideo(iface); TRACE("(%p/%p)->()\n", This, iface); - return VideoRenderer_Release((IBaseFilter*)This); + return IUnknown_Release(This->outer_unk); } -/*** IDispatch methods ***/ -static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); - - return S_OK; -} - -/*** IBasicVideo methods ***/ -static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface, - REFTIME *pAvgTimePerFrame) { - AM_MEDIA_TYPE *pmt; - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - if (!This->pInputPin->pin.pConnectedTo) - return VFW_E_NOT_CONNECTED; - - TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); - - pmt = &This->pInputPin->pin.mtCurrent; - if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { - VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)pmt->pbFormat; - *pAvgTimePerFrame = vih->AvgTimePerFrame; - } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { - VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)pmt->pbFormat; - *pAvgTimePerFrame = vih->AvgTimePerFrame; - } else { - ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); - *pAvgTimePerFrame = 0; - } - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface, - LONG *pBitRate) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface, - LONG *pBitErrorRate) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface, - LONG *pVideoWidth) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth); - - *pVideoWidth = This->VideoWidth; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface, - LONG *pVideoHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight); - - *pVideoHeight = This->VideoHeight; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface, - LONG SourceLeft) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft); - - This->SourceRect.left = SourceLeft; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface, - LONG *pSourceLeft) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft); - - *pSourceLeft = This->SourceRect.left; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface, - LONG SourceWidth) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth); - - This->SourceRect.right = This->SourceRect.left + SourceWidth; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface, - LONG *pSourceWidth) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth); - - *pSourceWidth = This->SourceRect.right - This->SourceRect.left; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface, - LONG SourceTop) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop); - - This->SourceRect.top = SourceTop; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface, - LONG *pSourceTop) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop); - - *pSourceTop = This->SourceRect.top; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface, - LONG SourceHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight); - - This->SourceRect.bottom = This->SourceRect.top + SourceHeight; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface, - LONG *pSourceHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight); - - *pSourceHeight = This->SourceRect.bottom - This->SourceRect.top; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface, - LONG DestinationLeft) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft); - - This->DestRect.left = DestinationLeft; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface, - LONG *pDestinationLeft) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft); - - *pDestinationLeft = This->DestRect.left; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface, - LONG DestinationWidth) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth); - - This->DestRect.right = This->DestRect.left + DestinationWidth; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface, - LONG *pDestinationWidth) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth); - - *pDestinationWidth = This->DestRect.right - This->DestRect.left; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface, - LONG DestinationTop) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop); - - This->DestRect.top = DestinationTop; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface, - LONG *pDestinationTop) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop); - - *pDestinationTop = This->DestRect.top; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface, - LONG DestinationHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight); - - This->DestRect.right = This->DestRect.left + DestinationHeight; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface, - LONG *pDestinationHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight); - - *pDestinationHeight = This->DestRect.right - This->DestRect.left; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface, - LONG Left, - LONG Top, - LONG Width, - LONG Height) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); - - This->SourceRect.left = Left; - This->SourceRect.top = Top; - This->SourceRect.right = Left + Width; - This->SourceRect.bottom = Top + Height; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); - - *pLeft = This->SourceRect.left; - *pTop = This->SourceRect.top; - *pWidth = This->SourceRect.right - This->SourceRect.left; - *pHeight = This->SourceRect.bottom - This->SourceRect.top; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->()\n", This, iface); - - This->SourceRect.left = 0; - This->SourceRect.top = 0; - This->SourceRect.right = This->VideoWidth; - This->SourceRect.bottom = This->VideoHeight; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface, - LONG Left, - LONG Top, - LONG Width, - LONG Height) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); - - This->DestRect.left = Left; - This->DestRect.top = Top; - This->DestRect.right = Left + Width; - This->DestRect.bottom = Top + Height; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); - - *pLeft = This->DestRect.left; - *pTop = This->DestRect.top; - *pWidth = This->DestRect.right - This->DestRect.left; - *pHeight = This->DestRect.bottom - This->DestRect.top; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - RECT rect; - - TRACE("(%p/%p)->()\n", This, iface); - - if (!GetClientRect(This->hWnd, &rect)) - return E_FAIL; - - This->SourceRect.left = 0; - This->SourceRect.top = 0; - This->SourceRect.right = rect.right; - This->SourceRect.bottom = rect.bottom; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); - - *pWidth = This->VideoWidth; - *pHeight = This->VideoHeight; - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface, - LONG StartIndex, - LONG Entries, - LONG *pRetrieved, - LONG *pPalette) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(%d, %d, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface, - LONG *pBufferSize, - LONG *pDIBImage) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - BITMAPINFOHEADER *bmiHeader; - LONG needed_size; - AM_MEDIA_TYPE *amt = &This->pInputPin->pin.mtCurrent; - char *ptr; - - FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage); - - EnterCriticalSection(&This->csFilter); - - if (!This->sample_held) - { - LeaveCriticalSection(&This->csFilter); - return (This->state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED); - } - - if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) - { - bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; - } - else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) - { - bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; - } - else - { - FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); - LeaveCriticalSection(&This->csFilter); - return VFW_E_RUNTIME_ERROR; - } - - needed_size = bmiHeader->biSize; - needed_size += IMediaSample_GetActualDataLength(This->sample_held); - - if (!pDIBImage) - { - *pBufferSize = needed_size; - LeaveCriticalSection(&This->csFilter); - return S_OK; - } - - if (needed_size < *pBufferSize) - { - ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize); - LeaveCriticalSection(&This->csFilter); - return E_FAIL; - } - *pBufferSize = needed_size; - - memcpy(pDIBImage, bmiHeader, bmiHeader->biSize); - IMediaSample_GetPointer(This->sample_held, (BYTE **)&ptr); - memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->sample_held)); - - LeaveCriticalSection(&This->csFilter); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(): stub !!!\n", This, iface); - - return S_OK; -} - -static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface); - - FIXME("(%p/%p)->(): stub !!!\n", This, iface); - - return S_OK; -} - - static const IBasicVideoVtbl IBasicVideo_VTable = { - Basicvideo_QueryInterface, - Basicvideo_AddRef, - Basicvideo_Release, - Basicvideo_GetTypeInfoCount, - Basicvideo_GetTypeInfo, - Basicvideo_GetIDsOfNames, - Basicvideo_Invoke, - Basicvideo_get_AvgTimePerFrame, - Basicvideo_get_BitRate, - Basicvideo_get_BitErrorRate, - Basicvideo_get_VideoWidth, - Basicvideo_get_VideoHeight, - Basicvideo_put_SourceLeft, - Basicvideo_get_SourceLeft, - Basicvideo_put_SourceWidth, - Basicvideo_get_SourceWidth, - Basicvideo_put_SourceTop, - Basicvideo_get_SourceTop, - Basicvideo_put_SourceHeight, - Basicvideo_get_SourceHeight, - Basicvideo_put_DestinationLeft, - Basicvideo_get_DestinationLeft, - Basicvideo_put_DestinationWidth, - Basicvideo_get_DestinationWidth, - Basicvideo_put_DestinationTop, - Basicvideo_get_DestinationTop, - Basicvideo_put_DestinationHeight, - Basicvideo_get_DestinationHeight, - Basicvideo_SetSourcePosition, - Basicvideo_GetSourcePosition, - Basicvideo_SetDefaultSourcePosition, - Basicvideo_SetDestinationPosition, - Basicvideo_GetDestinationPosition, - Basicvideo_SetDefaultDestinationPosition, - Basicvideo_GetVideoSize, - Basicvideo_GetVideoPaletteEntries, - Basicvideo_GetCurrentImage, - Basicvideo_IsUsingDefaultSource, - Basicvideo_IsUsingDefaultDestination + BasicVideo_QueryInterface, + BasicVideo_AddRef, + BasicVideo_Release, + BaseControlVideoImpl_GetTypeInfoCount, + BaseControlVideoImpl_GetTypeInfo, + BaseControlVideoImpl_GetIDsOfNames, + BaseControlVideoImpl_Invoke, + BaseControlVideoImpl_get_AvgTimePerFrame, + BaseControlVideoImpl_get_BitRate, + BaseControlVideoImpl_get_BitErrorRate, + BaseControlVideoImpl_get_VideoWidth, + BaseControlVideoImpl_get_VideoHeight, + BaseControlVideoImpl_put_SourceLeft, + BaseControlVideoImpl_get_SourceLeft, + BaseControlVideoImpl_put_SourceWidth, + BaseControlVideoImpl_get_SourceWidth, + BaseControlVideoImpl_put_SourceTop, + BaseControlVideoImpl_get_SourceTop, + BaseControlVideoImpl_put_SourceHeight, + BaseControlVideoImpl_get_SourceHeight, + BaseControlVideoImpl_put_DestinationLeft, + BaseControlVideoImpl_get_DestinationLeft, + BaseControlVideoImpl_put_DestinationWidth, + BaseControlVideoImpl_get_DestinationWidth, + BaseControlVideoImpl_put_DestinationTop, + BaseControlVideoImpl_get_DestinationTop, + BaseControlVideoImpl_put_DestinationHeight, + BaseControlVideoImpl_get_DestinationHeight, + BaseControlVideoImpl_SetSourcePosition, + BaseControlVideoImpl_GetSourcePosition, + BaseControlVideoImpl_SetDefaultSourcePosition, + BaseControlVideoImpl_SetDestinationPosition, + BaseControlVideoImpl_GetDestinationPosition, + BaseControlVideoImpl_SetDefaultDestinationPosition, + BaseControlVideoImpl_GetVideoSize, + BaseControlVideoImpl_GetVideoPaletteEntries, + BaseControlVideoImpl_GetCurrentImage, + BaseControlVideoImpl_IsUsingDefaultSource, + BaseControlVideoImpl_IsUsingDefaultDestination }; /*** IUnknown methods ***/ -static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, - REFIID riid, - LPVOID*ppvObj) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); +static HRESULT WINAPI VideoWindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID *ppvObj) +{ + VideoRendererImpl *This = impl_from_IVideoWindow(iface); TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); - return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); } -static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); +static ULONG WINAPI VideoWindow_AddRef(IVideoWindow *iface) +{ + VideoRendererImpl *This = impl_from_IVideoWindow(iface); TRACE("(%p/%p)->()\n", This, iface); - return VideoRenderer_AddRef((IBaseFilter*)This); + return IUnknown_AddRef(This->outer_unk); } -static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); +static ULONG WINAPI VideoWindow_Release(IVideoWindow *iface) +{ + VideoRendererImpl *This = impl_from_IVideoWindow(iface); TRACE("(%p/%p)->()\n", This, iface); - return VideoRenderer_Release((IBaseFilter*)This); + return IUnknown_Release(This->outer_unk); } -/*** IDispatch methods ***/ -static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface, - UINT*pctinfo) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface, - UINT iTInfo, - LCID lcid, - ITypeInfo**ppTInfo) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface, - REFIID riid, - LPOLESTR*rgszNames, - UINT cNames, - LCID lcid, - DISPID*rgDispId) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface, - DISPID dispIdMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS*pDispParams, - VARIANT*pVarResult, - EXCEPINFO*pExepInfo, - UINT*puArgErr) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); - - return S_OK; -} - -/*** IVideoWindow methods ***/ -static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface, - BSTR strCaption) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption); - - if (!SetWindowTextW(This->hWnd, strCaption)) - return E_FAIL; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface, - BSTR *strCaption) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, strCaption); - - GetWindowTextW(This->hWnd, (LPWSTR)strCaption, 100); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface, - LONG WindowStyle) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - LONG old; - - old = GetWindowLongA(This->hWnd, GWL_STYLE); - - TRACE("(%p/%p)->(%x -> %x)\n", This, iface, old, WindowStyle); - - if (WindowStyle & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) - return E_INVALIDARG; - - SetWindowLongA(This->hWnd, GWL_STYLE, WindowStyle); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface, - LONG *WindowStyle) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle); - - *WindowStyle = GetWindowLongA(This->hWnd, GWL_STYLE); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface, - LONG WindowStyleEx) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx); - - if (!SetWindowLongA(This->hWnd, GWL_EXSTYLE, WindowStyleEx)) - return E_FAIL; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface, - LONG *WindowStyleEx) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx); - - *WindowStyleEx = GetWindowLongA(This->hWnd, GWL_EXSTYLE); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface, - LONG AutoShow) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow); - - This->AutoShow = AutoShow; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface, - LONG *AutoShow) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow); - - *AutoShow = This->AutoShow; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface, - LONG WindowState) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, WindowState); - ShowWindow(This->hWnd, WindowState); - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface, - LONG *WindowState) { - WINDOWPLACEMENT place; - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - place.length = sizeof(place); - GetWindowPlacement(This->hWnd, &place); - TRACE("(%p/%p)->(%p)\n", This, iface, WindowState); - *WindowState = place.showCmd; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface, - LONG BackgroundPalette) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, BackgroundPalette); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface, - LONG *pBackgroundPalette) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface, - LONG Visible) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, Visible); - - ShowWindow(This->hWnd, Visible ? SW_SHOW : SW_HIDE); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface, - LONG *pVisible) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pVisible); - - *pVisible = IsWindowVisible(This->hWnd); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface, - LONG Left) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, Left); - - if (!SetWindowPos(This->hWnd, NULL, Left, This->WindowPos.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) - return E_FAIL; - - This->WindowPos.left = Left; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface, - LONG *pLeft) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pLeft); - - *pLeft = This->WindowPos.left; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface, - LONG Width) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, Width); - - if (!SetWindowPos(This->hWnd, NULL, 0, 0, Width, This->WindowPos.bottom-This->WindowPos.top, SWP_NOZORDER|SWP_NOMOVE)) - return E_FAIL; - - This->WindowPos.right = This->WindowPos.left + Width; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface, - LONG *pWidth) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pWidth); - - *pWidth = This->WindowPos.right - This->WindowPos.left; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface, - LONG Top) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, Top); - - if (!SetWindowPos(This->hWnd, NULL, This->WindowPos.left, Top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) - return E_FAIL; - - This->WindowPos.top = Top; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface, - LONG *pTop) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pTop); - - *pTop = This->WindowPos.top; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface, - LONG Height) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d)\n", This, iface, Height); - - if (!SetWindowPos(This->hWnd, NULL, 0, 0, This->WindowPos.right-This->WindowPos.left, Height, SWP_NOZORDER|SWP_NOMOVE)) - return E_FAIL; - - This->WindowPos.bottom = This->WindowPos.top + Height; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pHeight); - - *pHeight = This->WindowPos.bottom - This->WindowPos.top; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface, - OAHWND Owner) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner); - - SetParent(This->hWnd, (HWND)Owner); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface, - OAHWND *Owner) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, Owner); - - *(HWND*)Owner = GetParent(This->hWnd); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface, - OAHWND Drain) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain); - - This->hWndMsgDrain = (HWND)Drain; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface, - OAHWND *Drain) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, Drain); - - *Drain = (OAHWND)This->hWndMsgDrain; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface, - LONG *Color) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface, - LONG Color) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, Color); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface, - LONG *FullScreenMode) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); +static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, + LONG *FullScreenMode) +{ + VideoRendererImpl *This = impl_from_IVideoWindow(iface); FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode); return S_OK; } -static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface, - LONG FullScreenMode) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); +static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, + LONG FullScreenMode) +{ + VideoRendererImpl *This = impl_from_IVideoWindow(iface); FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, FullScreenMode); - return S_OK; -} - -static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface, - LONG Focus) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - BOOL ret; - IPin* pPin; - HRESULT hr; - - TRACE("(%p/%p)->(%d)\n", This, iface, Focus); - - if ((Focus != FALSE) && (Focus != TRUE)) - return E_INVALIDARG; - - hr = IPin_ConnectedTo((IPin *)This->pInputPin, &pPin); - if ((hr != S_OK) || !pPin) - return VFW_E_NOT_CONNECTED; - - if (Focus) - ret = SetForegroundWindow(This->hWnd); - else - ret = SetWindowPos(This->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - - if (!ret) - return E_FAIL; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface, - OAHWND hwnd, - LONG uMsg, - LONG_PTR wParam, - LONG_PTR lParam) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This, iface, hwnd, uMsg, wParam, lParam); - - if (!PostMessageA(This->hWnd, uMsg, wParam, lParam)) - return E_FAIL; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface, - LONG Left, - LONG Top, - LONG Width, - LONG Height) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); - - if (!SetWindowPos(This->hWnd, NULL, Left, Top, Width, Height, SWP_NOZORDER)) - return E_FAIL; - - This->WindowPos.left = Left; - This->WindowPos.top = Top; - This->WindowPos.right = Left + Width; - This->WindowPos.bottom = Top + Height; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); - - *pLeft = This->WindowPos.left; - *pTop = This->WindowPos.top; - *pWidth = This->WindowPos.right - This->WindowPos.left; - *pHeight = This->WindowPos.bottom - This->WindowPos.top; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight); - - *pWidth = This->VideoWidth; - *pHeight = This->VideoHeight; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight); - - *pWidth = This->VideoWidth; - *pHeight = This->VideoHeight; - - return S_OK; -} - -static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface, - LONG *pLeft, - LONG *pTop, - LONG *pWidth, - LONG *pHeight) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface, - LONG HideCursor) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, HideCursor); - - return S_OK; -} - -static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface, - LONG *CursorHidden) { - ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface); - - FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden); + if (FullScreenMode) { + This->baseControlWindow.baseWindow.WindowStyles = GetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE); + ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_HIDE); + SetParent(This->baseControlWindow.baseWindow.hWnd, 0); + SetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE, WS_POPUP); + SetWindowPos(This->baseControlWindow.baseWindow.hWnd,HWND_TOP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),SWP_SHOWWINDOW); + GetWindowRect(This->baseControlWindow.baseWindow.hWnd, &This->DestRect); + This->WindowPos = This->DestRect; + } else { + ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_HIDE); + SetParent(This->baseControlWindow.baseWindow.hWnd, This->baseControlWindow.hwndOwner); + SetWindowLongW(This->baseControlWindow.baseWindow.hWnd, GWL_STYLE, This->baseControlWindow.baseWindow.WindowStyles); + GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->DestRect); + SetWindowPos(This->baseControlWindow.baseWindow.hWnd,0,This->DestRect.left,This->DestRect.top,This->DestRect.right,This->DestRect.bottom,SWP_NOZORDER|SWP_SHOWWINDOW); + This->WindowPos = This->DestRect; + } return S_OK; } static const IVideoWindowVtbl IVideoWindow_VTable = { - Videowindow_QueryInterface, - Videowindow_AddRef, - Videowindow_Release, - Videowindow_GetTypeInfoCount, - Videowindow_GetTypeInfo, - Videowindow_GetIDsOfNames, - Videowindow_Invoke, - Videowindow_put_Caption, - Videowindow_get_Caption, - Videowindow_put_WindowStyle, - Videowindow_get_WindowStyle, - Videowindow_put_WindowStyleEx, - Videowindow_get_WindowStyleEx, - Videowindow_put_AutoShow, - Videowindow_get_AutoShow, - Videowindow_put_WindowState, - Videowindow_get_WindowState, - Videowindow_put_BackgroundPalette, - Videowindow_get_BackgroundPalette, - Videowindow_put_Visible, - Videowindow_get_Visible, - Videowindow_put_Left, - Videowindow_get_Left, - Videowindow_put_Width, - Videowindow_get_Width, - Videowindow_put_Top, - Videowindow_get_Top, - Videowindow_put_Height, - Videowindow_get_Height, - Videowindow_put_Owner, - Videowindow_get_Owner, - Videowindow_put_MessageDrain, - Videowindow_get_MessageDrain, - Videowindow_get_BorderColor, - Videowindow_put_BorderColor, - Videowindow_get_FullScreenMode, - Videowindow_put_FullScreenMode, - Videowindow_SetWindowForeground, - Videowindow_NotifyOwnerMessage, - Videowindow_SetWindowPosition, - Videowindow_GetWindowPosition, - Videowindow_GetMinIdealImageSize, - Videowindow_GetMaxIdealImageSize, - Videowindow_GetRestorePosition, - Videowindow_HideCursor, - Videowindow_IsCursorHidden + VideoWindow_QueryInterface, + VideoWindow_AddRef, + VideoWindow_Release, + BaseControlWindowImpl_GetTypeInfoCount, + BaseControlWindowImpl_GetTypeInfo, + BaseControlWindowImpl_GetIDsOfNames, + BaseControlWindowImpl_Invoke, + BaseControlWindowImpl_put_Caption, + BaseControlWindowImpl_get_Caption, + BaseControlWindowImpl_put_WindowStyle, + BaseControlWindowImpl_get_WindowStyle, + BaseControlWindowImpl_put_WindowStyleEx, + BaseControlWindowImpl_get_WindowStyleEx, + BaseControlWindowImpl_put_AutoShow, + BaseControlWindowImpl_get_AutoShow, + BaseControlWindowImpl_put_WindowState, + BaseControlWindowImpl_get_WindowState, + BaseControlWindowImpl_put_BackgroundPalette, + BaseControlWindowImpl_get_BackgroundPalette, + BaseControlWindowImpl_put_Visible, + BaseControlWindowImpl_get_Visible, + BaseControlWindowImpl_put_Left, + BaseControlWindowImpl_get_Left, + BaseControlWindowImpl_put_Width, + BaseControlWindowImpl_get_Width, + BaseControlWindowImpl_put_Top, + BaseControlWindowImpl_get_Top, + BaseControlWindowImpl_put_Height, + BaseControlWindowImpl_get_Height, + BaseControlWindowImpl_put_Owner, + BaseControlWindowImpl_get_Owner, + BaseControlWindowImpl_put_MessageDrain, + BaseControlWindowImpl_get_MessageDrain, + BaseControlWindowImpl_get_BorderColor, + BaseControlWindowImpl_put_BorderColor, + VideoWindow_get_FullScreenMode, + VideoWindow_put_FullScreenMode, + BaseControlWindowImpl_SetWindowForeground, + BaseControlWindowImpl_NotifyOwnerMessage, + BaseControlWindowImpl_SetWindowPosition, + BaseControlWindowImpl_GetWindowPosition, + BaseControlWindowImpl_GetMinIdealImageSize, + BaseControlWindowImpl_GetMaxIdealImageSize, + BaseControlWindowImpl_GetRestorePosition, + BaseControlWindowImpl_HideCursor, + BaseControlWindowImpl_IsCursorHidden }; + +static VideoRendererImpl *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, IAMFilterMiscFlags_iface); +} + +static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, + void **ppv) +{ + VideoRendererImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); +} + +static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) +{ + VideoRendererImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) +{ + VideoRendererImpl *This = impl_from_IAMFilterMiscFlags(iface); + return IUnknown_Release(This->outer_unk); +} + +static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) +{ + return AM_FILTER_MISC_FLAGS_IS_RENDERER; +} + +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = { + AMFilterMiscFlags_QueryInterface, + AMFilterMiscFlags_AddRef, + AMFilterMiscFlags_Release, + AMFilterMiscFlags_GetMiscFlags +}; + +HRESULT VideoRenderer_create(IUnknown *pUnkOuter, void **ppv) +{ + HRESULT hr; + VideoRendererImpl * pVideoRenderer; + + TRACE("(%p, %p)\n", pUnkOuter, ppv); + + *ppv = NULL; + + pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl)); + pVideoRenderer->IUnknown_inner.lpVtbl = &IInner_VTable; + pVideoRenderer->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl; + + pVideoRenderer->init = 0; + ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT)); + ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT)); + ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT)); + + if (pUnkOuter) + pVideoRenderer->outer_unk = pUnkOuter; + else + pVideoRenderer->outer_unk = &pVideoRenderer->IUnknown_inner; + + hr = BaseRenderer_Init(&pVideoRenderer->renderer, &VideoRenderer_Vtbl, pUnkOuter, + &CLSID_VideoRenderer, (DWORD_PTR)(__FILE__ ": VideoRendererImpl.csFilter"), + &BaseFuncTable); + + if (FAILED(hr)) + goto fail; + + hr = BaseControlWindow_Init(&pVideoRenderer->baseControlWindow, &IVideoWindow_VTable, + &pVideoRenderer->renderer.filter, &pVideoRenderer->renderer.filter.csFilter, + &pVideoRenderer->renderer.pInputPin->pin, &renderer_BaseWindowFuncTable); + if (FAILED(hr)) + goto fail; + + hr = BaseControlVideo_Init(&pVideoRenderer->baseControlVideo, &IBasicVideo_VTable, + &pVideoRenderer->renderer.filter, &pVideoRenderer->renderer.filter.csFilter, + &pVideoRenderer->renderer.pInputPin->pin, &renderer_BaseControlVideoFuncTable); + if (FAILED(hr)) + goto fail; + + if (!CreateRenderingSubsystem(pVideoRenderer)) { + hr = E_FAIL; + goto fail; + } + + *ppv = &pVideoRenderer->IUnknown_inner; + return S_OK; + +fail: + BaseRendererImpl_Release(&pVideoRenderer->renderer.filter.IBaseFilter_iface); + CoTaskMemFree(pVideoRenderer); + return hr; +} + +HRESULT VideoRendererDefault_create(IUnknown * pUnkOuter, LPVOID * ppv) +{ + /* TODO: Attempt to use the VMR-7 renderer instead when possible */ + return VideoRenderer_create(pUnkOuter, ppv); +} diff --git a/dll/directx/quartz/vmr9.c b/dll/directx/quartz/vmr9.c new file mode 100644 index 00000000000..5a837ddaf2c --- /dev/null +++ b/dll/directx/quartz/vmr9.c @@ -0,0 +1,2304 @@ +/* + * Video Mixing Renderer for dx9 + * + * Copyright 2004 Christian Costa + * Copyright 2008 Maarten Lankhorst + * Copyright 2012 Aric Stewart + * + * 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 + */ + +#include "config.h" + +#define NONAMELESSSTRUCT +#define NONAMELESSUNION +#include "quartz_private.h" + +#include "uuids.h" +#include "vfwmsgs.h" +#include "amvideo.h" +#include "windef.h" +#include "winbase.h" +#include "dshow.h" +#include "evcode.h" +#include "strmif.h" +#include "ddraw.h" +#include "dvdmedia.h" +#include "d3d9.h" +#include "vmr9.h" +#include "pin.h" + +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +typedef struct +{ + BaseRenderer renderer; + BaseControlWindow baseControlWindow; + BaseControlVideo baseControlVideo; + + IUnknown IUnknown_inner; + IAMFilterMiscFlags IAMFilterMiscFlags_iface; + IVMRFilterConfig9 IVMRFilterConfig9_iface; + IVMRWindowlessControl9 IVMRWindowlessControl9_iface; + IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface; + + IVMRSurfaceAllocatorEx9 *allocator; + IVMRImagePresenter9 *presenter; + BOOL allocator_is_ex; + + /* + * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed + * What I do is implement windowless as a special case of renderless, and then + * windowed also as a special case of windowless. This is probably the easiest way. + */ + VMR9Mode mode; + BITMAPINFOHEADER bmiheader; + IUnknown * outer_unk; + BOOL bUnkOuterValid; + BOOL bAggregatable; + + HMODULE hD3d9; + + /* Presentation related members */ + IDirect3DDevice9 *allocator_d3d9_dev; + HMONITOR allocator_mon; + DWORD num_surfaces; + DWORD cur_surface; + DWORD_PTR cookie; + + /* for Windowless Mode */ + HWND hWndClippingWindow; + + RECT source_rect; + RECT target_rect; + LONG VideoWidth; + LONG VideoHeight; +} VMR9Impl; + +static inline VMR9Impl *impl_from_inner_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, IUnknown_inner); +} + +static inline VMR9Impl *impl_from_BaseWindow( BaseWindow *wnd ) +{ + return CONTAINING_RECORD(wnd, VMR9Impl, baseControlWindow.baseWindow); +} + +static inline VMR9Impl *impl_from_IVideoWindow( IVideoWindow *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, baseControlWindow.IVideoWindow_iface); +} + +static inline VMR9Impl *impl_from_BaseControlVideo( BaseControlVideo *cvid ) +{ + return CONTAINING_RECORD(cvid, VMR9Impl, baseControlVideo); +} + +static inline VMR9Impl *impl_from_IBasicVideo( IBasicVideo *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, baseControlVideo.IBasicVideo_iface); +} + +static inline VMR9Impl *impl_from_IAMFilterMiscFlags( IAMFilterMiscFlags *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, IAMFilterMiscFlags_iface); +} + +static inline VMR9Impl *impl_from_IVMRFilterConfig9( IVMRFilterConfig9 *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, IVMRFilterConfig9_iface); +} + +static inline VMR9Impl *impl_from_IVMRWindowlessControl9( IVMRWindowlessControl9 *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, IVMRWindowlessControl9_iface); +} + +static inline VMR9Impl *impl_from_IVMRSurfaceAllocatorNotify9( IVMRSurfaceAllocatorNotify9 *iface) +{ + return CONTAINING_RECORD(iface, VMR9Impl, IVMRSurfaceAllocatorNotify9_iface); +} + +typedef struct +{ + IVMRImagePresenter9 IVMRImagePresenter9_iface; + IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface; + + LONG refCount; + + HANDLE ack; + DWORD tid; + HANDLE hWndThread; + + IDirect3DDevice9 *d3d9_dev; + IDirect3D9 *d3d9_ptr; + IDirect3DSurface9 **d3d9_surfaces; + IDirect3DVertexBuffer9 *d3d9_vertex; + HMONITOR hMon; + DWORD num_surfaces; + + BOOL reset; + VMR9AllocationInfo info; + + VMR9Impl* pVMR9; + IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify; +} VMR9DefaultAllocatorPresenterImpl; + +static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface) +{ + return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface); +} + +static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface) +{ + return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface); +} + +static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv); + +static DWORD VMR9_SendSampleData(VMR9Impl *This, VMR9PresentationInfo *info, LPBYTE data, DWORD size) +{ + AM_MEDIA_TYPE *amt; + HRESULT hr = S_OK; + int width; + int height; + BITMAPINFOHEADER *bmiHeader; + D3DLOCKED_RECT lock; + + TRACE("%p %p %d\n", This, data, size); + + amt = &This->renderer.pInputPin->pin.mtCurrent; + + if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) + { + bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; + } + else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) + { + bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; + } + else + { + FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); + return VFW_E_RUNTIME_ERROR; + } + + TRACE("biSize = %d\n", bmiHeader->biSize); + TRACE("biWidth = %d\n", bmiHeader->biWidth); + TRACE("biHeight = %d\n", bmiHeader->biHeight); + TRACE("biPlanes = %d\n", bmiHeader->biPlanes); + TRACE("biBitCount = %d\n", bmiHeader->biBitCount); + TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4)); + TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage); + + width = bmiHeader->biWidth; + height = bmiHeader->biHeight; + + TRACE("Src Rect: %d %d %d %d\n", This->source_rect.left, This->source_rect.top, This->source_rect.right, This->source_rect.bottom); + TRACE("Dst Rect: %d %d %d %d\n", This->target_rect.left, This->target_rect.top, This->target_rect.right, This->target_rect.bottom); + + hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD); + if (FAILED(hr)) + { + ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr); + return hr; + } + + if (lock.Pitch != width * bmiHeader->biBitCount / 8) + { + WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8); + + while (height--) + { + memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8); + data = data + width * bmiHeader->biBitCount / 8; + lock.pBits = (char *)lock.pBits + lock.Pitch; + } + } + else memcpy(lock.pBits, data, size); + + IDirect3DSurface9_UnlockRect(info->lpSurf); + + hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info); + return hr; +} + +static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample) +{ + VMR9Impl *This = (VMR9Impl *)iface; + LPBYTE pbSrcStream = NULL; + long cbSrcStream = 0; + REFERENCE_TIME tStart, tStop; + VMR9PresentationInfo info; + HRESULT hr; + + TRACE("%p %p\n", iface, pSample); + + /* It is possible that there is no device at this point */ + + if (!This->allocator || !This->presenter) + { + ERR("NO PRESENTER!!\n"); + return S_FALSE; + } + + hr = IMediaSample_GetTime(pSample, &tStart, &tStop); + if (FAILED(hr)) + info.dwFlags = VMR9Sample_SrcDstRectsValid; + else + info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid; + + if (IMediaSample_IsDiscontinuity(pSample) == S_OK) + info.dwFlags |= VMR9Sample_Discontinuity; + + if (IMediaSample_IsPreroll(pSample) == S_OK) + info.dwFlags |= VMR9Sample_Preroll; + + if (IMediaSample_IsSyncPoint(pSample) == S_OK) + info.dwFlags |= VMR9Sample_SyncPoint; + + /* If we render ourselves, and this is a preroll sample, discard it */ + if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll)) + { + return S_OK; + } + + hr = IMediaSample_GetPointer(pSample, &pbSrcStream); + if (FAILED(hr)) + { + ERR("Cannot get pointer to sample data (%x)\n", hr); + return hr; + } + + cbSrcStream = IMediaSample_GetActualDataLength(pSample); + + info.rtStart = tStart; + info.rtEnd = tStop; + info.szAspectRatio.cx = This->bmiheader.biWidth; + info.szAspectRatio.cy = This->bmiheader.biHeight; + + hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf); + + if (FAILED(hr)) + return hr; + + VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream); + IDirect3DSurface9_Release(info.lpSurf); + + return hr; +} + +static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) +{ + VMR9Impl *This = (VMR9Impl*)iface; + + if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat) + return S_FALSE; + + /* Ignore subtype, test for bicompression instead */ + if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) + { + VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat; + + This->bmiheader = format->bmiHeader; + TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight); + This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth; + This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight; + This->source_rect.top = This->source_rect.left = 0; + } + else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) + { + VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat; + + This->bmiheader = format->bmiHeader; + + TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight); + This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth; + This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight; + This->source_rect.top = This->source_rect.left = 0; + } + else + { + ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype)); + return S_FALSE; + } + if (This->bmiheader.biCompression) + return S_FALSE; + return S_OK; +} + +static HRESULT VMR9_maybe_init(VMR9Impl *This, BOOL force) +{ + VMR9AllocationInfo info; + DWORD buffers; + HRESULT hr; + + TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow); + if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo) + return S_OK; + + if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow) + return (force ? VFW_E_RUNTIME_ERROR : S_OK); + + TRACE("Initializing\n"); + info.dwFlags = VMR9AllocFlag_TextureSurface; + info.dwHeight = This->source_rect.bottom; + info.dwWidth = This->source_rect.right; + info.Pool = D3DPOOL_DEFAULT; + info.MinBuffers = 2; + FIXME("Reduce ratio to least common denominator\n"); + info.szAspectRatio.cx = info.dwWidth; + info.szAspectRatio.cy = info.dwHeight; + info.szNativeSize.cx = This->bmiheader.biWidth; + info.szNativeSize.cy = This->bmiheader.biHeight; + buffers = 2; + + switch (This->bmiheader.biBitCount) + { + case 8: info.Format = D3DFMT_R3G3B2; break; + case 15: info.Format = D3DFMT_X1R5G5B5; break; + case 16: info.Format = D3DFMT_R5G6B5; break; + case 24: info.Format = D3DFMT_R8G8B8; break; + case 32: info.Format = D3DFMT_X8R8G8B8; break; + default: + FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount); + hr = E_INVALIDARG; + } + + This->cur_surface = 0; + if (This->num_surfaces) + { + ERR("num_surfaces or d3d9_surfaces not 0\n"); + return E_FAIL; + } + + hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers); + if (SUCCEEDED(hr)) + { + This->source_rect.left = This->source_rect.top = 0; + This->source_rect.right = This->bmiheader.biWidth; + This->source_rect.bottom = This->bmiheader.biHeight; + + This->num_surfaces = buffers; + } + return hr; +} + +static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface) +{ + VMR9Impl *This = (VMR9Impl*)iface; + + TRACE("(%p)\n", This); + + VMR9_maybe_init(This, TRUE); + IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie); + SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, + This->source_rect.left, + This->source_rect.top, + This->source_rect.right - This->source_rect.left, + This->source_rect.bottom - This->source_rect.top, + SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE); + ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW); + GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect); +} + +static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface) +{ + VMR9Impl *This = (VMR9Impl*)iface; + + TRACE("(%p)\n", This); + + if (This->renderer.filter.state == State_Running) + IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie); +} + +static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime) +{ + /* Preroll means the sample isn't shown, this is used for key frames and things like that */ + if (IMediaSample_IsPreroll(pSample) == S_OK) + return E_FAIL; + return S_FALSE; +} + +static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin) +{ + VMR9Impl *pVMR9 = (VMR9Impl*)This; + HRESULT hr = S_OK; + + TRACE("(%p)\n", This); + + if (!pVMR9->mode && SUCCEEDED(hr)) + hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed); + + if (SUCCEEDED(hr)) + hr = VMR9_maybe_init(pVMR9, FALSE); + + return hr; +} + +static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This) +{ + VMR9Impl *pVMR9 = (VMR9Impl*)This; + HRESULT hr = S_OK; + + if (!pVMR9->mode) + return S_FALSE; + if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter) + { + if (pVMR9->renderer.filter.state != State_Stopped) + { + ERR("Disconnecting while not stopped! UNTESTED!!\n"); + } + if (pVMR9->renderer.filter.state == State_Running) + hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie); + IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie); + pVMR9->num_surfaces = 0; + } + return hr; +} + +static const BaseRendererFuncTable BaseFuncTable = { + VMR9_CheckMediaType, + VMR9_DoRenderSample, + /**/ + NULL, + NULL, + NULL, + VMR9_OnStartStreaming, + VMR9_OnStopStreaming, + NULL, + NULL, + NULL, + VMR9_ShouldDrawSampleNow, + NULL, + /**/ + VMR9_CompleteConnect, + VMR9_BreakConnect, + NULL, + NULL, + NULL, +}; + +static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx) +{ + static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 }; + + *pClassStyles = 0; + *pWindowStyles = WS_SIZEBOX; + *pWindowStylesEx = 0; + + return classnameW; +} + +static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This) +{ + VMR9Impl* pVMR9 = impl_from_BaseWindow(This); + static RECT defRect; + + defRect.left = defRect.top = 0; + defRect.right = pVMR9->VideoWidth; + defRect.bottom = pVMR9->VideoHeight; + + return defRect; +} + +static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height) +{ + VMR9Impl* pVMR9 = impl_from_BaseWindow(This); + + TRACE("WM_SIZE %d %d\n", Width, Height); + GetClientRect(This->hWnd, &pVMR9->target_rect); + TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n", + pVMR9->target_rect.left, + pVMR9->target_rect.top, + pVMR9->target_rect.right - pVMR9->target_rect.left, + pVMR9->target_rect.bottom - pVMR9->target_rect.top); + return BaseWindowImpl_OnSize(This, Width, Height); +} + +static const BaseWindowFuncTable renderer_BaseWindowFuncTable = { + VMR9_GetClassWindowStyles, + VMR9_GetDefaultRect, + NULL, + BaseControlWindowImpl_PossiblyEatMessage, + VMR9_OnSize, +}; + +static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + CopyRect(pSourceRect,&pVMR9->source_rect); + return S_OK; +} + +static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + BITMAPINFOHEADER *bmiHeader; + LONG needed_size; + AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent; + char *ptr; + + FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage); + + EnterCriticalSection(&pVMR9->renderer.filter.csFilter); + + if (!pVMR9->renderer.pMediaSample) + { + LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); + return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED); + } + + if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) + { + bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; + } + else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) + { + bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; + } + else + { + FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); + LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); + return VFW_E_RUNTIME_ERROR; + } + + needed_size = bmiHeader->biSize; + needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample); + + if (!pDIBImage) + { + *pBufferSize = needed_size; + LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); + return S_OK; + } + + if (needed_size < *pBufferSize) + { + ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize); + LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); + return E_FAIL; + } + *pBufferSize = needed_size; + + memcpy(pDIBImage, bmiHeader, bmiHeader->biSize); + IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr); + memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample)); + + LeaveCriticalSection(&pVMR9->renderer.filter.csFilter); + return S_OK; +} + +static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + CopyRect(pTargetRect,&pVMR9->target_rect); + return S_OK; +} + +static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + AM_MEDIA_TYPE *pmt; + + TRACE("(%p/%p)\n", pVMR9, This); + + pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent; + if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) { + return (VIDEOINFOHEADER*)pmt->pbFormat; + } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) { + static VIDEOINFOHEADER vih; + VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat; + memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER)); + memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER)); + return &vih; + } else { + ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype)); + return NULL; + } +} + +static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This); + + return S_OK; +} + +static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This); + + return S_OK; +} + +static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + + pVMR9->source_rect.left = 0; + pVMR9->source_rect.top = 0; + pVMR9->source_rect.right = pVMR9->VideoWidth; + pVMR9->source_rect.bottom = pVMR9->VideoHeight; + + return S_OK; +} + +static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This) +{ + RECT rect; + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + + if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect)) + return E_FAIL; + + pVMR9->target_rect.left = 0; + pVMR9->target_rect.top = 0; + pVMR9->target_rect.right = rect.right; + pVMR9->target_rect.bottom = rect.bottom; + + return S_OK; +} + +static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + CopyRect(&pVMR9->source_rect,pSourceRect); + return S_OK; +} + +static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect) +{ + VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This); + CopyRect(&pVMR9->target_rect,pTargetRect); + return S_OK; +} + +static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = { + VMR9_GetSourceRect, + VMR9_GetStaticImage, + VMR9_GetTargetRect, + VMR9_GetVideoFormat, + VMR9_IsDefaultSourceRect, + VMR9_IsDefaultTargetRect, + VMR9_SetDefaultSourceRect, + VMR9_SetDefaultTargetRect, + VMR9_SetSourceRect, + VMR9_SetTargetRect +}; + +static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) +{ + VMR9Impl *This = impl_from_inner_IUnknown(iface); + TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); + + if (This->bAggregatable) + This->bUnkOuterValid = TRUE; + + *ppv = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = &This->IUnknown_inner; + else if (IsEqualIID(riid, &IID_IVideoWindow)) + *ppv = &This->baseControlWindow.IVideoWindow_iface; + else if (IsEqualIID(riid, &IID_IBasicVideo)) + *ppv = &This->baseControlVideo.IBasicVideo_iface; + else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags)) + *ppv = &This->IAMFilterMiscFlags_iface; + else if (IsEqualIID(riid, &IID_IVMRFilterConfig9)) + *ppv = &This->IVMRFilterConfig9_iface; + else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless) + *ppv = &This->IVMRWindowlessControl9_iface; + else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless) + *ppv = &This->IVMRSurfaceAllocatorNotify9_iface; + else + { + HRESULT hr; + hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); + if (SUCCEEDED(hr)) + return hr; + } + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + else if (IsEqualIID(riid, &IID_IBasicVideo2)) + FIXME("No interface for IID_IBasicVideo2\n"); + else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9)) + ; + else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9)) + ; + else if (IsEqualIID(riid, &IID_IMediaPosition)) + FIXME("No interface for IID_IMediaPosition\n"); + else if (IsEqualIID(riid, &IID_IQualProp)) + FIXME("No interface for IID_IQualProp\n"); + else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9)) + FIXME("No interface for IID_IVMRAspectRatioControl9\n"); + else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9)) + FIXME("No interface for IID_IVMRDeinterlaceControl9\n"); + else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9)) + FIXME("No interface for IID_IVMRMixerBitmap9\n"); + else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9)) + FIXME("No interface for IID_IVMRMonitorConfig9\n"); + else if (IsEqualIID(riid, &IID_IVMRMixerControl9)) + FIXME("No interface for IID_IVMRMixerControl9\n"); + else + FIXME("No interface for %s\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface) +{ + VMR9Impl *This = impl_from_inner_IUnknown(iface); + ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface); + + TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); + + return refCount; +} + +static ULONG WINAPI VMR9Inner_Release(IUnknown * iface) +{ + VMR9Impl *This = impl_from_inner_IUnknown(iface); + ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface); + + TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); + + if (!refCount) + { + TRACE("Destroying\n"); + BaseControlWindow_Destroy(&This->baseControlWindow); + CloseHandle(This->hD3d9); + + if (This->allocator) + IVMRSurfaceAllocatorEx9_Release(This->allocator); + if (This->presenter) + IVMRImagePresenter9_Release(This->presenter); + + This->num_surfaces = 0; + if (This->allocator_d3d9_dev) + { + IDirect3DDevice9_Release(This->allocator_d3d9_dev); + This->allocator_d3d9_dev = NULL; + } + + CoTaskMemFree(This); + } + return refCount; +} + +static const IUnknownVtbl IInner_VTable = +{ + VMR9Inner_QueryInterface, + VMR9Inner_AddRef, + VMR9Inner_Release +}; + +static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) +{ + VMR9Impl *This = (VMR9Impl *)iface; + + if (This->bAggregatable) + This->bUnkOuterValid = TRUE; + + if (This->outer_unk) + { + if (This->bAggregatable) + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); + + if (IsEqualIID(riid, &IID_IUnknown)) + { + HRESULT hr; + + IUnknown_AddRef(&This->IUnknown_inner); + hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); + IUnknown_Release(&This->IUnknown_inner); + This->bAggregatable = TRUE; + return hr; + } + + *ppv = NULL; + return E_NOINTERFACE; + } + + return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); +} + +static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface) +{ + VMR9Impl *This = (VMR9Impl *)iface; + LONG ret; + + if (This->outer_unk && This->bUnkOuterValid) + ret = IUnknown_AddRef(This->outer_unk); + else + ret = IUnknown_AddRef(&This->IUnknown_inner); + + TRACE("(%p)->AddRef from %d\n", iface, ret - 1); + + return ret; +} + +static ULONG WINAPI VMR9_Release(IBaseFilter * iface) +{ + VMR9Impl *This = (VMR9Impl *)iface; + LONG ret; + + if (This->outer_unk && This->bUnkOuterValid) + ret = IUnknown_Release(This->outer_unk); + else + ret = IUnknown_Release(&This->IUnknown_inner); + + TRACE("(%p)->Release from %d\n", iface, ret + 1); + + if (ret) + return ret; + return 0; +} + +static const IBaseFilterVtbl VMR9_Vtbl = +{ + VMR9_QueryInterface, + VMR9_AddRef, + VMR9_Release, + BaseFilterImpl_GetClassID, + BaseRendererImpl_Stop, + BaseRendererImpl_Pause, + BaseRendererImpl_Run, + BaseRendererImpl_GetState, + BaseRendererImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + BaseRendererImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo +}; + +/*** IUnknown methods ***/ +static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj) +{ + VMR9Impl *This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); +} + +static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) +{ + VMR9Impl *This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) +{ + VMR9Impl *This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); +} + +static const IVideoWindowVtbl IVideoWindow_VTable = +{ + Videowindow_QueryInterface, + Videowindow_AddRef, + Videowindow_Release, + BaseControlWindowImpl_GetTypeInfoCount, + BaseControlWindowImpl_GetTypeInfo, + BaseControlWindowImpl_GetIDsOfNames, + BaseControlWindowImpl_Invoke, + BaseControlWindowImpl_put_Caption, + BaseControlWindowImpl_get_Caption, + BaseControlWindowImpl_put_WindowStyle, + BaseControlWindowImpl_get_WindowStyle, + BaseControlWindowImpl_put_WindowStyleEx, + BaseControlWindowImpl_get_WindowStyleEx, + BaseControlWindowImpl_put_AutoShow, + BaseControlWindowImpl_get_AutoShow, + BaseControlWindowImpl_put_WindowState, + BaseControlWindowImpl_get_WindowState, + BaseControlWindowImpl_put_BackgroundPalette, + BaseControlWindowImpl_get_BackgroundPalette, + BaseControlWindowImpl_put_Visible, + BaseControlWindowImpl_get_Visible, + BaseControlWindowImpl_put_Left, + BaseControlWindowImpl_get_Left, + BaseControlWindowImpl_put_Width, + BaseControlWindowImpl_get_Width, + BaseControlWindowImpl_put_Top, + BaseControlWindowImpl_get_Top, + BaseControlWindowImpl_put_Height, + BaseControlWindowImpl_get_Height, + BaseControlWindowImpl_put_Owner, + BaseControlWindowImpl_get_Owner, + BaseControlWindowImpl_put_MessageDrain, + BaseControlWindowImpl_get_MessageDrain, + BaseControlWindowImpl_get_BorderColor, + BaseControlWindowImpl_put_BorderColor, + BaseControlWindowImpl_get_FullScreenMode, + BaseControlWindowImpl_put_FullScreenMode, + BaseControlWindowImpl_SetWindowForeground, + BaseControlWindowImpl_NotifyOwnerMessage, + BaseControlWindowImpl_SetWindowPosition, + BaseControlWindowImpl_GetWindowPosition, + BaseControlWindowImpl_GetMinIdealImageSize, + BaseControlWindowImpl_GetMaxIdealImageSize, + BaseControlWindowImpl_GetRestorePosition, + BaseControlWindowImpl_HideCursor, + BaseControlWindowImpl_IsCursorHidden +}; + +/*** IUnknown methods ***/ +static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj) +{ + VMR9Impl *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj); +} + +static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) +{ + VMR9Impl *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) +{ + VMR9Impl *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); +} + +static const IBasicVideoVtbl IBasicVideo_VTable = +{ + Basicvideo_QueryInterface, + Basicvideo_AddRef, + Basicvideo_Release, + BaseControlVideoImpl_GetTypeInfoCount, + BaseControlVideoImpl_GetTypeInfo, + BaseControlVideoImpl_GetIDsOfNames, + BaseControlVideoImpl_Invoke, + BaseControlVideoImpl_get_AvgTimePerFrame, + BaseControlVideoImpl_get_BitRate, + BaseControlVideoImpl_get_BitErrorRate, + BaseControlVideoImpl_get_VideoWidth, + BaseControlVideoImpl_get_VideoHeight, + BaseControlVideoImpl_put_SourceLeft, + BaseControlVideoImpl_get_SourceLeft, + BaseControlVideoImpl_put_SourceWidth, + BaseControlVideoImpl_get_SourceWidth, + BaseControlVideoImpl_put_SourceTop, + BaseControlVideoImpl_get_SourceTop, + BaseControlVideoImpl_put_SourceHeight, + BaseControlVideoImpl_get_SourceHeight, + BaseControlVideoImpl_put_DestinationLeft, + BaseControlVideoImpl_get_DestinationLeft, + BaseControlVideoImpl_put_DestinationWidth, + BaseControlVideoImpl_get_DestinationWidth, + BaseControlVideoImpl_put_DestinationTop, + BaseControlVideoImpl_get_DestinationTop, + BaseControlVideoImpl_put_DestinationHeight, + BaseControlVideoImpl_get_DestinationHeight, + BaseControlVideoImpl_SetSourcePosition, + BaseControlVideoImpl_GetSourcePosition, + BaseControlVideoImpl_SetDefaultSourcePosition, + BaseControlVideoImpl_SetDestinationPosition, + BaseControlVideoImpl_GetDestinationPosition, + BaseControlVideoImpl_SetDefaultDestinationPosition, + BaseControlVideoImpl_GetVideoSize, + BaseControlVideoImpl_GetVideoPaletteEntries, + BaseControlVideoImpl_GetCurrentImage, + BaseControlVideoImpl_IsUsingDefaultSource, + BaseControlVideoImpl_IsUsingDefaultDestination +}; + +static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) { + VMR9Impl *This = impl_from_IAMFilterMiscFlags(iface); + return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); +} + +static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) { + VMR9Impl *This = impl_from_IAMFilterMiscFlags(iface); + return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) { + VMR9Impl *This = impl_from_IAMFilterMiscFlags(iface); + return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) { + return AM_FILTER_MISC_FLAGS_IS_RENDERER; +} + +static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = { + AMFilterMiscFlags_QueryInterface, + AMFilterMiscFlags_AddRef, + AMFilterMiscFlags_Release, + AMFilterMiscFlags_GetMiscFlags +}; + +static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); +} + +static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); +} + +static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + FIXME("(%p/%p)->(%u) stub\n", iface, This, max); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + FIXME("(%p/%p)->(%p) stub\n", iface, This, max); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode) +{ + HRESULT hr = S_OK; + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + TRACE("(%p/%p)->(%u)\n", iface, This, mode); + + EnterCriticalSection(&This->renderer.filter.csFilter); + if (This->mode) + { + LeaveCriticalSection(&This->renderer.filter.csFilter); + return VFW_E_WRONG_STATE; + } + + if (This->allocator) + IVMRSurfaceAllocatorEx9_Release(This->allocator); + if (This->presenter) + IVMRImagePresenter9_Release(This->presenter); + + This->allocator = NULL; + This->presenter = NULL; + + switch (mode) + { + case VMR9Mode_Windowed: + case VMR9Mode_Windowless: + This->allocator_is_ex = 0; + This->cookie = ~0; + + hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter); + if (SUCCEEDED(hr)) + hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator); + if (FAILED(hr)) + { + ERR("Unable to find Presenter interface\n"); + IVMRImagePresenter9_Release(This->presenter); + This->allocator = NULL; + This->presenter = NULL; + } + else + hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface); + break; + case VMR9Mode_Renderless: + break; + default: + LeaveCriticalSection(&This->renderer.filter.csFilter); + return E_INVALIDARG; + } + + This->mode = mode; + LeaveCriticalSection(&This->renderer.filter.csFilter); + return hr; +} + +static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode) +{ + VMR9Impl *This = impl_from_IVMRFilterConfig9(iface); + + TRACE("(%p/%p)->(%p) stub\n", iface, This, mode); + if (!mode) + return E_POINTER; + + if (This->mode) + *mode = This->mode; + else + *mode = VMR9Mode_Windowed; + + return S_OK; +} + +static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl = +{ + VMR9FilterConfig_QueryInterface, + VMR9FilterConfig_AddRef, + VMR9FilterConfig_Release, + VMR9FilterConfig_SetImageCompositor, + VMR9FilterConfig_SetNumberOfStreams, + VMR9FilterConfig_GetNumberOfStreams, + VMR9FilterConfig_SetRenderingPrefs, + VMR9FilterConfig_GetRenderingPrefs, + VMR9FilterConfig_SetRenderingMode, + VMR9FilterConfig_GetRenderingMode +}; + +static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); +} + +static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); +} + +static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight); + + if (!width || !height || !arwidth || !arheight) + { + ERR("Got no pointer\n"); + return E_POINTER; + } + + *width = This->bmiheader.biWidth; + *height = This->bmiheader.biHeight; + *arwidth = This->bmiheader.biWidth; + *arheight = This->bmiheader.biHeight; + + return S_OK; +} + +static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest); + + EnterCriticalSection(&This->renderer.filter.csFilter); + + if (source) + This->source_rect = *source; + if (dest) + { + This->target_rect = *dest; + if (This->baseControlWindow.baseWindow.hWnd) + { + FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest->left, dest->top, dest->right, dest->bottom); + SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left, + dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW); + } + } + + LeaveCriticalSection(&This->renderer.filter.csFilter); + + return S_OK; +} + +static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + if (source) + *source = This->source_rect; + + if (dest) + *dest = This->target_rect; + + FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest); + return S_OK; +} + +static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + TRACE("(%p/%p)->(%p)\n", iface, This, hwnd); + + EnterCriticalSection(&This->renderer.filter.csFilter); + This->hWndClippingWindow = hwnd; + VMR9_maybe_init(This, FALSE); + if (!hwnd) + IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie); + LeaveCriticalSection(&This->renderer.filter.csFilter); + return S_OK; +} + +static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + HRESULT hr; + + FIXME("(%p/%p)->(...) semi-stub\n", iface, This); + + EnterCriticalSection(&This->renderer.filter.csFilter); + if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd) + { + ERR("Not handling changing windows yet!!!\n"); + LeaveCriticalSection(&This->renderer.filter.csFilter); + return S_OK; + } + + if (!This->allocator_d3d9_dev) + { + ERR("No d3d9 device!\n"); + LeaveCriticalSection(&This->renderer.filter.csFilter); + return VFW_E_WRONG_STATE; + } + + /* Windowless extension */ + hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL); + LeaveCriticalSection(&This->renderer.filter.csFilter); + + return hr; +} + +static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color) +{ + VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl = +{ + VMR9WindowlessControl_QueryInterface, + VMR9WindowlessControl_AddRef, + VMR9WindowlessControl_Release, + VMR9WindowlessControl_GetNativeVideoSize, + VMR9WindowlessControl_GetMinIdealVideoSize, + VMR9WindowlessControl_GetMaxIdealVideoSize, + VMR9WindowlessControl_SetVideoPosition, + VMR9WindowlessControl_GetVideoPosition, + VMR9WindowlessControl_GetAspectRatioMode, + VMR9WindowlessControl_SetAspectRatioMode, + VMR9WindowlessControl_SetVideoClippingWindow, + VMR9WindowlessControl_RepaintVideo, + VMR9WindowlessControl_DisplayModeChanged, + VMR9WindowlessControl_GetCurrentImage, + VMR9WindowlessControl_SetBorderColor, + VMR9WindowlessControl_GetBorderColor +}; + +static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv); +} + +static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface); +} + +static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + return VMR9_Release(&This->renderer.filter.IBaseFilter_iface); +} + +static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + + /* FIXME: This code is not tested!!! */ + FIXME("(%p/%p)->(...) stub\n", iface, This); + This->cookie = id; + + if (This->presenter) + return VFW_E_WRONG_STATE; + + if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter))) + return E_NOINTERFACE; + + if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator))) + This->allocator_is_ex = 1; + else + { + This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc; + IVMRSurfaceAllocator9_AddRef(alloc); + This->allocator_is_ex = 0; + } + + return S_OK; +} + +static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + + FIXME("(%p/%p)->(...) semi-stub\n", iface, This); + if (This->allocator_d3d9_dev) + IDirect3DDevice9_Release(This->allocator_d3d9_dev); + This->allocator_d3d9_dev = device; + IDirect3DDevice9_AddRef(This->allocator_d3d9_dev); + This->allocator_mon = monitor; + + return S_OK; +} + +static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + + FIXME("(%p/%p)->(...) semi-stub\n", iface, This); + if (This->allocator_d3d9_dev) + IDirect3DDevice9_Release(This->allocator_d3d9_dev); + This->allocator_d3d9_dev = device; + IDirect3DDevice9_AddRef(This->allocator_d3d9_dev); + This->allocator_mon = monitor; + + return S_OK; +} + +static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + DWORD i; + HRESULT hr = S_OK; + + FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface); + + if (!allocinfo || !numbuffers || !surface) + return E_POINTER; + + if (!*numbuffers || *numbuffers < allocinfo->MinBuffers) + { + ERR("Invalid number of buffers?\n"); + return E_INVALIDARG; + } + + if (!This->allocator_d3d9_dev) + { + ERR("No direct3d device when requested to allocate a surface!\n"); + return VFW_E_WRONG_STATE; + } + + if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface) + { + ERR("Creating offscreen surface\n"); + for (i = 0; i < *numbuffers; ++i) + { + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, + allocinfo->Format, allocinfo->Pool, &surface[i], NULL); + if (FAILED(hr)) + break; + } + } + else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface) + { + TRACE("Creating texture surface\n"); + for (i = 0; i < *numbuffers; ++i) + { + IDirect3DTexture9 *texture; + + hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0, + allocinfo->Format, allocinfo->Pool, &texture, NULL); + if (FAILED(hr)) + break; + IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]); + IDirect3DTexture9_Release(texture); + } + } + else + { + FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags); + return E_NOTIMPL; + } + + if (i >= allocinfo->MinBuffers) + { + hr = S_OK; + *numbuffers = i; + } + else + { + for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]); + *numbuffers = 0; + } + return hr; +} + +static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2) +{ + VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface); + + FIXME("(%p/%p)->(...) stub\n", iface, This); + return E_NOTIMPL; +} + +static const IVMRSurfaceAllocatorNotify9Vtbl IVMRSurfaceAllocatorNotify9_Vtbl = +{ + VMR9SurfaceAllocatorNotify_QueryInterface, + VMR9SurfaceAllocatorNotify_AddRef, + VMR9SurfaceAllocatorNotify_Release, + VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator, + VMR9SurfaceAllocatorNotify_SetD3DDevice, + VMR9SurfaceAllocatorNotify_ChangeD3DDevice, + VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper, + VMR9SurfaceAllocatorNotify_NotifyEvent +}; + +HRESULT VMR9Impl_create(IUnknown * outer_unk, LPVOID * ppv) +{ + HRESULT hr; + VMR9Impl * pVMR9; + + TRACE("(%p, %p)\n", outer_unk, ppv); + + *ppv = NULL; + + pVMR9 = CoTaskMemAlloc(sizeof(VMR9Impl)); + + pVMR9->hD3d9 = LoadLibraryA("d3d9.dll"); + if (!pVMR9->hD3d9 ) + { + WARN("Could not load d3d9.dll\n"); + CoTaskMemFree(pVMR9); + return VFW_E_DDRAW_CAPS_NOT_SUITABLE; + } + + pVMR9->outer_unk = outer_unk; + pVMR9->bUnkOuterValid = FALSE; + pVMR9->bAggregatable = FALSE; + pVMR9->IUnknown_inner.lpVtbl = &IInner_VTable; + pVMR9->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl; + + pVMR9->mode = 0; + pVMR9->allocator_d3d9_dev = NULL; + pVMR9->allocator_mon= NULL; + pVMR9->num_surfaces = pVMR9->cur_surface = 0; + pVMR9->allocator = NULL; + pVMR9->presenter = NULL; + pVMR9->hWndClippingWindow = NULL; + pVMR9->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl; + pVMR9->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl; + pVMR9->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &IVMRSurfaceAllocatorNotify9_Vtbl; + + hr = BaseRenderer_Init(&pVMR9->renderer, &VMR9_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9, (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable); + if (FAILED(hr)) + goto fail; + + hr = BaseControlWindow_Init(&pVMR9->baseControlWindow, &IVideoWindow_VTable, &pVMR9->renderer.filter, &pVMR9->renderer.filter.csFilter, &pVMR9->renderer.pInputPin->pin, &renderer_BaseWindowFuncTable); + if (FAILED(hr)) + goto fail; + + hr = BaseControlVideo_Init(&pVMR9->baseControlVideo, &IBasicVideo_VTable, &pVMR9->renderer.filter, &pVMR9->renderer.filter.csFilter, &pVMR9->renderer.pInputPin->pin, &renderer_BaseControlVideoFuncTable); + if (FAILED(hr)) + goto fail; + + *ppv = (LPVOID)pVMR9; + ZeroMemory(&pVMR9->source_rect, sizeof(RECT)); + ZeroMemory(&pVMR9->target_rect, sizeof(RECT)); + TRACE("Created at %p\n", pVMR9); + return hr; + +fail: + BaseRendererImpl_Release(&pVMR9->renderer.filter.IBaseFilter_iface); + CloseHandle(pVMR9->hD3d9); + CoTaskMemFree(pVMR9); + return hr; +} + + + +static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); + TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); + + *ppv = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface); + else if (IsEqualIID(riid, &IID_IVMRImagePresenter9)) + *ppv = &This->IVMRImagePresenter9_iface; + else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9)) + *ppv = &This->IVMRSurfaceAllocatorEx9_iface; + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + FIXME("No interface for %s\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); + ULONG refCount = InterlockedIncrement(&This->refCount); + + TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1); + + return refCount; +} + +static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); + ULONG refCount = InterlockedDecrement(&This->refCount); + + TRACE("(%p)->() Release from %d\n", iface, refCount + 1); + + if (!refCount) + { + DWORD i; + TRACE("Destroying\n"); + CloseHandle(This->ack); + IDirect3D9_Release(This->d3d9_ptr); + + TRACE("Number of surfaces: %u\n", This->num_surfaces); + for (i = 0; i < This->num_surfaces; ++i) + { + IDirect3DSurface9 *surface = This->d3d9_surfaces[i]; + TRACE("Releasing surface %p\n", surface); + if (surface) + IDirect3DSurface9_Release(surface); + } + + CoTaskMemFree(This->d3d9_surfaces); + This->d3d9_surfaces = NULL; + This->num_surfaces = 0; + if (This->d3d9_vertex) + { + IDirect3DVertexBuffer9_Release(This->d3d9_vertex); + This->d3d9_vertex = NULL; + } + CoTaskMemFree(This); + return 0; + } + return refCount; +} + +static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); + + TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9); + return S_OK; +} + +static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); + + TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9); + return S_OK; +} + +#define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1) +struct VERTEX { float x, y, z, rhw, u, v; }; + +static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface) +{ + IDirect3DTexture9 *texture = NULL; + HRESULT hr; + + hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF); + if (FAILED(hr)) + { + FIXME("SetFVF: %08x\n", hr); + return hr; + } + + hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX)); + if (FAILED(hr)) + { + FIXME("SetStreamSource: %08x\n", hr); + return hr; + } + + hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture); + if (FAILED(hr)) + { + FIXME("IDirect3DSurface9_GetContainer failed\n"); + return hr; + } + hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture); + IDirect3DTexture9_Release(texture); + if (FAILED(hr)) + { + FIXME("SetTexture: %08x\n", hr); + return hr; + } + + hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2); + if (FAILED(hr)) + { + FIXME("DrawPrimitive: %08x\n", hr); + return hr; + } + + return S_OK; +} + +static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface) +{ + HRESULT hr; + IDirect3DSurface9 *target = NULL; + RECT target_rect; + + hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target); + if (FAILED(hr)) + { + ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr); + return hr; + } + + target_rect = This->pVMR9->target_rect; + target_rect.right -= target_rect.left; + target_rect.bottom -= target_rect.top; + target_rect.left = target_rect.top = 0; + + /* Flip */ + target_rect.top = target_rect.bottom; + target_rect.bottom = 0; + + hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR); + if (FAILED(hr)) + ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr); + IDirect3DSurface9_Release(target); + + return hr; +} + +static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface); + HRESULT hr; + RECT output; + BOOL render = FALSE; + + TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9); + GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output); + TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom); + + /* This might happen if we don't have active focus (eg on a different virtual desktop) */ + if (!This->d3d9_dev) + return S_OK; + + /* Display image here */ + hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + if (FAILED(hr)) + FIXME("hr: %08x\n", hr); + hr = IDirect3DDevice9_BeginScene(This->d3d9_dev); + if (SUCCEEDED(hr)) + { + if (This->d3d9_vertex) + hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf); + else + hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf); + render = SUCCEEDED(hr); + } + else + FIXME("BeginScene: %08x\n", hr); + hr = IDirect3DDevice9_EndScene(This->d3d9_dev); + if (render && SUCCEEDED(hr)) + { + hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL); + if (FAILED(hr)) + FIXME("Presenting image: %08x\n", hr); + } + + return S_OK; +} + +static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter = +{ + VMR9_ImagePresenter_QueryInterface, + VMR9_ImagePresenter_AddRef, + VMR9_ImagePresenter_Release, + VMR9_ImagePresenter_StartPresenting, + VMR9_ImagePresenter_StopPresenting, + VMR9_ImagePresenter_PresentImage +}; + +static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv); +} + +static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface); +} + +static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface); +} + +static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo) +{ + D3DCAPS9 caps; + UINT width, height; + HRESULT hr; + + if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)) + /* Only needed for texture surfaces */ + return S_OK; + + hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps); + if (FAILED(hr)) + return hr; + + if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) + { + width = allocinfo->dwWidth; + height = allocinfo->dwHeight; + } + else + { + width = height = 1; + while (width < allocinfo->dwWidth) + width *= 2; + + while (height < allocinfo->dwHeight) + height *= 2; + FIXME("NPOW2 support missing, not using proper surfaces!\n"); + } + + if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) + { + if (height > width) + width = height; + else + height = width; + FIXME("Square texture support required..\n"); + } + + hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL); + if (FAILED(hr)) + { + ERR("Couldn't create vertex buffer: %08x\n", hr); + return hr; + } + + This->reset = TRUE; + allocinfo->dwHeight = height; + allocinfo->dwWidth = width; + + return hr; +} + +static DWORD WINAPI MessageLoop(LPVOID lpParameter) +{ + MSG msg; + BOOL fGotMessage; + VMR9DefaultAllocatorPresenterImpl *This = lpParameter; + + TRACE("Starting message loop\n"); + + if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow))) + { + FIXME("Failed to prepare window\n"); + return FALSE; + } + + SetEvent(This->ack); + while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + TRACE("End of message loop\n"); + + return 0; +} + +static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out) +{ + UINT d3d9_adapter; + HMONITOR mon; + + mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL); + if (!mon) + d3d9_adapter = 0; + else + { + for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter) + { + if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter)) + break; + } + if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9)) + d3d9_adapter = 0; + } + if (mon_out) + *mon_out = mon; + return d3d9_adapter; +} + +static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers) +{ + D3DPRESENT_PARAMETERS d3dpp; + DWORD d3d9_adapter; + HRESULT hr; + + TRACE("(%p)->()\n", This); + + This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid); + if (!This->hWndThread) + return FALSE; + + WaitForSingleObject(This->ack, INFINITE); + + if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE; + + /* Obtain a monitor and d3d9 device */ + d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon); + + /* Now try to create the d3d9 device */ + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top; + d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left; + + hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); + if (FAILED(hr)) + { + ERR("Could not create device: %08x\n", hr); + BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow); + return FALSE; + } + IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon); + + This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *)); + ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *)); + + hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info); + if (FAILED(hr)) + ERR("Setting allocation settings failed: %08x\n", hr); + + if (SUCCEEDED(hr)) + { + hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces); + if (FAILED(hr)) + ERR("Allocating surfaces failed: %08x\n", hr); + } + + if (FAILED(hr)) + { + IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie); + BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow); + return FALSE; + } + + This->num_surfaces = *numbuffers; + + return TRUE; +} + +static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow) + { + ERR("No window set\n"); + return VFW_E_WRONG_STATE; + } + + This->info = *allocinfo; + + if (!CreateRenderingWindow(This, allocinfo, numbuffers)) + { + ERR("Failed to create rendering window, expect no output!\n"); + return VFW_E_WRONG_STATE; + } + + return S_OK; +} + +static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) + { + return S_OK; + } + + SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0); + PostThreadMessageW(This->tid, WM_QUIT, 0, 0); + WaitForSingleObject(This->hWndThread, INFINITE); + This->hWndThread = NULL; + BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow); + + return S_OK; +} + +/* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */ +static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This) +{ + struct VERTEX t_vert[4]; + UINT width, height; + unsigned int i; + void *bits = NULL; + D3DPRESENT_PARAMETERS d3dpp; + HRESULT hr; + + if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) + { + ERR("No window\n"); + return E_FAIL; + } + + if (!This->d3d9_surfaces || !This->reset) + return S_OK; + + This->reset = FALSE; + TRACE("RESETTING\n"); + if (This->d3d9_vertex) + { + IDirect3DVertexBuffer9_Release(This->d3d9_vertex); + This->d3d9_vertex = NULL; + } + + for (i = 0; i < This->num_surfaces; ++i) + { + IDirect3DSurface9 *surface = This->d3d9_surfaces[i]; + TRACE("Releasing surface %p\n", surface); + if (surface) + IDirect3DSurface9_Release(surface); + } + ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces); + + /* Now try to create the d3d9 device */ + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + if (This->d3d9_dev) + IDirect3DDevice9_Release(This->d3d9_dev); + This->d3d9_dev = NULL; + hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); + if (FAILED(hr)) + { + hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); + if (FAILED(hr)) + { + ERR("--> Creating device: %08x\n", hr); + return S_OK; + } + } + IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon); + + IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces); + + This->reset = FALSE; + + if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface)) + return S_OK; + + hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, + This->info.Pool, &This->d3d9_vertex, NULL); + + width = This->info.dwWidth; + height = This->info.dwHeight; + + for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i) + { + if (i % 2) + { + t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f; + t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width; + } + else + { + t_vert[i].x = -0.5f; + t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width; + } + + if (i % 4 < 2) + { + t_vert[i].y = -0.5f; + t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height; + } + else + { + t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f; + t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height; + } + t_vert[i].z = 0.0f; + t_vert[i].rhw = 1.0f; + } + + FIXME("Vertex rectangle:\n"); + FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y); + FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y); + FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v); + FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v); + + IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0); + memcpy(bits, t_vert, sizeof(t_vert)); + IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex); + + return S_OK; +} + +static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + /* Update everything first, this is needed because the surface might be destroyed in the reset */ + if (!This->d3d9_dev) + { + TRACE("Device has left me!\n"); + return E_FAIL; + } + + VMR9_SurfaceAllocator_UpdateDeviceReset(This); + + if (surfaceindex >= This->num_surfaces) + { + ERR("surfaceindex is greater than num_surfaces\n"); + return E_FAIL; + } + *surface = This->d3d9_surfaces[surfaceindex]; + IDirect3DSurface9_AddRef(*surface); + + return S_OK; +} + +static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify) +{ + VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface); + + TRACE("(%p/%p)->(...)\n", iface, This); + + /* No AddRef taken here or the base VMR9 filter would never be destroied */ + This->SurfaceAllocatorNotify = allocnotify; + return S_OK; +} + +static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator = +{ + VMR9_SurfaceAllocator_QueryInterface, + VMR9_SurfaceAllocator_AddRef, + VMR9_SurfaceAllocator_Release, + VMR9_SurfaceAllocator_InitializeDevice, + VMR9_SurfaceAllocator_TerminateDevice, + VMR9_SurfaceAllocator_GetSurface, + VMR9_SurfaceAllocator_AdviseNotify, + NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */ +}; + +static IDirect3D9 *init_d3d9(HMODULE d3d9_handle) +{ + IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion); + + d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9"); + if (!d3d9_create) return NULL; + + return d3d9_create(D3D_SDK_VERSION); +} + +static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv) +{ + HRESULT hr = S_OK; + int i; + VMR9DefaultAllocatorPresenterImpl* This; + + This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl)); + if (!This) + return E_OUTOFMEMORY; + + This->d3d9_ptr = init_d3d9(parent->hD3d9); + if (!This->d3d9_ptr) + { + WARN("Could not initialize d3d9.dll\n"); + CoTaskMemFree(This); + return VFW_E_DDRAW_CAPS_NOT_SUITABLE; + } + + i = 0; + do + { + D3DDISPLAYMODE mode; + + hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode); + } while (FAILED(hr)); + if (FAILED(hr)) + ERR("HR: %08x\n", hr); + if (hr == D3DERR_NOTAVAILABLE) + { + ERR("Format not supported\n"); + IDirect3D9_Release(This->d3d9_ptr); + CoTaskMemFree(This); + return VFW_E_DDRAW_CAPS_NOT_SUITABLE; + } + + This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter; + This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator; + + This->refCount = 1; + This->pVMR9 = parent; + This->d3d9_surfaces = NULL; + This->d3d9_dev = NULL; + This->hMon = 0; + This->d3d9_vertex = NULL; + This->num_surfaces = 0; + This->hWndThread = NULL; + This->ack = CreateEventW(NULL, 0, 0, NULL); + This->SurfaceAllocatorNotify = NULL; + This->reset = FALSE; + + *ppv = This; + return S_OK; +} diff --git a/dll/directx/quartz/waveparser.c b/dll/directx/quartz/waveparser.c index fed18e16637..f39a38a26d7 100644 --- a/dll/directx/quartz/waveparser.c +++ b/dll/directx/quartz/waveparser.c @@ -19,7 +19,6 @@ */ #include "quartz_private.h" -#include "control_private.h" #include "pin.h" //#include "uuids.h" @@ -49,6 +48,16 @@ typedef struct WAVEParserImpl DWORD dwLength; } WAVEParserImpl; +static inline WAVEParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) +{ + return CONTAINING_RECORD(iface, WAVEParserImpl, Parser.sourceSeeking.IMediaSeeking_iface); +} + +static inline WAVEParserImpl *impl_from_IBaseFilter( IBaseFilter *iface ) +{ + return CONTAINING_RECORD(iface, WAVEParserImpl, Parser.filter.IBaseFilter_iface); +} + static LONGLONG bytepos_to_duration(WAVEParserImpl *This, LONGLONG bytepos) { LONGLONG duration = BYTES_FROM_MEDIATIME(bytepos - This->StartOfFile); @@ -94,7 +103,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR return S_OK; } - pOutputPin = (Parser_OutputPin *)This->Parser.ppPins[1]; + pOutputPin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1]); if (SUCCEEDED(hr)) hr = IMemAllocator_GetBuffer(pin->pAlloc, &newsample, NULL, NULL, 0); @@ -132,7 +141,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR IMediaSample_SetTime(pSample, &tAviStart, &tAviStop); - hr = OutputPin_SendSample(&pOutputPin->pin, pSample); + hr = BaseOutputPinImpl_Deliver(&pOutputPin->pin, pSample); if (hr != S_OK && hr != S_FALSE && hr != VFW_E_WRONG_STATE) ERR("Error sending sample (%x)\n", hr); else if (hr != S_OK) @@ -140,7 +149,7 @@ static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample, DWORD_PTR This->Parser.pInputPin->rtCurrent = tStart; } - if (tStop >= This->EndOfFile || (bytepos_to_duration(This, tStop) >= This->Parser.mediaSeeking.llStop) || hr == VFW_E_NOT_CONNECTED) + if (tStop >= This->EndOfFile || (bytepos_to_duration(This, tStop) >= This->Parser.sourceSeeking.llStop) || hr == VFW_E_NOT_CONNECTED) { unsigned int i; @@ -184,14 +193,14 @@ static HRESULT WAVEParser_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt) return S_FALSE; } -static HRESULT WAVEParserImpl_seek(IBaseFilter *iface) +static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface) { - WAVEParserImpl *This = (WAVEParserImpl *)iface; + WAVEParserImpl *This = impl_from_IMediaSeeking(iface); PullPin *pPin = This->Parser.pInputPin; IPin *victim = NULL; LONGLONG newpos, curpos, endpos, bytepos; - newpos = This->Parser.mediaSeeking.llCurrent; + newpos = This->Parser.sourceSeeking.llCurrent; curpos = bytepos_to_duration(This, pPin->rtCurrent); endpos = bytepos_to_duration(This, This->EndOfFile); bytepos = duration_to_bytepos(This, newpos); @@ -211,10 +220,10 @@ static HRESULT WAVEParserImpl_seek(IBaseFilter *iface) TRACE("Moving sound to %08u bytes!\n", (DWORD)BYTES_FROM_MEDIATIME(bytepos)); EnterCriticalSection(&pPin->thread_lock); - IPin_BeginFlush((IPin *)pPin); + IPin_BeginFlush(&pPin->pin.IPin_iface); /* Make sure this is done while stopped, BeginFlush takes care of this */ - EnterCriticalSection(&This->Parser.csFilter); + EnterCriticalSection(&This->Parser.filter.csFilter); IPin_ConnectedTo(This->Parser.ppPins[1], &victim); if (victim) { @@ -223,11 +232,11 @@ static HRESULT WAVEParserImpl_seek(IBaseFilter *iface) } pPin->rtStart = pPin->rtCurrent = bytepos; - ((Parser_OutputPin *)This->Parser.ppPins[1])->dwSamplesProcessed = 0; - LeaveCriticalSection(&This->Parser.csFilter); + unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1])->dwSamplesProcessed = 0; + LeaveCriticalSection(&This->Parser.filter.csFilter); TRACE("Done flushing\n"); - IPin_EndFlush((IPin *)pPin); + IPin_EndFlush(&pPin->pin.IPin_iface); LeaveCriticalSection(&pPin->thread_lock); return S_OK; @@ -235,18 +244,18 @@ static HRESULT WAVEParserImpl_seek(IBaseFilter *iface) static HRESULT WAVEParser_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props) { - PullPin *This = (PullPin *)iface; + PullPin *This = impl_PullPin_from_IPin(iface); HRESULT hr; RIFFLIST list; RIFFCHUNK chunk; LONGLONG pos = 0; /* in bytes */ PIN_INFO piOutput; AM_MEDIA_TYPE amt; - WAVEParserImpl * pWAVEParser = (WAVEParserImpl *)This->pin.pinInfo.pFilter; + WAVEParserImpl * pWAVEParser = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); LONGLONG length, avail; piOutput.dir = PINDIR_OUTPUT; - piOutput.pFilter = (IBaseFilter *)This; + piOutput.pFilter = &pWAVEParser->Parser.filter.IBaseFilter_iface; lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0])); hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(list), (BYTE *)&list); @@ -319,9 +328,9 @@ static HRESULT WAVEParser_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, props, &amt); CoTaskMemFree(amt.pbFormat); - pWAVEParser->Parser.mediaSeeking.llCurrent = 0; - pWAVEParser->Parser.mediaSeeking.llStop = pWAVEParser->Parser.mediaSeeking.llDuration = bytepos_to_duration(pWAVEParser, pWAVEParser->EndOfFile); - TRACE("Duration: %u seconds\n", (DWORD)(pWAVEParser->Parser.mediaSeeking.llDuration / (LONGLONG)10000000)); + pWAVEParser->Parser.sourceSeeking.llCurrent = 0; + pWAVEParser->Parser.sourceSeeking.llStop = pWAVEParser->Parser.sourceSeeking.llDuration = bytepos_to_duration(pWAVEParser, pWAVEParser->EndOfFile); + TRACE("Duration: %u seconds\n", (DWORD)(pWAVEParser->Parser.sourceSeeking.llDuration / (LONGLONG)10000000)); This->rtStop = pWAVEParser->EndOfFile; This->rtStart = pWAVEParser->StartOfFile; @@ -362,7 +371,7 @@ static HRESULT WAVEParser_first_request(LPVOID iface) LONGLONG rtSampleStart = pin->rtNext; /* Add 4 for the next header, which should hopefully work */ LONGLONG rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(sample)); - Parser_OutputPin *outpin = (Parser_OutputPin *)This->Parser.ppPins[1]; + Parser_OutputPin *outpin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1]); if (rtSampleStop > pin->rtStop) rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(pin->rtStop), pin->cbAlign)); diff --git a/dll/opengl/glu32/CMakeLists.txt b/dll/opengl/glu32/CMakeLists.txt index 6892dc062f8..0801b3c09bd 100644 --- a/dll/opengl/glu32/CMakeLists.txt +++ b/dll/opengl/glu32/CMakeLists.txt @@ -1,21 +1,18 @@ +set_cpp(WITH_RUNTIME) + include_directories(BEFORE include src/include src/libnurbs/internals src/libnurbs/interface - src/libnurbs/nurbtess -) + src/libnurbs/nurbtess) add_definitions( -DBUILD_GLU32 -DNDEBUG -DLIBRARYBUILD - -DRESOLVE_3D_TEXTURE_SUPPORT -) - -#this library uses C++ -# set_cpp() + -DRESOLVE_3D_TEXTURE_SUPPORT) # we must use our own spec file spec2def(glu32.dll glu32.spec ADD_IMPORTLIB) @@ -117,8 +114,6 @@ add_library(glu32 SHARED ${SOURCE}) set_module_type(glu32 win32dll) if(NOT MSVC) -#FIXME: we really need a standard C++ library - target_link_libraries(glu32 -lsupc++ -lgcc) add_compile_flags("-Wno-error=write-strings") endif() diff --git a/dll/opengl/mesa/src/gallium/targets/libgl-gdi/CMakeLists.txt b/dll/opengl/mesa/src/gallium/targets/libgl-gdi/CMakeLists.txt index bbcadbf13d0..e4cabe040e5 100644 --- a/dll/opengl/mesa/src/gallium/targets/libgl-gdi/CMakeLists.txt +++ b/dll/opengl/mesa/src/gallium/targets/libgl-gdi/CMakeLists.txt @@ -1,11 +1,9 @@ -# we link against C++ static libs -set_cpp() +set_cpp(WITH_STL) include_directories( ../../state_trackers/wgl - ../../winsys/sw -) + ../../winsys/sw) add_definitions(-DWIN32_LEAN_AND_MEAN) @@ -16,21 +14,20 @@ list(APPEND SOURCE # and gallium is kind enough to provide good def files for both MSVC/mingw-w64 and mingw32 if(MSVC OR (ARCH STREQUAL "amd64")) list(APPEND SOURCE ../../state_trackers/wgl/opengl32.def) -else() +else() list(APPEND SOURCE ../../state_trackers/wgl/opengl32.mingw.def) endif() add_library(mesa32 SHARED ${SOURCE}) -target_link_libraries(mesa32 +target_link_libraries(mesa32 gallium_wgl gallium_ws_gdi mesa_glapi mesa_core gallium_softpipe gallium_core - mesa_glsl -) + mesa_glsl) set_module_type(mesa32 win32dll) @@ -42,4 +39,3 @@ endif() add_dependencies(mesa32 psdk) add_cd_file(TARGET mesa32 DESTINATION reactos/system32 FOR all) - \ No newline at end of file diff --git a/dll/opengl/mesa/src/glsl/CMakeLists.txt b/dll/opengl/mesa/src/glsl/CMakeLists.txt index 30e46683ff7..fde70ecf591 100644 --- a/dll/opengl/mesa/src/glsl/CMakeLists.txt +++ b/dll/opengl/mesa/src/glsl/CMakeLists.txt @@ -1,5 +1,5 @@ -set_cpp() +set_cpp(WITH_STL) # From Sconscript include_directories( @@ -18,73 +18,71 @@ list(APPEND SOURCE ../../generated/glsl/builtin_function.cpp # Regular files strtod.c - ralloc.c + ralloc.c glcpp/pp.c ast_expr.cpp - ast_function.cpp - ast_to_hir.cpp - ast_type.cpp - builtin_variables.cpp - glsl_parser_extras.cpp - glsl_types.cpp - glsl_symbol_table.cpp - hir_field_selection.cpp - ir_basic_block.cpp - ir_clone.cpp - ir_constant_expression.cpp - ir.cpp - ir_expression_flattening.cpp - ir_function_can_inline.cpp - ir_function_detect_recursion.cpp - ir_function.cpp - ir_hierarchical_visitor.cpp - ir_hv_accept.cpp - ir_import_prototypes.cpp - ir_print_visitor.cpp - ir_reader.cpp - ir_rvalue_visitor.cpp - ir_set_program_inouts.cpp - ir_validate.cpp - ir_variable_refcount.cpp - linker.cpp - link_functions.cpp - link_uniforms.cpp - loop_analysis.cpp - loop_controls.cpp - loop_unroll.cpp - lower_clip_distance.cpp - lower_discard.cpp - lower_if_to_cond_assign.cpp - lower_instructions.cpp - lower_jumps.cpp - lower_mat_op_to_vec.cpp - lower_noise.cpp - lower_texture_projection.cpp - lower_variable_index_to_cond_assign.cpp - lower_vec_index_to_cond_assign.cpp - lower_vec_index_to_swizzle.cpp - lower_vector.cpp - lower_output_reads.cpp - opt_algebraic.cpp - opt_constant_folding.cpp - opt_constant_propagation.cpp - opt_constant_variable.cpp - opt_copy_propagation.cpp - opt_copy_propagation_elements.cpp - opt_dead_code.cpp - opt_dead_code_local.cpp - opt_dead_functions.cpp - opt_discard_simplification.cpp - opt_function_inlining.cpp - opt_if_simplification.cpp - opt_noop_swizzle.cpp - opt_redundant_jumps.cpp - opt_structure_splitting.cpp - opt_swizzle_swizzle.cpp - opt_tree_grafting.cpp - s_expression.cpp) + ast_function.cpp + ast_to_hir.cpp + ast_type.cpp + builtin_variables.cpp + glsl_parser_extras.cpp + glsl_types.cpp + glsl_symbol_table.cpp + hir_field_selection.cpp + ir_basic_block.cpp + ir_clone.cpp + ir_constant_expression.cpp + ir.cpp + ir_expression_flattening.cpp + ir_function_can_inline.cpp + ir_function_detect_recursion.cpp + ir_function.cpp + ir_hierarchical_visitor.cpp + ir_hv_accept.cpp + ir_import_prototypes.cpp + ir_print_visitor.cpp + ir_reader.cpp + ir_rvalue_visitor.cpp + ir_set_program_inouts.cpp + ir_validate.cpp + ir_variable_refcount.cpp + linker.cpp + link_functions.cpp + link_uniforms.cpp + loop_analysis.cpp + loop_controls.cpp + loop_unroll.cpp + lower_clip_distance.cpp + lower_discard.cpp + lower_if_to_cond_assign.cpp + lower_instructions.cpp + lower_jumps.cpp + lower_mat_op_to_vec.cpp + lower_noise.cpp + lower_texture_projection.cpp + lower_variable_index_to_cond_assign.cpp + lower_vec_index_to_cond_assign.cpp + lower_vec_index_to_swizzle.cpp + lower_vector.cpp + lower_output_reads.cpp + opt_algebraic.cpp + opt_constant_folding.cpp + opt_constant_propagation.cpp + opt_constant_variable.cpp + opt_copy_propagation.cpp + opt_copy_propagation_elements.cpp + opt_dead_code.cpp + opt_dead_code_local.cpp + opt_dead_functions.cpp + opt_discard_simplification.cpp + opt_function_inlining.cpp + opt_if_simplification.cpp + opt_noop_swizzle.cpp + opt_redundant_jumps.cpp + opt_structure_splitting.cpp + opt_swizzle_swizzle.cpp + opt_tree_grafting.cpp + s_expression.cpp) -#this is just a helper library, don't include it in the all target +# this is just a helper library, don't include it in the all target add_library(mesa_glsl STATIC EXCLUDE_FROM_ALL ${SOURCE}) - - \ No newline at end of file diff --git a/dll/opengl/mesa/src/mapi/glapi/CMakeLists.txt b/dll/opengl/mesa/src/mapi/glapi/CMakeLists.txt index 06302d149b7..7e68ce97ec1 100644 --- a/dll/opengl/mesa/src/mapi/glapi/CMakeLists.txt +++ b/dll/opengl/mesa/src/mapi/glapi/CMakeLists.txt @@ -4,8 +4,7 @@ add_definitions( -D_GDI32_ # prevent gl* being declared __declspec(dllimport) in MS headers -DBUILD_GL32 # declare gl* as __declspec(dllexport) in Mesa headers -D_GLAPI_NO_EXPORTS # prevent _glapi_* from being declared __declspec(dllimport) - -DKHRONOS_DLL_EXPORTS -) + -DKHRONOS_DLL_EXPORTS) if((ARCH STREQUAL "i386") AND (NOT MSVC)) list(APPEND SOURCE glapi_x86.S) @@ -33,4 +32,4 @@ if(NOT MSVC) add_compile_flags("-Wno-unused-function") endif() -add_library(mesa_glapi STATIC EXCLUDE_FROM_ALL ${SOURCE}) \ No newline at end of file +add_library(mesa_glapi STATIC EXCLUDE_FROM_ALL ${SOURCE}) diff --git a/dll/opengl/mesa/src/mesa/CMakeLists.txt b/dll/opengl/mesa/src/mesa/CMakeLists.txt index 95171831c66..42c3191c8ee 100644 --- a/dll/opengl/mesa/src/mesa/CMakeLists.txt +++ b/dll/opengl/mesa/src/mesa/CMakeLists.txt @@ -1,4 +1,6 @@ +set_cpp(WITH_STL) + add_definitions( -DFEATURE_GL=1 -D_GDI32_ # prevent gl* being declared __declspec(dllimport) in MS headers @@ -12,9 +14,6 @@ include_directories( ../glsl . ../../generated/mesa) - -# This library uses C++ -set_cpp() if((ARCH STREQUAL "i386") AND (NOT MSVC)) list(APPEND SOURCE @@ -296,9 +295,9 @@ list(APPEND SOURCE # drivers/common/driverfuncs.c # drivers/common/meta.c ) - + if(NOT MSVC) add_compile_flags("-Wno-format") endif() -add_library(mesa_core STATIC EXCLUDE_FROM_ALL ${SOURCE}) \ No newline at end of file +add_library(mesa_core STATIC EXCLUDE_FROM_ALL ${SOURCE}) diff --git a/dll/win32/CMakeLists.txt b/dll/win32/CMakeLists.txt index c62f6a38724..2c4fe585926 100644 --- a/dll/win32/CMakeLists.txt +++ b/dll/win32/CMakeLists.txt @@ -93,10 +93,7 @@ add_subdirectory(msftedit) add_subdirectory(msg711.acm) add_subdirectory(msgina) add_subdirectory(msgsm32.acm) -if(NOT MSVC) - #FIXME: msvc build. - add_subdirectory(mshtml) -endif() +add_subdirectory(mshtml) add_subdirectory(msi) add_subdirectory(mshtml.tlb) add_subdirectory(msimg32) @@ -211,6 +208,7 @@ add_subdirectory(uxtheme) add_subdirectory(vbscript) add_subdirectory(vdmdbg) add_subdirectory(version) +add_subdirectory(wbemprox) if(ARCH STREQUAL "i386") add_subdirectory(wdmaud.drv) endif() diff --git a/dll/win32/advapi32/misc/logon.c b/dll/win32/advapi32/misc/logon.c index 8dce3bf47ba..950b425824c 100644 --- a/dll/win32/advapi32/misc/logon.c +++ b/dll/win32/advapi32/misc/logon.c @@ -650,7 +650,7 @@ LogonUserW(LPWSTR lpszUsername, /* Get the user SID from the registry */ if (!GetUserSid (lpszUsername, &UserSid)) { - ERR("SamGetUserSid() failed\n"); + ERR("GetUserSid() failed\n"); return FALSE; } diff --git a/dll/win32/advapi32/sec/sid.c b/dll/win32/advapi32/sec/sid.c index c289010d199..1b950be8cde 100644 --- a/dll/win32/advapi32/sec/sid.c +++ b/dll/win32/advapi32/sec/sid.c @@ -678,7 +678,7 @@ ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR Securi if (SDRevision != SDDL_REVISION_1) { - ERR("Pogram requested unknown SDDL revision %d\n", SDRevision); + ERR("Program requested unknown SDDL revision %d\n", SDRevision); SetLastError(ERROR_UNKNOWN_REVISION); return FALSE; } @@ -698,6 +698,9 @@ ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR Securi return FALSE; wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR)); + if (wstr == NULL) + return FALSE; + if (SecurityInformation & OWNER_SECURITY_INFORMATION) if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) return FALSE; @@ -740,6 +743,12 @@ ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR Securi lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL); *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA); + if (*OutputString == NULL) + { + LocalFree(wstr); + *OutputLen = 0; + return FALSE; + } WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL); LocalFree(wstr); @@ -1786,6 +1795,8 @@ ConvertStringSidToSidA(IN LPCSTR StringSid, { UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0); LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (wStringSid == NULL) + return FALSE; MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len); bRetVal = ConvertStringSidToSidW(wStringSid, sid); HeapFree(GetProcessHeap(), 0, wStringSid); diff --git a/dll/win32/avicap32/avicap32.c b/dll/win32/avicap32/avicap32.c index cb6a94bbc9c..276aaf9c8a1 100644 --- a/dll/win32/avicap32/avicap32.c +++ b/dll/win32/avicap32/avicap32.c @@ -218,21 +218,24 @@ capGetDriverDescriptionW(WORD wDriverIndex, if (dwInfoSize) { Version = HeapAlloc(GetProcessHeap(), 0, dwInfoSize); - - GetFileVersionInfo(szFileName, 0, dwInfoSize, Version); - - if (VerQueryValueW(Version, L"\\", &Ms, &Ls)) + + if (Version != NULL) { - memmove(&FileInfo, Ms, Ls); - swprintf(szVersion, L"Version: %d.%d.%d.%d", - HIWORD(FileInfo.dwFileVersionMS), - LOWORD(FileInfo.dwFileVersionMS), - HIWORD(FileInfo.dwFileVersionLS), - LOWORD(FileInfo.dwFileVersionLS)); + GetFileVersionInfo(szFileName, 0, dwInfoSize, Version); - lstrcpynW(lpszVer, szVersion, cbVer); + if (VerQueryValueW(Version, L"\\", &Ms, &Ls)) + { + memmove(&FileInfo, Ms, Ls); + swprintf(szVersion, L"Version: %d.%d.%d.%d", + HIWORD(FileInfo.dwFileVersionMS), + LOWORD(FileInfo.dwFileVersionMS), + HIWORD(FileInfo.dwFileVersionLS), + LOWORD(FileInfo.dwFileVersionLS)); + + lstrcpynW(lpszVer, szVersion, cbVer); + } + HeapFree(GetProcessHeap(), 0, Version); } - HeapFree(GetProcessHeap(), 0, Version); } } diff --git a/dll/win32/browseui/CMakeLists.txt b/dll/win32/browseui/CMakeLists.txt index 621a37229df..6bdd1f14d6c 100644 --- a/dll/win32/browseui/CMakeLists.txt +++ b/dll/win32/browseui/CMakeLists.txt @@ -1,13 +1,9 @@ -set_cpp() +set_cpp(WITH_RUNTIME) add_definitions( -D__WINESRC__) -if (MSVC) - add_compile_flags("/EHa-") -endif() - remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) @@ -70,4 +66,3 @@ add_importlibs(browseui add_pch(browseui precomp.h) add_cd_file(TARGET browseui DESTINATION reactos/system32 FOR all) - diff --git a/dll/win32/browseui/aclmulti.h b/dll/win32/browseui/aclmulti.h index b9a408b9065..66c740b51b2 100644 --- a/dll/win32/browseui/aclmulti.h +++ b/dll/win32/browseui/aclmulti.h @@ -25,8 +25,8 @@ class CACLMulti : public CComCoClass, public CComObjectRootEx, public IEnumString, - public IACList, - public IObjMgr + public IObjMgr, + public IACList { private: struct ACLMultiSublist diff --git a/dll/win32/browseui/addressband.h b/dll/win32/browseui/addressband.h index c5b44062be2..5e387b7606a 100644 --- a/dll/win32/browseui/addressband.h +++ b/dll/win32/browseui/addressband.h @@ -25,14 +25,14 @@ class CAddressBand : public CComCoClass, public CComObjectRootEx, public IDeskBand, - public IOleCommandTarget, public IObjectWithSite, public IInputObject, + public IPersistStream, + public IOleCommandTarget, + public IServiceProvider, public IWinEventHandler, public IAddressBand, - public IServiceProvider, - public IInputObjectSite, - public IPersistStream + public IInputObjectSite { private: CComPtr fSite; diff --git a/dll/win32/browseui/addresseditbox.h b/dll/win32/browseui/addresseditbox.h index c7208077c3e..e85d040536f 100644 --- a/dll/win32/browseui/addresseditbox.h +++ b/dll/win32/browseui/addresseditbox.h @@ -24,13 +24,13 @@ class CAddressEditBox : public CWindowImpl, public CComCoClass, public CComObjectRootEx, - public IShellService, + public IWinEventHandler, + public IDispatch, public IAddressBand, public IAddressEditBox, - public IWinEventHandler, public IOleCommandTarget, - public IDispatch, - public IPersistStream + public IPersistStream, + public IShellService { private: CContainedWindow fEditWindow; diff --git a/dll/win32/browseui/bandsite.h b/dll/win32/browseui/bandsite.h index cb68f3bae4b..c4b70091ba5 100644 --- a/dll/win32/browseui/bandsite.h +++ b/dll/win32/browseui/bandsite.h @@ -24,15 +24,15 @@ class CBandSiteBase : public CComObjectRootEx, public IBandSite, - public IWinEventHandler, - public IDeskBarClient, - public IOleCommandTarget, - public IInputObject, public IInputObjectSite, - public IServiceProvider, + public IInputObject, + public IDeskBarClient, + public IWinEventHandler, public IPersistStream, public IDropTarget, - public IBandSiteHelper + public IServiceProvider, + public IBandSiteHelper, + public IOleCommandTarget { private: struct BandObject diff --git a/dll/win32/browseui/bandsitemenu.cpp b/dll/win32/browseui/bandsitemenu.cpp index 8a5b353334e..2bab41f705e 100644 --- a/dll/win32/browseui/bandsitemenu.cpp +++ b/dll/win32/browseui/bandsitemenu.cpp @@ -59,6 +59,12 @@ HRESULT STDMETHODCALLTYPE CBandSiteMenu::GetCommandString(UINT_PTR idCmd, UINT u HRESULT STDMETHODCALLTYPE CBandSiteMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { - FIXME("(%p, %p)\n", this, uMsg, wParam, lParam); + FIXME("(%p, %u, %p, %p)\n", this, uMsg, wParam, lParam); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CBandSiteMenu::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) +{ + FIXME("(%p, %u, %p, %p, %p)\n", this, uMsg, wParam, lParam); return E_NOTIMPL; } diff --git a/dll/win32/browseui/bandsitemenu.h b/dll/win32/browseui/bandsitemenu.h index f82b167429e..9388c79fe7a 100644 --- a/dll/win32/browseui/bandsitemenu.h +++ b/dll/win32/browseui/bandsitemenu.h @@ -25,8 +25,8 @@ class CBandSiteMenu : public CComCoClass, public CComObjectRootEx, - public IShellService, - public IContextMenu2 + public IContextMenu3, + public IShellService { public: CBandSiteMenu(); @@ -43,6 +43,9 @@ public: // *** IContextMenu2 methods *** virtual HRESULT STDMETHODCALLTYPE HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam); + // *** IContextMenu3 methods *** + virtual HRESULT STDMETHODCALLTYPE HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult); + DECLARE_REGISTRY_RESOURCEID(IDR_BANDSITEMENU) DECLARE_NOT_AGGREGATABLE(CBandSiteMenu) diff --git a/dll/win32/browseui/brandband.h b/dll/win32/browseui/brandband.h index 483601a3356..d7999c4a495 100644 --- a/dll/win32/browseui/brandband.h +++ b/dll/win32/browseui/brandband.h @@ -28,9 +28,9 @@ class CBrandBand : public IObjectWithSite, public IInputObject, public IPersistStream, - public IWinEventHandler, public IOleCommandTarget, public IServiceProvider, + public IWinEventHandler, public IDispatch { private: diff --git a/dll/win32/browseui/browseui.cpp b/dll/win32/browseui/browseui.cpp index 438f505a0b6..bbc7570ed88 100644 --- a/dll/win32/browseui/browseui.cpp +++ b/dll/win32/browseui/browseui.cpp @@ -36,7 +36,10 @@ OBJECT_ENTRY(CLSID_BandProxy, CBandProxy) OBJECT_ENTRY(CLSID_RebarBandSite, CBandSite) OBJECT_ENTRY(CLSID_BandSiteMenu, CBandSiteMenu) OBJECT_ENTRY(CLSID_BrandBand, CBrandBand) +OBJECT_ENTRY(CLSID_CCommonBrowser, CCommonBrowser) +OBJECT_ENTRY(CLSID_GlobalFolderSettings, CGlobalFolderSettings) OBJECT_ENTRY(CLSID_InternetToolbar, CInternetToolbar) +OBJECT_ENTRY(CLSID_CRegTreeOptions, CRegTreeOptions) END_OBJECT_MAP() CBrowseUIModule gModule; diff --git a/dll/win32/browseui/commonbrowser.cpp b/dll/win32/browseui/commonbrowser.cpp index 7294b7ce408..f409d778296 100644 --- a/dll/win32/browseui/commonbrowser.cpp +++ b/dll/win32/browseui/commonbrowser.cpp @@ -509,13 +509,13 @@ HRESULT STDMETHODCALLTYPE CCommonBrowser::v_CheckZoneCrossing(LPCITEMIDLIST pidl return E_NOTIMPL; } -HRESULT STDMETHODCALLTYPE CCommonBrowser::_PositionViewWindow(HWND *, RECT *) +HRESULT STDMETHODCALLTYPE CCommonBrowser::_PositionViewWindow(HWND, RECT *) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE CCommonBrowser::IEParseDisplayNameEx( - unsigned int, const unsigned short *, DWORD, LPITEMIDLIST *) + UINT, PCWSTR, DWORD, LPITEMIDLIST *) { return E_NOTIMPL; } diff --git a/dll/win32/browseui/commonbrowser.h b/dll/win32/browseui/commonbrowser.h index b60c87034b3..8cd6f9f4530 100644 --- a/dll/win32/browseui/commonbrowser.h +++ b/dll/win32/browseui/commonbrowser.h @@ -21,17 +21,17 @@ #pragma once class CCommonBrowser : - public CComCoClass, + public CComCoClass, public CComObjectRootEx, + public IShellBrowser, + public IBrowserService3, public IServiceProvider, public IOleCommandTarget, - public IBrowserService3, - public IShellBrowser, - public IShellBrowserService, public IDockingWindowSite, public IDockingWindowFrame, public IInputObjectSite, - public IDropTarget + public IDropTarget, + public IShellBrowserService { private: public: @@ -142,8 +142,8 @@ public: virtual HRESULT STDMETHODCALLTYPE v_CheckZoneCrossing(LPCITEMIDLIST pidl); // *** IBrowserService3 methods *** - virtual HRESULT STDMETHODCALLTYPE _PositionViewWindow(HWND *, RECT *); - virtual HRESULT STDMETHODCALLTYPE IEParseDisplayNameEx(unsigned int, const unsigned short *, DWORD, LPITEMIDLIST *); + virtual HRESULT STDMETHODCALLTYPE _PositionViewWindow(HWND, RECT *); + virtual HRESULT STDMETHODCALLTYPE IEParseDisplayNameEx(UINT, PCWSTR, DWORD, LPITEMIDLIST *); // *** IShellBrowser methods *** virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths); @@ -187,6 +187,7 @@ public: virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect); DECLARE_REGISTRY_RESOURCEID(IDR_COMMONBROWSER) + DECLARE_NOT_AGGREGATABLE(CCommonBrowser) DECLARE_PROTECT_FINAL_CONSTRUCT() diff --git a/dll/win32/browseui/globalfoldersettings.h b/dll/win32/browseui/globalfoldersettings.h index e6e5493f2ce..abe476a9024 100644 --- a/dll/win32/browseui/globalfoldersettings.h +++ b/dll/win32/browseui/globalfoldersettings.h @@ -21,7 +21,7 @@ #pragma once class CGlobalFolderSettings : - public CComCoClass, + public CComCoClass, public CComObjectRootEx, public IGlobalFolderSettings { diff --git a/dll/win32/browseui/regtreeoptions.h b/dll/win32/browseui/regtreeoptions.h index 634e5da1df9..eafdd322863 100644 --- a/dll/win32/browseui/regtreeoptions.h +++ b/dll/win32/browseui/regtreeoptions.h @@ -21,7 +21,7 @@ #pragma once class CRegTreeOptions : - public CComCoClass, + public CComCoClass, public CComObjectRootEx, public IRegTreeOptions, public IObjectWithSite diff --git a/dll/win32/getuname/CMakeLists.txt b/dll/win32/getuname/CMakeLists.txt index 47423b2dc2c..f6c0cfc3fae 100644 --- a/dll/win32/getuname/CMakeLists.txt +++ b/dll/win32/getuname/CMakeLists.txt @@ -11,5 +11,5 @@ add_library(getuname SHARED set_module_type(getuname win32dll UNICODE) -add_importlibs(getuname msvcrt kernel32 ntdll) +add_importlibs(getuname user32 msvcrt kernel32 ntdll) add_cd_file(TARGET getuname DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/getuname/getuname.c b/dll/win32/getuname/getuname.c index 2e39ef97ec3..b1f670c4425 100644 --- a/dll/win32/getuname/getuname.c +++ b/dll/win32/getuname/getuname.c @@ -3,17 +3,32 @@ * FILE: dll\win32\getuname\getuname.c * PURPOSE: Main file * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org) + * Baruch Rutman (peterooch at gmail dot com) */ +#include #include +#include + +HINSTANCE hInstance; int WINAPI GetUName(IN WORD wCharCode, OUT LPWSTR lpBuf) { - wcscpy(lpBuf, L"Undefined"); - return 0; + WCHAR szDescription[256]; + int res = LoadStringW(hInstance, wCharCode, szDescription, 256); + if (res != 0) + { + wcscpy(lpBuf, szDescription); + return 0; + } + else + { + wcscpy(lpBuf, L"Undefined"); + return 0; + } } @@ -26,6 +41,7 @@ DllMain(IN HINSTANCE hinstDLL, switch (dwReason) { case DLL_PROCESS_ATTACH: + hInstance = hinstDLL; break; } diff --git a/dll/win32/getuname/getuname.rc b/dll/win32/getuname/getuname.rc index e033ccc792d..ad69a8b3103 100644 --- a/dll/win32/getuname/getuname.rc +++ b/dll/win32/getuname/getuname.rc @@ -5,3 +5,9 @@ #define REACTOS_STR_INTERNAL_NAME "getuname\0" #define REACTOS_STR_ORIGINAL_FILENAME "getuname.dll\0" #include + +//UTF-8 +#pragma code_page(65001) +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif diff --git a/dll/win32/getuname/lang/en-US.rc b/dll/win32/getuname/lang/en-US.rc new file mode 100644 index 00000000000..22e8145bae1 --- /dev/null +++ b/dll/win32/getuname/lang/en-US.rc @@ -0,0 +1,16049 @@ +/* + * PROJECT: Unicode name dll + * FILE: dll\win32\getuname\lang\en-US.rc + * PURPOSE: Unicode Description Strings + * PROGRAMMERS: Baruch Rutman (peterooch at gmail dot com) + */ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +STRINGTABLE DISCARDABLE +BEGIN +/* Autogenerated from http://www.unicode.org/Public/UNIDATA/UnicodeData.txt */ +0 "Null" +1 "Start Of Heading" +2 "Start Of Text" +3 "End Of Text" +4 "End Of Transmission" +5 "Enquiry" +6 "Acknowledge" +7 "Bell" +8 "Backspace" +9 "Character Tabulation" +10 "Line Feed" +11 "Line Tabulation" +12 "Form Feed" +13 "Carriage Return" +14 "Shift Out" +15 "Shift In" +16 "Data Link Escape" +17 "Device Control One" +18 "Device Control Two" +19 "Device Control Three" +20 "Device Control Four" +21 "Negative Acknowledge" +22 "Synchronous Idle" +23 "End Of Transmission Block" +24 "Cancel" +25 "End Of Medium" +26 "Substitute" +27 "Escape" +28 "Information Separator Four" +29 "Information Separator Three" +30 "Information Separator Two" +31 "Information Separator One" +32 "Space" +33 "Exclamation Mark" +34 "Quotation Mark" +35 "Number Sign" +36 "Dollar Sign" +37 "Percent Sign" +38 "Ampersand" +39 "Apostrophe" +40 "Left Parenthesis" +41 "Right Parenthesis" +42 "Asterisk" +43 "Plus Sign" +44 "Comma" +45 "Hyphen-Minus" +46 "Full Stop" +47 "Solidus" +48 "Digit Zero" +49 "Digit One" +50 "Digit Two" +51 "Digit Three" +52 "Digit Four" +53 "Digit Five" +54 "Digit Six" +55 "Digit Seven" +56 "Digit Eight" +57 "Digit Nine" +58 "Colon" +59 "Semicolon" +60 "Less-Than Sign" +61 "Equals Sign" +62 "Greater-Than Sign" +63 "Question Mark" +64 "Commercial At" +65 "Latin Capital Letter A" +66 "Latin Capital Letter B" +67 "Latin Capital Letter C" +68 "Latin Capital Letter D" +69 "Latin Capital Letter E" +70 "Latin Capital Letter F" +71 "Latin Capital Letter G" +72 "Latin Capital Letter H" +73 "Latin Capital Letter I" +74 "Latin Capital Letter J" +75 "Latin Capital Letter K" +76 "Latin Capital Letter L" +77 "Latin Capital Letter M" +78 "Latin Capital Letter N" +79 "Latin Capital Letter O" +80 "Latin Capital Letter P" +81 "Latin Capital Letter Q" +82 "Latin Capital Letter R" +83 "Latin Capital Letter S" +84 "Latin Capital Letter T" +85 "Latin Capital Letter U" +86 "Latin Capital Letter V" +87 "Latin Capital Letter W" +88 "Latin Capital Letter X" +89 "Latin Capital Letter Y" +90 "Latin Capital Letter Z" +91 "Left Square Bracket" +92 "Reverse Solidus" +93 "Right Square Bracket" +94 "Circumflex Accent" +95 "Low Line" +96 "Grave Accent" +97 "Latin Small Letter A" +98 "Latin Small Letter B" +99 "Latin Small Letter C" +100 "Latin Small Letter D" +101 "Latin Small Letter E" +102 "Latin Small Letter F" +103 "Latin Small Letter G" +104 "Latin Small Letter H" +105 "Latin Small Letter I" +106 "Latin Small Letter J" +107 "Latin Small Letter K" +108 "Latin Small Letter L" +109 "Latin Small Letter M" +110 "Latin Small Letter N" +111 "Latin Small Letter O" +112 "Latin Small Letter P" +113 "Latin Small Letter Q" +114 "Latin Small Letter R" +115 "Latin Small Letter S" +116 "Latin Small Letter T" +117 "Latin Small Letter U" +118 "Latin Small Letter V" +119 "Latin Small Letter W" +120 "Latin Small Letter X" +121 "Latin Small Letter Y" +122 "Latin Small Letter Z" +123 "Left Curly Bracket" +124 "Vertical Line" +125 "Right Curly Bracket" +126 "Tilde" +127 "Delete" +130 "Break Permitted Here" +131 "No Break Here" +133 "Next Line" +134 "Start Of Selected Area" +135 "End Of Selected Area" +136 "Character Tabulation Set" +137 "Character Tabulation With Justification" +138 "Line Tabulation Set" +139 "Partial Line Forward" +140 "Partial Line Backward" +141 "Reverse Line Feed" +142 "Single Shift Two" +143 "Single Shift Three" +144 "Device Control String" +145 "Private Use One" +146 "Private Use Two" +147 "Set Transmit State" +148 "Cancel Character" +149 "Message Waiting" +150 "Start Of Guarded Area" +151 "End Of Guarded Area" +152 "Start Of String" +154 "Single Character Introducer" +155 "Control Sequence Introducer" +156 "String Terminator" +157 "Operating System Command" +158 "Privacy Message" +159 "Application Program Command" +160 "No-Break Space" +161 "Inverted Exclamation Mark" +162 "Cent Sign" +163 "Pound Sign" +164 "Currency Sign" +165 "Yen Sign" +166 "Broken Bar" +167 "Section Sign" +168 "Diaeresis" +169 "Copyright Sign" +170 "Feminine Ordinal Indicator" +171 "Left-Pointing Double Angle Quotation Mark" +172 "Not Sign" +173 "Soft Hyphen" +174 "Registered Sign" +175 "Macron" +176 "Degree Sign" +177 "Plus-Minus Sign" +178 "Superscript Two" +179 "Superscript Three" +180 "Acute Accent" +181 "Micro Sign" +182 "Pilcrow Sign" +183 "Middle Dot" +184 "Cedilla" +185 "Superscript One" +186 "Masculine Ordinal Indicator" +187 "Right-Pointing Double Angle Quotation Mark" +188 "Vulgar Fraction One Quarter" +189 "Vulgar Fraction One Half" +190 "Vulgar Fraction Three Quarters" +191 "Inverted Question Mark" +192 "Latin Capital Letter A With Grave" +193 "Latin Capital Letter A With Acute" +194 "Latin Capital Letter A With Circumflex" +195 "Latin Capital Letter A With Tilde" +196 "Latin Capital Letter A With Diaeresis" +197 "Latin Capital Letter A With Ring Above" +198 "Latin Capital Letter Ae" +199 "Latin Capital Letter C With Cedilla" +200 "Latin Capital Letter E With Grave" +201 "Latin Capital Letter E With Acute" +202 "Latin Capital Letter E With Circumflex" +203 "Latin Capital Letter E With Diaeresis" +204 "Latin Capital Letter I With Grave" +205 "Latin Capital Letter I With Acute" +206 "Latin Capital Letter I With Circumflex" +207 "Latin Capital Letter I With Diaeresis" +208 "Latin Capital Letter Eth" +209 "Latin Capital Letter N With Tilde" +210 "Latin Capital Letter O With Grave" +211 "Latin Capital Letter O With Acute" +212 "Latin Capital Letter O With Circumflex" +213 "Latin Capital Letter O With Tilde" +214 "Latin Capital Letter O With Diaeresis" +215 "Multiplication Sign" +216 "Latin Capital Letter O With Stroke" +217 "Latin Capital Letter U With Grave" +218 "Latin Capital Letter U With Acute" +219 "Latin Capital Letter U With Circumflex" +220 "Latin Capital Letter U With Diaeresis" +221 "Latin Capital Letter Y With Acute" +222 "Latin Capital Letter Thorn" +223 "Latin Small Letter Sharp S" +224 "Latin Small Letter A With Grave" +225 "Latin Small Letter A With Acute" +226 "Latin Small Letter A With Circumflex" +227 "Latin Small Letter A With Tilde" +228 "Latin Small Letter A With Diaeresis" +229 "Latin Small Letter A With Ring Above" +230 "Latin Small Letter Ae" +231 "Latin Small Letter C With Cedilla" +232 "Latin Small Letter E With Grave" +233 "Latin Small Letter E With Acute" +234 "Latin Small Letter E With Circumflex" +235 "Latin Small Letter E With Diaeresis" +236 "Latin Small Letter I With Grave" +237 "Latin Small Letter I With Acute" +238 "Latin Small Letter I With Circumflex" +239 "Latin Small Letter I With Diaeresis" +240 "Latin Small Letter Eth" +241 "Latin Small Letter N With Tilde" +242 "Latin Small Letter O With Grave" +243 "Latin Small Letter O With Acute" +244 "Latin Small Letter O With Circumflex" +245 "Latin Small Letter O With Tilde" +246 "Latin Small Letter O With Diaeresis" +247 "Division Sign" +248 "Latin Small Letter O With Stroke" +249 "Latin Small Letter U With Grave" +250 "Latin Small Letter U With Acute" +251 "Latin Small Letter U With Circumflex" +252 "Latin Small Letter U With Diaeresis" +253 "Latin Small Letter Y With Acute" +254 "Latin Small Letter Thorn" +255 "Latin Small Letter Y With Diaeresis" +256 "Latin Capital Letter A With Macron" +257 "Latin Small Letter A With Macron" +258 "Latin Capital Letter A With Breve" +259 "Latin Small Letter A With Breve" +260 "Latin Capital Letter A With Ogonek" +261 "Latin Small Letter A With Ogonek" +262 "Latin Capital Letter C With Acute" +263 "Latin Small Letter C With Acute" +264 "Latin Capital Letter C With Circumflex" +265 "Latin Small Letter C With Circumflex" +266 "Latin Capital Letter C With Dot Above" +267 "Latin Small Letter C With Dot Above" +268 "Latin Capital Letter C With Caron" +269 "Latin Small Letter C With Caron" +270 "Latin Capital Letter D With Caron" +271 "Latin Small Letter D With Caron" +272 "Latin Capital Letter D With Stroke" +273 "Latin Small Letter D With Stroke" +274 "Latin Capital Letter E With Macron" +275 "Latin Small Letter E With Macron" +276 "Latin Capital Letter E With Breve" +277 "Latin Small Letter E With Breve" +278 "Latin Capital Letter E With Dot Above" +279 "Latin Small Letter E With Dot Above" +280 "Latin Capital Letter E With Ogonek" +281 "Latin Small Letter E With Ogonek" +282 "Latin Capital Letter E With Caron" +283 "Latin Small Letter E With Caron" +284 "Latin Capital Letter G With Circumflex" +285 "Latin Small Letter G With Circumflex" +286 "Latin Capital Letter G With Breve" +287 "Latin Small Letter G With Breve" +288 "Latin Capital Letter G With Dot Above" +289 "Latin Small Letter G With Dot Above" +290 "Latin Capital Letter G With Cedilla" +291 "Latin Small Letter G With Cedilla" +292 "Latin Capital Letter H With Circumflex" +293 "Latin Small Letter H With Circumflex" +294 "Latin Capital Letter H With Stroke" +295 "Latin Small Letter H With Stroke" +296 "Latin Capital Letter I With Tilde" +297 "Latin Small Letter I With Tilde" +298 "Latin Capital Letter I With Macron" +299 "Latin Small Letter I With Macron" +300 "Latin Capital Letter I With Breve" +301 "Latin Small Letter I With Breve" +302 "Latin Capital Letter I With Ogonek" +303 "Latin Small Letter I With Ogonek" +304 "Latin Capital Letter I With Dot Above" +305 "Latin Small Letter Dotless I" +306 "Latin Capital Ligature Ij" +307 "Latin Small Ligature Ij" +308 "Latin Capital Letter J With Circumflex" +309 "Latin Small Letter J With Circumflex" +310 "Latin Capital Letter K With Cedilla" +311 "Latin Small Letter K With Cedilla" +312 "Latin Small Letter Kra" +313 "Latin Capital Letter L With Acute" +314 "Latin Small Letter L With Acute" +315 "Latin Capital Letter L With Cedilla" +316 "Latin Small Letter L With Cedilla" +317 "Latin Capital Letter L With Caron" +318 "Latin Small Letter L With Caron" +319 "Latin Capital Letter L With Middle Dot" +320 "Latin Small Letter L With Middle Dot" +321 "Latin Capital Letter L With Stroke" +322 "Latin Small Letter L With Stroke" +323 "Latin Capital Letter N With Acute" +324 "Latin Small Letter N With Acute" +325 "Latin Capital Letter N With Cedilla" +326 "Latin Small Letter N With Cedilla" +327 "Latin Capital Letter N With Caron" +328 "Latin Small Letter N With Caron" +329 "Latin Small Letter N Preceded By Apostrophe" +330 "Latin Capital Letter Eng" +331 "Latin Small Letter Eng" +332 "Latin Capital Letter O With Macron" +333 "Latin Small Letter O With Macron" +334 "Latin Capital Letter O With Breve" +335 "Latin Small Letter O With Breve" +336 "Latin Capital Letter O With Double Acute" +337 "Latin Small Letter O With Double Acute" +338 "Latin Capital Ligature Oe" +339 "Latin Small Ligature Oe" +340 "Latin Capital Letter R With Acute" +341 "Latin Small Letter R With Acute" +342 "Latin Capital Letter R With Cedilla" +343 "Latin Small Letter R With Cedilla" +344 "Latin Capital Letter R With Caron" +345 "Latin Small Letter R With Caron" +346 "Latin Capital Letter S With Acute" +347 "Latin Small Letter S With Acute" +348 "Latin Capital Letter S With Circumflex" +349 "Latin Small Letter S With Circumflex" +350 "Latin Capital Letter S With Cedilla" +351 "Latin Small Letter S With Cedilla" +352 "Latin Capital Letter S With Caron" +353 "Latin Small Letter S With Caron" +354 "Latin Capital Letter T With Cedilla" +355 "Latin Small Letter T With Cedilla" +356 "Latin Capital Letter T With Caron" +357 "Latin Small Letter T With Caron" +358 "Latin Capital Letter T With Stroke" +359 "Latin Small Letter T With Stroke" +360 "Latin Capital Letter U With Tilde" +361 "Latin Small Letter U With Tilde" +362 "Latin Capital Letter U With Macron" +363 "Latin Small Letter U With Macron" +364 "Latin Capital Letter U With Breve" +365 "Latin Small Letter U With Breve" +366 "Latin Capital Letter U With Ring Above" +367 "Latin Small Letter U With Ring Above" +368 "Latin Capital Letter U With Double Acute" +369 "Latin Small Letter U With Double Acute" +370 "Latin Capital Letter U With Ogonek" +371 "Latin Small Letter U With Ogonek" +372 "Latin Capital Letter W With Circumflex" +373 "Latin Small Letter W With Circumflex" +374 "Latin Capital Letter Y With Circumflex" +375 "Latin Small Letter Y With Circumflex" +376 "Latin Capital Letter Y With Diaeresis" +377 "Latin Capital Letter Z With Acute" +378 "Latin Small Letter Z With Acute" +379 "Latin Capital Letter Z With Dot Above" +380 "Latin Small Letter Z With Dot Above" +381 "Latin Capital Letter Z With Caron" +382 "Latin Small Letter Z With Caron" +383 "Latin Small Letter Long S" +384 "Latin Small Letter B With Stroke" +385 "Latin Capital Letter B With Hook" +386 "Latin Capital Letter B With Topbar" +387 "Latin Small Letter B With Topbar" +388 "Latin Capital Letter Tone Six" +389 "Latin Small Letter Tone Six" +390 "Latin Capital Letter Open O" +391 "Latin Capital Letter C With Hook" +392 "Latin Small Letter C With Hook" +393 "Latin Capital Letter African D" +394 "Latin Capital Letter D With Hook" +395 "Latin Capital Letter D With Topbar" +396 "Latin Small Letter D With Topbar" +397 "Latin Small Letter Turned Delta" +398 "Latin Capital Letter Reversed E" +399 "Latin Capital Letter Schwa" +400 "Latin Capital Letter Open E" +401 "Latin Capital Letter F With Hook" +402 "Latin Small Letter F With Hook" +403 "Latin Capital Letter G With Hook" +404 "Latin Capital Letter Gamma" +405 "Latin Small Letter Hv" +406 "Latin Capital Letter Iota" +407 "Latin Capital Letter I With Stroke" +408 "Latin Capital Letter K With Hook" +409 "Latin Small Letter K With Hook" +410 "Latin Small Letter L With Bar" +411 "Latin Small Letter Lambda With Stroke" +412 "Latin Capital Letter Turned M" +413 "Latin Capital Letter N With Left Hook" +414 "Latin Small Letter N With Long Right Leg" +415 "Latin Capital Letter O With Middle Tilde" +416 "Latin Capital Letter O With Horn" +417 "Latin Small Letter O With Horn" +418 "Latin Capital Letter Oi" +419 "Latin Small Letter Oi" +420 "Latin Capital Letter P With Hook" +421 "Latin Small Letter P With Hook" +422 "Latin Letter Yr" +423 "Latin Capital Letter Tone Two" +424 "Latin Small Letter Tone Two" +425 "Latin Capital Letter Esh" +426 "Latin Letter Reversed Esh Loop" +427 "Latin Small Letter T With Palatal Hook" +428 "Latin Capital Letter T With Hook" +429 "Latin Small Letter T With Hook" +430 "Latin Capital Letter T With Retroflex Hook" +431 "Latin Capital Letter U With Horn" +432 "Latin Small Letter U With Horn" +433 "Latin Capital Letter Upsilon" +434 "Latin Capital Letter V With Hook" +435 "Latin Capital Letter Y With Hook" +436 "Latin Small Letter Y With Hook" +437 "Latin Capital Letter Z With Stroke" +438 "Latin Small Letter Z With Stroke" +439 "Latin Capital Letter Ezh" +440 "Latin Capital Letter Ezh Reversed" +441 "Latin Small Letter Ezh Reversed" +442 "Latin Small Letter Ezh With Tail" +443 "Latin Letter Two With Stroke" +444 "Latin Capital Letter Tone Five" +445 "Latin Small Letter Tone Five" +446 "Latin Letter Inverted Glottal Stop With Stroke" +447 "Latin Letter Wynn" +448 "Latin Letter Dental Click" +449 "Latin Letter Lateral Click" +450 "Latin Letter Alveolar Click" +451 "Latin Letter Retroflex Click" +452 "Latin Capital Letter Dz With Caron" +453 "Latin Capital Letter D With Small Letter Z With Caron" +454 "Latin Small Letter Dz With Caron" +455 "Latin Capital Letter Lj" +456 "Latin Capital Letter L With Small Letter J" +457 "Latin Small Letter Lj" +458 "Latin Capital Letter Nj" +459 "Latin Capital Letter N With Small Letter J" +460 "Latin Small Letter Nj" +461 "Latin Capital Letter A With Caron" +462 "Latin Small Letter A With Caron" +463 "Latin Capital Letter I With Caron" +464 "Latin Small Letter I With Caron" +465 "Latin Capital Letter O With Caron" +466 "Latin Small Letter O With Caron" +467 "Latin Capital Letter U With Caron" +468 "Latin Small Letter U With Caron" +469 "Latin Capital Letter U With Diaeresis And Macron" +470 "Latin Small Letter U With Diaeresis And Macron" +471 "Latin Capital Letter U With Diaeresis And Acute" +472 "Latin Small Letter U With Diaeresis And Acute" +473 "Latin Capital Letter U With Diaeresis And Caron" +474 "Latin Small Letter U With Diaeresis And Caron" +475 "Latin Capital Letter U With Diaeresis And Grave" +476 "Latin Small Letter U With Diaeresis And Grave" +477 "Latin Small Letter Turned E" +478 "Latin Capital Letter A With Diaeresis And Macron" +479 "Latin Small Letter A With Diaeresis And Macron" +480 "Latin Capital Letter A With Dot Above And Macron" +481 "Latin Small Letter A With Dot Above And Macron" +482 "Latin Capital Letter Ae With Macron" +483 "Latin Small Letter Ae With Macron" +484 "Latin Capital Letter G With Stroke" +485 "Latin Small Letter G With Stroke" +486 "Latin Capital Letter G With Caron" +487 "Latin Small Letter G With Caron" +488 "Latin Capital Letter K With Caron" +489 "Latin Small Letter K With Caron" +490 "Latin Capital Letter O With Ogonek" +491 "Latin Small Letter O With Ogonek" +492 "Latin Capital Letter O With Ogonek And Macron" +493 "Latin Small Letter O With Ogonek And Macron" +494 "Latin Capital Letter Ezh With Caron" +495 "Latin Small Letter Ezh With Caron" +496 "Latin Small Letter J With Caron" +497 "Latin Capital Letter Dz" +498 "Latin Capital Letter D With Small Letter Z" +499 "Latin Small Letter Dz" +500 "Latin Capital Letter G With Acute" +501 "Latin Small Letter G With Acute" +502 "Latin Capital Letter Hwair" +503 "Latin Capital Letter Wynn" +504 "Latin Capital Letter N With Grave" +505 "Latin Small Letter N With Grave" +506 "Latin Capital Letter A With Ring Above And Acute" +507 "Latin Small Letter A With Ring Above And Acute" +508 "Latin Capital Letter Ae With Acute" +509 "Latin Small Letter Ae With Acute" +510 "Latin Capital Letter O With Stroke And Acute" +511 "Latin Small Letter O With Stroke And Acute" +512 "Latin Capital Letter A With Double Grave" +513 "Latin Small Letter A With Double Grave" +514 "Latin Capital Letter A With Inverted Breve" +515 "Latin Small Letter A With Inverted Breve" +516 "Latin Capital Letter E With Double Grave" +517 "Latin Small Letter E With Double Grave" +518 "Latin Capital Letter E With Inverted Breve" +519 "Latin Small Letter E With Inverted Breve" +520 "Latin Capital Letter I With Double Grave" +521 "Latin Small Letter I With Double Grave" +522 "Latin Capital Letter I With Inverted Breve" +523 "Latin Small Letter I With Inverted Breve" +524 "Latin Capital Letter O With Double Grave" +525 "Latin Small Letter O With Double Grave" +526 "Latin Capital Letter O With Inverted Breve" +527 "Latin Small Letter O With Inverted Breve" +528 "Latin Capital Letter R With Double Grave" +529 "Latin Small Letter R With Double Grave" +530 "Latin Capital Letter R With Inverted Breve" +531 "Latin Small Letter R With Inverted Breve" +532 "Latin Capital Letter U With Double Grave" +533 "Latin Small Letter U With Double Grave" +534 "Latin Capital Letter U With Inverted Breve" +535 "Latin Small Letter U With Inverted Breve" +536 "Latin Capital Letter S With Comma Below" +537 "Latin Small Letter S With Comma Below" +538 "Latin Capital Letter T With Comma Below" +539 "Latin Small Letter T With Comma Below" +540 "Latin Capital Letter Yogh" +541 "Latin Small Letter Yogh" +542 "Latin Capital Letter H With Caron" +543 "Latin Small Letter H With Caron" +544 "Latin Capital Letter N With Long Right Leg" +545 "Latin Small Letter D With Curl" +546 "Latin Capital Letter Ou" +547 "Latin Small Letter Ou" +548 "Latin Capital Letter Z With Hook" +549 "Latin Small Letter Z With Hook" +550 "Latin Capital Letter A With Dot Above" +551 "Latin Small Letter A With Dot Above" +552 "Latin Capital Letter E With Cedilla" +553 "Latin Small Letter E With Cedilla" +554 "Latin Capital Letter O With Diaeresis And Macron" +555 "Latin Small Letter O With Diaeresis And Macron" +556 "Latin Capital Letter O With Tilde And Macron" +557 "Latin Small Letter O With Tilde And Macron" +558 "Latin Capital Letter O With Dot Above" +559 "Latin Small Letter O With Dot Above" +560 "Latin Capital Letter O With Dot Above And Macron" +561 "Latin Small Letter O With Dot Above And Macron" +562 "Latin Capital Letter Y With Macron" +563 "Latin Small Letter Y With Macron" +564 "Latin Small Letter L With Curl" +565 "Latin Small Letter N With Curl" +566 "Latin Small Letter T With Curl" +567 "Latin Small Letter Dotless J" +568 "Latin Small Letter Db Digraph" +569 "Latin Small Letter Qp Digraph" +570 "Latin Capital Letter A With Stroke" +571 "Latin Capital Letter C With Stroke" +572 "Latin Small Letter C With Stroke" +573 "Latin Capital Letter L With Bar" +574 "Latin Capital Letter T With Diagonal Stroke" +575 "Latin Small Letter S With Swash Tail" +576 "Latin Small Letter Z With Swash Tail" +577 "Latin Capital Letter Glottal Stop" +578 "Latin Small Letter Glottal Stop" +579 "Latin Capital Letter B With Stroke" +580 "Latin Capital Letter U Bar" +581 "Latin Capital Letter Turned V" +582 "Latin Capital Letter E With Stroke" +583 "Latin Small Letter E With Stroke" +584 "Latin Capital Letter J With Stroke" +585 "Latin Small Letter J With Stroke" +586 "Latin Capital Letter Small Q With Hook Tail" +587 "Latin Small Letter Q With Hook Tail" +588 "Latin Capital Letter R With Stroke" +589 "Latin Small Letter R With Stroke" +590 "Latin Capital Letter Y With Stroke" +591 "Latin Small Letter Y With Stroke" +592 "Latin Small Letter Turned A" +593 "Latin Small Letter Alpha" +594 "Latin Small Letter Turned Alpha" +595 "Latin Small Letter B With Hook" +596 "Latin Small Letter Open O" +597 "Latin Small Letter C With Curl" +598 "Latin Small Letter D With Tail" +599 "Latin Small Letter D With Hook" +600 "Latin Small Letter Reversed E" +601 "Latin Small Letter Schwa" +602 "Latin Small Letter Schwa With Hook" +603 "Latin Small Letter Open E" +604 "Latin Small Letter Reversed Open E" +605 "Latin Small Letter Reversed Open E With Hook" +606 "Latin Small Letter Closed Reversed Open E" +607 "Latin Small Letter Dotless J With Stroke" +608 "Latin Small Letter G With Hook" +609 "Latin Small Letter Script G" +610 "Latin Letter Small Capital G" +611 "Latin Small Letter Gamma" +612 "Latin Small Letter Rams Horn" +613 "Latin Small Letter Turned H" +614 "Latin Small Letter H With Hook" +615 "Latin Small Letter Heng With Hook" +616 "Latin Small Letter I With Stroke" +617 "Latin Small Letter Iota" +618 "Latin Letter Small Capital I" +619 "Latin Small Letter L With Middle Tilde" +620 "Latin Small Letter L With Belt" +621 "Latin Small Letter L With Retroflex Hook" +622 "Latin Small Letter Lezh" +623 "Latin Small Letter Turned M" +624 "Latin Small Letter Turned M With Long Leg" +625 "Latin Small Letter M With Hook" +626 "Latin Small Letter N With Left Hook" +627 "Latin Small Letter N With Retroflex Hook" +628 "Latin Letter Small Capital N" +629 "Latin Small Letter Barred O" +630 "Latin Letter Small Capital Oe" +631 "Latin Small Letter Closed Omega" +632 "Latin Small Letter Phi" +633 "Latin Small Letter Turned R" +634 "Latin Small Letter Turned R With Long Leg" +635 "Latin Small Letter Turned R With Hook" +636 "Latin Small Letter R With Long Leg" +637 "Latin Small Letter R With Tail" +638 "Latin Small Letter R With Fishhook" +639 "Latin Small Letter Reversed R With Fishhook" +640 "Latin Letter Small Capital R" +641 "Latin Letter Small Capital Inverted R" +642 "Latin Small Letter S With Hook" +643 "Latin Small Letter Esh" +644 "Latin Small Letter Dotless J With Stroke And Hook" +645 "Latin Small Letter Squat Reversed Esh" +646 "Latin Small Letter Esh With Curl" +647 "Latin Small Letter Turned T" +648 "Latin Small Letter T With Retroflex Hook" +649 "Latin Small Letter U Bar" +650 "Latin Small Letter Upsilon" +651 "Latin Small Letter V With Hook" +652 "Latin Small Letter Turned V" +653 "Latin Small Letter Turned W" +654 "Latin Small Letter Turned Y" +655 "Latin Letter Small Capital Y" +656 "Latin Small Letter Z With Retroflex Hook" +657 "Latin Small Letter Z With Curl" +658 "Latin Small Letter Ezh" +659 "Latin Small Letter Ezh With Curl" +660 "Latin Letter Glottal Stop" +661 "Latin Letter Pharyngeal Voiced Fricative" +662 "Latin Letter Inverted Glottal Stop" +663 "Latin Letter Stretched C" +664 "Latin Letter Bilabial Click" +665 "Latin Letter Small Capital B" +666 "Latin Small Letter Closed Open E" +667 "Latin Letter Small Capital G With Hook" +668 "Latin Letter Small Capital H" +669 "Latin Small Letter J With Crossed-Tail" +670 "Latin Small Letter Turned K" +671 "Latin Letter Small Capital L" +672 "Latin Small Letter Q With Hook" +673 "Latin Letter Glottal Stop With Stroke" +674 "Latin Letter Reversed Glottal Stop With Stroke" +675 "Latin Small Letter Dz Digraph" +676 "Latin Small Letter Dezh Digraph" +677 "Latin Small Letter Dz Digraph With Curl" +678 "Latin Small Letter Ts Digraph" +679 "Latin Small Letter Tesh Digraph" +680 "Latin Small Letter Tc Digraph With Curl" +681 "Latin Small Letter Feng Digraph" +682 "Latin Small Letter Ls Digraph" +683 "Latin Small Letter Lz Digraph" +684 "Latin Letter Bilabial Percussive" +685 "Latin Letter Bidental Percussive" +686 "Latin Small Letter Turned H With Fishhook" +687 "Latin Small Letter Turned H With Fishhook And Tail" +688 "Modifier Letter Small H" +689 "Modifier Letter Small H With Hook" +690 "Modifier Letter Small J" +691 "Modifier Letter Small R" +692 "Modifier Letter Small Turned R" +693 "Modifier Letter Small Turned R With Hook" +694 "Modifier Letter Small Capital Inverted R" +695 "Modifier Letter Small W" +696 "Modifier Letter Small Y" +697 "Modifier Letter Prime" +698 "Modifier Letter Double Prime" +699 "Modifier Letter Turned Comma" +700 "Modifier Letter Apostrophe" +701 "Modifier Letter Reversed Comma" +702 "Modifier Letter Right Half Ring" +703 "Modifier Letter Left Half Ring" +704 "Modifier Letter Glottal Stop" +705 "Modifier Letter Reversed Glottal Stop" +706 "Modifier Letter Left Arrowhead" +707 "Modifier Letter Right Arrowhead" +708 "Modifier Letter Up Arrowhead" +709 "Modifier Letter Down Arrowhead" +710 "Modifier Letter Circumflex Accent" +711 "Caron" +712 "Modifier Letter Vertical Line" +713 "Modifier Letter Macron" +714 "Modifier Letter Acute Accent" +715 "Modifier Letter Grave Accent" +716 "Modifier Letter Low Vertical Line" +717 "Modifier Letter Low Macron" +718 "Modifier Letter Low Grave Accent" +719 "Modifier Letter Low Acute Accent" +720 "Modifier Letter Triangular Colon" +721 "Modifier Letter Half Triangular Colon" +722 "Modifier Letter Centred Right Half Ring" +723 "Modifier Letter Centred Left Half Ring" +724 "Modifier Letter Up Tack" +725 "Modifier Letter Down Tack" +726 "Modifier Letter Plus Sign" +727 "Modifier Letter Minus Sign" +728 "Breve" +729 "Dot Above" +730 "Ring Above" +731 "Ogonek" +732 "Small Tilde" +733 "Double Acute Accent" +734 "Modifier Letter Rhotic Hook" +735 "Modifier Letter Cross Accent" +736 "Modifier Letter Small Gamma" +737 "Modifier Letter Small L" +738 "Modifier Letter Small S" +739 "Modifier Letter Small X" +740 "Modifier Letter Small Reversed Glottal Stop" +741 "Modifier Letter Extra-High Tone Bar" +742 "Modifier Letter High Tone Bar" +743 "Modifier Letter Mid Tone Bar" +744 "Modifier Letter Low Tone Bar" +745 "Modifier Letter Extra-Low Tone Bar" +746 "Modifier Letter Yin Departing Tone Mark" +747 "Modifier Letter Yang Departing Tone Mark" +748 "Modifier Letter Voicing" +749 "Modifier Letter Unaspirated" +750 "Modifier Letter Double Apostrophe" +751 "Modifier Letter Low Down Arrowhead" +752 "Modifier Letter Low Up Arrowhead" +753 "Modifier Letter Low Left Arrowhead" +754 "Modifier Letter Low Right Arrowhead" +755 "Modifier Letter Low Ring" +756 "Modifier Letter Middle Grave Accent" +757 "Modifier Letter Middle Double Grave Accent" +758 "Modifier Letter Middle Double Acute Accent" +759 "Modifier Letter Low Tilde" +760 "Modifier Letter Raised Colon" +761 "Modifier Letter Begin High Tone" +762 "Modifier Letter End High Tone" +763 "Modifier Letter Begin Low Tone" +764 "Modifier Letter End Low Tone" +765 "Modifier Letter Shelf" +766 "Modifier Letter Open Shelf" +767 "Modifier Letter Low Left Arrow" +768 "Combining Grave Accent" +769 "Combining Acute Accent" +770 "Combining Circumflex Accent" +771 "Combining Tilde" +772 "Combining Macron" +773 "Combining Overline" +774 "Combining Breve" +775 "Combining Dot Above" +776 "Combining Diaeresis" +777 "Combining Hook Above" +778 "Combining Ring Above" +779 "Combining Double Acute Accent" +780 "Combining Caron" +781 "Combining Vertical Line Above" +782 "Combining Double Vertical Line Above" +783 "Combining Double Grave Accent" +784 "Combining Candrabindu" +785 "Combining Inverted Breve" +786 "Combining Turned Comma Above" +787 "Combining Comma Above" +788 "Combining Reversed Comma Above" +789 "Combining Comma Above Right" +790 "Combining Grave Accent Below" +791 "Combining Acute Accent Below" +792 "Combining Left Tack Below" +793 "Combining Right Tack Below" +794 "Combining Left Angle Above" +795 "Combining Horn" +796 "Combining Left Half Ring Below" +797 "Combining Up Tack Below" +798 "Combining Down Tack Below" +799 "Combining Plus Sign Below" +800 "Combining Minus Sign Below" +801 "Combining Palatalized Hook Below" +802 "Combining Retroflex Hook Below" +803 "Combining Dot Below" +804 "Combining Diaeresis Below" +805 "Combining Ring Below" +806 "Combining Comma Below" +807 "Combining Cedilla" +808 "Combining Ogonek" +809 "Combining Vertical Line Below" +810 "Combining Bridge Below" +811 "Combining Inverted Double Arch Below" +812 "Combining Caron Below" +813 "Combining Circumflex Accent Below" +814 "Combining Breve Below" +815 "Combining Inverted Breve Below" +816 "Combining Tilde Below" +817 "Combining Macron Below" +818 "Combining Low Line" +819 "Combining Double Low Line" +820 "Combining Tilde Overlay" +821 "Combining Short Stroke Overlay" +822 "Combining Long Stroke Overlay" +823 "Combining Short Solidus Overlay" +824 "Combining Long Solidus Overlay" +825 "Combining Right Half Ring Below" +826 "Combining Inverted Bridge Below" +827 "Combining Square Below" +828 "Combining Seagull Below" +829 "Combining X Above" +830 "Combining Vertical Tilde" +831 "Combining Double Overline" +832 "Combining Grave Tone Mark" +833 "Combining Acute Tone Mark" +834 "Combining Greek Perispomeni" +835 "Combining Greek Koronis" +836 "Combining Greek Dialytika Tonos" +837 "Combining Greek Ypogegrammeni" +838 "Combining Bridge Above" +839 "Combining Equals Sign Below" +840 "Combining Double Vertical Line Below" +841 "Combining Left Angle Below" +842 "Combining Not Tilde Above" +843 "Combining Homothetic Above" +844 "Combining Almost Equal To Above" +845 "Combining Left Right Arrow Below" +846 "Combining Upwards Arrow Below" +847 "Combining Grapheme Joiner" +848 "Combining Right Arrowhead Above" +849 "Combining Left Half Ring Above" +850 "Combining Fermata" +851 "Combining X Below" +852 "Combining Left Arrowhead Below" +853 "Combining Right Arrowhead Below" +854 "Combining Right Arrowhead And Up Arrowhead Below" +855 "Combining Right Half Ring Above" +856 "Combining Dot Above Right" +857 "Combining Asterisk Below" +858 "Combining Double Ring Below" +859 "Combining Zigzag Above" +860 "Combining Double Breve Below" +861 "Combining Double Breve" +862 "Combining Double Macron" +863 "Combining Double Macron Below" +864 "Combining Double Tilde" +865 "Combining Double Inverted Breve" +866 "Combining Double Rightwards Arrow Below" +867 "Combining Latin Small Letter A" +868 "Combining Latin Small Letter E" +869 "Combining Latin Small Letter I" +870 "Combining Latin Small Letter O" +871 "Combining Latin Small Letter U" +872 "Combining Latin Small Letter C" +873 "Combining Latin Small Letter D" +874 "Combining Latin Small Letter H" +875 "Combining Latin Small Letter M" +876 "Combining Latin Small Letter R" +877 "Combining Latin Small Letter T" +878 "Combining Latin Small Letter V" +879 "Combining Latin Small Letter X" +880 "Greek Capital Letter Heta" +881 "Greek Small Letter Heta" +882 "Greek Capital Letter Archaic Sampi" +883 "Greek Small Letter Archaic Sampi" +884 "Greek Numeral Sign" +885 "Greek Lower Numeral Sign" +886 "Greek Capital Letter Pamphylian Digamma" +887 "Greek Small Letter Pamphylian Digamma" +890 "Greek Ypogegrammeni" +891 "Greek Small Reversed Lunate Sigma Symbol" +892 "Greek Small Dotted Lunate Sigma Symbol" +893 "Greek Small Reversed Dotted Lunate Sigma Symbol" +894 "Greek Question Mark" +900 "Greek Tonos" +901 "Greek Dialytika Tonos" +902 "Greek Capital Letter Alpha With Tonos" +903 "Greek Ano Teleia" +904 "Greek Capital Letter Epsilon With Tonos" +905 "Greek Capital Letter Eta With Tonos" +906 "Greek Capital Letter Iota With Tonos" +908 "Greek Capital Letter Omicron With Tonos" +910 "Greek Capital Letter Upsilon With Tonos" +911 "Greek Capital Letter Omega With Tonos" +912 "Greek Small Letter Iota With Dialytika And Tonos" +913 "Greek Capital Letter Alpha" +914 "Greek Capital Letter Beta" +915 "Greek Capital Letter Gamma" +916 "Greek Capital Letter Delta" +917 "Greek Capital Letter Epsilon" +918 "Greek Capital Letter Zeta" +919 "Greek Capital Letter Eta" +920 "Greek Capital Letter Theta" +921 "Greek Capital Letter Iota" +922 "Greek Capital Letter Kappa" +923 "Greek Capital Letter Lamda" +924 "Greek Capital Letter Mu" +925 "Greek Capital Letter Nu" +926 "Greek Capital Letter Xi" +927 "Greek Capital Letter Omicron" +928 "Greek Capital Letter Pi" +929 "Greek Capital Letter Rho" +931 "Greek Capital Letter Sigma" +932 "Greek Capital Letter Tau" +933 "Greek Capital Letter Upsilon" +934 "Greek Capital Letter Phi" +935 "Greek Capital Letter Chi" +936 "Greek Capital Letter Psi" +937 "Greek Capital Letter Omega" +938 "Greek Capital Letter Iota With Dialytika" +939 "Greek Capital Letter Upsilon With Dialytika" +940 "Greek Small Letter Alpha With Tonos" +941 "Greek Small Letter Epsilon With Tonos" +942 "Greek Small Letter Eta With Tonos" +943 "Greek Small Letter Iota With Tonos" +944 "Greek Small Letter Upsilon With Dialytika And Tonos" +945 "Greek Small Letter Alpha" +946 "Greek Small Letter Beta" +947 "Greek Small Letter Gamma" +948 "Greek Small Letter Delta" +949 "Greek Small Letter Epsilon" +950 "Greek Small Letter Zeta" +951 "Greek Small Letter Eta" +952 "Greek Small Letter Theta" +953 "Greek Small Letter Iota" +954 "Greek Small Letter Kappa" +955 "Greek Small Letter Lamda" +956 "Greek Small Letter Mu" +957 "Greek Small Letter Nu" +958 "Greek Small Letter Xi" +959 "Greek Small Letter Omicron" +960 "Greek Small Letter Pi" +961 "Greek Small Letter Rho" +962 "Greek Small Letter Final Sigma" +963 "Greek Small Letter Sigma" +964 "Greek Small Letter Tau" +965 "Greek Small Letter Upsilon" +966 "Greek Small Letter Phi" +967 "Greek Small Letter Chi" +968 "Greek Small Letter Psi" +969 "Greek Small Letter Omega" +970 "Greek Small Letter Iota With Dialytika" +971 "Greek Small Letter Upsilon With Dialytika" +972 "Greek Small Letter Omicron With Tonos" +973 "Greek Small Letter Upsilon With Tonos" +974 "Greek Small Letter Omega With Tonos" +975 "Greek Capital Kai Symbol" +976 "Greek Beta Symbol" +977 "Greek Theta Symbol" +978 "Greek Upsilon With Hook Symbol" +979 "Greek Upsilon With Acute And Hook Symbol" +980 "Greek Upsilon With Diaeresis And Hook Symbol" +981 "Greek Phi Symbol" +982 "Greek Pi Symbol" +983 "Greek Kai Symbol" +984 "Greek Letter Archaic Koppa" +985 "Greek Small Letter Archaic Koppa" +986 "Greek Letter Stigma" +987 "Greek Small Letter Stigma" +988 "Greek Letter Digamma" +989 "Greek Small Letter Digamma" +990 "Greek Letter Koppa" +991 "Greek Small Letter Koppa" +992 "Greek Letter Sampi" +993 "Greek Small Letter Sampi" +994 "Coptic Capital Letter Shei" +995 "Coptic Small Letter Shei" +996 "Coptic Capital Letter Fei" +997 "Coptic Small Letter Fei" +998 "Coptic Capital Letter Khei" +999 "Coptic Small Letter Khei" +1000 "Coptic Capital Letter Hori" +1001 "Coptic Small Letter Hori" +1002 "Coptic Capital Letter Gangia" +1003 "Coptic Small Letter Gangia" +1004 "Coptic Capital Letter Shima" +1005 "Coptic Small Letter Shima" +1006 "Coptic Capital Letter Dei" +1007 "Coptic Small Letter Dei" +1008 "Greek Kappa Symbol" +1009 "Greek Rho Symbol" +1010 "Greek Lunate Sigma Symbol" +1011 "Greek Letter Yot" +1012 "Greek Capital Theta Symbol" +1013 "Greek Lunate Epsilon Symbol" +1014 "Greek Reversed Lunate Epsilon Symbol" +1015 "Greek Capital Letter Sho" +1016 "Greek Small Letter Sho" +1017 "Greek Capital Lunate Sigma Symbol" +1018 "Greek Capital Letter San" +1019 "Greek Small Letter San" +1020 "Greek Rho With Stroke Symbol" +1021 "Greek Capital Reversed Lunate Sigma Symbol" +1022 "Greek Capital Dotted Lunate Sigma Symbol" +1023 "Greek Capital Reversed Dotted Lunate Sigma Symbol" +1024 "Cyrillic Capital Letter Ie With Grave" +1025 "Cyrillic Capital Letter Io" +1026 "Cyrillic Capital Letter Dje" +1027 "Cyrillic Capital Letter Gje" +1028 "Cyrillic Capital Letter Ukrainian Ie" +1029 "Cyrillic Capital Letter Dze" +1030 "Cyrillic Capital Letter Byelorussian-Ukrainian I" +1031 "Cyrillic Capital Letter Yi" +1032 "Cyrillic Capital Letter Je" +1033 "Cyrillic Capital Letter Lje" +1034 "Cyrillic Capital Letter Nje" +1035 "Cyrillic Capital Letter Tshe" +1036 "Cyrillic Capital Letter Kje" +1037 "Cyrillic Capital Letter I With Grave" +1038 "Cyrillic Capital Letter Short U" +1039 "Cyrillic Capital Letter Dzhe" +1040 "Cyrillic Capital Letter A" +1041 "Cyrillic Capital Letter Be" +1042 "Cyrillic Capital Letter Ve" +1043 "Cyrillic Capital Letter Ghe" +1044 "Cyrillic Capital Letter De" +1045 "Cyrillic Capital Letter Ie" +1046 "Cyrillic Capital Letter Zhe" +1047 "Cyrillic Capital Letter Ze" +1048 "Cyrillic Capital Letter I" +1049 "Cyrillic Capital Letter Short I" +1050 "Cyrillic Capital Letter Ka" +1051 "Cyrillic Capital Letter El" +1052 "Cyrillic Capital Letter Em" +1053 "Cyrillic Capital Letter En" +1054 "Cyrillic Capital Letter O" +1055 "Cyrillic Capital Letter Pe" +1056 "Cyrillic Capital Letter Er" +1057 "Cyrillic Capital Letter Es" +1058 "Cyrillic Capital Letter Te" +1059 "Cyrillic Capital Letter U" +1060 "Cyrillic Capital Letter Ef" +1061 "Cyrillic Capital Letter Ha" +1062 "Cyrillic Capital Letter Tse" +1063 "Cyrillic Capital Letter Che" +1064 "Cyrillic Capital Letter Sha" +1065 "Cyrillic Capital Letter Shcha" +1066 "Cyrillic Capital Letter Hard Sign" +1067 "Cyrillic Capital Letter Yeru" +1068 "Cyrillic Capital Letter Soft Sign" +1069 "Cyrillic Capital Letter E" +1070 "Cyrillic Capital Letter Yu" +1071 "Cyrillic Capital Letter Ya" +1072 "Cyrillic Small Letter A" +1073 "Cyrillic Small Letter Be" +1074 "Cyrillic Small Letter Ve" +1075 "Cyrillic Small Letter Ghe" +1076 "Cyrillic Small Letter De" +1077 "Cyrillic Small Letter Ie" +1078 "Cyrillic Small Letter Zhe" +1079 "Cyrillic Small Letter Ze" +1080 "Cyrillic Small Letter I" +1081 "Cyrillic Small Letter Short I" +1082 "Cyrillic Small Letter Ka" +1083 "Cyrillic Small Letter El" +1084 "Cyrillic Small Letter Em" +1085 "Cyrillic Small Letter En" +1086 "Cyrillic Small Letter O" +1087 "Cyrillic Small Letter Pe" +1088 "Cyrillic Small Letter Er" +1089 "Cyrillic Small Letter Es" +1090 "Cyrillic Small Letter Te" +1091 "Cyrillic Small Letter U" +1092 "Cyrillic Small Letter Ef" +1093 "Cyrillic Small Letter Ha" +1094 "Cyrillic Small Letter Tse" +1095 "Cyrillic Small Letter Che" +1096 "Cyrillic Small Letter Sha" +1097 "Cyrillic Small Letter Shcha" +1098 "Cyrillic Small Letter Hard Sign" +1099 "Cyrillic Small Letter Yeru" +1100 "Cyrillic Small Letter Soft Sign" +1101 "Cyrillic Small Letter E" +1102 "Cyrillic Small Letter Yu" +1103 "Cyrillic Small Letter Ya" +1104 "Cyrillic Small Letter Ie With Grave" +1105 "Cyrillic Small Letter Io" +1106 "Cyrillic Small Letter Dje" +1107 "Cyrillic Small Letter Gje" +1108 "Cyrillic Small Letter Ukrainian Ie" +1109 "Cyrillic Small Letter Dze" +1110 "Cyrillic Small Letter Byelorussian-Ukrainian I" +1111 "Cyrillic Small Letter Yi" +1112 "Cyrillic Small Letter Je" +1113 "Cyrillic Small Letter Lje" +1114 "Cyrillic Small Letter Nje" +1115 "Cyrillic Small Letter Tshe" +1116 "Cyrillic Small Letter Kje" +1117 "Cyrillic Small Letter I With Grave" +1118 "Cyrillic Small Letter Short U" +1119 "Cyrillic Small Letter Dzhe" +1120 "Cyrillic Capital Letter Omega" +1121 "Cyrillic Small Letter Omega" +1122 "Cyrillic Capital Letter Yat" +1123 "Cyrillic Small Letter Yat" +1124 "Cyrillic Capital Letter Iotified E" +1125 "Cyrillic Small Letter Iotified E" +1126 "Cyrillic Capital Letter Little Yus" +1127 "Cyrillic Small Letter Little Yus" +1128 "Cyrillic Capital Letter Iotified Little Yus" +1129 "Cyrillic Small Letter Iotified Little Yus" +1130 "Cyrillic Capital Letter Big Yus" +1131 "Cyrillic Small Letter Big Yus" +1132 "Cyrillic Capital Letter Iotified Big Yus" +1133 "Cyrillic Small Letter Iotified Big Yus" +1134 "Cyrillic Capital Letter Ksi" +1135 "Cyrillic Small Letter Ksi" +1136 "Cyrillic Capital Letter Psi" +1137 "Cyrillic Small Letter Psi" +1138 "Cyrillic Capital Letter Fita" +1139 "Cyrillic Small Letter Fita" +1140 "Cyrillic Capital Letter Izhitsa" +1141 "Cyrillic Small Letter Izhitsa" +1142 "Cyrillic Capital Letter Izhitsa With Double Grave Accent" +1143 "Cyrillic Small Letter Izhitsa With Double Grave Accent" +1144 "Cyrillic Capital Letter Uk" +1145 "Cyrillic Small Letter Uk" +1146 "Cyrillic Capital Letter Round Omega" +1147 "Cyrillic Small Letter Round Omega" +1148 "Cyrillic Capital Letter Omega With Titlo" +1149 "Cyrillic Small Letter Omega With Titlo" +1150 "Cyrillic Capital Letter Ot" +1151 "Cyrillic Small Letter Ot" +1152 "Cyrillic Capital Letter Koppa" +1153 "Cyrillic Small Letter Koppa" +1154 "Cyrillic Thousands Sign" +1155 "Combining Cyrillic Titlo" +1156 "Combining Cyrillic Palatalization" +1157 "Combining Cyrillic Dasia Pneumata" +1158 "Combining Cyrillic Psili Pneumata" +1159 "Combining Cyrillic Pokrytie" +1160 "Combining Cyrillic Hundred Thousands Sign" +1161 "Combining Cyrillic Millions Sign" +1162 "Cyrillic Capital Letter Short I With Tail" +1163 "Cyrillic Small Letter Short I With Tail" +1164 "Cyrillic Capital Letter Semisoft Sign" +1165 "Cyrillic Small Letter Semisoft Sign" +1166 "Cyrillic Capital Letter Er With Tick" +1167 "Cyrillic Small Letter Er With Tick" +1168 "Cyrillic Capital Letter Ghe With Upturn" +1169 "Cyrillic Small Letter Ghe With Upturn" +1170 "Cyrillic Capital Letter Ghe With Stroke" +1171 "Cyrillic Small Letter Ghe With Stroke" +1172 "Cyrillic Capital Letter Ghe With Middle Hook" +1173 "Cyrillic Small Letter Ghe With Middle Hook" +1174 "Cyrillic Capital Letter Zhe With Descender" +1175 "Cyrillic Small Letter Zhe With Descender" +1176 "Cyrillic Capital Letter Ze With Descender" +1177 "Cyrillic Small Letter Ze With Descender" +1178 "Cyrillic Capital Letter Ka With Descender" +1179 "Cyrillic Small Letter Ka With Descender" +1180 "Cyrillic Capital Letter Ka With Vertical Stroke" +1181 "Cyrillic Small Letter Ka With Vertical Stroke" +1182 "Cyrillic Capital Letter Ka With Stroke" +1183 "Cyrillic Small Letter Ka With Stroke" +1184 "Cyrillic Capital Letter Bashkir Ka" +1185 "Cyrillic Small Letter Bashkir Ka" +1186 "Cyrillic Capital Letter En With Descender" +1187 "Cyrillic Small Letter En With Descender" +1188 "Cyrillic Capital Ligature En Ghe" +1189 "Cyrillic Small Ligature En Ghe" +1190 "Cyrillic Capital Letter Pe With Middle Hook" +1191 "Cyrillic Small Letter Pe With Middle Hook" +1192 "Cyrillic Capital Letter Abkhasian Ha" +1193 "Cyrillic Small Letter Abkhasian Ha" +1194 "Cyrillic Capital Letter Es With Descender" +1195 "Cyrillic Small Letter Es With Descender" +1196 "Cyrillic Capital Letter Te With Descender" +1197 "Cyrillic Small Letter Te With Descender" +1198 "Cyrillic Capital Letter Straight U" +1199 "Cyrillic Small Letter Straight U" +1200 "Cyrillic Capital Letter Straight U With Stroke" +1201 "Cyrillic Small Letter Straight U With Stroke" +1202 "Cyrillic Capital Letter Ha With Descender" +1203 "Cyrillic Small Letter Ha With Descender" +1204 "Cyrillic Capital Ligature Te Tse" +1205 "Cyrillic Small Ligature Te Tse" +1206 "Cyrillic Capital Letter Che With Descender" +1207 "Cyrillic Small Letter Che With Descender" +1208 "Cyrillic Capital Letter Che With Vertical Stroke" +1209 "Cyrillic Small Letter Che With Vertical Stroke" +1210 "Cyrillic Capital Letter Shha" +1211 "Cyrillic Small Letter Shha" +1212 "Cyrillic Capital Letter Abkhasian Che" +1213 "Cyrillic Small Letter Abkhasian Che" +1214 "Cyrillic Capital Letter Abkhasian Che With Descender" +1215 "Cyrillic Small Letter Abkhasian Che With Descender" +1216 "Cyrillic Letter Palochka" +1217 "Cyrillic Capital Letter Zhe With Breve" +1218 "Cyrillic Small Letter Zhe With Breve" +1219 "Cyrillic Capital Letter Ka With Hook" +1220 "Cyrillic Small Letter Ka With Hook" +1221 "Cyrillic Capital Letter El With Tail" +1222 "Cyrillic Small Letter El With Tail" +1223 "Cyrillic Capital Letter En With Hook" +1224 "Cyrillic Small Letter En With Hook" +1225 "Cyrillic Capital Letter En With Tail" +1226 "Cyrillic Small Letter En With Tail" +1227 "Cyrillic Capital Letter Khakassian Che" +1228 "Cyrillic Small Letter Khakassian Che" +1229 "Cyrillic Capital Letter Em With Tail" +1230 "Cyrillic Small Letter Em With Tail" +1231 "Cyrillic Small Letter Palochka" +1232 "Cyrillic Capital Letter A With Breve" +1233 "Cyrillic Small Letter A With Breve" +1234 "Cyrillic Capital Letter A With Diaeresis" +1235 "Cyrillic Small Letter A With Diaeresis" +1236 "Cyrillic Capital Ligature A Ie" +1237 "Cyrillic Small Ligature A Ie" +1238 "Cyrillic Capital Letter Ie With Breve" +1239 "Cyrillic Small Letter Ie With Breve" +1240 "Cyrillic Capital Letter Schwa" +1241 "Cyrillic Small Letter Schwa" +1242 "Cyrillic Capital Letter Schwa With Diaeresis" +1243 "Cyrillic Small Letter Schwa With Diaeresis" +1244 "Cyrillic Capital Letter Zhe With Diaeresis" +1245 "Cyrillic Small Letter Zhe With Diaeresis" +1246 "Cyrillic Capital Letter Ze With Diaeresis" +1247 "Cyrillic Small Letter Ze With Diaeresis" +1248 "Cyrillic Capital Letter Abkhasian Dze" +1249 "Cyrillic Small Letter Abkhasian Dze" +1250 "Cyrillic Capital Letter I With Macron" +1251 "Cyrillic Small Letter I With Macron" +1252 "Cyrillic Capital Letter I With Diaeresis" +1253 "Cyrillic Small Letter I With Diaeresis" +1254 "Cyrillic Capital Letter O With Diaeresis" +1255 "Cyrillic Small Letter O With Diaeresis" +1256 "Cyrillic Capital Letter Barred O" +1257 "Cyrillic Small Letter Barred O" +1258 "Cyrillic Capital Letter Barred O With Diaeresis" +1259 "Cyrillic Small Letter Barred O With Diaeresis" +1260 "Cyrillic Capital Letter E With Diaeresis" +1261 "Cyrillic Small Letter E With Diaeresis" +1262 "Cyrillic Capital Letter U With Macron" +1263 "Cyrillic Small Letter U With Macron" +1264 "Cyrillic Capital Letter U With Diaeresis" +1265 "Cyrillic Small Letter U With Diaeresis" +1266 "Cyrillic Capital Letter U With Double Acute" +1267 "Cyrillic Small Letter U With Double Acute" +1268 "Cyrillic Capital Letter Che With Diaeresis" +1269 "Cyrillic Small Letter Che With Diaeresis" +1270 "Cyrillic Capital Letter Ghe With Descender" +1271 "Cyrillic Small Letter Ghe With Descender" +1272 "Cyrillic Capital Letter Yeru With Diaeresis" +1273 "Cyrillic Small Letter Yeru With Diaeresis" +1274 "Cyrillic Capital Letter Ghe With Stroke And Hook" +1275 "Cyrillic Small Letter Ghe With Stroke And Hook" +1276 "Cyrillic Capital Letter Ha With Hook" +1277 "Cyrillic Small Letter Ha With Hook" +1278 "Cyrillic Capital Letter Ha With Stroke" +1279 "Cyrillic Small Letter Ha With Stroke" +1280 "Cyrillic Capital Letter Komi De" +1281 "Cyrillic Small Letter Komi De" +1282 "Cyrillic Capital Letter Komi Dje" +1283 "Cyrillic Small Letter Komi Dje" +1284 "Cyrillic Capital Letter Komi Zje" +1285 "Cyrillic Small Letter Komi Zje" +1286 "Cyrillic Capital Letter Komi Dzje" +1287 "Cyrillic Small Letter Komi Dzje" +1288 "Cyrillic Capital Letter Komi Lje" +1289 "Cyrillic Small Letter Komi Lje" +1290 "Cyrillic Capital Letter Komi Nje" +1291 "Cyrillic Small Letter Komi Nje" +1292 "Cyrillic Capital Letter Komi Sje" +1293 "Cyrillic Small Letter Komi Sje" +1294 "Cyrillic Capital Letter Komi Tje" +1295 "Cyrillic Small Letter Komi Tje" +1296 "Cyrillic Capital Letter Reversed Ze" +1297 "Cyrillic Small Letter Reversed Ze" +1298 "Cyrillic Capital Letter El With Hook" +1299 "Cyrillic Small Letter El With Hook" +1300 "Cyrillic Capital Letter Lha" +1301 "Cyrillic Small Letter Lha" +1302 "Cyrillic Capital Letter Rha" +1303 "Cyrillic Small Letter Rha" +1304 "Cyrillic Capital Letter Yae" +1305 "Cyrillic Small Letter Yae" +1306 "Cyrillic Capital Letter Qa" +1307 "Cyrillic Small Letter Qa" +1308 "Cyrillic Capital Letter We" +1309 "Cyrillic Small Letter We" +1310 "Cyrillic Capital Letter Aleut Ka" +1311 "Cyrillic Small Letter Aleut Ka" +1312 "Cyrillic Capital Letter El With Middle Hook" +1313 "Cyrillic Small Letter El With Middle Hook" +1314 "Cyrillic Capital Letter En With Middle Hook" +1315 "Cyrillic Small Letter En With Middle Hook" +1316 "Cyrillic Capital Letter Pe With Descender" +1317 "Cyrillic Small Letter Pe With Descender" +1318 "Cyrillic Capital Letter Shha With Descender" +1319 "Cyrillic Small Letter Shha With Descender" +1329 "Armenian Capital Letter Ayb" +1330 "Armenian Capital Letter Ben" +1331 "Armenian Capital Letter Gim" +1332 "Armenian Capital Letter Da" +1333 "Armenian Capital Letter Ech" +1334 "Armenian Capital Letter Za" +1335 "Armenian Capital Letter Eh" +1336 "Armenian Capital Letter Et" +1337 "Armenian Capital Letter To" +1338 "Armenian Capital Letter Zhe" +1339 "Armenian Capital Letter Ini" +1340 "Armenian Capital Letter Liwn" +1341 "Armenian Capital Letter Xeh" +1342 "Armenian Capital Letter Ca" +1343 "Armenian Capital Letter Ken" +1344 "Armenian Capital Letter Ho" +1345 "Armenian Capital Letter Ja" +1346 "Armenian Capital Letter Ghad" +1347 "Armenian Capital Letter Cheh" +1348 "Armenian Capital Letter Men" +1349 "Armenian Capital Letter Yi" +1350 "Armenian Capital Letter Now" +1351 "Armenian Capital Letter Sha" +1352 "Armenian Capital Letter Vo" +1353 "Armenian Capital Letter Cha" +1354 "Armenian Capital Letter Peh" +1355 "Armenian Capital Letter Jheh" +1356 "Armenian Capital Letter Ra" +1357 "Armenian Capital Letter Seh" +1358 "Armenian Capital Letter Vew" +1359 "Armenian Capital Letter Tiwn" +1360 "Armenian Capital Letter Reh" +1361 "Armenian Capital Letter Co" +1362 "Armenian Capital Letter Yiwn" +1363 "Armenian Capital Letter Piwr" +1364 "Armenian Capital Letter Keh" +1365 "Armenian Capital Letter Oh" +1366 "Armenian Capital Letter Feh" +1369 "Armenian Modifier Letter Left Half Ring" +1370 "Armenian Apostrophe" +1371 "Armenian Emphasis Mark" +1372 "Armenian Exclamation Mark" +1373 "Armenian Comma" +1374 "Armenian Question Mark" +1375 "Armenian Abbreviation Mark" +1377 "Armenian Small Letter Ayb" +1378 "Armenian Small Letter Ben" +1379 "Armenian Small Letter Gim" +1380 "Armenian Small Letter Da" +1381 "Armenian Small Letter Ech" +1382 "Armenian Small Letter Za" +1383 "Armenian Small Letter Eh" +1384 "Armenian Small Letter Et" +1385 "Armenian Small Letter To" +1386 "Armenian Small Letter Zhe" +1387 "Armenian Small Letter Ini" +1388 "Armenian Small Letter Liwn" +1389 "Armenian Small Letter Xeh" +1390 "Armenian Small Letter Ca" +1391 "Armenian Small Letter Ken" +1392 "Armenian Small Letter Ho" +1393 "Armenian Small Letter Ja" +1394 "Armenian Small Letter Ghad" +1395 "Armenian Small Letter Cheh" +1396 "Armenian Small Letter Men" +1397 "Armenian Small Letter Yi" +1398 "Armenian Small Letter Now" +1399 "Armenian Small Letter Sha" +1400 "Armenian Small Letter Vo" +1401 "Armenian Small Letter Cha" +1402 "Armenian Small Letter Peh" +1403 "Armenian Small Letter Jheh" +1404 "Armenian Small Letter Ra" +1405 "Armenian Small Letter Seh" +1406 "Armenian Small Letter Vew" +1407 "Armenian Small Letter Tiwn" +1408 "Armenian Small Letter Reh" +1409 "Armenian Small Letter Co" +1410 "Armenian Small Letter Yiwn" +1411 "Armenian Small Letter Piwr" +1412 "Armenian Small Letter Keh" +1413 "Armenian Small Letter Oh" +1414 "Armenian Small Letter Feh" +1415 "Armenian Small Ligature Ech Yiwn" +1417 "Armenian Full Stop" +1418 "Armenian Hyphen" +1423 "Armenian Dram Sign" +1425 "Hebrew Accent Etnahta" +1426 "Hebrew Accent Segol" +1427 "Hebrew Accent Shalshelet" +1428 "Hebrew Accent Zaqef Qatan" +1429 "Hebrew Accent Zaqef Gadol" +1430 "Hebrew Accent Tipeha" +1431 "Hebrew Accent Revia" +1432 "Hebrew Accent Zarqa" +1433 "Hebrew Accent Pashta" +1434 "Hebrew Accent Yetiv" +1435 "Hebrew Accent Tevir" +1436 "Hebrew Accent Geresh" +1437 "Hebrew Accent Geresh Muqdam" +1438 "Hebrew Accent Gershayim" +1439 "Hebrew Accent Qarney Para" +1440 "Hebrew Accent Telisha Gedola" +1441 "Hebrew Accent Pazer" +1442 "Hebrew Accent Atnah Hafukh" +1443 "Hebrew Accent Munah" +1444 "Hebrew Accent Mahapakh" +1445 "Hebrew Accent Merkha" +1446 "Hebrew Accent Merkha Kefula" +1447 "Hebrew Accent Darga" +1448 "Hebrew Accent Qadma" +1449 "Hebrew Accent Telisha Qetana" +1450 "Hebrew Accent Yerah Ben Yomo" +1451 "Hebrew Accent Ole" +1452 "Hebrew Accent Iluy" +1453 "Hebrew Accent Dehi" +1454 "Hebrew Accent Zinor" +1455 "Hebrew Mark Masora Circle" +1456 "Hebrew Point Sheva" +1457 "Hebrew Point Hataf Segol" +1458 "Hebrew Point Hataf Patah" +1459 "Hebrew Point Hataf Qamats" +1460 "Hebrew Point Hiriq" +1461 "Hebrew Point Tsere" +1462 "Hebrew Point Segol" +1463 "Hebrew Point Patah" +1464 "Hebrew Point Qamats" +1465 "Hebrew Point Holam" +1466 "Hebrew Point Holam Haser For Vav" +1467 "Hebrew Point Qubuts" +1468 "Hebrew Point Dagesh Or Mapiq" +1469 "Hebrew Point Meteg" +1470 "Hebrew Punctuation Maqaf" +1471 "Hebrew Point Rafe" +1472 "Hebrew Punctuation Paseq" +1473 "Hebrew Point Shin Dot" +1474 "Hebrew Point Sin Dot" +1475 "Hebrew Punctuation Sof Pasuq" +1476 "Hebrew Mark Upper Dot" +1477 "Hebrew Mark Lower Dot" +1478 "Hebrew Punctuation Nun Hafukha" +1479 "Hebrew Point Qamats Qatan" +1488 "Hebrew Letter Alef" +1489 "Hebrew Letter Bet" +1490 "Hebrew Letter Gimel" +1491 "Hebrew Letter Dalet" +1492 "Hebrew Letter He" +1493 "Hebrew Letter Vav" +1494 "Hebrew Letter Zayin" +1495 "Hebrew Letter Het" +1496 "Hebrew Letter Tet" +1497 "Hebrew Letter Yod" +1498 "Hebrew Letter Final Kaf" +1499 "Hebrew Letter Kaf" +1500 "Hebrew Letter Lamed" +1501 "Hebrew Letter Final Mem" +1502 "Hebrew Letter Mem" +1503 "Hebrew Letter Final Nun" +1504 "Hebrew Letter Nun" +1505 "Hebrew Letter Samekh" +1506 "Hebrew Letter Ayin" +1507 "Hebrew Letter Final Pe" +1508 "Hebrew Letter Pe" +1509 "Hebrew Letter Final Tsadi" +1510 "Hebrew Letter Tsadi" +1511 "Hebrew Letter Qof" +1512 "Hebrew Letter Resh" +1513 "Hebrew Letter Shin" +1514 "Hebrew Letter Tav" +1520 "Hebrew Ligature Yiddish Double Vav" +1521 "Hebrew Ligature Yiddish Vav Yod" +1522 "Hebrew Ligature Yiddish Double Yod" +1523 "Hebrew Punctuation Geresh" +1524 "Hebrew Punctuation Gershayim" +1536 "Arabic Number Sign" +1537 "Arabic Sign Sanah" +1538 "Arabic Footnote Marker" +1539 "Arabic Sign Safha" +1540 "Arabic Sign Samvat" +1542 "Arabic-Indic Cube Root" +1543 "Arabic-Indic Fourth Root" +1544 "Arabic Ray" +1545 "Arabic-Indic Per Mille Sign" +1546 "Arabic-Indic Per Ten Thousand Sign" +1547 "Afghani Sign" +1548 "Arabic Comma" +1549 "Arabic Date Separator" +1550 "Arabic Poetic Verse Sign" +1551 "Arabic Sign Misra" +1552 "Arabic Sign Sallallahou Alayhe Wassallam" +1553 "Arabic Sign Alayhe Assallam" +1554 "Arabic Sign Rahmatullah Alayhe" +1555 "Arabic Sign Radi Allahou Anhu" +1556 "Arabic Sign Takhallus" +1557 "Arabic Small High Tah" +1558 "Arabic Small High Ligature Alef With Lam With Yeh" +1559 "Arabic Small High Zain" +1560 "Arabic Small Fatha" +1561 "Arabic Small Damma" +1562 "Arabic Small Kasra" +1563 "Arabic Semicolon" +1566 "Arabic Triple Dot Punctuation Mark" +1567 "Arabic Question Mark" +1568 "Arabic Letter Kashmiri Yeh" +1569 "Arabic Letter Hamza" +1570 "Arabic Letter Alef With Madda Above" +1571 "Arabic Letter Alef With Hamza Above" +1572 "Arabic Letter Waw With Hamza Above" +1573 "Arabic Letter Alef With Hamza Below" +1574 "Arabic Letter Yeh With Hamza Above" +1575 "Arabic Letter Alef" +1576 "Arabic Letter Beh" +1577 "Arabic Letter Teh Marbuta" +1578 "Arabic Letter Teh" +1579 "Arabic Letter Theh" +1580 "Arabic Letter Jeem" +1581 "Arabic Letter Hah" +1582 "Arabic Letter Khah" +1583 "Arabic Letter Dal" +1584 "Arabic Letter Thal" +1585 "Arabic Letter Reh" +1586 "Arabic Letter Zain" +1587 "Arabic Letter Seen" +1588 "Arabic Letter Sheen" +1589 "Arabic Letter Sad" +1590 "Arabic Letter Dad" +1591 "Arabic Letter Tah" +1592 "Arabic Letter Zah" +1593 "Arabic Letter Ain" +1594 "Arabic Letter Ghain" +1595 "Arabic Letter Keheh With Two Dots Above" +1596 "Arabic Letter Keheh With Three Dots Below" +1597 "Arabic Letter Farsi Yeh With Inverted V" +1598 "Arabic Letter Farsi Yeh With Two Dots Above" +1599 "Arabic Letter Farsi Yeh With Three Dots Above" +1600 "Arabic Tatweel" +1601 "Arabic Letter Feh" +1602 "Arabic Letter Qaf" +1603 "Arabic Letter Kaf" +1604 "Arabic Letter Lam" +1605 "Arabic Letter Meem" +1606 "Arabic Letter Noon" +1607 "Arabic Letter Heh" +1608 "Arabic Letter Waw" +1609 "Arabic Letter Alef Maksura" +1610 "Arabic Letter Yeh" +1611 "Arabic Fathatan" +1612 "Arabic Dammatan" +1613 "Arabic Kasratan" +1614 "Arabic Fatha" +1615 "Arabic Damma" +1616 "Arabic Kasra" +1617 "Arabic Shadda" +1618 "Arabic Sukun" +1619 "Arabic Maddah Above" +1620 "Arabic Hamza Above" +1621 "Arabic Hamza Below" +1622 "Arabic Subscript Alef" +1623 "Arabic Inverted Damma" +1624 "Arabic Mark Noon Ghunna" +1625 "Arabic Zwarakay" +1626 "Arabic Vowel Sign Small V Above" +1627 "Arabic Vowel Sign Inverted Small V Above" +1628 "Arabic Vowel Sign Dot Below" +1629 "Arabic Reversed Damma" +1630 "Arabic Fatha With Two Dots" +1631 "Arabic Wavy Hamza Below" +1632 "Arabic-Indic Digit Zero" +1633 "Arabic-Indic Digit One" +1634 "Arabic-Indic Digit Two" +1635 "Arabic-Indic Digit Three" +1636 "Arabic-Indic Digit Four" +1637 "Arabic-Indic Digit Five" +1638 "Arabic-Indic Digit Six" +1639 "Arabic-Indic Digit Seven" +1640 "Arabic-Indic Digit Eight" +1641 "Arabic-Indic Digit Nine" +1642 "Arabic Percent Sign" +1643 "Arabic Decimal Separator" +1644 "Arabic Thousands Separator" +1645 "Arabic Five Pointed Star" +1646 "Arabic Letter Dotless Beh" +1647 "Arabic Letter Dotless Qaf" +1648 "Arabic Letter Superscript Alef" +1649 "Arabic Letter Alef Wasla" +1650 "Arabic Letter Alef With Wavy Hamza Above" +1651 "Arabic Letter Alef With Wavy Hamza Below" +1652 "Arabic Letter High Hamza" +1653 "Arabic Letter High Hamza Alef" +1654 "Arabic Letter High Hamza Waw" +1655 "Arabic Letter U With Hamza Above" +1656 "Arabic Letter High Hamza Yeh" +1657 "Arabic Letter Tteh" +1658 "Arabic Letter Tteheh" +1659 "Arabic Letter Beeh" +1660 "Arabic Letter Teh With Ring" +1661 "Arabic Letter Teh With Three Dots Above Downwards" +1662 "Arabic Letter Peh" +1663 "Arabic Letter Teheh" +1664 "Arabic Letter Beheh" +1665 "Arabic Letter Hah With Hamza Above" +1666 "Arabic Letter Hah With Two Dots Vertical Above" +1667 "Arabic Letter Nyeh" +1668 "Arabic Letter Dyeh" +1669 "Arabic Letter Hah With Three Dots Above" +1670 "Arabic Letter Tcheh" +1671 "Arabic Letter Tcheheh" +1672 "Arabic Letter Ddal" +1673 "Arabic Letter Dal With Ring" +1674 "Arabic Letter Dal With Dot Below" +1675 "Arabic Letter Dal With Dot Below And Small Tah" +1676 "Arabic Letter Dahal" +1677 "Arabic Letter Ddahal" +1678 "Arabic Letter Dul" +1679 "Arabic Letter Dal With Three Dots Above Downwards" +1680 "Arabic Letter Dal With Four Dots Above" +1681 "Arabic Letter Rreh" +1682 "Arabic Letter Reh With Small V" +1683 "Arabic Letter Reh With Ring" +1684 "Arabic Letter Reh With Dot Below" +1685 "Arabic Letter Reh With Small V Below" +1686 "Arabic Letter Reh With Dot Below And Dot Above" +1687 "Arabic Letter Reh With Two Dots Above" +1688 "Arabic Letter Jeh" +1689 "Arabic Letter Reh With Four Dots Above" +1690 "Arabic Letter Seen With Dot Below And Dot Above" +1691 "Arabic Letter Seen With Three Dots Below" +1692 "Arabic Letter Seen With Three Dots Below And Three Dots Above" +1693 "Arabic Letter Sad With Two Dots Below" +1694 "Arabic Letter Sad With Three Dots Above" +1695 "Arabic Letter Tah With Three Dots Above" +1696 "Arabic Letter Ain With Three Dots Above" +1697 "Arabic Letter Dotless Feh" +1698 "Arabic Letter Feh With Dot Moved Below" +1699 "Arabic Letter Feh With Dot Below" +1700 "Arabic Letter Veh" +1701 "Arabic Letter Feh With Three Dots Below" +1702 "Arabic Letter Peheh" +1703 "Arabic Letter Qaf With Dot Above" +1704 "Arabic Letter Qaf With Three Dots Above" +1705 "Arabic Letter Keheh" +1706 "Arabic Letter Swash Kaf" +1707 "Arabic Letter Kaf With Ring" +1708 "Arabic Letter Kaf With Dot Above" +1709 "Arabic Letter Ng" +1710 "Arabic Letter Kaf With Three Dots Below" +1711 "Arabic Letter Gaf" +1712 "Arabic Letter Gaf With Ring" +1713 "Arabic Letter Ngoeh" +1714 "Arabic Letter Gaf With Two Dots Below" +1715 "Arabic Letter Gueh" +1716 "Arabic Letter Gaf With Three Dots Above" +1717 "Arabic Letter Lam With Small V" +1718 "Arabic Letter Lam With Dot Above" +1719 "Arabic Letter Lam With Three Dots Above" +1720 "Arabic Letter Lam With Three Dots Below" +1721 "Arabic Letter Noon With Dot Below" +1722 "Arabic Letter Noon Ghunna" +1723 "Arabic Letter Rnoon" +1724 "Arabic Letter Noon With Ring" +1725 "Arabic Letter Noon With Three Dots Above" +1726 "Arabic Letter Heh Doachashmee" +1727 "Arabic Letter Tcheh With Dot Above" +1728 "Arabic Letter Heh With Yeh Above" +1729 "Arabic Letter Heh Goal" +1730 "Arabic Letter Heh Goal With Hamza Above" +1731 "Arabic Letter Teh Marbuta Goal" +1732 "Arabic Letter Waw With Ring" +1733 "Arabic Letter Kirghiz Oe" +1734 "Arabic Letter Oe" +1735 "Arabic Letter U" +1736 "Arabic Letter Yu" +1737 "Arabic Letter Kirghiz Yu" +1738 "Arabic Letter Waw With Two Dots Above" +1739 "Arabic Letter Ve" +1740 "Arabic Letter Farsi Yeh" +1741 "Arabic Letter Yeh With Tail" +1742 "Arabic Letter Yeh With Small V" +1743 "Arabic Letter Waw With Dot Above" +1744 "Arabic Letter E" +1745 "Arabic Letter Yeh With Three Dots Below" +1746 "Arabic Letter Yeh Barree" +1747 "Arabic Letter Yeh Barree With Hamza Above" +1748 "Arabic Full Stop" +1749 "Arabic Letter Ae" +1750 "Arabic Small High Ligature Sad With Lam With Alef Maksura" +1751 "Arabic Small High Ligature Qaf With Lam With Alef Maksura" +1752 "Arabic Small High Meem Initial Form" +1753 "Arabic Small High Lam Alef" +1754 "Arabic Small High Jeem" +1755 "Arabic Small High Three Dots" +1756 "Arabic Small High Seen" +1757 "Arabic End Of Ayah" +1758 "Arabic Start Of Rub El Hizb" +1759 "Arabic Small High Rounded Zero" +1760 "Arabic Small High Upright Rectangular Zero" +1761 "Arabic Small High Dotless Head Of Khah" +1762 "Arabic Small High Meem Isolated Form" +1763 "Arabic Small Low Seen" +1764 "Arabic Small High Madda" +1765 "Arabic Small Waw" +1766 "Arabic Small Yeh" +1767 "Arabic Small High Yeh" +1768 "Arabic Small High Noon" +1769 "Arabic Place Of Sajdah" +1770 "Arabic Empty Centre Low Stop" +1771 "Arabic Empty Centre High Stop" +1772 "Arabic Rounded High Stop With Filled Centre" +1773 "Arabic Small Low Meem" +1774 "Arabic Letter Dal With Inverted V" +1775 "Arabic Letter Reh With Inverted V" +1776 "Extended Arabic-Indic Digit Zero" +1777 "Extended Arabic-Indic Digit One" +1778 "Extended Arabic-Indic Digit Two" +1779 "Extended Arabic-Indic Digit Three" +1780 "Extended Arabic-Indic Digit Four" +1781 "Extended Arabic-Indic Digit Five" +1782 "Extended Arabic-Indic Digit Six" +1783 "Extended Arabic-Indic Digit Seven" +1784 "Extended Arabic-Indic Digit Eight" +1785 "Extended Arabic-Indic Digit Nine" +1786 "Arabic Letter Sheen With Dot Below" +1787 "Arabic Letter Dad With Dot Below" +1788 "Arabic Letter Ghain With Dot Below" +1789 "Arabic Sign Sindhi Ampersand" +1790 "Arabic Sign Sindhi Postposition Men" +1791 "Arabic Letter Heh With Inverted V" +1792 "Syriac End Of Paragraph" +1793 "Syriac Supralinear Full Stop" +1794 "Syriac Sublinear Full Stop" +1795 "Syriac Supralinear Colon" +1796 "Syriac Sublinear Colon" +1797 "Syriac Horizontal Colon" +1798 "Syriac Colon Skewed Left" +1799 "Syriac Colon Skewed Right" +1800 "Syriac Supralinear Colon Skewed Left" +1801 "Syriac Sublinear Colon Skewed Right" +1802 "Syriac Contraction" +1803 "Syriac Harklean Obelus" +1804 "Syriac Harklean Metobelus" +1805 "Syriac Harklean Asteriscus" +1807 "Syriac Abbreviation Mark" +1808 "Syriac Letter Alaph" +1809 "Syriac Letter Superscript Alaph" +1810 "Syriac Letter Beth" +1811 "Syriac Letter Gamal" +1812 "Syriac Letter Gamal Garshuni" +1813 "Syriac Letter Dalath" +1814 "Syriac Letter Dotless Dalath Rish" +1815 "Syriac Letter He" +1816 "Syriac Letter Waw" +1817 "Syriac Letter Zain" +1818 "Syriac Letter Heth" +1819 "Syriac Letter Teth" +1820 "Syriac Letter Teth Garshuni" +1821 "Syriac Letter Yudh" +1822 "Syriac Letter Yudh He" +1823 "Syriac Letter Kaph" +1824 "Syriac Letter Lamadh" +1825 "Syriac Letter Mim" +1826 "Syriac Letter Nun" +1827 "Syriac Letter Semkath" +1828 "Syriac Letter Final Semkath" +1829 "Syriac Letter E" +1830 "Syriac Letter Pe" +1831 "Syriac Letter Reversed Pe" +1832 "Syriac Letter Sadhe" +1833 "Syriac Letter Qaph" +1834 "Syriac Letter Rish" +1835 "Syriac Letter Shin" +1836 "Syriac Letter Taw" +1837 "Syriac Letter Persian Bheth" +1838 "Syriac Letter Persian Ghamal" +1839 "Syriac Letter Persian Dhalath" +1840 "Syriac Pthaha Above" +1841 "Syriac Pthaha Below" +1842 "Syriac Pthaha Dotted" +1843 "Syriac Zqapha Above" +1844 "Syriac Zqapha Below" +1845 "Syriac Zqapha Dotted" +1846 "Syriac Rbasa Above" +1847 "Syriac Rbasa Below" +1848 "Syriac Dotted Zlama Horizontal" +1849 "Syriac Dotted Zlama Angular" +1850 "Syriac Hbasa Above" +1851 "Syriac Hbasa Below" +1852 "Syriac Hbasa-Esasa Dotted" +1853 "Syriac Esasa Above" +1854 "Syriac Esasa Below" +1855 "Syriac Rwaha" +1856 "Syriac Feminine Dot" +1857 "Syriac Qushshaya" +1858 "Syriac Rukkakha" +1859 "Syriac Two Vertical Dots Above" +1860 "Syriac Two Vertical Dots Below" +1861 "Syriac Three Dots Above" +1862 "Syriac Three Dots Below" +1863 "Syriac Oblique Line Above" +1864 "Syriac Oblique Line Below" +1865 "Syriac Music" +1866 "Syriac Barrekh" +1869 "Syriac Letter Sogdian Zhain" +1870 "Syriac Letter Sogdian Khaph" +1871 "Syriac Letter Sogdian Fe" +1872 "Arabic Letter Beh With Three Dots Horizontally Below" +1873 "Arabic Letter Beh With Dot Below And Three Dots Above" +1874 "Arabic Letter Beh With Three Dots Pointing Upwards Below" +1875 "Arabic Letter Beh With Three Dots Pointing Upwards Below And Two Dots Above" +1876 "Arabic Letter Beh With Two Dots Below And Dot Above" +1877 "Arabic Letter Beh With Inverted Small V Below" +1878 "Arabic Letter Beh With Small V" +1879 "Arabic Letter Hah With Two Dots Above" +1880 "Arabic Letter Hah With Three Dots Pointing Upwards Below" +1881 "Arabic Letter Dal With Two Dots Vertically Below And Small Tah" +1882 "Arabic Letter Dal With Inverted Small V Below" +1883 "Arabic Letter Reh With Stroke" +1884 "Arabic Letter Seen With Four Dots Above" +1885 "Arabic Letter Ain With Two Dots Above" +1886 "Arabic Letter Ain With Three Dots Pointing Downwards Above" +1887 "Arabic Letter Ain With Two Dots Vertically Above" +1888 "Arabic Letter Feh With Two Dots Below" +1889 "Arabic Letter Feh With Three Dots Pointing Upwards Below" +1890 "Arabic Letter Keheh With Dot Above" +1891 "Arabic Letter Keheh With Three Dots Above" +1892 "Arabic Letter Keheh With Three Dots Pointing Upwards Below" +1893 "Arabic Letter Meem With Dot Above" +1894 "Arabic Letter Meem With Dot Below" +1895 "Arabic Letter Noon With Two Dots Below" +1896 "Arabic Letter Noon With Small Tah" +1897 "Arabic Letter Noon With Small V" +1898 "Arabic Letter Lam With Bar" +1899 "Arabic Letter Reh With Two Dots Vertically Above" +1900 "Arabic Letter Reh With Hamza Above" +1901 "Arabic Letter Seen With Two Dots Vertically Above" +1902 "Arabic Letter Hah With Small Arabic Letter Tah Below" +1903 "Arabic Letter Hah With Small Arabic Letter Tah And Two Dots" +1904 "Arabic Letter Seen With Small Arabic Letter Tah And Two Dots" +1905 "Arabic Letter Reh With Small Arabic Letter Tah And Two Dots" +1906 "Arabic Letter Hah With Small Arabic Letter Tah Above" +1907 "Arabic Letter Alef With Extended Arabic-Indic Digit Two Above" +1908 "Arabic Letter Alef With Extended Arabic-Indic Digit Three Above" +1909 "Arabic Letter Farsi Yeh With Extended Arabic-Indic Digit Two Above" +1910 "Arabic Letter Farsi Yeh With Extended Arabic-Indic Digit Three Above" +1911 "Arabic Letter Farsi Yeh With Extended Arabic-Indic Digit Four Below" +1912 "Arabic Letter Waw With Extended Arabic-Indic Digit Two Above" +1913 "Arabic Letter Waw With Extended Arabic-Indic Digit Three Above" +1914 "Arabic Letter Yeh Barree With Extended Arabic-Indic Digit Two Above" +1915 "Arabic Letter Yeh Barree With Extended Arabic-Indic Digit Three Above" +1916 "Arabic Letter Hah With Extended Arabic-Indic Digit Four Below" +1917 "Arabic Letter Seen With Extended Arabic-Indic Digit Four Above" +1918 "Arabic Letter Seen With Inverted V" +1919 "Arabic Letter Kaf With Two Dots Above" +1920 "Thaana Letter Haa" +1921 "Thaana Letter Shaviyani" +1922 "Thaana Letter Noonu" +1923 "Thaana Letter Raa" +1924 "Thaana Letter Baa" +1925 "Thaana Letter Lhaviyani" +1926 "Thaana Letter Kaafu" +1927 "Thaana Letter Alifu" +1928 "Thaana Letter Vaavu" +1929 "Thaana Letter Meemu" +1930 "Thaana Letter Faafu" +1931 "Thaana Letter Dhaalu" +1932 "Thaana Letter Thaa" +1933 "Thaana Letter Laamu" +1934 "Thaana Letter Gaafu" +1935 "Thaana Letter Gnaviyani" +1936 "Thaana Letter Seenu" +1937 "Thaana Letter Daviyani" +1938 "Thaana Letter Zaviyani" +1939 "Thaana Letter Taviyani" +1940 "Thaana Letter Yaa" +1941 "Thaana Letter Paviyani" +1942 "Thaana Letter Javiyani" +1943 "Thaana Letter Chaviyani" +1944 "Thaana Letter Ttaa" +1945 "Thaana Letter Hhaa" +1946 "Thaana Letter Khaa" +1947 "Thaana Letter Thaalu" +1948 "Thaana Letter Zaa" +1949 "Thaana Letter Sheenu" +1950 "Thaana Letter Saadhu" +1951 "Thaana Letter Daadhu" +1952 "Thaana Letter To" +1953 "Thaana Letter Zo" +1954 "Thaana Letter Ainu" +1955 "Thaana Letter Ghainu" +1956 "Thaana Letter Qaafu" +1957 "Thaana Letter Waavu" +1958 "Thaana Abafili" +1959 "Thaana Aabaafili" +1960 "Thaana Ibifili" +1961 "Thaana Eebeefili" +1962 "Thaana Ubufili" +1963 "Thaana Ooboofili" +1964 "Thaana Ebefili" +1965 "Thaana Eybeyfili" +1966 "Thaana Obofili" +1967 "Thaana Oaboafili" +1968 "Thaana Sukun" +1969 "Thaana Letter Naa" +1984 "Nko Digit Zero" +1985 "Nko Digit One" +1986 "Nko Digit Two" +1987 "Nko Digit Three" +1988 "Nko Digit Four" +1989 "Nko Digit Five" +1990 "Nko Digit Six" +1991 "Nko Digit Seven" +1992 "Nko Digit Eight" +1993 "Nko Digit Nine" +1994 "Nko Letter A" +1995 "Nko Letter Ee" +1996 "Nko Letter I" +1997 "Nko Letter E" +1998 "Nko Letter U" +1999 "Nko Letter Oo" +2000 "Nko Letter O" +2001 "Nko Letter Dagbasinna" +2002 "Nko Letter N" +2003 "Nko Letter Ba" +2004 "Nko Letter Pa" +2005 "Nko Letter Ta" +2006 "Nko Letter Ja" +2007 "Nko Letter Cha" +2008 "Nko Letter Da" +2009 "Nko Letter Ra" +2010 "Nko Letter Rra" +2011 "Nko Letter Sa" +2012 "Nko Letter Gba" +2013 "Nko Letter Fa" +2014 "Nko Letter Ka" +2015 "Nko Letter La" +2016 "Nko Letter Na Woloso" +2017 "Nko Letter Ma" +2018 "Nko Letter Nya" +2019 "Nko Letter Na" +2020 "Nko Letter Ha" +2021 "Nko Letter Wa" +2022 "Nko Letter Ya" +2023 "Nko Letter Nya Woloso" +2024 "Nko Letter Jona Ja" +2025 "Nko Letter Jona Cha" +2026 "Nko Letter Jona Ra" +2027 "Nko Combining Short High Tone" +2028 "Nko Combining Short Low Tone" +2029 "Nko Combining Short Rising Tone" +2030 "Nko Combining Long Descending Tone" +2031 "Nko Combining Long High Tone" +2032 "Nko Combining Long Low Tone" +2033 "Nko Combining Long Rising Tone" +2034 "Nko Combining Nasalization Mark" +2035 "Nko Combining Double Dot Above" +2036 "Nko High Tone Apostrophe" +2037 "Nko Low Tone Apostrophe" +2038 "Nko Symbol Oo Dennen" +2039 "Nko Symbol Gbakurunen" +2040 "Nko Comma" +2041 "Nko Exclamation Mark" +2042 "Nko Lajanyalan" +2048 "Samaritan Letter Alaf" +2049 "Samaritan Letter Bit" +2050 "Samaritan Letter Gaman" +2051 "Samaritan Letter Dalat" +2052 "Samaritan Letter Iy" +2053 "Samaritan Letter Baa" +2054 "Samaritan Letter Zen" +2055 "Samaritan Letter It" +2056 "Samaritan Letter Tit" +2057 "Samaritan Letter Yut" +2058 "Samaritan Letter Kaaf" +2059 "Samaritan Letter Labat" +2060 "Samaritan Letter Mim" +2061 "Samaritan Letter Nun" +2062 "Samaritan Letter Singaat" +2063 "Samaritan Letter In" +2064 "Samaritan Letter Fi" +2065 "Samaritan Letter Tsaadiy" +2066 "Samaritan Letter Quf" +2067 "Samaritan Letter Rish" +2068 "Samaritan Letter Shan" +2069 "Samaritan Letter Taaf" +2070 "Samaritan Mark In" +2071 "Samaritan Mark In-Alaf" +2072 "Samaritan Mark Occlusion" +2073 "Samaritan Mark Dagesh" +2074 "Samaritan Modifier Letter Epenthetic Yut" +2075 "Samaritan Mark Epenthetic Yut" +2076 "Samaritan Vowel Sign Long E" +2077 "Samaritan Vowel Sign E" +2078 "Samaritan Vowel Sign Overlong Aa" +2079 "Samaritan Vowel Sign Long Aa" +2080 "Samaritan Vowel Sign Aa" +2081 "Samaritan Vowel Sign Overlong A" +2082 "Samaritan Vowel Sign Long A" +2083 "Samaritan Vowel Sign A" +2084 "Samaritan Modifier Letter Short A" +2085 "Samaritan Vowel Sign Short A" +2086 "Samaritan Vowel Sign Long U" +2087 "Samaritan Vowel Sign U" +2088 "Samaritan Modifier Letter I" +2089 "Samaritan Vowel Sign Long I" +2090 "Samaritan Vowel Sign I" +2091 "Samaritan Vowel Sign O" +2092 "Samaritan Vowel Sign Sukun" +2093 "Samaritan Mark Nequdaa" +2096 "Samaritan Punctuation Nequdaa" +2097 "Samaritan Punctuation Afsaaq" +2098 "Samaritan Punctuation Anged" +2099 "Samaritan Punctuation Bau" +2100 "Samaritan Punctuation Atmaau" +2101 "Samaritan Punctuation Shiyyaalaa" +2102 "Samaritan Abbreviation Mark" +2103 "Samaritan Punctuation Melodic Qitsa" +2104 "Samaritan Punctuation Ziqaa" +2105 "Samaritan Punctuation Qitsa" +2106 "Samaritan Punctuation Zaef" +2107 "Samaritan Punctuation Turu" +2108 "Samaritan Punctuation Arkaanu" +2109 "Samaritan Punctuation Sof Mashfaat" +2110 "Samaritan Punctuation Annaau" +2112 "Mandaic Letter Halqa" +2113 "Mandaic Letter Ab" +2114 "Mandaic Letter Ag" +2115 "Mandaic Letter Ad" +2116 "Mandaic Letter Ah" +2117 "Mandaic Letter Ushenna" +2118 "Mandaic Letter Az" +2119 "Mandaic Letter It" +2120 "Mandaic Letter Att" +2121 "Mandaic Letter Aksa" +2122 "Mandaic Letter Ak" +2123 "Mandaic Letter Al" +2124 "Mandaic Letter Am" +2125 "Mandaic Letter An" +2126 "Mandaic Letter As" +2127 "Mandaic Letter In" +2128 "Mandaic Letter Ap" +2129 "Mandaic Letter Asz" +2130 "Mandaic Letter Aq" +2131 "Mandaic Letter Ar" +2132 "Mandaic Letter Ash" +2133 "Mandaic Letter At" +2134 "Mandaic Letter Dushenna" +2135 "Mandaic Letter Kad" +2136 "Mandaic Letter Ain" +2137 "Mandaic Affrication Mark" +2138 "Mandaic Vocalization Mark" +2139 "Mandaic Gemination Mark" +2142 "Mandaic Punctuation" +2208 "Arabic Letter Beh With Small V Below" +2210 "Arabic Letter Jeem With Two Dots Above" +2211 "Arabic Letter Tah With Two Dots Above" +2212 "Arabic Letter Feh With Dot Below And Three Dots Above" +2213 "Arabic Letter Qaf With Dot Below" +2214 "Arabic Letter Lam With Double Bar" +2215 "Arabic Letter Meem With Three Dots Above" +2216 "Arabic Letter Yeh With Two Dots Below And Hamza Above" +2217 "Arabic Letter Yeh With Two Dots Below And Dot Above" +2218 "Arabic Letter Reh With Loop" +2219 "Arabic Letter Waw With Dot Within" +2220 "Arabic Letter Rohingya Yeh" +2276 "Arabic Curly Fatha" +2277 "Arabic Curly Damma" +2278 "Arabic Curly Kasra" +2279 "Arabic Curly Fathatan" +2280 "Arabic Curly Dammatan" +2281 "Arabic Curly Kasratan" +2282 "Arabic Tone One Dot Above" +2283 "Arabic Tone Two Dots Above" +2284 "Arabic Tone Loop Above" +2285 "Arabic Tone One Dot Below" +2286 "Arabic Tone Two Dots Below" +2287 "Arabic Tone Loop Below" +2288 "Arabic Open Fathatan" +2289 "Arabic Open Dammatan" +2290 "Arabic Open Kasratan" +2291 "Arabic Small High Waw" +2292 "Arabic Fatha With Ring" +2293 "Arabic Fatha With Dot Above" +2294 "Arabic Kasra With Dot Below" +2295 "Arabic Left Arrowhead Above" +2296 "Arabic Right Arrowhead Above" +2297 "Arabic Left Arrowhead Below" +2298 "Arabic Right Arrowhead Below" +2299 "Arabic Double Right Arrowhead Above" +2300 "Arabic Double Right Arrowhead Above With Dot" +2301 "Arabic Right Arrowhead Above With Dot" +2302 "Arabic Damma With Dot" +2304 "Devanagari Sign Inverted Candrabindu" +2305 "Devanagari Sign Candrabindu" +2306 "Devanagari Sign Anusvara" +2307 "Devanagari Sign Visarga" +2308 "Devanagari Letter Short A" +2309 "Devanagari Letter A" +2310 "Devanagari Letter Aa" +2311 "Devanagari Letter I" +2312 "Devanagari Letter Ii" +2313 "Devanagari Letter U" +2314 "Devanagari Letter Uu" +2315 "Devanagari Letter Vocalic R" +2316 "Devanagari Letter Vocalic L" +2317 "Devanagari Letter Candra E" +2318 "Devanagari Letter Short E" +2319 "Devanagari Letter E" +2320 "Devanagari Letter Ai" +2321 "Devanagari Letter Candra O" +2322 "Devanagari Letter Short O" +2323 "Devanagari Letter O" +2324 "Devanagari Letter Au" +2325 "Devanagari Letter Ka" +2326 "Devanagari Letter Kha" +2327 "Devanagari Letter Ga" +2328 "Devanagari Letter Gha" +2329 "Devanagari Letter Nga" +2330 "Devanagari Letter Ca" +2331 "Devanagari Letter Cha" +2332 "Devanagari Letter Ja" +2333 "Devanagari Letter Jha" +2334 "Devanagari Letter Nya" +2335 "Devanagari Letter Tta" +2336 "Devanagari Letter Ttha" +2337 "Devanagari Letter Dda" +2338 "Devanagari Letter Ddha" +2339 "Devanagari Letter Nna" +2340 "Devanagari Letter Ta" +2341 "Devanagari Letter Tha" +2342 "Devanagari Letter Da" +2343 "Devanagari Letter Dha" +2344 "Devanagari Letter Na" +2345 "Devanagari Letter Nnna" +2346 "Devanagari Letter Pa" +2347 "Devanagari Letter Pha" +2348 "Devanagari Letter Ba" +2349 "Devanagari Letter Bha" +2350 "Devanagari Letter Ma" +2351 "Devanagari Letter Ya" +2352 "Devanagari Letter Ra" +2353 "Devanagari Letter Rra" +2354 "Devanagari Letter La" +2355 "Devanagari Letter Lla" +2356 "Devanagari Letter Llla" +2357 "Devanagari Letter Va" +2358 "Devanagari Letter Sha" +2359 "Devanagari Letter Ssa" +2360 "Devanagari Letter Sa" +2361 "Devanagari Letter Ha" +2362 "Devanagari Vowel Sign Oe" +2363 "Devanagari Vowel Sign Ooe" +2364 "Devanagari Sign Nukta" +2365 "Devanagari Sign Avagraha" +2366 "Devanagari Vowel Sign Aa" +2367 "Devanagari Vowel Sign I" +2368 "Devanagari Vowel Sign Ii" +2369 "Devanagari Vowel Sign U" +2370 "Devanagari Vowel Sign Uu" +2371 "Devanagari Vowel Sign Vocalic R" +2372 "Devanagari Vowel Sign Vocalic Rr" +2373 "Devanagari Vowel Sign Candra E" +2374 "Devanagari Vowel Sign Short E" +2375 "Devanagari Vowel Sign E" +2376 "Devanagari Vowel Sign Ai" +2377 "Devanagari Vowel Sign Candra O" +2378 "Devanagari Vowel Sign Short O" +2379 "Devanagari Vowel Sign O" +2380 "Devanagari Vowel Sign Au" +2381 "Devanagari Sign Virama" +2382 "Devanagari Vowel Sign Prishthamatra E" +2383 "Devanagari Vowel Sign Aw" +2384 "Devanagari Om" +2385 "Devanagari Stress Sign Udatta" +2386 "Devanagari Stress Sign Anudatta" +2387 "Devanagari Grave Accent" +2388 "Devanagari Acute Accent" +2389 "Devanagari Vowel Sign Candra Long E" +2390 "Devanagari Vowel Sign Ue" +2391 "Devanagari Vowel Sign Uue" +2392 "Devanagari Letter Qa" +2393 "Devanagari Letter Khha" +2394 "Devanagari Letter Ghha" +2395 "Devanagari Letter Za" +2396 "Devanagari Letter Dddha" +2397 "Devanagari Letter Rha" +2398 "Devanagari Letter Fa" +2399 "Devanagari Letter Yya" +2400 "Devanagari Letter Vocalic Rr" +2401 "Devanagari Letter Vocalic Ll" +2402 "Devanagari Vowel Sign Vocalic L" +2403 "Devanagari Vowel Sign Vocalic Ll" +2404 "Devanagari Danda" +2405 "Devanagari Double Danda" +2406 "Devanagari Digit Zero" +2407 "Devanagari Digit One" +2408 "Devanagari Digit Two" +2409 "Devanagari Digit Three" +2410 "Devanagari Digit Four" +2411 "Devanagari Digit Five" +2412 "Devanagari Digit Six" +2413 "Devanagari Digit Seven" +2414 "Devanagari Digit Eight" +2415 "Devanagari Digit Nine" +2416 "Devanagari Abbreviation Sign" +2417 "Devanagari Sign High Spacing Dot" +2418 "Devanagari Letter Candra A" +2419 "Devanagari Letter Oe" +2420 "Devanagari Letter Ooe" +2421 "Devanagari Letter Aw" +2422 "Devanagari Letter Ue" +2423 "Devanagari Letter Uue" +2425 "Devanagari Letter Zha" +2426 "Devanagari Letter Heavy Ya" +2427 "Devanagari Letter Gga" +2428 "Devanagari Letter Jja" +2429 "Devanagari Letter Glottal Stop" +2430 "Devanagari Letter Ddda" +2431 "Devanagari Letter Bba" +2433 "Bengali Sign Candrabindu" +2434 "Bengali Sign Anusvara" +2435 "Bengali Sign Visarga" +2437 "Bengali Letter A" +2438 "Bengali Letter Aa" +2439 "Bengali Letter I" +2440 "Bengali Letter Ii" +2441 "Bengali Letter U" +2442 "Bengali Letter Uu" +2443 "Bengali Letter Vocalic R" +2444 "Bengali Letter Vocalic L" +2447 "Bengali Letter E" +2448 "Bengali Letter Ai" +2451 "Bengali Letter O" +2452 "Bengali Letter Au" +2453 "Bengali Letter Ka" +2454 "Bengali Letter Kha" +2455 "Bengali Letter Ga" +2456 "Bengali Letter Gha" +2457 "Bengali Letter Nga" +2458 "Bengali Letter Ca" +2459 "Bengali Letter Cha" +2460 "Bengali Letter Ja" +2461 "Bengali Letter Jha" +2462 "Bengali Letter Nya" +2463 "Bengali Letter Tta" +2464 "Bengali Letter Ttha" +2465 "Bengali Letter Dda" +2466 "Bengali Letter Ddha" +2467 "Bengali Letter Nna" +2468 "Bengali Letter Ta" +2469 "Bengali Letter Tha" +2470 "Bengali Letter Da" +2471 "Bengali Letter Dha" +2472 "Bengali Letter Na" +2474 "Bengali Letter Pa" +2475 "Bengali Letter Pha" +2476 "Bengali Letter Ba" +2477 "Bengali Letter Bha" +2478 "Bengali Letter Ma" +2479 "Bengali Letter Ya" +2480 "Bengali Letter Ra" +2482 "Bengali Letter La" +2486 "Bengali Letter Sha" +2487 "Bengali Letter Ssa" +2488 "Bengali Letter Sa" +2489 "Bengali Letter Ha" +2492 "Bengali Sign Nukta" +2493 "Bengali Sign Avagraha" +2494 "Bengali Vowel Sign Aa" +2495 "Bengali Vowel Sign I" +2496 "Bengali Vowel Sign Ii" +2497 "Bengali Vowel Sign U" +2498 "Bengali Vowel Sign Uu" +2499 "Bengali Vowel Sign Vocalic R" +2500 "Bengali Vowel Sign Vocalic Rr" +2503 "Bengali Vowel Sign E" +2504 "Bengali Vowel Sign Ai" +2507 "Bengali Vowel Sign O" +2508 "Bengali Vowel Sign Au" +2509 "Bengali Sign Virama" +2510 "Bengali Letter Khanda Ta" +2519 "Bengali Au Length Mark" +2524 "Bengali Letter Rra" +2525 "Bengali Letter Rha" +2527 "Bengali Letter Yya" +2528 "Bengali Letter Vocalic Rr" +2529 "Bengali Letter Vocalic Ll" +2530 "Bengali Vowel Sign Vocalic L" +2531 "Bengali Vowel Sign Vocalic Ll" +2534 "Bengali Digit Zero" +2535 "Bengali Digit One" +2536 "Bengali Digit Two" +2537 "Bengali Digit Three" +2538 "Bengali Digit Four" +2539 "Bengali Digit Five" +2540 "Bengali Digit Six" +2541 "Bengali Digit Seven" +2542 "Bengali Digit Eight" +2543 "Bengali Digit Nine" +2544 "Bengali Letter Ra With Middle Diagonal" +2545 "Bengali Letter Ra With Lower Diagonal" +2546 "Bengali Rupee Mark" +2547 "Bengali Rupee Sign" +2548 "Bengali Currency Numerator One" +2549 "Bengali Currency Numerator Two" +2550 "Bengali Currency Numerator Three" +2551 "Bengali Currency Numerator Four" +2552 "Bengali Currency Numerator One Less Than The Denominator" +2553 "Bengali Currency Denominator Sixteen" +2554 "Bengali Isshar" +2555 "Bengali Ganda Mark" +2561 "Gurmukhi Sign Adak Bindi" +2562 "Gurmukhi Sign Bindi" +2563 "Gurmukhi Sign Visarga" +2565 "Gurmukhi Letter A" +2566 "Gurmukhi Letter Aa" +2567 "Gurmukhi Letter I" +2568 "Gurmukhi Letter Ii" +2569 "Gurmukhi Letter U" +2570 "Gurmukhi Letter Uu" +2575 "Gurmukhi Letter Ee" +2576 "Gurmukhi Letter Ai" +2579 "Gurmukhi Letter Oo" +2580 "Gurmukhi Letter Au" +2581 "Gurmukhi Letter Ka" +2582 "Gurmukhi Letter Kha" +2583 "Gurmukhi Letter Ga" +2584 "Gurmukhi Letter Gha" +2585 "Gurmukhi Letter Nga" +2586 "Gurmukhi Letter Ca" +2587 "Gurmukhi Letter Cha" +2588 "Gurmukhi Letter Ja" +2589 "Gurmukhi Letter Jha" +2590 "Gurmukhi Letter Nya" +2591 "Gurmukhi Letter Tta" +2592 "Gurmukhi Letter Ttha" +2593 "Gurmukhi Letter Dda" +2594 "Gurmukhi Letter Ddha" +2595 "Gurmukhi Letter Nna" +2596 "Gurmukhi Letter Ta" +2597 "Gurmukhi Letter Tha" +2598 "Gurmukhi Letter Da" +2599 "Gurmukhi Letter Dha" +2600 "Gurmukhi Letter Na" +2602 "Gurmukhi Letter Pa" +2603 "Gurmukhi Letter Pha" +2604 "Gurmukhi Letter Ba" +2605 "Gurmukhi Letter Bha" +2606 "Gurmukhi Letter Ma" +2607 "Gurmukhi Letter Ya" +2608 "Gurmukhi Letter Ra" +2610 "Gurmukhi Letter La" +2611 "Gurmukhi Letter Lla" +2613 "Gurmukhi Letter Va" +2614 "Gurmukhi Letter Sha" +2616 "Gurmukhi Letter Sa" +2617 "Gurmukhi Letter Ha" +2620 "Gurmukhi Sign Nukta" +2622 "Gurmukhi Vowel Sign Aa" +2623 "Gurmukhi Vowel Sign I" +2624 "Gurmukhi Vowel Sign Ii" +2625 "Gurmukhi Vowel Sign U" +2626 "Gurmukhi Vowel Sign Uu" +2631 "Gurmukhi Vowel Sign Ee" +2632 "Gurmukhi Vowel Sign Ai" +2635 "Gurmukhi Vowel Sign Oo" +2636 "Gurmukhi Vowel Sign Au" +2637 "Gurmukhi Sign Virama" +2641 "Gurmukhi Sign Udaat" +2649 "Gurmukhi Letter Khha" +2650 "Gurmukhi Letter Ghha" +2651 "Gurmukhi Letter Za" +2652 "Gurmukhi Letter Rra" +2654 "Gurmukhi Letter Fa" +2662 "Gurmukhi Digit Zero" +2663 "Gurmukhi Digit One" +2664 "Gurmukhi Digit Two" +2665 "Gurmukhi Digit Three" +2666 "Gurmukhi Digit Four" +2667 "Gurmukhi Digit Five" +2668 "Gurmukhi Digit Six" +2669 "Gurmukhi Digit Seven" +2670 "Gurmukhi Digit Eight" +2671 "Gurmukhi Digit Nine" +2672 "Gurmukhi Tippi" +2673 "Gurmukhi Addak" +2674 "Gurmukhi Iri" +2675 "Gurmukhi Ura" +2676 "Gurmukhi Ek Onkar" +2677 "Gurmukhi Sign Yakash" +2689 "Gujarati Sign Candrabindu" +2690 "Gujarati Sign Anusvara" +2691 "Gujarati Sign Visarga" +2693 "Gujarati Letter A" +2694 "Gujarati Letter Aa" +2695 "Gujarati Letter I" +2696 "Gujarati Letter Ii" +2697 "Gujarati Letter U" +2698 "Gujarati Letter Uu" +2699 "Gujarati Letter Vocalic R" +2700 "Gujarati Letter Vocalic L" +2701 "Gujarati Vowel Candra E" +2703 "Gujarati Letter E" +2704 "Gujarati Letter Ai" +2705 "Gujarati Vowel Candra O" +2707 "Gujarati Letter O" +2708 "Gujarati Letter Au" +2709 "Gujarati Letter Ka" +2710 "Gujarati Letter Kha" +2711 "Gujarati Letter Ga" +2712 "Gujarati Letter Gha" +2713 "Gujarati Letter Nga" +2714 "Gujarati Letter Ca" +2715 "Gujarati Letter Cha" +2716 "Gujarati Letter Ja" +2717 "Gujarati Letter Jha" +2718 "Gujarati Letter Nya" +2719 "Gujarati Letter Tta" +2720 "Gujarati Letter Ttha" +2721 "Gujarati Letter Dda" +2722 "Gujarati Letter Ddha" +2723 "Gujarati Letter Nna" +2724 "Gujarati Letter Ta" +2725 "Gujarati Letter Tha" +2726 "Gujarati Letter Da" +2727 "Gujarati Letter Dha" +2728 "Gujarati Letter Na" +2730 "Gujarati Letter Pa" +2731 "Gujarati Letter Pha" +2732 "Gujarati Letter Ba" +2733 "Gujarati Letter Bha" +2734 "Gujarati Letter Ma" +2735 "Gujarati Letter Ya" +2736 "Gujarati Letter Ra" +2738 "Gujarati Letter La" +2739 "Gujarati Letter Lla" +2741 "Gujarati Letter Va" +2742 "Gujarati Letter Sha" +2743 "Gujarati Letter Ssa" +2744 "Gujarati Letter Sa" +2745 "Gujarati Letter Ha" +2748 "Gujarati Sign Nukta" +2749 "Gujarati Sign Avagraha" +2750 "Gujarati Vowel Sign Aa" +2751 "Gujarati Vowel Sign I" +2752 "Gujarati Vowel Sign Ii" +2753 "Gujarati Vowel Sign U" +2754 "Gujarati Vowel Sign Uu" +2755 "Gujarati Vowel Sign Vocalic R" +2756 "Gujarati Vowel Sign Vocalic Rr" +2757 "Gujarati Vowel Sign Candra E" +2759 "Gujarati Vowel Sign E" +2760 "Gujarati Vowel Sign Ai" +2761 "Gujarati Vowel Sign Candra O" +2763 "Gujarati Vowel Sign O" +2764 "Gujarati Vowel Sign Au" +2765 "Gujarati Sign Virama" +2768 "Gujarati Om" +2784 "Gujarati Letter Vocalic Rr" +2785 "Gujarati Letter Vocalic Ll" +2786 "Gujarati Vowel Sign Vocalic L" +2787 "Gujarati Vowel Sign Vocalic Ll" +2790 "Gujarati Digit Zero" +2791 "Gujarati Digit One" +2792 "Gujarati Digit Two" +2793 "Gujarati Digit Three" +2794 "Gujarati Digit Four" +2795 "Gujarati Digit Five" +2796 "Gujarati Digit Six" +2797 "Gujarati Digit Seven" +2798 "Gujarati Digit Eight" +2799 "Gujarati Digit Nine" +2800 "Gujarati Abbreviation Sign" +2801 "Gujarati Rupee Sign" +2817 "Oriya Sign Candrabindu" +2818 "Oriya Sign Anusvara" +2819 "Oriya Sign Visarga" +2821 "Oriya Letter A" +2822 "Oriya Letter Aa" +2823 "Oriya Letter I" +2824 "Oriya Letter Ii" +2825 "Oriya Letter U" +2826 "Oriya Letter Uu" +2827 "Oriya Letter Vocalic R" +2828 "Oriya Letter Vocalic L" +2831 "Oriya Letter E" +2832 "Oriya Letter Ai" +2835 "Oriya Letter O" +2836 "Oriya Letter Au" +2837 "Oriya Letter Ka" +2838 "Oriya Letter Kha" +2839 "Oriya Letter Ga" +2840 "Oriya Letter Gha" +2841 "Oriya Letter Nga" +2842 "Oriya Letter Ca" +2843 "Oriya Letter Cha" +2844 "Oriya Letter Ja" +2845 "Oriya Letter Jha" +2846 "Oriya Letter Nya" +2847 "Oriya Letter Tta" +2848 "Oriya Letter Ttha" +2849 "Oriya Letter Dda" +2850 "Oriya Letter Ddha" +2851 "Oriya Letter Nna" +2852 "Oriya Letter Ta" +2853 "Oriya Letter Tha" +2854 "Oriya Letter Da" +2855 "Oriya Letter Dha" +2856 "Oriya Letter Na" +2858 "Oriya Letter Pa" +2859 "Oriya Letter Pha" +2860 "Oriya Letter Ba" +2861 "Oriya Letter Bha" +2862 "Oriya Letter Ma" +2863 "Oriya Letter Ya" +2864 "Oriya Letter Ra" +2866 "Oriya Letter La" +2867 "Oriya Letter Lla" +2869 "Oriya Letter Va" +2870 "Oriya Letter Sha" +2871 "Oriya Letter Ssa" +2872 "Oriya Letter Sa" +2873 "Oriya Letter Ha" +2876 "Oriya Sign Nukta" +2877 "Oriya Sign Avagraha" +2878 "Oriya Vowel Sign Aa" +2879 "Oriya Vowel Sign I" +2880 "Oriya Vowel Sign Ii" +2881 "Oriya Vowel Sign U" +2882 "Oriya Vowel Sign Uu" +2883 "Oriya Vowel Sign Vocalic R" +2884 "Oriya Vowel Sign Vocalic Rr" +2887 "Oriya Vowel Sign E" +2888 "Oriya Vowel Sign Ai" +2891 "Oriya Vowel Sign O" +2892 "Oriya Vowel Sign Au" +2893 "Oriya Sign Virama" +2902 "Oriya Ai Length Mark" +2903 "Oriya Au Length Mark" +2908 "Oriya Letter Rra" +2909 "Oriya Letter Rha" +2911 "Oriya Letter Yya" +2912 "Oriya Letter Vocalic Rr" +2913 "Oriya Letter Vocalic Ll" +2914 "Oriya Vowel Sign Vocalic L" +2915 "Oriya Vowel Sign Vocalic Ll" +2918 "Oriya Digit Zero" +2919 "Oriya Digit One" +2920 "Oriya Digit Two" +2921 "Oriya Digit Three" +2922 "Oriya Digit Four" +2923 "Oriya Digit Five" +2924 "Oriya Digit Six" +2925 "Oriya Digit Seven" +2926 "Oriya Digit Eight" +2927 "Oriya Digit Nine" +2928 "Oriya Isshar" +2929 "Oriya Letter Wa" +2930 "Oriya Fraction One Quarter" +2931 "Oriya Fraction One Half" +2932 "Oriya Fraction Three Quarters" +2933 "Oriya Fraction One Sixteenth" +2934 "Oriya Fraction One Eighth" +2935 "Oriya Fraction Three Sixteenths" +2946 "Tamil Sign Anusvara" +2947 "Tamil Sign Visarga" +2949 "Tamil Letter A" +2950 "Tamil Letter Aa" +2951 "Tamil Letter I" +2952 "Tamil Letter Ii" +2953 "Tamil Letter U" +2954 "Tamil Letter Uu" +2958 "Tamil Letter E" +2959 "Tamil Letter Ee" +2960 "Tamil Letter Ai" +2962 "Tamil Letter O" +2963 "Tamil Letter Oo" +2964 "Tamil Letter Au" +2965 "Tamil Letter Ka" +2969 "Tamil Letter Nga" +2970 "Tamil Letter Ca" +2972 "Tamil Letter Ja" +2974 "Tamil Letter Nya" +2975 "Tamil Letter Tta" +2979 "Tamil Letter Nna" +2980 "Tamil Letter Ta" +2984 "Tamil Letter Na" +2985 "Tamil Letter Nnna" +2986 "Tamil Letter Pa" +2990 "Tamil Letter Ma" +2991 "Tamil Letter Ya" +2992 "Tamil Letter Ra" +2993 "Tamil Letter Rra" +2994 "Tamil Letter La" +2995 "Tamil Letter Lla" +2996 "Tamil Letter Llla" +2997 "Tamil Letter Va" +2998 "Tamil Letter Sha" +2999 "Tamil Letter Ssa" +3000 "Tamil Letter Sa" +3001 "Tamil Letter Ha" +3006 "Tamil Vowel Sign Aa" +3007 "Tamil Vowel Sign I" +3008 "Tamil Vowel Sign Ii" +3009 "Tamil Vowel Sign U" +3010 "Tamil Vowel Sign Uu" +3014 "Tamil Vowel Sign E" +3015 "Tamil Vowel Sign Ee" +3016 "Tamil Vowel Sign Ai" +3018 "Tamil Vowel Sign O" +3019 "Tamil Vowel Sign Oo" +3020 "Tamil Vowel Sign Au" +3021 "Tamil Sign Virama" +3024 "Tamil Om" +3031 "Tamil Au Length Mark" +3046 "Tamil Digit Zero" +3047 "Tamil Digit One" +3048 "Tamil Digit Two" +3049 "Tamil Digit Three" +3050 "Tamil Digit Four" +3051 "Tamil Digit Five" +3052 "Tamil Digit Six" +3053 "Tamil Digit Seven" +3054 "Tamil Digit Eight" +3055 "Tamil Digit Nine" +3056 "Tamil Number Ten" +3057 "Tamil Number One Hundred" +3058 "Tamil Number One Thousand" +3059 "Tamil Day Sign" +3060 "Tamil Month Sign" +3061 "Tamil Year Sign" +3062 "Tamil Debit Sign" +3063 "Tamil Credit Sign" +3064 "Tamil As Above Sign" +3065 "Tamil Rupee Sign" +3066 "Tamil Number Sign" +3073 "Telugu Sign Candrabindu" +3074 "Telugu Sign Anusvara" +3075 "Telugu Sign Visarga" +3077 "Telugu Letter A" +3078 "Telugu Letter Aa" +3079 "Telugu Letter I" +3080 "Telugu Letter Ii" +3081 "Telugu Letter U" +3082 "Telugu Letter Uu" +3083 "Telugu Letter Vocalic R" +3084 "Telugu Letter Vocalic L" +3086 "Telugu Letter E" +3087 "Telugu Letter Ee" +3088 "Telugu Letter Ai" +3090 "Telugu Letter O" +3091 "Telugu Letter Oo" +3092 "Telugu Letter Au" +3093 "Telugu Letter Ka" +3094 "Telugu Letter Kha" +3095 "Telugu Letter Ga" +3096 "Telugu Letter Gha" +3097 "Telugu Letter Nga" +3098 "Telugu Letter Ca" +3099 "Telugu Letter Cha" +3100 "Telugu Letter Ja" +3101 "Telugu Letter Jha" +3102 "Telugu Letter Nya" +3103 "Telugu Letter Tta" +3104 "Telugu Letter Ttha" +3105 "Telugu Letter Dda" +3106 "Telugu Letter Ddha" +3107 "Telugu Letter Nna" +3108 "Telugu Letter Ta" +3109 "Telugu Letter Tha" +3110 "Telugu Letter Da" +3111 "Telugu Letter Dha" +3112 "Telugu Letter Na" +3114 "Telugu Letter Pa" +3115 "Telugu Letter Pha" +3116 "Telugu Letter Ba" +3117 "Telugu Letter Bha" +3118 "Telugu Letter Ma" +3119 "Telugu Letter Ya" +3120 "Telugu Letter Ra" +3121 "Telugu Letter Rra" +3122 "Telugu Letter La" +3123 "Telugu Letter Lla" +3125 "Telugu Letter Va" +3126 "Telugu Letter Sha" +3127 "Telugu Letter Ssa" +3128 "Telugu Letter Sa" +3129 "Telugu Letter Ha" +3133 "Telugu Sign Avagraha" +3134 "Telugu Vowel Sign Aa" +3135 "Telugu Vowel Sign I" +3136 "Telugu Vowel Sign Ii" +3137 "Telugu Vowel Sign U" +3138 "Telugu Vowel Sign Uu" +3139 "Telugu Vowel Sign Vocalic R" +3140 "Telugu Vowel Sign Vocalic Rr" +3142 "Telugu Vowel Sign E" +3143 "Telugu Vowel Sign Ee" +3144 "Telugu Vowel Sign Ai" +3146 "Telugu Vowel Sign O" +3147 "Telugu Vowel Sign Oo" +3148 "Telugu Vowel Sign Au" +3149 "Telugu Sign Virama" +3157 "Telugu Length Mark" +3158 "Telugu Ai Length Mark" +3160 "Telugu Letter Tsa" +3161 "Telugu Letter Dza" +3168 "Telugu Letter Vocalic Rr" +3169 "Telugu Letter Vocalic Ll" +3170 "Telugu Vowel Sign Vocalic L" +3171 "Telugu Vowel Sign Vocalic Ll" +3174 "Telugu Digit Zero" +3175 "Telugu Digit One" +3176 "Telugu Digit Two" +3177 "Telugu Digit Three" +3178 "Telugu Digit Four" +3179 "Telugu Digit Five" +3180 "Telugu Digit Six" +3181 "Telugu Digit Seven" +3182 "Telugu Digit Eight" +3183 "Telugu Digit Nine" +3192 "Telugu Fraction Digit Zero For Odd Powers Of Four" +3193 "Telugu Fraction Digit One For Odd Powers Of Four" +3194 "Telugu Fraction Digit Two For Odd Powers Of Four" +3195 "Telugu Fraction Digit Three For Odd Powers Of Four" +3196 "Telugu Fraction Digit One For Even Powers Of Four" +3197 "Telugu Fraction Digit Two For Even Powers Of Four" +3198 "Telugu Fraction Digit Three For Even Powers Of Four" +3199 "Telugu Sign Tuumu" +3202 "Kannada Sign Anusvara" +3203 "Kannada Sign Visarga" +3205 "Kannada Letter A" +3206 "Kannada Letter Aa" +3207 "Kannada Letter I" +3208 "Kannada Letter Ii" +3209 "Kannada Letter U" +3210 "Kannada Letter Uu" +3211 "Kannada Letter Vocalic R" +3212 "Kannada Letter Vocalic L" +3214 "Kannada Letter E" +3215 "Kannada Letter Ee" +3216 "Kannada Letter Ai" +3218 "Kannada Letter O" +3219 "Kannada Letter Oo" +3220 "Kannada Letter Au" +3221 "Kannada Letter Ka" +3222 "Kannada Letter Kha" +3223 "Kannada Letter Ga" +3224 "Kannada Letter Gha" +3225 "Kannada Letter Nga" +3226 "Kannada Letter Ca" +3227 "Kannada Letter Cha" +3228 "Kannada Letter Ja" +3229 "Kannada Letter Jha" +3230 "Kannada Letter Nya" +3231 "Kannada Letter Tta" +3232 "Kannada Letter Ttha" +3233 "Kannada Letter Dda" +3234 "Kannada Letter Ddha" +3235 "Kannada Letter Nna" +3236 "Kannada Letter Ta" +3237 "Kannada Letter Tha" +3238 "Kannada Letter Da" +3239 "Kannada Letter Dha" +3240 "Kannada Letter Na" +3242 "Kannada Letter Pa" +3243 "Kannada Letter Pha" +3244 "Kannada Letter Ba" +3245 "Kannada Letter Bha" +3246 "Kannada Letter Ma" +3247 "Kannada Letter Ya" +3248 "Kannada Letter Ra" +3249 "Kannada Letter Rra" +3250 "Kannada Letter La" +3251 "Kannada Letter Lla" +3253 "Kannada Letter Va" +3254 "Kannada Letter Sha" +3255 "Kannada Letter Ssa" +3256 "Kannada Letter Sa" +3257 "Kannada Letter Ha" +3260 "Kannada Sign Nukta" +3261 "Kannada Sign Avagraha" +3262 "Kannada Vowel Sign Aa" +3263 "Kannada Vowel Sign I" +3264 "Kannada Vowel Sign Ii" +3265 "Kannada Vowel Sign U" +3266 "Kannada Vowel Sign Uu" +3267 "Kannada Vowel Sign Vocalic R" +3268 "Kannada Vowel Sign Vocalic Rr" +3270 "Kannada Vowel Sign E" +3271 "Kannada Vowel Sign Ee" +3272 "Kannada Vowel Sign Ai" +3274 "Kannada Vowel Sign O" +3275 "Kannada Vowel Sign Oo" +3276 "Kannada Vowel Sign Au" +3277 "Kannada Sign Virama" +3285 "Kannada Length Mark" +3286 "Kannada Ai Length Mark" +3294 "Kannada Letter Fa" +3296 "Kannada Letter Vocalic Rr" +3297 "Kannada Letter Vocalic Ll" +3298 "Kannada Vowel Sign Vocalic L" +3299 "Kannada Vowel Sign Vocalic Ll" +3302 "Kannada Digit Zero" +3303 "Kannada Digit One" +3304 "Kannada Digit Two" +3305 "Kannada Digit Three" +3306 "Kannada Digit Four" +3307 "Kannada Digit Five" +3308 "Kannada Digit Six" +3309 "Kannada Digit Seven" +3310 "Kannada Digit Eight" +3311 "Kannada Digit Nine" +3313 "Kannada Sign Jihvamuliya" +3314 "Kannada Sign Upadhmaniya" +3330 "Malayalam Sign Anusvara" +3331 "Malayalam Sign Visarga" +3333 "Malayalam Letter A" +3334 "Malayalam Letter Aa" +3335 "Malayalam Letter I" +3336 "Malayalam Letter Ii" +3337 "Malayalam Letter U" +3338 "Malayalam Letter Uu" +3339 "Malayalam Letter Vocalic R" +3340 "Malayalam Letter Vocalic L" +3342 "Malayalam Letter E" +3343 "Malayalam Letter Ee" +3344 "Malayalam Letter Ai" +3346 "Malayalam Letter O" +3347 "Malayalam Letter Oo" +3348 "Malayalam Letter Au" +3349 "Malayalam Letter Ka" +3350 "Malayalam Letter Kha" +3351 "Malayalam Letter Ga" +3352 "Malayalam Letter Gha" +3353 "Malayalam Letter Nga" +3354 "Malayalam Letter Ca" +3355 "Malayalam Letter Cha" +3356 "Malayalam Letter Ja" +3357 "Malayalam Letter Jha" +3358 "Malayalam Letter Nya" +3359 "Malayalam Letter Tta" +3360 "Malayalam Letter Ttha" +3361 "Malayalam Letter Dda" +3362 "Malayalam Letter Ddha" +3363 "Malayalam Letter Nna" +3364 "Malayalam Letter Ta" +3365 "Malayalam Letter Tha" +3366 "Malayalam Letter Da" +3367 "Malayalam Letter Dha" +3368 "Malayalam Letter Na" +3369 "Malayalam Letter Nnna" +3370 "Malayalam Letter Pa" +3371 "Malayalam Letter Pha" +3372 "Malayalam Letter Ba" +3373 "Malayalam Letter Bha" +3374 "Malayalam Letter Ma" +3375 "Malayalam Letter Ya" +3376 "Malayalam Letter Ra" +3377 "Malayalam Letter Rra" +3378 "Malayalam Letter La" +3379 "Malayalam Letter Lla" +3380 "Malayalam Letter Llla" +3381 "Malayalam Letter Va" +3382 "Malayalam Letter Sha" +3383 "Malayalam Letter Ssa" +3384 "Malayalam Letter Sa" +3385 "Malayalam Letter Ha" +3386 "Malayalam Letter Ttta" +3389 "Malayalam Sign Avagraha" +3390 "Malayalam Vowel Sign Aa" +3391 "Malayalam Vowel Sign I" +3392 "Malayalam Vowel Sign Ii" +3393 "Malayalam Vowel Sign U" +3394 "Malayalam Vowel Sign Uu" +3395 "Malayalam Vowel Sign Vocalic R" +3396 "Malayalam Vowel Sign Vocalic Rr" +3398 "Malayalam Vowel Sign E" +3399 "Malayalam Vowel Sign Ee" +3400 "Malayalam Vowel Sign Ai" +3402 "Malayalam Vowel Sign O" +3403 "Malayalam Vowel Sign Oo" +3404 "Malayalam Vowel Sign Au" +3405 "Malayalam Sign Virama" +3406 "Malayalam Letter Dot Reph" +3415 "Malayalam Au Length Mark" +3424 "Malayalam Letter Vocalic Rr" +3425 "Malayalam Letter Vocalic Ll" +3426 "Malayalam Vowel Sign Vocalic L" +3427 "Malayalam Vowel Sign Vocalic Ll" +3430 "Malayalam Digit Zero" +3431 "Malayalam Digit One" +3432 "Malayalam Digit Two" +3433 "Malayalam Digit Three" +3434 "Malayalam Digit Four" +3435 "Malayalam Digit Five" +3436 "Malayalam Digit Six" +3437 "Malayalam Digit Seven" +3438 "Malayalam Digit Eight" +3439 "Malayalam Digit Nine" +3440 "Malayalam Number Ten" +3441 "Malayalam Number One Hundred" +3442 "Malayalam Number One Thousand" +3443 "Malayalam Fraction One Quarter" +3444 "Malayalam Fraction One Half" +3445 "Malayalam Fraction Three Quarters" +3449 "Malayalam Date Mark" +3450 "Malayalam Letter Chillu Nn" +3451 "Malayalam Letter Chillu N" +3452 "Malayalam Letter Chillu Rr" +3453 "Malayalam Letter Chillu L" +3454 "Malayalam Letter Chillu Ll" +3455 "Malayalam Letter Chillu K" +3458 "Sinhala Sign Anusvaraya" +3459 "Sinhala Sign Visargaya" +3461 "Sinhala Letter Ayanna" +3462 "Sinhala Letter Aayanna" +3463 "Sinhala Letter Aeyanna" +3464 "Sinhala Letter Aeeyanna" +3465 "Sinhala Letter Iyanna" +3466 "Sinhala Letter Iiyanna" +3467 "Sinhala Letter Uyanna" +3468 "Sinhala Letter Uuyanna" +3469 "Sinhala Letter Iruyanna" +3470 "Sinhala Letter Iruuyanna" +3471 "Sinhala Letter Iluyanna" +3472 "Sinhala Letter Iluuyanna" +3473 "Sinhala Letter Eyanna" +3474 "Sinhala Letter Eeyanna" +3475 "Sinhala Letter Aiyanna" +3476 "Sinhala Letter Oyanna" +3477 "Sinhala Letter Ooyanna" +3478 "Sinhala Letter Auyanna" +3482 "Sinhala Letter Alpapraana Kayanna" +3483 "Sinhala Letter Mahaapraana Kayanna" +3484 "Sinhala Letter Alpapraana Gayanna" +3485 "Sinhala Letter Mahaapraana Gayanna" +3486 "Sinhala Letter Kantaja Naasikyaya" +3487 "Sinhala Letter Sanyaka Gayanna" +3488 "Sinhala Letter Alpapraana Cayanna" +3489 "Sinhala Letter Mahaapraana Cayanna" +3490 "Sinhala Letter Alpapraana Jayanna" +3491 "Sinhala Letter Mahaapraana Jayanna" +3492 "Sinhala Letter Taaluja Naasikyaya" +3493 "Sinhala Letter Taaluja Sanyooga Naaksikyaya" +3494 "Sinhala Letter Sanyaka Jayanna" +3495 "Sinhala Letter Alpapraana Ttayanna" +3496 "Sinhala Letter Mahaapraana Ttayanna" +3497 "Sinhala Letter Alpapraana Ddayanna" +3498 "Sinhala Letter Mahaapraana Ddayanna" +3499 "Sinhala Letter Muurdhaja Nayanna" +3500 "Sinhala Letter Sanyaka Ddayanna" +3501 "Sinhala Letter Alpapraana Tayanna" +3502 "Sinhala Letter Mahaapraana Tayanna" +3503 "Sinhala Letter Alpapraana Dayanna" +3504 "Sinhala Letter Mahaapraana Dayanna" +3505 "Sinhala Letter Dantaja Nayanna" +3507 "Sinhala Letter Sanyaka Dayanna" +3508 "Sinhala Letter Alpapraana Payanna" +3509 "Sinhala Letter Mahaapraana Payanna" +3510 "Sinhala Letter Alpapraana Bayanna" +3511 "Sinhala Letter Mahaapraana Bayanna" +3512 "Sinhala Letter Mayanna" +3513 "Sinhala Letter Amba Bayanna" +3514 "Sinhala Letter Yayanna" +3515 "Sinhala Letter Rayanna" +3517 "Sinhala Letter Dantaja Layanna" +3520 "Sinhala Letter Vayanna" +3521 "Sinhala Letter Taaluja Sayanna" +3522 "Sinhala Letter Muurdhaja Sayanna" +3523 "Sinhala Letter Dantaja Sayanna" +3524 "Sinhala Letter Hayanna" +3525 "Sinhala Letter Muurdhaja Layanna" +3526 "Sinhala Letter Fayanna" +3530 "Sinhala Sign Al-Lakuna" +3535 "Sinhala Vowel Sign Aela-Pilla" +3536 "Sinhala Vowel Sign Ketti Aeda-Pilla" +3537 "Sinhala Vowel Sign Diga Aeda-Pilla" +3538 "Sinhala Vowel Sign Ketti Is-Pilla" +3539 "Sinhala Vowel Sign Diga Is-Pilla" +3540 "Sinhala Vowel Sign Ketti Paa-Pilla" +3542 "Sinhala Vowel Sign Diga Paa-Pilla" +3544 "Sinhala Vowel Sign Gaetta-Pilla" +3545 "Sinhala Vowel Sign Kombuva" +3546 "Sinhala Vowel Sign Diga Kombuva" +3547 "Sinhala Vowel Sign Kombu Deka" +3548 "Sinhala Vowel Sign Kombuva Haa Aela-Pilla" +3549 "Sinhala Vowel Sign Kombuva Haa Diga Aela-Pilla" +3550 "Sinhala Vowel Sign Kombuva Haa Gayanukitta" +3551 "Sinhala Vowel Sign Gayanukitta" +3570 "Sinhala Vowel Sign Diga Gaetta-Pilla" +3571 "Sinhala Vowel Sign Diga Gayanukitta" +3572 "Sinhala Punctuation Kunddaliya" +3585 "Thai Character Ko Kai" +3586 "Thai Character Kho Khai" +3587 "Thai Character Kho Khuat" +3588 "Thai Character Kho Khwai" +3589 "Thai Character Kho Khon" +3590 "Thai Character Kho Rakhang" +3591 "Thai Character Ngo Ngu" +3592 "Thai Character Cho Chan" +3593 "Thai Character Cho Ching" +3594 "Thai Character Cho Chang" +3595 "Thai Character So So" +3596 "Thai Character Cho Choe" +3597 "Thai Character Yo Ying" +3598 "Thai Character Do Chada" +3599 "Thai Character To Patak" +3600 "Thai Character Tho Than" +3601 "Thai Character Tho Nangmontho" +3602 "Thai Character Tho Phuthao" +3603 "Thai Character No Nen" +3604 "Thai Character Do Dek" +3605 "Thai Character To Tao" +3606 "Thai Character Tho Thung" +3607 "Thai Character Tho Thahan" +3608 "Thai Character Tho Thong" +3609 "Thai Character No Nu" +3610 "Thai Character Bo Baimai" +3611 "Thai Character Po Pla" +3612 "Thai Character Pho Phung" +3613 "Thai Character Fo Fa" +3614 "Thai Character Pho Phan" +3615 "Thai Character Fo Fan" +3616 "Thai Character Pho Samphao" +3617 "Thai Character Mo Ma" +3618 "Thai Character Yo Yak" +3619 "Thai Character Ro Rua" +3620 "Thai Character Ru" +3621 "Thai Character Lo Ling" +3622 "Thai Character Lu" +3623 "Thai Character Wo Waen" +3624 "Thai Character So Sala" +3625 "Thai Character So Rusi" +3626 "Thai Character So Sua" +3627 "Thai Character Ho Hip" +3628 "Thai Character Lo Chula" +3629 "Thai Character O Ang" +3630 "Thai Character Ho Nokhuk" +3631 "Thai Character Paiyannoi" +3632 "Thai Character Sara A" +3633 "Thai Character Mai Han-Akat" +3634 "Thai Character Sara Aa" +3635 "Thai Character Sara Am" +3636 "Thai Character Sara I" +3637 "Thai Character Sara Ii" +3638 "Thai Character Sara Ue" +3639 "Thai Character Sara Uee" +3640 "Thai Character Sara U" +3641 "Thai Character Sara Uu" +3642 "Thai Character Phinthu" +3647 "Thai Currency Symbol Baht" +3648 "Thai Character Sara E" +3649 "Thai Character Sara Ae" +3650 "Thai Character Sara O" +3651 "Thai Character Sara Ai Maimuan" +3652 "Thai Character Sara Ai Maimalai" +3653 "Thai Character Lakkhangyao" +3654 "Thai Character Maiyamok" +3655 "Thai Character Maitaikhu" +3656 "Thai Character Mai Ek" +3657 "Thai Character Mai Tho" +3658 "Thai Character Mai Tri" +3659 "Thai Character Mai Chattawa" +3660 "Thai Character Thanthakhat" +3661 "Thai Character Nikhahit" +3662 "Thai Character Yamakkan" +3663 "Thai Character Fongman" +3664 "Thai Digit Zero" +3665 "Thai Digit One" +3666 "Thai Digit Two" +3667 "Thai Digit Three" +3668 "Thai Digit Four" +3669 "Thai Digit Five" +3670 "Thai Digit Six" +3671 "Thai Digit Seven" +3672 "Thai Digit Eight" +3673 "Thai Digit Nine" +3674 "Thai Character Angkhankhu" +3675 "Thai Character Khomut" +3713 "Lao Letter Ko" +3714 "Lao Letter Kho Sung" +3716 "Lao Letter Kho Tam" +3719 "Lao Letter Ngo" +3720 "Lao Letter Co" +3722 "Lao Letter So Tam" +3725 "Lao Letter Nyo" +3732 "Lao Letter Do" +3733 "Lao Letter To" +3734 "Lao Letter Tho Sung" +3735 "Lao Letter Tho Tam" +3737 "Lao Letter No" +3738 "Lao Letter Bo" +3739 "Lao Letter Po" +3740 "Lao Letter Pho Sung" +3741 "Lao Letter Fo Tam" +3742 "Lao Letter Pho Tam" +3743 "Lao Letter Fo Sung" +3745 "Lao Letter Mo" +3746 "Lao Letter Yo" +3747 "Lao Letter Lo Ling" +3749 "Lao Letter Lo Loot" +3751 "Lao Letter Wo" +3754 "Lao Letter So Sung" +3755 "Lao Letter Ho Sung" +3757 "Lao Letter O" +3758 "Lao Letter Ho Tam" +3759 "Lao Ellipsis" +3760 "Lao Vowel Sign A" +3761 "Lao Vowel Sign Mai Kan" +3762 "Lao Vowel Sign Aa" +3763 "Lao Vowel Sign Am" +3764 "Lao Vowel Sign I" +3765 "Lao Vowel Sign Ii" +3766 "Lao Vowel Sign Y" +3767 "Lao Vowel Sign Yy" +3768 "Lao Vowel Sign U" +3769 "Lao Vowel Sign Uu" +3771 "Lao Vowel Sign Mai Kon" +3772 "Lao Semivowel Sign Lo" +3773 "Lao Semivowel Sign Nyo" +3776 "Lao Vowel Sign E" +3777 "Lao Vowel Sign Ei" +3778 "Lao Vowel Sign O" +3779 "Lao Vowel Sign Ay" +3780 "Lao Vowel Sign Ai" +3782 "Lao Ko La" +3784 "Lao Tone Mai Ek" +3785 "Lao Tone Mai Tho" +3786 "Lao Tone Mai Ti" +3787 "Lao Tone Mai Catawa" +3788 "Lao Cancellation Mark" +3789 "Lao Niggahita" +3792 "Lao Digit Zero" +3793 "Lao Digit One" +3794 "Lao Digit Two" +3795 "Lao Digit Three" +3796 "Lao Digit Four" +3797 "Lao Digit Five" +3798 "Lao Digit Six" +3799 "Lao Digit Seven" +3800 "Lao Digit Eight" +3801 "Lao Digit Nine" +3804 "Lao Ho No" +3805 "Lao Ho Mo" +3806 "Lao Letter Khmu Go" +3807 "Lao Letter Khmu Nyo" +3840 "Tibetan Syllable Om" +3841 "Tibetan Mark Gter Yig Mgo Truncated A" +3842 "Tibetan Mark Gter Yig Mgo -Um Rnam Bcad Ma" +3843 "Tibetan Mark Gter Yig Mgo -Um Gter Tsheg Ma" +3844 "Tibetan Mark Initial Yig Mgo Mdun Ma" +3845 "Tibetan Mark Closing Yig Mgo Sgab Ma" +3846 "Tibetan Mark Caret Yig Mgo Phur Shad Ma" +3847 "Tibetan Mark Yig Mgo Tsheg Shad Ma" +3848 "Tibetan Mark Sbrul Shad" +3849 "Tibetan Mark Bskur Yig Mgo" +3850 "Tibetan Mark Bka- Shog Yig Mgo" +3851 "Tibetan Mark Intersyllabic Tsheg" +3852 "Tibetan Mark Delimiter Tsheg Bstar" +3853 "Tibetan Mark Shad" +3854 "Tibetan Mark Nyis Shad" +3855 "Tibetan Mark Tsheg Shad" +3856 "Tibetan Mark Nyis Tsheg Shad" +3857 "Tibetan Mark Rin Chen Spungs Shad" +3858 "Tibetan Mark Rgya Gram Shad" +3859 "Tibetan Mark Caret -Dzud Rtags Me Long Can" +3860 "Tibetan Mark Gter Tsheg" +3861 "Tibetan Logotype Sign Chad Rtags" +3862 "Tibetan Logotype Sign Lhag Rtags" +3863 "Tibetan Astrological Sign Sgra Gcan -Char Rtags" +3864 "Tibetan Astrological Sign -Khyud Pa" +3865 "Tibetan Astrological Sign Sdong Tshugs" +3866 "Tibetan Sign Rdel Dkar Gcig" +3867 "Tibetan Sign Rdel Dkar Gnyis" +3868 "Tibetan Sign Rdel Dkar Gsum" +3869 "Tibetan Sign Rdel Nag Gcig" +3870 "Tibetan Sign Rdel Nag Gnyis" +3871 "Tibetan Sign Rdel Dkar Rdel Nag" +3872 "Tibetan Digit Zero" +3873 "Tibetan Digit One" +3874 "Tibetan Digit Two" +3875 "Tibetan Digit Three" +3876 "Tibetan Digit Four" +3877 "Tibetan Digit Five" +3878 "Tibetan Digit Six" +3879 "Tibetan Digit Seven" +3880 "Tibetan Digit Eight" +3881 "Tibetan Digit Nine" +3882 "Tibetan Digit Half One" +3883 "Tibetan Digit Half Two" +3884 "Tibetan Digit Half Three" +3885 "Tibetan Digit Half Four" +3886 "Tibetan Digit Half Five" +3887 "Tibetan Digit Half Six" +3888 "Tibetan Digit Half Seven" +3889 "Tibetan Digit Half Eight" +3890 "Tibetan Digit Half Nine" +3891 "Tibetan Digit Half Zero" +3892 "Tibetan Mark Bsdus Rtags" +3893 "Tibetan Mark Ngas Bzung Nyi Zla" +3894 "Tibetan Mark Caret -Dzud Rtags Bzhi Mig Can" +3895 "Tibetan Mark Ngas Bzung Sgor Rtags" +3896 "Tibetan Mark Che Mgo" +3897 "Tibetan Mark Tsa -Phru" +3898 "Tibetan Mark Gug Rtags Gyon" +3899 "Tibetan Mark Gug Rtags Gyas" +3900 "Tibetan Mark Ang Khang Gyon" +3901 "Tibetan Mark Ang Khang Gyas" +3902 "Tibetan Sign Yar Tshes" +3903 "Tibetan Sign Mar Tshes" +3904 "Tibetan Letter Ka" +3905 "Tibetan Letter Kha" +3906 "Tibetan Letter Ga" +3907 "Tibetan Letter Gha" +3908 "Tibetan Letter Nga" +3909 "Tibetan Letter Ca" +3910 "Tibetan Letter Cha" +3911 "Tibetan Letter Ja" +3913 "Tibetan Letter Nya" +3914 "Tibetan Letter Tta" +3915 "Tibetan Letter Ttha" +3916 "Tibetan Letter Dda" +3917 "Tibetan Letter Ddha" +3918 "Tibetan Letter Nna" +3919 "Tibetan Letter Ta" +3920 "Tibetan Letter Tha" +3921 "Tibetan Letter Da" +3922 "Tibetan Letter Dha" +3923 "Tibetan Letter Na" +3924 "Tibetan Letter Pa" +3925 "Tibetan Letter Pha" +3926 "Tibetan Letter Ba" +3927 "Tibetan Letter Bha" +3928 "Tibetan Letter Ma" +3929 "Tibetan Letter Tsa" +3930 "Tibetan Letter Tsha" +3931 "Tibetan Letter Dza" +3932 "Tibetan Letter Dzha" +3933 "Tibetan Letter Wa" +3934 "Tibetan Letter Zha" +3935 "Tibetan Letter Za" +3936 "Tibetan Letter -A" +3937 "Tibetan Letter Ya" +3938 "Tibetan Letter Ra" +3939 "Tibetan Letter La" +3940 "Tibetan Letter Sha" +3941 "Tibetan Letter Ssa" +3942 "Tibetan Letter Sa" +3943 "Tibetan Letter Ha" +3944 "Tibetan Letter A" +3945 "Tibetan Letter Kssa" +3946 "Tibetan Letter Fixed-Form Ra" +3947 "Tibetan Letter Kka" +3948 "Tibetan Letter Rra" +3953 "Tibetan Vowel Sign Aa" +3954 "Tibetan Vowel Sign I" +3955 "Tibetan Vowel Sign Ii" +3956 "Tibetan Vowel Sign U" +3957 "Tibetan Vowel Sign Uu" +3958 "Tibetan Vowel Sign Vocalic R" +3959 "Tibetan Vowel Sign Vocalic Rr" +3960 "Tibetan Vowel Sign Vocalic L" +3961 "Tibetan Vowel Sign Vocalic Ll" +3962 "Tibetan Vowel Sign E" +3963 "Tibetan Vowel Sign Ee" +3964 "Tibetan Vowel Sign O" +3965 "Tibetan Vowel Sign Oo" +3966 "Tibetan Sign Rjes Su Nga Ro" +3967 "Tibetan Sign Rnam Bcad" +3968 "Tibetan Vowel Sign Reversed I" +3969 "Tibetan Vowel Sign Reversed Ii" +3970 "Tibetan Sign Nyi Zla Naa Da" +3971 "Tibetan Sign Sna Ldan" +3972 "Tibetan Mark Halanta" +3973 "Tibetan Mark Paluta" +3974 "Tibetan Sign Lci Rtags" +3975 "Tibetan Sign Yang Rtags" +3976 "Tibetan Sign Lce Tsa Can" +3977 "Tibetan Sign Mchu Can" +3978 "Tibetan Sign Gru Can Rgyings" +3979 "Tibetan Sign Gru Med Rgyings" +3980 "Tibetan Sign Inverted Mchu Can" +3981 "Tibetan Subjoined Sign Lce Tsa Can" +3982 "Tibetan Subjoined Sign Mchu Can" +3983 "Tibetan Subjoined Sign Inverted Mchu Can" +3984 "Tibetan Subjoined Letter Ka" +3985 "Tibetan Subjoined Letter Kha" +3986 "Tibetan Subjoined Letter Ga" +3987 "Tibetan Subjoined Letter Gha" +3988 "Tibetan Subjoined Letter Nga" +3989 "Tibetan Subjoined Letter Ca" +3990 "Tibetan Subjoined Letter Cha" +3991 "Tibetan Subjoined Letter Ja" +3993 "Tibetan Subjoined Letter Nya" +3994 "Tibetan Subjoined Letter Tta" +3995 "Tibetan Subjoined Letter Ttha" +3996 "Tibetan Subjoined Letter Dda" +3997 "Tibetan Subjoined Letter Ddha" +3998 "Tibetan Subjoined Letter Nna" +3999 "Tibetan Subjoined Letter Ta" +4000 "Tibetan Subjoined Letter Tha" +4001 "Tibetan Subjoined Letter Da" +4002 "Tibetan Subjoined Letter Dha" +4003 "Tibetan Subjoined Letter Na" +4004 "Tibetan Subjoined Letter Pa" +4005 "Tibetan Subjoined Letter Pha" +4006 "Tibetan Subjoined Letter Ba" +4007 "Tibetan Subjoined Letter Bha" +4008 "Tibetan Subjoined Letter Ma" +4009 "Tibetan Subjoined Letter Tsa" +4010 "Tibetan Subjoined Letter Tsha" +4011 "Tibetan Subjoined Letter Dza" +4012 "Tibetan Subjoined Letter Dzha" +4013 "Tibetan Subjoined Letter Wa" +4014 "Tibetan Subjoined Letter Zha" +4015 "Tibetan Subjoined Letter Za" +4016 "Tibetan Subjoined Letter -A" +4017 "Tibetan Subjoined Letter Ya" +4018 "Tibetan Subjoined Letter Ra" +4019 "Tibetan Subjoined Letter La" +4020 "Tibetan Subjoined Letter Sha" +4021 "Tibetan Subjoined Letter Ssa" +4022 "Tibetan Subjoined Letter Sa" +4023 "Tibetan Subjoined Letter Ha" +4024 "Tibetan Subjoined Letter A" +4025 "Tibetan Subjoined Letter Kssa" +4026 "Tibetan Subjoined Letter Fixed-Form Wa" +4027 "Tibetan Subjoined Letter Fixed-Form Ya" +4028 "Tibetan Subjoined Letter Fixed-Form Ra" +4030 "Tibetan Ku Ru Kha" +4031 "Tibetan Ku Ru Kha Bzhi Mig Can" +4032 "Tibetan Cantillation Sign Heavy Beat" +4033 "Tibetan Cantillation Sign Light Beat" +4034 "Tibetan Cantillation Sign Cang Te-U" +4035 "Tibetan Cantillation Sign Sbub -Chal" +4036 "Tibetan Symbol Dril Bu" +4037 "Tibetan Symbol Rdo Rje" +4038 "Tibetan Symbol Padma Gdan" +4039 "Tibetan Symbol Rdo Rje Rgya Gram" +4040 "Tibetan Symbol Phur Pa" +4041 "Tibetan Symbol Nor Bu" +4042 "Tibetan Symbol Nor Bu Nyis -Khyil" +4043 "Tibetan Symbol Nor Bu Gsum -Khyil" +4044 "Tibetan Symbol Nor Bu Bzhi -Khyil" +4046 "Tibetan Sign Rdel Nag Rdel Dkar" +4047 "Tibetan Sign Rdel Nag Gsum" +4048 "Tibetan Mark Bska- Shog Gi Mgo Rgyan" +4049 "Tibetan Mark Mnyam Yig Gi Mgo Rgyan" +4050 "Tibetan Mark Nyis Tsheg" +4051 "Tibetan Mark Initial Brda Rnying Yig Mgo Mdun Ma" +4052 "Tibetan Mark Closing Brda Rnying Yig Mgo Sgab Ma" +4053 "Right-Facing Svasti Sign" +4054 "Left-Facing Svasti Sign" +4055 "Right-Facing Svasti Sign With Dots" +4056 "Left-Facing Svasti Sign With Dots" +4057 "Tibetan Mark Leading Mchan Rtags" +4058 "Tibetan Mark Trailing Mchan Rtags" +4096 "Myanmar Letter Ka" +4097 "Myanmar Letter Kha" +4098 "Myanmar Letter Ga" +4099 "Myanmar Letter Gha" +4100 "Myanmar Letter Nga" +4101 "Myanmar Letter Ca" +4102 "Myanmar Letter Cha" +4103 "Myanmar Letter Ja" +4104 "Myanmar Letter Jha" +4105 "Myanmar Letter Nya" +4106 "Myanmar Letter Nnya" +4107 "Myanmar Letter Tta" +4108 "Myanmar Letter Ttha" +4109 "Myanmar Letter Dda" +4110 "Myanmar Letter Ddha" +4111 "Myanmar Letter Nna" +4112 "Myanmar Letter Ta" +4113 "Myanmar Letter Tha" +4114 "Myanmar Letter Da" +4115 "Myanmar Letter Dha" +4116 "Myanmar Letter Na" +4117 "Myanmar Letter Pa" +4118 "Myanmar Letter Pha" +4119 "Myanmar Letter Ba" +4120 "Myanmar Letter Bha" +4121 "Myanmar Letter Ma" +4122 "Myanmar Letter Ya" +4123 "Myanmar Letter Ra" +4124 "Myanmar Letter La" +4125 "Myanmar Letter Wa" +4126 "Myanmar Letter Sa" +4127 "Myanmar Letter Ha" +4128 "Myanmar Letter Lla" +4129 "Myanmar Letter A" +4130 "Myanmar Letter Shan A" +4131 "Myanmar Letter I" +4132 "Myanmar Letter Ii" +4133 "Myanmar Letter U" +4134 "Myanmar Letter Uu" +4135 "Myanmar Letter E" +4136 "Myanmar Letter Mon E" +4137 "Myanmar Letter O" +4138 "Myanmar Letter Au" +4139 "Myanmar Vowel Sign Tall Aa" +4140 "Myanmar Vowel Sign Aa" +4141 "Myanmar Vowel Sign I" +4142 "Myanmar Vowel Sign Ii" +4143 "Myanmar Vowel Sign U" +4144 "Myanmar Vowel Sign Uu" +4145 "Myanmar Vowel Sign E" +4146 "Myanmar Vowel Sign Ai" +4147 "Myanmar Vowel Sign Mon Ii" +4148 "Myanmar Vowel Sign Mon O" +4149 "Myanmar Vowel Sign E Above" +4150 "Myanmar Sign Anusvara" +4151 "Myanmar Sign Dot Below" +4152 "Myanmar Sign Visarga" +4153 "Myanmar Sign Virama" +4154 "Myanmar Sign Asat" +4155 "Myanmar Consonant Sign Medial Ya" +4156 "Myanmar Consonant Sign Medial Ra" +4157 "Myanmar Consonant Sign Medial Wa" +4158 "Myanmar Consonant Sign Medial Ha" +4159 "Myanmar Letter Great Sa" +4160 "Myanmar Digit Zero" +4161 "Myanmar Digit One" +4162 "Myanmar Digit Two" +4163 "Myanmar Digit Three" +4164 "Myanmar Digit Four" +4165 "Myanmar Digit Five" +4166 "Myanmar Digit Six" +4167 "Myanmar Digit Seven" +4168 "Myanmar Digit Eight" +4169 "Myanmar Digit Nine" +4170 "Myanmar Sign Little Section" +4171 "Myanmar Sign Section" +4172 "Myanmar Symbol Locative" +4173 "Myanmar Symbol Completed" +4174 "Myanmar Symbol Aforementioned" +4175 "Myanmar Symbol Genitive" +4176 "Myanmar Letter Sha" +4177 "Myanmar Letter Ssa" +4178 "Myanmar Letter Vocalic R" +4179 "Myanmar Letter Vocalic Rr" +4180 "Myanmar Letter Vocalic L" +4181 "Myanmar Letter Vocalic Ll" +4182 "Myanmar Vowel Sign Vocalic R" +4183 "Myanmar Vowel Sign Vocalic Rr" +4184 "Myanmar Vowel Sign Vocalic L" +4185 "Myanmar Vowel Sign Vocalic Ll" +4186 "Myanmar Letter Mon Nga" +4187 "Myanmar Letter Mon Jha" +4188 "Myanmar Letter Mon Bba" +4189 "Myanmar Letter Mon Bbe" +4190 "Myanmar Consonant Sign Mon Medial Na" +4191 "Myanmar Consonant Sign Mon Medial Ma" +4192 "Myanmar Consonant Sign Mon Medial La" +4193 "Myanmar Letter Sgaw Karen Sha" +4194 "Myanmar Vowel Sign Sgaw Karen Eu" +4195 "Myanmar Tone Mark Sgaw Karen Hathi" +4196 "Myanmar Tone Mark Sgaw Karen Ke Pho" +4197 "Myanmar Letter Western Pwo Karen Tha" +4198 "Myanmar Letter Western Pwo Karen Pwa" +4199 "Myanmar Vowel Sign Western Pwo Karen Eu" +4200 "Myanmar Vowel Sign Western Pwo Karen Ue" +4201 "Myanmar Sign Western Pwo Karen Tone-1" +4202 "Myanmar Sign Western Pwo Karen Tone-2" +4203 "Myanmar Sign Western Pwo Karen Tone-3" +4204 "Myanmar Sign Western Pwo Karen Tone-4" +4205 "Myanmar Sign Western Pwo Karen Tone-5" +4206 "Myanmar Letter Eastern Pwo Karen Nna" +4207 "Myanmar Letter Eastern Pwo Karen Ywa" +4208 "Myanmar Letter Eastern Pwo Karen Ghwa" +4209 "Myanmar Vowel Sign Geba Karen I" +4210 "Myanmar Vowel Sign Kayah Oe" +4211 "Myanmar Vowel Sign Kayah U" +4212 "Myanmar Vowel Sign Kayah Ee" +4213 "Myanmar Letter Shan Ka" +4214 "Myanmar Letter Shan Kha" +4215 "Myanmar Letter Shan Ga" +4216 "Myanmar Letter Shan Ca" +4217 "Myanmar Letter Shan Za" +4218 "Myanmar Letter Shan Nya" +4219 "Myanmar Letter Shan Da" +4220 "Myanmar Letter Shan Na" +4221 "Myanmar Letter Shan Pha" +4222 "Myanmar Letter Shan Fa" +4223 "Myanmar Letter Shan Ba" +4224 "Myanmar Letter Shan Tha" +4225 "Myanmar Letter Shan Ha" +4226 "Myanmar Consonant Sign Shan Medial Wa" +4227 "Myanmar Vowel Sign Shan Aa" +4228 "Myanmar Vowel Sign Shan E" +4229 "Myanmar Vowel Sign Shan E Above" +4230 "Myanmar Vowel Sign Shan Final Y" +4231 "Myanmar Sign Shan Tone-2" +4232 "Myanmar Sign Shan Tone-3" +4233 "Myanmar Sign Shan Tone-5" +4234 "Myanmar Sign Shan Tone-6" +4235 "Myanmar Sign Shan Council Tone-2" +4236 "Myanmar Sign Shan Council Tone-3" +4237 "Myanmar Sign Shan Council Emphatic Tone" +4238 "Myanmar Letter Rumai Palaung Fa" +4239 "Myanmar Sign Rumai Palaung Tone-5" +4240 "Myanmar Shan Digit Zero" +4241 "Myanmar Shan Digit One" +4242 "Myanmar Shan Digit Two" +4243 "Myanmar Shan Digit Three" +4244 "Myanmar Shan Digit Four" +4245 "Myanmar Shan Digit Five" +4246 "Myanmar Shan Digit Six" +4247 "Myanmar Shan Digit Seven" +4248 "Myanmar Shan Digit Eight" +4249 "Myanmar Shan Digit Nine" +4250 "Myanmar Sign Khamti Tone-1" +4251 "Myanmar Sign Khamti Tone-3" +4252 "Myanmar Vowel Sign Aiton A" +4253 "Myanmar Vowel Sign Aiton Ai" +4254 "Myanmar Symbol Shan One" +4255 "Myanmar Symbol Shan Exclamation" +4256 "Georgian Capital Letter An" +4257 "Georgian Capital Letter Ban" +4258 "Georgian Capital Letter Gan" +4259 "Georgian Capital Letter Don" +4260 "Georgian Capital Letter En" +4261 "Georgian Capital Letter Vin" +4262 "Georgian Capital Letter Zen" +4263 "Georgian Capital Letter Tan" +4264 "Georgian Capital Letter In" +4265 "Georgian Capital Letter Kan" +4266 "Georgian Capital Letter Las" +4267 "Georgian Capital Letter Man" +4268 "Georgian Capital Letter Nar" +4269 "Georgian Capital Letter On" +4270 "Georgian Capital Letter Par" +4271 "Georgian Capital Letter Zhar" +4272 "Georgian Capital Letter Rae" +4273 "Georgian Capital Letter San" +4274 "Georgian Capital Letter Tar" +4275 "Georgian Capital Letter Un" +4276 "Georgian Capital Letter Phar" +4277 "Georgian Capital Letter Khar" +4278 "Georgian Capital Letter Ghan" +4279 "Georgian Capital Letter Qar" +4280 "Georgian Capital Letter Shin" +4281 "Georgian Capital Letter Chin" +4282 "Georgian Capital Letter Can" +4283 "Georgian Capital Letter Jil" +4284 "Georgian Capital Letter Cil" +4285 "Georgian Capital Letter Char" +4286 "Georgian Capital Letter Xan" +4287 "Georgian Capital Letter Jhan" +4288 "Georgian Capital Letter Hae" +4289 "Georgian Capital Letter He" +4290 "Georgian Capital Letter Hie" +4291 "Georgian Capital Letter We" +4292 "Georgian Capital Letter Har" +4293 "Georgian Capital Letter Hoe" +4295 "Georgian Capital Letter Yn" +4301 "Georgian Capital Letter Aen" +4304 "Georgian Letter An" +4305 "Georgian Letter Ban" +4306 "Georgian Letter Gan" +4307 "Georgian Letter Don" +4308 "Georgian Letter En" +4309 "Georgian Letter Vin" +4310 "Georgian Letter Zen" +4311 "Georgian Letter Tan" +4312 "Georgian Letter In" +4313 "Georgian Letter Kan" +4314 "Georgian Letter Las" +4315 "Georgian Letter Man" +4316 "Georgian Letter Nar" +4317 "Georgian Letter On" +4318 "Georgian Letter Par" +4319 "Georgian Letter Zhar" +4320 "Georgian Letter Rae" +4321 "Georgian Letter San" +4322 "Georgian Letter Tar" +4323 "Georgian Letter Un" +4324 "Georgian Letter Phar" +4325 "Georgian Letter Khar" +4326 "Georgian Letter Ghan" +4327 "Georgian Letter Qar" +4328 "Georgian Letter Shin" +4329 "Georgian Letter Chin" +4330 "Georgian Letter Can" +4331 "Georgian Letter Jil" +4332 "Georgian Letter Cil" +4333 "Georgian Letter Char" +4334 "Georgian Letter Xan" +4335 "Georgian Letter Jhan" +4336 "Georgian Letter Hae" +4337 "Georgian Letter He" +4338 "Georgian Letter Hie" +4339 "Georgian Letter We" +4340 "Georgian Letter Har" +4341 "Georgian Letter Hoe" +4342 "Georgian Letter Fi" +4343 "Georgian Letter Yn" +4344 "Georgian Letter Elifi" +4345 "Georgian Letter Turned Gan" +4346 "Georgian Letter Ain" +4347 "Georgian Paragraph Separator" +4348 "Modifier Letter Georgian Nar" +4349 "Georgian Letter Aen" +4350 "Georgian Letter Hard Sign" +4351 "Georgian Letter Labial Sign" +4352 "Hangul Choseong Kiyeok" +4353 "Hangul Choseong Ssangkiyeok" +4354 "Hangul Choseong Nieun" +4355 "Hangul Choseong Tikeut" +4356 "Hangul Choseong Ssangtikeut" +4357 "Hangul Choseong Rieul" +4358 "Hangul Choseong Mieum" +4359 "Hangul Choseong Pieup" +4360 "Hangul Choseong Ssangpieup" +4361 "Hangul Choseong Sios" +4362 "Hangul Choseong Ssangsios" +4363 "Hangul Choseong Ieung" +4364 "Hangul Choseong Cieuc" +4365 "Hangul Choseong Ssangcieuc" +4366 "Hangul Choseong Chieuch" +4367 "Hangul Choseong Khieukh" +4368 "Hangul Choseong Thieuth" +4369 "Hangul Choseong Phieuph" +4370 "Hangul Choseong Hieuh" +4371 "Hangul Choseong Nieun-Kiyeok" +4372 "Hangul Choseong Ssangnieun" +4373 "Hangul Choseong Nieun-Tikeut" +4374 "Hangul Choseong Nieun-Pieup" +4375 "Hangul Choseong Tikeut-Kiyeok" +4376 "Hangul Choseong Rieul-Nieun" +4377 "Hangul Choseong Ssangrieul" +4378 "Hangul Choseong Rieul-Hieuh" +4379 "Hangul Choseong Kapyeounrieul" +4380 "Hangul Choseong Mieum-Pieup" +4381 "Hangul Choseong Kapyeounmieum" +4382 "Hangul Choseong Pieup-Kiyeok" +4383 "Hangul Choseong Pieup-Nieun" +4384 "Hangul Choseong Pieup-Tikeut" +4385 "Hangul Choseong Pieup-Sios" +4386 "Hangul Choseong Pieup-Sios-Kiyeok" +4387 "Hangul Choseong Pieup-Sios-Tikeut" +4388 "Hangul Choseong Pieup-Sios-Pieup" +4389 "Hangul Choseong Pieup-Ssangsios" +4390 "Hangul Choseong Pieup-Sios-Cieuc" +4391 "Hangul Choseong Pieup-Cieuc" +4392 "Hangul Choseong Pieup-Chieuch" +4393 "Hangul Choseong Pieup-Thieuth" +4394 "Hangul Choseong Pieup-Phieuph" +4395 "Hangul Choseong Kapyeounpieup" +4396 "Hangul Choseong Kapyeounssangpieup" +4397 "Hangul Choseong Sios-Kiyeok" +4398 "Hangul Choseong Sios-Nieun" +4399 "Hangul Choseong Sios-Tikeut" +4400 "Hangul Choseong Sios-Rieul" +4401 "Hangul Choseong Sios-Mieum" +4402 "Hangul Choseong Sios-Pieup" +4403 "Hangul Choseong Sios-Pieup-Kiyeok" +4404 "Hangul Choseong Sios-Ssangsios" +4405 "Hangul Choseong Sios-Ieung" +4406 "Hangul Choseong Sios-Cieuc" +4407 "Hangul Choseong Sios-Chieuch" +4408 "Hangul Choseong Sios-Khieukh" +4409 "Hangul Choseong Sios-Thieuth" +4410 "Hangul Choseong Sios-Phieuph" +4411 "Hangul Choseong Sios-Hieuh" +4412 "Hangul Choseong Chitueumsios" +4413 "Hangul Choseong Chitueumssangsios" +4414 "Hangul Choseong Ceongchieumsios" +4415 "Hangul Choseong Ceongchieumssangsios" +4416 "Hangul Choseong Pansios" +4417 "Hangul Choseong Ieung-Kiyeok" +4418 "Hangul Choseong Ieung-Tikeut" +4419 "Hangul Choseong Ieung-Mieum" +4420 "Hangul Choseong Ieung-Pieup" +4421 "Hangul Choseong Ieung-Sios" +4422 "Hangul Choseong Ieung-Pansios" +4423 "Hangul Choseong Ssangieung" +4424 "Hangul Choseong Ieung-Cieuc" +4425 "Hangul Choseong Ieung-Chieuch" +4426 "Hangul Choseong Ieung-Thieuth" +4427 "Hangul Choseong Ieung-Phieuph" +4428 "Hangul Choseong Yesieung" +4429 "Hangul Choseong Cieuc-Ieung" +4430 "Hangul Choseong Chitueumcieuc" +4431 "Hangul Choseong Chitueumssangcieuc" +4432 "Hangul Choseong Ceongchieumcieuc" +4433 "Hangul Choseong Ceongchieumssangcieuc" +4434 "Hangul Choseong Chieuch-Khieukh" +4435 "Hangul Choseong Chieuch-Hieuh" +4436 "Hangul Choseong Chitueumchieuch" +4437 "Hangul Choseong Ceongchieumchieuch" +4438 "Hangul Choseong Phieuph-Pieup" +4439 "Hangul Choseong Kapyeounphieuph" +4440 "Hangul Choseong Ssanghieuh" +4441 "Hangul Choseong Yeorinhieuh" +4442 "Hangul Choseong Kiyeok-Tikeut" +4443 "Hangul Choseong Nieun-Sios" +4444 "Hangul Choseong Nieun-Cieuc" +4445 "Hangul Choseong Nieun-Hieuh" +4446 "Hangul Choseong Tikeut-Rieul" +4447 "Hangul Choseong Filler" +4448 "Hangul Jungseong Filler" +4449 "Hangul Jungseong A" +4450 "Hangul Jungseong Ae" +4451 "Hangul Jungseong Ya" +4452 "Hangul Jungseong Yae" +4453 "Hangul Jungseong Eo" +4454 "Hangul Jungseong E" +4455 "Hangul Jungseong Yeo" +4456 "Hangul Jungseong Ye" +4457 "Hangul Jungseong O" +4458 "Hangul Jungseong Wa" +4459 "Hangul Jungseong Wae" +4460 "Hangul Jungseong Oe" +4461 "Hangul Jungseong Yo" +4462 "Hangul Jungseong U" +4463 "Hangul Jungseong Weo" +4464 "Hangul Jungseong We" +4465 "Hangul Jungseong Wi" +4466 "Hangul Jungseong Yu" +4467 "Hangul Jungseong Eu" +4468 "Hangul Jungseong Yi" +4469 "Hangul Jungseong I" +4470 "Hangul Jungseong A-O" +4471 "Hangul Jungseong A-U" +4472 "Hangul Jungseong Ya-O" +4473 "Hangul Jungseong Ya-Yo" +4474 "Hangul Jungseong Eo-O" +4475 "Hangul Jungseong Eo-U" +4476 "Hangul Jungseong Eo-Eu" +4477 "Hangul Jungseong Yeo-O" +4478 "Hangul Jungseong Yeo-U" +4479 "Hangul Jungseong O-Eo" +4480 "Hangul Jungseong O-E" +4481 "Hangul Jungseong O-Ye" +4482 "Hangul Jungseong O-O" +4483 "Hangul Jungseong O-U" +4484 "Hangul Jungseong Yo-Ya" +4485 "Hangul Jungseong Yo-Yae" +4486 "Hangul Jungseong Yo-Yeo" +4487 "Hangul Jungseong Yo-O" +4488 "Hangul Jungseong Yo-I" +4489 "Hangul Jungseong U-A" +4490 "Hangul Jungseong U-Ae" +4491 "Hangul Jungseong U-Eo-Eu" +4492 "Hangul Jungseong U-Ye" +4493 "Hangul Jungseong U-U" +4494 "Hangul Jungseong Yu-A" +4495 "Hangul Jungseong Yu-Eo" +4496 "Hangul Jungseong Yu-E" +4497 "Hangul Jungseong Yu-Yeo" +4498 "Hangul Jungseong Yu-Ye" +4499 "Hangul Jungseong Yu-U" +4500 "Hangul Jungseong Yu-I" +4501 "Hangul Jungseong Eu-U" +4502 "Hangul Jungseong Eu-Eu" +4503 "Hangul Jungseong Yi-U" +4504 "Hangul Jungseong I-A" +4505 "Hangul Jungseong I-Ya" +4506 "Hangul Jungseong I-O" +4507 "Hangul Jungseong I-U" +4508 "Hangul Jungseong I-Eu" +4509 "Hangul Jungseong I-Araea" +4510 "Hangul Jungseong Araea" +4511 "Hangul Jungseong Araea-Eo" +4512 "Hangul Jungseong Araea-U" +4513 "Hangul Jungseong Araea-I" +4514 "Hangul Jungseong Ssangaraea" +4515 "Hangul Jungseong A-Eu" +4516 "Hangul Jungseong Ya-U" +4517 "Hangul Jungseong Yeo-Ya" +4518 "Hangul Jungseong O-Ya" +4519 "Hangul Jungseong O-Yae" +4520 "Hangul Jongseong Kiyeok" +4521 "Hangul Jongseong Ssangkiyeok" +4522 "Hangul Jongseong Kiyeok-Sios" +4523 "Hangul Jongseong Nieun" +4524 "Hangul Jongseong Nieun-Cieuc" +4525 "Hangul Jongseong Nieun-Hieuh" +4526 "Hangul Jongseong Tikeut" +4527 "Hangul Jongseong Rieul" +4528 "Hangul Jongseong Rieul-Kiyeok" +4529 "Hangul Jongseong Rieul-Mieum" +4530 "Hangul Jongseong Rieul-Pieup" +4531 "Hangul Jongseong Rieul-Sios" +4532 "Hangul Jongseong Rieul-Thieuth" +4533 "Hangul Jongseong Rieul-Phieuph" +4534 "Hangul Jongseong Rieul-Hieuh" +4535 "Hangul Jongseong Mieum" +4536 "Hangul Jongseong Pieup" +4537 "Hangul Jongseong Pieup-Sios" +4538 "Hangul Jongseong Sios" +4539 "Hangul Jongseong Ssangsios" +4540 "Hangul Jongseong Ieung" +4541 "Hangul Jongseong Cieuc" +4542 "Hangul Jongseong Chieuch" +4543 "Hangul Jongseong Khieukh" +4544 "Hangul Jongseong Thieuth" +4545 "Hangul Jongseong Phieuph" +4546 "Hangul Jongseong Hieuh" +4547 "Hangul Jongseong Kiyeok-Rieul" +4548 "Hangul Jongseong Kiyeok-Sios-Kiyeok" +4549 "Hangul Jongseong Nieun-Kiyeok" +4550 "Hangul Jongseong Nieun-Tikeut" +4551 "Hangul Jongseong Nieun-Sios" +4552 "Hangul Jongseong Nieun-Pansios" +4553 "Hangul Jongseong Nieun-Thieuth" +4554 "Hangul Jongseong Tikeut-Kiyeok" +4555 "Hangul Jongseong Tikeut-Rieul" +4556 "Hangul Jongseong Rieul-Kiyeok-Sios" +4557 "Hangul Jongseong Rieul-Nieun" +4558 "Hangul Jongseong Rieul-Tikeut" +4559 "Hangul Jongseong Rieul-Tikeut-Hieuh" +4560 "Hangul Jongseong Ssangrieul" +4561 "Hangul Jongseong Rieul-Mieum-Kiyeok" +4562 "Hangul Jongseong Rieul-Mieum-Sios" +4563 "Hangul Jongseong Rieul-Pieup-Sios" +4564 "Hangul Jongseong Rieul-Pieup-Hieuh" +4565 "Hangul Jongseong Rieul-Kapyeounpieup" +4566 "Hangul Jongseong Rieul-Ssangsios" +4567 "Hangul Jongseong Rieul-Pansios" +4568 "Hangul Jongseong Rieul-Khieukh" +4569 "Hangul Jongseong Rieul-Yeorinhieuh" +4570 "Hangul Jongseong Mieum-Kiyeok" +4571 "Hangul Jongseong Mieum-Rieul" +4572 "Hangul Jongseong Mieum-Pieup" +4573 "Hangul Jongseong Mieum-Sios" +4574 "Hangul Jongseong Mieum-Ssangsios" +4575 "Hangul Jongseong Mieum-Pansios" +4576 "Hangul Jongseong Mieum-Chieuch" +4577 "Hangul Jongseong Mieum-Hieuh" +4578 "Hangul Jongseong Kapyeounmieum" +4579 "Hangul Jongseong Pieup-Rieul" +4580 "Hangul Jongseong Pieup-Phieuph" +4581 "Hangul Jongseong Pieup-Hieuh" +4582 "Hangul Jongseong Kapyeounpieup" +4583 "Hangul Jongseong Sios-Kiyeok" +4584 "Hangul Jongseong Sios-Tikeut" +4585 "Hangul Jongseong Sios-Rieul" +4586 "Hangul Jongseong Sios-Pieup" +4587 "Hangul Jongseong Pansios" +4588 "Hangul Jongseong Ieung-Kiyeok" +4589 "Hangul Jongseong Ieung-Ssangkiyeok" +4590 "Hangul Jongseong Ssangieung" +4591 "Hangul Jongseong Ieung-Khieukh" +4592 "Hangul Jongseong Yesieung" +4593 "Hangul Jongseong Yesieung-Sios" +4594 "Hangul Jongseong Yesieung-Pansios" +4595 "Hangul Jongseong Phieuph-Pieup" +4596 "Hangul Jongseong Kapyeounphieuph" +4597 "Hangul Jongseong Hieuh-Nieun" +4598 "Hangul Jongseong Hieuh-Rieul" +4599 "Hangul Jongseong Hieuh-Mieum" +4600 "Hangul Jongseong Hieuh-Pieup" +4601 "Hangul Jongseong Yeorinhieuh" +4602 "Hangul Jongseong Kiyeok-Nieun" +4603 "Hangul Jongseong Kiyeok-Pieup" +4604 "Hangul Jongseong Kiyeok-Chieuch" +4605 "Hangul Jongseong Kiyeok-Khieukh" +4606 "Hangul Jongseong Kiyeok-Hieuh" +4607 "Hangul Jongseong Ssangnieun" +4608 "Ethiopic Syllable Ha" +4609 "Ethiopic Syllable Hu" +4610 "Ethiopic Syllable Hi" +4611 "Ethiopic Syllable Haa" +4612 "Ethiopic Syllable Hee" +4613 "Ethiopic Syllable He" +4614 "Ethiopic Syllable Ho" +4615 "Ethiopic Syllable Hoa" +4616 "Ethiopic Syllable La" +4617 "Ethiopic Syllable Lu" +4618 "Ethiopic Syllable Li" +4619 "Ethiopic Syllable Laa" +4620 "Ethiopic Syllable Lee" +4621 "Ethiopic Syllable Le" +4622 "Ethiopic Syllable Lo" +4623 "Ethiopic Syllable Lwa" +4624 "Ethiopic Syllable Hha" +4625 "Ethiopic Syllable Hhu" +4626 "Ethiopic Syllable Hhi" +4627 "Ethiopic Syllable Hhaa" +4628 "Ethiopic Syllable Hhee" +4629 "Ethiopic Syllable Hhe" +4630 "Ethiopic Syllable Hho" +4631 "Ethiopic Syllable Hhwa" +4632 "Ethiopic Syllable Ma" +4633 "Ethiopic Syllable Mu" +4634 "Ethiopic Syllable Mi" +4635 "Ethiopic Syllable Maa" +4636 "Ethiopic Syllable Mee" +4637 "Ethiopic Syllable Me" +4638 "Ethiopic Syllable Mo" +4639 "Ethiopic Syllable Mwa" +4640 "Ethiopic Syllable Sza" +4641 "Ethiopic Syllable Szu" +4642 "Ethiopic Syllable Szi" +4643 "Ethiopic Syllable Szaa" +4644 "Ethiopic Syllable Szee" +4645 "Ethiopic Syllable Sze" +4646 "Ethiopic Syllable Szo" +4647 "Ethiopic Syllable Szwa" +4648 "Ethiopic Syllable Ra" +4649 "Ethiopic Syllable Ru" +4650 "Ethiopic Syllable Ri" +4651 "Ethiopic Syllable Raa" +4652 "Ethiopic Syllable Ree" +4653 "Ethiopic Syllable Re" +4654 "Ethiopic Syllable Ro" +4655 "Ethiopic Syllable Rwa" +4656 "Ethiopic Syllable Sa" +4657 "Ethiopic Syllable Su" +4658 "Ethiopic Syllable Si" +4659 "Ethiopic Syllable Saa" +4660 "Ethiopic Syllable See" +4661 "Ethiopic Syllable Se" +4662 "Ethiopic Syllable So" +4663 "Ethiopic Syllable Swa" +4664 "Ethiopic Syllable Sha" +4665 "Ethiopic Syllable Shu" +4666 "Ethiopic Syllable Shi" +4667 "Ethiopic Syllable Shaa" +4668 "Ethiopic Syllable Shee" +4669 "Ethiopic Syllable She" +4670 "Ethiopic Syllable Sho" +4671 "Ethiopic Syllable Shwa" +4672 "Ethiopic Syllable Qa" +4673 "Ethiopic Syllable Qu" +4674 "Ethiopic Syllable Qi" +4675 "Ethiopic Syllable Qaa" +4676 "Ethiopic Syllable Qee" +4677 "Ethiopic Syllable Qe" +4678 "Ethiopic Syllable Qo" +4679 "Ethiopic Syllable Qoa" +4680 "Ethiopic Syllable Qwa" +4682 "Ethiopic Syllable Qwi" +4683 "Ethiopic Syllable Qwaa" +4684 "Ethiopic Syllable Qwee" +4685 "Ethiopic Syllable Qwe" +4688 "Ethiopic Syllable Qha" +4689 "Ethiopic Syllable Qhu" +4690 "Ethiopic Syllable Qhi" +4691 "Ethiopic Syllable Qhaa" +4692 "Ethiopic Syllable Qhee" +4693 "Ethiopic Syllable Qhe" +4694 "Ethiopic Syllable Qho" +4696 "Ethiopic Syllable Qhwa" +4698 "Ethiopic Syllable Qhwi" +4699 "Ethiopic Syllable Qhwaa" +4700 "Ethiopic Syllable Qhwee" +4701 "Ethiopic Syllable Qhwe" +4704 "Ethiopic Syllable Ba" +4705 "Ethiopic Syllable Bu" +4706 "Ethiopic Syllable Bi" +4707 "Ethiopic Syllable Baa" +4708 "Ethiopic Syllable Bee" +4709 "Ethiopic Syllable Be" +4710 "Ethiopic Syllable Bo" +4711 "Ethiopic Syllable Bwa" +4712 "Ethiopic Syllable Va" +4713 "Ethiopic Syllable Vu" +4714 "Ethiopic Syllable Vi" +4715 "Ethiopic Syllable Vaa" +4716 "Ethiopic Syllable Vee" +4717 "Ethiopic Syllable Ve" +4718 "Ethiopic Syllable Vo" +4719 "Ethiopic Syllable Vwa" +4720 "Ethiopic Syllable Ta" +4721 "Ethiopic Syllable Tu" +4722 "Ethiopic Syllable Ti" +4723 "Ethiopic Syllable Taa" +4724 "Ethiopic Syllable Tee" +4725 "Ethiopic Syllable Te" +4726 "Ethiopic Syllable To" +4727 "Ethiopic Syllable Twa" +4728 "Ethiopic Syllable Ca" +4729 "Ethiopic Syllable Cu" +4730 "Ethiopic Syllable Ci" +4731 "Ethiopic Syllable Caa" +4732 "Ethiopic Syllable Cee" +4733 "Ethiopic Syllable Ce" +4734 "Ethiopic Syllable Co" +4735 "Ethiopic Syllable Cwa" +4736 "Ethiopic Syllable Xa" +4737 "Ethiopic Syllable Xu" +4738 "Ethiopic Syllable Xi" +4739 "Ethiopic Syllable Xaa" +4740 "Ethiopic Syllable Xee" +4741 "Ethiopic Syllable Xe" +4742 "Ethiopic Syllable Xo" +4743 "Ethiopic Syllable Xoa" +4744 "Ethiopic Syllable Xwa" +4746 "Ethiopic Syllable Xwi" +4747 "Ethiopic Syllable Xwaa" +4748 "Ethiopic Syllable Xwee" +4749 "Ethiopic Syllable Xwe" +4752 "Ethiopic Syllable Na" +4753 "Ethiopic Syllable Nu" +4754 "Ethiopic Syllable Ni" +4755 "Ethiopic Syllable Naa" +4756 "Ethiopic Syllable Nee" +4757 "Ethiopic Syllable Ne" +4758 "Ethiopic Syllable No" +4759 "Ethiopic Syllable Nwa" +4760 "Ethiopic Syllable Nya" +4761 "Ethiopic Syllable Nyu" +4762 "Ethiopic Syllable Nyi" +4763 "Ethiopic Syllable Nyaa" +4764 "Ethiopic Syllable Nyee" +4765 "Ethiopic Syllable Nye" +4766 "Ethiopic Syllable Nyo" +4767 "Ethiopic Syllable Nywa" +4768 "Ethiopic Syllable Glottal A" +4769 "Ethiopic Syllable Glottal U" +4770 "Ethiopic Syllable Glottal I" +4771 "Ethiopic Syllable Glottal Aa" +4772 "Ethiopic Syllable Glottal Ee" +4773 "Ethiopic Syllable Glottal E" +4774 "Ethiopic Syllable Glottal O" +4775 "Ethiopic Syllable Glottal Wa" +4776 "Ethiopic Syllable Ka" +4777 "Ethiopic Syllable Ku" +4778 "Ethiopic Syllable Ki" +4779 "Ethiopic Syllable Kaa" +4780 "Ethiopic Syllable Kee" +4781 "Ethiopic Syllable Ke" +4782 "Ethiopic Syllable Ko" +4783 "Ethiopic Syllable Koa" +4784 "Ethiopic Syllable Kwa" +4786 "Ethiopic Syllable Kwi" +4787 "Ethiopic Syllable Kwaa" +4788 "Ethiopic Syllable Kwee" +4789 "Ethiopic Syllable Kwe" +4792 "Ethiopic Syllable Kxa" +4793 "Ethiopic Syllable Kxu" +4794 "Ethiopic Syllable Kxi" +4795 "Ethiopic Syllable Kxaa" +4796 "Ethiopic Syllable Kxee" +4797 "Ethiopic Syllable Kxe" +4798 "Ethiopic Syllable Kxo" +4800 "Ethiopic Syllable Kxwa" +4802 "Ethiopic Syllable Kxwi" +4803 "Ethiopic Syllable Kxwaa" +4804 "Ethiopic Syllable Kxwee" +4805 "Ethiopic Syllable Kxwe" +4808 "Ethiopic Syllable Wa" +4809 "Ethiopic Syllable Wu" +4810 "Ethiopic Syllable Wi" +4811 "Ethiopic Syllable Waa" +4812 "Ethiopic Syllable Wee" +4813 "Ethiopic Syllable We" +4814 "Ethiopic Syllable Wo" +4815 "Ethiopic Syllable Woa" +4816 "Ethiopic Syllable Pharyngeal A" +4817 "Ethiopic Syllable Pharyngeal U" +4818 "Ethiopic Syllable Pharyngeal I" +4819 "Ethiopic Syllable Pharyngeal Aa" +4820 "Ethiopic Syllable Pharyngeal Ee" +4821 "Ethiopic Syllable Pharyngeal E" +4822 "Ethiopic Syllable Pharyngeal O" +4824 "Ethiopic Syllable Za" +4825 "Ethiopic Syllable Zu" +4826 "Ethiopic Syllable Zi" +4827 "Ethiopic Syllable Zaa" +4828 "Ethiopic Syllable Zee" +4829 "Ethiopic Syllable Ze" +4830 "Ethiopic Syllable Zo" +4831 "Ethiopic Syllable Zwa" +4832 "Ethiopic Syllable Zha" +4833 "Ethiopic Syllable Zhu" +4834 "Ethiopic Syllable Zhi" +4835 "Ethiopic Syllable Zhaa" +4836 "Ethiopic Syllable Zhee" +4837 "Ethiopic Syllable Zhe" +4838 "Ethiopic Syllable Zho" +4839 "Ethiopic Syllable Zhwa" +4840 "Ethiopic Syllable Ya" +4841 "Ethiopic Syllable Yu" +4842 "Ethiopic Syllable Yi" +4843 "Ethiopic Syllable Yaa" +4844 "Ethiopic Syllable Yee" +4845 "Ethiopic Syllable Ye" +4846 "Ethiopic Syllable Yo" +4847 "Ethiopic Syllable Yoa" +4848 "Ethiopic Syllable Da" +4849 "Ethiopic Syllable Du" +4850 "Ethiopic Syllable Di" +4851 "Ethiopic Syllable Daa" +4852 "Ethiopic Syllable Dee" +4853 "Ethiopic Syllable De" +4854 "Ethiopic Syllable Do" +4855 "Ethiopic Syllable Dwa" +4856 "Ethiopic Syllable Dda" +4857 "Ethiopic Syllable Ddu" +4858 "Ethiopic Syllable Ddi" +4859 "Ethiopic Syllable Ddaa" +4860 "Ethiopic Syllable Ddee" +4861 "Ethiopic Syllable Dde" +4862 "Ethiopic Syllable Ddo" +4863 "Ethiopic Syllable Ddwa" +4864 "Ethiopic Syllable Ja" +4865 "Ethiopic Syllable Ju" +4866 "Ethiopic Syllable Ji" +4867 "Ethiopic Syllable Jaa" +4868 "Ethiopic Syllable Jee" +4869 "Ethiopic Syllable Je" +4870 "Ethiopic Syllable Jo" +4871 "Ethiopic Syllable Jwa" +4872 "Ethiopic Syllable Ga" +4873 "Ethiopic Syllable Gu" +4874 "Ethiopic Syllable Gi" +4875 "Ethiopic Syllable Gaa" +4876 "Ethiopic Syllable Gee" +4877 "Ethiopic Syllable Ge" +4878 "Ethiopic Syllable Go" +4879 "Ethiopic Syllable Goa" +4880 "Ethiopic Syllable Gwa" +4882 "Ethiopic Syllable Gwi" +4883 "Ethiopic Syllable Gwaa" +4884 "Ethiopic Syllable Gwee" +4885 "Ethiopic Syllable Gwe" +4888 "Ethiopic Syllable Gga" +4889 "Ethiopic Syllable Ggu" +4890 "Ethiopic Syllable Ggi" +4891 "Ethiopic Syllable Ggaa" +4892 "Ethiopic Syllable Ggee" +4893 "Ethiopic Syllable Gge" +4894 "Ethiopic Syllable Ggo" +4895 "Ethiopic Syllable Ggwaa" +4896 "Ethiopic Syllable Tha" +4897 "Ethiopic Syllable Thu" +4898 "Ethiopic Syllable Thi" +4899 "Ethiopic Syllable Thaa" +4900 "Ethiopic Syllable Thee" +4901 "Ethiopic Syllable The" +4902 "Ethiopic Syllable Tho" +4903 "Ethiopic Syllable Thwa" +4904 "Ethiopic Syllable Cha" +4905 "Ethiopic Syllable Chu" +4906 "Ethiopic Syllable Chi" +4907 "Ethiopic Syllable Chaa" +4908 "Ethiopic Syllable Chee" +4909 "Ethiopic Syllable Che" +4910 "Ethiopic Syllable Cho" +4911 "Ethiopic Syllable Chwa" +4912 "Ethiopic Syllable Pha" +4913 "Ethiopic Syllable Phu" +4914 "Ethiopic Syllable Phi" +4915 "Ethiopic Syllable Phaa" +4916 "Ethiopic Syllable Phee" +4917 "Ethiopic Syllable Phe" +4918 "Ethiopic Syllable Pho" +4919 "Ethiopic Syllable Phwa" +4920 "Ethiopic Syllable Tsa" +4921 "Ethiopic Syllable Tsu" +4922 "Ethiopic Syllable Tsi" +4923 "Ethiopic Syllable Tsaa" +4924 "Ethiopic Syllable Tsee" +4925 "Ethiopic Syllable Tse" +4926 "Ethiopic Syllable Tso" +4927 "Ethiopic Syllable Tswa" +4928 "Ethiopic Syllable Tza" +4929 "Ethiopic Syllable Tzu" +4930 "Ethiopic Syllable Tzi" +4931 "Ethiopic Syllable Tzaa" +4932 "Ethiopic Syllable Tzee" +4933 "Ethiopic Syllable Tze" +4934 "Ethiopic Syllable Tzo" +4935 "Ethiopic Syllable Tzoa" +4936 "Ethiopic Syllable Fa" +4937 "Ethiopic Syllable Fu" +4938 "Ethiopic Syllable Fi" +4939 "Ethiopic Syllable Faa" +4940 "Ethiopic Syllable Fee" +4941 "Ethiopic Syllable Fe" +4942 "Ethiopic Syllable Fo" +4943 "Ethiopic Syllable Fwa" +4944 "Ethiopic Syllable Pa" +4945 "Ethiopic Syllable Pu" +4946 "Ethiopic Syllable Pi" +4947 "Ethiopic Syllable Paa" +4948 "Ethiopic Syllable Pee" +4949 "Ethiopic Syllable Pe" +4950 "Ethiopic Syllable Po" +4951 "Ethiopic Syllable Pwa" +4952 "Ethiopic Syllable Rya" +4953 "Ethiopic Syllable Mya" +4954 "Ethiopic Syllable Fya" +4957 "Ethiopic Combining Gemination And Vowel Length Mark" +4958 "Ethiopic Combining Vowel Length Mark" +4959 "Ethiopic Combining Gemination Mark" +4960 "Ethiopic Section Mark" +4961 "Ethiopic Wordspace" +4962 "Ethiopic Full Stop" +4963 "Ethiopic Comma" +4964 "Ethiopic Semicolon" +4965 "Ethiopic Colon" +4966 "Ethiopic Preface Colon" +4967 "Ethiopic Question Mark" +4968 "Ethiopic Paragraph Separator" +4969 "Ethiopic Digit One" +4970 "Ethiopic Digit Two" +4971 "Ethiopic Digit Three" +4972 "Ethiopic Digit Four" +4973 "Ethiopic Digit Five" +4974 "Ethiopic Digit Six" +4975 "Ethiopic Digit Seven" +4976 "Ethiopic Digit Eight" +4977 "Ethiopic Digit Nine" +4978 "Ethiopic Number Ten" +4979 "Ethiopic Number Twenty" +4980 "Ethiopic Number Thirty" +4981 "Ethiopic Number Forty" +4982 "Ethiopic Number Fifty" +4983 "Ethiopic Number Sixty" +4984 "Ethiopic Number Seventy" +4985 "Ethiopic Number Eighty" +4986 "Ethiopic Number Ninety" +4987 "Ethiopic Number Hundred" +4988 "Ethiopic Number Ten Thousand" +4992 "Ethiopic Syllable Sebatbeit Mwa" +4993 "Ethiopic Syllable Mwi" +4994 "Ethiopic Syllable Mwee" +4995 "Ethiopic Syllable Mwe" +4996 "Ethiopic Syllable Sebatbeit Bwa" +4997 "Ethiopic Syllable Bwi" +4998 "Ethiopic Syllable Bwee" +4999 "Ethiopic Syllable Bwe" +5000 "Ethiopic Syllable Sebatbeit Fwa" +5001 "Ethiopic Syllable Fwi" +5002 "Ethiopic Syllable Fwee" +5003 "Ethiopic Syllable Fwe" +5004 "Ethiopic Syllable Sebatbeit Pwa" +5005 "Ethiopic Syllable Pwi" +5006 "Ethiopic Syllable Pwee" +5007 "Ethiopic Syllable Pwe" +5008 "Ethiopic Tonal Mark Yizet" +5009 "Ethiopic Tonal Mark Deret" +5010 "Ethiopic Tonal Mark Rikrik" +5011 "Ethiopic Tonal Mark Short Rikrik" +5012 "Ethiopic Tonal Mark Difat" +5013 "Ethiopic Tonal Mark Kenat" +5014 "Ethiopic Tonal Mark Chiret" +5015 "Ethiopic Tonal Mark Hidet" +5016 "Ethiopic Tonal Mark Deret-Hidet" +5017 "Ethiopic Tonal Mark Kurt" +5024 "Cherokee Letter A" +5025 "Cherokee Letter E" +5026 "Cherokee Letter I" +5027 "Cherokee Letter O" +5028 "Cherokee Letter U" +5029 "Cherokee Letter V" +5030 "Cherokee Letter Ga" +5031 "Cherokee Letter Ka" +5032 "Cherokee Letter Ge" +5033 "Cherokee Letter Gi" +5034 "Cherokee Letter Go" +5035 "Cherokee Letter Gu" +5036 "Cherokee Letter Gv" +5037 "Cherokee Letter Ha" +5038 "Cherokee Letter He" +5039 "Cherokee Letter Hi" +5040 "Cherokee Letter Ho" +5041 "Cherokee Letter Hu" +5042 "Cherokee Letter Hv" +5043 "Cherokee Letter La" +5044 "Cherokee Letter Le" +5045 "Cherokee Letter Li" +5046 "Cherokee Letter Lo" +5047 "Cherokee Letter Lu" +5048 "Cherokee Letter Lv" +5049 "Cherokee Letter Ma" +5050 "Cherokee Letter Me" +5051 "Cherokee Letter Mi" +5052 "Cherokee Letter Mo" +5053 "Cherokee Letter Mu" +5054 "Cherokee Letter Na" +5055 "Cherokee Letter Hna" +5056 "Cherokee Letter Nah" +5057 "Cherokee Letter Ne" +5058 "Cherokee Letter Ni" +5059 "Cherokee Letter No" +5060 "Cherokee Letter Nu" +5061 "Cherokee Letter Nv" +5062 "Cherokee Letter Qua" +5063 "Cherokee Letter Que" +5064 "Cherokee Letter Qui" +5065 "Cherokee Letter Quo" +5066 "Cherokee Letter Quu" +5067 "Cherokee Letter Quv" +5068 "Cherokee Letter Sa" +5069 "Cherokee Letter S" +5070 "Cherokee Letter Se" +5071 "Cherokee Letter Si" +5072 "Cherokee Letter So" +5073 "Cherokee Letter Su" +5074 "Cherokee Letter Sv" +5075 "Cherokee Letter Da" +5076 "Cherokee Letter Ta" +5077 "Cherokee Letter De" +5078 "Cherokee Letter Te" +5079 "Cherokee Letter Di" +5080 "Cherokee Letter Ti" +5081 "Cherokee Letter Do" +5082 "Cherokee Letter Du" +5083 "Cherokee Letter Dv" +5084 "Cherokee Letter Dla" +5085 "Cherokee Letter Tla" +5086 "Cherokee Letter Tle" +5087 "Cherokee Letter Tli" +5088 "Cherokee Letter Tlo" +5089 "Cherokee Letter Tlu" +5090 "Cherokee Letter Tlv" +5091 "Cherokee Letter Tsa" +5092 "Cherokee Letter Tse" +5093 "Cherokee Letter Tsi" +5094 "Cherokee Letter Tso" +5095 "Cherokee Letter Tsu" +5096 "Cherokee Letter Tsv" +5097 "Cherokee Letter Wa" +5098 "Cherokee Letter We" +5099 "Cherokee Letter Wi" +5100 "Cherokee Letter Wo" +5101 "Cherokee Letter Wu" +5102 "Cherokee Letter Wv" +5103 "Cherokee Letter Ya" +5104 "Cherokee Letter Ye" +5105 "Cherokee Letter Yi" +5106 "Cherokee Letter Yo" +5107 "Cherokee Letter Yu" +5108 "Cherokee Letter Yv" +5120 "Canadian Syllabics Hyphen" +5121 "Canadian Syllabics E" +5122 "Canadian Syllabics Aai" +5123 "Canadian Syllabics I" +5124 "Canadian Syllabics Ii" +5125 "Canadian Syllabics O" +5126 "Canadian Syllabics Oo" +5127 "Canadian Syllabics Y-Cree Oo" +5128 "Canadian Syllabics Carrier Ee" +5129 "Canadian Syllabics Carrier I" +5130 "Canadian Syllabics A" +5131 "Canadian Syllabics Aa" +5132 "Canadian Syllabics We" +5133 "Canadian Syllabics West-Cree We" +5134 "Canadian Syllabics Wi" +5135 "Canadian Syllabics West-Cree Wi" +5136 "Canadian Syllabics Wii" +5137 "Canadian Syllabics West-Cree Wii" +5138 "Canadian Syllabics Wo" +5139 "Canadian Syllabics West-Cree Wo" +5140 "Canadian Syllabics Woo" +5141 "Canadian Syllabics West-Cree Woo" +5142 "Canadian Syllabics Naskapi Woo" +5143 "Canadian Syllabics Wa" +5144 "Canadian Syllabics West-Cree Wa" +5145 "Canadian Syllabics Waa" +5146 "Canadian Syllabics West-Cree Waa" +5147 "Canadian Syllabics Naskapi Waa" +5148 "Canadian Syllabics Ai" +5149 "Canadian Syllabics Y-Cree W" +5150 "Canadian Syllabics Glottal Stop" +5151 "Canadian Syllabics Final Acute" +5152 "Canadian Syllabics Final Grave" +5153 "Canadian Syllabics Final Bottom Half Ring" +5154 "Canadian Syllabics Final Top Half Ring" +5155 "Canadian Syllabics Final Right Half Ring" +5156 "Canadian Syllabics Final Ring" +5157 "Canadian Syllabics Final Double Acute" +5158 "Canadian Syllabics Final Double Short Vertical Strokes" +5159 "Canadian Syllabics Final Middle Dot" +5160 "Canadian Syllabics Final Short Horizontal Stroke" +5161 "Canadian Syllabics Final Plus" +5162 "Canadian Syllabics Final Down Tack" +5163 "Canadian Syllabics En" +5164 "Canadian Syllabics In" +5165 "Canadian Syllabics On" +5166 "Canadian Syllabics An" +5167 "Canadian Syllabics Pe" +5168 "Canadian Syllabics Paai" +5169 "Canadian Syllabics Pi" +5170 "Canadian Syllabics Pii" +5171 "Canadian Syllabics Po" +5172 "Canadian Syllabics Poo" +5173 "Canadian Syllabics Y-Cree Poo" +5174 "Canadian Syllabics Carrier Hee" +5175 "Canadian Syllabics Carrier Hi" +5176 "Canadian Syllabics Pa" +5177 "Canadian Syllabics Paa" +5178 "Canadian Syllabics Pwe" +5179 "Canadian Syllabics West-Cree Pwe" +5180 "Canadian Syllabics Pwi" +5181 "Canadian Syllabics West-Cree Pwi" +5182 "Canadian Syllabics Pwii" +5183 "Canadian Syllabics West-Cree Pwii" +5184 "Canadian Syllabics Pwo" +5185 "Canadian Syllabics West-Cree Pwo" +5186 "Canadian Syllabics Pwoo" +5187 "Canadian Syllabics West-Cree Pwoo" +5188 "Canadian Syllabics Pwa" +5189 "Canadian Syllabics West-Cree Pwa" +5190 "Canadian Syllabics Pwaa" +5191 "Canadian Syllabics West-Cree Pwaa" +5192 "Canadian Syllabics Y-Cree Pwaa" +5193 "Canadian Syllabics P" +5194 "Canadian Syllabics West-Cree P" +5195 "Canadian Syllabics Carrier H" +5196 "Canadian Syllabics Te" +5197 "Canadian Syllabics Taai" +5198 "Canadian Syllabics Ti" +5199 "Canadian Syllabics Tii" +5200 "Canadian Syllabics To" +5201 "Canadian Syllabics Too" +5202 "Canadian Syllabics Y-Cree Too" +5203 "Canadian Syllabics Carrier Dee" +5204 "Canadian Syllabics Carrier Di" +5205 "Canadian Syllabics Ta" +5206 "Canadian Syllabics Taa" +5207 "Canadian Syllabics Twe" +5208 "Canadian Syllabics West-Cree Twe" +5209 "Canadian Syllabics Twi" +5210 "Canadian Syllabics West-Cree Twi" +5211 "Canadian Syllabics Twii" +5212 "Canadian Syllabics West-Cree Twii" +5213 "Canadian Syllabics Two" +5214 "Canadian Syllabics West-Cree Two" +5215 "Canadian Syllabics Twoo" +5216 "Canadian Syllabics West-Cree Twoo" +5217 "Canadian Syllabics Twa" +5218 "Canadian Syllabics West-Cree Twa" +5219 "Canadian Syllabics Twaa" +5220 "Canadian Syllabics West-Cree Twaa" +5221 "Canadian Syllabics Naskapi Twaa" +5222 "Canadian Syllabics T" +5223 "Canadian Syllabics Tte" +5224 "Canadian Syllabics Tti" +5225 "Canadian Syllabics Tto" +5226 "Canadian Syllabics Tta" +5227 "Canadian Syllabics Ke" +5228 "Canadian Syllabics Kaai" +5229 "Canadian Syllabics Ki" +5230 "Canadian Syllabics Kii" +5231 "Canadian Syllabics Ko" +5232 "Canadian Syllabics Koo" +5233 "Canadian Syllabics Y-Cree Koo" +5234 "Canadian Syllabics Ka" +5235 "Canadian Syllabics Kaa" +5236 "Canadian Syllabics Kwe" +5237 "Canadian Syllabics West-Cree Kwe" +5238 "Canadian Syllabics Kwi" +5239 "Canadian Syllabics West-Cree Kwi" +5240 "Canadian Syllabics Kwii" +5241 "Canadian Syllabics West-Cree Kwii" +5242 "Canadian Syllabics Kwo" +5243 "Canadian Syllabics West-Cree Kwo" +5244 "Canadian Syllabics Kwoo" +5245 "Canadian Syllabics West-Cree Kwoo" +5246 "Canadian Syllabics Kwa" +5247 "Canadian Syllabics West-Cree Kwa" +5248 "Canadian Syllabics Kwaa" +5249 "Canadian Syllabics West-Cree Kwaa" +5250 "Canadian Syllabics Naskapi Kwaa" +5251 "Canadian Syllabics K" +5252 "Canadian Syllabics Kw" +5253 "Canadian Syllabics South-Slavey Keh" +5254 "Canadian Syllabics South-Slavey Kih" +5255 "Canadian Syllabics South-Slavey Koh" +5256 "Canadian Syllabics South-Slavey Kah" +5257 "Canadian Syllabics Ce" +5258 "Canadian Syllabics Caai" +5259 "Canadian Syllabics Ci" +5260 "Canadian Syllabics Cii" +5261 "Canadian Syllabics Co" +5262 "Canadian Syllabics Coo" +5263 "Canadian Syllabics Y-Cree Coo" +5264 "Canadian Syllabics Ca" +5265 "Canadian Syllabics Caa" +5266 "Canadian Syllabics Cwe" +5267 "Canadian Syllabics West-Cree Cwe" +5268 "Canadian Syllabics Cwi" +5269 "Canadian Syllabics West-Cree Cwi" +5270 "Canadian Syllabics Cwii" +5271 "Canadian Syllabics West-Cree Cwii" +5272 "Canadian Syllabics Cwo" +5273 "Canadian Syllabics West-Cree Cwo" +5274 "Canadian Syllabics Cwoo" +5275 "Canadian Syllabics West-Cree Cwoo" +5276 "Canadian Syllabics Cwa" +5277 "Canadian Syllabics West-Cree Cwa" +5278 "Canadian Syllabics Cwaa" +5279 "Canadian Syllabics West-Cree Cwaa" +5280 "Canadian Syllabics Naskapi Cwaa" +5281 "Canadian Syllabics C" +5282 "Canadian Syllabics Sayisi Th" +5283 "Canadian Syllabics Me" +5284 "Canadian Syllabics Maai" +5285 "Canadian Syllabics Mi" +5286 "Canadian Syllabics Mii" +5287 "Canadian Syllabics Mo" +5288 "Canadian Syllabics Moo" +5289 "Canadian Syllabics Y-Cree Moo" +5290 "Canadian Syllabics Ma" +5291 "Canadian Syllabics Maa" +5292 "Canadian Syllabics Mwe" +5293 "Canadian Syllabics West-Cree Mwe" +5294 "Canadian Syllabics Mwi" +5295 "Canadian Syllabics West-Cree Mwi" +5296 "Canadian Syllabics Mwii" +5297 "Canadian Syllabics West-Cree Mwii" +5298 "Canadian Syllabics Mwo" +5299 "Canadian Syllabics West-Cree Mwo" +5300 "Canadian Syllabics Mwoo" +5301 "Canadian Syllabics West-Cree Mwoo" +5302 "Canadian Syllabics Mwa" +5303 "Canadian Syllabics West-Cree Mwa" +5304 "Canadian Syllabics Mwaa" +5305 "Canadian Syllabics West-Cree Mwaa" +5306 "Canadian Syllabics Naskapi Mwaa" +5307 "Canadian Syllabics M" +5308 "Canadian Syllabics West-Cree M" +5309 "Canadian Syllabics Mh" +5310 "Canadian Syllabics Athapascan M" +5311 "Canadian Syllabics Sayisi M" +5312 "Canadian Syllabics Ne" +5313 "Canadian Syllabics Naai" +5314 "Canadian Syllabics Ni" +5315 "Canadian Syllabics Nii" +5316 "Canadian Syllabics No" +5317 "Canadian Syllabics Noo" +5318 "Canadian Syllabics Y-Cree Noo" +5319 "Canadian Syllabics Na" +5320 "Canadian Syllabics Naa" +5321 "Canadian Syllabics Nwe" +5322 "Canadian Syllabics West-Cree Nwe" +5323 "Canadian Syllabics Nwa" +5324 "Canadian Syllabics West-Cree Nwa" +5325 "Canadian Syllabics Nwaa" +5326 "Canadian Syllabics West-Cree Nwaa" +5327 "Canadian Syllabics Naskapi Nwaa" +5328 "Canadian Syllabics N" +5329 "Canadian Syllabics Carrier Ng" +5330 "Canadian Syllabics Nh" +5331 "Canadian Syllabics Le" +5332 "Canadian Syllabics Laai" +5333 "Canadian Syllabics Li" +5334 "Canadian Syllabics Lii" +5335 "Canadian Syllabics Lo" +5336 "Canadian Syllabics Loo" +5337 "Canadian Syllabics Y-Cree Loo" +5338 "Canadian Syllabics La" +5339 "Canadian Syllabics Laa" +5340 "Canadian Syllabics Lwe" +5341 "Canadian Syllabics West-Cree Lwe" +5342 "Canadian Syllabics Lwi" +5343 "Canadian Syllabics West-Cree Lwi" +5344 "Canadian Syllabics Lwii" +5345 "Canadian Syllabics West-Cree Lwii" +5346 "Canadian Syllabics Lwo" +5347 "Canadian Syllabics West-Cree Lwo" +5348 "Canadian Syllabics Lwoo" +5349 "Canadian Syllabics West-Cree Lwoo" +5350 "Canadian Syllabics Lwa" +5351 "Canadian Syllabics West-Cree Lwa" +5352 "Canadian Syllabics Lwaa" +5353 "Canadian Syllabics West-Cree Lwaa" +5354 "Canadian Syllabics L" +5355 "Canadian Syllabics West-Cree L" +5356 "Canadian Syllabics Medial L" +5357 "Canadian Syllabics Se" +5358 "Canadian Syllabics Saai" +5359 "Canadian Syllabics Si" +5360 "Canadian Syllabics Sii" +5361 "Canadian Syllabics So" +5362 "Canadian Syllabics Soo" +5363 "Canadian Syllabics Y-Cree Soo" +5364 "Canadian Syllabics Sa" +5365 "Canadian Syllabics Saa" +5366 "Canadian Syllabics Swe" +5367 "Canadian Syllabics West-Cree Swe" +5368 "Canadian Syllabics Swi" +5369 "Canadian Syllabics West-Cree Swi" +5370 "Canadian Syllabics Swii" +5371 "Canadian Syllabics West-Cree Swii" +5372 "Canadian Syllabics Swo" +5373 "Canadian Syllabics West-Cree Swo" +5374 "Canadian Syllabics Swoo" +5375 "Canadian Syllabics West-Cree Swoo" +5376 "Canadian Syllabics Swa" +5377 "Canadian Syllabics West-Cree Swa" +5378 "Canadian Syllabics Swaa" +5379 "Canadian Syllabics West-Cree Swaa" +5380 "Canadian Syllabics Naskapi Swaa" +5381 "Canadian Syllabics S" +5382 "Canadian Syllabics Athapascan S" +5383 "Canadian Syllabics Sw" +5384 "Canadian Syllabics Blackfoot S" +5385 "Canadian Syllabics Moose-Cree Sk" +5386 "Canadian Syllabics Naskapi Skw" +5387 "Canadian Syllabics Naskapi S-W" +5388 "Canadian Syllabics Naskapi Spwa" +5389 "Canadian Syllabics Naskapi Stwa" +5390 "Canadian Syllabics Naskapi Skwa" +5391 "Canadian Syllabics Naskapi Scwa" +5392 "Canadian Syllabics She" +5393 "Canadian Syllabics Shi" +5394 "Canadian Syllabics Shii" +5395 "Canadian Syllabics Sho" +5396 "Canadian Syllabics Shoo" +5397 "Canadian Syllabics Sha" +5398 "Canadian Syllabics Shaa" +5399 "Canadian Syllabics Shwe" +5400 "Canadian Syllabics West-Cree Shwe" +5401 "Canadian Syllabics Shwi" +5402 "Canadian Syllabics West-Cree Shwi" +5403 "Canadian Syllabics Shwii" +5404 "Canadian Syllabics West-Cree Shwii" +5405 "Canadian Syllabics Shwo" +5406 "Canadian Syllabics West-Cree Shwo" +5407 "Canadian Syllabics Shwoo" +5408 "Canadian Syllabics West-Cree Shwoo" +5409 "Canadian Syllabics Shwa" +5410 "Canadian Syllabics West-Cree Shwa" +5411 "Canadian Syllabics Shwaa" +5412 "Canadian Syllabics West-Cree Shwaa" +5413 "Canadian Syllabics Sh" +5414 "Canadian Syllabics Ye" +5415 "Canadian Syllabics Yaai" +5416 "Canadian Syllabics Yi" +5417 "Canadian Syllabics Yii" +5418 "Canadian Syllabics Yo" +5419 "Canadian Syllabics Yoo" +5420 "Canadian Syllabics Y-Cree Yoo" +5421 "Canadian Syllabics Ya" +5422 "Canadian Syllabics Yaa" +5423 "Canadian Syllabics Ywe" +5424 "Canadian Syllabics West-Cree Ywe" +5425 "Canadian Syllabics Ywi" +5426 "Canadian Syllabics West-Cree Ywi" +5427 "Canadian Syllabics Ywii" +5428 "Canadian Syllabics West-Cree Ywii" +5429 "Canadian Syllabics Ywo" +5430 "Canadian Syllabics West-Cree Ywo" +5431 "Canadian Syllabics Ywoo" +5432 "Canadian Syllabics West-Cree Ywoo" +5433 "Canadian Syllabics Ywa" +5434 "Canadian Syllabics West-Cree Ywa" +5435 "Canadian Syllabics Ywaa" +5436 "Canadian Syllabics West-Cree Ywaa" +5437 "Canadian Syllabics Naskapi Ywaa" +5438 "Canadian Syllabics Y" +5439 "Canadian Syllabics Bible-Cree Y" +5440 "Canadian Syllabics West-Cree Y" +5441 "Canadian Syllabics Sayisi Yi" +5442 "Canadian Syllabics Re" +5443 "Canadian Syllabics R-Cree Re" +5444 "Canadian Syllabics West-Cree Le" +5445 "Canadian Syllabics Raai" +5446 "Canadian Syllabics Ri" +5447 "Canadian Syllabics Rii" +5448 "Canadian Syllabics Ro" +5449 "Canadian Syllabics Roo" +5450 "Canadian Syllabics West-Cree Lo" +5451 "Canadian Syllabics Ra" +5452 "Canadian Syllabics Raa" +5453 "Canadian Syllabics West-Cree La" +5454 "Canadian Syllabics Rwaa" +5455 "Canadian Syllabics West-Cree Rwaa" +5456 "Canadian Syllabics R" +5457 "Canadian Syllabics West-Cree R" +5458 "Canadian Syllabics Medial R" +5459 "Canadian Syllabics Fe" +5460 "Canadian Syllabics Faai" +5461 "Canadian Syllabics Fi" +5462 "Canadian Syllabics Fii" +5463 "Canadian Syllabics Fo" +5464 "Canadian Syllabics Foo" +5465 "Canadian Syllabics Fa" +5466 "Canadian Syllabics Faa" +5467 "Canadian Syllabics Fwaa" +5468 "Canadian Syllabics West-Cree Fwaa" +5469 "Canadian Syllabics F" +5470 "Canadian Syllabics The" +5471 "Canadian Syllabics N-Cree The" +5472 "Canadian Syllabics Thi" +5473 "Canadian Syllabics N-Cree Thi" +5474 "Canadian Syllabics Thii" +5475 "Canadian Syllabics N-Cree Thii" +5476 "Canadian Syllabics Tho" +5477 "Canadian Syllabics Thoo" +5478 "Canadian Syllabics Tha" +5479 "Canadian Syllabics Thaa" +5480 "Canadian Syllabics Thwaa" +5481 "Canadian Syllabics West-Cree Thwaa" +5482 "Canadian Syllabics Th" +5483 "Canadian Syllabics Tthe" +5484 "Canadian Syllabics Tthi" +5485 "Canadian Syllabics Ttho" +5486 "Canadian Syllabics Ttha" +5487 "Canadian Syllabics Tth" +5488 "Canadian Syllabics Tye" +5489 "Canadian Syllabics Tyi" +5490 "Canadian Syllabics Tyo" +5491 "Canadian Syllabics Tya" +5492 "Canadian Syllabics Nunavik He" +5493 "Canadian Syllabics Nunavik Hi" +5494 "Canadian Syllabics Nunavik Hii" +5495 "Canadian Syllabics Nunavik Ho" +5496 "Canadian Syllabics Nunavik Hoo" +5497 "Canadian Syllabics Nunavik Ha" +5498 "Canadian Syllabics Nunavik Haa" +5499 "Canadian Syllabics Nunavik H" +5500 "Canadian Syllabics Nunavut H" +5501 "Canadian Syllabics Hk" +5502 "Canadian Syllabics Qaai" +5503 "Canadian Syllabics Qi" +5504 "Canadian Syllabics Qii" +5505 "Canadian Syllabics Qo" +5506 "Canadian Syllabics Qoo" +5507 "Canadian Syllabics Qa" +5508 "Canadian Syllabics Qaa" +5509 "Canadian Syllabics Q" +5510 "Canadian Syllabics Tlhe" +5511 "Canadian Syllabics Tlhi" +5512 "Canadian Syllabics Tlho" +5513 "Canadian Syllabics Tlha" +5514 "Canadian Syllabics West-Cree Re" +5515 "Canadian Syllabics West-Cree Ri" +5516 "Canadian Syllabics West-Cree Ro" +5517 "Canadian Syllabics West-Cree Ra" +5518 "Canadian Syllabics Ngaai" +5519 "Canadian Syllabics Ngi" +5520 "Canadian Syllabics Ngii" +5521 "Canadian Syllabics Ngo" +5522 "Canadian Syllabics Ngoo" +5523 "Canadian Syllabics Nga" +5524 "Canadian Syllabics Ngaa" +5525 "Canadian Syllabics Ng" +5526 "Canadian Syllabics Nng" +5527 "Canadian Syllabics Sayisi She" +5528 "Canadian Syllabics Sayisi Shi" +5529 "Canadian Syllabics Sayisi Sho" +5530 "Canadian Syllabics Sayisi Sha" +5531 "Canadian Syllabics Woods-Cree The" +5532 "Canadian Syllabics Woods-Cree Thi" +5533 "Canadian Syllabics Woods-Cree Tho" +5534 "Canadian Syllabics Woods-Cree Tha" +5535 "Canadian Syllabics Woods-Cree Th" +5536 "Canadian Syllabics Lhi" +5537 "Canadian Syllabics Lhii" +5538 "Canadian Syllabics Lho" +5539 "Canadian Syllabics Lhoo" +5540 "Canadian Syllabics Lha" +5541 "Canadian Syllabics Lhaa" +5542 "Canadian Syllabics Lh" +5543 "Canadian Syllabics Th-Cree The" +5544 "Canadian Syllabics Th-Cree Thi" +5545 "Canadian Syllabics Th-Cree Thii" +5546 "Canadian Syllabics Th-Cree Tho" +5547 "Canadian Syllabics Th-Cree Thoo" +5548 "Canadian Syllabics Th-Cree Tha" +5549 "Canadian Syllabics Th-Cree Thaa" +5550 "Canadian Syllabics Th-Cree Th" +5551 "Canadian Syllabics Aivilik B" +5552 "Canadian Syllabics Blackfoot E" +5553 "Canadian Syllabics Blackfoot I" +5554 "Canadian Syllabics Blackfoot O" +5555 "Canadian Syllabics Blackfoot A" +5556 "Canadian Syllabics Blackfoot We" +5557 "Canadian Syllabics Blackfoot Wi" +5558 "Canadian Syllabics Blackfoot Wo" +5559 "Canadian Syllabics Blackfoot Wa" +5560 "Canadian Syllabics Blackfoot Ne" +5561 "Canadian Syllabics Blackfoot Ni" +5562 "Canadian Syllabics Blackfoot No" +5563 "Canadian Syllabics Blackfoot Na" +5564 "Canadian Syllabics Blackfoot Ke" +5565 "Canadian Syllabics Blackfoot Ki" +5566 "Canadian Syllabics Blackfoot Ko" +5567 "Canadian Syllabics Blackfoot Ka" +5568 "Canadian Syllabics Sayisi He" +5569 "Canadian Syllabics Sayisi Hi" +5570 "Canadian Syllabics Sayisi Ho" +5571 "Canadian Syllabics Sayisi Ha" +5572 "Canadian Syllabics Carrier Ghu" +5573 "Canadian Syllabics Carrier Gho" +5574 "Canadian Syllabics Carrier Ghe" +5575 "Canadian Syllabics Carrier Ghee" +5576 "Canadian Syllabics Carrier Ghi" +5577 "Canadian Syllabics Carrier Gha" +5578 "Canadian Syllabics Carrier Ru" +5579 "Canadian Syllabics Carrier Ro" +5580 "Canadian Syllabics Carrier Re" +5581 "Canadian Syllabics Carrier Ree" +5582 "Canadian Syllabics Carrier Ri" +5583 "Canadian Syllabics Carrier Ra" +5584 "Canadian Syllabics Carrier Wu" +5585 "Canadian Syllabics Carrier Wo" +5586 "Canadian Syllabics Carrier We" +5587 "Canadian Syllabics Carrier Wee" +5588 "Canadian Syllabics Carrier Wi" +5589 "Canadian Syllabics Carrier Wa" +5590 "Canadian Syllabics Carrier Hwu" +5591 "Canadian Syllabics Carrier Hwo" +5592 "Canadian Syllabics Carrier Hwe" +5593 "Canadian Syllabics Carrier Hwee" +5594 "Canadian Syllabics Carrier Hwi" +5595 "Canadian Syllabics Carrier Hwa" +5596 "Canadian Syllabics Carrier Thu" +5597 "Canadian Syllabics Carrier Tho" +5598 "Canadian Syllabics Carrier The" +5599 "Canadian Syllabics Carrier Thee" +5600 "Canadian Syllabics Carrier Thi" +5601 "Canadian Syllabics Carrier Tha" +5602 "Canadian Syllabics Carrier Ttu" +5603 "Canadian Syllabics Carrier Tto" +5604 "Canadian Syllabics Carrier Tte" +5605 "Canadian Syllabics Carrier Ttee" +5606 "Canadian Syllabics Carrier Tti" +5607 "Canadian Syllabics Carrier Tta" +5608 "Canadian Syllabics Carrier Pu" +5609 "Canadian Syllabics Carrier Po" +5610 "Canadian Syllabics Carrier Pe" +5611 "Canadian Syllabics Carrier Pee" +5612 "Canadian Syllabics Carrier Pi" +5613 "Canadian Syllabics Carrier Pa" +5614 "Canadian Syllabics Carrier P" +5615 "Canadian Syllabics Carrier Gu" +5616 "Canadian Syllabics Carrier Go" +5617 "Canadian Syllabics Carrier Ge" +5618 "Canadian Syllabics Carrier Gee" +5619 "Canadian Syllabics Carrier Gi" +5620 "Canadian Syllabics Carrier Ga" +5621 "Canadian Syllabics Carrier Khu" +5622 "Canadian Syllabics Carrier Kho" +5623 "Canadian Syllabics Carrier Khe" +5624 "Canadian Syllabics Carrier Khee" +5625 "Canadian Syllabics Carrier Khi" +5626 "Canadian Syllabics Carrier Kha" +5627 "Canadian Syllabics Carrier Kku" +5628 "Canadian Syllabics Carrier Kko" +5629 "Canadian Syllabics Carrier Kke" +5630 "Canadian Syllabics Carrier Kkee" +5631 "Canadian Syllabics Carrier Kki" +5632 "Canadian Syllabics Carrier Kka" +5633 "Canadian Syllabics Carrier Kk" +5634 "Canadian Syllabics Carrier Nu" +5635 "Canadian Syllabics Carrier No" +5636 "Canadian Syllabics Carrier Ne" +5637 "Canadian Syllabics Carrier Nee" +5638 "Canadian Syllabics Carrier Ni" +5639 "Canadian Syllabics Carrier Na" +5640 "Canadian Syllabics Carrier Mu" +5641 "Canadian Syllabics Carrier Mo" +5642 "Canadian Syllabics Carrier Me" +5643 "Canadian Syllabics Carrier Mee" +5644 "Canadian Syllabics Carrier Mi" +5645 "Canadian Syllabics Carrier Ma" +5646 "Canadian Syllabics Carrier Yu" +5647 "Canadian Syllabics Carrier Yo" +5648 "Canadian Syllabics Carrier Ye" +5649 "Canadian Syllabics Carrier Yee" +5650 "Canadian Syllabics Carrier Yi" +5651 "Canadian Syllabics Carrier Ya" +5652 "Canadian Syllabics Carrier Ju" +5653 "Canadian Syllabics Sayisi Ju" +5654 "Canadian Syllabics Carrier Jo" +5655 "Canadian Syllabics Carrier Je" +5656 "Canadian Syllabics Carrier Jee" +5657 "Canadian Syllabics Carrier Ji" +5658 "Canadian Syllabics Sayisi Ji" +5659 "Canadian Syllabics Carrier Ja" +5660 "Canadian Syllabics Carrier Jju" +5661 "Canadian Syllabics Carrier Jjo" +5662 "Canadian Syllabics Carrier Jje" +5663 "Canadian Syllabics Carrier Jjee" +5664 "Canadian Syllabics Carrier Jji" +5665 "Canadian Syllabics Carrier Jja" +5666 "Canadian Syllabics Carrier Lu" +5667 "Canadian Syllabics Carrier Lo" +5668 "Canadian Syllabics Carrier Le" +5669 "Canadian Syllabics Carrier Lee" +5670 "Canadian Syllabics Carrier Li" +5671 "Canadian Syllabics Carrier La" +5672 "Canadian Syllabics Carrier Dlu" +5673 "Canadian Syllabics Carrier Dlo" +5674 "Canadian Syllabics Carrier Dle" +5675 "Canadian Syllabics Carrier Dlee" +5676 "Canadian Syllabics Carrier Dli" +5677 "Canadian Syllabics Carrier Dla" +5678 "Canadian Syllabics Carrier Lhu" +5679 "Canadian Syllabics Carrier Lho" +5680 "Canadian Syllabics Carrier Lhe" +5681 "Canadian Syllabics Carrier Lhee" +5682 "Canadian Syllabics Carrier Lhi" +5683 "Canadian Syllabics Carrier Lha" +5684 "Canadian Syllabics Carrier Tlhu" +5685 "Canadian Syllabics Carrier Tlho" +5686 "Canadian Syllabics Carrier Tlhe" +5687 "Canadian Syllabics Carrier Tlhee" +5688 "Canadian Syllabics Carrier Tlhi" +5689 "Canadian Syllabics Carrier Tlha" +5690 "Canadian Syllabics Carrier Tlu" +5691 "Canadian Syllabics Carrier Tlo" +5692 "Canadian Syllabics Carrier Tle" +5693 "Canadian Syllabics Carrier Tlee" +5694 "Canadian Syllabics Carrier Tli" +5695 "Canadian Syllabics Carrier Tla" +5696 "Canadian Syllabics Carrier Zu" +5697 "Canadian Syllabics Carrier Zo" +5698 "Canadian Syllabics Carrier Ze" +5699 "Canadian Syllabics Carrier Zee" +5700 "Canadian Syllabics Carrier Zi" +5701 "Canadian Syllabics Carrier Za" +5702 "Canadian Syllabics Carrier Z" +5703 "Canadian Syllabics Carrier Initial Z" +5704 "Canadian Syllabics Carrier Dzu" +5705 "Canadian Syllabics Carrier Dzo" +5706 "Canadian Syllabics Carrier Dze" +5707 "Canadian Syllabics Carrier Dzee" +5708 "Canadian Syllabics Carrier Dzi" +5709 "Canadian Syllabics Carrier Dza" +5710 "Canadian Syllabics Carrier Su" +5711 "Canadian Syllabics Carrier So" +5712 "Canadian Syllabics Carrier Se" +5713 "Canadian Syllabics Carrier See" +5714 "Canadian Syllabics Carrier Si" +5715 "Canadian Syllabics Carrier Sa" +5716 "Canadian Syllabics Carrier Shu" +5717 "Canadian Syllabics Carrier Sho" +5718 "Canadian Syllabics Carrier She" +5719 "Canadian Syllabics Carrier Shee" +5720 "Canadian Syllabics Carrier Shi" +5721 "Canadian Syllabics Carrier Sha" +5722 "Canadian Syllabics Carrier Sh" +5723 "Canadian Syllabics Carrier Tsu" +5724 "Canadian Syllabics Carrier Tso" +5725 "Canadian Syllabics Carrier Tse" +5726 "Canadian Syllabics Carrier Tsee" +5727 "Canadian Syllabics Carrier Tsi" +5728 "Canadian Syllabics Carrier Tsa" +5729 "Canadian Syllabics Carrier Chu" +5730 "Canadian Syllabics Carrier Cho" +5731 "Canadian Syllabics Carrier Che" +5732 "Canadian Syllabics Carrier Chee" +5733 "Canadian Syllabics Carrier Chi" +5734 "Canadian Syllabics Carrier Cha" +5735 "Canadian Syllabics Carrier Ttsu" +5736 "Canadian Syllabics Carrier Ttso" +5737 "Canadian Syllabics Carrier Ttse" +5738 "Canadian Syllabics Carrier Ttsee" +5739 "Canadian Syllabics Carrier Ttsi" +5740 "Canadian Syllabics Carrier Ttsa" +5741 "Canadian Syllabics Chi Sign" +5742 "Canadian Syllabics Full Stop" +5743 "Canadian Syllabics Qai" +5744 "Canadian Syllabics Ngai" +5745 "Canadian Syllabics Nngi" +5746 "Canadian Syllabics Nngii" +5747 "Canadian Syllabics Nngo" +5748 "Canadian Syllabics Nngoo" +5749 "Canadian Syllabics Nnga" +5750 "Canadian Syllabics Nngaa" +5751 "Canadian Syllabics Woods-Cree Thwee" +5752 "Canadian Syllabics Woods-Cree Thwi" +5753 "Canadian Syllabics Woods-Cree Thwii" +5754 "Canadian Syllabics Woods-Cree Thwo" +5755 "Canadian Syllabics Woods-Cree Thwoo" +5756 "Canadian Syllabics Woods-Cree Thwa" +5757 "Canadian Syllabics Woods-Cree Thwaa" +5758 "Canadian Syllabics Woods-Cree Final Th" +5759 "Canadian Syllabics Blackfoot W" +5760 "Ogham Space Mark" +5761 "Ogham Letter Beith" +5762 "Ogham Letter Luis" +5763 "Ogham Letter Fearn" +5764 "Ogham Letter Sail" +5765 "Ogham Letter Nion" +5766 "Ogham Letter Uath" +5767 "Ogham Letter Dair" +5768 "Ogham Letter Tinne" +5769 "Ogham Letter Coll" +5770 "Ogham Letter Ceirt" +5771 "Ogham Letter Muin" +5772 "Ogham Letter Gort" +5773 "Ogham Letter Ngeadal" +5774 "Ogham Letter Straif" +5775 "Ogham Letter Ruis" +5776 "Ogham Letter Ailm" +5777 "Ogham Letter Onn" +5778 "Ogham Letter Ur" +5779 "Ogham Letter Eadhadh" +5780 "Ogham Letter Iodhadh" +5781 "Ogham Letter Eabhadh" +5782 "Ogham Letter Or" +5783 "Ogham Letter Uilleann" +5784 "Ogham Letter Ifin" +5785 "Ogham Letter Eamhancholl" +5786 "Ogham Letter Peith" +5787 "Ogham Feather Mark" +5788 "Ogham Reversed Feather Mark" +5792 "Runic Letter Fehu Feoh Fe F" +5793 "Runic Letter V" +5794 "Runic Letter Uruz Ur U" +5795 "Runic Letter Yr" +5796 "Runic Letter Y" +5797 "Runic Letter W" +5798 "Runic Letter Thurisaz Thurs Thorn" +5799 "Runic Letter Eth" +5800 "Runic Letter Ansuz A" +5801 "Runic Letter Os O" +5802 "Runic Letter Ac A" +5803 "Runic Letter Aesc" +5804 "Runic Letter Long-Branch-Oss O" +5805 "Runic Letter Short-Twig-Oss O" +5806 "Runic Letter O" +5807 "Runic Letter Oe" +5808 "Runic Letter On" +5809 "Runic Letter Raido Rad Reid R" +5810 "Runic Letter Kauna" +5811 "Runic Letter Cen" +5812 "Runic Letter Kaun K" +5813 "Runic Letter G" +5814 "Runic Letter Eng" +5815 "Runic Letter Gebo Gyfu G" +5816 "Runic Letter Gar" +5817 "Runic Letter Wunjo Wynn W" +5818 "Runic Letter Haglaz H" +5819 "Runic Letter Haegl H" +5820 "Runic Letter Long-Branch-Hagall H" +5821 "Runic Letter Short-Twig-Hagall H" +5822 "Runic Letter Naudiz Nyd Naud N" +5823 "Runic Letter Short-Twig-Naud N" +5824 "Runic Letter Dotted-N" +5825 "Runic Letter Isaz Is Iss I" +5826 "Runic Letter E" +5827 "Runic Letter Jeran J" +5828 "Runic Letter Ger" +5829 "Runic Letter Long-Branch-Ar Ae" +5830 "Runic Letter Short-Twig-Ar A" +5831 "Runic Letter Iwaz Eoh" +5832 "Runic Letter Pertho Peorth P" +5833 "Runic Letter Algiz Eolhx" +5834 "Runic Letter Sowilo S" +5835 "Runic Letter Sigel Long-Branch-Sol S" +5836 "Runic Letter Short-Twig-Sol S" +5837 "Runic Letter C" +5838 "Runic Letter Z" +5839 "Runic Letter Tiwaz Tir Tyr T" +5840 "Runic Letter Short-Twig-Tyr T" +5841 "Runic Letter D" +5842 "Runic Letter Berkanan Beorc Bjarkan B" +5843 "Runic Letter Short-Twig-Bjarkan B" +5844 "Runic Letter Dotted-P" +5845 "Runic Letter Open-P" +5846 "Runic Letter Ehwaz Eh E" +5847 "Runic Letter Mannaz Man M" +5848 "Runic Letter Long-Branch-Madr M" +5849 "Runic Letter Short-Twig-Madr M" +5850 "Runic Letter Laukaz Lagu Logr L" +5851 "Runic Letter Dotted-L" +5852 "Runic Letter Ingwaz" +5853 "Runic Letter Ing" +5854 "Runic Letter Dagaz Daeg D" +5855 "Runic Letter Othalan Ethel O" +5856 "Runic Letter Ear" +5857 "Runic Letter Ior" +5858 "Runic Letter Cweorth" +5859 "Runic Letter Calc" +5860 "Runic Letter Cealc" +5861 "Runic Letter Stan" +5862 "Runic Letter Long-Branch-Yr" +5863 "Runic Letter Short-Twig-Yr" +5864 "Runic Letter Icelandic-Yr" +5865 "Runic Letter Q" +5866 "Runic Letter X" +5867 "Runic Single Punctuation" +5868 "Runic Multiple Punctuation" +5869 "Runic Cross Punctuation" +5870 "Runic Arlaug Symbol" +5871 "Runic Tvimadur Symbol" +5872 "Runic Belgthor Symbol" +5888 "Tagalog Letter A" +5889 "Tagalog Letter I" +5890 "Tagalog Letter U" +5891 "Tagalog Letter Ka" +5892 "Tagalog Letter Ga" +5893 "Tagalog Letter Nga" +5894 "Tagalog Letter Ta" +5895 "Tagalog Letter Da" +5896 "Tagalog Letter Na" +5897 "Tagalog Letter Pa" +5898 "Tagalog Letter Ba" +5899 "Tagalog Letter Ma" +5900 "Tagalog Letter Ya" +5902 "Tagalog Letter La" +5903 "Tagalog Letter Wa" +5904 "Tagalog Letter Sa" +5905 "Tagalog Letter Ha" +5906 "Tagalog Vowel Sign I" +5907 "Tagalog Vowel Sign U" +5908 "Tagalog Sign Virama" +5920 "Hanunoo Letter A" +5921 "Hanunoo Letter I" +5922 "Hanunoo Letter U" +5923 "Hanunoo Letter Ka" +5924 "Hanunoo Letter Ga" +5925 "Hanunoo Letter Nga" +5926 "Hanunoo Letter Ta" +5927 "Hanunoo Letter Da" +5928 "Hanunoo Letter Na" +5929 "Hanunoo Letter Pa" +5930 "Hanunoo Letter Ba" +5931 "Hanunoo Letter Ma" +5932 "Hanunoo Letter Ya" +5933 "Hanunoo Letter Ra" +5934 "Hanunoo Letter La" +5935 "Hanunoo Letter Wa" +5936 "Hanunoo Letter Sa" +5937 "Hanunoo Letter Ha" +5938 "Hanunoo Vowel Sign I" +5939 "Hanunoo Vowel Sign U" +5940 "Hanunoo Sign Pamudpod" +5941 "Philippine Single Punctuation" +5942 "Philippine Double Punctuation" +5952 "Buhid Letter A" +5953 "Buhid Letter I" +5954 "Buhid Letter U" +5955 "Buhid Letter Ka" +5956 "Buhid Letter Ga" +5957 "Buhid Letter Nga" +5958 "Buhid Letter Ta" +5959 "Buhid Letter Da" +5960 "Buhid Letter Na" +5961 "Buhid Letter Pa" +5962 "Buhid Letter Ba" +5963 "Buhid Letter Ma" +5964 "Buhid Letter Ya" +5965 "Buhid Letter Ra" +5966 "Buhid Letter La" +5967 "Buhid Letter Wa" +5968 "Buhid Letter Sa" +5969 "Buhid Letter Ha" +5970 "Buhid Vowel Sign I" +5971 "Buhid Vowel Sign U" +5984 "Tagbanwa Letter A" +5985 "Tagbanwa Letter I" +5986 "Tagbanwa Letter U" +5987 "Tagbanwa Letter Ka" +5988 "Tagbanwa Letter Ga" +5989 "Tagbanwa Letter Nga" +5990 "Tagbanwa Letter Ta" +5991 "Tagbanwa Letter Da" +5992 "Tagbanwa Letter Na" +5993 "Tagbanwa Letter Pa" +5994 "Tagbanwa Letter Ba" +5995 "Tagbanwa Letter Ma" +5996 "Tagbanwa Letter Ya" +5998 "Tagbanwa Letter La" +5999 "Tagbanwa Letter Wa" +6000 "Tagbanwa Letter Sa" +6002 "Tagbanwa Vowel Sign I" +6003 "Tagbanwa Vowel Sign U" +6016 "Khmer Letter Ka" +6017 "Khmer Letter Kha" +6018 "Khmer Letter Ko" +6019 "Khmer Letter Kho" +6020 "Khmer Letter Ngo" +6021 "Khmer Letter Ca" +6022 "Khmer Letter Cha" +6023 "Khmer Letter Co" +6024 "Khmer Letter Cho" +6025 "Khmer Letter Nyo" +6026 "Khmer Letter Da" +6027 "Khmer Letter Ttha" +6028 "Khmer Letter Do" +6029 "Khmer Letter Ttho" +6030 "Khmer Letter Nno" +6031 "Khmer Letter Ta" +6032 "Khmer Letter Tha" +6033 "Khmer Letter To" +6034 "Khmer Letter Tho" +6035 "Khmer Letter No" +6036 "Khmer Letter Ba" +6037 "Khmer Letter Pha" +6038 "Khmer Letter Po" +6039 "Khmer Letter Pho" +6040 "Khmer Letter Mo" +6041 "Khmer Letter Yo" +6042 "Khmer Letter Ro" +6043 "Khmer Letter Lo" +6044 "Khmer Letter Vo" +6045 "Khmer Letter Sha" +6046 "Khmer Letter Sso" +6047 "Khmer Letter Sa" +6048 "Khmer Letter Ha" +6049 "Khmer Letter La" +6050 "Khmer Letter Qa" +6051 "Khmer Independent Vowel Qaq" +6052 "Khmer Independent Vowel Qaa" +6053 "Khmer Independent Vowel Qi" +6054 "Khmer Independent Vowel Qii" +6055 "Khmer Independent Vowel Qu" +6056 "Khmer Independent Vowel Quk" +6057 "Khmer Independent Vowel Quu" +6058 "Khmer Independent Vowel Quuv" +6059 "Khmer Independent Vowel Ry" +6060 "Khmer Independent Vowel Ryy" +6061 "Khmer Independent Vowel Ly" +6062 "Khmer Independent Vowel Lyy" +6063 "Khmer Independent Vowel Qe" +6064 "Khmer Independent Vowel Qai" +6065 "Khmer Independent Vowel Qoo Type One" +6066 "Khmer Independent Vowel Qoo Type Two" +6067 "Khmer Independent Vowel Qau" +6068 "Khmer Vowel Inherent Aq" +6069 "Khmer Vowel Inherent Aa" +6070 "Khmer Vowel Sign Aa" +6071 "Khmer Vowel Sign I" +6072 "Khmer Vowel Sign Ii" +6073 "Khmer Vowel Sign Y" +6074 "Khmer Vowel Sign Yy" +6075 "Khmer Vowel Sign U" +6076 "Khmer Vowel Sign Uu" +6077 "Khmer Vowel Sign Ua" +6078 "Khmer Vowel Sign Oe" +6079 "Khmer Vowel Sign Ya" +6080 "Khmer Vowel Sign Ie" +6081 "Khmer Vowel Sign E" +6082 "Khmer Vowel Sign Ae" +6083 "Khmer Vowel Sign Ai" +6084 "Khmer Vowel Sign Oo" +6085 "Khmer Vowel Sign Au" +6086 "Khmer Sign Nikahit" +6087 "Khmer Sign Reahmuk" +6088 "Khmer Sign Yuukaleapintu" +6089 "Khmer Sign Muusikatoan" +6090 "Khmer Sign Triisap" +6091 "Khmer Sign Bantoc" +6092 "Khmer Sign Robat" +6093 "Khmer Sign Toandakhiat" +6094 "Khmer Sign Kakabat" +6095 "Khmer Sign Ahsda" +6096 "Khmer Sign Samyok Sannya" +6097 "Khmer Sign Viriam" +6098 "Khmer Sign Coeng" +6099 "Khmer Sign Bathamasat" +6100 "Khmer Sign Khan" +6101 "Khmer Sign Bariyoosan" +6102 "Khmer Sign Camnuc Pii Kuuh" +6103 "Khmer Sign Lek Too" +6104 "Khmer Sign Beyyal" +6105 "Khmer Sign Phnaek Muan" +6106 "Khmer Sign Koomuut" +6107 "Khmer Currency Symbol Riel" +6108 "Khmer Sign Avakrahasanya" +6109 "Khmer Sign Atthacan" +6112 "Khmer Digit Zero" +6113 "Khmer Digit One" +6114 "Khmer Digit Two" +6115 "Khmer Digit Three" +6116 "Khmer Digit Four" +6117 "Khmer Digit Five" +6118 "Khmer Digit Six" +6119 "Khmer Digit Seven" +6120 "Khmer Digit Eight" +6121 "Khmer Digit Nine" +6128 "Khmer Symbol Lek Attak Son" +6129 "Khmer Symbol Lek Attak Muoy" +6130 "Khmer Symbol Lek Attak Pii" +6131 "Khmer Symbol Lek Attak Bei" +6132 "Khmer Symbol Lek Attak Buon" +6133 "Khmer Symbol Lek Attak Pram" +6134 "Khmer Symbol Lek Attak Pram-Muoy" +6135 "Khmer Symbol Lek Attak Pram-Pii" +6136 "Khmer Symbol Lek Attak Pram-Bei" +6137 "Khmer Symbol Lek Attak Pram-Buon" +6144 "Mongolian Birga" +6145 "Mongolian Ellipsis" +6146 "Mongolian Comma" +6147 "Mongolian Full Stop" +6148 "Mongolian Colon" +6149 "Mongolian Four Dots" +6150 "Mongolian Todo Soft Hyphen" +6151 "Mongolian Sibe Syllable Boundary Marker" +6152 "Mongolian Manchu Comma" +6153 "Mongolian Manchu Full Stop" +6154 "Mongolian Nirugu" +6155 "Mongolian Free Variation Selector One" +6156 "Mongolian Free Variation Selector Two" +6157 "Mongolian Free Variation Selector Three" +6158 "Mongolian Vowel Separator" +6160 "Mongolian Digit Zero" +6161 "Mongolian Digit One" +6162 "Mongolian Digit Two" +6163 "Mongolian Digit Three" +6164 "Mongolian Digit Four" +6165 "Mongolian Digit Five" +6166 "Mongolian Digit Six" +6167 "Mongolian Digit Seven" +6168 "Mongolian Digit Eight" +6169 "Mongolian Digit Nine" +6176 "Mongolian Letter A" +6177 "Mongolian Letter E" +6178 "Mongolian Letter I" +6179 "Mongolian Letter O" +6180 "Mongolian Letter U" +6181 "Mongolian Letter Oe" +6182 "Mongolian Letter Ue" +6183 "Mongolian Letter Ee" +6184 "Mongolian Letter Na" +6185 "Mongolian Letter Ang" +6186 "Mongolian Letter Ba" +6187 "Mongolian Letter Pa" +6188 "Mongolian Letter Qa" +6189 "Mongolian Letter Ga" +6190 "Mongolian Letter Ma" +6191 "Mongolian Letter La" +6192 "Mongolian Letter Sa" +6193 "Mongolian Letter Sha" +6194 "Mongolian Letter Ta" +6195 "Mongolian Letter Da" +6196 "Mongolian Letter Cha" +6197 "Mongolian Letter Ja" +6198 "Mongolian Letter Ya" +6199 "Mongolian Letter Ra" +6200 "Mongolian Letter Wa" +6201 "Mongolian Letter Fa" +6202 "Mongolian Letter Ka" +6203 "Mongolian Letter Kha" +6204 "Mongolian Letter Tsa" +6205 "Mongolian Letter Za" +6206 "Mongolian Letter Haa" +6207 "Mongolian Letter Zra" +6208 "Mongolian Letter Lha" +6209 "Mongolian Letter Zhi" +6210 "Mongolian Letter Chi" +6211 "Mongolian Letter Todo Long Vowel Sign" +6212 "Mongolian Letter Todo E" +6213 "Mongolian Letter Todo I" +6214 "Mongolian Letter Todo O" +6215 "Mongolian Letter Todo U" +6216 "Mongolian Letter Todo Oe" +6217 "Mongolian Letter Todo Ue" +6218 "Mongolian Letter Todo Ang" +6219 "Mongolian Letter Todo Ba" +6220 "Mongolian Letter Todo Pa" +6221 "Mongolian Letter Todo Qa" +6222 "Mongolian Letter Todo Ga" +6223 "Mongolian Letter Todo Ma" +6224 "Mongolian Letter Todo Ta" +6225 "Mongolian Letter Todo Da" +6226 "Mongolian Letter Todo Cha" +6227 "Mongolian Letter Todo Ja" +6228 "Mongolian Letter Todo Tsa" +6229 "Mongolian Letter Todo Ya" +6230 "Mongolian Letter Todo Wa" +6231 "Mongolian Letter Todo Ka" +6232 "Mongolian Letter Todo Gaa" +6233 "Mongolian Letter Todo Haa" +6234 "Mongolian Letter Todo Jia" +6235 "Mongolian Letter Todo Nia" +6236 "Mongolian Letter Todo Dza" +6237 "Mongolian Letter Sibe E" +6238 "Mongolian Letter Sibe I" +6239 "Mongolian Letter Sibe Iy" +6240 "Mongolian Letter Sibe Ue" +6241 "Mongolian Letter Sibe U" +6242 "Mongolian Letter Sibe Ang" +6243 "Mongolian Letter Sibe Ka" +6244 "Mongolian Letter Sibe Ga" +6245 "Mongolian Letter Sibe Ha" +6246 "Mongolian Letter Sibe Pa" +6247 "Mongolian Letter Sibe Sha" +6248 "Mongolian Letter Sibe Ta" +6249 "Mongolian Letter Sibe Da" +6250 "Mongolian Letter Sibe Ja" +6251 "Mongolian Letter Sibe Fa" +6252 "Mongolian Letter Sibe Gaa" +6253 "Mongolian Letter Sibe Haa" +6254 "Mongolian Letter Sibe Tsa" +6255 "Mongolian Letter Sibe Za" +6256 "Mongolian Letter Sibe Raa" +6257 "Mongolian Letter Sibe Cha" +6258 "Mongolian Letter Sibe Zha" +6259 "Mongolian Letter Manchu I" +6260 "Mongolian Letter Manchu Ka" +6261 "Mongolian Letter Manchu Ra" +6262 "Mongolian Letter Manchu Fa" +6263 "Mongolian Letter Manchu Zha" +6272 "Mongolian Letter Ali Gali Anusvara One" +6273 "Mongolian Letter Ali Gali Visarga One" +6274 "Mongolian Letter Ali Gali Damaru" +6275 "Mongolian Letter Ali Gali Ubadama" +6276 "Mongolian Letter Ali Gali Inverted Ubadama" +6277 "Mongolian Letter Ali Gali Baluda" +6278 "Mongolian Letter Ali Gali Three Baluda" +6279 "Mongolian Letter Ali Gali A" +6280 "Mongolian Letter Ali Gali I" +6281 "Mongolian Letter Ali Gali Ka" +6282 "Mongolian Letter Ali Gali Nga" +6283 "Mongolian Letter Ali Gali Ca" +6284 "Mongolian Letter Ali Gali Tta" +6285 "Mongolian Letter Ali Gali Ttha" +6286 "Mongolian Letter Ali Gali Dda" +6287 "Mongolian Letter Ali Gali Nna" +6288 "Mongolian Letter Ali Gali Ta" +6289 "Mongolian Letter Ali Gali Da" +6290 "Mongolian Letter Ali Gali Pa" +6291 "Mongolian Letter Ali Gali Pha" +6292 "Mongolian Letter Ali Gali Ssa" +6293 "Mongolian Letter Ali Gali Zha" +6294 "Mongolian Letter Ali Gali Za" +6295 "Mongolian Letter Ali Gali Ah" +6296 "Mongolian Letter Todo Ali Gali Ta" +6297 "Mongolian Letter Todo Ali Gali Zha" +6298 "Mongolian Letter Manchu Ali Gali Gha" +6299 "Mongolian Letter Manchu Ali Gali Nga" +6300 "Mongolian Letter Manchu Ali Gali Ca" +6301 "Mongolian Letter Manchu Ali Gali Jha" +6302 "Mongolian Letter Manchu Ali Gali Tta" +6303 "Mongolian Letter Manchu Ali Gali Ddha" +6304 "Mongolian Letter Manchu Ali Gali Ta" +6305 "Mongolian Letter Manchu Ali Gali Dha" +6306 "Mongolian Letter Manchu Ali Gali Ssa" +6307 "Mongolian Letter Manchu Ali Gali Cya" +6308 "Mongolian Letter Manchu Ali Gali Zha" +6309 "Mongolian Letter Manchu Ali Gali Za" +6310 "Mongolian Letter Ali Gali Half U" +6311 "Mongolian Letter Ali Gali Half Ya" +6312 "Mongolian Letter Manchu Ali Gali Bha" +6313 "Mongolian Letter Ali Gali Dagalga" +6314 "Mongolian Letter Manchu Ali Gali Lha" +6320 "Canadian Syllabics Oy" +6321 "Canadian Syllabics Ay" +6322 "Canadian Syllabics Aay" +6323 "Canadian Syllabics Way" +6324 "Canadian Syllabics Poy" +6325 "Canadian Syllabics Pay" +6326 "Canadian Syllabics Pwoy" +6327 "Canadian Syllabics Tay" +6328 "Canadian Syllabics Kay" +6329 "Canadian Syllabics Kway" +6330 "Canadian Syllabics May" +6331 "Canadian Syllabics Noy" +6332 "Canadian Syllabics Nay" +6333 "Canadian Syllabics Lay" +6334 "Canadian Syllabics Soy" +6335 "Canadian Syllabics Say" +6336 "Canadian Syllabics Shoy" +6337 "Canadian Syllabics Shay" +6338 "Canadian Syllabics Shwoy" +6339 "Canadian Syllabics Yoy" +6340 "Canadian Syllabics Yay" +6341 "Canadian Syllabics Ray" +6342 "Canadian Syllabics Nwi" +6343 "Canadian Syllabics Ojibway Nwi" +6344 "Canadian Syllabics Nwii" +6345 "Canadian Syllabics Ojibway Nwii" +6346 "Canadian Syllabics Nwo" +6347 "Canadian Syllabics Ojibway Nwo" +6348 "Canadian Syllabics Nwoo" +6349 "Canadian Syllabics Ojibway Nwoo" +6350 "Canadian Syllabics Rwee" +6351 "Canadian Syllabics Rwi" +6352 "Canadian Syllabics Rwii" +6353 "Canadian Syllabics Rwo" +6354 "Canadian Syllabics Rwoo" +6355 "Canadian Syllabics Rwa" +6356 "Canadian Syllabics Ojibway P" +6357 "Canadian Syllabics Ojibway T" +6358 "Canadian Syllabics Ojibway K" +6359 "Canadian Syllabics Ojibway C" +6360 "Canadian Syllabics Ojibway M" +6361 "Canadian Syllabics Ojibway N" +6362 "Canadian Syllabics Ojibway S" +6363 "Canadian Syllabics Ojibway Sh" +6364 "Canadian Syllabics Eastern W" +6365 "Canadian Syllabics Western W" +6366 "Canadian Syllabics Final Small Ring" +6367 "Canadian Syllabics Final Raised Dot" +6368 "Canadian Syllabics R-Cree Rwe" +6369 "Canadian Syllabics West-Cree Loo" +6370 "Canadian Syllabics West-Cree Laa" +6371 "Canadian Syllabics Thwe" +6372 "Canadian Syllabics Thwa" +6373 "Canadian Syllabics Tthwe" +6374 "Canadian Syllabics Tthoo" +6375 "Canadian Syllabics Tthaa" +6376 "Canadian Syllabics Tlhwe" +6377 "Canadian Syllabics Tlhoo" +6378 "Canadian Syllabics Sayisi Shwe" +6379 "Canadian Syllabics Sayisi Shoo" +6380 "Canadian Syllabics Sayisi Hoo" +6381 "Canadian Syllabics Carrier Gwu" +6382 "Canadian Syllabics Carrier Dene Gee" +6383 "Canadian Syllabics Carrier Gaa" +6384 "Canadian Syllabics Carrier Gwa" +6385 "Canadian Syllabics Sayisi Juu" +6386 "Canadian Syllabics Carrier Jwa" +6387 "Canadian Syllabics Beaver Dene L" +6388 "Canadian Syllabics Beaver Dene R" +6389 "Canadian Syllabics Carrier Dental S" +6400 "Limbu Vowel-Carrier Letter" +6401 "Limbu Letter Ka" +6402 "Limbu Letter Kha" +6403 "Limbu Letter Ga" +6404 "Limbu Letter Gha" +6405 "Limbu Letter Nga" +6406 "Limbu Letter Ca" +6407 "Limbu Letter Cha" +6408 "Limbu Letter Ja" +6409 "Limbu Letter Jha" +6410 "Limbu Letter Yan" +6411 "Limbu Letter Ta" +6412 "Limbu Letter Tha" +6413 "Limbu Letter Da" +6414 "Limbu Letter Dha" +6415 "Limbu Letter Na" +6416 "Limbu Letter Pa" +6417 "Limbu Letter Pha" +6418 "Limbu Letter Ba" +6419 "Limbu Letter Bha" +6420 "Limbu Letter Ma" +6421 "Limbu Letter Ya" +6422 "Limbu Letter Ra" +6423 "Limbu Letter La" +6424 "Limbu Letter Wa" +6425 "Limbu Letter Sha" +6426 "Limbu Letter Ssa" +6427 "Limbu Letter Sa" +6428 "Limbu Letter Ha" +6432 "Limbu Vowel Sign A" +6433 "Limbu Vowel Sign I" +6434 "Limbu Vowel Sign U" +6435 "Limbu Vowel Sign Ee" +6436 "Limbu Vowel Sign Ai" +6437 "Limbu Vowel Sign Oo" +6438 "Limbu Vowel Sign Au" +6439 "Limbu Vowel Sign E" +6440 "Limbu Vowel Sign O" +6441 "Limbu Subjoined Letter Ya" +6442 "Limbu Subjoined Letter Ra" +6443 "Limbu Subjoined Letter Wa" +6448 "Limbu Small Letter Ka" +6449 "Limbu Small Letter Nga" +6450 "Limbu Small Letter Anusvara" +6451 "Limbu Small Letter Ta" +6452 "Limbu Small Letter Na" +6453 "Limbu Small Letter Pa" +6454 "Limbu Small Letter Ma" +6455 "Limbu Small Letter Ra" +6456 "Limbu Small Letter La" +6457 "Limbu Sign Mukphreng" +6458 "Limbu Sign Kemphreng" +6459 "Limbu Sign Sa-I" +6464 "Limbu Sign Loo" +6468 "Limbu Exclamation Mark" +6469 "Limbu Question Mark" +6470 "Limbu Digit Zero" +6471 "Limbu Digit One" +6472 "Limbu Digit Two" +6473 "Limbu Digit Three" +6474 "Limbu Digit Four" +6475 "Limbu Digit Five" +6476 "Limbu Digit Six" +6477 "Limbu Digit Seven" +6478 "Limbu Digit Eight" +6479 "Limbu Digit Nine" +6480 "Tai Le Letter Ka" +6481 "Tai Le Letter Xa" +6482 "Tai Le Letter Nga" +6483 "Tai Le Letter Tsa" +6484 "Tai Le Letter Sa" +6485 "Tai Le Letter Ya" +6486 "Tai Le Letter Ta" +6487 "Tai Le Letter Tha" +6488 "Tai Le Letter La" +6489 "Tai Le Letter Pa" +6490 "Tai Le Letter Pha" +6491 "Tai Le Letter Ma" +6492 "Tai Le Letter Fa" +6493 "Tai Le Letter Va" +6494 "Tai Le Letter Ha" +6495 "Tai Le Letter Qa" +6496 "Tai Le Letter Kha" +6497 "Tai Le Letter Tsha" +6498 "Tai Le Letter Na" +6499 "Tai Le Letter A" +6500 "Tai Le Letter I" +6501 "Tai Le Letter Ee" +6502 "Tai Le Letter Eh" +6503 "Tai Le Letter U" +6504 "Tai Le Letter Oo" +6505 "Tai Le Letter O" +6506 "Tai Le Letter Ue" +6507 "Tai Le Letter E" +6508 "Tai Le Letter Aue" +6509 "Tai Le Letter Ai" +6512 "Tai Le Letter Tone-2" +6513 "Tai Le Letter Tone-3" +6514 "Tai Le Letter Tone-4" +6515 "Tai Le Letter Tone-5" +6516 "Tai Le Letter Tone-6" +6528 "New Tai Lue Letter High Qa" +6529 "New Tai Lue Letter Low Qa" +6530 "New Tai Lue Letter High Ka" +6531 "New Tai Lue Letter High Xa" +6532 "New Tai Lue Letter High Nga" +6533 "New Tai Lue Letter Low Ka" +6534 "New Tai Lue Letter Low Xa" +6535 "New Tai Lue Letter Low Nga" +6536 "New Tai Lue Letter High Tsa" +6537 "New Tai Lue Letter High Sa" +6538 "New Tai Lue Letter High Ya" +6539 "New Tai Lue Letter Low Tsa" +6540 "New Tai Lue Letter Low Sa" +6541 "New Tai Lue Letter Low Ya" +6542 "New Tai Lue Letter High Ta" +6543 "New Tai Lue Letter High Tha" +6544 "New Tai Lue Letter High Na" +6545 "New Tai Lue Letter Low Ta" +6546 "New Tai Lue Letter Low Tha" +6547 "New Tai Lue Letter Low Na" +6548 "New Tai Lue Letter High Pa" +6549 "New Tai Lue Letter High Pha" +6550 "New Tai Lue Letter High Ma" +6551 "New Tai Lue Letter Low Pa" +6552 "New Tai Lue Letter Low Pha" +6553 "New Tai Lue Letter Low Ma" +6554 "New Tai Lue Letter High Fa" +6555 "New Tai Lue Letter High Va" +6556 "New Tai Lue Letter High La" +6557 "New Tai Lue Letter Low Fa" +6558 "New Tai Lue Letter Low Va" +6559 "New Tai Lue Letter Low La" +6560 "New Tai Lue Letter High Ha" +6561 "New Tai Lue Letter High Da" +6562 "New Tai Lue Letter High Ba" +6563 "New Tai Lue Letter Low Ha" +6564 "New Tai Lue Letter Low Da" +6565 "New Tai Lue Letter Low Ba" +6566 "New Tai Lue Letter High Kva" +6567 "New Tai Lue Letter High Xva" +6568 "New Tai Lue Letter Low Kva" +6569 "New Tai Lue Letter Low Xva" +6570 "New Tai Lue Letter High Sua" +6571 "New Tai Lue Letter Low Sua" +6576 "New Tai Lue Vowel Sign Vowel Shortener" +6577 "New Tai Lue Vowel Sign Aa" +6578 "New Tai Lue Vowel Sign Ii" +6579 "New Tai Lue Vowel Sign U" +6580 "New Tai Lue Vowel Sign Uu" +6581 "New Tai Lue Vowel Sign E" +6582 "New Tai Lue Vowel Sign Ae" +6583 "New Tai Lue Vowel Sign O" +6584 "New Tai Lue Vowel Sign Oa" +6585 "New Tai Lue Vowel Sign Ue" +6586 "New Tai Lue Vowel Sign Ay" +6587 "New Tai Lue Vowel Sign Aay" +6588 "New Tai Lue Vowel Sign Uy" +6589 "New Tai Lue Vowel Sign Oy" +6590 "New Tai Lue Vowel Sign Oay" +6591 "New Tai Lue Vowel Sign Uey" +6592 "New Tai Lue Vowel Sign Iy" +6593 "New Tai Lue Letter Final V" +6594 "New Tai Lue Letter Final Ng" +6595 "New Tai Lue Letter Final N" +6596 "New Tai Lue Letter Final M" +6597 "New Tai Lue Letter Final K" +6598 "New Tai Lue Letter Final D" +6599 "New Tai Lue Letter Final B" +6600 "New Tai Lue Tone Mark-1" +6601 "New Tai Lue Tone Mark-2" +6608 "New Tai Lue Digit Zero" +6609 "New Tai Lue Digit One" +6610 "New Tai Lue Digit Two" +6611 "New Tai Lue Digit Three" +6612 "New Tai Lue Digit Four" +6613 "New Tai Lue Digit Five" +6614 "New Tai Lue Digit Six" +6615 "New Tai Lue Digit Seven" +6616 "New Tai Lue Digit Eight" +6617 "New Tai Lue Digit Nine" +6618 "New Tai Lue Tham Digit One" +6622 "New Tai Lue Sign Lae" +6623 "New Tai Lue Sign Laev" +6624 "Khmer Symbol Pathamasat" +6625 "Khmer Symbol Muoy Koet" +6626 "Khmer Symbol Pii Koet" +6627 "Khmer Symbol Bei Koet" +6628 "Khmer Symbol Buon Koet" +6629 "Khmer Symbol Pram Koet" +6630 "Khmer Symbol Pram-Muoy Koet" +6631 "Khmer Symbol Pram-Pii Koet" +6632 "Khmer Symbol Pram-Bei Koet" +6633 "Khmer Symbol Pram-Buon Koet" +6634 "Khmer Symbol Dap Koet" +6635 "Khmer Symbol Dap-Muoy Koet" +6636 "Khmer Symbol Dap-Pii Koet" +6637 "Khmer Symbol Dap-Bei Koet" +6638 "Khmer Symbol Dap-Buon Koet" +6639 "Khmer Symbol Dap-Pram Koet" +6640 "Khmer Symbol Tuteyasat" +6641 "Khmer Symbol Muoy Roc" +6642 "Khmer Symbol Pii Roc" +6643 "Khmer Symbol Bei Roc" +6644 "Khmer Symbol Buon Roc" +6645 "Khmer Symbol Pram Roc" +6646 "Khmer Symbol Pram-Muoy Roc" +6647 "Khmer Symbol Pram-Pii Roc" +6648 "Khmer Symbol Pram-Bei Roc" +6649 "Khmer Symbol Pram-Buon Roc" +6650 "Khmer Symbol Dap Roc" +6651 "Khmer Symbol Dap-Muoy Roc" +6652 "Khmer Symbol Dap-Pii Roc" +6653 "Khmer Symbol Dap-Bei Roc" +6654 "Khmer Symbol Dap-Buon Roc" +6655 "Khmer Symbol Dap-Pram Roc" +6656 "Buginese Letter Ka" +6657 "Buginese Letter Ga" +6658 "Buginese Letter Nga" +6659 "Buginese Letter Ngka" +6660 "Buginese Letter Pa" +6661 "Buginese Letter Ba" +6662 "Buginese Letter Ma" +6663 "Buginese Letter Mpa" +6664 "Buginese Letter Ta" +6665 "Buginese Letter Da" +6666 "Buginese Letter Na" +6667 "Buginese Letter Nra" +6668 "Buginese Letter Ca" +6669 "Buginese Letter Ja" +6670 "Buginese Letter Nya" +6671 "Buginese Letter Nyca" +6672 "Buginese Letter Ya" +6673 "Buginese Letter Ra" +6674 "Buginese Letter La" +6675 "Buginese Letter Va" +6676 "Buginese Letter Sa" +6677 "Buginese Letter A" +6678 "Buginese Letter Ha" +6679 "Buginese Vowel Sign I" +6680 "Buginese Vowel Sign U" +6681 "Buginese Vowel Sign E" +6682 "Buginese Vowel Sign O" +6683 "Buginese Vowel Sign Ae" +6686 "Buginese Pallawa" +6687 "Buginese End Of Section" +6688 "Tai Tham Letter High Ka" +6689 "Tai Tham Letter High Kha" +6690 "Tai Tham Letter High Kxa" +6691 "Tai Tham Letter Low Ka" +6692 "Tai Tham Letter Low Kxa" +6693 "Tai Tham Letter Low Kha" +6694 "Tai Tham Letter Nga" +6695 "Tai Tham Letter High Ca" +6696 "Tai Tham Letter High Cha" +6697 "Tai Tham Letter Low Ca" +6698 "Tai Tham Letter Low Sa" +6699 "Tai Tham Letter Low Cha" +6700 "Tai Tham Letter Nya" +6701 "Tai Tham Letter Rata" +6702 "Tai Tham Letter High Ratha" +6703 "Tai Tham Letter Da" +6704 "Tai Tham Letter Low Ratha" +6705 "Tai Tham Letter Rana" +6706 "Tai Tham Letter High Ta" +6707 "Tai Tham Letter High Tha" +6708 "Tai Tham Letter Low Ta" +6709 "Tai Tham Letter Low Tha" +6710 "Tai Tham Letter Na" +6711 "Tai Tham Letter Ba" +6712 "Tai Tham Letter High Pa" +6713 "Tai Tham Letter High Pha" +6714 "Tai Tham Letter High Fa" +6715 "Tai Tham Letter Low Pa" +6716 "Tai Tham Letter Low Fa" +6717 "Tai Tham Letter Low Pha" +6718 "Tai Tham Letter Ma" +6719 "Tai Tham Letter Low Ya" +6720 "Tai Tham Letter High Ya" +6721 "Tai Tham Letter Ra" +6722 "Tai Tham Letter Rue" +6723 "Tai Tham Letter La" +6724 "Tai Tham Letter Lue" +6725 "Tai Tham Letter Wa" +6726 "Tai Tham Letter High Sha" +6727 "Tai Tham Letter High Ssa" +6728 "Tai Tham Letter High Sa" +6729 "Tai Tham Letter High Ha" +6730 "Tai Tham Letter Lla" +6731 "Tai Tham Letter A" +6732 "Tai Tham Letter Low Ha" +6733 "Tai Tham Letter I" +6734 "Tai Tham Letter Ii" +6735 "Tai Tham Letter U" +6736 "Tai Tham Letter Uu" +6737 "Tai Tham Letter Ee" +6738 "Tai Tham Letter Oo" +6739 "Tai Tham Letter Lae" +6740 "Tai Tham Letter Great Sa" +6741 "Tai Tham Consonant Sign Medial Ra" +6742 "Tai Tham Consonant Sign Medial La" +6743 "Tai Tham Consonant Sign La Tang Lai" +6744 "Tai Tham Sign Mai Kang Lai" +6745 "Tai Tham Consonant Sign Final Nga" +6746 "Tai Tham Consonant Sign Low Pa" +6747 "Tai Tham Consonant Sign High Ratha Or Low Pa" +6748 "Tai Tham Consonant Sign Ma" +6749 "Tai Tham Consonant Sign Ba" +6750 "Tai Tham Consonant Sign Sa" +6752 "Tai Tham Sign Sakot" +6753 "Tai Tham Vowel Sign A" +6754 "Tai Tham Vowel Sign Mai Sat" +6755 "Tai Tham Vowel Sign Aa" +6756 "Tai Tham Vowel Sign Tall Aa" +6757 "Tai Tham Vowel Sign I" +6758 "Tai Tham Vowel Sign Ii" +6759 "Tai Tham Vowel Sign Ue" +6760 "Tai Tham Vowel Sign Uue" +6761 "Tai Tham Vowel Sign U" +6762 "Tai Tham Vowel Sign Uu" +6763 "Tai Tham Vowel Sign O" +6764 "Tai Tham Vowel Sign Oa Below" +6765 "Tai Tham Vowel Sign Oy" +6766 "Tai Tham Vowel Sign E" +6767 "Tai Tham Vowel Sign Ae" +6768 "Tai Tham Vowel Sign Oo" +6769 "Tai Tham Vowel Sign Ai" +6770 "Tai Tham Vowel Sign Tham Ai" +6771 "Tai Tham Vowel Sign Oa Above" +6772 "Tai Tham Sign Mai Kang" +6773 "Tai Tham Sign Tone-1" +6774 "Tai Tham Sign Tone-2" +6775 "Tai Tham Sign Khuen Tone-3" +6776 "Tai Tham Sign Khuen Tone-4" +6777 "Tai Tham Sign Khuen Tone-5" +6778 "Tai Tham Sign Ra Haam" +6779 "Tai Tham Sign Mai Sam" +6780 "Tai Tham Sign Khuen-Lue Karan" +6783 "Tai Tham Combining Cryptogrammic Dot" +6784 "Tai Tham Hora Digit Zero" +6785 "Tai Tham Hora Digit One" +6786 "Tai Tham Hora Digit Two" +6787 "Tai Tham Hora Digit Three" +6788 "Tai Tham Hora Digit Four" +6789 "Tai Tham Hora Digit Five" +6790 "Tai Tham Hora Digit Six" +6791 "Tai Tham Hora Digit Seven" +6792 "Tai Tham Hora Digit Eight" +6793 "Tai Tham Hora Digit Nine" +6800 "Tai Tham Tham Digit Zero" +6801 "Tai Tham Tham Digit One" +6802 "Tai Tham Tham Digit Two" +6803 "Tai Tham Tham Digit Three" +6804 "Tai Tham Tham Digit Four" +6805 "Tai Tham Tham Digit Five" +6806 "Tai Tham Tham Digit Six" +6807 "Tai Tham Tham Digit Seven" +6808 "Tai Tham Tham Digit Eight" +6809 "Tai Tham Tham Digit Nine" +6816 "Tai Tham Sign Wiang" +6817 "Tai Tham Sign Wiangwaak" +6818 "Tai Tham Sign Sawan" +6819 "Tai Tham Sign Keow" +6820 "Tai Tham Sign Hoy" +6821 "Tai Tham Sign Dokmai" +6822 "Tai Tham Sign Reversed Rotated Rana" +6823 "Tai Tham Sign Mai Yamok" +6824 "Tai Tham Sign Kaan" +6825 "Tai Tham Sign Kaankuu" +6826 "Tai Tham Sign Satkaan" +6827 "Tai Tham Sign Satkaankuu" +6828 "Tai Tham Sign Hang" +6829 "Tai Tham Sign Caang" +6912 "Balinese Sign Ulu Ricem" +6913 "Balinese Sign Ulu Candra" +6914 "Balinese Sign Cecek" +6915 "Balinese Sign Surang" +6916 "Balinese Sign Bisah" +6917 "Balinese Letter Akara" +6918 "Balinese Letter Akara Tedung" +6919 "Balinese Letter Ikara" +6920 "Balinese Letter Ikara Tedung" +6921 "Balinese Letter Ukara" +6922 "Balinese Letter Ukara Tedung" +6923 "Balinese Letter Ra Repa" +6924 "Balinese Letter Ra Repa Tedung" +6925 "Balinese Letter La Lenga" +6926 "Balinese Letter La Lenga Tedung" +6927 "Balinese Letter Ekara" +6928 "Balinese Letter Aikara" +6929 "Balinese Letter Okara" +6930 "Balinese Letter Okara Tedung" +6931 "Balinese Letter Ka" +6932 "Balinese Letter Ka Mahaprana" +6933 "Balinese Letter Ga" +6934 "Balinese Letter Ga Gora" +6935 "Balinese Letter Nga" +6936 "Balinese Letter Ca" +6937 "Balinese Letter Ca Laca" +6938 "Balinese Letter Ja" +6939 "Balinese Letter Ja Jera" +6940 "Balinese Letter Nya" +6941 "Balinese Letter Ta Latik" +6942 "Balinese Letter Ta Murda Mahaprana" +6943 "Balinese Letter Da Murda Alpaprana" +6944 "Balinese Letter Da Murda Mahaprana" +6945 "Balinese Letter Na Rambat" +6946 "Balinese Letter Ta" +6947 "Balinese Letter Ta Tawa" +6948 "Balinese Letter Da" +6949 "Balinese Letter Da Madu" +6950 "Balinese Letter Na" +6951 "Balinese Letter Pa" +6952 "Balinese Letter Pa Kapal" +6953 "Balinese Letter Ba" +6954 "Balinese Letter Ba Kembang" +6955 "Balinese Letter Ma" +6956 "Balinese Letter Ya" +6957 "Balinese Letter Ra" +6958 "Balinese Letter La" +6959 "Balinese Letter Wa" +6960 "Balinese Letter Sa Saga" +6961 "Balinese Letter Sa Sapa" +6962 "Balinese Letter Sa" +6963 "Balinese Letter Ha" +6964 "Balinese Sign Rerekan" +6965 "Balinese Vowel Sign Tedung" +6966 "Balinese Vowel Sign Ulu" +6967 "Balinese Vowel Sign Ulu Sari" +6968 "Balinese Vowel Sign Suku" +6969 "Balinese Vowel Sign Suku Ilut" +6970 "Balinese Vowel Sign Ra Repa" +6971 "Balinese Vowel Sign Ra Repa Tedung" +6972 "Balinese Vowel Sign La Lenga" +6973 "Balinese Vowel Sign La Lenga Tedung" +6974 "Balinese Vowel Sign Taling" +6975 "Balinese Vowel Sign Taling Repa" +6976 "Balinese Vowel Sign Taling Tedung" +6977 "Balinese Vowel Sign Taling Repa Tedung" +6978 "Balinese Vowel Sign Pepet" +6979 "Balinese Vowel Sign Pepet Tedung" +6980 "Balinese Adeg Adeg" +6981 "Balinese Letter Kaf Sasak" +6982 "Balinese Letter Khot Sasak" +6983 "Balinese Letter Tzir Sasak" +6984 "Balinese Letter Ef Sasak" +6985 "Balinese Letter Ve Sasak" +6986 "Balinese Letter Zal Sasak" +6987 "Balinese Letter Asyura Sasak" +6992 "Balinese Digit Zero" +6993 "Balinese Digit One" +6994 "Balinese Digit Two" +6995 "Balinese Digit Three" +6996 "Balinese Digit Four" +6997 "Balinese Digit Five" +6998 "Balinese Digit Six" +6999 "Balinese Digit Seven" +7000 "Balinese Digit Eight" +7001 "Balinese Digit Nine" +7002 "Balinese Panti" +7003 "Balinese Pamada" +7004 "Balinese Windu" +7005 "Balinese Carik Pamungkah" +7006 "Balinese Carik Siki" +7007 "Balinese Carik Pareren" +7008 "Balinese Pameneng" +7009 "Balinese Musical Symbol Dong" +7010 "Balinese Musical Symbol Deng" +7011 "Balinese Musical Symbol Dung" +7012 "Balinese Musical Symbol Dang" +7013 "Balinese Musical Symbol Dang Surang" +7014 "Balinese Musical Symbol Ding" +7015 "Balinese Musical Symbol Daeng" +7016 "Balinese Musical Symbol Deung" +7017 "Balinese Musical Symbol Daing" +7018 "Balinese Musical Symbol Dang Gede" +7019 "Balinese Musical Symbol Combining Tegeh" +7020 "Balinese Musical Symbol Combining Endep" +7021 "Balinese Musical Symbol Combining Kempul" +7022 "Balinese Musical Symbol Combining Kempli" +7023 "Balinese Musical Symbol Combining Jegogan" +7024 "Balinese Musical Symbol Combining Kempul With Jegogan" +7025 "Balinese Musical Symbol Combining Kempli With Jegogan" +7026 "Balinese Musical Symbol Combining Bende" +7027 "Balinese Musical Symbol Combining Gong" +7028 "Balinese Musical Symbol Right-Hand Open Dug" +7029 "Balinese Musical Symbol Right-Hand Open Dag" +7030 "Balinese Musical Symbol Right-Hand Closed Tuk" +7031 "Balinese Musical Symbol Right-Hand Closed Tak" +7032 "Balinese Musical Symbol Left-Hand Open Pang" +7033 "Balinese Musical Symbol Left-Hand Open Pung" +7034 "Balinese Musical Symbol Left-Hand Closed Plak" +7035 "Balinese Musical Symbol Left-Hand Closed Pluk" +7036 "Balinese Musical Symbol Left-Hand Open Ping" +7040 "Sundanese Sign Panyecek" +7041 "Sundanese Sign Panglayar" +7042 "Sundanese Sign Pangwisad" +7043 "Sundanese Letter A" +7044 "Sundanese Letter I" +7045 "Sundanese Letter U" +7046 "Sundanese Letter Ae" +7047 "Sundanese Letter O" +7048 "Sundanese Letter E" +7049 "Sundanese Letter Eu" +7050 "Sundanese Letter Ka" +7051 "Sundanese Letter Qa" +7052 "Sundanese Letter Ga" +7053 "Sundanese Letter Nga" +7054 "Sundanese Letter Ca" +7055 "Sundanese Letter Ja" +7056 "Sundanese Letter Za" +7057 "Sundanese Letter Nya" +7058 "Sundanese Letter Ta" +7059 "Sundanese Letter Da" +7060 "Sundanese Letter Na" +7061 "Sundanese Letter Pa" +7062 "Sundanese Letter Fa" +7063 "Sundanese Letter Va" +7064 "Sundanese Letter Ba" +7065 "Sundanese Letter Ma" +7066 "Sundanese Letter Ya" +7067 "Sundanese Letter Ra" +7068 "Sundanese Letter La" +7069 "Sundanese Letter Wa" +7070 "Sundanese Letter Sa" +7071 "Sundanese Letter Xa" +7072 "Sundanese Letter Ha" +7073 "Sundanese Consonant Sign Pamingkal" +7074 "Sundanese Consonant Sign Panyakra" +7075 "Sundanese Consonant Sign Panyiku" +7076 "Sundanese Vowel Sign Panghulu" +7077 "Sundanese Vowel Sign Panyuku" +7078 "Sundanese Vowel Sign Panaelaeng" +7079 "Sundanese Vowel Sign Panolong" +7080 "Sundanese Vowel Sign Pamepet" +7081 "Sundanese Vowel Sign Paneuleung" +7082 "Sundanese Sign Pamaaeh" +7083 "Sundanese Sign Virama" +7084 "Sundanese Consonant Sign Pasangan Ma" +7085 "Sundanese Consonant Sign Pasangan Wa" +7086 "Sundanese Letter Kha" +7087 "Sundanese Letter Sya" +7088 "Sundanese Digit Zero" +7089 "Sundanese Digit One" +7090 "Sundanese Digit Two" +7091 "Sundanese Digit Three" +7092 "Sundanese Digit Four" +7093 "Sundanese Digit Five" +7094 "Sundanese Digit Six" +7095 "Sundanese Digit Seven" +7096 "Sundanese Digit Eight" +7097 "Sundanese Digit Nine" +7098 "Sundanese Avagraha" +7099 "Sundanese Letter Reu" +7100 "Sundanese Letter Leu" +7101 "Sundanese Letter Bha" +7102 "Sundanese Letter Final K" +7103 "Sundanese Letter Final M" +7104 "Batak Letter A" +7105 "Batak Letter Simalungun A" +7106 "Batak Letter Ha" +7107 "Batak Letter Simalungun Ha" +7108 "Batak Letter Mandailing Ha" +7109 "Batak Letter Ba" +7110 "Batak Letter Karo Ba" +7111 "Batak Letter Pa" +7112 "Batak Letter Simalungun Pa" +7113 "Batak Letter Na" +7114 "Batak Letter Mandailing Na" +7115 "Batak Letter Wa" +7116 "Batak Letter Simalungun Wa" +7117 "Batak Letter Pakpak Wa" +7118 "Batak Letter Ga" +7119 "Batak Letter Simalungun Ga" +7120 "Batak Letter Ja" +7121 "Batak Letter Da" +7122 "Batak Letter Ra" +7123 "Batak Letter Simalungun Ra" +7124 "Batak Letter Ma" +7125 "Batak Letter Simalungun Ma" +7126 "Batak Letter Southern Ta" +7127 "Batak Letter Northern Ta" +7128 "Batak Letter Sa" +7129 "Batak Letter Simalungun Sa" +7130 "Batak Letter Mandailing Sa" +7131 "Batak Letter Ya" +7132 "Batak Letter Simalungun Ya" +7133 "Batak Letter Nga" +7134 "Batak Letter La" +7135 "Batak Letter Simalungun La" +7136 "Batak Letter Nya" +7137 "Batak Letter Ca" +7138 "Batak Letter Nda" +7139 "Batak Letter Mba" +7140 "Batak Letter I" +7141 "Batak Letter U" +7142 "Batak Sign Tompi" +7143 "Batak Vowel Sign E" +7144 "Batak Vowel Sign Pakpak E" +7145 "Batak Vowel Sign Ee" +7146 "Batak Vowel Sign I" +7147 "Batak Vowel Sign Karo I" +7148 "Batak Vowel Sign O" +7149 "Batak Vowel Sign Karo O" +7150 "Batak Vowel Sign U" +7151 "Batak Vowel Sign U For Simalungun Sa" +7152 "Batak Consonant Sign Ng" +7153 "Batak Consonant Sign H" +7154 "Batak Pangolat" +7155 "Batak Panongonan" +7164 "Batak Symbol Bindu Na Metek" +7165 "Batak Symbol Bindu Pinarboras" +7166 "Batak Symbol Bindu Judul" +7167 "Batak Symbol Bindu Pangolat" +7168 "Lepcha Letter Ka" +7169 "Lepcha Letter Kla" +7170 "Lepcha Letter Kha" +7171 "Lepcha Letter Ga" +7172 "Lepcha Letter Gla" +7173 "Lepcha Letter Nga" +7174 "Lepcha Letter Ca" +7175 "Lepcha Letter Cha" +7176 "Lepcha Letter Ja" +7177 "Lepcha Letter Nya" +7178 "Lepcha Letter Ta" +7179 "Lepcha Letter Tha" +7180 "Lepcha Letter Da" +7181 "Lepcha Letter Na" +7182 "Lepcha Letter Pa" +7183 "Lepcha Letter Pla" +7184 "Lepcha Letter Pha" +7185 "Lepcha Letter Fa" +7186 "Lepcha Letter Fla" +7187 "Lepcha Letter Ba" +7188 "Lepcha Letter Bla" +7189 "Lepcha Letter Ma" +7190 "Lepcha Letter Mla" +7191 "Lepcha Letter Tsa" +7192 "Lepcha Letter Tsha" +7193 "Lepcha Letter Dza" +7194 "Lepcha Letter Ya" +7195 "Lepcha Letter Ra" +7196 "Lepcha Letter La" +7197 "Lepcha Letter Ha" +7198 "Lepcha Letter Hla" +7199 "Lepcha Letter Va" +7200 "Lepcha Letter Sa" +7201 "Lepcha Letter Sha" +7202 "Lepcha Letter Wa" +7203 "Lepcha Letter A" +7204 "Lepcha Subjoined Letter Ya" +7205 "Lepcha Subjoined Letter Ra" +7206 "Lepcha Vowel Sign Aa" +7207 "Lepcha Vowel Sign I" +7208 "Lepcha Vowel Sign O" +7209 "Lepcha Vowel Sign Oo" +7210 "Lepcha Vowel Sign U" +7211 "Lepcha Vowel Sign Uu" +7212 "Lepcha Vowel Sign E" +7213 "Lepcha Consonant Sign K" +7214 "Lepcha Consonant Sign M" +7215 "Lepcha Consonant Sign L" +7216 "Lepcha Consonant Sign N" +7217 "Lepcha Consonant Sign P" +7218 "Lepcha Consonant Sign R" +7219 "Lepcha Consonant Sign T" +7220 "Lepcha Consonant Sign Nyin-Do" +7221 "Lepcha Consonant Sign Kang" +7222 "Lepcha Sign Ran" +7223 "Lepcha Sign Nukta" +7227 "Lepcha Punctuation Ta-Rol" +7228 "Lepcha Punctuation Nyet Thyoom Ta-Rol" +7229 "Lepcha Punctuation Cer-Wa" +7230 "Lepcha Punctuation Tshook Cer-Wa" +7231 "Lepcha Punctuation Tshook" +7232 "Lepcha Digit Zero" +7233 "Lepcha Digit One" +7234 "Lepcha Digit Two" +7235 "Lepcha Digit Three" +7236 "Lepcha Digit Four" +7237 "Lepcha Digit Five" +7238 "Lepcha Digit Six" +7239 "Lepcha Digit Seven" +7240 "Lepcha Digit Eight" +7241 "Lepcha Digit Nine" +7245 "Lepcha Letter Tta" +7246 "Lepcha Letter Ttha" +7247 "Lepcha Letter Dda" +7248 "Ol Chiki Digit Zero" +7249 "Ol Chiki Digit One" +7250 "Ol Chiki Digit Two" +7251 "Ol Chiki Digit Three" +7252 "Ol Chiki Digit Four" +7253 "Ol Chiki Digit Five" +7254 "Ol Chiki Digit Six" +7255 "Ol Chiki Digit Seven" +7256 "Ol Chiki Digit Eight" +7257 "Ol Chiki Digit Nine" +7258 "Ol Chiki Letter La" +7259 "Ol Chiki Letter At" +7260 "Ol Chiki Letter Ag" +7261 "Ol Chiki Letter Ang" +7262 "Ol Chiki Letter Al" +7263 "Ol Chiki Letter Laa" +7264 "Ol Chiki Letter Aak" +7265 "Ol Chiki Letter Aaj" +7266 "Ol Chiki Letter Aam" +7267 "Ol Chiki Letter Aaw" +7268 "Ol Chiki Letter Li" +7269 "Ol Chiki Letter Is" +7270 "Ol Chiki Letter Ih" +7271 "Ol Chiki Letter Iny" +7272 "Ol Chiki Letter Ir" +7273 "Ol Chiki Letter Lu" +7274 "Ol Chiki Letter Uc" +7275 "Ol Chiki Letter Ud" +7276 "Ol Chiki Letter Unn" +7277 "Ol Chiki Letter Uy" +7278 "Ol Chiki Letter Le" +7279 "Ol Chiki Letter Ep" +7280 "Ol Chiki Letter Edd" +7281 "Ol Chiki Letter En" +7282 "Ol Chiki Letter Err" +7283 "Ol Chiki Letter Lo" +7284 "Ol Chiki Letter Ott" +7285 "Ol Chiki Letter Ob" +7286 "Ol Chiki Letter Ov" +7287 "Ol Chiki Letter Oh" +7288 "Ol Chiki Mu Ttuddag" +7289 "Ol Chiki Gaahlaa Ttuddaag" +7290 "Ol Chiki Mu-Gaahlaa Ttuddaag" +7291 "Ol Chiki Relaa" +7292 "Ol Chiki Phaarkaa" +7293 "Ol Chiki Ahad" +7294 "Ol Chiki Punctuation Mucaad" +7295 "Ol Chiki Punctuation Double Mucaad" +7360 "Sundanese Punctuation Bindu Surya" +7361 "Sundanese Punctuation Bindu Panglong" +7362 "Sundanese Punctuation Bindu Purnama" +7363 "Sundanese Punctuation Bindu Cakra" +7364 "Sundanese Punctuation Bindu Leu Satanga" +7365 "Sundanese Punctuation Bindu Ka Satanga" +7366 "Sundanese Punctuation Bindu Da Satanga" +7367 "Sundanese Punctuation Bindu Ba Satanga" +7376 "Vedic Tone Karshana" +7377 "Vedic Tone Shara" +7378 "Vedic Tone Prenkha" +7379 "Vedic Sign Nihshvasa" +7380 "Vedic Sign Yajurvedic Midline Svarita" +7381 "Vedic Tone Yajurvedic Aggravated Independent Svarita" +7382 "Vedic Tone Yajurvedic Independent Svarita" +7383 "Vedic Tone Yajurvedic Kathaka Independent Svarita" +7384 "Vedic Tone Candra Below" +7385 "Vedic Tone Yajurvedic Kathaka Independent Svarita Schroeder" +7386 "Vedic Tone Double Svarita" +7387 "Vedic Tone Triple Svarita" +7388 "Vedic Tone Kathaka Anudatta" +7389 "Vedic Tone Dot Below" +7390 "Vedic Tone Two Dots Below" +7391 "Vedic Tone Three Dots Below" +7392 "Vedic Tone Rigvedic Kashmiri Independent Svarita" +7393 "Vedic Tone Atharvavedic Independent Svarita" +7394 "Vedic Sign Visarga Svarita" +7395 "Vedic Sign Visarga Udatta" +7396 "Vedic Sign Reversed Visarga Udatta" +7397 "Vedic Sign Visarga Anudatta" +7398 "Vedic Sign Reversed Visarga Anudatta" +7399 "Vedic Sign Visarga Udatta With Tail" +7400 "Vedic Sign Visarga Anudatta With Tail" +7401 "Vedic Sign Anusvara Antargomukha" +7402 "Vedic Sign Anusvara Bahirgomukha" +7403 "Vedic Sign Anusvara Vamagomukha" +7404 "Vedic Sign Anusvara Vamagomukha With Tail" +7405 "Vedic Sign Tiryak" +7406 "Vedic Sign Hexiform Long Anusvara" +7407 "Vedic Sign Long Anusvara" +7408 "Vedic Sign Rthang Long Anusvara" +7409 "Vedic Sign Anusvara Ubhayato Mukha" +7410 "Vedic Sign Ardhavisarga" +7411 "Vedic Sign Rotated Ardhavisarga" +7412 "Vedic Tone Candra Above" +7413 "Vedic Sign Jihvamuliya" +7414 "Vedic Sign Upadhmaniya" +7424 "Latin Letter Small Capital A" +7425 "Latin Letter Small Capital Ae" +7426 "Latin Small Letter Turned Ae" +7427 "Latin Letter Small Capital Barred B" +7428 "Latin Letter Small Capital C" +7429 "Latin Letter Small Capital D" +7430 "Latin Letter Small Capital Eth" +7431 "Latin Letter Small Capital E" +7432 "Latin Small Letter Turned Open E" +7433 "Latin Small Letter Turned I" +7434 "Latin Letter Small Capital J" +7435 "Latin Letter Small Capital K" +7436 "Latin Letter Small Capital L With Stroke" +7437 "Latin Letter Small Capital M" +7438 "Latin Letter Small Capital Reversed N" +7439 "Latin Letter Small Capital O" +7440 "Latin Letter Small Capital Open O" +7441 "Latin Small Letter Sideways O" +7442 "Latin Small Letter Sideways Open O" +7443 "Latin Small Letter Sideways O With Stroke" +7444 "Latin Small Letter Turned Oe" +7445 "Latin Letter Small Capital Ou" +7446 "Latin Small Letter Top Half O" +7447 "Latin Small Letter Bottom Half O" +7448 "Latin Letter Small Capital P" +7449 "Latin Letter Small Capital Reversed R" +7450 "Latin Letter Small Capital Turned R" +7451 "Latin Letter Small Capital T" +7452 "Latin Letter Small Capital U" +7453 "Latin Small Letter Sideways U" +7454 "Latin Small Letter Sideways Diaeresized U" +7455 "Latin Small Letter Sideways Turned M" +7456 "Latin Letter Small Capital V" +7457 "Latin Letter Small Capital W" +7458 "Latin Letter Small Capital Z" +7459 "Latin Letter Small Capital Ezh" +7460 "Latin Letter Voiced Laryngeal Spirant" +7461 "Latin Letter Ain" +7462 "Greek Letter Small Capital Gamma" +7463 "Greek Letter Small Capital Lamda" +7464 "Greek Letter Small Capital Pi" +7465 "Greek Letter Small Capital Rho" +7466 "Greek Letter Small Capital Psi" +7467 "Cyrillic Letter Small Capital El" +7468 "Modifier Letter Capital A" +7469 "Modifier Letter Capital Ae" +7470 "Modifier Letter Capital B" +7471 "Modifier Letter Capital Barred B" +7472 "Modifier Letter Capital D" +7473 "Modifier Letter Capital E" +7474 "Modifier Letter Capital Reversed E" +7475 "Modifier Letter Capital G" +7476 "Modifier Letter Capital H" +7477 "Modifier Letter Capital I" +7478 "Modifier Letter Capital J" +7479 "Modifier Letter Capital K" +7480 "Modifier Letter Capital L" +7481 "Modifier Letter Capital M" +7482 "Modifier Letter Capital N" +7483 "Modifier Letter Capital Reversed N" +7484 "Modifier Letter Capital O" +7485 "Modifier Letter Capital Ou" +7486 "Modifier Letter Capital P" +7487 "Modifier Letter Capital R" +7488 "Modifier Letter Capital T" +7489 "Modifier Letter Capital U" +7490 "Modifier Letter Capital W" +7491 "Modifier Letter Small A" +7492 "Modifier Letter Small Turned A" +7493 "Modifier Letter Small Alpha" +7494 "Modifier Letter Small Turned Ae" +7495 "Modifier Letter Small B" +7496 "Modifier Letter Small D" +7497 "Modifier Letter Small E" +7498 "Modifier Letter Small Schwa" +7499 "Modifier Letter Small Open E" +7500 "Modifier Letter Small Turned Open E" +7501 "Modifier Letter Small G" +7502 "Modifier Letter Small Turned I" +7503 "Modifier Letter Small K" +7504 "Modifier Letter Small M" +7505 "Modifier Letter Small Eng" +7506 "Modifier Letter Small O" +7507 "Modifier Letter Small Open O" +7508 "Modifier Letter Small Top Half O" +7509 "Modifier Letter Small Bottom Half O" +7510 "Modifier Letter Small P" +7511 "Modifier Letter Small T" +7512 "Modifier Letter Small U" +7513 "Modifier Letter Small Sideways U" +7514 "Modifier Letter Small Turned M" +7515 "Modifier Letter Small V" +7516 "Modifier Letter Small Ain" +7517 "Modifier Letter Small Beta" +7518 "Modifier Letter Small Greek Gamma" +7519 "Modifier Letter Small Delta" +7520 "Modifier Letter Small Greek Phi" +7521 "Modifier Letter Small Chi" +7522 "Latin Subscript Small Letter I" +7523 "Latin Subscript Small Letter R" +7524 "Latin Subscript Small Letter U" +7525 "Latin Subscript Small Letter V" +7526 "Greek Subscript Small Letter Beta" +7527 "Greek Subscript Small Letter Gamma" +7528 "Greek Subscript Small Letter Rho" +7529 "Greek Subscript Small Letter Phi" +7530 "Greek Subscript Small Letter Chi" +7531 "Latin Small Letter Ue" +7532 "Latin Small Letter B With Middle Tilde" +7533 "Latin Small Letter D With Middle Tilde" +7534 "Latin Small Letter F With Middle Tilde" +7535 "Latin Small Letter M With Middle Tilde" +7536 "Latin Small Letter N With Middle Tilde" +7537 "Latin Small Letter P With Middle Tilde" +7538 "Latin Small Letter R With Middle Tilde" +7539 "Latin Small Letter R With Fishhook And Middle Tilde" +7540 "Latin Small Letter S With Middle Tilde" +7541 "Latin Small Letter T With Middle Tilde" +7542 "Latin Small Letter Z With Middle Tilde" +7543 "Latin Small Letter Turned G" +7544 "Modifier Letter Cyrillic En" +7545 "Latin Small Letter Insular G" +7546 "Latin Small Letter Th With Strikethrough" +7547 "Latin Small Capital Letter I With Stroke" +7548 "Latin Small Letter Iota With Stroke" +7549 "Latin Small Letter P With Stroke" +7550 "Latin Small Capital Letter U With Stroke" +7551 "Latin Small Letter Upsilon With Stroke" +7552 "Latin Small Letter B With Palatal Hook" +7553 "Latin Small Letter D With Palatal Hook" +7554 "Latin Small Letter F With Palatal Hook" +7555 "Latin Small Letter G With Palatal Hook" +7556 "Latin Small Letter K With Palatal Hook" +7557 "Latin Small Letter L With Palatal Hook" +7558 "Latin Small Letter M With Palatal Hook" +7559 "Latin Small Letter N With Palatal Hook" +7560 "Latin Small Letter P With Palatal Hook" +7561 "Latin Small Letter R With Palatal Hook" +7562 "Latin Small Letter S With Palatal Hook" +7563 "Latin Small Letter Esh With Palatal Hook" +7564 "Latin Small Letter V With Palatal Hook" +7565 "Latin Small Letter X With Palatal Hook" +7566 "Latin Small Letter Z With Palatal Hook" +7567 "Latin Small Letter A With Retroflex Hook" +7568 "Latin Small Letter Alpha With Retroflex Hook" +7569 "Latin Small Letter D With Hook And Tail" +7570 "Latin Small Letter E With Retroflex Hook" +7571 "Latin Small Letter Open E With Retroflex Hook" +7572 "Latin Small Letter Reversed Open E With Retroflex Hook" +7573 "Latin Small Letter Schwa With Retroflex Hook" +7574 "Latin Small Letter I With Retroflex Hook" +7575 "Latin Small Letter Open O With Retroflex Hook" +7576 "Latin Small Letter Esh With Retroflex Hook" +7577 "Latin Small Letter U With Retroflex Hook" +7578 "Latin Small Letter Ezh With Retroflex Hook" +7579 "Modifier Letter Small Turned Alpha" +7580 "Modifier Letter Small C" +7581 "Modifier Letter Small C With Curl" +7582 "Modifier Letter Small Eth" +7583 "Modifier Letter Small Reversed Open E" +7584 "Modifier Letter Small F" +7585 "Modifier Letter Small Dotless J With Stroke" +7586 "Modifier Letter Small Script G" +7587 "Modifier Letter Small Turned H" +7588 "Modifier Letter Small I With Stroke" +7589 "Modifier Letter Small Iota" +7590 "Modifier Letter Small Capital I" +7591 "Modifier Letter Small Capital I With Stroke" +7592 "Modifier Letter Small J With Crossed-Tail" +7593 "Modifier Letter Small L With Retroflex Hook" +7594 "Modifier Letter Small L With Palatal Hook" +7595 "Modifier Letter Small Capital L" +7596 "Modifier Letter Small M With Hook" +7597 "Modifier Letter Small Turned M With Long Leg" +7598 "Modifier Letter Small N With Left Hook" +7599 "Modifier Letter Small N With Retroflex Hook" +7600 "Modifier Letter Small Capital N" +7601 "Modifier Letter Small Barred O" +7602 "Modifier Letter Small Phi" +7603 "Modifier Letter Small S With Hook" +7604 "Modifier Letter Small Esh" +7605 "Modifier Letter Small T With Palatal Hook" +7606 "Modifier Letter Small U Bar" +7607 "Modifier Letter Small Upsilon" +7608 "Modifier Letter Small Capital U" +7609 "Modifier Letter Small V With Hook" +7610 "Modifier Letter Small Turned V" +7611 "Modifier Letter Small Z" +7612 "Modifier Letter Small Z With Retroflex Hook" +7613 "Modifier Letter Small Z With Curl" +7614 "Modifier Letter Small Ezh" +7615 "Modifier Letter Small Theta" +7616 "Combining Dotted Grave Accent" +7617 "Combining Dotted Acute Accent" +7618 "Combining Snake Below" +7619 "Combining Suspension Mark" +7620 "Combining Macron-Acute" +7621 "Combining Grave-Macron" +7622 "Combining Macron-Grave" +7623 "Combining Acute-Macron" +7624 "Combining Grave-Acute-Grave" +7625 "Combining Acute-Grave-Acute" +7626 "Combining Latin Small Letter R Below" +7627 "Combining Breve-Macron" +7628 "Combining Macron-Breve" +7629 "Combining Double Circumflex Above" +7630 "Combining Ogonek Above" +7631 "Combining Zigzag Below" +7632 "Combining Is Below" +7633 "Combining Ur Above" +7634 "Combining Us Above" +7635 "Combining Latin Small Letter Flattened Open A Above" +7636 "Combining Latin Small Letter Ae" +7637 "Combining Latin Small Letter Ao" +7638 "Combining Latin Small Letter Av" +7639 "Combining Latin Small Letter C Cedilla" +7640 "Combining Latin Small Letter Insular D" +7641 "Combining Latin Small Letter Eth" +7642 "Combining Latin Small Letter G" +7643 "Combining Latin Letter Small Capital G" +7644 "Combining Latin Small Letter K" +7645 "Combining Latin Small Letter L" +7646 "Combining Latin Letter Small Capital L" +7647 "Combining Latin Letter Small Capital M" +7648 "Combining Latin Small Letter N" +7649 "Combining Latin Letter Small Capital N" +7650 "Combining Latin Letter Small Capital R" +7651 "Combining Latin Small Letter R Rotunda" +7652 "Combining Latin Small Letter S" +7653 "Combining Latin Small Letter Long S" +7654 "Combining Latin Small Letter Z" +7676 "Combining Double Inverted Breve Below" +7677 "Combining Almost Equal To Below" +7678 "Combining Left Arrowhead Above" +7679 "Combining Right Arrowhead And Down Arrowhead Below" +7680 "Latin Capital Letter A With Ring Below" +7681 "Latin Small Letter A With Ring Below" +7682 "Latin Capital Letter B With Dot Above" +7683 "Latin Small Letter B With Dot Above" +7684 "Latin Capital Letter B With Dot Below" +7685 "Latin Small Letter B With Dot Below" +7686 "Latin Capital Letter B With Line Below" +7687 "Latin Small Letter B With Line Below" +7688 "Latin Capital Letter C With Cedilla And Acute" +7689 "Latin Small Letter C With Cedilla And Acute" +7690 "Latin Capital Letter D With Dot Above" +7691 "Latin Small Letter D With Dot Above" +7692 "Latin Capital Letter D With Dot Below" +7693 "Latin Small Letter D With Dot Below" +7694 "Latin Capital Letter D With Line Below" +7695 "Latin Small Letter D With Line Below" +7696 "Latin Capital Letter D With Cedilla" +7697 "Latin Small Letter D With Cedilla" +7698 "Latin Capital Letter D With Circumflex Below" +7699 "Latin Small Letter D With Circumflex Below" +7700 "Latin Capital Letter E With Macron And Grave" +7701 "Latin Small Letter E With Macron And Grave" +7702 "Latin Capital Letter E With Macron And Acute" +7703 "Latin Small Letter E With Macron And Acute" +7704 "Latin Capital Letter E With Circumflex Below" +7705 "Latin Small Letter E With Circumflex Below" +7706 "Latin Capital Letter E With Tilde Below" +7707 "Latin Small Letter E With Tilde Below" +7708 "Latin Capital Letter E With Cedilla And Breve" +7709 "Latin Small Letter E With Cedilla And Breve" +7710 "Latin Capital Letter F With Dot Above" +7711 "Latin Small Letter F With Dot Above" +7712 "Latin Capital Letter G With Macron" +7713 "Latin Small Letter G With Macron" +7714 "Latin Capital Letter H With Dot Above" +7715 "Latin Small Letter H With Dot Above" +7716 "Latin Capital Letter H With Dot Below" +7717 "Latin Small Letter H With Dot Below" +7718 "Latin Capital Letter H With Diaeresis" +7719 "Latin Small Letter H With Diaeresis" +7720 "Latin Capital Letter H With Cedilla" +7721 "Latin Small Letter H With Cedilla" +7722 "Latin Capital Letter H With Breve Below" +7723 "Latin Small Letter H With Breve Below" +7724 "Latin Capital Letter I With Tilde Below" +7725 "Latin Small Letter I With Tilde Below" +7726 "Latin Capital Letter I With Diaeresis And Acute" +7727 "Latin Small Letter I With Diaeresis And Acute" +7728 "Latin Capital Letter K With Acute" +7729 "Latin Small Letter K With Acute" +7730 "Latin Capital Letter K With Dot Below" +7731 "Latin Small Letter K With Dot Below" +7732 "Latin Capital Letter K With Line Below" +7733 "Latin Small Letter K With Line Below" +7734 "Latin Capital Letter L With Dot Below" +7735 "Latin Small Letter L With Dot Below" +7736 "Latin Capital Letter L With Dot Below And Macron" +7737 "Latin Small Letter L With Dot Below And Macron" +7738 "Latin Capital Letter L With Line Below" +7739 "Latin Small Letter L With Line Below" +7740 "Latin Capital Letter L With Circumflex Below" +7741 "Latin Small Letter L With Circumflex Below" +7742 "Latin Capital Letter M With Acute" +7743 "Latin Small Letter M With Acute" +7744 "Latin Capital Letter M With Dot Above" +7745 "Latin Small Letter M With Dot Above" +7746 "Latin Capital Letter M With Dot Below" +7747 "Latin Small Letter M With Dot Below" +7748 "Latin Capital Letter N With Dot Above" +7749 "Latin Small Letter N With Dot Above" +7750 "Latin Capital Letter N With Dot Below" +7751 "Latin Small Letter N With Dot Below" +7752 "Latin Capital Letter N With Line Below" +7753 "Latin Small Letter N With Line Below" +7754 "Latin Capital Letter N With Circumflex Below" +7755 "Latin Small Letter N With Circumflex Below" +7756 "Latin Capital Letter O With Tilde And Acute" +7757 "Latin Small Letter O With Tilde And Acute" +7758 "Latin Capital Letter O With Tilde And Diaeresis" +7759 "Latin Small Letter O With Tilde And Diaeresis" +7760 "Latin Capital Letter O With Macron And Grave" +7761 "Latin Small Letter O With Macron And Grave" +7762 "Latin Capital Letter O With Macron And Acute" +7763 "Latin Small Letter O With Macron And Acute" +7764 "Latin Capital Letter P With Acute" +7765 "Latin Small Letter P With Acute" +7766 "Latin Capital Letter P With Dot Above" +7767 "Latin Small Letter P With Dot Above" +7768 "Latin Capital Letter R With Dot Above" +7769 "Latin Small Letter R With Dot Above" +7770 "Latin Capital Letter R With Dot Below" +7771 "Latin Small Letter R With Dot Below" +7772 "Latin Capital Letter R With Dot Below And Macron" +7773 "Latin Small Letter R With Dot Below And Macron" +7774 "Latin Capital Letter R With Line Below" +7775 "Latin Small Letter R With Line Below" +7776 "Latin Capital Letter S With Dot Above" +7777 "Latin Small Letter S With Dot Above" +7778 "Latin Capital Letter S With Dot Below" +7779 "Latin Small Letter S With Dot Below" +7780 "Latin Capital Letter S With Acute And Dot Above" +7781 "Latin Small Letter S With Acute And Dot Above" +7782 "Latin Capital Letter S With Caron And Dot Above" +7783 "Latin Small Letter S With Caron And Dot Above" +7784 "Latin Capital Letter S With Dot Below And Dot Above" +7785 "Latin Small Letter S With Dot Below And Dot Above" +7786 "Latin Capital Letter T With Dot Above" +7787 "Latin Small Letter T With Dot Above" +7788 "Latin Capital Letter T With Dot Below" +7789 "Latin Small Letter T With Dot Below" +7790 "Latin Capital Letter T With Line Below" +7791 "Latin Small Letter T With Line Below" +7792 "Latin Capital Letter T With Circumflex Below" +7793 "Latin Small Letter T With Circumflex Below" +7794 "Latin Capital Letter U With Diaeresis Below" +7795 "Latin Small Letter U With Diaeresis Below" +7796 "Latin Capital Letter U With Tilde Below" +7797 "Latin Small Letter U With Tilde Below" +7798 "Latin Capital Letter U With Circumflex Below" +7799 "Latin Small Letter U With Circumflex Below" +7800 "Latin Capital Letter U With Tilde And Acute" +7801 "Latin Small Letter U With Tilde And Acute" +7802 "Latin Capital Letter U With Macron And Diaeresis" +7803 "Latin Small Letter U With Macron And Diaeresis" +7804 "Latin Capital Letter V With Tilde" +7805 "Latin Small Letter V With Tilde" +7806 "Latin Capital Letter V With Dot Below" +7807 "Latin Small Letter V With Dot Below" +7808 "Latin Capital Letter W With Grave" +7809 "Latin Small Letter W With Grave" +7810 "Latin Capital Letter W With Acute" +7811 "Latin Small Letter W With Acute" +7812 "Latin Capital Letter W With Diaeresis" +7813 "Latin Small Letter W With Diaeresis" +7814 "Latin Capital Letter W With Dot Above" +7815 "Latin Small Letter W With Dot Above" +7816 "Latin Capital Letter W With Dot Below" +7817 "Latin Small Letter W With Dot Below" +7818 "Latin Capital Letter X With Dot Above" +7819 "Latin Small Letter X With Dot Above" +7820 "Latin Capital Letter X With Diaeresis" +7821 "Latin Small Letter X With Diaeresis" +7822 "Latin Capital Letter Y With Dot Above" +7823 "Latin Small Letter Y With Dot Above" +7824 "Latin Capital Letter Z With Circumflex" +7825 "Latin Small Letter Z With Circumflex" +7826 "Latin Capital Letter Z With Dot Below" +7827 "Latin Small Letter Z With Dot Below" +7828 "Latin Capital Letter Z With Line Below" +7829 "Latin Small Letter Z With Line Below" +7830 "Latin Small Letter H With Line Below" +7831 "Latin Small Letter T With Diaeresis" +7832 "Latin Small Letter W With Ring Above" +7833 "Latin Small Letter Y With Ring Above" +7834 "Latin Small Letter A With Right Half Ring" +7835 "Latin Small Letter Long S With Dot Above" +7836 "Latin Small Letter Long S With Diagonal Stroke" +7837 "Latin Small Letter Long S With High Stroke" +7838 "Latin Capital Letter Sharp S" +7839 "Latin Small Letter Delta" +7840 "Latin Capital Letter A With Dot Below" +7841 "Latin Small Letter A With Dot Below" +7842 "Latin Capital Letter A With Hook Above" +7843 "Latin Small Letter A With Hook Above" +7844 "Latin Capital Letter A With Circumflex And Acute" +7845 "Latin Small Letter A With Circumflex And Acute" +7846 "Latin Capital Letter A With Circumflex And Grave" +7847 "Latin Small Letter A With Circumflex And Grave" +7848 "Latin Capital Letter A With Circumflex And Hook Above" +7849 "Latin Small Letter A With Circumflex And Hook Above" +7850 "Latin Capital Letter A With Circumflex And Tilde" +7851 "Latin Small Letter A With Circumflex And Tilde" +7852 "Latin Capital Letter A With Circumflex And Dot Below" +7853 "Latin Small Letter A With Circumflex And Dot Below" +7854 "Latin Capital Letter A With Breve And Acute" +7855 "Latin Small Letter A With Breve And Acute" +7856 "Latin Capital Letter A With Breve And Grave" +7857 "Latin Small Letter A With Breve And Grave" +7858 "Latin Capital Letter A With Breve And Hook Above" +7859 "Latin Small Letter A With Breve And Hook Above" +7860 "Latin Capital Letter A With Breve And Tilde" +7861 "Latin Small Letter A With Breve And Tilde" +7862 "Latin Capital Letter A With Breve And Dot Below" +7863 "Latin Small Letter A With Breve And Dot Below" +7864 "Latin Capital Letter E With Dot Below" +7865 "Latin Small Letter E With Dot Below" +7866 "Latin Capital Letter E With Hook Above" +7867 "Latin Small Letter E With Hook Above" +7868 "Latin Capital Letter E With Tilde" +7869 "Latin Small Letter E With Tilde" +7870 "Latin Capital Letter E With Circumflex And Acute" +7871 "Latin Small Letter E With Circumflex And Acute" +7872 "Latin Capital Letter E With Circumflex And Grave" +7873 "Latin Small Letter E With Circumflex And Grave" +7874 "Latin Capital Letter E With Circumflex And Hook Above" +7875 "Latin Small Letter E With Circumflex And Hook Above" +7876 "Latin Capital Letter E With Circumflex And Tilde" +7877 "Latin Small Letter E With Circumflex And Tilde" +7878 "Latin Capital Letter E With Circumflex And Dot Below" +7879 "Latin Small Letter E With Circumflex And Dot Below" +7880 "Latin Capital Letter I With Hook Above" +7881 "Latin Small Letter I With Hook Above" +7882 "Latin Capital Letter I With Dot Below" +7883 "Latin Small Letter I With Dot Below" +7884 "Latin Capital Letter O With Dot Below" +7885 "Latin Small Letter O With Dot Below" +7886 "Latin Capital Letter O With Hook Above" +7887 "Latin Small Letter O With Hook Above" +7888 "Latin Capital Letter O With Circumflex And Acute" +7889 "Latin Small Letter O With Circumflex And Acute" +7890 "Latin Capital Letter O With Circumflex And Grave" +7891 "Latin Small Letter O With Circumflex And Grave" +7892 "Latin Capital Letter O With Circumflex And Hook Above" +7893 "Latin Small Letter O With Circumflex And Hook Above" +7894 "Latin Capital Letter O With Circumflex And Tilde" +7895 "Latin Small Letter O With Circumflex And Tilde" +7896 "Latin Capital Letter O With Circumflex And Dot Below" +7897 "Latin Small Letter O With Circumflex And Dot Below" +7898 "Latin Capital Letter O With Horn And Acute" +7899 "Latin Small Letter O With Horn And Acute" +7900 "Latin Capital Letter O With Horn And Grave" +7901 "Latin Small Letter O With Horn And Grave" +7902 "Latin Capital Letter O With Horn And Hook Above" +7903 "Latin Small Letter O With Horn And Hook Above" +7904 "Latin Capital Letter O With Horn And Tilde" +7905 "Latin Small Letter O With Horn And Tilde" +7906 "Latin Capital Letter O With Horn And Dot Below" +7907 "Latin Small Letter O With Horn And Dot Below" +7908 "Latin Capital Letter U With Dot Below" +7909 "Latin Small Letter U With Dot Below" +7910 "Latin Capital Letter U With Hook Above" +7911 "Latin Small Letter U With Hook Above" +7912 "Latin Capital Letter U With Horn And Acute" +7913 "Latin Small Letter U With Horn And Acute" +7914 "Latin Capital Letter U With Horn And Grave" +7915 "Latin Small Letter U With Horn And Grave" +7916 "Latin Capital Letter U With Horn And Hook Above" +7917 "Latin Small Letter U With Horn And Hook Above" +7918 "Latin Capital Letter U With Horn And Tilde" +7919 "Latin Small Letter U With Horn And Tilde" +7920 "Latin Capital Letter U With Horn And Dot Below" +7921 "Latin Small Letter U With Horn And Dot Below" +7922 "Latin Capital Letter Y With Grave" +7923 "Latin Small Letter Y With Grave" +7924 "Latin Capital Letter Y With Dot Below" +7925 "Latin Small Letter Y With Dot Below" +7926 "Latin Capital Letter Y With Hook Above" +7927 "Latin Small Letter Y With Hook Above" +7928 "Latin Capital Letter Y With Tilde" +7929 "Latin Small Letter Y With Tilde" +7930 "Latin Capital Letter Middle-Welsh Ll" +7931 "Latin Small Letter Middle-Welsh Ll" +7932 "Latin Capital Letter Middle-Welsh V" +7933 "Latin Small Letter Middle-Welsh V" +7934 "Latin Capital Letter Y With Loop" +7935 "Latin Small Letter Y With Loop" +7936 "Greek Small Letter Alpha With Psili" +7937 "Greek Small Letter Alpha With Dasia" +7938 "Greek Small Letter Alpha With Psili And Varia" +7939 "Greek Small Letter Alpha With Dasia And Varia" +7940 "Greek Small Letter Alpha With Psili And Oxia" +7941 "Greek Small Letter Alpha With Dasia And Oxia" +7942 "Greek Small Letter Alpha With Psili And Perispomeni" +7943 "Greek Small Letter Alpha With Dasia And Perispomeni" +7944 "Greek Capital Letter Alpha With Psili" +7945 "Greek Capital Letter Alpha With Dasia" +7946 "Greek Capital Letter Alpha With Psili And Varia" +7947 "Greek Capital Letter Alpha With Dasia And Varia" +7948 "Greek Capital Letter Alpha With Psili And Oxia" +7949 "Greek Capital Letter Alpha With Dasia And Oxia" +7950 "Greek Capital Letter Alpha With Psili And Perispomeni" +7951 "Greek Capital Letter Alpha With Dasia And Perispomeni" +7952 "Greek Small Letter Epsilon With Psili" +7953 "Greek Small Letter Epsilon With Dasia" +7954 "Greek Small Letter Epsilon With Psili And Varia" +7955 "Greek Small Letter Epsilon With Dasia And Varia" +7956 "Greek Small Letter Epsilon With Psili And Oxia" +7957 "Greek Small Letter Epsilon With Dasia And Oxia" +7960 "Greek Capital Letter Epsilon With Psili" +7961 "Greek Capital Letter Epsilon With Dasia" +7962 "Greek Capital Letter Epsilon With Psili And Varia" +7963 "Greek Capital Letter Epsilon With Dasia And Varia" +7964 "Greek Capital Letter Epsilon With Psili And Oxia" +7965 "Greek Capital Letter Epsilon With Dasia And Oxia" +7968 "Greek Small Letter Eta With Psili" +7969 "Greek Small Letter Eta With Dasia" +7970 "Greek Small Letter Eta With Psili And Varia" +7971 "Greek Small Letter Eta With Dasia And Varia" +7972 "Greek Small Letter Eta With Psili And Oxia" +7973 "Greek Small Letter Eta With Dasia And Oxia" +7974 "Greek Small Letter Eta With Psili And Perispomeni" +7975 "Greek Small Letter Eta With Dasia And Perispomeni" +7976 "Greek Capital Letter Eta With Psili" +7977 "Greek Capital Letter Eta With Dasia" +7978 "Greek Capital Letter Eta With Psili And Varia" +7979 "Greek Capital Letter Eta With Dasia And Varia" +7980 "Greek Capital Letter Eta With Psili And Oxia" +7981 "Greek Capital Letter Eta With Dasia And Oxia" +7982 "Greek Capital Letter Eta With Psili And Perispomeni" +7983 "Greek Capital Letter Eta With Dasia And Perispomeni" +7984 "Greek Small Letter Iota With Psili" +7985 "Greek Small Letter Iota With Dasia" +7986 "Greek Small Letter Iota With Psili And Varia" +7987 "Greek Small Letter Iota With Dasia And Varia" +7988 "Greek Small Letter Iota With Psili And Oxia" +7989 "Greek Small Letter Iota With Dasia And Oxia" +7990 "Greek Small Letter Iota With Psili And Perispomeni" +7991 "Greek Small Letter Iota With Dasia And Perispomeni" +7992 "Greek Capital Letter Iota With Psili" +7993 "Greek Capital Letter Iota With Dasia" +7994 "Greek Capital Letter Iota With Psili And Varia" +7995 "Greek Capital Letter Iota With Dasia And Varia" +7996 "Greek Capital Letter Iota With Psili And Oxia" +7997 "Greek Capital Letter Iota With Dasia And Oxia" +7998 "Greek Capital Letter Iota With Psili And Perispomeni" +7999 "Greek Capital Letter Iota With Dasia And Perispomeni" +8000 "Greek Small Letter Omicron With Psili" +8001 "Greek Small Letter Omicron With Dasia" +8002 "Greek Small Letter Omicron With Psili And Varia" +8003 "Greek Small Letter Omicron With Dasia And Varia" +8004 "Greek Small Letter Omicron With Psili And Oxia" +8005 "Greek Small Letter Omicron With Dasia And Oxia" +8008 "Greek Capital Letter Omicron With Psili" +8009 "Greek Capital Letter Omicron With Dasia" +8010 "Greek Capital Letter Omicron With Psili And Varia" +8011 "Greek Capital Letter Omicron With Dasia And Varia" +8012 "Greek Capital Letter Omicron With Psili And Oxia" +8013 "Greek Capital Letter Omicron With Dasia And Oxia" +8016 "Greek Small Letter Upsilon With Psili" +8017 "Greek Small Letter Upsilon With Dasia" +8018 "Greek Small Letter Upsilon With Psili And Varia" +8019 "Greek Small Letter Upsilon With Dasia And Varia" +8020 "Greek Small Letter Upsilon With Psili And Oxia" +8021 "Greek Small Letter Upsilon With Dasia And Oxia" +8022 "Greek Small Letter Upsilon With Psili And Perispomeni" +8023 "Greek Small Letter Upsilon With Dasia And Perispomeni" +8025 "Greek Capital Letter Upsilon With Dasia" +8027 "Greek Capital Letter Upsilon With Dasia And Varia" +8029 "Greek Capital Letter Upsilon With Dasia And Oxia" +8031 "Greek Capital Letter Upsilon With Dasia And Perispomeni" +8032 "Greek Small Letter Omega With Psili" +8033 "Greek Small Letter Omega With Dasia" +8034 "Greek Small Letter Omega With Psili And Varia" +8035 "Greek Small Letter Omega With Dasia And Varia" +8036 "Greek Small Letter Omega With Psili And Oxia" +8037 "Greek Small Letter Omega With Dasia And Oxia" +8038 "Greek Small Letter Omega With Psili And Perispomeni" +8039 "Greek Small Letter Omega With Dasia And Perispomeni" +8040 "Greek Capital Letter Omega With Psili" +8041 "Greek Capital Letter Omega With Dasia" +8042 "Greek Capital Letter Omega With Psili And Varia" +8043 "Greek Capital Letter Omega With Dasia And Varia" +8044 "Greek Capital Letter Omega With Psili And Oxia" +8045 "Greek Capital Letter Omega With Dasia And Oxia" +8046 "Greek Capital Letter Omega With Psili And Perispomeni" +8047 "Greek Capital Letter Omega With Dasia And Perispomeni" +8048 "Greek Small Letter Alpha With Varia" +8049 "Greek Small Letter Alpha With Oxia" +8050 "Greek Small Letter Epsilon With Varia" +8051 "Greek Small Letter Epsilon With Oxia" +8052 "Greek Small Letter Eta With Varia" +8053 "Greek Small Letter Eta With Oxia" +8054 "Greek Small Letter Iota With Varia" +8055 "Greek Small Letter Iota With Oxia" +8056 "Greek Small Letter Omicron With Varia" +8057 "Greek Small Letter Omicron With Oxia" +8058 "Greek Small Letter Upsilon With Varia" +8059 "Greek Small Letter Upsilon With Oxia" +8060 "Greek Small Letter Omega With Varia" +8061 "Greek Small Letter Omega With Oxia" +8064 "Greek Small Letter Alpha With Psili And Ypogegrammeni" +8065 "Greek Small Letter Alpha With Dasia And Ypogegrammeni" +8066 "Greek Small Letter Alpha With Psili And Varia And Ypogegrammeni" +8067 "Greek Small Letter Alpha With Dasia And Varia And Ypogegrammeni" +8068 "Greek Small Letter Alpha With Psili And Oxia And Ypogegrammeni" +8069 "Greek Small Letter Alpha With Dasia And Oxia And Ypogegrammeni" +8070 "Greek Small Letter Alpha With Psili And Perispomeni And Ypogegrammeni" +8071 "Greek Small Letter Alpha With Dasia And Perispomeni And Ypogegrammeni" +8072 "Greek Capital Letter Alpha With Psili And Prosgegrammeni" +8073 "Greek Capital Letter Alpha With Dasia And Prosgegrammeni" +8074 "Greek Capital Letter Alpha With Psili And Varia And Prosgegrammeni" +8075 "Greek Capital Letter Alpha With Dasia And Varia And Prosgegrammeni" +8076 "Greek Capital Letter Alpha With Psili And Oxia And Prosgegrammeni" +8077 "Greek Capital Letter Alpha With Dasia And Oxia And Prosgegrammeni" +8078 "Greek Capital Letter Alpha With Psili And Perispomeni And Prosgegrammeni" +8079 "Greek Capital Letter Alpha With Dasia And Perispomeni And Prosgegrammeni" +8080 "Greek Small Letter Eta With Psili And Ypogegrammeni" +8081 "Greek Small Letter Eta With Dasia And Ypogegrammeni" +8082 "Greek Small Letter Eta With Psili And Varia And Ypogegrammeni" +8083 "Greek Small Letter Eta With Dasia And Varia And Ypogegrammeni" +8084 "Greek Small Letter Eta With Psili And Oxia And Ypogegrammeni" +8085 "Greek Small Letter Eta With Dasia And Oxia And Ypogegrammeni" +8086 "Greek Small Letter Eta With Psili And Perispomeni And Ypogegrammeni" +8087 "Greek Small Letter Eta With Dasia And Perispomeni And Ypogegrammeni" +8088 "Greek Capital Letter Eta With Psili And Prosgegrammeni" +8089 "Greek Capital Letter Eta With Dasia And Prosgegrammeni" +8090 "Greek Capital Letter Eta With Psili And Varia And Prosgegrammeni" +8091 "Greek Capital Letter Eta With Dasia And Varia And Prosgegrammeni" +8092 "Greek Capital Letter Eta With Psili And Oxia And Prosgegrammeni" +8093 "Greek Capital Letter Eta With Dasia And Oxia And Prosgegrammeni" +8094 "Greek Capital Letter Eta With Psili And Perispomeni And Prosgegrammeni" +8095 "Greek Capital Letter Eta With Dasia And Perispomeni And Prosgegrammeni" +8096 "Greek Small Letter Omega With Psili And Ypogegrammeni" +8097 "Greek Small Letter Omega With Dasia And Ypogegrammeni" +8098 "Greek Small Letter Omega With Psili And Varia And Ypogegrammeni" +8099 "Greek Small Letter Omega With Dasia And Varia And Ypogegrammeni" +8100 "Greek Small Letter Omega With Psili And Oxia And Ypogegrammeni" +8101 "Greek Small Letter Omega With Dasia And Oxia And Ypogegrammeni" +8102 "Greek Small Letter Omega With Psili And Perispomeni And Ypogegrammeni" +8103 "Greek Small Letter Omega With Dasia And Perispomeni And Ypogegrammeni" +8104 "Greek Capital Letter Omega With Psili And Prosgegrammeni" +8105 "Greek Capital Letter Omega With Dasia And Prosgegrammeni" +8106 "Greek Capital Letter Omega With Psili And Varia And Prosgegrammeni" +8107 "Greek Capital Letter Omega With Dasia And Varia And Prosgegrammeni" +8108 "Greek Capital Letter Omega With Psili And Oxia And Prosgegrammeni" +8109 "Greek Capital Letter Omega With Dasia And Oxia And Prosgegrammeni" +8110 "Greek Capital Letter Omega With Psili And Perispomeni And Prosgegrammeni" +8111 "Greek Capital Letter Omega With Dasia And Perispomeni And Prosgegrammeni" +8112 "Greek Small Letter Alpha With Vrachy" +8113 "Greek Small Letter Alpha With Macron" +8114 "Greek Small Letter Alpha With Varia And Ypogegrammeni" +8115 "Greek Small Letter Alpha With Ypogegrammeni" +8116 "Greek Small Letter Alpha With Oxia And Ypogegrammeni" +8118 "Greek Small Letter Alpha With Perispomeni" +8119 "Greek Small Letter Alpha With Perispomeni And Ypogegrammeni" +8120 "Greek Capital Letter Alpha With Vrachy" +8121 "Greek Capital Letter Alpha With Macron" +8122 "Greek Capital Letter Alpha With Varia" +8123 "Greek Capital Letter Alpha With Oxia" +8124 "Greek Capital Letter Alpha With Prosgegrammeni" +8125 "Greek Koronis" +8126 "Greek Prosgegrammeni" +8127 "Greek Psili" +8128 "Greek Perispomeni" +8129 "Greek Dialytika And Perispomeni" +8130 "Greek Small Letter Eta With Varia And Ypogegrammeni" +8131 "Greek Small Letter Eta With Ypogegrammeni" +8132 "Greek Small Letter Eta With Oxia And Ypogegrammeni" +8134 "Greek Small Letter Eta With Perispomeni" +8135 "Greek Small Letter Eta With Perispomeni And Ypogegrammeni" +8136 "Greek Capital Letter Epsilon With Varia" +8137 "Greek Capital Letter Epsilon With Oxia" +8138 "Greek Capital Letter Eta With Varia" +8139 "Greek Capital Letter Eta With Oxia" +8140 "Greek Capital Letter Eta With Prosgegrammeni" +8141 "Greek Psili And Varia" +8142 "Greek Psili And Oxia" +8143 "Greek Psili And Perispomeni" +8144 "Greek Small Letter Iota With Vrachy" +8145 "Greek Small Letter Iota With Macron" +8146 "Greek Small Letter Iota With Dialytika And Varia" +8147 "Greek Small Letter Iota With Dialytika And Oxia" +8150 "Greek Small Letter Iota With Perispomeni" +8151 "Greek Small Letter Iota With Dialytika And Perispomeni" +8152 "Greek Capital Letter Iota With Vrachy" +8153 "Greek Capital Letter Iota With Macron" +8154 "Greek Capital Letter Iota With Varia" +8155 "Greek Capital Letter Iota With Oxia" +8157 "Greek Dasia And Varia" +8158 "Greek Dasia And Oxia" +8159 "Greek Dasia And Perispomeni" +8160 "Greek Small Letter Upsilon With Vrachy" +8161 "Greek Small Letter Upsilon With Macron" +8162 "Greek Small Letter Upsilon With Dialytika And Varia" +8163 "Greek Small Letter Upsilon With Dialytika And Oxia" +8164 "Greek Small Letter Rho With Psili" +8165 "Greek Small Letter Rho With Dasia" +8166 "Greek Small Letter Upsilon With Perispomeni" +8167 "Greek Small Letter Upsilon With Dialytika And Perispomeni" +8168 "Greek Capital Letter Upsilon With Vrachy" +8169 "Greek Capital Letter Upsilon With Macron" +8170 "Greek Capital Letter Upsilon With Varia" +8171 "Greek Capital Letter Upsilon With Oxia" +8172 "Greek Capital Letter Rho With Dasia" +8173 "Greek Dialytika And Varia" +8174 "Greek Dialytika And Oxia" +8175 "Greek Varia" +8178 "Greek Small Letter Omega With Varia And Ypogegrammeni" +8179 "Greek Small Letter Omega With Ypogegrammeni" +8180 "Greek Small Letter Omega With Oxia And Ypogegrammeni" +8182 "Greek Small Letter Omega With Perispomeni" +8183 "Greek Small Letter Omega With Perispomeni And Ypogegrammeni" +8184 "Greek Capital Letter Omicron With Varia" +8185 "Greek Capital Letter Omicron With Oxia" +8186 "Greek Capital Letter Omega With Varia" +8187 "Greek Capital Letter Omega With Oxia" +8188 "Greek Capital Letter Omega With Prosgegrammeni" +8189 "Greek Oxia" +8190 "Greek Dasia" +8192 "En Quad" +8193 "Em Quad" +8194 "En Space" +8195 "Em Space" +8196 "Three-Per-Em Space" +8197 "Four-Per-Em Space" +8198 "Six-Per-Em Space" +8199 "Figure Space" +8200 "Punctuation Space" +8201 "Thin Space" +8202 "Hair Space" +8203 "Zero Width Space" +8204 "Zero Width Non-Joiner" +8205 "Zero Width Joiner" +8206 "Left-To-Right Mark" +8207 "Right-To-Left Mark" +8208 "Hyphen" +8209 "Non-Breaking Hyphen" +8210 "Figure Dash" +8211 "En Dash" +8212 "Em Dash" +8213 "Horizontal Bar" +8214 "Double Vertical Line" +8215 "Double Low Line" +8216 "Left Single Quotation Mark" +8217 "Right Single Quotation Mark" +8218 "Single Low-9 Quotation Mark" +8219 "Single High-Reversed-9 Quotation Mark" +8220 "Left Double Quotation Mark" +8221 "Right Double Quotation Mark" +8222 "Double Low-9 Quotation Mark" +8223 "Double High-Reversed-9 Quotation Mark" +8224 "Dagger" +8225 "Double Dagger" +8226 "Bullet" +8227 "Triangular Bullet" +8228 "One Dot Leader" +8229 "Two Dot Leader" +8230 "Horizontal Ellipsis" +8231 "Hyphenation Point" +8232 "Line Separator" +8233 "Paragraph Separator" +8234 "Left-To-Right Embedding" +8235 "Right-To-Left Embedding" +8236 "Pop Directional Formatting" +8237 "Left-To-Right Override" +8238 "Right-To-Left Override" +8239 "Narrow No-Break Space" +8240 "Per Mille Sign" +8241 "Per Ten Thousand Sign" +8242 "Prime" +8243 "Double Prime" +8244 "Triple Prime" +8245 "Reversed Prime" +8246 "Reversed Double Prime" +8247 "Reversed Triple Prime" +8248 "Caret" +8249 "Single Left-Pointing Angle Quotation Mark" +8250 "Single Right-Pointing Angle Quotation Mark" +8251 "Reference Mark" +8252 "Double Exclamation Mark" +8253 "Interrobang" +8254 "Overline" +8255 "Undertie" +8256 "Character Tie" +8257 "Caret Insertion Point" +8258 "Asterism" +8259 "Hyphen Bullet" +8260 "Fraction Slash" +8261 "Left Square Bracket With Quill" +8262 "Right Square Bracket With Quill" +8263 "Double Question Mark" +8264 "Question Exclamation Mark" +8265 "Exclamation Question Mark" +8266 "Tironian Sign Et" +8267 "Reversed Pilcrow Sign" +8268 "Black Leftwards Bullet" +8269 "Black Rightwards Bullet" +8270 "Low Asterisk" +8271 "Reversed Semicolon" +8272 "Close Up" +8273 "Two Asterisks Aligned Vertically" +8274 "Commercial Minus Sign" +8275 "Swung Dash" +8276 "Inverted Undertie" +8277 "Flower Punctuation Mark" +8278 "Three Dot Punctuation" +8279 "Quadruple Prime" +8280 "Four Dot Punctuation" +8281 "Five Dot Punctuation" +8282 "Two Dot Punctuation" +8283 "Four Dot Mark" +8284 "Dotted Cross" +8285 "Tricolon" +8286 "Vertical Four Dots" +8287 "Medium Mathematical Space" +8288 "Word Joiner" +8289 "Function Application" +8290 "Invisible Times" +8291 "Invisible Separator" +8292 "Invisible Plus" +8298 "Inhibit Symmetric Swapping" +8299 "Activate Symmetric Swapping" +8300 "Inhibit Arabic Form Shaping" +8301 "Activate Arabic Form Shaping" +8302 "National Digit Shapes" +8303 "Nominal Digit Shapes" +8304 "Superscript Zero" +8305 "Superscript Latin Small Letter I" +8308 "Superscript Four" +8309 "Superscript Five" +8310 "Superscript Six" +8311 "Superscript Seven" +8312 "Superscript Eight" +8313 "Superscript Nine" +8314 "Superscript Plus Sign" +8315 "Superscript Minus" +8316 "Superscript Equals Sign" +8317 "Superscript Left Parenthesis" +8318 "Superscript Right Parenthesis" +8319 "Superscript Latin Small Letter N" +8320 "Subscript Zero" +8321 "Subscript One" +8322 "Subscript Two" +8323 "Subscript Three" +8324 "Subscript Four" +8325 "Subscript Five" +8326 "Subscript Six" +8327 "Subscript Seven" +8328 "Subscript Eight" +8329 "Subscript Nine" +8330 "Subscript Plus Sign" +8331 "Subscript Minus" +8332 "Subscript Equals Sign" +8333 "Subscript Left Parenthesis" +8334 "Subscript Right Parenthesis" +8336 "Latin Subscript Small Letter A" +8337 "Latin Subscript Small Letter E" +8338 "Latin Subscript Small Letter O" +8339 "Latin Subscript Small Letter X" +8340 "Latin Subscript Small Letter Schwa" +8341 "Latin Subscript Small Letter H" +8342 "Latin Subscript Small Letter K" +8343 "Latin Subscript Small Letter L" +8344 "Latin Subscript Small Letter M" +8345 "Latin Subscript Small Letter N" +8346 "Latin Subscript Small Letter P" +8347 "Latin Subscript Small Letter S" +8348 "Latin Subscript Small Letter T" +8352 "Euro-Currency Sign" +8353 "Colon Sign" +8354 "Cruzeiro Sign" +8355 "French Franc Sign" +8356 "Lira Sign" +8357 "Mill Sign" +8358 "Naira Sign" +8359 "Peseta Sign" +8360 "Rupee Sign" +8361 "Won Sign" +8362 "New Sheqel Sign" +8363 "Dong Sign" +8364 "Euro Sign" +8365 "Kip Sign" +8366 "Tugrik Sign" +8367 "Drachma Sign" +8368 "German Penny Sign" +8369 "Peso Sign" +8370 "Guarani Sign" +8371 "Austral Sign" +8372 "Hryvnia Sign" +8373 "Cedi Sign" +8374 "Livre Tournois Sign" +8375 "Spesmilo Sign" +8376 "Tenge Sign" +8377 "Indian Rupee Sign" +8378 "Turkish Lira Sign" +8400 "Combining Left Harpoon Above" +8401 "Combining Right Harpoon Above" +8402 "Combining Long Vertical Line Overlay" +8403 "Combining Short Vertical Line Overlay" +8404 "Combining Anticlockwise Arrow Above" +8405 "Combining Clockwise Arrow Above" +8406 "Combining Left Arrow Above" +8407 "Combining Right Arrow Above" +8408 "Combining Ring Overlay" +8409 "Combining Clockwise Ring Overlay" +8410 "Combining Anticlockwise Ring Overlay" +8411 "Combining Three Dots Above" +8412 "Combining Four Dots Above" +8413 "Combining Enclosing Circle" +8414 "Combining Enclosing Square" +8415 "Combining Enclosing Diamond" +8416 "Combining Enclosing Circle Backslash" +8417 "Combining Left Right Arrow Above" +8418 "Combining Enclosing Screen" +8419 "Combining Enclosing Keycap" +8420 "Combining Enclosing Upward Pointing Triangle" +8421 "Combining Reverse Solidus Overlay" +8422 "Combining Double Vertical Stroke Overlay" +8423 "Combining Annuity Symbol" +8424 "Combining Triple Underdot" +8425 "Combining Wide Bridge Above" +8426 "Combining Leftwards Arrow Overlay" +8427 "Combining Long Double Solidus Overlay" +8428 "Combining Rightwards Harpoon With Barb Downwards" +8429 "Combining Leftwards Harpoon With Barb Downwards" +8430 "Combining Left Arrow Below" +8431 "Combining Right Arrow Below" +8432 "Combining Asterisk Above" +8448 "Account Of" +8449 "Addressed To The Subject" +8450 "Double-Struck Capital C" +8451 "Degree Celsius" +8452 "Centre Line Symbol" +8453 "Care Of" +8454 "Cada Una" +8455 "Euler Constant" +8456 "Scruple" +8457 "Degree Fahrenheit" +8458 "Script Small G" +8459 "Script Capital H" +8460 "Black-Letter Capital H" +8461 "Double-Struck Capital H" +8462 "Planck Constant" +8463 "Planck Constant Over Two Pi" +8464 "Script Capital I" +8465 "Black-Letter Capital I" +8466 "Script Capital L" +8467 "Script Small L" +8468 "L B Bar Symbol" +8469 "Double-Struck Capital N" +8470 "Numero Sign" +8471 "Sound Recording Copyright" +8472 "Script Capital P" +8473 "Double-Struck Capital P" +8474 "Double-Struck Capital Q" +8475 "Script Capital R" +8476 "Black-Letter Capital R" +8477 "Double-Struck Capital R" +8478 "Prescription Take" +8479 "Response" +8480 "Service Mark" +8481 "Telephone Sign" +8482 "Trade Mark Sign" +8483 "Versicle" +8484 "Double-Struck Capital Z" +8485 "Ounce Sign" +8486 "Ohm Sign" +8487 "Inverted Ohm Sign" +8488 "Black-Letter Capital Z" +8489 "Turned Greek Small Letter Iota" +8490 "Kelvin Sign" +8491 "Angstrom Sign" +8492 "Script Capital B" +8493 "Black-Letter Capital C" +8494 "Estimated Symbol" +8495 "Script Small E" +8496 "Script Capital E" +8497 "Script Capital F" +8498 "Turned Capital F" +8499 "Script Capital M" +8500 "Script Small O" +8501 "Alef Symbol" +8502 "Bet Symbol" +8503 "Gimel Symbol" +8504 "Dalet Symbol" +8505 "Information Source" +8506 "Rotated Capital Q" +8507 "Facsimile Sign" +8508 "Double-Struck Small Pi" +8509 "Double-Struck Small Gamma" +8510 "Double-Struck Capital Gamma" +8511 "Double-Struck Capital Pi" +8512 "Double-Struck N-Ary Summation" +8513 "Turned Sans-Serif Capital G" +8514 "Turned Sans-Serif Capital L" +8515 "Reversed Sans-Serif Capital L" +8516 "Turned Sans-Serif Capital Y" +8517 "Double-Struck Italic Capital D" +8518 "Double-Struck Italic Small D" +8519 "Double-Struck Italic Small E" +8520 "Double-Struck Italic Small I" +8521 "Double-Struck Italic Small J" +8522 "Property Line" +8523 "Turned Ampersand" +8524 "Per Sign" +8525 "Aktieselskab" +8526 "Turned Small F" +8527 "Symbol For Samaritan Source" +8528 "Vulgar Fraction One Seventh" +8529 "Vulgar Fraction One Ninth" +8530 "Vulgar Fraction One Tenth" +8531 "Vulgar Fraction One Third" +8532 "Vulgar Fraction Two Thirds" +8533 "Vulgar Fraction One Fifth" +8534 "Vulgar Fraction Two Fifths" +8535 "Vulgar Fraction Three Fifths" +8536 "Vulgar Fraction Four Fifths" +8537 "Vulgar Fraction One Sixth" +8538 "Vulgar Fraction Five Sixths" +8539 "Vulgar Fraction One Eighth" +8540 "Vulgar Fraction Three Eighths" +8541 "Vulgar Fraction Five Eighths" +8542 "Vulgar Fraction Seven Eighths" +8543 "Fraction Numerator One" +8544 "Roman Numeral One" +8545 "Roman Numeral Two" +8546 "Roman Numeral Three" +8547 "Roman Numeral Four" +8548 "Roman Numeral Five" +8549 "Roman Numeral Six" +8550 "Roman Numeral Seven" +8551 "Roman Numeral Eight" +8552 "Roman Numeral Nine" +8553 "Roman Numeral Ten" +8554 "Roman Numeral Eleven" +8555 "Roman Numeral Twelve" +8556 "Roman Numeral Fifty" +8557 "Roman Numeral One Hundred" +8558 "Roman Numeral Five Hundred" +8559 "Roman Numeral One Thousand" +8560 "Small Roman Numeral One" +8561 "Small Roman Numeral Two" +8562 "Small Roman Numeral Three" +8563 "Small Roman Numeral Four" +8564 "Small Roman Numeral Five" +8565 "Small Roman Numeral Six" +8566 "Small Roman Numeral Seven" +8567 "Small Roman Numeral Eight" +8568 "Small Roman Numeral Nine" +8569 "Small Roman Numeral Ten" +8570 "Small Roman Numeral Eleven" +8571 "Small Roman Numeral Twelve" +8572 "Small Roman Numeral Fifty" +8573 "Small Roman Numeral One Hundred" +8574 "Small Roman Numeral Five Hundred" +8575 "Small Roman Numeral One Thousand" +8576 "Roman Numeral One Thousand C D" +8577 "Roman Numeral Five Thousand" +8578 "Roman Numeral Ten Thousand" +8579 "Roman Numeral Reversed One Hundred" +8580 "Latin Small Letter Reversed C" +8581 "Roman Numeral Six Late Form" +8582 "Roman Numeral Fifty Early Form" +8583 "Roman Numeral Fifty Thousand" +8584 "Roman Numeral One Hundred Thousand" +8585 "Vulgar Fraction Zero Thirds" +8592 "Leftwards Arrow" +8593 "Upwards Arrow" +8594 "Rightwards Arrow" +8595 "Downwards Arrow" +8596 "Left Right Arrow" +8597 "Up Down Arrow" +8598 "North West Arrow" +8599 "North East Arrow" +8600 "South East Arrow" +8601 "South West Arrow" +8602 "Leftwards Arrow With Stroke" +8603 "Rightwards Arrow With Stroke" +8604 "Leftwards Wave Arrow" +8605 "Rightwards Wave Arrow" +8606 "Leftwards Two Headed Arrow" +8607 "Upwards Two Headed Arrow" +8608 "Rightwards Two Headed Arrow" +8609 "Downwards Two Headed Arrow" +8610 "Leftwards Arrow With Tail" +8611 "Rightwards Arrow With Tail" +8612 "Leftwards Arrow From Bar" +8613 "Upwards Arrow From Bar" +8614 "Rightwards Arrow From Bar" +8615 "Downwards Arrow From Bar" +8616 "Up Down Arrow With Base" +8617 "Leftwards Arrow With Hook" +8618 "Rightwards Arrow With Hook" +8619 "Leftwards Arrow With Loop" +8620 "Rightwards Arrow With Loop" +8621 "Left Right Wave Arrow" +8622 "Left Right Arrow With Stroke" +8623 "Downwards Zigzag Arrow" +8624 "Upwards Arrow With Tip Leftwards" +8625 "Upwards Arrow With Tip Rightwards" +8626 "Downwards Arrow With Tip Leftwards" +8627 "Downwards Arrow With Tip Rightwards" +8628 "Rightwards Arrow With Corner Downwards" +8629 "Downwards Arrow With Corner Leftwards" +8630 "Anticlockwise Top Semicircle Arrow" +8631 "Clockwise Top Semicircle Arrow" +8632 "North West Arrow To Long Bar" +8633 "Leftwards Arrow To Bar Over Rightwards Arrow To Bar" +8634 "Anticlockwise Open Circle Arrow" +8635 "Clockwise Open Circle Arrow" +8636 "Leftwards Harpoon With Barb Upwards" +8637 "Leftwards Harpoon With Barb Downwards" +8638 "Upwards Harpoon With Barb Rightwards" +8639 "Upwards Harpoon With Barb Leftwards" +8640 "Rightwards Harpoon With Barb Upwards" +8641 "Rightwards Harpoon With Barb Downwards" +8642 "Downwards Harpoon With Barb Rightwards" +8643 "Downwards Harpoon With Barb Leftwards" +8644 "Rightwards Arrow Over Leftwards Arrow" +8645 "Upwards Arrow Leftwards Of Downwards Arrow" +8646 "Leftwards Arrow Over Rightwards Arrow" +8647 "Leftwards Paired Arrows" +8648 "Upwards Paired Arrows" +8649 "Rightwards Paired Arrows" +8650 "Downwards Paired Arrows" +8651 "Leftwards Harpoon Over Rightwards Harpoon" +8652 "Rightwards Harpoon Over Leftwards Harpoon" +8653 "Leftwards Double Arrow With Stroke" +8654 "Left Right Double Arrow With Stroke" +8655 "Rightwards Double Arrow With Stroke" +8656 "Leftwards Double Arrow" +8657 "Upwards Double Arrow" +8658 "Rightwards Double Arrow" +8659 "Downwards Double Arrow" +8660 "Left Right Double Arrow" +8661 "Up Down Double Arrow" +8662 "North West Double Arrow" +8663 "North East Double Arrow" +8664 "South East Double Arrow" +8665 "South West Double Arrow" +8666 "Leftwards Triple Arrow" +8667 "Rightwards Triple Arrow" +8668 "Leftwards Squiggle Arrow" +8669 "Rightwards Squiggle Arrow" +8670 "Upwards Arrow With Double Stroke" +8671 "Downwards Arrow With Double Stroke" +8672 "Leftwards Dashed Arrow" +8673 "Upwards Dashed Arrow" +8674 "Rightwards Dashed Arrow" +8675 "Downwards Dashed Arrow" +8676 "Leftwards Arrow To Bar" +8677 "Rightwards Arrow To Bar" +8678 "Leftwards White Arrow" +8679 "Upwards White Arrow" +8680 "Rightwards White Arrow" +8681 "Downwards White Arrow" +8682 "Upwards White Arrow From Bar" +8683 "Upwards White Arrow On Pedestal" +8684 "Upwards White Arrow On Pedestal With Horizontal Bar" +8685 "Upwards White Arrow On Pedestal With Vertical Bar" +8686 "Upwards White Double Arrow" +8687 "Upwards White Double Arrow On Pedestal" +8688 "Rightwards White Arrow From Wall" +8689 "North West Arrow To Corner" +8690 "South East Arrow To Corner" +8691 "Up Down White Arrow" +8692 "Right Arrow With Small Circle" +8693 "Downwards Arrow Leftwards Of Upwards Arrow" +8694 "Three Rightwards Arrows" +8695 "Leftwards Arrow With Vertical Stroke" +8696 "Rightwards Arrow With Vertical Stroke" +8697 "Left Right Arrow With Vertical Stroke" +8698 "Leftwards Arrow With Double Vertical Stroke" +8699 "Rightwards Arrow With Double Vertical Stroke" +8700 "Left Right Arrow With Double Vertical Stroke" +8701 "Leftwards Open-Headed Arrow" +8702 "Rightwards Open-Headed Arrow" +8703 "Left Right Open-Headed Arrow" +8704 "For All" +8705 "Complement" +8706 "Partial Differential" +8707 "There Exists" +8708 "There Does Not Exist" +8709 "Empty Set" +8710 "Increment" +8711 "Nabla" +8712 "Element Of" +8713 "Not An Element Of" +8714 "Small Element Of" +8715 "Contains As Member" +8716 "Does Not Contain As Member" +8717 "Small Contains As Member" +8718 "End Of Proof" +8719 "N-Ary Product" +8720 "N-Ary Coproduct" +8721 "N-Ary Summation" +8722 "Minus Sign" +8723 "Minus-Or-Plus Sign" +8724 "Dot Plus" +8725 "Division Slash" +8726 "Set Minus" +8727 "Asterisk Operator" +8728 "Ring Operator" +8729 "Bullet Operator" +8730 "Square Root" +8731 "Cube Root" +8732 "Fourth Root" +8733 "Proportional To" +8734 "Infinity" +8735 "Right Angle" +8736 "Angle" +8737 "Measured Angle" +8738 "Spherical Angle" +8739 "Divides" +8740 "Does Not Divide" +8741 "Parallel To" +8742 "Not Parallel To" +8743 "Logical And" +8744 "Logical Or" +8745 "Intersection" +8746 "Union" +8747 "Integral" +8748 "Double Integral" +8749 "Triple Integral" +8750 "Contour Integral" +8751 "Surface Integral" +8752 "Volume Integral" +8753 "Clockwise Integral" +8754 "Clockwise Contour Integral" +8755 "Anticlockwise Contour Integral" +8756 "Therefore" +8757 "Because" +8758 "Ratio" +8759 "Proportion" +8760 "Dot Minus" +8761 "Excess" +8762 "Geometric Proportion" +8763 "Homothetic" +8764 "Tilde Operator" +8765 "Reversed Tilde" +8766 "Inverted Lazy S" +8767 "Sine Wave" +8768 "Wreath Product" +8769 "Not Tilde" +8770 "Minus Tilde" +8771 "Asymptotically Equal To" +8772 "Not Asymptotically Equal To" +8773 "Approximately Equal To" +8774 "Approximately But Not Actually Equal To" +8775 "Neither Approximately Nor Actually Equal To" +8776 "Almost Equal To" +8777 "Not Almost Equal To" +8778 "Almost Equal Or Equal To" +8779 "Triple Tilde" +8780 "All Equal To" +8781 "Equivalent To" +8782 "Geometrically Equivalent To" +8783 "Difference Between" +8784 "Approaches The Limit" +8785 "Geometrically Equal To" +8786 "Approximately Equal To Or The Image Of" +8787 "Image Of Or Approximately Equal To" +8788 "Colon Equals" +8789 "Equals Colon" +8790 "Ring In Equal To" +8791 "Ring Equal To" +8792 "Corresponds To" +8793 "Estimates" +8794 "Equiangular To" +8795 "Star Equals" +8796 "Delta Equal To" +8797 "Equal To By Definition" +8798 "Measured By" +8799 "Questioned Equal To" +8800 "Not Equal To" +8801 "Identical To" +8802 "Not Identical To" +8803 "Strictly Equivalent To" +8804 "Less-Than Or Equal To" +8805 "Greater-Than Or Equal To" +8806 "Less-Than Over Equal To" +8807 "Greater-Than Over Equal To" +8808 "Less-Than But Not Equal To" +8809 "Greater-Than But Not Equal To" +8810 "Much Less-Than" +8811 "Much Greater-Than" +8812 "Between" +8813 "Not Equivalent To" +8814 "Not Less-Than" +8815 "Not Greater-Than" +8816 "Neither Less-Than Nor Equal To" +8817 "Neither Greater-Than Nor Equal To" +8818 "Less-Than Or Equivalent To" +8819 "Greater-Than Or Equivalent To" +8820 "Neither Less-Than Nor Equivalent To" +8821 "Neither Greater-Than Nor Equivalent To" +8822 "Less-Than Or Greater-Than" +8823 "Greater-Than Or Less-Than" +8824 "Neither Less-Than Nor Greater-Than" +8825 "Neither Greater-Than Nor Less-Than" +8826 "Precedes" +8827 "Succeeds" +8828 "Precedes Or Equal To" +8829 "Succeeds Or Equal To" +8830 "Precedes Or Equivalent To" +8831 "Succeeds Or Equivalent To" +8832 "Does Not Precede" +8833 "Does Not Succeed" +8834 "Subset Of" +8835 "Superset Of" +8836 "Not A Subset Of" +8837 "Not A Superset Of" +8838 "Subset Of Or Equal To" +8839 "Superset Of Or Equal To" +8840 "Neither A Subset Of Nor Equal To" +8841 "Neither A Superset Of Nor Equal To" +8842 "Subset Of With Not Equal To" +8843 "Superset Of With Not Equal To" +8844 "Multiset" +8845 "Multiset Multiplication" +8846 "Multiset Union" +8847 "Square Image Of" +8848 "Square Original Of" +8849 "Square Image Of Or Equal To" +8850 "Square Original Of Or Equal To" +8851 "Square Cap" +8852 "Square Cup" +8853 "Circled Plus" +8854 "Circled Minus" +8855 "Circled Times" +8856 "Circled Division Slash" +8857 "Circled Dot Operator" +8858 "Circled Ring Operator" +8859 "Circled Asterisk Operator" +8860 "Circled Equals" +8861 "Circled Dash" +8862 "Squared Plus" +8863 "Squared Minus" +8864 "Squared Times" +8865 "Squared Dot Operator" +8866 "Right Tack" +8867 "Left Tack" +8868 "Down Tack" +8869 "Up Tack" +8870 "Assertion" +8871 "Models" +8872 "True" +8873 "Forces" +8874 "Triple Vertical Bar Right Turnstile" +8875 "Double Vertical Bar Double Right Turnstile" +8876 "Does Not Prove" +8877 "Not True" +8878 "Does Not Force" +8879 "Negated Double Vertical Bar Double Right Turnstile" +8880 "Precedes Under Relation" +8881 "Succeeds Under Relation" +8882 "Normal Subgroup Of" +8883 "Contains As Normal Subgroup" +8884 "Normal Subgroup Of Or Equal To" +8885 "Contains As Normal Subgroup Or Equal To" +8886 "Original Of" +8887 "Image Of" +8888 "Multimap" +8889 "Hermitian Conjugate Matrix" +8890 "Intercalate" +8891 "Xor" +8892 "Nand" +8893 "Nor" +8894 "Right Angle With Arc" +8895 "Right Triangle" +8896 "N-Ary Logical And" +8897 "N-Ary Logical Or" +8898 "N-Ary Intersection" +8899 "N-Ary Union" +8900 "Diamond Operator" +8901 "Dot Operator" +8902 "Star Operator" +8903 "Division Times" +8904 "Bowtie" +8905 "Left Normal Factor Semidirect Product" +8906 "Right Normal Factor Semidirect Product" +8907 "Left Semidirect Product" +8908 "Right Semidirect Product" +8909 "Reversed Tilde Equals" +8910 "Curly Logical Or" +8911 "Curly Logical And" +8912 "Double Subset" +8913 "Double Superset" +8914 "Double Intersection" +8915 "Double Union" +8916 "Pitchfork" +8917 "Equal And Parallel To" +8918 "Less-Than With Dot" +8919 "Greater-Than With Dot" +8920 "Very Much Less-Than" +8921 "Very Much Greater-Than" +8922 "Less-Than Equal To Or Greater-Than" +8923 "Greater-Than Equal To Or Less-Than" +8924 "Equal To Or Less-Than" +8925 "Equal To Or Greater-Than" +8926 "Equal To Or Precedes" +8927 "Equal To Or Succeeds" +8928 "Does Not Precede Or Equal" +8929 "Does Not Succeed Or Equal" +8930 "Not Square Image Of Or Equal To" +8931 "Not Square Original Of Or Equal To" +8932 "Square Image Of Or Not Equal To" +8933 "Square Original Of Or Not Equal To" +8934 "Less-Than But Not Equivalent To" +8935 "Greater-Than But Not Equivalent To" +8936 "Precedes But Not Equivalent To" +8937 "Succeeds But Not Equivalent To" +8938 "Not Normal Subgroup Of" +8939 "Does Not Contain As Normal Subgroup" +8940 "Not Normal Subgroup Of Or Equal To" +8941 "Does Not Contain As Normal Subgroup Or Equal" +8942 "Vertical Ellipsis" +8943 "Midline Horizontal Ellipsis" +8944 "Up Right Diagonal Ellipsis" +8945 "Down Right Diagonal Ellipsis" +8946 "Element Of With Long Horizontal Stroke" +8947 "Element Of With Vertical Bar At End Of Horizontal Stroke" +8948 "Small Element Of With Vertical Bar At End Of Horizontal Stroke" +8949 "Element Of With Dot Above" +8950 "Element Of With Overbar" +8951 "Small Element Of With Overbar" +8952 "Element Of With Underbar" +8953 "Element Of With Two Horizontal Strokes" +8954 "Contains With Long Horizontal Stroke" +8955 "Contains With Vertical Bar At End Of Horizontal Stroke" +8956 "Small Contains With Vertical Bar At End Of Horizontal Stroke" +8957 "Contains With Overbar" +8958 "Small Contains With Overbar" +8959 "Z Notation Bag Membership" +8960 "Diameter Sign" +8961 "Electric Arrow" +8962 "House" +8963 "Up Arrowhead" +8964 "Down Arrowhead" +8965 "Projective" +8966 "Perspective" +8967 "Wavy Line" +8968 "Left Ceiling" +8969 "Right Ceiling" +8970 "Left Floor" +8971 "Right Floor" +8972 "Bottom Right Crop" +8973 "Bottom Left Crop" +8974 "Top Right Crop" +8975 "Top Left Crop" +8976 "Reversed Not Sign" +8977 "Square Lozenge" +8978 "Arc" +8979 "Segment" +8980 "Sector" +8981 "Telephone Recorder" +8982 "Position Indicator" +8983 "Viewdata Square" +8984 "Place Of Interest Sign" +8985 "Turned Not Sign" +8986 "Watch" +8987 "Hourglass" +8988 "Top Left Corner" +8989 "Top Right Corner" +8990 "Bottom Left Corner" +8991 "Bottom Right Corner" +8992 "Top Half Integral" +8993 "Bottom Half Integral" +8994 "Frown" +8995 "Smile" +8996 "Up Arrowhead Between Two Horizontal Bars" +8997 "Option Key" +8998 "Erase To The Right" +8999 "X In A Rectangle Box" +9000 "Keyboard" +9001 "Left-Pointing Angle Bracket" +9002 "Right-Pointing Angle Bracket" +9003 "Erase To The Left" +9004 "Benzene Ring" +9005 "Cylindricity" +9006 "All Around-Profile" +9007 "Symmetry" +9008 "Total Runout" +9009 "Dimension Origin" +9010 "Conical Taper" +9011 "Slope" +9012 "Counterbore" +9013 "Countersink" +9014 "Apl Functional Symbol I-Beam" +9015 "Apl Functional Symbol Squish Quad" +9016 "Apl Functional Symbol Quad Equal" +9017 "Apl Functional Symbol Quad Divide" +9018 "Apl Functional Symbol Quad Diamond" +9019 "Apl Functional Symbol Quad Jot" +9020 "Apl Functional Symbol Quad Circle" +9021 "Apl Functional Symbol Circle Stile" +9022 "Apl Functional Symbol Circle Jot" +9023 "Apl Functional Symbol Slash Bar" +9024 "Apl Functional Symbol Backslash Bar" +9025 "Apl Functional Symbol Quad Slash" +9026 "Apl Functional Symbol Quad Backslash" +9027 "Apl Functional Symbol Quad Less-Than" +9028 "Apl Functional Symbol Quad Greater-Than" +9029 "Apl Functional Symbol Leftwards Vane" +9030 "Apl Functional Symbol Rightwards Vane" +9031 "Apl Functional Symbol Quad Leftwards Arrow" +9032 "Apl Functional Symbol Quad Rightwards Arrow" +9033 "Apl Functional Symbol Circle Backslash" +9034 "Apl Functional Symbol Down Tack Underbar" +9035 "Apl Functional Symbol Delta Stile" +9036 "Apl Functional Symbol Quad Down Caret" +9037 "Apl Functional Symbol Quad Delta" +9038 "Apl Functional Symbol Down Tack Jot" +9039 "Apl Functional Symbol Upwards Vane" +9040 "Apl Functional Symbol Quad Upwards Arrow" +9041 "Apl Functional Symbol Up Tack Overbar" +9042 "Apl Functional Symbol Del Stile" +9043 "Apl Functional Symbol Quad Up Caret" +9044 "Apl Functional Symbol Quad Del" +9045 "Apl Functional Symbol Up Tack Jot" +9046 "Apl Functional Symbol Downwards Vane" +9047 "Apl Functional Symbol Quad Downwards Arrow" +9048 "Apl Functional Symbol Quote Underbar" +9049 "Apl Functional Symbol Delta Underbar" +9050 "Apl Functional Symbol Diamond Underbar" +9051 "Apl Functional Symbol Jot Underbar" +9052 "Apl Functional Symbol Circle Underbar" +9053 "Apl Functional Symbol Up Shoe Jot" +9054 "Apl Functional Symbol Quote Quad" +9055 "Apl Functional Symbol Circle Star" +9056 "Apl Functional Symbol Quad Colon" +9057 "Apl Functional Symbol Up Tack Diaeresis" +9058 "Apl Functional Symbol Del Diaeresis" +9059 "Apl Functional Symbol Star Diaeresis" +9060 "Apl Functional Symbol Jot Diaeresis" +9061 "Apl Functional Symbol Circle Diaeresis" +9062 "Apl Functional Symbol Down Shoe Stile" +9063 "Apl Functional Symbol Left Shoe Stile" +9064 "Apl Functional Symbol Tilde Diaeresis" +9065 "Apl Functional Symbol Greater-Than Diaeresis" +9066 "Apl Functional Symbol Comma Bar" +9067 "Apl Functional Symbol Del Tilde" +9068 "Apl Functional Symbol Zilde" +9069 "Apl Functional Symbol Stile Tilde" +9070 "Apl Functional Symbol Semicolon Underbar" +9071 "Apl Functional Symbol Quad Not Equal" +9072 "Apl Functional Symbol Quad Question" +9073 "Apl Functional Symbol Down Caret Tilde" +9074 "Apl Functional Symbol Up Caret Tilde" +9075 "Apl Functional Symbol Iota" +9076 "Apl Functional Symbol Rho" +9077 "Apl Functional Symbol Omega" +9078 "Apl Functional Symbol Alpha Underbar" +9079 "Apl Functional Symbol Epsilon Underbar" +9080 "Apl Functional Symbol Iota Underbar" +9081 "Apl Functional Symbol Omega Underbar" +9082 "Apl Functional Symbol Alpha" +9083 "Not Check Mark" +9084 "Right Angle With Downwards Zigzag Arrow" +9085 "Shouldered Open Box" +9086 "Bell Symbol" +9087 "Vertical Line With Middle Dot" +9088 "Insertion Symbol" +9089 "Continuous Underline Symbol" +9090 "Discontinuous Underline Symbol" +9091 "Emphasis Symbol" +9092 "Composition Symbol" +9093 "White Square With Centre Vertical Line" +9094 "Enter Symbol" +9095 "Alternative Key Symbol" +9096 "Helm Symbol" +9097 "Circled Horizontal Bar With Notch" +9098 "Circled Triangle Down" +9099 "Broken Circle With Northwest Arrow" +9100 "Undo Symbol" +9101 "Monostable Symbol" +9102 "Hysteresis Symbol" +9103 "Open-Circuit-Output H-Type Symbol" +9104 "Open-Circuit-Output L-Type Symbol" +9105 "Passive-Pull-Down-Output Symbol" +9106 "Passive-Pull-Up-Output Symbol" +9107 "Direct Current Symbol Form Two" +9108 "Software-Function Symbol" +9109 "Apl Functional Symbol Quad" +9110 "Decimal Separator Key Symbol" +9111 "Previous Page" +9112 "Next Page" +9113 "Print Screen Symbol" +9114 "Clear Screen Symbol" +9115 "Left Parenthesis Upper Hook" +9116 "Left Parenthesis Extension" +9117 "Left Parenthesis Lower Hook" +9118 "Right Parenthesis Upper Hook" +9119 "Right Parenthesis Extension" +9120 "Right Parenthesis Lower Hook" +9121 "Left Square Bracket Upper Corner" +9122 "Left Square Bracket Extension" +9123 "Left Square Bracket Lower Corner" +9124 "Right Square Bracket Upper Corner" +9125 "Right Square Bracket Extension" +9126 "Right Square Bracket Lower Corner" +9127 "Left Curly Bracket Upper Hook" +9128 "Left Curly Bracket Middle Piece" +9129 "Left Curly Bracket Lower Hook" +9130 "Curly Bracket Extension" +9131 "Right Curly Bracket Upper Hook" +9132 "Right Curly Bracket Middle Piece" +9133 "Right Curly Bracket Lower Hook" +9134 "Integral Extension" +9135 "Horizontal Line Extension" +9136 "Upper Left Or Lower Right Curly Bracket Section" +9137 "Upper Right Or Lower Left Curly Bracket Section" +9138 "Summation Top" +9139 "Summation Bottom" +9140 "Top Square Bracket" +9141 "Bottom Square Bracket" +9142 "Bottom Square Bracket Over Top Square Bracket" +9143 "Radical Symbol Bottom" +9144 "Left Vertical Box Line" +9145 "Right Vertical Box Line" +9146 "Horizontal Scan Line-1" +9147 "Horizontal Scan Line-3" +9148 "Horizontal Scan Line-7" +9149 "Horizontal Scan Line-9" +9150 "Dentistry Symbol Light Vertical And Top Right" +9151 "Dentistry Symbol Light Vertical And Bottom Right" +9152 "Dentistry Symbol Light Vertical With Circle" +9153 "Dentistry Symbol Light Down And Horizontal With Circle" +9154 "Dentistry Symbol Light Up And Horizontal With Circle" +9155 "Dentistry Symbol Light Vertical With Triangle" +9156 "Dentistry Symbol Light Down And Horizontal With Triangle" +9157 "Dentistry Symbol Light Up And Horizontal With Triangle" +9158 "Dentistry Symbol Light Vertical And Wave" +9159 "Dentistry Symbol Light Down And Horizontal With Wave" +9160 "Dentistry Symbol Light Up And Horizontal With Wave" +9161 "Dentistry Symbol Light Down And Horizontal" +9162 "Dentistry Symbol Light Up And Horizontal" +9163 "Dentistry Symbol Light Vertical And Top Left" +9164 "Dentistry Symbol Light Vertical And Bottom Left" +9165 "Square Foot" +9166 "Return Symbol" +9167 "Eject Symbol" +9168 "Vertical Line Extension" +9169 "Metrical Breve" +9170 "Metrical Long Over Short" +9171 "Metrical Short Over Long" +9172 "Metrical Long Over Two Shorts" +9173 "Metrical Two Shorts Over Long" +9174 "Metrical Two Shorts Joined" +9175 "Metrical Triseme" +9176 "Metrical Tetraseme" +9177 "Metrical Pentaseme" +9178 "Earth Ground" +9179 "Fuse" +9180 "Top Parenthesis" +9181 "Bottom Parenthesis" +9182 "Top Curly Bracket" +9183 "Bottom Curly Bracket" +9184 "Top Tortoise Shell Bracket" +9185 "Bottom Tortoise Shell Bracket" +9186 "White Trapezium" +9187 "Benzene Ring With Circle" +9188 "Straightness" +9189 "Flatness" +9190 "Ac Current" +9191 "Electrical Intersection" +9192 "Decimal Exponent Symbol" +9193 "Black Right-Pointing Double Triangle" +9194 "Black Left-Pointing Double Triangle" +9195 "Black Up-Pointing Double Triangle" +9196 "Black Down-Pointing Double Triangle" +9197 "Black Right-Pointing Double Triangle With Vertical Bar" +9198 "Black Left-Pointing Double Triangle With Vertical Bar" +9199 "Black Right-Pointing Triangle With Double Vertical Bar" +9200 "Alarm Clock" +9201 "Stopwatch" +9202 "Timer Clock" +9203 "Hourglass With Flowing Sand" +9216 "Symbol For Null" +9217 "Symbol For Start Of Heading" +9218 "Symbol For Start Of Text" +9219 "Symbol For End Of Text" +9220 "Symbol For End Of Transmission" +9221 "Symbol For Enquiry" +9222 "Symbol For Acknowledge" +9223 "Symbol For Bell" +9224 "Symbol For Backspace" +9225 "Symbol For Horizontal Tabulation" +9226 "Symbol For Line Feed" +9227 "Symbol For Vertical Tabulation" +9228 "Symbol For Form Feed" +9229 "Symbol For Carriage Return" +9230 "Symbol For Shift Out" +9231 "Symbol For Shift In" +9232 "Symbol For Data Link Escape" +9233 "Symbol For Device Control One" +9234 "Symbol For Device Control Two" +9235 "Symbol For Device Control Three" +9236 "Symbol For Device Control Four" +9237 "Symbol For Negative Acknowledge" +9238 "Symbol For Synchronous Idle" +9239 "Symbol For End Of Transmission Block" +9240 "Symbol For Cancel" +9241 "Symbol For End Of Medium" +9242 "Symbol For Substitute" +9243 "Symbol For Escape" +9244 "Symbol For File Separator" +9245 "Symbol For Group Separator" +9246 "Symbol For Record Separator" +9247 "Symbol For Unit Separator" +9248 "Symbol For Space" +9249 "Symbol For Delete" +9250 "Blank Symbol" +9251 "Open Box" +9252 "Symbol For Newline" +9253 "Symbol For Delete Form Two" +9254 "Symbol For Substitute Form Two" +9280 "Ocr Hook" +9281 "Ocr Chair" +9282 "Ocr Fork" +9283 "Ocr Inverted Fork" +9284 "Ocr Belt Buckle" +9285 "Ocr Bow Tie" +9286 "Ocr Branch Bank Identification" +9287 "Ocr Amount Of Check" +9288 "Ocr Dash" +9289 "Ocr Customer Account Number" +9290 "Ocr Double Backslash" +9312 "Circled Digit One" +9313 "Circled Digit Two" +9314 "Circled Digit Three" +9315 "Circled Digit Four" +9316 "Circled Digit Five" +9317 "Circled Digit Six" +9318 "Circled Digit Seven" +9319 "Circled Digit Eight" +9320 "Circled Digit Nine" +9321 "Circled Number Ten" +9322 "Circled Number Eleven" +9323 "Circled Number Twelve" +9324 "Circled Number Thirteen" +9325 "Circled Number Fourteen" +9326 "Circled Number Fifteen" +9327 "Circled Number Sixteen" +9328 "Circled Number Seventeen" +9329 "Circled Number Eighteen" +9330 "Circled Number Nineteen" +9331 "Circled Number Twenty" +9332 "Parenthesized Digit One" +9333 "Parenthesized Digit Two" +9334 "Parenthesized Digit Three" +9335 "Parenthesized Digit Four" +9336 "Parenthesized Digit Five" +9337 "Parenthesized Digit Six" +9338 "Parenthesized Digit Seven" +9339 "Parenthesized Digit Eight" +9340 "Parenthesized Digit Nine" +9341 "Parenthesized Number Ten" +9342 "Parenthesized Number Eleven" +9343 "Parenthesized Number Twelve" +9344 "Parenthesized Number Thirteen" +9345 "Parenthesized Number Fourteen" +9346 "Parenthesized Number Fifteen" +9347 "Parenthesized Number Sixteen" +9348 "Parenthesized Number Seventeen" +9349 "Parenthesized Number Eighteen" +9350 "Parenthesized Number Nineteen" +9351 "Parenthesized Number Twenty" +9352 "Digit One Full Stop" +9353 "Digit Two Full Stop" +9354 "Digit Three Full Stop" +9355 "Digit Four Full Stop" +9356 "Digit Five Full Stop" +9357 "Digit Six Full Stop" +9358 "Digit Seven Full Stop" +9359 "Digit Eight Full Stop" +9360 "Digit Nine Full Stop" +9361 "Number Ten Full Stop" +9362 "Number Eleven Full Stop" +9363 "Number Twelve Full Stop" +9364 "Number Thirteen Full Stop" +9365 "Number Fourteen Full Stop" +9366 "Number Fifteen Full Stop" +9367 "Number Sixteen Full Stop" +9368 "Number Seventeen Full Stop" +9369 "Number Eighteen Full Stop" +9370 "Number Nineteen Full Stop" +9371 "Number Twenty Full Stop" +9372 "Parenthesized Latin Small Letter A" +9373 "Parenthesized Latin Small Letter B" +9374 "Parenthesized Latin Small Letter C" +9375 "Parenthesized Latin Small Letter D" +9376 "Parenthesized Latin Small Letter E" +9377 "Parenthesized Latin Small Letter F" +9378 "Parenthesized Latin Small Letter G" +9379 "Parenthesized Latin Small Letter H" +9380 "Parenthesized Latin Small Letter I" +9381 "Parenthesized Latin Small Letter J" +9382 "Parenthesized Latin Small Letter K" +9383 "Parenthesized Latin Small Letter L" +9384 "Parenthesized Latin Small Letter M" +9385 "Parenthesized Latin Small Letter N" +9386 "Parenthesized Latin Small Letter O" +9387 "Parenthesized Latin Small Letter P" +9388 "Parenthesized Latin Small Letter Q" +9389 "Parenthesized Latin Small Letter R" +9390 "Parenthesized Latin Small Letter S" +9391 "Parenthesized Latin Small Letter T" +9392 "Parenthesized Latin Small Letter U" +9393 "Parenthesized Latin Small Letter V" +9394 "Parenthesized Latin Small Letter W" +9395 "Parenthesized Latin Small Letter X" +9396 "Parenthesized Latin Small Letter Y" +9397 "Parenthesized Latin Small Letter Z" +9398 "Circled Latin Capital Letter A" +9399 "Circled Latin Capital Letter B" +9400 "Circled Latin Capital Letter C" +9401 "Circled Latin Capital Letter D" +9402 "Circled Latin Capital Letter E" +9403 "Circled Latin Capital Letter F" +9404 "Circled Latin Capital Letter G" +9405 "Circled Latin Capital Letter H" +9406 "Circled Latin Capital Letter I" +9407 "Circled Latin Capital Letter J" +9408 "Circled Latin Capital Letter K" +9409 "Circled Latin Capital Letter L" +9410 "Circled Latin Capital Letter M" +9411 "Circled Latin Capital Letter N" +9412 "Circled Latin Capital Letter O" +9413 "Circled Latin Capital Letter P" +9414 "Circled Latin Capital Letter Q" +9415 "Circled Latin Capital Letter R" +9416 "Circled Latin Capital Letter S" +9417 "Circled Latin Capital Letter T" +9418 "Circled Latin Capital Letter U" +9419 "Circled Latin Capital Letter V" +9420 "Circled Latin Capital Letter W" +9421 "Circled Latin Capital Letter X" +9422 "Circled Latin Capital Letter Y" +9423 "Circled Latin Capital Letter Z" +9424 "Circled Latin Small Letter A" +9425 "Circled Latin Small Letter B" +9426 "Circled Latin Small Letter C" +9427 "Circled Latin Small Letter D" +9428 "Circled Latin Small Letter E" +9429 "Circled Latin Small Letter F" +9430 "Circled Latin Small Letter G" +9431 "Circled Latin Small Letter H" +9432 "Circled Latin Small Letter I" +9433 "Circled Latin Small Letter J" +9434 "Circled Latin Small Letter K" +9435 "Circled Latin Small Letter L" +9436 "Circled Latin Small Letter M" +9437 "Circled Latin Small Letter N" +9438 "Circled Latin Small Letter O" +9439 "Circled Latin Small Letter P" +9440 "Circled Latin Small Letter Q" +9441 "Circled Latin Small Letter R" +9442 "Circled Latin Small Letter S" +9443 "Circled Latin Small Letter T" +9444 "Circled Latin Small Letter U" +9445 "Circled Latin Small Letter V" +9446 "Circled Latin Small Letter W" +9447 "Circled Latin Small Letter X" +9448 "Circled Latin Small Letter Y" +9449 "Circled Latin Small Letter Z" +9450 "Circled Digit Zero" +9451 "Negative Circled Number Eleven" +9452 "Negative Circled Number Twelve" +9453 "Negative Circled Number Thirteen" +9454 "Negative Circled Number Fourteen" +9455 "Negative Circled Number Fifteen" +9456 "Negative Circled Number Sixteen" +9457 "Negative Circled Number Seventeen" +9458 "Negative Circled Number Eighteen" +9459 "Negative Circled Number Nineteen" +9460 "Negative Circled Number Twenty" +9461 "Double Circled Digit One" +9462 "Double Circled Digit Two" +9463 "Double Circled Digit Three" +9464 "Double Circled Digit Four" +9465 "Double Circled Digit Five" +9466 "Double Circled Digit Six" +9467 "Double Circled Digit Seven" +9468 "Double Circled Digit Eight" +9469 "Double Circled Digit Nine" +9470 "Double Circled Number Ten" +9471 "Negative Circled Digit Zero" +9472 "Box Drawings Light Horizontal" +9473 "Box Drawings Heavy Horizontal" +9474 "Box Drawings Light Vertical" +9475 "Box Drawings Heavy Vertical" +9476 "Box Drawings Light Triple Dash Horizontal" +9477 "Box Drawings Heavy Triple Dash Horizontal" +9478 "Box Drawings Light Triple Dash Vertical" +9479 "Box Drawings Heavy Triple Dash Vertical" +9480 "Box Drawings Light Quadruple Dash Horizontal" +9481 "Box Drawings Heavy Quadruple Dash Horizontal" +9482 "Box Drawings Light Quadruple Dash Vertical" +9483 "Box Drawings Heavy Quadruple Dash Vertical" +9484 "Box Drawings Light Down And Right" +9485 "Box Drawings Down Light And Right Heavy" +9486 "Box Drawings Down Heavy And Right Light" +9487 "Box Drawings Heavy Down And Right" +9488 "Box Drawings Light Down And Left" +9489 "Box Drawings Down Light And Left Heavy" +9490 "Box Drawings Down Heavy And Left Light" +9491 "Box Drawings Heavy Down And Left" +9492 "Box Drawings Light Up And Right" +9493 "Box Drawings Up Light And Right Heavy" +9494 "Box Drawings Up Heavy And Right Light" +9495 "Box Drawings Heavy Up And Right" +9496 "Box Drawings Light Up And Left" +9497 "Box Drawings Up Light And Left Heavy" +9498 "Box Drawings Up Heavy And Left Light" +9499 "Box Drawings Heavy Up And Left" +9500 "Box Drawings Light Vertical And Right" +9501 "Box Drawings Vertical Light And Right Heavy" +9502 "Box Drawings Up Heavy And Right Down Light" +9503 "Box Drawings Down Heavy And Right Up Light" +9504 "Box Drawings Vertical Heavy And Right Light" +9505 "Box Drawings Down Light And Right Up Heavy" +9506 "Box Drawings Up Light And Right Down Heavy" +9507 "Box Drawings Heavy Vertical And Right" +9508 "Box Drawings Light Vertical And Left" +9509 "Box Drawings Vertical Light And Left Heavy" +9510 "Box Drawings Up Heavy And Left Down Light" +9511 "Box Drawings Down Heavy And Left Up Light" +9512 "Box Drawings Vertical Heavy And Left Light" +9513 "Box Drawings Down Light And Left Up Heavy" +9514 "Box Drawings Up Light And Left Down Heavy" +9515 "Box Drawings Heavy Vertical And Left" +9516 "Box Drawings Light Down And Horizontal" +9517 "Box Drawings Left Heavy And Right Down Light" +9518 "Box Drawings Right Heavy And Left Down Light" +9519 "Box Drawings Down Light And Horizontal Heavy" +9520 "Box Drawings Down Heavy And Horizontal Light" +9521 "Box Drawings Right Light And Left Down Heavy" +9522 "Box Drawings Left Light And Right Down Heavy" +9523 "Box Drawings Heavy Down And Horizontal" +9524 "Box Drawings Light Up And Horizontal" +9525 "Box Drawings Left Heavy And Right Up Light" +9526 "Box Drawings Right Heavy And Left Up Light" +9527 "Box Drawings Up Light And Horizontal Heavy" +9528 "Box Drawings Up Heavy And Horizontal Light" +9529 "Box Drawings Right Light And Left Up Heavy" +9530 "Box Drawings Left Light And Right Up Heavy" +9531 "Box Drawings Heavy Up And Horizontal" +9532 "Box Drawings Light Vertical And Horizontal" +9533 "Box Drawings Left Heavy And Right Vertical Light" +9534 "Box Drawings Right Heavy And Left Vertical Light" +9535 "Box Drawings Vertical Light And Horizontal Heavy" +9536 "Box Drawings Up Heavy And Down Horizontal Light" +9537 "Box Drawings Down Heavy And Up Horizontal Light" +9538 "Box Drawings Vertical Heavy And Horizontal Light" +9539 "Box Drawings Left Up Heavy And Right Down Light" +9540 "Box Drawings Right Up Heavy And Left Down Light" +9541 "Box Drawings Left Down Heavy And Right Up Light" +9542 "Box Drawings Right Down Heavy And Left Up Light" +9543 "Box Drawings Down Light And Up Horizontal Heavy" +9544 "Box Drawings Up Light And Down Horizontal Heavy" +9545 "Box Drawings Right Light And Left Vertical Heavy" +9546 "Box Drawings Left Light And Right Vertical Heavy" +9547 "Box Drawings Heavy Vertical And Horizontal" +9548 "Box Drawings Light Double Dash Horizontal" +9549 "Box Drawings Heavy Double Dash Horizontal" +9550 "Box Drawings Light Double Dash Vertical" +9551 "Box Drawings Heavy Double Dash Vertical" +9552 "Box Drawings Double Horizontal" +9553 "Box Drawings Double Vertical" +9554 "Box Drawings Down Single And Right Double" +9555 "Box Drawings Down Double And Right Single" +9556 "Box Drawings Double Down And Right" +9557 "Box Drawings Down Single And Left Double" +9558 "Box Drawings Down Double And Left Single" +9559 "Box Drawings Double Down And Left" +9560 "Box Drawings Up Single And Right Double" +9561 "Box Drawings Up Double And Right Single" +9562 "Box Drawings Double Up And Right" +9563 "Box Drawings Up Single And Left Double" +9564 "Box Drawings Up Double And Left Single" +9565 "Box Drawings Double Up And Left" +9566 "Box Drawings Vertical Single And Right Double" +9567 "Box Drawings Vertical Double And Right Single" +9568 "Box Drawings Double Vertical And Right" +9569 "Box Drawings Vertical Single And Left Double" +9570 "Box Drawings Vertical Double And Left Single" +9571 "Box Drawings Double Vertical And Left" +9572 "Box Drawings Down Single And Horizontal Double" +9573 "Box Drawings Down Double And Horizontal Single" +9574 "Box Drawings Double Down And Horizontal" +9575 "Box Drawings Up Single And Horizontal Double" +9576 "Box Drawings Up Double And Horizontal Single" +9577 "Box Drawings Double Up And Horizontal" +9578 "Box Drawings Vertical Single And Horizontal Double" +9579 "Box Drawings Vertical Double And Horizontal Single" +9580 "Box Drawings Double Vertical And Horizontal" +9581 "Box Drawings Light Arc Down And Right" +9582 "Box Drawings Light Arc Down And Left" +9583 "Box Drawings Light Arc Up And Left" +9584 "Box Drawings Light Arc Up And Right" +9585 "Box Drawings Light Diagonal Upper Right To Lower Left" +9586 "Box Drawings Light Diagonal Upper Left To Lower Right" +9587 "Box Drawings Light Diagonal Cross" +9588 "Box Drawings Light Left" +9589 "Box Drawings Light Up" +9590 "Box Drawings Light Right" +9591 "Box Drawings Light Down" +9592 "Box Drawings Heavy Left" +9593 "Box Drawings Heavy Up" +9594 "Box Drawings Heavy Right" +9595 "Box Drawings Heavy Down" +9596 "Box Drawings Light Left And Heavy Right" +9597 "Box Drawings Light Up And Heavy Down" +9598 "Box Drawings Heavy Left And Light Right" +9599 "Box Drawings Heavy Up And Light Down" +9600 "Upper Half Block" +9601 "Lower One Eighth Block" +9602 "Lower One Quarter Block" +9603 "Lower Three Eighths Block" +9604 "Lower Half Block" +9605 "Lower Five Eighths Block" +9606 "Lower Three Quarters Block" +9607 "Lower Seven Eighths Block" +9608 "Full Block" +9609 "Left Seven Eighths Block" +9610 "Left Three Quarters Block" +9611 "Left Five Eighths Block" +9612 "Left Half Block" +9613 "Left Three Eighths Block" +9614 "Left One Quarter Block" +9615 "Left One Eighth Block" +9616 "Right Half Block" +9617 "Light Shade" +9618 "Medium Shade" +9619 "Dark Shade" +9620 "Upper One Eighth Block" +9621 "Right One Eighth Block" +9622 "Quadrant Lower Left" +9623 "Quadrant Lower Right" +9624 "Quadrant Upper Left" +9625 "Quadrant Upper Left And Lower Left And Lower Right" +9626 "Quadrant Upper Left And Lower Right" +9627 "Quadrant Upper Left And Upper Right And Lower Left" +9628 "Quadrant Upper Left And Upper Right And Lower Right" +9629 "Quadrant Upper Right" +9630 "Quadrant Upper Right And Lower Left" +9631 "Quadrant Upper Right And Lower Left And Lower Right" +9632 "Black Square" +9633 "White Square" +9634 "White Square With Rounded Corners" +9635 "White Square Containing Black Small Square" +9636 "Square With Horizontal Fill" +9637 "Square With Vertical Fill" +9638 "Square With Orthogonal Crosshatch Fill" +9639 "Square With Upper Left To Lower Right Fill" +9640 "Square With Upper Right To Lower Left Fill" +9641 "Square With Diagonal Crosshatch Fill" +9642 "Black Small Square" +9643 "White Small Square" +9644 "Black Rectangle" +9645 "White Rectangle" +9646 "Black Vertical Rectangle" +9647 "White Vertical Rectangle" +9648 "Black Parallelogram" +9649 "White Parallelogram" +9650 "Black Up-Pointing Triangle" +9651 "White Up-Pointing Triangle" +9652 "Black Up-Pointing Small Triangle" +9653 "White Up-Pointing Small Triangle" +9654 "Black Right-Pointing Triangle" +9655 "White Right-Pointing Triangle" +9656 "Black Right-Pointing Small Triangle" +9657 "White Right-Pointing Small Triangle" +9658 "Black Right-Pointing Pointer" +9659 "White Right-Pointing Pointer" +9660 "Black Down-Pointing Triangle" +9661 "White Down-Pointing Triangle" +9662 "Black Down-Pointing Small Triangle" +9663 "White Down-Pointing Small Triangle" +9664 "Black Left-Pointing Triangle" +9665 "White Left-Pointing Triangle" +9666 "Black Left-Pointing Small Triangle" +9667 "White Left-Pointing Small Triangle" +9668 "Black Left-Pointing Pointer" +9669 "White Left-Pointing Pointer" +9670 "Black Diamond" +9671 "White Diamond" +9672 "White Diamond Containing Black Small Diamond" +9673 "Fisheye" +9674 "Lozenge" +9675 "White Circle" +9676 "Dotted Circle" +9677 "Circle With Vertical Fill" +9678 "Bullseye" +9679 "Black Circle" +9680 "Circle With Left Half Black" +9681 "Circle With Right Half Black" +9682 "Circle With Lower Half Black" +9683 "Circle With Upper Half Black" +9684 "Circle With Upper Right Quadrant Black" +9685 "Circle With All But Upper Left Quadrant Black" +9686 "Left Half Black Circle" +9687 "Right Half Black Circle" +9688 "Inverse Bullet" +9689 "Inverse White Circle" +9690 "Upper Half Inverse White Circle" +9691 "Lower Half Inverse White Circle" +9692 "Upper Left Quadrant Circular Arc" +9693 "Upper Right Quadrant Circular Arc" +9694 "Lower Right Quadrant Circular Arc" +9695 "Lower Left Quadrant Circular Arc" +9696 "Upper Half Circle" +9697 "Lower Half Circle" +9698 "Black Lower Right Triangle" +9699 "Black Lower Left Triangle" +9700 "Black Upper Left Triangle" +9701 "Black Upper Right Triangle" +9702 "White Bullet" +9703 "Square With Left Half Black" +9704 "Square With Right Half Black" +9705 "Square With Upper Left Diagonal Half Black" +9706 "Square With Lower Right Diagonal Half Black" +9707 "White Square With Vertical Bisecting Line" +9708 "White Up-Pointing Triangle With Dot" +9709 "Up-Pointing Triangle With Left Half Black" +9710 "Up-Pointing Triangle With Right Half Black" +9711 "Large Circle" +9712 "White Square With Upper Left Quadrant" +9713 "White Square With Lower Left Quadrant" +9714 "White Square With Lower Right Quadrant" +9715 "White Square With Upper Right Quadrant" +9716 "White Circle With Upper Left Quadrant" +9717 "White Circle With Lower Left Quadrant" +9718 "White Circle With Lower Right Quadrant" +9719 "White Circle With Upper Right Quadrant" +9720 "Upper Left Triangle" +9721 "Upper Right Triangle" +9722 "Lower Left Triangle" +9723 "White Medium Square" +9724 "Black Medium Square" +9725 "White Medium Small Square" +9726 "Black Medium Small Square" +9727 "Lower Right Triangle" +9728 "Black Sun With Rays" +9729 "Cloud" +9730 "Umbrella" +9731 "Snowman" +9732 "Comet" +9733 "Black Star" +9734 "White Star" +9735 "Lightning" +9736 "Thunderstorm" +9737 "Sun" +9738 "Ascending Node" +9739 "Descending Node" +9740 "Conjunction" +9741 "Opposition" +9742 "Black Telephone" +9743 "White Telephone" +9744 "Ballot Box" +9745 "Ballot Box With Check" +9746 "Ballot Box With X" +9747 "Saltire" +9748 "Umbrella With Rain Drops" +9749 "Hot Beverage" +9750 "White Shogi Piece" +9751 "Black Shogi Piece" +9752 "Shamrock" +9753 "Reversed Rotated Floral Heart Bullet" +9754 "Black Left Pointing Index" +9755 "Black Right Pointing Index" +9756 "White Left Pointing Index" +9757 "White Up Pointing Index" +9758 "White Right Pointing Index" +9759 "White Down Pointing Index" +9760 "Skull And Crossbones" +9761 "Caution Sign" +9762 "Radioactive Sign" +9763 "Biohazard Sign" +9764 "Caduceus" +9765 "Ankh" +9766 "Orthodox Cross" +9767 "Chi Rho" +9768 "Cross Of Lorraine" +9769 "Cross Of Jerusalem" +9770 "Star And Crescent" +9771 "Farsi Symbol" +9772 "Adi Shakti" +9773 "Hammer And Sickle" +9774 "Peace Symbol" +9775 "Yin Yang" +9776 "Trigram For Heaven" +9777 "Trigram For Lake" +9778 "Trigram For Fire" +9779 "Trigram For Thunder" +9780 "Trigram For Wind" +9781 "Trigram For Water" +9782 "Trigram For Mountain" +9783 "Trigram For Earth" +9784 "Wheel Of Dharma" +9785 "White Frowning Face" +9786 "White Smiling Face" +9787 "Black Smiling Face" +9788 "White Sun With Rays" +9789 "First Quarter Moon" +9790 "Last Quarter Moon" +9791 "Mercury" +9792 "Female Sign" +9793 "Earth" +9794 "Male Sign" +9795 "Jupiter" +9796 "Saturn" +9797 "Uranus" +9798 "Neptune" +9799 "Pluto" +9800 "Aries" +9801 "Taurus" +9802 "Gemini" +9803 "Cancer" +9804 "Leo" +9805 "Virgo" +9806 "Libra" +9807 "Scorpius" +9808 "Sagittarius" +9809 "Capricorn" +9810 "Aquarius" +9811 "Pisces" +9812 "White Chess King" +9813 "White Chess Queen" +9814 "White Chess Rook" +9815 "White Chess Bishop" +9816 "White Chess Knight" +9817 "White Chess Pawn" +9818 "Black Chess King" +9819 "Black Chess Queen" +9820 "Black Chess Rook" +9821 "Black Chess Bishop" +9822 "Black Chess Knight" +9823 "Black Chess Pawn" +9824 "Black Spade Suit" +9825 "White Heart Suit" +9826 "White Diamond Suit" +9827 "Black Club Suit" +9828 "White Spade Suit" +9829 "Black Heart Suit" +9830 "Black Diamond Suit" +9831 "White Club Suit" +9832 "Hot Springs" +9833 "Quarter Note" +9834 "Eighth Note" +9835 "Beamed Eighth Notes" +9836 "Beamed Sixteenth Notes" +9837 "Music Flat Sign" +9838 "Music Natural Sign" +9839 "Music Sharp Sign" +9840 "West Syriac Cross" +9841 "East Syriac Cross" +9842 "Universal Recycling Symbol" +9843 "Recycling Symbol For Type-1 Plastics" +9844 "Recycling Symbol For Type-2 Plastics" +9845 "Recycling Symbol For Type-3 Plastics" +9846 "Recycling Symbol For Type-4 Plastics" +9847 "Recycling Symbol For Type-5 Plastics" +9848 "Recycling Symbol For Type-6 Plastics" +9849 "Recycling Symbol For Type-7 Plastics" +9850 "Recycling Symbol For Generic Materials" +9851 "Black Universal Recycling Symbol" +9852 "Recycled Paper Symbol" +9853 "Partially-Recycled Paper Symbol" +9854 "Permanent Paper Sign" +9855 "Wheelchair Symbol" +9856 "Die Face-1" +9857 "Die Face-2" +9858 "Die Face-3" +9859 "Die Face-4" +9860 "Die Face-5" +9861 "Die Face-6" +9862 "White Circle With Dot Right" +9863 "White Circle With Two Dots" +9864 "Black Circle With White Dot Right" +9865 "Black Circle With Two White Dots" +9866 "Monogram For Yang" +9867 "Monogram For Yin" +9868 "Digram For Greater Yang" +9869 "Digram For Lesser Yin" +9870 "Digram For Lesser Yang" +9871 "Digram For Greater Yin" +9872 "White Flag" +9873 "Black Flag" +9874 "Hammer And Pick" +9875 "Anchor" +9876 "Crossed Swords" +9877 "Staff Of Aesculapius" +9878 "Scales" +9879 "Alembic" +9880 "Flower" +9881 "Gear" +9882 "Staff Of Hermes" +9883 "Atom Symbol" +9884 "Fleur-De-Lis" +9885 "Outlined White Star" +9886 "Three Lines Converging Right" +9887 "Three Lines Converging Left" +9888 "Warning Sign" +9889 "High Voltage Sign" +9890 "Doubled Female Sign" +9891 "Doubled Male Sign" +9892 "Interlocked Female And Male Sign" +9893 "Male And Female Sign" +9894 "Male With Stroke Sign" +9895 "Male With Stroke And Male And Female Sign" +9896 "Vertical Male With Stroke Sign" +9897 "Horizontal Male With Stroke Sign" +9898 "Medium White Circle" +9899 "Medium Black Circle" +9900 "Medium Small White Circle" +9901 "Marriage Symbol" +9902 "Divorce Symbol" +9903 "Unmarried Partnership Symbol" +9904 "Coffin" +9905 "Funeral Urn" +9906 "Neuter" +9907 "Ceres" +9908 "Pallas" +9909 "Juno" +9910 "Vesta" +9911 "Chiron" +9912 "Black Moon Lilith" +9913 "Sextile" +9914 "Semisextile" +9915 "Quincunx" +9916 "Sesquiquadrate" +9917 "Soccer Ball" +9918 "Baseball" +9919 "Squared Key" +9920 "White Draughts Man" +9921 "White Draughts King" +9922 "Black Draughts Man" +9923 "Black Draughts King" +9924 "Snowman Without Snow" +9925 "Sun Behind Cloud" +9926 "Rain" +9927 "Black Snowman" +9928 "Thunder Cloud And Rain" +9929 "Turned White Shogi Piece" +9930 "Turned Black Shogi Piece" +9931 "White Diamond In Square" +9932 "Crossing Lanes" +9933 "Disabled Car" +9934 "Ophiuchus" +9935 "Pick" +9936 "Car Sliding" +9937 "Helmet With White Cross" +9938 "Circled Crossing Lanes" +9939 "Chains" +9940 "No Entry" +9941 "Alternate One-Way Left Way Traffic" +9942 "Black Two-Way Left Way Traffic" +9943 "White Two-Way Left Way Traffic" +9944 "Black Left Lane Merge" +9945 "White Left Lane Merge" +9946 "Drive Slow Sign" +9947 "Heavy White Down-Pointing Triangle" +9948 "Left Closed Entry" +9949 "Squared Saltire" +9950 "Falling Diagonal In White Circle In Black Square" +9951 "Black Truck" +9952 "Restricted Left Entry-1" +9953 "Restricted Left Entry-2" +9954 "Astronomical Symbol For Uranus" +9955 "Heavy Circle With Stroke And Two Dots Above" +9956 "Pentagram" +9957 "Right-Handed Interlaced Pentagram" +9958 "Left-Handed Interlaced Pentagram" +9959 "Inverted Pentagram" +9960 "Black Cross On Shield" +9961 "Shinto Shrine" +9962 "Church" +9963 "Castle" +9964 "Historic Site" +9965 "Gear Without Hub" +9966 "Gear With Handles" +9967 "Map Symbol For Lighthouse" +9968 "Mountain" +9969 "Umbrella On Ground" +9970 "Fountain" +9971 "Flag In Hole" +9972 "Ferry" +9973 "Sailboat" +9974 "Square Four Corners" +9975 "Skier" +9976 "Ice Skate" +9977 "Person With Ball" +9978 "Tent" +9979 "Japanese Bank Symbol" +9980 "Headstone Graveyard Symbol" +9981 "Fuel Pump" +9982 "Cup On Black Square" +9983 "White Flag With Horizontal Middle Black Stripe" +9985 "Upper Blade Scissors" +9986 "Black Scissors" +9987 "Lower Blade Scissors" +9988 "White Scissors" +9989 "White Heavy Check Mark" +9990 "Telephone Location Sign" +9991 "Tape Drive" +9992 "Airplane" +9993 "Envelope" +9994 "Raised Fist" +9995 "Raised Hand" +9996 "Victory Hand" +9997 "Writing Hand" +9998 "Lower Right Pencil" +9999 "Pencil" +10000 "Upper Right Pencil" +10001 "White Nib" +10002 "Black Nib" +10003 "Check Mark" +10004 "Heavy Check Mark" +10005 "Multiplication X" +10006 "Heavy Multiplication X" +10007 "Ballot X" +10008 "Heavy Ballot X" +10009 "Outlined Greek Cross" +10010 "Heavy Greek Cross" +10011 "Open Centre Cross" +10012 "Heavy Open Centre Cross" +10013 "Latin Cross" +10014 "Shadowed White Latin Cross" +10015 "Outlined Latin Cross" +10016 "Maltese Cross" +10017 "Star Of David" +10018 "Four Teardrop-Spoked Asterisk" +10019 "Four Balloon-Spoked Asterisk" +10020 "Heavy Four Balloon-Spoked Asterisk" +10021 "Four Club-Spoked Asterisk" +10022 "Black Four Pointed Star" +10023 "White Four Pointed Star" +10024 "Sparkles" +10025 "Stress Outlined White Star" +10026 "Circled White Star" +10027 "Open Centre Black Star" +10028 "Black Centre White Star" +10029 "Outlined Black Star" +10030 "Heavy Outlined Black Star" +10031 "Pinwheel Star" +10032 "Shadowed White Star" +10033 "Heavy Asterisk" +10034 "Open Centre Asterisk" +10035 "Eight Spoked Asterisk" +10036 "Eight Pointed Black Star" +10037 "Eight Pointed Pinwheel Star" +10038 "Six Pointed Black Star" +10039 "Eight Pointed Rectilinear Black Star" +10040 "Heavy Eight Pointed Rectilinear Black Star" +10041 "Twelve Pointed Black Star" +10042 "Sixteen Pointed Asterisk" +10043 "Teardrop-Spoked Asterisk" +10044 "Open Centre Teardrop-Spoked Asterisk" +10045 "Heavy Teardrop-Spoked Asterisk" +10046 "Six Petalled Black And White Florette" +10047 "Black Florette" +10048 "White Florette" +10049 "Eight Petalled Outlined Black Florette" +10050 "Circled Open Centre Eight Pointed Star" +10051 "Heavy Teardrop-Spoked Pinwheel Asterisk" +10052 "Snowflake" +10053 "Tight Trifoliate Snowflake" +10054 "Heavy Chevron Snowflake" +10055 "Sparkle" +10056 "Heavy Sparkle" +10057 "Balloon-Spoked Asterisk" +10058 "Eight Teardrop-Spoked Propeller Asterisk" +10059 "Heavy Eight Teardrop-Spoked Propeller Asterisk" +10060 "Cross Mark" +10061 "Shadowed White Circle" +10062 "Negative Squared Cross Mark" +10063 "Lower Right Drop-Shadowed White Square" +10064 "Upper Right Drop-Shadowed White Square" +10065 "Lower Right Shadowed White Square" +10066 "Upper Right Shadowed White Square" +10067 "Black Question Mark Ornament" +10068 "White Question Mark Ornament" +10069 "White Exclamation Mark Ornament" +10070 "Black Diamond Minus White X" +10071 "Heavy Exclamation Mark Symbol" +10072 "Light Vertical Bar" +10073 "Medium Vertical Bar" +10074 "Heavy Vertical Bar" +10075 "Heavy Single Turned Comma Quotation Mark Ornament" +10076 "Heavy Single Comma Quotation Mark Ornament" +10077 "Heavy Double Turned Comma Quotation Mark Ornament" +10078 "Heavy Double Comma Quotation Mark Ornament" +10079 "Heavy Low Single Comma Quotation Mark Ornament" +10080 "Heavy Low Double Comma Quotation Mark Ornament" +10081 "Curved Stem Paragraph Sign Ornament" +10082 "Heavy Exclamation Mark Ornament" +10083 "Heavy Heart Exclamation Mark Ornament" +10084 "Heavy Black Heart" +10085 "Rotated Heavy Black Heart Bullet" +10086 "Floral Heart" +10087 "Rotated Floral Heart Bullet" +10088 "Medium Left Parenthesis Ornament" +10089 "Medium Right Parenthesis Ornament" +10090 "Medium Flattened Left Parenthesis Ornament" +10091 "Medium Flattened Right Parenthesis Ornament" +10092 "Medium Left-Pointing Angle Bracket Ornament" +10093 "Medium Right-Pointing Angle Bracket Ornament" +10094 "Heavy Left-Pointing Angle Quotation Mark Ornament" +10095 "Heavy Right-Pointing Angle Quotation Mark Ornament" +10096 "Heavy Left-Pointing Angle Bracket Ornament" +10097 "Heavy Right-Pointing Angle Bracket Ornament" +10098 "Light Left Tortoise Shell Bracket Ornament" +10099 "Light Right Tortoise Shell Bracket Ornament" +10100 "Medium Left Curly Bracket Ornament" +10101 "Medium Right Curly Bracket Ornament" +10102 "Dingbat Negative Circled Digit One" +10103 "Dingbat Negative Circled Digit Two" +10104 "Dingbat Negative Circled Digit Three" +10105 "Dingbat Negative Circled Digit Four" +10106 "Dingbat Negative Circled Digit Five" +10107 "Dingbat Negative Circled Digit Six" +10108 "Dingbat Negative Circled Digit Seven" +10109 "Dingbat Negative Circled Digit Eight" +10110 "Dingbat Negative Circled Digit Nine" +10111 "Dingbat Negative Circled Number Ten" +10112 "Dingbat Circled Sans-Serif Digit One" +10113 "Dingbat Circled Sans-Serif Digit Two" +10114 "Dingbat Circled Sans-Serif Digit Three" +10115 "Dingbat Circled Sans-Serif Digit Four" +10116 "Dingbat Circled Sans-Serif Digit Five" +10117 "Dingbat Circled Sans-Serif Digit Six" +10118 "Dingbat Circled Sans-Serif Digit Seven" +10119 "Dingbat Circled Sans-Serif Digit Eight" +10120 "Dingbat Circled Sans-Serif Digit Nine" +10121 "Dingbat Circled Sans-Serif Number Ten" +10122 "Dingbat Negative Circled Sans-Serif Digit One" +10123 "Dingbat Negative Circled Sans-Serif Digit Two" +10124 "Dingbat Negative Circled Sans-Serif Digit Three" +10125 "Dingbat Negative Circled Sans-Serif Digit Four" +10126 "Dingbat Negative Circled Sans-Serif Digit Five" +10127 "Dingbat Negative Circled Sans-Serif Digit Six" +10128 "Dingbat Negative Circled Sans-Serif Digit Seven" +10129 "Dingbat Negative Circled Sans-Serif Digit Eight" +10130 "Dingbat Negative Circled Sans-Serif Digit Nine" +10131 "Dingbat Negative Circled Sans-Serif Number Ten" +10132 "Heavy Wide-Headed Rightwards Arrow" +10133 "Heavy Plus Sign" +10134 "Heavy Minus Sign" +10135 "Heavy Division Sign" +10136 "Heavy South East Arrow" +10137 "Heavy Rightwards Arrow" +10138 "Heavy North East Arrow" +10139 "Drafting Point Rightwards Arrow" +10140 "Heavy Round-Tipped Rightwards Arrow" +10141 "Triangle-Headed Rightwards Arrow" +10142 "Heavy Triangle-Headed Rightwards Arrow" +10143 "Dashed Triangle-Headed Rightwards Arrow" +10144 "Heavy Dashed Triangle-Headed Rightwards Arrow" +10145 "Black Rightwards Arrow" +10146 "Three-D Top-Lighted Rightwards Arrowhead" +10147 "Three-D Bottom-Lighted Rightwards Arrowhead" +10148 "Black Rightwards Arrowhead" +10149 "Heavy Black Curved Downwards And Rightwards Arrow" +10150 "Heavy Black Curved Upwards And Rightwards Arrow" +10151 "Squat Black Rightwards Arrow" +10152 "Heavy Concave-Pointed Black Rightwards Arrow" +10153 "Right-Shaded White Rightwards Arrow" +10154 "Left-Shaded White Rightwards Arrow" +10155 "Back-Tilted Shadowed White Rightwards Arrow" +10156 "Front-Tilted Shadowed White Rightwards Arrow" +10157 "Heavy Lower Right-Shadowed White Rightwards Arrow" +10158 "Heavy Upper Right-Shadowed White Rightwards Arrow" +10159 "Notched Lower Right-Shadowed White Rightwards Arrow" +10160 "Curly Loop" +10161 "Notched Upper Right-Shadowed White Rightwards Arrow" +10162 "Circled Heavy White Rightwards Arrow" +10163 "White-Feathered Rightwards Arrow" +10164 "Black-Feathered South East Arrow" +10165 "Black-Feathered Rightwards Arrow" +10166 "Black-Feathered North East Arrow" +10167 "Heavy Black-Feathered South East Arrow" +10168 "Heavy Black-Feathered Rightwards Arrow" +10169 "Heavy Black-Feathered North East Arrow" +10170 "Teardrop-Barbed Rightwards Arrow" +10171 "Heavy Teardrop-Shanked Rightwards Arrow" +10172 "Wedge-Tailed Rightwards Arrow" +10173 "Heavy Wedge-Tailed Rightwards Arrow" +10174 "Open-Outlined Rightwards Arrow" +10175 "Double Curly Loop" +10176 "Three Dimensional Angle" +10177 "White Triangle Containing Small White Triangle" +10178 "Perpendicular" +10179 "Open Subset" +10180 "Open Superset" +10181 "Left S-Shaped Bag Delimiter" +10182 "Right S-Shaped Bag Delimiter" +10183 "Or With Dot Inside" +10184 "Reverse Solidus Preceding Subset" +10185 "Superset Preceding Solidus" +10186 "Vertical Bar With Horizontal Stroke" +10187 "Mathematical Rising Diagonal" +10188 "Long Division" +10189 "Mathematical Falling Diagonal" +10190 "Squared Logical And" +10191 "Squared Logical Or" +10192 "White Diamond With Centred Dot" +10193 "And With Dot" +10194 "Element Of Opening Upwards" +10195 "Lower Right Corner With Dot" +10196 "Upper Left Corner With Dot" +10197 "Left Outer Join" +10198 "Right Outer Join" +10199 "Full Outer Join" +10200 "Large Up Tack" +10201 "Large Down Tack" +10202 "Left And Right Double Turnstile" +10203 "Left And Right Tack" +10204 "Left Multimap" +10205 "Long Right Tack" +10206 "Long Left Tack" +10207 "Up Tack With Circle Above" +10208 "Lozenge Divided By Horizontal Rule" +10209 "White Concave-Sided Diamond" +10210 "White Concave-Sided Diamond With Leftwards Tick" +10211 "White Concave-Sided Diamond With Rightwards Tick" +10212 "White Square With Leftwards Tick" +10213 "White Square With Rightwards Tick" +10214 "Mathematical Left White Square Bracket" +10215 "Mathematical Right White Square Bracket" +10216 "Mathematical Left Angle Bracket" +10217 "Mathematical Right Angle Bracket" +10218 "Mathematical Left Double Angle Bracket" +10219 "Mathematical Right Double Angle Bracket" +10220 "Mathematical Left White Tortoise Shell Bracket" +10221 "Mathematical Right White Tortoise Shell Bracket" +10222 "Mathematical Left Flattened Parenthesis" +10223 "Mathematical Right Flattened Parenthesis" +10224 "Upwards Quadruple Arrow" +10225 "Downwards Quadruple Arrow" +10226 "Anticlockwise Gapped Circle Arrow" +10227 "Clockwise Gapped Circle Arrow" +10228 "Right Arrow With Circled Plus" +10229 "Long Leftwards Arrow" +10230 "Long Rightwards Arrow" +10231 "Long Left Right Arrow" +10232 "Long Leftwards Double Arrow" +10233 "Long Rightwards Double Arrow" +10234 "Long Left Right Double Arrow" +10235 "Long Leftwards Arrow From Bar" +10236 "Long Rightwards Arrow From Bar" +10237 "Long Leftwards Double Arrow From Bar" +10238 "Long Rightwards Double Arrow From Bar" +10239 "Long Rightwards Squiggle Arrow" +10240 "Braille Pattern Blank" +10241 "Braille Pattern Dots-1" +10242 "Braille Pattern Dots-2" +10243 "Braille Pattern Dots-12" +10244 "Braille Pattern Dots-3" +10245 "Braille Pattern Dots-13" +10246 "Braille Pattern Dots-23" +10247 "Braille Pattern Dots-123" +10248 "Braille Pattern Dots-4" +10249 "Braille Pattern Dots-14" +10250 "Braille Pattern Dots-24" +10251 "Braille Pattern Dots-124" +10252 "Braille Pattern Dots-34" +10253 "Braille Pattern Dots-134" +10254 "Braille Pattern Dots-234" +10255 "Braille Pattern Dots-1234" +10256 "Braille Pattern Dots-5" +10257 "Braille Pattern Dots-15" +10258 "Braille Pattern Dots-25" +10259 "Braille Pattern Dots-125" +10260 "Braille Pattern Dots-35" +10261 "Braille Pattern Dots-135" +10262 "Braille Pattern Dots-235" +10263 "Braille Pattern Dots-1235" +10264 "Braille Pattern Dots-45" +10265 "Braille Pattern Dots-145" +10266 "Braille Pattern Dots-245" +10267 "Braille Pattern Dots-1245" +10268 "Braille Pattern Dots-345" +10269 "Braille Pattern Dots-1345" +10270 "Braille Pattern Dots-2345" +10271 "Braille Pattern Dots-12345" +10272 "Braille Pattern Dots-6" +10273 "Braille Pattern Dots-16" +10274 "Braille Pattern Dots-26" +10275 "Braille Pattern Dots-126" +10276 "Braille Pattern Dots-36" +10277 "Braille Pattern Dots-136" +10278 "Braille Pattern Dots-236" +10279 "Braille Pattern Dots-1236" +10280 "Braille Pattern Dots-46" +10281 "Braille Pattern Dots-146" +10282 "Braille Pattern Dots-246" +10283 "Braille Pattern Dots-1246" +10284 "Braille Pattern Dots-346" +10285 "Braille Pattern Dots-1346" +10286 "Braille Pattern Dots-2346" +10287 "Braille Pattern Dots-12346" +10288 "Braille Pattern Dots-56" +10289 "Braille Pattern Dots-156" +10290 "Braille Pattern Dots-256" +10291 "Braille Pattern Dots-1256" +10292 "Braille Pattern Dots-356" +10293 "Braille Pattern Dots-1356" +10294 "Braille Pattern Dots-2356" +10295 "Braille Pattern Dots-12356" +10296 "Braille Pattern Dots-456" +10297 "Braille Pattern Dots-1456" +10298 "Braille Pattern Dots-2456" +10299 "Braille Pattern Dots-12456" +10300 "Braille Pattern Dots-3456" +10301 "Braille Pattern Dots-13456" +10302 "Braille Pattern Dots-23456" +10303 "Braille Pattern Dots-123456" +10304 "Braille Pattern Dots-7" +10305 "Braille Pattern Dots-17" +10306 "Braille Pattern Dots-27" +10307 "Braille Pattern Dots-127" +10308 "Braille Pattern Dots-37" +10309 "Braille Pattern Dots-137" +10310 "Braille Pattern Dots-237" +10311 "Braille Pattern Dots-1237" +10312 "Braille Pattern Dots-47" +10313 "Braille Pattern Dots-147" +10314 "Braille Pattern Dots-247" +10315 "Braille Pattern Dots-1247" +10316 "Braille Pattern Dots-347" +10317 "Braille Pattern Dots-1347" +10318 "Braille Pattern Dots-2347" +10319 "Braille Pattern Dots-12347" +10320 "Braille Pattern Dots-57" +10321 "Braille Pattern Dots-157" +10322 "Braille Pattern Dots-257" +10323 "Braille Pattern Dots-1257" +10324 "Braille Pattern Dots-357" +10325 "Braille Pattern Dots-1357" +10326 "Braille Pattern Dots-2357" +10327 "Braille Pattern Dots-12357" +10328 "Braille Pattern Dots-457" +10329 "Braille Pattern Dots-1457" +10330 "Braille Pattern Dots-2457" +10331 "Braille Pattern Dots-12457" +10332 "Braille Pattern Dots-3457" +10333 "Braille Pattern Dots-13457" +10334 "Braille Pattern Dots-23457" +10335 "Braille Pattern Dots-123457" +10336 "Braille Pattern Dots-67" +10337 "Braille Pattern Dots-167" +10338 "Braille Pattern Dots-267" +10339 "Braille Pattern Dots-1267" +10340 "Braille Pattern Dots-367" +10341 "Braille Pattern Dots-1367" +10342 "Braille Pattern Dots-2367" +10343 "Braille Pattern Dots-12367" +10344 "Braille Pattern Dots-467" +10345 "Braille Pattern Dots-1467" +10346 "Braille Pattern Dots-2467" +10347 "Braille Pattern Dots-12467" +10348 "Braille Pattern Dots-3467" +10349 "Braille Pattern Dots-13467" +10350 "Braille Pattern Dots-23467" +10351 "Braille Pattern Dots-123467" +10352 "Braille Pattern Dots-567" +10353 "Braille Pattern Dots-1567" +10354 "Braille Pattern Dots-2567" +10355 "Braille Pattern Dots-12567" +10356 "Braille Pattern Dots-3567" +10357 "Braille Pattern Dots-13567" +10358 "Braille Pattern Dots-23567" +10359 "Braille Pattern Dots-123567" +10360 "Braille Pattern Dots-4567" +10361 "Braille Pattern Dots-14567" +10362 "Braille Pattern Dots-24567" +10363 "Braille Pattern Dots-124567" +10364 "Braille Pattern Dots-34567" +10365 "Braille Pattern Dots-134567" +10366 "Braille Pattern Dots-234567" +10367 "Braille Pattern Dots-1234567" +10368 "Braille Pattern Dots-8" +10369 "Braille Pattern Dots-18" +10370 "Braille Pattern Dots-28" +10371 "Braille Pattern Dots-128" +10372 "Braille Pattern Dots-38" +10373 "Braille Pattern Dots-138" +10374 "Braille Pattern Dots-238" +10375 "Braille Pattern Dots-1238" +10376 "Braille Pattern Dots-48" +10377 "Braille Pattern Dots-148" +10378 "Braille Pattern Dots-248" +10379 "Braille Pattern Dots-1248" +10380 "Braille Pattern Dots-348" +10381 "Braille Pattern Dots-1348" +10382 "Braille Pattern Dots-2348" +10383 "Braille Pattern Dots-12348" +10384 "Braille Pattern Dots-58" +10385 "Braille Pattern Dots-158" +10386 "Braille Pattern Dots-258" +10387 "Braille Pattern Dots-1258" +10388 "Braille Pattern Dots-358" +10389 "Braille Pattern Dots-1358" +10390 "Braille Pattern Dots-2358" +10391 "Braille Pattern Dots-12358" +10392 "Braille Pattern Dots-458" +10393 "Braille Pattern Dots-1458" +10394 "Braille Pattern Dots-2458" +10395 "Braille Pattern Dots-12458" +10396 "Braille Pattern Dots-3458" +10397 "Braille Pattern Dots-13458" +10398 "Braille Pattern Dots-23458" +10399 "Braille Pattern Dots-123458" +10400 "Braille Pattern Dots-68" +10401 "Braille Pattern Dots-168" +10402 "Braille Pattern Dots-268" +10403 "Braille Pattern Dots-1268" +10404 "Braille Pattern Dots-368" +10405 "Braille Pattern Dots-1368" +10406 "Braille Pattern Dots-2368" +10407 "Braille Pattern Dots-12368" +10408 "Braille Pattern Dots-468" +10409 "Braille Pattern Dots-1468" +10410 "Braille Pattern Dots-2468" +10411 "Braille Pattern Dots-12468" +10412 "Braille Pattern Dots-3468" +10413 "Braille Pattern Dots-13468" +10414 "Braille Pattern Dots-23468" +10415 "Braille Pattern Dots-123468" +10416 "Braille Pattern Dots-568" +10417 "Braille Pattern Dots-1568" +10418 "Braille Pattern Dots-2568" +10419 "Braille Pattern Dots-12568" +10420 "Braille Pattern Dots-3568" +10421 "Braille Pattern Dots-13568" +10422 "Braille Pattern Dots-23568" +10423 "Braille Pattern Dots-123568" +10424 "Braille Pattern Dots-4568" +10425 "Braille Pattern Dots-14568" +10426 "Braille Pattern Dots-24568" +10427 "Braille Pattern Dots-124568" +10428 "Braille Pattern Dots-34568" +10429 "Braille Pattern Dots-134568" +10430 "Braille Pattern Dots-234568" +10431 "Braille Pattern Dots-1234568" +10432 "Braille Pattern Dots-78" +10433 "Braille Pattern Dots-178" +10434 "Braille Pattern Dots-278" +10435 "Braille Pattern Dots-1278" +10436 "Braille Pattern Dots-378" +10437 "Braille Pattern Dots-1378" +10438 "Braille Pattern Dots-2378" +10439 "Braille Pattern Dots-12378" +10440 "Braille Pattern Dots-478" +10441 "Braille Pattern Dots-1478" +10442 "Braille Pattern Dots-2478" +10443 "Braille Pattern Dots-12478" +10444 "Braille Pattern Dots-3478" +10445 "Braille Pattern Dots-13478" +10446 "Braille Pattern Dots-23478" +10447 "Braille Pattern Dots-123478" +10448 "Braille Pattern Dots-578" +10449 "Braille Pattern Dots-1578" +10450 "Braille Pattern Dots-2578" +10451 "Braille Pattern Dots-12578" +10452 "Braille Pattern Dots-3578" +10453 "Braille Pattern Dots-13578" +10454 "Braille Pattern Dots-23578" +10455 "Braille Pattern Dots-123578" +10456 "Braille Pattern Dots-4578" +10457 "Braille Pattern Dots-14578" +10458 "Braille Pattern Dots-24578" +10459 "Braille Pattern Dots-124578" +10460 "Braille Pattern Dots-34578" +10461 "Braille Pattern Dots-134578" +10462 "Braille Pattern Dots-234578" +10463 "Braille Pattern Dots-1234578" +10464 "Braille Pattern Dots-678" +10465 "Braille Pattern Dots-1678" +10466 "Braille Pattern Dots-2678" +10467 "Braille Pattern Dots-12678" +10468 "Braille Pattern Dots-3678" +10469 "Braille Pattern Dots-13678" +10470 "Braille Pattern Dots-23678" +10471 "Braille Pattern Dots-123678" +10472 "Braille Pattern Dots-4678" +10473 "Braille Pattern Dots-14678" +10474 "Braille Pattern Dots-24678" +10475 "Braille Pattern Dots-124678" +10476 "Braille Pattern Dots-34678" +10477 "Braille Pattern Dots-134678" +10478 "Braille Pattern Dots-234678" +10479 "Braille Pattern Dots-1234678" +10480 "Braille Pattern Dots-5678" +10481 "Braille Pattern Dots-15678" +10482 "Braille Pattern Dots-25678" +10483 "Braille Pattern Dots-125678" +10484 "Braille Pattern Dots-35678" +10485 "Braille Pattern Dots-135678" +10486 "Braille Pattern Dots-235678" +10487 "Braille Pattern Dots-1235678" +10488 "Braille Pattern Dots-45678" +10489 "Braille Pattern Dots-145678" +10490 "Braille Pattern Dots-245678" +10491 "Braille Pattern Dots-1245678" +10492 "Braille Pattern Dots-345678" +10493 "Braille Pattern Dots-1345678" +10494 "Braille Pattern Dots-2345678" +10495 "Braille Pattern Dots-12345678" +10496 "Rightwards Two-Headed Arrow With Vertical Stroke" +10497 "Rightwards Two-Headed Arrow With Double Vertical Stroke" +10498 "Leftwards Double Arrow With Vertical Stroke" +10499 "Rightwards Double Arrow With Vertical Stroke" +10500 "Left Right Double Arrow With Vertical Stroke" +10501 "Rightwards Two-Headed Arrow From Bar" +10502 "Leftwards Double Arrow From Bar" +10503 "Rightwards Double Arrow From Bar" +10504 "Downwards Arrow With Horizontal Stroke" +10505 "Upwards Arrow With Horizontal Stroke" +10506 "Upwards Triple Arrow" +10507 "Downwards Triple Arrow" +10508 "Leftwards Double Dash Arrow" +10509 "Rightwards Double Dash Arrow" +10510 "Leftwards Triple Dash Arrow" +10511 "Rightwards Triple Dash Arrow" +10512 "Rightwards Two-Headed Triple Dash Arrow" +10513 "Rightwards Arrow With Dotted Stem" +10514 "Upwards Arrow To Bar" +10515 "Downwards Arrow To Bar" +10516 "Rightwards Arrow With Tail With Vertical Stroke" +10517 "Rightwards Arrow With Tail With Double Vertical Stroke" +10518 "Rightwards Two-Headed Arrow With Tail" +10519 "Rightwards Two-Headed Arrow With Tail With Vertical Stroke" +10520 "Rightwards Two-Headed Arrow With Tail With Double Vertical Stroke" +10521 "Leftwards Arrow-Tail" +10522 "Rightwards Arrow-Tail" +10523 "Leftwards Double Arrow-Tail" +10524 "Rightwards Double Arrow-Tail" +10525 "Leftwards Arrow To Black Diamond" +10526 "Rightwards Arrow To Black Diamond" +10527 "Leftwards Arrow From Bar To Black Diamond" +10528 "Rightwards Arrow From Bar To Black Diamond" +10529 "North West And South East Arrow" +10530 "North East And South West Arrow" +10531 "North West Arrow With Hook" +10532 "North East Arrow With Hook" +10533 "South East Arrow With Hook" +10534 "South West Arrow With Hook" +10535 "North West Arrow And North East Arrow" +10536 "North East Arrow And South East Arrow" +10537 "South East Arrow And South West Arrow" +10538 "South West Arrow And North West Arrow" +10539 "Rising Diagonal Crossing Falling Diagonal" +10540 "Falling Diagonal Crossing Rising Diagonal" +10541 "South East Arrow Crossing North East Arrow" +10542 "North East Arrow Crossing South East Arrow" +10543 "Falling Diagonal Crossing North East Arrow" +10544 "Rising Diagonal Crossing South East Arrow" +10545 "North East Arrow Crossing North West Arrow" +10546 "North West Arrow Crossing North East Arrow" +10547 "Wave Arrow Pointing Directly Right" +10548 "Arrow Pointing Rightwards Then Curving Upwards" +10549 "Arrow Pointing Rightwards Then Curving Downwards" +10550 "Arrow Pointing Downwards Then Curving Leftwards" +10551 "Arrow Pointing Downwards Then Curving Rightwards" +10552 "Right-Side Arc Clockwise Arrow" +10553 "Left-Side Arc Anticlockwise Arrow" +10554 "Top Arc Anticlockwise Arrow" +10555 "Bottom Arc Anticlockwise Arrow" +10556 "Top Arc Clockwise Arrow With Minus" +10557 "Top Arc Anticlockwise Arrow With Plus" +10558 "Lower Right Semicircular Clockwise Arrow" +10559 "Lower Left Semicircular Anticlockwise Arrow" +10560 "Anticlockwise Closed Circle Arrow" +10561 "Clockwise Closed Circle Arrow" +10562 "Rightwards Arrow Above Short Leftwards Arrow" +10563 "Leftwards Arrow Above Short Rightwards Arrow" +10564 "Short Rightwards Arrow Above Leftwards Arrow" +10565 "Rightwards Arrow With Plus Below" +10566 "Leftwards Arrow With Plus Below" +10567 "Rightwards Arrow Through X" +10568 "Left Right Arrow Through Small Circle" +10569 "Upwards Two-Headed Arrow From Small Circle" +10570 "Left Barb Up Right Barb Down Harpoon" +10571 "Left Barb Down Right Barb Up Harpoon" +10572 "Up Barb Right Down Barb Left Harpoon" +10573 "Up Barb Left Down Barb Right Harpoon" +10574 "Left Barb Up Right Barb Up Harpoon" +10575 "Up Barb Right Down Barb Right Harpoon" +10576 "Left Barb Down Right Barb Down Harpoon" +10577 "Up Barb Left Down Barb Left Harpoon" +10578 "Leftwards Harpoon With Barb Up To Bar" +10579 "Rightwards Harpoon With Barb Up To Bar" +10580 "Upwards Harpoon With Barb Right To Bar" +10581 "Downwards Harpoon With Barb Right To Bar" +10582 "Leftwards Harpoon With Barb Down To Bar" +10583 "Rightwards Harpoon With Barb Down To Bar" +10584 "Upwards Harpoon With Barb Left To Bar" +10585 "Downwards Harpoon With Barb Left To Bar" +10586 "Leftwards Harpoon With Barb Up From Bar" +10587 "Rightwards Harpoon With Barb Up From Bar" +10588 "Upwards Harpoon With Barb Right From Bar" +10589 "Downwards Harpoon With Barb Right From Bar" +10590 "Leftwards Harpoon With Barb Down From Bar" +10591 "Rightwards Harpoon With Barb Down From Bar" +10592 "Upwards Harpoon With Barb Left From Bar" +10593 "Downwards Harpoon With Barb Left From Bar" +10594 "Leftwards Harpoon With Barb Up Above Leftwards Harpoon With Barb Down" +10595 "Upwards Harpoon With Barb Left Beside Upwards Harpoon With Barb Right" +10596 "Rightwards Harpoon With Barb Up Above Rightwards Harpoon With Barb Down" +10597 "Downwards Harpoon With Barb Left Beside Downwards Harpoon With Barb Right" +10598 "Leftwards Harpoon With Barb Up Above Rightwards Harpoon With Barb Up" +10599 "Leftwards Harpoon With Barb Down Above Rightwards Harpoon With Barb Down" +10600 "Rightwards Harpoon With Barb Up Above Leftwards Harpoon With Barb Up" +10601 "Rightwards Harpoon With Barb Down Above Leftwards Harpoon With Barb Down" +10602 "Leftwards Harpoon With Barb Up Above Long Dash" +10603 "Leftwards Harpoon With Barb Down Below Long Dash" +10604 "Rightwards Harpoon With Barb Up Above Long Dash" +10605 "Rightwards Harpoon With Barb Down Below Long Dash" +10606 "Upwards Harpoon With Barb Left Beside Downwards Harpoon With Barb Right" +10607 "Downwards Harpoon With Barb Left Beside Upwards Harpoon With Barb Right" +10608 "Right Double Arrow With Rounded Head" +10609 "Equals Sign Above Rightwards Arrow" +10610 "Tilde Operator Above Rightwards Arrow" +10611 "Leftwards Arrow Above Tilde Operator" +10612 "Rightwards Arrow Above Tilde Operator" +10613 "Rightwards Arrow Above Almost Equal To" +10614 "Less-Than Above Leftwards Arrow" +10615 "Leftwards Arrow Through Less-Than" +10616 "Greater-Than Above Rightwards Arrow" +10617 "Subset Above Rightwards Arrow" +10618 "Leftwards Arrow Through Subset" +10619 "Superset Above Leftwards Arrow" +10620 "Left Fish Tail" +10621 "Right Fish Tail" +10622 "Up Fish Tail" +10623 "Down Fish Tail" +10624 "Triple Vertical Bar Delimiter" +10625 "Z Notation Spot" +10626 "Z Notation Type Colon" +10627 "Left White Curly Bracket" +10628 "Right White Curly Bracket" +10629 "Left White Parenthesis" +10630 "Right White Parenthesis" +10631 "Z Notation Left Image Bracket" +10632 "Z Notation Right Image Bracket" +10633 "Z Notation Left Binding Bracket" +10634 "Z Notation Right Binding Bracket" +10635 "Left Square Bracket With Underbar" +10636 "Right Square Bracket With Underbar" +10637 "Left Square Bracket With Tick In Top Corner" +10638 "Right Square Bracket With Tick In Bottom Corner" +10639 "Left Square Bracket With Tick In Bottom Corner" +10640 "Right Square Bracket With Tick In Top Corner" +10641 "Left Angle Bracket With Dot" +10642 "Right Angle Bracket With Dot" +10643 "Left Arc Less-Than Bracket" +10644 "Right Arc Greater-Than Bracket" +10645 "Double Left Arc Greater-Than Bracket" +10646 "Double Right Arc Less-Than Bracket" +10647 "Left Black Tortoise Shell Bracket" +10648 "Right Black Tortoise Shell Bracket" +10649 "Dotted Fence" +10650 "Vertical Zigzag Line" +10651 "Measured Angle Opening Left" +10652 "Right Angle Variant With Square" +10653 "Measured Right Angle With Dot" +10654 "Angle With S Inside" +10655 "Acute Angle" +10656 "Spherical Angle Opening Left" +10657 "Spherical Angle Opening Up" +10658 "Turned Angle" +10659 "Reversed Angle" +10660 "Angle With Underbar" +10661 "Reversed Angle With Underbar" +10662 "Oblique Angle Opening Up" +10663 "Oblique Angle Opening Down" +10664 "Measured Angle With Open Arm Ending In Arrow Pointing Up And Right" +10665 "Measured Angle With Open Arm Ending In Arrow Pointing Up And Left" +10666 "Measured Angle With Open Arm Ending In Arrow Pointing Down And Right" +10667 "Measured Angle With Open Arm Ending In Arrow Pointing Down And Left" +10668 "Measured Angle With Open Arm Ending In Arrow Pointing Right And Up" +10669 "Measured Angle With Open Arm Ending In Arrow Pointing Left And Up" +10670 "Measured Angle With Open Arm Ending In Arrow Pointing Right And Down" +10671 "Measured Angle With Open Arm Ending In Arrow Pointing Left And Down" +10672 "Reversed Empty Set" +10673 "Empty Set With Overbar" +10674 "Empty Set With Small Circle Above" +10675 "Empty Set With Right Arrow Above" +10676 "Empty Set With Left Arrow Above" +10677 "Circle With Horizontal Bar" +10678 "Circled Vertical Bar" +10679 "Circled Parallel" +10680 "Circled Reverse Solidus" +10681 "Circled Perpendicular" +10682 "Circle Divided By Horizontal Bar And Top Half Divided By Vertical Bar" +10683 "Circle With Superimposed X" +10684 "Circled Anticlockwise-Rotated Division Sign" +10685 "Up Arrow Through Circle" +10686 "Circled White Bullet" +10687 "Circled Bullet" +10688 "Circled Less-Than" +10689 "Circled Greater-Than" +10690 "Circle With Small Circle To The Right" +10691 "Circle With Two Horizontal Strokes To The Right" +10692 "Squared Rising Diagonal Slash" +10693 "Squared Falling Diagonal Slash" +10694 "Squared Asterisk" +10695 "Squared Small Circle" +10696 "Squared Square" +10697 "Two Joined Squares" +10698 "Triangle With Dot Above" +10699 "Triangle With Underbar" +10700 "S In Triangle" +10701 "Triangle With Serifs At Bottom" +10702 "Right Triangle Above Left Triangle" +10703 "Left Triangle Beside Vertical Bar" +10704 "Vertical Bar Beside Right Triangle" +10705 "Bowtie With Left Half Black" +10706 "Bowtie With Right Half Black" +10707 "Black Bowtie" +10708 "Times With Left Half Black" +10709 "Times With Right Half Black" +10710 "White Hourglass" +10711 "Black Hourglass" +10712 "Left Wiggly Fence" +10713 "Right Wiggly Fence" +10714 "Left Double Wiggly Fence" +10715 "Right Double Wiggly Fence" +10716 "Incomplete Infinity" +10717 "Tie Over Infinity" +10718 "Infinity Negated With Vertical Bar" +10719 "Double-Ended Multimap" +10720 "Square With Contoured Outline" +10721 "Increases As" +10722 "Shuffle Product" +10723 "Equals Sign And Slanted Parallel" +10724 "Equals Sign And Slanted Parallel With Tilde Above" +10725 "Identical To And Slanted Parallel" +10726 "Gleich Stark" +10727 "Thermodynamic" +10728 "Down-Pointing Triangle With Left Half Black" +10729 "Down-Pointing Triangle With Right Half Black" +10730 "Black Diamond With Down Arrow" +10731 "Black Lozenge" +10732 "White Circle With Down Arrow" +10733 "Black Circle With Down Arrow" +10734 "Error-Barred White Square" +10735 "Error-Barred Black Square" +10736 "Error-Barred White Diamond" +10737 "Error-Barred Black Diamond" +10738 "Error-Barred White Circle" +10739 "Error-Barred Black Circle" +10740 "Rule-Delayed" +10741 "Reverse Solidus Operator" +10742 "Solidus With Overbar" +10743 "Reverse Solidus With Horizontal Stroke" +10744 "Big Solidus" +10745 "Big Reverse Solidus" +10746 "Double Plus" +10747 "Triple Plus" +10748 "Left-Pointing Curved Angle Bracket" +10749 "Right-Pointing Curved Angle Bracket" +10750 "Tiny" +10751 "Miny" +10752 "N-Ary Circled Dot Operator" +10753 "N-Ary Circled Plus Operator" +10754 "N-Ary Circled Times Operator" +10755 "N-Ary Union Operator With Dot" +10756 "N-Ary Union Operator With Plus" +10757 "N-Ary Square Intersection Operator" +10758 "N-Ary Square Union Operator" +10759 "Two Logical And Operator" +10760 "Two Logical Or Operator" +10761 "N-Ary Times Operator" +10762 "Modulo Two Sum" +10763 "Summation With Integral" +10764 "Quadruple Integral Operator" +10765 "Finite Part Integral" +10766 "Integral With Double Stroke" +10767 "Integral Average With Slash" +10768 "Circulation Function" +10769 "Anticlockwise Integration" +10770 "Line Integration With Rectangular Path Around Pole" +10771 "Line Integration With Semicircular Path Around Pole" +10772 "Line Integration Not Including The Pole" +10773 "Integral Around A Point Operator" +10774 "Quaternion Integral Operator" +10775 "Integral With Leftwards Arrow With Hook" +10776 "Integral With Times Sign" +10777 "Integral With Intersection" +10778 "Integral With Union" +10779 "Integral With Overbar" +10780 "Integral With Underbar" +10781 "Join" +10782 "Large Left Triangle Operator" +10783 "Z Notation Schema Composition" +10784 "Z Notation Schema Piping" +10785 "Z Notation Schema Projection" +10786 "Plus Sign With Small Circle Above" +10787 "Plus Sign With Circumflex Accent Above" +10788 "Plus Sign With Tilde Above" +10789 "Plus Sign With Dot Below" +10790 "Plus Sign With Tilde Below" +10791 "Plus Sign With Subscript Two" +10792 "Plus Sign With Black Triangle" +10793 "Minus Sign With Comma Above" +10794 "Minus Sign With Dot Below" +10795 "Minus Sign With Falling Dots" +10796 "Minus Sign With Rising Dots" +10797 "Plus Sign In Left Half Circle" +10798 "Plus Sign In Right Half Circle" +10799 "Vector Or Cross Product" +10800 "Multiplication Sign With Dot Above" +10801 "Multiplication Sign With Underbar" +10802 "Semidirect Product With Bottom Closed" +10803 "Smash Product" +10804 "Multiplication Sign In Left Half Circle" +10805 "Multiplication Sign In Right Half Circle" +10806 "Circled Multiplication Sign With Circumflex Accent" +10807 "Multiplication Sign In Double Circle" +10808 "Circled Division Sign" +10809 "Plus Sign In Triangle" +10810 "Minus Sign In Triangle" +10811 "Multiplication Sign In Triangle" +10812 "Interior Product" +10813 "Righthand Interior Product" +10814 "Z Notation Relational Composition" +10815 "Amalgamation Or Coproduct" +10816 "Intersection With Dot" +10817 "Union With Minus Sign" +10818 "Union With Overbar" +10819 "Intersection With Overbar" +10820 "Intersection With Logical And" +10821 "Union With Logical Or" +10822 "Union Above Intersection" +10823 "Intersection Above Union" +10824 "Union Above Bar Above Intersection" +10825 "Intersection Above Bar Above Union" +10826 "Union Beside And Joined With Union" +10827 "Intersection Beside And Joined With Intersection" +10828 "Closed Union With Serifs" +10829 "Closed Intersection With Serifs" +10830 "Double Square Intersection" +10831 "Double Square Union" +10832 "Closed Union With Serifs And Smash Product" +10833 "Logical And With Dot Above" +10834 "Logical Or With Dot Above" +10835 "Double Logical And" +10836 "Double Logical Or" +10837 "Two Intersecting Logical And" +10838 "Two Intersecting Logical Or" +10839 "Sloping Large Or" +10840 "Sloping Large And" +10841 "Logical Or Overlapping Logical And" +10842 "Logical And With Middle Stem" +10843 "Logical Or With Middle Stem" +10844 "Logical And With Horizontal Dash" +10845 "Logical Or With Horizontal Dash" +10846 "Logical And With Double Overbar" +10847 "Logical And With Underbar" +10848 "Logical And With Double Underbar" +10849 "Small Vee With Underbar" +10850 "Logical Or With Double Overbar" +10851 "Logical Or With Double Underbar" +10852 "Z Notation Domain Antirestriction" +10853 "Z Notation Range Antirestriction" +10854 "Equals Sign With Dot Below" +10855 "Identical With Dot Above" +10856 "Triple Horizontal Bar With Double Vertical Stroke" +10857 "Triple Horizontal Bar With Triple Vertical Stroke" +10858 "Tilde Operator With Dot Above" +10859 "Tilde Operator With Rising Dots" +10860 "Similar Minus Similar" +10861 "Congruent With Dot Above" +10862 "Equals With Asterisk" +10863 "Almost Equal To With Circumflex Accent" +10864 "Approximately Equal Or Equal To" +10865 "Equals Sign Above Plus Sign" +10866 "Plus Sign Above Equals Sign" +10867 "Equals Sign Above Tilde Operator" +10868 "Double Colon Equal" +10869 "Two Consecutive Equals Signs" +10870 "Three Consecutive Equals Signs" +10871 "Equals Sign With Two Dots Above And Two Dots Below" +10872 "Equivalent With Four Dots Above" +10873 "Less-Than With Circle Inside" +10874 "Greater-Than With Circle Inside" +10875 "Less-Than With Question Mark Above" +10876 "Greater-Than With Question Mark Above" +10877 "Less-Than Or Slanted Equal To" +10878 "Greater-Than Or Slanted Equal To" +10879 "Less-Than Or Slanted Equal To With Dot Inside" +10880 "Greater-Than Or Slanted Equal To With Dot Inside" +10881 "Less-Than Or Slanted Equal To With Dot Above" +10882 "Greater-Than Or Slanted Equal To With Dot Above" +10883 "Less-Than Or Slanted Equal To With Dot Above Right" +10884 "Greater-Than Or Slanted Equal To With Dot Above Left" +10885 "Less-Than Or Approximate" +10886 "Greater-Than Or Approximate" +10887 "Less-Than And Single-Line Not Equal To" +10888 "Greater-Than And Single-Line Not Equal To" +10889 "Less-Than And Not Approximate" +10890 "Greater-Than And Not Approximate" +10891 "Less-Than Above Double-Line Equal Above Greater-Than" +10892 "Greater-Than Above Double-Line Equal Above Less-Than" +10893 "Less-Than Above Similar Or Equal" +10894 "Greater-Than Above Similar Or Equal" +10895 "Less-Than Above Similar Above Greater-Than" +10896 "Greater-Than Above Similar Above Less-Than" +10897 "Less-Than Above Greater-Than Above Double-Line Equal" +10898 "Greater-Than Above Less-Than Above Double-Line Equal" +10899 "Less-Than Above Slanted Equal Above Greater-Than Above Slanted Equal" +10900 "Greater-Than Above Slanted Equal Above Less-Than Above Slanted Equal" +10901 "Slanted Equal To Or Less-Than" +10902 "Slanted Equal To Or Greater-Than" +10903 "Slanted Equal To Or Less-Than With Dot Inside" +10904 "Slanted Equal To Or Greater-Than With Dot Inside" +10905 "Double-Line Equal To Or Less-Than" +10906 "Double-Line Equal To Or Greater-Than" +10907 "Double-Line Slanted Equal To Or Less-Than" +10908 "Double-Line Slanted Equal To Or Greater-Than" +10909 "Similar Or Less-Than" +10910 "Similar Or Greater-Than" +10911 "Similar Above Less-Than Above Equals Sign" +10912 "Similar Above Greater-Than Above Equals Sign" +10913 "Double Nested Less-Than" +10914 "Double Nested Greater-Than" +10915 "Double Nested Less-Than With Underbar" +10916 "Greater-Than Overlapping Less-Than" +10917 "Greater-Than Beside Less-Than" +10918 "Less-Than Closed By Curve" +10919 "Greater-Than Closed By Curve" +10920 "Less-Than Closed By Curve Above Slanted Equal" +10921 "Greater-Than Closed By Curve Above Slanted Equal" +10922 "Smaller Than" +10923 "Larger Than" +10924 "Smaller Than Or Equal To" +10925 "Larger Than Or Equal To" +10926 "Equals Sign With Bumpy Above" +10927 "Precedes Above Single-Line Equals Sign" +10928 "Succeeds Above Single-Line Equals Sign" +10929 "Precedes Above Single-Line Not Equal To" +10930 "Succeeds Above Single-Line Not Equal To" +10931 "Precedes Above Equals Sign" +10932 "Succeeds Above Equals Sign" +10933 "Precedes Above Not Equal To" +10934 "Succeeds Above Not Equal To" +10935 "Precedes Above Almost Equal To" +10936 "Succeeds Above Almost Equal To" +10937 "Precedes Above Not Almost Equal To" +10938 "Succeeds Above Not Almost Equal To" +10939 "Double Precedes" +10940 "Double Succeeds" +10941 "Subset With Dot" +10942 "Superset With Dot" +10943 "Subset With Plus Sign Below" +10944 "Superset With Plus Sign Below" +10945 "Subset With Multiplication Sign Below" +10946 "Superset With Multiplication Sign Below" +10947 "Subset Of Or Equal To With Dot Above" +10948 "Superset Of Or Equal To With Dot Above" +10949 "Subset Of Above Equals Sign" +10950 "Superset Of Above Equals Sign" +10951 "Subset Of Above Tilde Operator" +10952 "Superset Of Above Tilde Operator" +10953 "Subset Of Above Almost Equal To" +10954 "Superset Of Above Almost Equal To" +10955 "Subset Of Above Not Equal To" +10956 "Superset Of Above Not Equal To" +10957 "Square Left Open Box Operator" +10958 "Square Right Open Box Operator" +10959 "Closed Subset" +10960 "Closed Superset" +10961 "Closed Subset Or Equal To" +10962 "Closed Superset Or Equal To" +10963 "Subset Above Superset" +10964 "Superset Above Subset" +10965 "Subset Above Subset" +10966 "Superset Above Superset" +10967 "Superset Beside Subset" +10968 "Superset Beside And Joined By Dash With Subset" +10969 "Element Of Opening Downwards" +10970 "Pitchfork With Tee Top" +10971 "Transversal Intersection" +10972 "Forking" +10973 "Nonforking" +10974 "Short Left Tack" +10975 "Short Down Tack" +10976 "Short Up Tack" +10977 "Perpendicular With S" +10978 "Vertical Bar Triple Right Turnstile" +10979 "Double Vertical Bar Left Turnstile" +10980 "Vertical Bar Double Left Turnstile" +10981 "Double Vertical Bar Double Left Turnstile" +10982 "Long Dash From Left Member Of Double Vertical" +10983 "Short Down Tack With Overbar" +10984 "Short Up Tack With Underbar" +10985 "Short Up Tack Above Short Down Tack" +10986 "Double Down Tack" +10987 "Double Up Tack" +10988 "Double Stroke Not Sign" +10989 "Reversed Double Stroke Not Sign" +10990 "Does Not Divide With Reversed Negation Slash" +10991 "Vertical Line With Circle Above" +10992 "Vertical Line With Circle Below" +10993 "Down Tack With Circle Below" +10994 "Parallel With Horizontal Stroke" +10995 "Parallel With Tilde Operator" +10996 "Triple Vertical Bar Binary Relation" +10997 "Triple Vertical Bar With Horizontal Stroke" +10998 "Triple Colon Operator" +10999 "Triple Nested Less-Than" +11000 "Triple Nested Greater-Than" +11001 "Double-Line Slanted Less-Than Or Equal To" +11002 "Double-Line Slanted Greater-Than Or Equal To" +11003 "Triple Solidus Binary Relation" +11004 "Large Triple Vertical Bar Operator" +11005 "Double Solidus Operator" +11006 "White Vertical Bar" +11007 "N-Ary White Vertical Bar" +11008 "North East White Arrow" +11009 "North West White Arrow" +11010 "South East White Arrow" +11011 "South West White Arrow" +11012 "Left Right White Arrow" +11013 "Leftwards Black Arrow" +11014 "Upwards Black Arrow" +11015 "Downwards Black Arrow" +11016 "North East Black Arrow" +11017 "North West Black Arrow" +11018 "South East Black Arrow" +11019 "South West Black Arrow" +11020 "Left Right Black Arrow" +11021 "Up Down Black Arrow" +11022 "Rightwards Arrow With Tip Downwards" +11023 "Rightwards Arrow With Tip Upwards" +11024 "Leftwards Arrow With Tip Downwards" +11025 "Leftwards Arrow With Tip Upwards" +11026 "Square With Top Half Black" +11027 "Square With Bottom Half Black" +11028 "Square With Upper Right Diagonal Half Black" +11029 "Square With Lower Left Diagonal Half Black" +11030 "Diamond With Left Half Black" +11031 "Diamond With Right Half Black" +11032 "Diamond With Top Half Black" +11033 "Diamond With Bottom Half Black" +11034 "Dotted Square" +11035 "Black Large Square" +11036 "White Large Square" +11037 "Black Very Small Square" +11038 "White Very Small Square" +11039 "Black Pentagon" +11040 "White Pentagon" +11041 "White Hexagon" +11042 "Black Hexagon" +11043 "Horizontal Black Hexagon" +11044 "Black Large Circle" +11045 "Black Medium Diamond" +11046 "White Medium Diamond" +11047 "Black Medium Lozenge" +11048 "White Medium Lozenge" +11049 "Black Small Diamond" +11050 "Black Small Lozenge" +11051 "White Small Lozenge" +11052 "Black Horizontal Ellipse" +11053 "White Horizontal Ellipse" +11054 "Black Vertical Ellipse" +11055 "White Vertical Ellipse" +11056 "Left Arrow With Small Circle" +11057 "Three Leftwards Arrows" +11058 "Left Arrow With Circled Plus" +11059 "Long Leftwards Squiggle Arrow" +11060 "Leftwards Two-Headed Arrow With Vertical Stroke" +11061 "Leftwards Two-Headed Arrow With Double Vertical Stroke" +11062 "Leftwards Two-Headed Arrow From Bar" +11063 "Leftwards Two-Headed Triple Dash Arrow" +11064 "Leftwards Arrow With Dotted Stem" +11065 "Leftwards Arrow With Tail With Vertical Stroke" +11066 "Leftwards Arrow With Tail With Double Vertical Stroke" +11067 "Leftwards Two-Headed Arrow With Tail" +11068 "Leftwards Two-Headed Arrow With Tail With Vertical Stroke" +11069 "Leftwards Two-Headed Arrow With Tail With Double Vertical Stroke" +11070 "Leftwards Arrow Through X" +11071 "Wave Arrow Pointing Directly Left" +11072 "Equals Sign Above Leftwards Arrow" +11073 "Reverse Tilde Operator Above Leftwards Arrow" +11074 "Leftwards Arrow Above Reverse Almost Equal To" +11075 "Rightwards Arrow Through Greater-Than" +11076 "Rightwards Arrow Through Superset" +11077 "Leftwards Quadruple Arrow" +11078 "Rightwards Quadruple Arrow" +11079 "Reverse Tilde Operator Above Rightwards Arrow" +11080 "Rightwards Arrow Above Reverse Almost Equal To" +11081 "Tilde Operator Above Leftwards Arrow" +11082 "Leftwards Arrow Above Almost Equal To" +11083 "Leftwards Arrow Above Reverse Tilde Operator" +11084 "Rightwards Arrow Above Reverse Tilde Operator" +11088 "White Medium Star" +11089 "Black Small Star" +11090 "White Small Star" +11091 "Black Right-Pointing Pentagon" +11092 "White Right-Pointing Pentagon" +11093 "Heavy Large Circle" +11094 "Heavy Oval With Oval Inside" +11095 "Heavy Circle With Circle Inside" +11096 "Heavy Circle" +11097 "Heavy Circled Saltire" +11264 "Glagolitic Capital Letter Azu" +11265 "Glagolitic Capital Letter Buky" +11266 "Glagolitic Capital Letter Vede" +11267 "Glagolitic Capital Letter Glagoli" +11268 "Glagolitic Capital Letter Dobro" +11269 "Glagolitic Capital Letter Yestu" +11270 "Glagolitic Capital Letter Zhivete" +11271 "Glagolitic Capital Letter Dzelo" +11272 "Glagolitic Capital Letter Zemlja" +11273 "Glagolitic Capital Letter Izhe" +11274 "Glagolitic Capital Letter Initial Izhe" +11275 "Glagolitic Capital Letter I" +11276 "Glagolitic Capital Letter Djervi" +11277 "Glagolitic Capital Letter Kako" +11278 "Glagolitic Capital Letter Ljudije" +11279 "Glagolitic Capital Letter Myslite" +11280 "Glagolitic Capital Letter Nashi" +11281 "Glagolitic Capital Letter Onu" +11282 "Glagolitic Capital Letter Pokoji" +11283 "Glagolitic Capital Letter Ritsi" +11284 "Glagolitic Capital Letter Slovo" +11285 "Glagolitic Capital Letter Tvrido" +11286 "Glagolitic Capital Letter Uku" +11287 "Glagolitic Capital Letter Fritu" +11288 "Glagolitic Capital Letter Heru" +11289 "Glagolitic Capital Letter Otu" +11290 "Glagolitic Capital Letter Pe" +11291 "Glagolitic Capital Letter Shta" +11292 "Glagolitic Capital Letter Tsi" +11293 "Glagolitic Capital Letter Chrivi" +11294 "Glagolitic Capital Letter Sha" +11295 "Glagolitic Capital Letter Yeru" +11296 "Glagolitic Capital Letter Yeri" +11297 "Glagolitic Capital Letter Yati" +11298 "Glagolitic Capital Letter Spidery Ha" +11299 "Glagolitic Capital Letter Yu" +11300 "Glagolitic Capital Letter Small Yus" +11301 "Glagolitic Capital Letter Small Yus With Tail" +11302 "Glagolitic Capital Letter Yo" +11303 "Glagolitic Capital Letter Iotated Small Yus" +11304 "Glagolitic Capital Letter Big Yus" +11305 "Glagolitic Capital Letter Iotated Big Yus" +11306 "Glagolitic Capital Letter Fita" +11307 "Glagolitic Capital Letter Izhitsa" +11308 "Glagolitic Capital Letter Shtapic" +11309 "Glagolitic Capital Letter Trokutasti A" +11310 "Glagolitic Capital Letter Latinate Myslite" +11312 "Glagolitic Small Letter Azu" +11313 "Glagolitic Small Letter Buky" +11314 "Glagolitic Small Letter Vede" +11315 "Glagolitic Small Letter Glagoli" +11316 "Glagolitic Small Letter Dobro" +11317 "Glagolitic Small Letter Yestu" +11318 "Glagolitic Small Letter Zhivete" +11319 "Glagolitic Small Letter Dzelo" +11320 "Glagolitic Small Letter Zemlja" +11321 "Glagolitic Small Letter Izhe" +11322 "Glagolitic Small Letter Initial Izhe" +11323 "Glagolitic Small Letter I" +11324 "Glagolitic Small Letter Djervi" +11325 "Glagolitic Small Letter Kako" +11326 "Glagolitic Small Letter Ljudije" +11327 "Glagolitic Small Letter Myslite" +11328 "Glagolitic Small Letter Nashi" +11329 "Glagolitic Small Letter Onu" +11330 "Glagolitic Small Letter Pokoji" +11331 "Glagolitic Small Letter Ritsi" +11332 "Glagolitic Small Letter Slovo" +11333 "Glagolitic Small Letter Tvrido" +11334 "Glagolitic Small Letter Uku" +11335 "Glagolitic Small Letter Fritu" +11336 "Glagolitic Small Letter Heru" +11337 "Glagolitic Small Letter Otu" +11338 "Glagolitic Small Letter Pe" +11339 "Glagolitic Small Letter Shta" +11340 "Glagolitic Small Letter Tsi" +11341 "Glagolitic Small Letter Chrivi" +11342 "Glagolitic Small Letter Sha" +11343 "Glagolitic Small Letter Yeru" +11344 "Glagolitic Small Letter Yeri" +11345 "Glagolitic Small Letter Yati" +11346 "Glagolitic Small Letter Spidery Ha" +11347 "Glagolitic Small Letter Yu" +11348 "Glagolitic Small Letter Small Yus" +11349 "Glagolitic Small Letter Small Yus With Tail" +11350 "Glagolitic Small Letter Yo" +11351 "Glagolitic Small Letter Iotated Small Yus" +11352 "Glagolitic Small Letter Big Yus" +11353 "Glagolitic Small Letter Iotated Big Yus" +11354 "Glagolitic Small Letter Fita" +11355 "Glagolitic Small Letter Izhitsa" +11356 "Glagolitic Small Letter Shtapic" +11357 "Glagolitic Small Letter Trokutasti A" +11358 "Glagolitic Small Letter Latinate Myslite" +11360 "Latin Capital Letter L With Double Bar" +11361 "Latin Small Letter L With Double Bar" +11362 "Latin Capital Letter L With Middle Tilde" +11363 "Latin Capital Letter P With Stroke" +11364 "Latin Capital Letter R With Tail" +11365 "Latin Small Letter A With Stroke" +11366 "Latin Small Letter T With Diagonal Stroke" +11367 "Latin Capital Letter H With Descender" +11368 "Latin Small Letter H With Descender" +11369 "Latin Capital Letter K With Descender" +11370 "Latin Small Letter K With Descender" +11371 "Latin Capital Letter Z With Descender" +11372 "Latin Small Letter Z With Descender" +11373 "Latin Capital Letter Alpha" +11374 "Latin Capital Letter M With Hook" +11375 "Latin Capital Letter Turned A" +11376 "Latin Capital Letter Turned Alpha" +11377 "Latin Small Letter V With Right Hook" +11378 "Latin Capital Letter W With Hook" +11379 "Latin Small Letter W With Hook" +11380 "Latin Small Letter V With Curl" +11381 "Latin Capital Letter Half H" +11382 "Latin Small Letter Half H" +11383 "Latin Small Letter Tailless Phi" +11384 "Latin Small Letter E With Notch" +11385 "Latin Small Letter Turned R With Tail" +11386 "Latin Small Letter O With Low Ring Inside" +11387 "Latin Letter Small Capital Turned E" +11388 "Latin Subscript Small Letter J" +11389 "Modifier Letter Capital V" +11390 "Latin Capital Letter S With Swash Tail" +11391 "Latin Capital Letter Z With Swash Tail" +11392 "Coptic Capital Letter Alfa" +11393 "Coptic Small Letter Alfa" +11394 "Coptic Capital Letter Vida" +11395 "Coptic Small Letter Vida" +11396 "Coptic Capital Letter Gamma" +11397 "Coptic Small Letter Gamma" +11398 "Coptic Capital Letter Dalda" +11399 "Coptic Small Letter Dalda" +11400 "Coptic Capital Letter Eie" +11401 "Coptic Small Letter Eie" +11402 "Coptic Capital Letter Sou" +11403 "Coptic Small Letter Sou" +11404 "Coptic Capital Letter Zata" +11405 "Coptic Small Letter Zata" +11406 "Coptic Capital Letter Hate" +11407 "Coptic Small Letter Hate" +11408 "Coptic Capital Letter Thethe" +11409 "Coptic Small Letter Thethe" +11410 "Coptic Capital Letter Iauda" +11411 "Coptic Small Letter Iauda" +11412 "Coptic Capital Letter Kapa" +11413 "Coptic Small Letter Kapa" +11414 "Coptic Capital Letter Laula" +11415 "Coptic Small Letter Laula" +11416 "Coptic Capital Letter Mi" +11417 "Coptic Small Letter Mi" +11418 "Coptic Capital Letter Ni" +11419 "Coptic Small Letter Ni" +11420 "Coptic Capital Letter Ksi" +11421 "Coptic Small Letter Ksi" +11422 "Coptic Capital Letter O" +11423 "Coptic Small Letter O" +11424 "Coptic Capital Letter Pi" +11425 "Coptic Small Letter Pi" +11426 "Coptic Capital Letter Ro" +11427 "Coptic Small Letter Ro" +11428 "Coptic Capital Letter Sima" +11429 "Coptic Small Letter Sima" +11430 "Coptic Capital Letter Tau" +11431 "Coptic Small Letter Tau" +11432 "Coptic Capital Letter Ua" +11433 "Coptic Small Letter Ua" +11434 "Coptic Capital Letter Fi" +11435 "Coptic Small Letter Fi" +11436 "Coptic Capital Letter Khi" +11437 "Coptic Small Letter Khi" +11438 "Coptic Capital Letter Psi" +11439 "Coptic Small Letter Psi" +11440 "Coptic Capital Letter Oou" +11441 "Coptic Small Letter Oou" +11442 "Coptic Capital Letter Dialect-P Alef" +11443 "Coptic Small Letter Dialect-P Alef" +11444 "Coptic Capital Letter Old Coptic Ain" +11445 "Coptic Small Letter Old Coptic Ain" +11446 "Coptic Capital Letter Cryptogrammic Eie" +11447 "Coptic Small Letter Cryptogrammic Eie" +11448 "Coptic Capital Letter Dialect-P Kapa" +11449 "Coptic Small Letter Dialect-P Kapa" +11450 "Coptic Capital Letter Dialect-P Ni" +11451 "Coptic Small Letter Dialect-P Ni" +11452 "Coptic Capital Letter Cryptogrammic Ni" +11453 "Coptic Small Letter Cryptogrammic Ni" +11454 "Coptic Capital Letter Old Coptic Oou" +11455 "Coptic Small Letter Old Coptic Oou" +11456 "Coptic Capital Letter Sampi" +11457 "Coptic Small Letter Sampi" +11458 "Coptic Capital Letter Crossed Shei" +11459 "Coptic Small Letter Crossed Shei" +11460 "Coptic Capital Letter Old Coptic Shei" +11461 "Coptic Small Letter Old Coptic Shei" +11462 "Coptic Capital Letter Old Coptic Esh" +11463 "Coptic Small Letter Old Coptic Esh" +11464 "Coptic Capital Letter Akhmimic Khei" +11465 "Coptic Small Letter Akhmimic Khei" +11466 "Coptic Capital Letter Dialect-P Hori" +11467 "Coptic Small Letter Dialect-P Hori" +11468 "Coptic Capital Letter Old Coptic Hori" +11469 "Coptic Small Letter Old Coptic Hori" +11470 "Coptic Capital Letter Old Coptic Ha" +11471 "Coptic Small Letter Old Coptic Ha" +11472 "Coptic Capital Letter L-Shaped Ha" +11473 "Coptic Small Letter L-Shaped Ha" +11474 "Coptic Capital Letter Old Coptic Hei" +11475 "Coptic Small Letter Old Coptic Hei" +11476 "Coptic Capital Letter Old Coptic Hat" +11477 "Coptic Small Letter Old Coptic Hat" +11478 "Coptic Capital Letter Old Coptic Gangia" +11479 "Coptic Small Letter Old Coptic Gangia" +11480 "Coptic Capital Letter Old Coptic Dja" +11481 "Coptic Small Letter Old Coptic Dja" +11482 "Coptic Capital Letter Old Coptic Shima" +11483 "Coptic Small Letter Old Coptic Shima" +11484 "Coptic Capital Letter Old Nubian Shima" +11485 "Coptic Small Letter Old Nubian Shima" +11486 "Coptic Capital Letter Old Nubian Ngi" +11487 "Coptic Small Letter Old Nubian Ngi" +11488 "Coptic Capital Letter Old Nubian Nyi" +11489 "Coptic Small Letter Old Nubian Nyi" +11490 "Coptic Capital Letter Old Nubian Wau" +11491 "Coptic Small Letter Old Nubian Wau" +11492 "Coptic Symbol Kai" +11493 "Coptic Symbol Mi Ro" +11494 "Coptic Symbol Pi Ro" +11495 "Coptic Symbol Stauros" +11496 "Coptic Symbol Tau Ro" +11497 "Coptic Symbol Khi Ro" +11498 "Coptic Symbol Shima Sima" +11499 "Coptic Capital Letter Cryptogrammic Shei" +11500 "Coptic Small Letter Cryptogrammic Shei" +11501 "Coptic Capital Letter Cryptogrammic Gangia" +11502 "Coptic Small Letter Cryptogrammic Gangia" +11503 "Coptic Combining Ni Above" +11504 "Coptic Combining Spiritus Asper" +11505 "Coptic Combining Spiritus Lenis" +11506 "Coptic Capital Letter Bohairic Khei" +11507 "Coptic Small Letter Bohairic Khei" +11513 "Coptic Old Nubian Full Stop" +11514 "Coptic Old Nubian Direct Question Mark" +11515 "Coptic Old Nubian Indirect Question Mark" +11516 "Coptic Old Nubian Verse Divider" +11517 "Coptic Fraction One Half" +11518 "Coptic Full Stop" +11519 "Coptic Morphological Divider" +11520 "Georgian Small Letter An" +11521 "Georgian Small Letter Ban" +11522 "Georgian Small Letter Gan" +11523 "Georgian Small Letter Don" +11524 "Georgian Small Letter En" +11525 "Georgian Small Letter Vin" +11526 "Georgian Small Letter Zen" +11527 "Georgian Small Letter Tan" +11528 "Georgian Small Letter In" +11529 "Georgian Small Letter Kan" +11530 "Georgian Small Letter Las" +11531 "Georgian Small Letter Man" +11532 "Georgian Small Letter Nar" +11533 "Georgian Small Letter On" +11534 "Georgian Small Letter Par" +11535 "Georgian Small Letter Zhar" +11536 "Georgian Small Letter Rae" +11537 "Georgian Small Letter San" +11538 "Georgian Small Letter Tar" +11539 "Georgian Small Letter Un" +11540 "Georgian Small Letter Phar" +11541 "Georgian Small Letter Khar" +11542 "Georgian Small Letter Ghan" +11543 "Georgian Small Letter Qar" +11544 "Georgian Small Letter Shin" +11545 "Georgian Small Letter Chin" +11546 "Georgian Small Letter Can" +11547 "Georgian Small Letter Jil" +11548 "Georgian Small Letter Cil" +11549 "Georgian Small Letter Char" +11550 "Georgian Small Letter Xan" +11551 "Georgian Small Letter Jhan" +11552 "Georgian Small Letter Hae" +11553 "Georgian Small Letter He" +11554 "Georgian Small Letter Hie" +11555 "Georgian Small Letter We" +11556 "Georgian Small Letter Har" +11557 "Georgian Small Letter Hoe" +11559 "Georgian Small Letter Yn" +11565 "Georgian Small Letter Aen" +11568 "Tifinagh Letter Ya" +11569 "Tifinagh Letter Yab" +11570 "Tifinagh Letter Yabh" +11571 "Tifinagh Letter Yag" +11572 "Tifinagh Letter Yaghh" +11573 "Tifinagh Letter Berber Academy Yaj" +11574 "Tifinagh Letter Yaj" +11575 "Tifinagh Letter Yad" +11576 "Tifinagh Letter Yadh" +11577 "Tifinagh Letter Yadd" +11578 "Tifinagh Letter Yaddh" +11579 "Tifinagh Letter Yey" +11580 "Tifinagh Letter Yaf" +11581 "Tifinagh Letter Yak" +11582 "Tifinagh Letter Tuareg Yak" +11583 "Tifinagh Letter Yakhh" +11584 "Tifinagh Letter Yah" +11585 "Tifinagh Letter Berber Academy Yah" +11586 "Tifinagh Letter Tuareg Yah" +11587 "Tifinagh Letter Yahh" +11588 "Tifinagh Letter Yaa" +11589 "Tifinagh Letter Yakh" +11590 "Tifinagh Letter Tuareg Yakh" +11591 "Tifinagh Letter Yaq" +11592 "Tifinagh Letter Tuareg Yaq" +11593 "Tifinagh Letter Yi" +11594 "Tifinagh Letter Yazh" +11595 "Tifinagh Letter Ahaggar Yazh" +11596 "Tifinagh Letter Tuareg Yazh" +11597 "Tifinagh Letter Yal" +11598 "Tifinagh Letter Yam" +11599 "Tifinagh Letter Yan" +11600 "Tifinagh Letter Tuareg Yagn" +11601 "Tifinagh Letter Tuareg Yang" +11602 "Tifinagh Letter Yap" +11603 "Tifinagh Letter Yu" +11604 "Tifinagh Letter Yar" +11605 "Tifinagh Letter Yarr" +11606 "Tifinagh Letter Yagh" +11607 "Tifinagh Letter Tuareg Yagh" +11608 "Tifinagh Letter Ayer Yagh" +11609 "Tifinagh Letter Yas" +11610 "Tifinagh Letter Yass" +11611 "Tifinagh Letter Yash" +11612 "Tifinagh Letter Yat" +11613 "Tifinagh Letter Yath" +11614 "Tifinagh Letter Yach" +11615 "Tifinagh Letter Yatt" +11616 "Tifinagh Letter Yav" +11617 "Tifinagh Letter Yaw" +11618 "Tifinagh Letter Yay" +11619 "Tifinagh Letter Yaz" +11620 "Tifinagh Letter Tawellemet Yaz" +11621 "Tifinagh Letter Yazz" +11622 "Tifinagh Letter Ye" +11623 "Tifinagh Letter Yo" +11631 "Tifinagh Modifier Letter Labialization Mark" +11632 "Tifinagh Separator Mark" +11647 "Tifinagh Consonant Joiner" +11648 "Ethiopic Syllable Loa" +11649 "Ethiopic Syllable Moa" +11650 "Ethiopic Syllable Roa" +11651 "Ethiopic Syllable Soa" +11652 "Ethiopic Syllable Shoa" +11653 "Ethiopic Syllable Boa" +11654 "Ethiopic Syllable Toa" +11655 "Ethiopic Syllable Coa" +11656 "Ethiopic Syllable Noa" +11657 "Ethiopic Syllable Nyoa" +11658 "Ethiopic Syllable Glottal Oa" +11659 "Ethiopic Syllable Zoa" +11660 "Ethiopic Syllable Doa" +11661 "Ethiopic Syllable Ddoa" +11662 "Ethiopic Syllable Joa" +11663 "Ethiopic Syllable Thoa" +11664 "Ethiopic Syllable Choa" +11665 "Ethiopic Syllable Phoa" +11666 "Ethiopic Syllable Poa" +11667 "Ethiopic Syllable Ggwa" +11668 "Ethiopic Syllable Ggwi" +11669 "Ethiopic Syllable Ggwee" +11670 "Ethiopic Syllable Ggwe" +11680 "Ethiopic Syllable Ssa" +11681 "Ethiopic Syllable Ssu" +11682 "Ethiopic Syllable Ssi" +11683 "Ethiopic Syllable Ssaa" +11684 "Ethiopic Syllable Ssee" +11685 "Ethiopic Syllable Sse" +11686 "Ethiopic Syllable Sso" +11688 "Ethiopic Syllable Cca" +11689 "Ethiopic Syllable Ccu" +11690 "Ethiopic Syllable Cci" +11691 "Ethiopic Syllable Ccaa" +11692 "Ethiopic Syllable Ccee" +11693 "Ethiopic Syllable Cce" +11694 "Ethiopic Syllable Cco" +11696 "Ethiopic Syllable Zza" +11697 "Ethiopic Syllable Zzu" +11698 "Ethiopic Syllable Zzi" +11699 "Ethiopic Syllable Zzaa" +11700 "Ethiopic Syllable Zzee" +11701 "Ethiopic Syllable Zze" +11702 "Ethiopic Syllable Zzo" +11704 "Ethiopic Syllable Ccha" +11705 "Ethiopic Syllable Cchu" +11706 "Ethiopic Syllable Cchi" +11707 "Ethiopic Syllable Cchaa" +11708 "Ethiopic Syllable Cchee" +11709 "Ethiopic Syllable Cche" +11710 "Ethiopic Syllable Ccho" +11712 "Ethiopic Syllable Qya" +11713 "Ethiopic Syllable Qyu" +11714 "Ethiopic Syllable Qyi" +11715 "Ethiopic Syllable Qyaa" +11716 "Ethiopic Syllable Qyee" +11717 "Ethiopic Syllable Qye" +11718 "Ethiopic Syllable Qyo" +11720 "Ethiopic Syllable Kya" +11721 "Ethiopic Syllable Kyu" +11722 "Ethiopic Syllable Kyi" +11723 "Ethiopic Syllable Kyaa" +11724 "Ethiopic Syllable Kyee" +11725 "Ethiopic Syllable Kye" +11726 "Ethiopic Syllable Kyo" +11728 "Ethiopic Syllable Xya" +11729 "Ethiopic Syllable Xyu" +11730 "Ethiopic Syllable Xyi" +11731 "Ethiopic Syllable Xyaa" +11732 "Ethiopic Syllable Xyee" +11733 "Ethiopic Syllable Xye" +11734 "Ethiopic Syllable Xyo" +11736 "Ethiopic Syllable Gya" +11737 "Ethiopic Syllable Gyu" +11738 "Ethiopic Syllable Gyi" +11739 "Ethiopic Syllable Gyaa" +11740 "Ethiopic Syllable Gyee" +11741 "Ethiopic Syllable Gye" +11742 "Ethiopic Syllable Gyo" +11744 "Combining Cyrillic Letter Be" +11745 "Combining Cyrillic Letter Ve" +11746 "Combining Cyrillic Letter Ghe" +11747 "Combining Cyrillic Letter De" +11748 "Combining Cyrillic Letter Zhe" +11749 "Combining Cyrillic Letter Ze" +11750 "Combining Cyrillic Letter Ka" +11751 "Combining Cyrillic Letter El" +11752 "Combining Cyrillic Letter Em" +11753 "Combining Cyrillic Letter En" +11754 "Combining Cyrillic Letter O" +11755 "Combining Cyrillic Letter Pe" +11756 "Combining Cyrillic Letter Er" +11757 "Combining Cyrillic Letter Es" +11758 "Combining Cyrillic Letter Te" +11759 "Combining Cyrillic Letter Ha" +11760 "Combining Cyrillic Letter Tse" +11761 "Combining Cyrillic Letter Che" +11762 "Combining Cyrillic Letter Sha" +11763 "Combining Cyrillic Letter Shcha" +11764 "Combining Cyrillic Letter Fita" +11765 "Combining Cyrillic Letter Es-Te" +11766 "Combining Cyrillic Letter A" +11767 "Combining Cyrillic Letter Ie" +11768 "Combining Cyrillic Letter Djerv" +11769 "Combining Cyrillic Letter Monograph Uk" +11770 "Combining Cyrillic Letter Yat" +11771 "Combining Cyrillic Letter Yu" +11772 "Combining Cyrillic Letter Iotified A" +11773 "Combining Cyrillic Letter Little Yus" +11774 "Combining Cyrillic Letter Big Yus" +11775 "Combining Cyrillic Letter Iotified Big Yus" +11776 "Right Angle Substitution Marker" +11777 "Right Angle Dotted Substitution Marker" +11778 "Left Substitution Bracket" +11779 "Right Substitution Bracket" +11780 "Left Dotted Substitution Bracket" +11781 "Right Dotted Substitution Bracket" +11782 "Raised Interpolation Marker" +11783 "Raised Dotted Interpolation Marker" +11784 "Dotted Transposition Marker" +11785 "Left Transposition Bracket" +11786 "Right Transposition Bracket" +11787 "Raised Square" +11788 "Left Raised Omission Bracket" +11789 "Right Raised Omission Bracket" +11790 "Editorial Coronis" +11791 "Paragraphos" +11792 "Forked Paragraphos" +11793 "Reversed Forked Paragraphos" +11794 "Hypodiastole" +11795 "Dotted Obelos" +11796 "Downwards Ancora" +11797 "Upwards Ancora" +11798 "Dotted Right-Pointing Angle" +11799 "Double Oblique Hyphen" +11800 "Inverted Interrobang" +11801 "Palm Branch" +11802 "Hyphen With Diaeresis" +11803 "Tilde With Ring Above" +11804 "Left Low Paraphrase Bracket" +11805 "Right Low Paraphrase Bracket" +11806 "Tilde With Dot Above" +11807 "Tilde With Dot Below" +11808 "Left Vertical Bar With Quill" +11809 "Right Vertical Bar With Quill" +11810 "Top Left Half Bracket" +11811 "Top Right Half Bracket" +11812 "Bottom Left Half Bracket" +11813 "Bottom Right Half Bracket" +11814 "Left Sideways U Bracket" +11815 "Right Sideways U Bracket" +11816 "Left Double Parenthesis" +11817 "Right Double Parenthesis" +11818 "Two Dots Over One Dot Punctuation" +11819 "One Dot Over Two Dots Punctuation" +11820 "Squared Four Dot Punctuation" +11821 "Five Dot Mark" +11822 "Reversed Question Mark" +11823 "Vertical Tilde" +11824 "Ring Point" +11825 "Word Separator Middle Dot" +11826 "Turned Comma" +11827 "Raised Dot" +11828 "Raised Comma" +11829 "Turned Semicolon" +11830 "Dagger With Left Guard" +11831 "Dagger With Right Guard" +11832 "Turned Dagger" +11833 "Top Half Section Sign" +11834 "Two-Em Dash" +11835 "Three-Em Dash" +11904 "CJK Radical Repeat" +11905 "CJK Radical Cliff" +11906 "CJK Radical Second One" +11907 "CJK Radical Second Two" +11908 "CJK Radical Second Three" +11909 "CJK Radical Person" +11910 "CJK Radical Box" +11911 "CJK Radical Table" +11912 "CJK Radical Knife One" +11913 "CJK Radical Knife Two" +11914 "CJK Radical Divination" +11915 "CJK Radical Seal" +11916 "CJK Radical Small One" +11917 "CJK Radical Small Two" +11918 "CJK Radical Lame One" +11919 "CJK Radical Lame Two" +11920 "CJK Radical Lame Three" +11921 "CJK Radical Lame Four" +11922 "CJK Radical Snake" +11923 "CJK Radical Thread" +11924 "CJK Radical Snout One" +11925 "CJK Radical Snout Two" +11926 "CJK Radical Heart One" +11927 "CJK Radical Heart Two" +11928 "CJK Radical Hand" +11929 "CJK Radical Rap" +11931 "CJK Radical Choke" +11932 "CJK Radical Sun" +11933 "CJK Radical Moon" +11934 "CJK Radical Death" +11935 "CJK Radical Mother" +11936 "CJK Radical Civilian" +11937 "CJK Radical Water One" +11938 "CJK Radical Water Two" +11939 "CJK Radical Fire" +11940 "CJK Radical Paw One" +11941 "CJK Radical Paw Two" +11942 "CJK Radical Simplified Half Tree Trunk" +11943 "CJK Radical Cow" +11944 "CJK Radical Dog" +11945 "CJK Radical Jade" +11946 "CJK Radical Bolt Of Cloth" +11947 "CJK Radical Eye" +11948 "CJK Radical Spirit One" +11949 "CJK Radical Spirit Two" +11950 "CJK Radical Bamboo" +11951 "CJK Radical Silk" +11952 "CJK Radical C-Simplified Silk" +11953 "CJK Radical Net One" +11954 "CJK Radical Net Two" +11955 "CJK Radical Net Three" +11956 "CJK Radical Net Four" +11957 "CJK Radical Mesh" +11958 "CJK Radical Sheep" +11959 "CJK Radical Ram" +11960 "CJK Radical Ewe" +11961 "CJK Radical Old" +11962 "CJK Radical Brush One" +11963 "CJK Radical Brush Two" +11964 "CJK Radical Meat" +11965 "CJK Radical Mortar" +11966 "CJK Radical Grass One" +11967 "CJK Radical Grass Two" +11968 "CJK Radical Grass Three" +11969 "CJK Radical Tiger" +11970 "CJK Radical Clothes" +11971 "CJK Radical West One" +11972 "CJK Radical West Two" +11973 "CJK Radical C-Simplified See" +11974 "CJK Radical Simplified Horn" +11975 "CJK Radical Horn" +11976 "CJK Radical C-Simplified Speech" +11977 "CJK Radical C-Simplified Shell" +11978 "CJK Radical Foot" +11979 "CJK Radical C-Simplified Cart" +11980 "CJK Radical Simplified Walk" +11981 "CJK Radical Walk One" +11982 "CJK Radical Walk Two" +11983 "CJK Radical City" +11984 "CJK Radical C-Simplified Gold" +11985 "CJK Radical Long One" +11986 "CJK Radical Long Two" +11987 "CJK Radical C-Simplified Long" +11988 "CJK Radical C-Simplified Gate" +11989 "CJK Radical Mound One" +11990 "CJK Radical Mound Two" +11991 "CJK Radical Rain" +11992 "CJK Radical Blue" +11993 "CJK Radical C-Simplified Tanned Leather" +11994 "CJK Radical C-Simplified Leaf" +11995 "CJK Radical C-Simplified Wind" +11996 "CJK Radical C-Simplified Fly" +11997 "CJK Radical Eat One" +11998 "CJK Radical Eat Two" +11999 "CJK Radical Eat Three" +12000 "CJK Radical C-Simplified Eat" +12001 "CJK Radical Head" +12002 "CJK Radical C-Simplified Horse" +12003 "CJK Radical Bone" +12004 "CJK Radical Ghost" +12005 "CJK Radical C-Simplified Fish" +12006 "CJK Radical C-Simplified Bird" +12007 "CJK Radical C-Simplified Salt" +12008 "CJK Radical Simplified Wheat" +12009 "CJK Radical Simplified Yellow" +12010 "CJK Radical C-Simplified Frog" +12011 "CJK Radical J-Simplified Even" +12012 "CJK Radical C-Simplified Even" +12013 "CJK Radical J-Simplified Tooth" +12014 "CJK Radical C-Simplified Tooth" +12015 "CJK Radical J-Simplified Dragon" +12016 "CJK Radical C-Simplified Dragon" +12017 "CJK Radical Turtle" +12018 "CJK Radical J-Simplified Turtle" +12019 "CJK Radical C-Simplified Turtle" +12032 "Kangxi Radical One" +12033 "Kangxi Radical Line" +12034 "Kangxi Radical Dot" +12035 "Kangxi Radical Slash" +12036 "Kangxi Radical Second" +12037 "Kangxi Radical Hook" +12038 "Kangxi Radical Two" +12039 "Kangxi Radical Lid" +12040 "Kangxi Radical Man" +12041 "Kangxi Radical Legs" +12042 "Kangxi Radical Enter" +12043 "Kangxi Radical Eight" +12044 "Kangxi Radical Down Box" +12045 "Kangxi Radical Cover" +12046 "Kangxi Radical Ice" +12047 "Kangxi Radical Table" +12048 "Kangxi Radical Open Box" +12049 "Kangxi Radical Knife" +12050 "Kangxi Radical Power" +12051 "Kangxi Radical Wrap" +12052 "Kangxi Radical Spoon" +12053 "Kangxi Radical Right Open Box" +12054 "Kangxi Radical Hiding Enclosure" +12055 "Kangxi Radical Ten" +12056 "Kangxi Radical Divination" +12057 "Kangxi Radical Seal" +12058 "Kangxi Radical Cliff" +12059 "Kangxi Radical Private" +12060 "Kangxi Radical Again" +12061 "Kangxi Radical Mouth" +12062 "Kangxi Radical Enclosure" +12063 "Kangxi Radical Earth" +12064 "Kangxi Radical Scholar" +12065 "Kangxi Radical Go" +12066 "Kangxi Radical Go Slowly" +12067 "Kangxi Radical Evening" +12068 "Kangxi Radical Big" +12069 "Kangxi Radical Woman" +12070 "Kangxi Radical Child" +12071 "Kangxi Radical Roof" +12072 "Kangxi Radical Inch" +12073 "Kangxi Radical Small" +12074 "Kangxi Radical Lame" +12075 "Kangxi Radical Corpse" +12076 "Kangxi Radical Sprout" +12077 "Kangxi Radical Mountain" +12078 "Kangxi Radical River" +12079 "Kangxi Radical Work" +12080 "Kangxi Radical Oneself" +12081 "Kangxi Radical Turban" +12082 "Kangxi Radical Dry" +12083 "Kangxi Radical Short Thread" +12084 "Kangxi Radical Dotted Cliff" +12085 "Kangxi Radical Long Stride" +12086 "Kangxi Radical Two Hands" +12087 "Kangxi Radical Shoot" +12088 "Kangxi Radical Bow" +12089 "Kangxi Radical Snout" +12090 "Kangxi Radical Bristle" +12091 "Kangxi Radical Step" +12092 "Kangxi Radical Heart" +12093 "Kangxi Radical Halberd" +12094 "Kangxi Radical Door" +12095 "Kangxi Radical Hand" +12096 "Kangxi Radical Branch" +12097 "Kangxi Radical Rap" +12098 "Kangxi Radical Script" +12099 "Kangxi Radical Dipper" +12100 "Kangxi Radical Axe" +12101 "Kangxi Radical Square" +12102 "Kangxi Radical Not" +12103 "Kangxi Radical Sun" +12104 "Kangxi Radical Say" +12105 "Kangxi Radical Moon" +12106 "Kangxi Radical Tree" +12107 "Kangxi Radical Lack" +12108 "Kangxi Radical Stop" +12109 "Kangxi Radical Death" +12110 "Kangxi Radical Weapon" +12111 "Kangxi Radical Do Not" +12112 "Kangxi Radical Compare" +12113 "Kangxi Radical Fur" +12114 "Kangxi Radical Clan" +12115 "Kangxi Radical Steam" +12116 "Kangxi Radical Water" +12117 "Kangxi Radical Fire" +12118 "Kangxi Radical Claw" +12119 "Kangxi Radical Father" +12120 "Kangxi Radical Double X" +12121 "Kangxi Radical Half Tree Trunk" +12122 "Kangxi Radical Slice" +12123 "Kangxi Radical Fang" +12124 "Kangxi Radical Cow" +12125 "Kangxi Radical Dog" +12126 "Kangxi Radical Profound" +12127 "Kangxi Radical Jade" +12128 "Kangxi Radical Melon" +12129 "Kangxi Radical Tile" +12130 "Kangxi Radical Sweet" +12131 "Kangxi Radical Life" +12132 "Kangxi Radical Use" +12133 "Kangxi Radical Field" +12134 "Kangxi Radical Bolt Of Cloth" +12135 "Kangxi Radical Sickness" +12136 "Kangxi Radical Dotted Tent" +12137 "Kangxi Radical White" +12138 "Kangxi Radical Skin" +12139 "Kangxi Radical Dish" +12140 "Kangxi Radical Eye" +12141 "Kangxi Radical Spear" +12142 "Kangxi Radical Arrow" +12143 "Kangxi Radical Stone" +12144 "Kangxi Radical Spirit" +12145 "Kangxi Radical Track" +12146 "Kangxi Radical Grain" +12147 "Kangxi Radical Cave" +12148 "Kangxi Radical Stand" +12149 "Kangxi Radical Bamboo" +12150 "Kangxi Radical Rice" +12151 "Kangxi Radical Silk" +12152 "Kangxi Radical Jar" +12153 "Kangxi Radical Net" +12154 "Kangxi Radical Sheep" +12155 "Kangxi Radical Feather" +12156 "Kangxi Radical Old" +12157 "Kangxi Radical And" +12158 "Kangxi Radical Plow" +12159 "Kangxi Radical Ear" +12160 "Kangxi Radical Brush" +12161 "Kangxi Radical Meat" +12162 "Kangxi Radical Minister" +12163 "Kangxi Radical Self" +12164 "Kangxi Radical Arrive" +12165 "Kangxi Radical Mortar" +12166 "Kangxi Radical Tongue" +12167 "Kangxi Radical Oppose" +12168 "Kangxi Radical Boat" +12169 "Kangxi Radical Stopping" +12170 "Kangxi Radical Color" +12171 "Kangxi Radical Grass" +12172 "Kangxi Radical Tiger" +12173 "Kangxi Radical Insect" +12174 "Kangxi Radical Blood" +12175 "Kangxi Radical Walk Enclosure" +12176 "Kangxi Radical Clothes" +12177 "Kangxi Radical West" +12178 "Kangxi Radical See" +12179 "Kangxi Radical Horn" +12180 "Kangxi Radical Speech" +12181 "Kangxi Radical Valley" +12182 "Kangxi Radical Bean" +12183 "Kangxi Radical Pig" +12184 "Kangxi Radical Badger" +12185 "Kangxi Radical Shell" +12186 "Kangxi Radical Red" +12187 "Kangxi Radical Run" +12188 "Kangxi Radical Foot" +12189 "Kangxi Radical Body" +12190 "Kangxi Radical Cart" +12191 "Kangxi Radical Bitter" +12192 "Kangxi Radical Morning" +12193 "Kangxi Radical Walk" +12194 "Kangxi Radical City" +12195 "Kangxi Radical Wine" +12196 "Kangxi Radical Distinguish" +12197 "Kangxi Radical Village" +12198 "Kangxi Radical Gold" +12199 "Kangxi Radical Long" +12200 "Kangxi Radical Gate" +12201 "Kangxi Radical Mound" +12202 "Kangxi Radical Slave" +12203 "Kangxi Radical Short Tailed Bird" +12204 "Kangxi Radical Rain" +12205 "Kangxi Radical Blue" +12206 "Kangxi Radical Wrong" +12207 "Kangxi Radical Face" +12208 "Kangxi Radical Leather" +12209 "Kangxi Radical Tanned Leather" +12210 "Kangxi Radical Leek" +12211 "Kangxi Radical Sound" +12212 "Kangxi Radical Leaf" +12213 "Kangxi Radical Wind" +12214 "Kangxi Radical Fly" +12215 "Kangxi Radical Eat" +12216 "Kangxi Radical Head" +12217 "Kangxi Radical Fragrant" +12218 "Kangxi Radical Horse" +12219 "Kangxi Radical Bone" +12220 "Kangxi Radical Tall" +12221 "Kangxi Radical Hair" +12222 "Kangxi Radical Fight" +12223 "Kangxi Radical Sacrificial Wine" +12224 "Kangxi Radical Cauldron" +12225 "Kangxi Radical Ghost" +12226 "Kangxi Radical Fish" +12227 "Kangxi Radical Bird" +12228 "Kangxi Radical Salt" +12229 "Kangxi Radical Deer" +12230 "Kangxi Radical Wheat" +12231 "Kangxi Radical Hemp" +12232 "Kangxi Radical Yellow" +12233 "Kangxi Radical Millet" +12234 "Kangxi Radical Black" +12235 "Kangxi Radical Embroidery" +12236 "Kangxi Radical Frog" +12237 "Kangxi Radical Tripod" +12238 "Kangxi Radical Drum" +12239 "Kangxi Radical Rat" +12240 "Kangxi Radical Nose" +12241 "Kangxi Radical Even" +12242 "Kangxi Radical Tooth" +12243 "Kangxi Radical Dragon" +12244 "Kangxi Radical Turtle" +12245 "Kangxi Radical Flute" +12272 "Ideographic Description Character Left To Right" +12273 "Ideographic Description Character Above To Below" +12274 "Ideographic Description Character Left To Middle And Right" +12275 "Ideographic Description Character Above To Middle And Below" +12276 "Ideographic Description Character Full Surround" +12277 "Ideographic Description Character Surround From Above" +12278 "Ideographic Description Character Surround From Below" +12279 "Ideographic Description Character Surround From Left" +12280 "Ideographic Description Character Surround From Upper Left" +12281 "Ideographic Description Character Surround From Upper Right" +12282 "Ideographic Description Character Surround From Lower Left" +12283 "Ideographic Description Character Overlaid" +12288 "Ideographic Space" +12289 "Ideographic Comma" +12290 "Ideographic Full Stop" +12291 "Ditto Mark" +12292 "Japanese Industrial Standard Symbol" +12293 "Ideographic Iteration Mark" +12294 "Ideographic Closing Mark" +12295 "Ideographic Number Zero" +12296 "Left Angle Bracket" +12297 "Right Angle Bracket" +12298 "Left Double Angle Bracket" +12299 "Right Double Angle Bracket" +12300 "Left Corner Bracket" +12301 "Right Corner Bracket" +12302 "Left White Corner Bracket" +12303 "Right White Corner Bracket" +12304 "Left Black Lenticular Bracket" +12305 "Right Black Lenticular Bracket" +12306 "Postal Mark" +12307 "Geta Mark" +12308 "Left Tortoise Shell Bracket" +12309 "Right Tortoise Shell Bracket" +12310 "Left White Lenticular Bracket" +12311 "Right White Lenticular Bracket" +12312 "Left White Tortoise Shell Bracket" +12313 "Right White Tortoise Shell Bracket" +12314 "Left White Square Bracket" +12315 "Right White Square Bracket" +12316 "Wave Dash" +12317 "Reversed Double Prime Quotation Mark" +12318 "Double Prime Quotation Mark" +12319 "Low Double Prime Quotation Mark" +12320 "Postal Mark Face" +12321 "Hangzhou Numeral One" +12322 "Hangzhou Numeral Two" +12323 "Hangzhou Numeral Three" +12324 "Hangzhou Numeral Four" +12325 "Hangzhou Numeral Five" +12326 "Hangzhou Numeral Six" +12327 "Hangzhou Numeral Seven" +12328 "Hangzhou Numeral Eight" +12329 "Hangzhou Numeral Nine" +12330 "Ideographic Level Tone Mark" +12331 "Ideographic Rising Tone Mark" +12332 "Ideographic Departing Tone Mark" +12333 "Ideographic Entering Tone Mark" +12334 "Hangul Single Dot Tone Mark" +12335 "Hangul Double Dot Tone Mark" +12336 "Wavy Dash" +12337 "Vertical Kana Repeat Mark" +12338 "Vertical Kana Repeat With Voiced Sound Mark" +12339 "Vertical Kana Repeat Mark Upper Half" +12340 "Vertical Kana Repeat With Voiced Sound Mark Upper Half" +12341 "Vertical Kana Repeat Mark Lower Half" +12342 "Circled Postal Mark" +12343 "Ideographic Telegraph Line Feed Separator Symbol" +12344 "Hangzhou Numeral Ten" +12345 "Hangzhou Numeral Twenty" +12346 "Hangzhou Numeral Thirty" +12347 "Vertical Ideographic Iteration Mark" +12348 "Masu Mark" +12349 "Part Alternation Mark" +12350 "Ideographic Variation Indicator" +12351 "Ideographic Half Fill Space" +12353 "Hiragana Letter Small A" +12354 "Hiragana Letter A" +12355 "Hiragana Letter Small I" +12356 "Hiragana Letter I" +12357 "Hiragana Letter Small U" +12358 "Hiragana Letter U" +12359 "Hiragana Letter Small E" +12360 "Hiragana Letter E" +12361 "Hiragana Letter Small O" +12362 "Hiragana Letter O" +12363 "Hiragana Letter Ka" +12364 "Hiragana Letter Ga" +12365 "Hiragana Letter Ki" +12366 "Hiragana Letter Gi" +12367 "Hiragana Letter Ku" +12368 "Hiragana Letter Gu" +12369 "Hiragana Letter Ke" +12370 "Hiragana Letter Ge" +12371 "Hiragana Letter Ko" +12372 "Hiragana Letter Go" +12373 "Hiragana Letter Sa" +12374 "Hiragana Letter Za" +12375 "Hiragana Letter Si" +12376 "Hiragana Letter Zi" +12377 "Hiragana Letter Su" +12378 "Hiragana Letter Zu" +12379 "Hiragana Letter Se" +12380 "Hiragana Letter Ze" +12381 "Hiragana Letter So" +12382 "Hiragana Letter Zo" +12383 "Hiragana Letter Ta" +12384 "Hiragana Letter Da" +12385 "Hiragana Letter Ti" +12386 "Hiragana Letter Di" +12387 "Hiragana Letter Small Tu" +12388 "Hiragana Letter Tu" +12389 "Hiragana Letter Du" +12390 "Hiragana Letter Te" +12391 "Hiragana Letter De" +12392 "Hiragana Letter To" +12393 "Hiragana Letter Do" +12394 "Hiragana Letter Na" +12395 "Hiragana Letter Ni" +12396 "Hiragana Letter Nu" +12397 "Hiragana Letter Ne" +12398 "Hiragana Letter No" +12399 "Hiragana Letter Ha" +12400 "Hiragana Letter Ba" +12401 "Hiragana Letter Pa" +12402 "Hiragana Letter Hi" +12403 "Hiragana Letter Bi" +12404 "Hiragana Letter Pi" +12405 "Hiragana Letter Hu" +12406 "Hiragana Letter Bu" +12407 "Hiragana Letter Pu" +12408 "Hiragana Letter He" +12409 "Hiragana Letter Be" +12410 "Hiragana Letter Pe" +12411 "Hiragana Letter Ho" +12412 "Hiragana Letter Bo" +12413 "Hiragana Letter Po" +12414 "Hiragana Letter Ma" +12415 "Hiragana Letter Mi" +12416 "Hiragana Letter Mu" +12417 "Hiragana Letter Me" +12418 "Hiragana Letter Mo" +12419 "Hiragana Letter Small Ya" +12420 "Hiragana Letter Ya" +12421 "Hiragana Letter Small Yu" +12422 "Hiragana Letter Yu" +12423 "Hiragana Letter Small Yo" +12424 "Hiragana Letter Yo" +12425 "Hiragana Letter Ra" +12426 "Hiragana Letter Ri" +12427 "Hiragana Letter Ru" +12428 "Hiragana Letter Re" +12429 "Hiragana Letter Ro" +12430 "Hiragana Letter Small Wa" +12431 "Hiragana Letter Wa" +12432 "Hiragana Letter Wi" +12433 "Hiragana Letter We" +12434 "Hiragana Letter Wo" +12435 "Hiragana Letter N" +12436 "Hiragana Letter Vu" +12437 "Hiragana Letter Small Ka" +12438 "Hiragana Letter Small Ke" +12441 "Combining Katakana-Hiragana Voiced Sound Mark" +12442 "Combining Katakana-Hiragana Semi-Voiced Sound Mark" +12443 "Katakana-Hiragana Voiced Sound Mark" +12444 "Katakana-Hiragana Semi-Voiced Sound Mark" +12445 "Hiragana Iteration Mark" +12446 "Hiragana Voiced Iteration Mark" +12447 "Hiragana Digraph Yori" +12448 "Katakana-Hiragana Double Hyphen" +12449 "Katakana Letter Small A" +12450 "Katakana Letter A" +12451 "Katakana Letter Small I" +12452 "Katakana Letter I" +12453 "Katakana Letter Small U" +12454 "Katakana Letter U" +12455 "Katakana Letter Small E" +12456 "Katakana Letter E" +12457 "Katakana Letter Small O" +12458 "Katakana Letter O" +12459 "Katakana Letter Ka" +12460 "Katakana Letter Ga" +12461 "Katakana Letter Ki" +12462 "Katakana Letter Gi" +12463 "Katakana Letter Ku" +12464 "Katakana Letter Gu" +12465 "Katakana Letter Ke" +12466 "Katakana Letter Ge" +12467 "Katakana Letter Ko" +12468 "Katakana Letter Go" +12469 "Katakana Letter Sa" +12470 "Katakana Letter Za" +12471 "Katakana Letter Si" +12472 "Katakana Letter Zi" +12473 "Katakana Letter Su" +12474 "Katakana Letter Zu" +12475 "Katakana Letter Se" +12476 "Katakana Letter Ze" +12477 "Katakana Letter So" +12478 "Katakana Letter Zo" +12479 "Katakana Letter Ta" +12480 "Katakana Letter Da" +12481 "Katakana Letter Ti" +12482 "Katakana Letter Di" +12483 "Katakana Letter Small Tu" +12484 "Katakana Letter Tu" +12485 "Katakana Letter Du" +12486 "Katakana Letter Te" +12487 "Katakana Letter De" +12488 "Katakana Letter To" +12489 "Katakana Letter Do" +12490 "Katakana Letter Na" +12491 "Katakana Letter Ni" +12492 "Katakana Letter Nu" +12493 "Katakana Letter Ne" +12494 "Katakana Letter No" +12495 "Katakana Letter Ha" +12496 "Katakana Letter Ba" +12497 "Katakana Letter Pa" +12498 "Katakana Letter Hi" +12499 "Katakana Letter Bi" +12500 "Katakana Letter Pi" +12501 "Katakana Letter Hu" +12502 "Katakana Letter Bu" +12503 "Katakana Letter Pu" +12504 "Katakana Letter He" +12505 "Katakana Letter Be" +12506 "Katakana Letter Pe" +12507 "Katakana Letter Ho" +12508 "Katakana Letter Bo" +12509 "Katakana Letter Po" +12510 "Katakana Letter Ma" +12511 "Katakana Letter Mi" +12512 "Katakana Letter Mu" +12513 "Katakana Letter Me" +12514 "Katakana Letter Mo" +12515 "Katakana Letter Small Ya" +12516 "Katakana Letter Ya" +12517 "Katakana Letter Small Yu" +12518 "Katakana Letter Yu" +12519 "Katakana Letter Small Yo" +12520 "Katakana Letter Yo" +12521 "Katakana Letter Ra" +12522 "Katakana Letter Ri" +12523 "Katakana Letter Ru" +12524 "Katakana Letter Re" +12525 "Katakana Letter Ro" +12526 "Katakana Letter Small Wa" +12527 "Katakana Letter Wa" +12528 "Katakana Letter Wi" +12529 "Katakana Letter We" +12530 "Katakana Letter Wo" +12531 "Katakana Letter N" +12532 "Katakana Letter Vu" +12533 "Katakana Letter Small Ka" +12534 "Katakana Letter Small Ke" +12535 "Katakana Letter Va" +12536 "Katakana Letter Vi" +12537 "Katakana Letter Ve" +12538 "Katakana Letter Vo" +12539 "Katakana Middle Dot" +12540 "Katakana-Hiragana Prolonged Sound Mark" +12541 "Katakana Iteration Mark" +12542 "Katakana Voiced Iteration Mark" +12543 "Katakana Digraph Koto" +12549 "Bopomofo Letter B" +12550 "Bopomofo Letter P" +12551 "Bopomofo Letter M" +12552 "Bopomofo Letter F" +12553 "Bopomofo Letter D" +12554 "Bopomofo Letter T" +12555 "Bopomofo Letter N" +12556 "Bopomofo Letter L" +12557 "Bopomofo Letter G" +12558 "Bopomofo Letter K" +12559 "Bopomofo Letter H" +12560 "Bopomofo Letter J" +12561 "Bopomofo Letter Q" +12562 "Bopomofo Letter X" +12563 "Bopomofo Letter Zh" +12564 "Bopomofo Letter Ch" +12565 "Bopomofo Letter Sh" +12566 "Bopomofo Letter R" +12567 "Bopomofo Letter Z" +12568 "Bopomofo Letter C" +12569 "Bopomofo Letter S" +12570 "Bopomofo Letter A" +12571 "Bopomofo Letter O" +12572 "Bopomofo Letter E" +12573 "Bopomofo Letter Eh" +12574 "Bopomofo Letter Ai" +12575 "Bopomofo Letter Ei" +12576 "Bopomofo Letter Au" +12577 "Bopomofo Letter Ou" +12578 "Bopomofo Letter An" +12579 "Bopomofo Letter En" +12580 "Bopomofo Letter Ang" +12581 "Bopomofo Letter Eng" +12582 "Bopomofo Letter Er" +12583 "Bopomofo Letter I" +12584 "Bopomofo Letter U" +12585 "Bopomofo Letter Iu" +12586 "Bopomofo Letter V" +12587 "Bopomofo Letter Ng" +12588 "Bopomofo Letter Gn" +12589 "Bopomofo Letter Ih" +12593 "Hangul Letter Kiyeok" +12594 "Hangul Letter Ssangkiyeok" +12595 "Hangul Letter Kiyeok-Sios" +12596 "Hangul Letter Nieun" +12597 "Hangul Letter Nieun-Cieuc" +12598 "Hangul Letter Nieun-Hieuh" +12599 "Hangul Letter Tikeut" +12600 "Hangul Letter Ssangtikeut" +12601 "Hangul Letter Rieul" +12602 "Hangul Letter Rieul-Kiyeok" +12603 "Hangul Letter Rieul-Mieum" +12604 "Hangul Letter Rieul-Pieup" +12605 "Hangul Letter Rieul-Sios" +12606 "Hangul Letter Rieul-Thieuth" +12607 "Hangul Letter Rieul-Phieuph" +12608 "Hangul Letter Rieul-Hieuh" +12609 "Hangul Letter Mieum" +12610 "Hangul Letter Pieup" +12611 "Hangul Letter Ssangpieup" +12612 "Hangul Letter Pieup-Sios" +12613 "Hangul Letter Sios" +12614 "Hangul Letter Ssangsios" +12615 "Hangul Letter Ieung" +12616 "Hangul Letter Cieuc" +12617 "Hangul Letter Ssangcieuc" +12618 "Hangul Letter Chieuch" +12619 "Hangul Letter Khieukh" +12620 "Hangul Letter Thieuth" +12621 "Hangul Letter Phieuph" +12622 "Hangul Letter Hieuh" +12623 "Hangul Letter A" +12624 "Hangul Letter Ae" +12625 "Hangul Letter Ya" +12626 "Hangul Letter Yae" +12627 "Hangul Letter Eo" +12628 "Hangul Letter E" +12629 "Hangul Letter Yeo" +12630 "Hangul Letter Ye" +12631 "Hangul Letter O" +12632 "Hangul Letter Wa" +12633 "Hangul Letter Wae" +12634 "Hangul Letter Oe" +12635 "Hangul Letter Yo" +12636 "Hangul Letter U" +12637 "Hangul Letter Weo" +12638 "Hangul Letter We" +12639 "Hangul Letter Wi" +12640 "Hangul Letter Yu" +12641 "Hangul Letter Eu" +12642 "Hangul Letter Yi" +12643 "Hangul Letter I" +12644 "Hangul Filler" +12645 "Hangul Letter Ssangnieun" +12646 "Hangul Letter Nieun-Tikeut" +12647 "Hangul Letter Nieun-Sios" +12648 "Hangul Letter Nieun-Pansios" +12649 "Hangul Letter Rieul-Kiyeok-Sios" +12650 "Hangul Letter Rieul-Tikeut" +12651 "Hangul Letter Rieul-Pieup-Sios" +12652 "Hangul Letter Rieul-Pansios" +12653 "Hangul Letter Rieul-Yeorinhieuh" +12654 "Hangul Letter Mieum-Pieup" +12655 "Hangul Letter Mieum-Sios" +12656 "Hangul Letter Mieum-Pansios" +12657 "Hangul Letter Kapyeounmieum" +12658 "Hangul Letter Pieup-Kiyeok" +12659 "Hangul Letter Pieup-Tikeut" +12660 "Hangul Letter Pieup-Sios-Kiyeok" +12661 "Hangul Letter Pieup-Sios-Tikeut" +12662 "Hangul Letter Pieup-Cieuc" +12663 "Hangul Letter Pieup-Thieuth" +12664 "Hangul Letter Kapyeounpieup" +12665 "Hangul Letter Kapyeounssangpieup" +12666 "Hangul Letter Sios-Kiyeok" +12667 "Hangul Letter Sios-Nieun" +12668 "Hangul Letter Sios-Tikeut" +12669 "Hangul Letter Sios-Pieup" +12670 "Hangul Letter Sios-Cieuc" +12671 "Hangul Letter Pansios" +12672 "Hangul Letter Ssangieung" +12673 "Hangul Letter Yesieung" +12674 "Hangul Letter Yesieung-Sios" +12675 "Hangul Letter Yesieung-Pansios" +12676 "Hangul Letter Kapyeounphieuph" +12677 "Hangul Letter Ssanghieuh" +12678 "Hangul Letter Yeorinhieuh" +12679 "Hangul Letter Yo-Ya" +12680 "Hangul Letter Yo-Yae" +12681 "Hangul Letter Yo-I" +12682 "Hangul Letter Yu-Yeo" +12683 "Hangul Letter Yu-Ye" +12684 "Hangul Letter Yu-I" +12685 "Hangul Letter Araea" +12686 "Hangul Letter Araeae" +12688 "Ideographic Annotation Linking Mark" +12689 "Ideographic Annotation Reverse Mark" +12690 "Ideographic Annotation One Mark" +12691 "Ideographic Annotation Two Mark" +12692 "Ideographic Annotation Three Mark" +12693 "Ideographic Annotation Four Mark" +12694 "Ideographic Annotation Top Mark" +12695 "Ideographic Annotation Middle Mark" +12696 "Ideographic Annotation Bottom Mark" +12697 "Ideographic Annotation First Mark" +12698 "Ideographic Annotation Second Mark" +12699 "Ideographic Annotation Third Mark" +12700 "Ideographic Annotation Fourth Mark" +12701 "Ideographic Annotation Heaven Mark" +12702 "Ideographic Annotation Earth Mark" +12703 "Ideographic Annotation Man Mark" +12704 "Bopomofo Letter Bu" +12705 "Bopomofo Letter Zi" +12706 "Bopomofo Letter Ji" +12707 "Bopomofo Letter Gu" +12708 "Bopomofo Letter Ee" +12709 "Bopomofo Letter Enn" +12710 "Bopomofo Letter Oo" +12711 "Bopomofo Letter Onn" +12712 "Bopomofo Letter Ir" +12713 "Bopomofo Letter Ann" +12714 "Bopomofo Letter Inn" +12715 "Bopomofo Letter Unn" +12716 "Bopomofo Letter Im" +12717 "Bopomofo Letter Ngg" +12718 "Bopomofo Letter Ainn" +12719 "Bopomofo Letter Aunn" +12720 "Bopomofo Letter Am" +12721 "Bopomofo Letter Om" +12722 "Bopomofo Letter Ong" +12723 "Bopomofo Letter Innn" +12724 "Bopomofo Final Letter P" +12725 "Bopomofo Final Letter T" +12726 "Bopomofo Final Letter K" +12727 "Bopomofo Final Letter H" +12728 "Bopomofo Letter Gh" +12729 "Bopomofo Letter Lh" +12730 "Bopomofo Letter Zy" +12736 "CJK Stroke T" +12737 "CJK Stroke Wg" +12738 "CJK Stroke Xg" +12739 "CJK Stroke Bxg" +12740 "CJK Stroke Sw" +12741 "CJK Stroke Hzz" +12742 "CJK Stroke Hzg" +12743 "CJK Stroke Hp" +12744 "CJK Stroke Hzwg" +12745 "CJK Stroke Szwg" +12746 "CJK Stroke Hzt" +12747 "CJK Stroke Hzzp" +12748 "CJK Stroke Hpwg" +12749 "CJK Stroke Hzw" +12750 "CJK Stroke Hzzz" +12751 "CJK Stroke N" +12752 "CJK Stroke H" +12753 "CJK Stroke S" +12754 "CJK Stroke P" +12755 "CJK Stroke Sp" +12756 "CJK Stroke D" +12757 "CJK Stroke Hz" +12758 "CJK Stroke Hg" +12759 "CJK Stroke Sz" +12760 "CJK Stroke Swz" +12761 "CJK Stroke St" +12762 "CJK Stroke Sg" +12763 "CJK Stroke Pd" +12764 "CJK Stroke Pz" +12765 "CJK Stroke Tn" +12766 "CJK Stroke Szz" +12767 "CJK Stroke Swg" +12768 "CJK Stroke Hxwg" +12769 "CJK Stroke Hzzzg" +12770 "CJK Stroke Pg" +12771 "CJK Stroke Q" +12784 "Katakana Letter Small Ku" +12785 "Katakana Letter Small Si" +12786 "Katakana Letter Small Su" +12787 "Katakana Letter Small To" +12788 "Katakana Letter Small Nu" +12789 "Katakana Letter Small Ha" +12790 "Katakana Letter Small Hi" +12791 "Katakana Letter Small Hu" +12792 "Katakana Letter Small He" +12793 "Katakana Letter Small Ho" +12794 "Katakana Letter Small Mu" +12795 "Katakana Letter Small Ra" +12796 "Katakana Letter Small Ri" +12797 "Katakana Letter Small Ru" +12798 "Katakana Letter Small Re" +12799 "Katakana Letter Small Ro" +12800 "Parenthesized Hangul Kiyeok" +12801 "Parenthesized Hangul Nieun" +12802 "Parenthesized Hangul Tikeut" +12803 "Parenthesized Hangul Rieul" +12804 "Parenthesized Hangul Mieum" +12805 "Parenthesized Hangul Pieup" +12806 "Parenthesized Hangul Sios" +12807 "Parenthesized Hangul Ieung" +12808 "Parenthesized Hangul Cieuc" +12809 "Parenthesized Hangul Chieuch" +12810 "Parenthesized Hangul Khieukh" +12811 "Parenthesized Hangul Thieuth" +12812 "Parenthesized Hangul Phieuph" +12813 "Parenthesized Hangul Hieuh" +12814 "Parenthesized Hangul Kiyeok A" +12815 "Parenthesized Hangul Nieun A" +12816 "Parenthesized Hangul Tikeut A" +12817 "Parenthesized Hangul Rieul A" +12818 "Parenthesized Hangul Mieum A" +12819 "Parenthesized Hangul Pieup A" +12820 "Parenthesized Hangul Sios A" +12821 "Parenthesized Hangul Ieung A" +12822 "Parenthesized Hangul Cieuc A" +12823 "Parenthesized Hangul Chieuch A" +12824 "Parenthesized Hangul Khieukh A" +12825 "Parenthesized Hangul Thieuth A" +12826 "Parenthesized Hangul Phieuph A" +12827 "Parenthesized Hangul Hieuh A" +12828 "Parenthesized Hangul Cieuc U" +12829 "Parenthesized Korean Character Ojeon" +12830 "Parenthesized Korean Character O Hu" +12832 "Parenthesized Ideograph One" +12833 "Parenthesized Ideograph Two" +12834 "Parenthesized Ideograph Three" +12835 "Parenthesized Ideograph Four" +12836 "Parenthesized Ideograph Five" +12837 "Parenthesized Ideograph Six" +12838 "Parenthesized Ideograph Seven" +12839 "Parenthesized Ideograph Eight" +12840 "Parenthesized Ideograph Nine" +12841 "Parenthesized Ideograph Ten" +12842 "Parenthesized Ideograph Moon" +12843 "Parenthesized Ideograph Fire" +12844 "Parenthesized Ideograph Water" +12845 "Parenthesized Ideograph Wood" +12846 "Parenthesized Ideograph Metal" +12847 "Parenthesized Ideograph Earth" +12848 "Parenthesized Ideograph Sun" +12849 "Parenthesized Ideograph Stock" +12850 "Parenthesized Ideograph Have" +12851 "Parenthesized Ideograph Society" +12852 "Parenthesized Ideograph Name" +12853 "Parenthesized Ideograph Special" +12854 "Parenthesized Ideograph Financial" +12855 "Parenthesized Ideograph Congratulation" +12856 "Parenthesized Ideograph Labor" +12857 "Parenthesized Ideograph Represent" +12858 "Parenthesized Ideograph Call" +12859 "Parenthesized Ideograph Study" +12860 "Parenthesized Ideograph Supervise" +12861 "Parenthesized Ideograph Enterprise" +12862 "Parenthesized Ideograph Resource" +12863 "Parenthesized Ideograph Alliance" +12864 "Parenthesized Ideograph Festival" +12865 "Parenthesized Ideograph Rest" +12866 "Parenthesized Ideograph Self" +12867 "Parenthesized Ideograph Reach" +12868 "Circled Ideograph Question" +12869 "Circled Ideograph Kindergarten" +12870 "Circled Ideograph School" +12871 "Circled Ideograph Koto" +12872 "Circled Number Ten On Black Square" +12873 "Circled Number Twenty On Black Square" +12874 "Circled Number Thirty On Black Square" +12875 "Circled Number Forty On Black Square" +12876 "Circled Number Fifty On Black Square" +12877 "Circled Number Sixty On Black Square" +12878 "Circled Number Seventy On Black Square" +12879 "Circled Number Eighty On Black Square" +12880 "Partnership Sign" +12881 "Circled Number Twenty One" +12882 "Circled Number Twenty Two" +12883 "Circled Number Twenty Three" +12884 "Circled Number Twenty Four" +12885 "Circled Number Twenty Five" +12886 "Circled Number Twenty Six" +12887 "Circled Number Twenty Seven" +12888 "Circled Number Twenty Eight" +12889 "Circled Number Twenty Nine" +12890 "Circled Number Thirty" +12891 "Circled Number Thirty One" +12892 "Circled Number Thirty Two" +12893 "Circled Number Thirty Three" +12894 "Circled Number Thirty Four" +12895 "Circled Number Thirty Five" +12896 "Circled Hangul Kiyeok" +12897 "Circled Hangul Nieun" +12898 "Circled Hangul Tikeut" +12899 "Circled Hangul Rieul" +12900 "Circled Hangul Mieum" +12901 "Circled Hangul Pieup" +12902 "Circled Hangul Sios" +12903 "Circled Hangul Ieung" +12904 "Circled Hangul Cieuc" +12905 "Circled Hangul Chieuch" +12906 "Circled Hangul Khieukh" +12907 "Circled Hangul Thieuth" +12908 "Circled Hangul Phieuph" +12909 "Circled Hangul Hieuh" +12910 "Circled Hangul Kiyeok A" +12911 "Circled Hangul Nieun A" +12912 "Circled Hangul Tikeut A" +12913 "Circled Hangul Rieul A" +12914 "Circled Hangul Mieum A" +12915 "Circled Hangul Pieup A" +12916 "Circled Hangul Sios A" +12917 "Circled Hangul Ieung A" +12918 "Circled Hangul Cieuc A" +12919 "Circled Hangul Chieuch A" +12920 "Circled Hangul Khieukh A" +12921 "Circled Hangul Thieuth A" +12922 "Circled Hangul Phieuph A" +12923 "Circled Hangul Hieuh A" +12924 "Circled Korean Character Chamko" +12925 "Circled Korean Character Jueui" +12926 "Circled Hangul Ieung U" +12927 "Korean Standard Symbol" +12928 "Circled Ideograph One" +12929 "Circled Ideograph Two" +12930 "Circled Ideograph Three" +12931 "Circled Ideograph Four" +12932 "Circled Ideograph Five" +12933 "Circled Ideograph Six" +12934 "Circled Ideograph Seven" +12935 "Circled Ideograph Eight" +12936 "Circled Ideograph Nine" +12937 "Circled Ideograph Ten" +12938 "Circled Ideograph Moon" +12939 "Circled Ideograph Fire" +12940 "Circled Ideograph Water" +12941 "Circled Ideograph Wood" +12942 "Circled Ideograph Metal" +12943 "Circled Ideograph Earth" +12944 "Circled Ideograph Sun" +12945 "Circled Ideograph Stock" +12946 "Circled Ideograph Have" +12947 "Circled Ideograph Society" +12948 "Circled Ideograph Name" +12949 "Circled Ideograph Special" +12950 "Circled Ideograph Financial" +12951 "Circled Ideograph Congratulation" +12952 "Circled Ideograph Labor" +12953 "Circled Ideograph Secret" +12954 "Circled Ideograph Male" +12955 "Circled Ideograph Female" +12956 "Circled Ideograph Suitable" +12957 "Circled Ideograph Excellent" +12958 "Circled Ideograph Print" +12959 "Circled Ideograph Attention" +12960 "Circled Ideograph Item" +12961 "Circled Ideograph Rest" +12962 "Circled Ideograph Copy" +12963 "Circled Ideograph Correct" +12964 "Circled Ideograph High" +12965 "Circled Ideograph Centre" +12966 "Circled Ideograph Low" +12967 "Circled Ideograph Left" +12968 "Circled Ideograph Right" +12969 "Circled Ideograph Medicine" +12970 "Circled Ideograph Religion" +12971 "Circled Ideograph Study" +12972 "Circled Ideograph Supervise" +12973 "Circled Ideograph Enterprise" +12974 "Circled Ideograph Resource" +12975 "Circled Ideograph Alliance" +12976 "Circled Ideograph Night" +12977 "Circled Number Thirty Six" +12978 "Circled Number Thirty Seven" +12979 "Circled Number Thirty Eight" +12980 "Circled Number Thirty Nine" +12981 "Circled Number Forty" +12982 "Circled Number Forty One" +12983 "Circled Number Forty Two" +12984 "Circled Number Forty Three" +12985 "Circled Number Forty Four" +12986 "Circled Number Forty Five" +12987 "Circled Number Forty Six" +12988 "Circled Number Forty Seven" +12989 "Circled Number Forty Eight" +12990 "Circled Number Forty Nine" +12991 "Circled Number Fifty" +12992 "Ideographic Telegraph Symbol For January" +12993 "Ideographic Telegraph Symbol For February" +12994 "Ideographic Telegraph Symbol For March" +12995 "Ideographic Telegraph Symbol For April" +12996 "Ideographic Telegraph Symbol For May" +12997 "Ideographic Telegraph Symbol For June" +12998 "Ideographic Telegraph Symbol For July" +12999 "Ideographic Telegraph Symbol For August" +13000 "Ideographic Telegraph Symbol For September" +13001 "Ideographic Telegraph Symbol For October" +13002 "Ideographic Telegraph Symbol For November" +13003 "Ideographic Telegraph Symbol For December" +13004 "Square Hg" +13005 "Square Erg" +13006 "Square Ev" +13007 "Limited Liability Sign" +13008 "Circled Katakana A" +13009 "Circled Katakana I" +13010 "Circled Katakana U" +13011 "Circled Katakana E" +13012 "Circled Katakana O" +13013 "Circled Katakana Ka" +13014 "Circled Katakana Ki" +13015 "Circled Katakana Ku" +13016 "Circled Katakana Ke" +13017 "Circled Katakana Ko" +13018 "Circled Katakana Sa" +13019 "Circled Katakana Si" +13020 "Circled Katakana Su" +13021 "Circled Katakana Se" +13022 "Circled Katakana So" +13023 "Circled Katakana Ta" +13024 "Circled Katakana Ti" +13025 "Circled Katakana Tu" +13026 "Circled Katakana Te" +13027 "Circled Katakana To" +13028 "Circled Katakana Na" +13029 "Circled Katakana Ni" +13030 "Circled Katakana Nu" +13031 "Circled Katakana Ne" +13032 "Circled Katakana No" +13033 "Circled Katakana Ha" +13034 "Circled Katakana Hi" +13035 "Circled Katakana Hu" +13036 "Circled Katakana He" +13037 "Circled Katakana Ho" +13038 "Circled Katakana Ma" +13039 "Circled Katakana Mi" +13040 "Circled Katakana Mu" +13041 "Circled Katakana Me" +13042 "Circled Katakana Mo" +13043 "Circled Katakana Ya" +13044 "Circled Katakana Yu" +13045 "Circled Katakana Yo" +13046 "Circled Katakana Ra" +13047 "Circled Katakana Ri" +13048 "Circled Katakana Ru" +13049 "Circled Katakana Re" +13050 "Circled Katakana Ro" +13051 "Circled Katakana Wa" +13052 "Circled Katakana Wi" +13053 "Circled Katakana We" +13054 "Circled Katakana Wo" +13056 "Square Apaato" +13057 "Square Aruhua" +13058 "Square Anpea" +13059 "Square Aaru" +13060 "Square Iningu" +13061 "Square Inti" +13062 "Square Uon" +13063 "Square Esukuudo" +13064 "Square Eekaa" +13065 "Square Onsu" +13066 "Square Oomu" +13067 "Square Kairi" +13068 "Square Karatto" +13069 "Square Karorii" +13070 "Square Garon" +13071 "Square Ganma" +13072 "Square Giga" +13073 "Square Ginii" +13074 "Square Kyurii" +13075 "Square Girudaa" +13076 "Square Kiro" +13077 "Square Kiroguramu" +13078 "Square Kiromeetoru" +13079 "Square Kirowatto" +13080 "Square Guramu" +13081 "Square Guramuton" +13082 "Square Kuruzeiro" +13083 "Square Kuroone" +13084 "Square Keesu" +13085 "Square Koruna" +13086 "Square Koopo" +13087 "Square Saikuru" +13088 "Square Santiimu" +13089 "Square Siringu" +13090 "Square Senti" +13091 "Square Sento" +13092 "Square Daasu" +13093 "Square Desi" +13094 "Square Doru" +13095 "Square Ton" +13096 "Square Nano" +13097 "Square Notto" +13098 "Square Haitu" +13099 "Square Paasento" +13100 "Square Paatu" +13101 "Square Baareru" +13102 "Square Piasutoru" +13103 "Square Pikuru" +13104 "Square Piko" +13105 "Square Biru" +13106 "Square Huaraddo" +13107 "Square Huiito" +13108 "Square Bussyeru" +13109 "Square Huran" +13110 "Square Hekutaaru" +13111 "Square Peso" +13112 "Square Penihi" +13113 "Square Herutu" +13114 "Square Pensu" +13115 "Square Peezi" +13116 "Square Beeta" +13117 "Square Pointo" +13118 "Square Boruto" +13119 "Square Hon" +13120 "Square Pondo" +13121 "Square Hooru" +13122 "Square Hoon" +13123 "Square Maikuro" +13124 "Square Mairu" +13125 "Square Mahha" +13126 "Square Maruku" +13127 "Square Mansyon" +13128 "Square Mikuron" +13129 "Square Miri" +13130 "Square Miribaaru" +13131 "Square Mega" +13132 "Square Megaton" +13133 "Square Meetoru" +13134 "Square Yaado" +13135 "Square Yaaru" +13136 "Square Yuan" +13137 "Square Rittoru" +13138 "Square Rira" +13139 "Square Rupii" +13140 "Square Ruuburu" +13141 "Square Remu" +13142 "Square Rentogen" +13143 "Square Watto" +13144 "Ideographic Telegraph Symbol For Hour Zero" +13145 "Ideographic Telegraph Symbol For Hour One" +13146 "Ideographic Telegraph Symbol For Hour Two" +13147 "Ideographic Telegraph Symbol For Hour Three" +13148 "Ideographic Telegraph Symbol For Hour Four" +13149 "Ideographic Telegraph Symbol For Hour Five" +13150 "Ideographic Telegraph Symbol For Hour Six" +13151 "Ideographic Telegraph Symbol For Hour Seven" +13152 "Ideographic Telegraph Symbol For Hour Eight" +13153 "Ideographic Telegraph Symbol For Hour Nine" +13154 "Ideographic Telegraph Symbol For Hour Ten" +13155 "Ideographic Telegraph Symbol For Hour Eleven" +13156 "Ideographic Telegraph Symbol For Hour Twelve" +13157 "Ideographic Telegraph Symbol For Hour Thirteen" +13158 "Ideographic Telegraph Symbol For Hour Fourteen" +13159 "Ideographic Telegraph Symbol For Hour Fifteen" +13160 "Ideographic Telegraph Symbol For Hour Sixteen" +13161 "Ideographic Telegraph Symbol For Hour Seventeen" +13162 "Ideographic Telegraph Symbol For Hour Eighteen" +13163 "Ideographic Telegraph Symbol For Hour Nineteen" +13164 "Ideographic Telegraph Symbol For Hour Twenty" +13165 "Ideographic Telegraph Symbol For Hour Twenty-One" +13166 "Ideographic Telegraph Symbol For Hour Twenty-Two" +13167 "Ideographic Telegraph Symbol For Hour Twenty-Three" +13168 "Ideographic Telegraph Symbol For Hour Twenty-Four" +13169 "Square Hpa" +13170 "Square Da" +13171 "Square Au" +13172 "Square Bar" +13173 "Square Ov" +13174 "Square Pc" +13175 "Square Dm" +13176 "Square Dm Squared" +13177 "Square Dm Cubed" +13178 "Square Iu" +13179 "Square Era Name Heisei" +13180 "Square Era Name Syouwa" +13181 "Square Era Name Taisyou" +13182 "Square Era Name Meizi" +13183 "Square Corporation" +13184 "Square Pa Amps" +13185 "Square Na" +13186 "Square Mu A" +13187 "Square Ma" +13188 "Square Ka" +13189 "Square Kb" +13190 "Square Mb" +13191 "Square Gb" +13192 "Square Cal" +13193 "Square Kcal" +13194 "Square Pf" +13195 "Square Nf" +13196 "Square Mu F" +13197 "Square Mu G" +13198 "Square Mg" +13199 "Square Kg" +13200 "Square Hz" +13201 "Square Khz" +13202 "Square Mhz" +13203 "Square Ghz" +13204 "Square Thz" +13205 "Square Mu L" +13206 "Square Ml" +13207 "Square Dl" +13208 "Square Kl" +13209 "Square Fm" +13210 "Square Nm" +13211 "Square Mu M" +13212 "Square Mm" +13213 "Square Cm" +13214 "Square Km" +13215 "Square Mm Squared" +13216 "Square Cm Squared" +13217 "Square M Squared" +13218 "Square Km Squared" +13219 "Square Mm Cubed" +13220 "Square Cm Cubed" +13221 "Square M Cubed" +13222 "Square Km Cubed" +13223 "Square M Over S" +13224 "Square M Over S Squared" +13225 "Square Pa" +13226 "Square Kpa" +13227 "Square Mpa" +13228 "Square Gpa" +13229 "Square Rad" +13230 "Square Rad Over S" +13231 "Square Rad Over S Squared" +13232 "Square Ps" +13233 "Square Ns" +13234 "Square Mu S" +13235 "Square Ms" +13236 "Square Pv" +13237 "Square Nv" +13238 "Square Mu V" +13239 "Square Mv" +13240 "Square Kv" +13241 "Square Mv Mega" +13242 "Square Pw" +13243 "Square Nw" +13244 "Square Mu W" +13245 "Square Mw" +13246 "Square Kw" +13247 "Square Mw Mega" +13248 "Square K Ohm" +13249 "Square M Ohm" +13250 "Square Am" +13251 "Square Bq" +13252 "Square Cc" +13253 "Square Cd" +13254 "Square C Over Kg" +13255 "Square Co" +13256 "Square Db" +13257 "Square Gy" +13258 "Square Ha" +13259 "Square Hp" +13260 "Square In" +13261 "Square Kk" +13262 "Square Km Capital" +13263 "Square Kt" +13264 "Square Lm" +13265 "Square Ln" +13266 "Square Log" +13267 "Square Lx" +13268 "Square Mb Small" +13269 "Square Mil" +13270 "Square Mol" +13271 "Square Ph" +13272 "Square Pm" +13273 "Square Ppm" +13274 "Square Pr" +13275 "Square Sr" +13276 "Square Sv" +13277 "Square Wb" +13278 "Square V Over M" +13279 "Square A Over M" +13280 "Ideographic Telegraph Symbol For Day One" +13281 "Ideographic Telegraph Symbol For Day Two" +13282 "Ideographic Telegraph Symbol For Day Three" +13283 "Ideographic Telegraph Symbol For Day Four" +13284 "Ideographic Telegraph Symbol For Day Five" +13285 "Ideographic Telegraph Symbol For Day Six" +13286 "Ideographic Telegraph Symbol For Day Seven" +13287 "Ideographic Telegraph Symbol For Day Eight" +13288 "Ideographic Telegraph Symbol For Day Nine" +13289 "Ideographic Telegraph Symbol For Day Ten" +13290 "Ideographic Telegraph Symbol For Day Eleven" +13291 "Ideographic Telegraph Symbol For Day Twelve" +13292 "Ideographic Telegraph Symbol For Day Thirteen" +13293 "Ideographic Telegraph Symbol For Day Fourteen" +13294 "Ideographic Telegraph Symbol For Day Fifteen" +13295 "Ideographic Telegraph Symbol For Day Sixteen" +13296 "Ideographic Telegraph Symbol For Day Seventeen" +13297 "Ideographic Telegraph Symbol For Day Eighteen" +13298 "Ideographic Telegraph Symbol For Day Nineteen" +13299 "Ideographic Telegraph Symbol For Day Twenty" +13300 "Ideographic Telegraph Symbol For Day Twenty-One" +13301 "Ideographic Telegraph Symbol For Day Twenty-Two" +13302 "Ideographic Telegraph Symbol For Day Twenty-Three" +13303 "Ideographic Telegraph Symbol For Day Twenty-Four" +13304 "Ideographic Telegraph Symbol For Day Twenty-Five" +13305 "Ideographic Telegraph Symbol For Day Twenty-Six" +13306 "Ideographic Telegraph Symbol For Day Twenty-Seven" +13307 "Ideographic Telegraph Symbol For Day Twenty-Eight" +13308 "Ideographic Telegraph Symbol For Day Twenty-Nine" +13309 "Ideographic Telegraph Symbol For Day Thirty" +13310 "Ideographic Telegraph Symbol For Day Thirty-One" +13311 "Square Gal" +13312 "" +19893 "" +19904 "Hexagram For The Creative Heaven" +19905 "Hexagram For The Receptive Earth" +19906 "Hexagram For Difficulty At The Beginning" +19907 "Hexagram For Youthful Folly" +19908 "Hexagram For Waiting" +19909 "Hexagram For Conflict" +19910 "Hexagram For The Army" +19911 "Hexagram For Holding Together" +19912 "Hexagram For Small Taming" +19913 "Hexagram For Treading" +19914 "Hexagram For Peace" +19915 "Hexagram For Standstill" +19916 "Hexagram For Fellowship" +19917 "Hexagram For Great Possession" +19918 "Hexagram For Modesty" +19919 "Hexagram For Enthusiasm" +19920 "Hexagram For Following" +19921 "Hexagram For Work On The Decayed" +19922 "Hexagram For Approach" +19923 "Hexagram For Contemplation" +19924 "Hexagram For Biting Through" +19925 "Hexagram For Grace" +19926 "Hexagram For Splitting Apart" +19927 "Hexagram For Return" +19928 "Hexagram For Innocence" +19929 "Hexagram For Great Taming" +19930 "Hexagram For Mouth Corners" +19931 "Hexagram For Great Preponderance" +19932 "Hexagram For The Abysmal Water" +19933 "Hexagram For The Clinging Fire" +19934 "Hexagram For Influence" +19935 "Hexagram For Duration" +19936 "Hexagram For Retreat" +19937 "Hexagram For Great Power" +19938 "Hexagram For Progress" +19939 "Hexagram For Darkening Of The Light" +19940 "Hexagram For The Family" +19941 "Hexagram For Opposition" +19942 "Hexagram For Obstruction" +19943 "Hexagram For Deliverance" +19944 "Hexagram For Decrease" +19945 "Hexagram For Increase" +19946 "Hexagram For Breakthrough" +19947 "Hexagram For Coming To Meet" +19948 "Hexagram For Gathering Together" +19949 "Hexagram For Pushing Upward" +19950 "Hexagram For Oppression" +19951 "Hexagram For The Well" +19952 "Hexagram For Revolution" +19953 "Hexagram For The Cauldron" +19954 "Hexagram For The Arousing Thunder" +19955 "Hexagram For The Keeping Still Mountain" +19956 "Hexagram For Development" +19957 "Hexagram For The Marrying Maiden" +19958 "Hexagram For Abundance" +19959 "Hexagram For The Wanderer" +19960 "Hexagram For The Gentle Wind" +19961 "Hexagram For The Joyous Lake" +19962 "Hexagram For Dispersion" +19963 "Hexagram For Limitation" +19964 "Hexagram For Inner Truth" +19965 "Hexagram For Small Preponderance" +19966 "Hexagram For After Completion" +19967 "Hexagram For Before Completion" +19968 "" +40908 "" +40960 "Yi Syllable It" +40961 "Yi Syllable Ix" +40962 "Yi Syllable I" +40963 "Yi Syllable Ip" +40964 "Yi Syllable Iet" +40965 "Yi Syllable Iex" +40966 "Yi Syllable Ie" +40967 "Yi Syllable Iep" +40968 "Yi Syllable At" +40969 "Yi Syllable Ax" +40970 "Yi Syllable A" +40971 "Yi Syllable Ap" +40972 "Yi Syllable Uox" +40973 "Yi Syllable Uo" +40974 "Yi Syllable Uop" +40975 "Yi Syllable Ot" +40976 "Yi Syllable Ox" +40977 "Yi Syllable O" +40978 "Yi Syllable Op" +40979 "Yi Syllable Ex" +40980 "Yi Syllable E" +40981 "Yi Syllable Wu" +40982 "Yi Syllable Bit" +40983 "Yi Syllable Bix" +40984 "Yi Syllable Bi" +40985 "Yi Syllable Bip" +40986 "Yi Syllable Biet" +40987 "Yi Syllable Biex" +40988 "Yi Syllable Bie" +40989 "Yi Syllable Biep" +40990 "Yi Syllable Bat" +40991 "Yi Syllable Bax" +40992 "Yi Syllable Ba" +40993 "Yi Syllable Bap" +40994 "Yi Syllable Buox" +40995 "Yi Syllable Buo" +40996 "Yi Syllable Buop" +40997 "Yi Syllable Bot" +40998 "Yi Syllable Box" +40999 "Yi Syllable Bo" +41000 "Yi Syllable Bop" +41001 "Yi Syllable Bex" +41002 "Yi Syllable Be" +41003 "Yi Syllable Bep" +41004 "Yi Syllable But" +41005 "Yi Syllable Bux" +41006 "Yi Syllable Bu" +41007 "Yi Syllable Bup" +41008 "Yi Syllable Burx" +41009 "Yi Syllable Bur" +41010 "Yi Syllable Byt" +41011 "Yi Syllable Byx" +41012 "Yi Syllable By" +41013 "Yi Syllable Byp" +41014 "Yi Syllable Byrx" +41015 "Yi Syllable Byr" +41016 "Yi Syllable Pit" +41017 "Yi Syllable Pix" +41018 "Yi Syllable Pi" +41019 "Yi Syllable Pip" +41020 "Yi Syllable Piex" +41021 "Yi Syllable Pie" +41022 "Yi Syllable Piep" +41023 "Yi Syllable Pat" +41024 "Yi Syllable Pax" +41025 "Yi Syllable Pa" +41026 "Yi Syllable Pap" +41027 "Yi Syllable Puox" +41028 "Yi Syllable Puo" +41029 "Yi Syllable Puop" +41030 "Yi Syllable Pot" +41031 "Yi Syllable Pox" +41032 "Yi Syllable Po" +41033 "Yi Syllable Pop" +41034 "Yi Syllable Put" +41035 "Yi Syllable Pux" +41036 "Yi Syllable Pu" +41037 "Yi Syllable Pup" +41038 "Yi Syllable Purx" +41039 "Yi Syllable Pur" +41040 "Yi Syllable Pyt" +41041 "Yi Syllable Pyx" +41042 "Yi Syllable Py" +41043 "Yi Syllable Pyp" +41044 "Yi Syllable Pyrx" +41045 "Yi Syllable Pyr" +41046 "Yi Syllable Bbit" +41047 "Yi Syllable Bbix" +41048 "Yi Syllable Bbi" +41049 "Yi Syllable Bbip" +41050 "Yi Syllable Bbiet" +41051 "Yi Syllable Bbiex" +41052 "Yi Syllable Bbie" +41053 "Yi Syllable Bbiep" +41054 "Yi Syllable Bbat" +41055 "Yi Syllable Bbax" +41056 "Yi Syllable Bba" +41057 "Yi Syllable Bbap" +41058 "Yi Syllable Bbuox" +41059 "Yi Syllable Bbuo" +41060 "Yi Syllable Bbuop" +41061 "Yi Syllable Bbot" +41062 "Yi Syllable Bbox" +41063 "Yi Syllable Bbo" +41064 "Yi Syllable Bbop" +41065 "Yi Syllable Bbex" +41066 "Yi Syllable Bbe" +41067 "Yi Syllable Bbep" +41068 "Yi Syllable Bbut" +41069 "Yi Syllable Bbux" +41070 "Yi Syllable Bbu" +41071 "Yi Syllable Bbup" +41072 "Yi Syllable Bburx" +41073 "Yi Syllable Bbur" +41074 "Yi Syllable Bbyt" +41075 "Yi Syllable Bbyx" +41076 "Yi Syllable Bby" +41077 "Yi Syllable Bbyp" +41078 "Yi Syllable Nbit" +41079 "Yi Syllable Nbix" +41080 "Yi Syllable Nbi" +41081 "Yi Syllable Nbip" +41082 "Yi Syllable Nbiex" +41083 "Yi Syllable Nbie" +41084 "Yi Syllable Nbiep" +41085 "Yi Syllable Nbat" +41086 "Yi Syllable Nbax" +41087 "Yi Syllable Nba" +41088 "Yi Syllable Nbap" +41089 "Yi Syllable Nbot" +41090 "Yi Syllable Nbox" +41091 "Yi Syllable Nbo" +41092 "Yi Syllable Nbop" +41093 "Yi Syllable Nbut" +41094 "Yi Syllable Nbux" +41095 "Yi Syllable Nbu" +41096 "Yi Syllable Nbup" +41097 "Yi Syllable Nburx" +41098 "Yi Syllable Nbur" +41099 "Yi Syllable Nbyt" +41100 "Yi Syllable Nbyx" +41101 "Yi Syllable Nby" +41102 "Yi Syllable Nbyp" +41103 "Yi Syllable Nbyrx" +41104 "Yi Syllable Nbyr" +41105 "Yi Syllable Hmit" +41106 "Yi Syllable Hmix" +41107 "Yi Syllable Hmi" +41108 "Yi Syllable Hmip" +41109 "Yi Syllable Hmiex" +41110 "Yi Syllable Hmie" +41111 "Yi Syllable Hmiep" +41112 "Yi Syllable Hmat" +41113 "Yi Syllable Hmax" +41114 "Yi Syllable Hma" +41115 "Yi Syllable Hmap" +41116 "Yi Syllable Hmuox" +41117 "Yi Syllable Hmuo" +41118 "Yi Syllable Hmuop" +41119 "Yi Syllable Hmot" +41120 "Yi Syllable Hmox" +41121 "Yi Syllable Hmo" +41122 "Yi Syllable Hmop" +41123 "Yi Syllable Hmut" +41124 "Yi Syllable Hmux" +41125 "Yi Syllable Hmu" +41126 "Yi Syllable Hmup" +41127 "Yi Syllable Hmurx" +41128 "Yi Syllable Hmur" +41129 "Yi Syllable Hmyx" +41130 "Yi Syllable Hmy" +41131 "Yi Syllable Hmyp" +41132 "Yi Syllable Hmyrx" +41133 "Yi Syllable Hmyr" +41134 "Yi Syllable Mit" +41135 "Yi Syllable Mix" +41136 "Yi Syllable Mi" +41137 "Yi Syllable Mip" +41138 "Yi Syllable Miex" +41139 "Yi Syllable Mie" +41140 "Yi Syllable Miep" +41141 "Yi Syllable Mat" +41142 "Yi Syllable Max" +41143 "Yi Syllable Ma" +41144 "Yi Syllable Map" +41145 "Yi Syllable Muot" +41146 "Yi Syllable Muox" +41147 "Yi Syllable Muo" +41148 "Yi Syllable Muop" +41149 "Yi Syllable Mot" +41150 "Yi Syllable Mox" +41151 "Yi Syllable Mo" +41152 "Yi Syllable Mop" +41153 "Yi Syllable Mex" +41154 "Yi Syllable Me" +41155 "Yi Syllable Mut" +41156 "Yi Syllable Mux" +41157 "Yi Syllable Mu" +41158 "Yi Syllable Mup" +41159 "Yi Syllable Murx" +41160 "Yi Syllable Mur" +41161 "Yi Syllable Myt" +41162 "Yi Syllable Myx" +41163 "Yi Syllable My" +41164 "Yi Syllable Myp" +41165 "Yi Syllable Fit" +41166 "Yi Syllable Fix" +41167 "Yi Syllable Fi" +41168 "Yi Syllable Fip" +41169 "Yi Syllable Fat" +41170 "Yi Syllable Fax" +41171 "Yi Syllable Fa" +41172 "Yi Syllable Fap" +41173 "Yi Syllable Fox" +41174 "Yi Syllable Fo" +41175 "Yi Syllable Fop" +41176 "Yi Syllable Fut" +41177 "Yi Syllable Fux" +41178 "Yi Syllable Fu" +41179 "Yi Syllable Fup" +41180 "Yi Syllable Furx" +41181 "Yi Syllable Fur" +41182 "Yi Syllable Fyt" +41183 "Yi Syllable Fyx" +41184 "Yi Syllable Fy" +41185 "Yi Syllable Fyp" +41186 "Yi Syllable Vit" +41187 "Yi Syllable Vix" +41188 "Yi Syllable Vi" +41189 "Yi Syllable Vip" +41190 "Yi Syllable Viet" +41191 "Yi Syllable Viex" +41192 "Yi Syllable Vie" +41193 "Yi Syllable Viep" +41194 "Yi Syllable Vat" +41195 "Yi Syllable Vax" +41196 "Yi Syllable Va" +41197 "Yi Syllable Vap" +41198 "Yi Syllable Vot" +41199 "Yi Syllable Vox" +41200 "Yi Syllable Vo" +41201 "Yi Syllable Vop" +41202 "Yi Syllable Vex" +41203 "Yi Syllable Vep" +41204 "Yi Syllable Vut" +41205 "Yi Syllable Vux" +41206 "Yi Syllable Vu" +41207 "Yi Syllable Vup" +41208 "Yi Syllable Vurx" +41209 "Yi Syllable Vur" +41210 "Yi Syllable Vyt" +41211 "Yi Syllable Vyx" +41212 "Yi Syllable Vy" +41213 "Yi Syllable Vyp" +41214 "Yi Syllable Vyrx" +41215 "Yi Syllable Vyr" +41216 "Yi Syllable Dit" +41217 "Yi Syllable Dix" +41218 "Yi Syllable Di" +41219 "Yi Syllable Dip" +41220 "Yi Syllable Diex" +41221 "Yi Syllable Die" +41222 "Yi Syllable Diep" +41223 "Yi Syllable Dat" +41224 "Yi Syllable Dax" +41225 "Yi Syllable Da" +41226 "Yi Syllable Dap" +41227 "Yi Syllable Duox" +41228 "Yi Syllable Duo" +41229 "Yi Syllable Dot" +41230 "Yi Syllable Dox" +41231 "Yi Syllable Do" +41232 "Yi Syllable Dop" +41233 "Yi Syllable Dex" +41234 "Yi Syllable De" +41235 "Yi Syllable Dep" +41236 "Yi Syllable Dut" +41237 "Yi Syllable Dux" +41238 "Yi Syllable Du" +41239 "Yi Syllable Dup" +41240 "Yi Syllable Durx" +41241 "Yi Syllable Dur" +41242 "Yi Syllable Tit" +41243 "Yi Syllable Tix" +41244 "Yi Syllable Ti" +41245 "Yi Syllable Tip" +41246 "Yi Syllable Tiex" +41247 "Yi Syllable Tie" +41248 "Yi Syllable Tiep" +41249 "Yi Syllable Tat" +41250 "Yi Syllable Tax" +41251 "Yi Syllable Ta" +41252 "Yi Syllable Tap" +41253 "Yi Syllable Tuot" +41254 "Yi Syllable Tuox" +41255 "Yi Syllable Tuo" +41256 "Yi Syllable Tuop" +41257 "Yi Syllable Tot" +41258 "Yi Syllable Tox" +41259 "Yi Syllable To" +41260 "Yi Syllable Top" +41261 "Yi Syllable Tex" +41262 "Yi Syllable Te" +41263 "Yi Syllable Tep" +41264 "Yi Syllable Tut" +41265 "Yi Syllable Tux" +41266 "Yi Syllable Tu" +41267 "Yi Syllable Tup" +41268 "Yi Syllable Turx" +41269 "Yi Syllable Tur" +41270 "Yi Syllable Ddit" +41271 "Yi Syllable Ddix" +41272 "Yi Syllable Ddi" +41273 "Yi Syllable Ddip" +41274 "Yi Syllable Ddiex" +41275 "Yi Syllable Ddie" +41276 "Yi Syllable Ddiep" +41277 "Yi Syllable Ddat" +41278 "Yi Syllable Ddax" +41279 "Yi Syllable Dda" +41280 "Yi Syllable Ddap" +41281 "Yi Syllable Dduox" +41282 "Yi Syllable Dduo" +41283 "Yi Syllable Dduop" +41284 "Yi Syllable Ddot" +41285 "Yi Syllable Ddox" +41286 "Yi Syllable Ddo" +41287 "Yi Syllable Ddop" +41288 "Yi Syllable Ddex" +41289 "Yi Syllable Dde" +41290 "Yi Syllable Ddep" +41291 "Yi Syllable Ddut" +41292 "Yi Syllable Ddux" +41293 "Yi Syllable Ddu" +41294 "Yi Syllable Ddup" +41295 "Yi Syllable Ddurx" +41296 "Yi Syllable Ddur" +41297 "Yi Syllable Ndit" +41298 "Yi Syllable Ndix" +41299 "Yi Syllable Ndi" +41300 "Yi Syllable Ndip" +41301 "Yi Syllable Ndiex" +41302 "Yi Syllable Ndie" +41303 "Yi Syllable Ndat" +41304 "Yi Syllable Ndax" +41305 "Yi Syllable Nda" +41306 "Yi Syllable Ndap" +41307 "Yi Syllable Ndot" +41308 "Yi Syllable Ndox" +41309 "Yi Syllable Ndo" +41310 "Yi Syllable Ndop" +41311 "Yi Syllable Ndex" +41312 "Yi Syllable Nde" +41313 "Yi Syllable Ndep" +41314 "Yi Syllable Ndut" +41315 "Yi Syllable Ndux" +41316 "Yi Syllable Ndu" +41317 "Yi Syllable Ndup" +41318 "Yi Syllable Ndurx" +41319 "Yi Syllable Ndur" +41320 "Yi Syllable Hnit" +41321 "Yi Syllable Hnix" +41322 "Yi Syllable Hni" +41323 "Yi Syllable Hnip" +41324 "Yi Syllable Hniet" +41325 "Yi Syllable Hniex" +41326 "Yi Syllable Hnie" +41327 "Yi Syllable Hniep" +41328 "Yi Syllable Hnat" +41329 "Yi Syllable Hnax" +41330 "Yi Syllable Hna" +41331 "Yi Syllable Hnap" +41332 "Yi Syllable Hnuox" +41333 "Yi Syllable Hnuo" +41334 "Yi Syllable Hnot" +41335 "Yi Syllable Hnox" +41336 "Yi Syllable Hnop" +41337 "Yi Syllable Hnex" +41338 "Yi Syllable Hne" +41339 "Yi Syllable Hnep" +41340 "Yi Syllable Hnut" +41341 "Yi Syllable Nit" +41342 "Yi Syllable Nix" +41343 "Yi Syllable Ni" +41344 "Yi Syllable Nip" +41345 "Yi Syllable Niex" +41346 "Yi Syllable Nie" +41347 "Yi Syllable Niep" +41348 "Yi Syllable Nax" +41349 "Yi Syllable Na" +41350 "Yi Syllable Nap" +41351 "Yi Syllable Nuox" +41352 "Yi Syllable Nuo" +41353 "Yi Syllable Nuop" +41354 "Yi Syllable Not" +41355 "Yi Syllable Nox" +41356 "Yi Syllable No" +41357 "Yi Syllable Nop" +41358 "Yi Syllable Nex" +41359 "Yi Syllable Ne" +41360 "Yi Syllable Nep" +41361 "Yi Syllable Nut" +41362 "Yi Syllable Nux" +41363 "Yi Syllable Nu" +41364 "Yi Syllable Nup" +41365 "Yi Syllable Nurx" +41366 "Yi Syllable Nur" +41367 "Yi Syllable Hlit" +41368 "Yi Syllable Hlix" +41369 "Yi Syllable Hli" +41370 "Yi Syllable Hlip" +41371 "Yi Syllable Hliex" +41372 "Yi Syllable Hlie" +41373 "Yi Syllable Hliep" +41374 "Yi Syllable Hlat" +41375 "Yi Syllable Hlax" +41376 "Yi Syllable Hla" +41377 "Yi Syllable Hlap" +41378 "Yi Syllable Hluox" +41379 "Yi Syllable Hluo" +41380 "Yi Syllable Hluop" +41381 "Yi Syllable Hlox" +41382 "Yi Syllable Hlo" +41383 "Yi Syllable Hlop" +41384 "Yi Syllable Hlex" +41385 "Yi Syllable Hle" +41386 "Yi Syllable Hlep" +41387 "Yi Syllable Hlut" +41388 "Yi Syllable Hlux" +41389 "Yi Syllable Hlu" +41390 "Yi Syllable Hlup" +41391 "Yi Syllable Hlurx" +41392 "Yi Syllable Hlur" +41393 "Yi Syllable Hlyt" +41394 "Yi Syllable Hlyx" +41395 "Yi Syllable Hly" +41396 "Yi Syllable Hlyp" +41397 "Yi Syllable Hlyrx" +41398 "Yi Syllable Hlyr" +41399 "Yi Syllable Lit" +41400 "Yi Syllable Lix" +41401 "Yi Syllable Li" +41402 "Yi Syllable Lip" +41403 "Yi Syllable Liet" +41404 "Yi Syllable Liex" +41405 "Yi Syllable Lie" +41406 "Yi Syllable Liep" +41407 "Yi Syllable Lat" +41408 "Yi Syllable Lax" +41409 "Yi Syllable La" +41410 "Yi Syllable Lap" +41411 "Yi Syllable Luot" +41412 "Yi Syllable Luox" +41413 "Yi Syllable Luo" +41414 "Yi Syllable Luop" +41415 "Yi Syllable Lot" +41416 "Yi Syllable Lox" +41417 "Yi Syllable Lo" +41418 "Yi Syllable Lop" +41419 "Yi Syllable Lex" +41420 "Yi Syllable Le" +41421 "Yi Syllable Lep" +41422 "Yi Syllable Lut" +41423 "Yi Syllable Lux" +41424 "Yi Syllable Lu" +41425 "Yi Syllable Lup" +41426 "Yi Syllable Lurx" +41427 "Yi Syllable Lur" +41428 "Yi Syllable Lyt" +41429 "Yi Syllable Lyx" +41430 "Yi Syllable Ly" +41431 "Yi Syllable Lyp" +41432 "Yi Syllable Lyrx" +41433 "Yi Syllable Lyr" +41434 "Yi Syllable Git" +41435 "Yi Syllable Gix" +41436 "Yi Syllable Gi" +41437 "Yi Syllable Gip" +41438 "Yi Syllable Giet" +41439 "Yi Syllable Giex" +41440 "Yi Syllable Gie" +41441 "Yi Syllable Giep" +41442 "Yi Syllable Gat" +41443 "Yi Syllable Gax" +41444 "Yi Syllable Ga" +41445 "Yi Syllable Gap" +41446 "Yi Syllable Guot" +41447 "Yi Syllable Guox" +41448 "Yi Syllable Guo" +41449 "Yi Syllable Guop" +41450 "Yi Syllable Got" +41451 "Yi Syllable Gox" +41452 "Yi Syllable Go" +41453 "Yi Syllable Gop" +41454 "Yi Syllable Get" +41455 "Yi Syllable Gex" +41456 "Yi Syllable Ge" +41457 "Yi Syllable Gep" +41458 "Yi Syllable Gut" +41459 "Yi Syllable Gux" +41460 "Yi Syllable Gu" +41461 "Yi Syllable Gup" +41462 "Yi Syllable Gurx" +41463 "Yi Syllable Gur" +41464 "Yi Syllable Kit" +41465 "Yi Syllable Kix" +41466 "Yi Syllable Ki" +41467 "Yi Syllable Kip" +41468 "Yi Syllable Kiex" +41469 "Yi Syllable Kie" +41470 "Yi Syllable Kiep" +41471 "Yi Syllable Kat" +41472 "Yi Syllable Kax" +41473 "Yi Syllable Ka" +41474 "Yi Syllable Kap" +41475 "Yi Syllable Kuox" +41476 "Yi Syllable Kuo" +41477 "Yi Syllable Kuop" +41478 "Yi Syllable Kot" +41479 "Yi Syllable Kox" +41480 "Yi Syllable Ko" +41481 "Yi Syllable Kop" +41482 "Yi Syllable Ket" +41483 "Yi Syllable Kex" +41484 "Yi Syllable Ke" +41485 "Yi Syllable Kep" +41486 "Yi Syllable Kut" +41487 "Yi Syllable Kux" +41488 "Yi Syllable Ku" +41489 "Yi Syllable Kup" +41490 "Yi Syllable Kurx" +41491 "Yi Syllable Kur" +41492 "Yi Syllable Ggit" +41493 "Yi Syllable Ggix" +41494 "Yi Syllable Ggi" +41495 "Yi Syllable Ggiex" +41496 "Yi Syllable Ggie" +41497 "Yi Syllable Ggiep" +41498 "Yi Syllable Ggat" +41499 "Yi Syllable Ggax" +41500 "Yi Syllable Gga" +41501 "Yi Syllable Ggap" +41502 "Yi Syllable Gguot" +41503 "Yi Syllable Gguox" +41504 "Yi Syllable Gguo" +41505 "Yi Syllable Gguop" +41506 "Yi Syllable Ggot" +41507 "Yi Syllable Ggox" +41508 "Yi Syllable Ggo" +41509 "Yi Syllable Ggop" +41510 "Yi Syllable Gget" +41511 "Yi Syllable Ggex" +41512 "Yi Syllable Gge" +41513 "Yi Syllable Ggep" +41514 "Yi Syllable Ggut" +41515 "Yi Syllable Ggux" +41516 "Yi Syllable Ggu" +41517 "Yi Syllable Ggup" +41518 "Yi Syllable Ggurx" +41519 "Yi Syllable Ggur" +41520 "Yi Syllable Mgiex" +41521 "Yi Syllable Mgie" +41522 "Yi Syllable Mgat" +41523 "Yi Syllable Mgax" +41524 "Yi Syllable Mga" +41525 "Yi Syllable Mgap" +41526 "Yi Syllable Mguox" +41527 "Yi Syllable Mguo" +41528 "Yi Syllable Mguop" +41529 "Yi Syllable Mgot" +41530 "Yi Syllable Mgox" +41531 "Yi Syllable Mgo" +41532 "Yi Syllable Mgop" +41533 "Yi Syllable Mgex" +41534 "Yi Syllable Mge" +41535 "Yi Syllable Mgep" +41536 "Yi Syllable Mgut" +41537 "Yi Syllable Mgux" +41538 "Yi Syllable Mgu" +41539 "Yi Syllable Mgup" +41540 "Yi Syllable Mgurx" +41541 "Yi Syllable Mgur" +41542 "Yi Syllable Hxit" +41543 "Yi Syllable Hxix" +41544 "Yi Syllable Hxi" +41545 "Yi Syllable Hxip" +41546 "Yi Syllable Hxiet" +41547 "Yi Syllable Hxiex" +41548 "Yi Syllable Hxie" +41549 "Yi Syllable Hxiep" +41550 "Yi Syllable Hxat" +41551 "Yi Syllable Hxax" +41552 "Yi Syllable Hxa" +41553 "Yi Syllable Hxap" +41554 "Yi Syllable Hxuot" +41555 "Yi Syllable Hxuox" +41556 "Yi Syllable Hxuo" +41557 "Yi Syllable Hxuop" +41558 "Yi Syllable Hxot" +41559 "Yi Syllable Hxox" +41560 "Yi Syllable Hxo" +41561 "Yi Syllable Hxop" +41562 "Yi Syllable Hxex" +41563 "Yi Syllable Hxe" +41564 "Yi Syllable Hxep" +41565 "Yi Syllable Ngiex" +41566 "Yi Syllable Ngie" +41567 "Yi Syllable Ngiep" +41568 "Yi Syllable Ngat" +41569 "Yi Syllable Ngax" +41570 "Yi Syllable Nga" +41571 "Yi Syllable Ngap" +41572 "Yi Syllable Nguot" +41573 "Yi Syllable Nguox" +41574 "Yi Syllable Nguo" +41575 "Yi Syllable Ngot" +41576 "Yi Syllable Ngox" +41577 "Yi Syllable Ngo" +41578 "Yi Syllable Ngop" +41579 "Yi Syllable Ngex" +41580 "Yi Syllable Nge" +41581 "Yi Syllable Ngep" +41582 "Yi Syllable Hit" +41583 "Yi Syllable Hiex" +41584 "Yi Syllable Hie" +41585 "Yi Syllable Hat" +41586 "Yi Syllable Hax" +41587 "Yi Syllable Ha" +41588 "Yi Syllable Hap" +41589 "Yi Syllable Huot" +41590 "Yi Syllable Huox" +41591 "Yi Syllable Huo" +41592 "Yi Syllable Huop" +41593 "Yi Syllable Hot" +41594 "Yi Syllable Hox" +41595 "Yi Syllable Ho" +41596 "Yi Syllable Hop" +41597 "Yi Syllable Hex" +41598 "Yi Syllable He" +41599 "Yi Syllable Hep" +41600 "Yi Syllable Wat" +41601 "Yi Syllable Wax" +41602 "Yi Syllable Wa" +41603 "Yi Syllable Wap" +41604 "Yi Syllable Wuox" +41605 "Yi Syllable Wuo" +41606 "Yi Syllable Wuop" +41607 "Yi Syllable Wox" +41608 "Yi Syllable Wo" +41609 "Yi Syllable Wop" +41610 "Yi Syllable Wex" +41611 "Yi Syllable We" +41612 "Yi Syllable Wep" +41613 "Yi Syllable Zit" +41614 "Yi Syllable Zix" +41615 "Yi Syllable Zi" +41616 "Yi Syllable Zip" +41617 "Yi Syllable Ziex" +41618 "Yi Syllable Zie" +41619 "Yi Syllable Ziep" +41620 "Yi Syllable Zat" +41621 "Yi Syllable Zax" +41622 "Yi Syllable Za" +41623 "Yi Syllable Zap" +41624 "Yi Syllable Zuox" +41625 "Yi Syllable Zuo" +41626 "Yi Syllable Zuop" +41627 "Yi Syllable Zot" +41628 "Yi Syllable Zox" +41629 "Yi Syllable Zo" +41630 "Yi Syllable Zop" +41631 "Yi Syllable Zex" +41632 "Yi Syllable Ze" +41633 "Yi Syllable Zep" +41634 "Yi Syllable Zut" +41635 "Yi Syllable Zux" +41636 "Yi Syllable Zu" +41637 "Yi Syllable Zup" +41638 "Yi Syllable Zurx" +41639 "Yi Syllable Zur" +41640 "Yi Syllable Zyt" +41641 "Yi Syllable Zyx" +41642 "Yi Syllable Zy" +41643 "Yi Syllable Zyp" +41644 "Yi Syllable Zyrx" +41645 "Yi Syllable Zyr" +41646 "Yi Syllable Cit" +41647 "Yi Syllable Cix" +41648 "Yi Syllable Ci" +41649 "Yi Syllable Cip" +41650 "Yi Syllable Ciet" +41651 "Yi Syllable Ciex" +41652 "Yi Syllable Cie" +41653 "Yi Syllable Ciep" +41654 "Yi Syllable Cat" +41655 "Yi Syllable Cax" +41656 "Yi Syllable Ca" +41657 "Yi Syllable Cap" +41658 "Yi Syllable Cuox" +41659 "Yi Syllable Cuo" +41660 "Yi Syllable Cuop" +41661 "Yi Syllable Cot" +41662 "Yi Syllable Cox" +41663 "Yi Syllable Co" +41664 "Yi Syllable Cop" +41665 "Yi Syllable Cex" +41666 "Yi Syllable Ce" +41667 "Yi Syllable Cep" +41668 "Yi Syllable Cut" +41669 "Yi Syllable Cux" +41670 "Yi Syllable Cu" +41671 "Yi Syllable Cup" +41672 "Yi Syllable Curx" +41673 "Yi Syllable Cur" +41674 "Yi Syllable Cyt" +41675 "Yi Syllable Cyx" +41676 "Yi Syllable Cy" +41677 "Yi Syllable Cyp" +41678 "Yi Syllable Cyrx" +41679 "Yi Syllable Cyr" +41680 "Yi Syllable Zzit" +41681 "Yi Syllable Zzix" +41682 "Yi Syllable Zzi" +41683 "Yi Syllable Zzip" +41684 "Yi Syllable Zziet" +41685 "Yi Syllable Zziex" +41686 "Yi Syllable Zzie" +41687 "Yi Syllable Zziep" +41688 "Yi Syllable Zzat" +41689 "Yi Syllable Zzax" +41690 "Yi Syllable Zza" +41691 "Yi Syllable Zzap" +41692 "Yi Syllable Zzox" +41693 "Yi Syllable Zzo" +41694 "Yi Syllable Zzop" +41695 "Yi Syllable Zzex" +41696 "Yi Syllable Zze" +41697 "Yi Syllable Zzep" +41698 "Yi Syllable Zzux" +41699 "Yi Syllable Zzu" +41700 "Yi Syllable Zzup" +41701 "Yi Syllable Zzurx" +41702 "Yi Syllable Zzur" +41703 "Yi Syllable Zzyt" +41704 "Yi Syllable Zzyx" +41705 "Yi Syllable Zzy" +41706 "Yi Syllable Zzyp" +41707 "Yi Syllable Zzyrx" +41708 "Yi Syllable Zzyr" +41709 "Yi Syllable Nzit" +41710 "Yi Syllable Nzix" +41711 "Yi Syllable Nzi" +41712 "Yi Syllable Nzip" +41713 "Yi Syllable Nziex" +41714 "Yi Syllable Nzie" +41715 "Yi Syllable Nziep" +41716 "Yi Syllable Nzat" +41717 "Yi Syllable Nzax" +41718 "Yi Syllable Nza" +41719 "Yi Syllable Nzap" +41720 "Yi Syllable Nzuox" +41721 "Yi Syllable Nzuo" +41722 "Yi Syllable Nzox" +41723 "Yi Syllable Nzop" +41724 "Yi Syllable Nzex" +41725 "Yi Syllable Nze" +41726 "Yi Syllable Nzux" +41727 "Yi Syllable Nzu" +41728 "Yi Syllable Nzup" +41729 "Yi Syllable Nzurx" +41730 "Yi Syllable Nzur" +41731 "Yi Syllable Nzyt" +41732 "Yi Syllable Nzyx" +41733 "Yi Syllable Nzy" +41734 "Yi Syllable Nzyp" +41735 "Yi Syllable Nzyrx" +41736 "Yi Syllable Nzyr" +41737 "Yi Syllable Sit" +41738 "Yi Syllable Six" +41739 "Yi Syllable Si" +41740 "Yi Syllable Sip" +41741 "Yi Syllable Siex" +41742 "Yi Syllable Sie" +41743 "Yi Syllable Siep" +41744 "Yi Syllable Sat" +41745 "Yi Syllable Sax" +41746 "Yi Syllable Sa" +41747 "Yi Syllable Sap" +41748 "Yi Syllable Suox" +41749 "Yi Syllable Suo" +41750 "Yi Syllable Suop" +41751 "Yi Syllable Sot" +41752 "Yi Syllable Sox" +41753 "Yi Syllable So" +41754 "Yi Syllable Sop" +41755 "Yi Syllable Sex" +41756 "Yi Syllable Se" +41757 "Yi Syllable Sep" +41758 "Yi Syllable Sut" +41759 "Yi Syllable Sux" +41760 "Yi Syllable Su" +41761 "Yi Syllable Sup" +41762 "Yi Syllable Surx" +41763 "Yi Syllable Sur" +41764 "Yi Syllable Syt" +41765 "Yi Syllable Syx" +41766 "Yi Syllable Sy" +41767 "Yi Syllable Syp" +41768 "Yi Syllable Syrx" +41769 "Yi Syllable Syr" +41770 "Yi Syllable Ssit" +41771 "Yi Syllable Ssix" +41772 "Yi Syllable Ssi" +41773 "Yi Syllable Ssip" +41774 "Yi Syllable Ssiex" +41775 "Yi Syllable Ssie" +41776 "Yi Syllable Ssiep" +41777 "Yi Syllable Ssat" +41778 "Yi Syllable Ssax" +41779 "Yi Syllable Ssa" +41780 "Yi Syllable Ssap" +41781 "Yi Syllable Ssot" +41782 "Yi Syllable Ssox" +41783 "Yi Syllable Sso" +41784 "Yi Syllable Ssop" +41785 "Yi Syllable Ssex" +41786 "Yi Syllable Sse" +41787 "Yi Syllable Ssep" +41788 "Yi Syllable Ssut" +41789 "Yi Syllable Ssux" +41790 "Yi Syllable Ssu" +41791 "Yi Syllable Ssup" +41792 "Yi Syllable Ssyt" +41793 "Yi Syllable Ssyx" +41794 "Yi Syllable Ssy" +41795 "Yi Syllable Ssyp" +41796 "Yi Syllable Ssyrx" +41797 "Yi Syllable Ssyr" +41798 "Yi Syllable Zhat" +41799 "Yi Syllable Zhax" +41800 "Yi Syllable Zha" +41801 "Yi Syllable Zhap" +41802 "Yi Syllable Zhuox" +41803 "Yi Syllable Zhuo" +41804 "Yi Syllable Zhuop" +41805 "Yi Syllable Zhot" +41806 "Yi Syllable Zhox" +41807 "Yi Syllable Zho" +41808 "Yi Syllable Zhop" +41809 "Yi Syllable Zhet" +41810 "Yi Syllable Zhex" +41811 "Yi Syllable Zhe" +41812 "Yi Syllable Zhep" +41813 "Yi Syllable Zhut" +41814 "Yi Syllable Zhux" +41815 "Yi Syllable Zhu" +41816 "Yi Syllable Zhup" +41817 "Yi Syllable Zhurx" +41818 "Yi Syllable Zhur" +41819 "Yi Syllable Zhyt" +41820 "Yi Syllable Zhyx" +41821 "Yi Syllable Zhy" +41822 "Yi Syllable Zhyp" +41823 "Yi Syllable Zhyrx" +41824 "Yi Syllable Zhyr" +41825 "Yi Syllable Chat" +41826 "Yi Syllable Chax" +41827 "Yi Syllable Cha" +41828 "Yi Syllable Chap" +41829 "Yi Syllable Chuot" +41830 "Yi Syllable Chuox" +41831 "Yi Syllable Chuo" +41832 "Yi Syllable Chuop" +41833 "Yi Syllable Chot" +41834 "Yi Syllable Chox" +41835 "Yi Syllable Cho" +41836 "Yi Syllable Chop" +41837 "Yi Syllable Chet" +41838 "Yi Syllable Chex" +41839 "Yi Syllable Che" +41840 "Yi Syllable Chep" +41841 "Yi Syllable Chux" +41842 "Yi Syllable Chu" +41843 "Yi Syllable Chup" +41844 "Yi Syllable Churx" +41845 "Yi Syllable Chur" +41846 "Yi Syllable Chyt" +41847 "Yi Syllable Chyx" +41848 "Yi Syllable Chy" +41849 "Yi Syllable Chyp" +41850 "Yi Syllable Chyrx" +41851 "Yi Syllable Chyr" +41852 "Yi Syllable Rrax" +41853 "Yi Syllable Rra" +41854 "Yi Syllable Rruox" +41855 "Yi Syllable Rruo" +41856 "Yi Syllable Rrot" +41857 "Yi Syllable Rrox" +41858 "Yi Syllable Rro" +41859 "Yi Syllable Rrop" +41860 "Yi Syllable Rret" +41861 "Yi Syllable Rrex" +41862 "Yi Syllable Rre" +41863 "Yi Syllable Rrep" +41864 "Yi Syllable Rrut" +41865 "Yi Syllable Rrux" +41866 "Yi Syllable Rru" +41867 "Yi Syllable Rrup" +41868 "Yi Syllable Rrurx" +41869 "Yi Syllable Rrur" +41870 "Yi Syllable Rryt" +41871 "Yi Syllable Rryx" +41872 "Yi Syllable Rry" +41873 "Yi Syllable Rryp" +41874 "Yi Syllable Rryrx" +41875 "Yi Syllable Rryr" +41876 "Yi Syllable Nrat" +41877 "Yi Syllable Nrax" +41878 "Yi Syllable Nra" +41879 "Yi Syllable Nrap" +41880 "Yi Syllable Nrox" +41881 "Yi Syllable Nro" +41882 "Yi Syllable Nrop" +41883 "Yi Syllable Nret" +41884 "Yi Syllable Nrex" +41885 "Yi Syllable Nre" +41886 "Yi Syllable Nrep" +41887 "Yi Syllable Nrut" +41888 "Yi Syllable Nrux" +41889 "Yi Syllable Nru" +41890 "Yi Syllable Nrup" +41891 "Yi Syllable Nrurx" +41892 "Yi Syllable Nrur" +41893 "Yi Syllable Nryt" +41894 "Yi Syllable Nryx" +41895 "Yi Syllable Nry" +41896 "Yi Syllable Nryp" +41897 "Yi Syllable Nryrx" +41898 "Yi Syllable Nryr" +41899 "Yi Syllable Shat" +41900 "Yi Syllable Shax" +41901 "Yi Syllable Sha" +41902 "Yi Syllable Shap" +41903 "Yi Syllable Shuox" +41904 "Yi Syllable Shuo" +41905 "Yi Syllable Shuop" +41906 "Yi Syllable Shot" +41907 "Yi Syllable Shox" +41908 "Yi Syllable Sho" +41909 "Yi Syllable Shop" +41910 "Yi Syllable Shet" +41911 "Yi Syllable Shex" +41912 "Yi Syllable She" +41913 "Yi Syllable Shep" +41914 "Yi Syllable Shut" +41915 "Yi Syllable Shux" +41916 "Yi Syllable Shu" +41917 "Yi Syllable Shup" +41918 "Yi Syllable Shurx" +41919 "Yi Syllable Shur" +41920 "Yi Syllable Shyt" +41921 "Yi Syllable Shyx" +41922 "Yi Syllable Shy" +41923 "Yi Syllable Shyp" +41924 "Yi Syllable Shyrx" +41925 "Yi Syllable Shyr" +41926 "Yi Syllable Rat" +41927 "Yi Syllable Rax" +41928 "Yi Syllable Ra" +41929 "Yi Syllable Rap" +41930 "Yi Syllable Ruox" +41931 "Yi Syllable Ruo" +41932 "Yi Syllable Ruop" +41933 "Yi Syllable Rot" +41934 "Yi Syllable Rox" +41935 "Yi Syllable Ro" +41936 "Yi Syllable Rop" +41937 "Yi Syllable Rex" +41938 "Yi Syllable Re" +41939 "Yi Syllable Rep" +41940 "Yi Syllable Rut" +41941 "Yi Syllable Rux" +41942 "Yi Syllable Ru" +41943 "Yi Syllable Rup" +41944 "Yi Syllable Rurx" +41945 "Yi Syllable Rur" +41946 "Yi Syllable Ryt" +41947 "Yi Syllable Ryx" +41948 "Yi Syllable Ry" +41949 "Yi Syllable Ryp" +41950 "Yi Syllable Ryrx" +41951 "Yi Syllable Ryr" +41952 "Yi Syllable Jit" +41953 "Yi Syllable Jix" +41954 "Yi Syllable Ji" +41955 "Yi Syllable Jip" +41956 "Yi Syllable Jiet" +41957 "Yi Syllable Jiex" +41958 "Yi Syllable Jie" +41959 "Yi Syllable Jiep" +41960 "Yi Syllable Juot" +41961 "Yi Syllable Juox" +41962 "Yi Syllable Juo" +41963 "Yi Syllable Juop" +41964 "Yi Syllable Jot" +41965 "Yi Syllable Jox" +41966 "Yi Syllable Jo" +41967 "Yi Syllable Jop" +41968 "Yi Syllable Jut" +41969 "Yi Syllable Jux" +41970 "Yi Syllable Ju" +41971 "Yi Syllable Jup" +41972 "Yi Syllable Jurx" +41973 "Yi Syllable Jur" +41974 "Yi Syllable Jyt" +41975 "Yi Syllable Jyx" +41976 "Yi Syllable Jy" +41977 "Yi Syllable Jyp" +41978 "Yi Syllable Jyrx" +41979 "Yi Syllable Jyr" +41980 "Yi Syllable Qit" +41981 "Yi Syllable Qix" +41982 "Yi Syllable Qi" +41983 "Yi Syllable Qip" +41984 "Yi Syllable Qiet" +41985 "Yi Syllable Qiex" +41986 "Yi Syllable Qie" +41987 "Yi Syllable Qiep" +41988 "Yi Syllable Quot" +41989 "Yi Syllable Quox" +41990 "Yi Syllable Quo" +41991 "Yi Syllable Quop" +41992 "Yi Syllable Qot" +41993 "Yi Syllable Qox" +41994 "Yi Syllable Qo" +41995 "Yi Syllable Qop" +41996 "Yi Syllable Qut" +41997 "Yi Syllable Qux" +41998 "Yi Syllable Qu" +41999 "Yi Syllable Qup" +42000 "Yi Syllable Qurx" +42001 "Yi Syllable Qur" +42002 "Yi Syllable Qyt" +42003 "Yi Syllable Qyx" +42004 "Yi Syllable Qy" +42005 "Yi Syllable Qyp" +42006 "Yi Syllable Qyrx" +42007 "Yi Syllable Qyr" +42008 "Yi Syllable Jjit" +42009 "Yi Syllable Jjix" +42010 "Yi Syllable Jji" +42011 "Yi Syllable Jjip" +42012 "Yi Syllable Jjiet" +42013 "Yi Syllable Jjiex" +42014 "Yi Syllable Jjie" +42015 "Yi Syllable Jjiep" +42016 "Yi Syllable Jjuox" +42017 "Yi Syllable Jjuo" +42018 "Yi Syllable Jjuop" +42019 "Yi Syllable Jjot" +42020 "Yi Syllable Jjox" +42021 "Yi Syllable Jjo" +42022 "Yi Syllable Jjop" +42023 "Yi Syllable Jjut" +42024 "Yi Syllable Jjux" +42025 "Yi Syllable Jju" +42026 "Yi Syllable Jjup" +42027 "Yi Syllable Jjurx" +42028 "Yi Syllable Jjur" +42029 "Yi Syllable Jjyt" +42030 "Yi Syllable Jjyx" +42031 "Yi Syllable Jjy" +42032 "Yi Syllable Jjyp" +42033 "Yi Syllable Njit" +42034 "Yi Syllable Njix" +42035 "Yi Syllable Nji" +42036 "Yi Syllable Njip" +42037 "Yi Syllable Njiet" +42038 "Yi Syllable Njiex" +42039 "Yi Syllable Njie" +42040 "Yi Syllable Njiep" +42041 "Yi Syllable Njuox" +42042 "Yi Syllable Njuo" +42043 "Yi Syllable Njot" +42044 "Yi Syllable Njox" +42045 "Yi Syllable Njo" +42046 "Yi Syllable Njop" +42047 "Yi Syllable Njux" +42048 "Yi Syllable Nju" +42049 "Yi Syllable Njup" +42050 "Yi Syllable Njurx" +42051 "Yi Syllable Njur" +42052 "Yi Syllable Njyt" +42053 "Yi Syllable Njyx" +42054 "Yi Syllable Njy" +42055 "Yi Syllable Njyp" +42056 "Yi Syllable Njyrx" +42057 "Yi Syllable Njyr" +42058 "Yi Syllable Nyit" +42059 "Yi Syllable Nyix" +42060 "Yi Syllable Nyi" +42061 "Yi Syllable Nyip" +42062 "Yi Syllable Nyiet" +42063 "Yi Syllable Nyiex" +42064 "Yi Syllable Nyie" +42065 "Yi Syllable Nyiep" +42066 "Yi Syllable Nyuox" +42067 "Yi Syllable Nyuo" +42068 "Yi Syllable Nyuop" +42069 "Yi Syllable Nyot" +42070 "Yi Syllable Nyox" +42071 "Yi Syllable Nyo" +42072 "Yi Syllable Nyop" +42073 "Yi Syllable Nyut" +42074 "Yi Syllable Nyux" +42075 "Yi Syllable Nyu" +42076 "Yi Syllable Nyup" +42077 "Yi Syllable Xit" +42078 "Yi Syllable Xix" +42079 "Yi Syllable Xi" +42080 "Yi Syllable Xip" +42081 "Yi Syllable Xiet" +42082 "Yi Syllable Xiex" +42083 "Yi Syllable Xie" +42084 "Yi Syllable Xiep" +42085 "Yi Syllable Xuox" +42086 "Yi Syllable Xuo" +42087 "Yi Syllable Xot" +42088 "Yi Syllable Xox" +42089 "Yi Syllable Xo" +42090 "Yi Syllable Xop" +42091 "Yi Syllable Xyt" +42092 "Yi Syllable Xyx" +42093 "Yi Syllable Xy" +42094 "Yi Syllable Xyp" +42095 "Yi Syllable Xyrx" +42096 "Yi Syllable Xyr" +42097 "Yi Syllable Yit" +42098 "Yi Syllable Yix" +42099 "Yi Syllable Yi" +42100 "Yi Syllable Yip" +42101 "Yi Syllable Yiet" +42102 "Yi Syllable Yiex" +42103 "Yi Syllable Yie" +42104 "Yi Syllable Yiep" +42105 "Yi Syllable Yuot" +42106 "Yi Syllable Yuox" +42107 "Yi Syllable Yuo" +42108 "Yi Syllable Yuop" +42109 "Yi Syllable Yot" +42110 "Yi Syllable Yox" +42111 "Yi Syllable Yo" +42112 "Yi Syllable Yop" +42113 "Yi Syllable Yut" +42114 "Yi Syllable Yux" +42115 "Yi Syllable Yu" +42116 "Yi Syllable Yup" +42117 "Yi Syllable Yurx" +42118 "Yi Syllable Yur" +42119 "Yi Syllable Yyt" +42120 "Yi Syllable Yyx" +42121 "Yi Syllable Yy" +42122 "Yi Syllable Yyp" +42123 "Yi Syllable Yyrx" +42124 "Yi Syllable Yyr" +42128 "Yi Radical Qot" +42129 "Yi Radical Li" +42130 "Yi Radical Kit" +42131 "Yi Radical Nyip" +42132 "Yi Radical Cyp" +42133 "Yi Radical Ssi" +42134 "Yi Radical Ggop" +42135 "Yi Radical Gep" +42136 "Yi Radical Mi" +42137 "Yi Radical Hxit" +42138 "Yi Radical Lyr" +42139 "Yi Radical Bbut" +42140 "Yi Radical Mop" +42141 "Yi Radical Yo" +42142 "Yi Radical Put" +42143 "Yi Radical Hxuo" +42144 "Yi Radical Tat" +42145 "Yi Radical Ga" +42146 "Yi Radical Zup" +42147 "Yi Radical Cyt" +42148 "Yi Radical Ddur" +42149 "Yi Radical Bur" +42150 "Yi Radical Gguo" +42151 "Yi Radical Nyop" +42152 "Yi Radical Tu" +42153 "Yi Radical Op" +42154 "Yi Radical Jjut" +42155 "Yi Radical Zot" +42156 "Yi Radical Pyt" +42157 "Yi Radical Hmo" +42158 "Yi Radical Yit" +42159 "Yi Radical Vur" +42160 "Yi Radical Shy" +42161 "Yi Radical Vep" +42162 "Yi Radical Za" +42163 "Yi Radical Jo" +42164 "Yi Radical Nzup" +42165 "Yi Radical Jjy" +42166 "Yi Radical Got" +42167 "Yi Radical Jjie" +42168 "Yi Radical Wo" +42169 "Yi Radical Du" +42170 "Yi Radical Shur" +42171 "Yi Radical Lie" +42172 "Yi Radical Cy" +42173 "Yi Radical Cuop" +42174 "Yi Radical Cip" +42175 "Yi Radical Hxop" +42176 "Yi Radical Shat" +42177 "Yi Radical Zur" +42178 "Yi Radical Shop" +42179 "Yi Radical Che" +42180 "Yi Radical Zziet" +42181 "Yi Radical Nbie" +42182 "Yi Radical Ke" +42192 "Lisu Letter Ba" +42193 "Lisu Letter Pa" +42194 "Lisu Letter Pha" +42195 "Lisu Letter Da" +42196 "Lisu Letter Ta" +42197 "Lisu Letter Tha" +42198 "Lisu Letter Ga" +42199 "Lisu Letter Ka" +42200 "Lisu Letter Kha" +42201 "Lisu Letter Ja" +42202 "Lisu Letter Ca" +42203 "Lisu Letter Cha" +42204 "Lisu Letter Dza" +42205 "Lisu Letter Tsa" +42206 "Lisu Letter Tsha" +42207 "Lisu Letter Ma" +42208 "Lisu Letter Na" +42209 "Lisu Letter La" +42210 "Lisu Letter Sa" +42211 "Lisu Letter Zha" +42212 "Lisu Letter Za" +42213 "Lisu Letter Nga" +42214 "Lisu Letter Ha" +42215 "Lisu Letter Xa" +42216 "Lisu Letter Hha" +42217 "Lisu Letter Fa" +42218 "Lisu Letter Wa" +42219 "Lisu Letter Sha" +42220 "Lisu Letter Ya" +42221 "Lisu Letter Gha" +42222 "Lisu Letter A" +42223 "Lisu Letter Ae" +42224 "Lisu Letter E" +42225 "Lisu Letter Eu" +42226 "Lisu Letter I" +42227 "Lisu Letter O" +42228 "Lisu Letter U" +42229 "Lisu Letter Ue" +42230 "Lisu Letter Uh" +42231 "Lisu Letter Oe" +42232 "Lisu Letter Tone Mya Ti" +42233 "Lisu Letter Tone Na Po" +42234 "Lisu Letter Tone Mya Cya" +42235 "Lisu Letter Tone Mya Bo" +42236 "Lisu Letter Tone Mya Na" +42237 "Lisu Letter Tone Mya Jeu" +42238 "Lisu Punctuation Comma" +42239 "Lisu Punctuation Full Stop" +42240 "Vai Syllable Ee" +42241 "Vai Syllable Een" +42242 "Vai Syllable Hee" +42243 "Vai Syllable Wee" +42244 "Vai Syllable Ween" +42245 "Vai Syllable Pee" +42246 "Vai Syllable Bhee" +42247 "Vai Syllable Bee" +42248 "Vai Syllable Mbee" +42249 "Vai Syllable Kpee" +42250 "Vai Syllable Mgbee" +42251 "Vai Syllable Gbee" +42252 "Vai Syllable Fee" +42253 "Vai Syllable Vee" +42254 "Vai Syllable Tee" +42255 "Vai Syllable Thee" +42256 "Vai Syllable Dhee" +42257 "Vai Syllable Dhhee" +42258 "Vai Syllable Lee" +42259 "Vai Syllable Ree" +42260 "Vai Syllable Dee" +42261 "Vai Syllable Ndee" +42262 "Vai Syllable See" +42263 "Vai Syllable Shee" +42264 "Vai Syllable Zee" +42265 "Vai Syllable Zhee" +42266 "Vai Syllable Cee" +42267 "Vai Syllable Jee" +42268 "Vai Syllable Njee" +42269 "Vai Syllable Yee" +42270 "Vai Syllable Kee" +42271 "Vai Syllable Nggee" +42272 "Vai Syllable Gee" +42273 "Vai Syllable Mee" +42274 "Vai Syllable Nee" +42275 "Vai Syllable Nyee" +42276 "Vai Syllable I" +42277 "Vai Syllable In" +42278 "Vai Syllable Hi" +42279 "Vai Syllable Hin" +42280 "Vai Syllable Wi" +42281 "Vai Syllable Win" +42282 "Vai Syllable Pi" +42283 "Vai Syllable Bhi" +42284 "Vai Syllable Bi" +42285 "Vai Syllable Mbi" +42286 "Vai Syllable Kpi" +42287 "Vai Syllable Mgbi" +42288 "Vai Syllable Gbi" +42289 "Vai Syllable Fi" +42290 "Vai Syllable Vi" +42291 "Vai Syllable Ti" +42292 "Vai Syllable Thi" +42293 "Vai Syllable Dhi" +42294 "Vai Syllable Dhhi" +42295 "Vai Syllable Li" +42296 "Vai Syllable Ri" +42297 "Vai Syllable Di" +42298 "Vai Syllable Ndi" +42299 "Vai Syllable Si" +42300 "Vai Syllable Shi" +42301 "Vai Syllable Zi" +42302 "Vai Syllable Zhi" +42303 "Vai Syllable Ci" +42304 "Vai Syllable Ji" +42305 "Vai Syllable Nji" +42306 "Vai Syllable Yi" +42307 "Vai Syllable Ki" +42308 "Vai Syllable Nggi" +42309 "Vai Syllable Gi" +42310 "Vai Syllable Mi" +42311 "Vai Syllable Ni" +42312 "Vai Syllable Nyi" +42313 "Vai Syllable A" +42314 "Vai Syllable An" +42315 "Vai Syllable Ngan" +42316 "Vai Syllable Ha" +42317 "Vai Syllable Han" +42318 "Vai Syllable Wa" +42319 "Vai Syllable Wan" +42320 "Vai Syllable Pa" +42321 "Vai Syllable Bha" +42322 "Vai Syllable Ba" +42323 "Vai Syllable Mba" +42324 "Vai Syllable Kpa" +42325 "Vai Syllable Kpan" +42326 "Vai Syllable Mgba" +42327 "Vai Syllable Gba" +42328 "Vai Syllable Fa" +42329 "Vai Syllable Va" +42330 "Vai Syllable Ta" +42331 "Vai Syllable Tha" +42332 "Vai Syllable Dha" +42333 "Vai Syllable Dhha" +42334 "Vai Syllable La" +42335 "Vai Syllable Ra" +42336 "Vai Syllable Da" +42337 "Vai Syllable Nda" +42338 "Vai Syllable Sa" +42339 "Vai Syllable Sha" +42340 "Vai Syllable Za" +42341 "Vai Syllable Zha" +42342 "Vai Syllable Ca" +42343 "Vai Syllable Ja" +42344 "Vai Syllable Nja" +42345 "Vai Syllable Ya" +42346 "Vai Syllable Ka" +42347 "Vai Syllable Kan" +42348 "Vai Syllable Ngga" +42349 "Vai Syllable Ga" +42350 "Vai Syllable Ma" +42351 "Vai Syllable Na" +42352 "Vai Syllable Nya" +42353 "Vai Syllable Oo" +42354 "Vai Syllable Oon" +42355 "Vai Syllable Hoo" +42356 "Vai Syllable Woo" +42357 "Vai Syllable Woon" +42358 "Vai Syllable Poo" +42359 "Vai Syllable Bhoo" +42360 "Vai Syllable Boo" +42361 "Vai Syllable Mboo" +42362 "Vai Syllable Kpoo" +42363 "Vai Syllable Mgboo" +42364 "Vai Syllable Gboo" +42365 "Vai Syllable Foo" +42366 "Vai Syllable Voo" +42367 "Vai Syllable Too" +42368 "Vai Syllable Thoo" +42369 "Vai Syllable Dhoo" +42370 "Vai Syllable Dhhoo" +42371 "Vai Syllable Loo" +42372 "Vai Syllable Roo" +42373 "Vai Syllable Doo" +42374 "Vai Syllable Ndoo" +42375 "Vai Syllable Soo" +42376 "Vai Syllable Shoo" +42377 "Vai Syllable Zoo" +42378 "Vai Syllable Zhoo" +42379 "Vai Syllable Coo" +42380 "Vai Syllable Joo" +42381 "Vai Syllable Njoo" +42382 "Vai Syllable Yoo" +42383 "Vai Syllable Koo" +42384 "Vai Syllable Nggoo" +42385 "Vai Syllable Goo" +42386 "Vai Syllable Moo" +42387 "Vai Syllable Noo" +42388 "Vai Syllable Nyoo" +42389 "Vai Syllable U" +42390 "Vai Syllable Un" +42391 "Vai Syllable Hu" +42392 "Vai Syllable Hun" +42393 "Vai Syllable Wu" +42394 "Vai Syllable Wun" +42395 "Vai Syllable Pu" +42396 "Vai Syllable Bhu" +42397 "Vai Syllable Bu" +42398 "Vai Syllable Mbu" +42399 "Vai Syllable Kpu" +42400 "Vai Syllable Mgbu" +42401 "Vai Syllable Gbu" +42402 "Vai Syllable Fu" +42403 "Vai Syllable Vu" +42404 "Vai Syllable Tu" +42405 "Vai Syllable Thu" +42406 "Vai Syllable Dhu" +42407 "Vai Syllable Dhhu" +42408 "Vai Syllable Lu" +42409 "Vai Syllable Ru" +42410 "Vai Syllable Du" +42411 "Vai Syllable Ndu" +42412 "Vai Syllable Su" +42413 "Vai Syllable Shu" +42414 "Vai Syllable Zu" +42415 "Vai Syllable Zhu" +42416 "Vai Syllable Cu" +42417 "Vai Syllable Ju" +42418 "Vai Syllable Nju" +42419 "Vai Syllable Yu" +42420 "Vai Syllable Ku" +42421 "Vai Syllable Nggu" +42422 "Vai Syllable Gu" +42423 "Vai Syllable Mu" +42424 "Vai Syllable Nu" +42425 "Vai Syllable Nyu" +42426 "Vai Syllable O" +42427 "Vai Syllable On" +42428 "Vai Syllable Ngon" +42429 "Vai Syllable Ho" +42430 "Vai Syllable Hon" +42431 "Vai Syllable Wo" +42432 "Vai Syllable Won" +42433 "Vai Syllable Po" +42434 "Vai Syllable Bho" +42435 "Vai Syllable Bo" +42436 "Vai Syllable Mbo" +42437 "Vai Syllable Kpo" +42438 "Vai Syllable Mgbo" +42439 "Vai Syllable Gbo" +42440 "Vai Syllable Gbon" +42441 "Vai Syllable Fo" +42442 "Vai Syllable Vo" +42443 "Vai Syllable To" +42444 "Vai Syllable Tho" +42445 "Vai Syllable Dho" +42446 "Vai Syllable Dhho" +42447 "Vai Syllable Lo" +42448 "Vai Syllable Ro" +42449 "Vai Syllable Do" +42450 "Vai Syllable Ndo" +42451 "Vai Syllable So" +42452 "Vai Syllable Sho" +42453 "Vai Syllable Zo" +42454 "Vai Syllable Zho" +42455 "Vai Syllable Co" +42456 "Vai Syllable Jo" +42457 "Vai Syllable Njo" +42458 "Vai Syllable Yo" +42459 "Vai Syllable Ko" +42460 "Vai Syllable Nggo" +42461 "Vai Syllable Go" +42462 "Vai Syllable Mo" +42463 "Vai Syllable No" +42464 "Vai Syllable Nyo" +42465 "Vai Syllable E" +42466 "Vai Syllable En" +42467 "Vai Syllable Ngen" +42468 "Vai Syllable He" +42469 "Vai Syllable Hen" +42470 "Vai Syllable We" +42471 "Vai Syllable Wen" +42472 "Vai Syllable Pe" +42473 "Vai Syllable Bhe" +42474 "Vai Syllable Be" +42475 "Vai Syllable Mbe" +42476 "Vai Syllable Kpe" +42477 "Vai Syllable Kpen" +42478 "Vai Syllable Mgbe" +42479 "Vai Syllable Gbe" +42480 "Vai Syllable Gben" +42481 "Vai Syllable Fe" +42482 "Vai Syllable Ve" +42483 "Vai Syllable Te" +42484 "Vai Syllable The" +42485 "Vai Syllable Dhe" +42486 "Vai Syllable Dhhe" +42487 "Vai Syllable Le" +42488 "Vai Syllable Re" +42489 "Vai Syllable De" +42490 "Vai Syllable Nde" +42491 "Vai Syllable Se" +42492 "Vai Syllable She" +42493 "Vai Syllable Ze" +42494 "Vai Syllable Zhe" +42495 "Vai Syllable Ce" +42496 "Vai Syllable Je" +42497 "Vai Syllable Nje" +42498 "Vai Syllable Ye" +42499 "Vai Syllable Ke" +42500 "Vai Syllable Ngge" +42501 "Vai Syllable Nggen" +42502 "Vai Syllable Ge" +42503 "Vai Syllable Gen" +42504 "Vai Syllable Me" +42505 "Vai Syllable Ne" +42506 "Vai Syllable Nye" +42507 "Vai Syllable Ng" +42508 "Vai Syllable Lengthener" +42509 "Vai Comma" +42510 "Vai Full Stop" +42511 "Vai Question Mark" +42512 "Vai Syllable Ndole Fa" +42513 "Vai Syllable Ndole Ka" +42514 "Vai Syllable Ndole Soo" +42515 "Vai Symbol Feeng" +42516 "Vai Symbol Keeng" +42517 "Vai Symbol Ting" +42518 "Vai Symbol Nii" +42519 "Vai Symbol Bang" +42520 "Vai Symbol Faa" +42521 "Vai Symbol Taa" +42522 "Vai Symbol Dang" +42523 "Vai Symbol Doong" +42524 "Vai Symbol Kung" +42525 "Vai Symbol Tong" +42526 "Vai Symbol Do-O" +42527 "Vai Symbol Jong" +42528 "Vai Digit Zero" +42529 "Vai Digit One" +42530 "Vai Digit Two" +42531 "Vai Digit Three" +42532 "Vai Digit Four" +42533 "Vai Digit Five" +42534 "Vai Digit Six" +42535 "Vai Digit Seven" +42536 "Vai Digit Eight" +42537 "Vai Digit Nine" +42538 "Vai Syllable Ndole Ma" +42539 "Vai Syllable Ndole Do" +42560 "Cyrillic Capital Letter Zemlya" +42561 "Cyrillic Small Letter Zemlya" +42562 "Cyrillic Capital Letter Dzelo" +42563 "Cyrillic Small Letter Dzelo" +42564 "Cyrillic Capital Letter Reversed Dze" +42565 "Cyrillic Small Letter Reversed Dze" +42566 "Cyrillic Capital Letter Iota" +42567 "Cyrillic Small Letter Iota" +42568 "Cyrillic Capital Letter Djerv" +42569 "Cyrillic Small Letter Djerv" +42570 "Cyrillic Capital Letter Monograph Uk" +42571 "Cyrillic Small Letter Monograph Uk" +42572 "Cyrillic Capital Letter Broad Omega" +42573 "Cyrillic Small Letter Broad Omega" +42574 "Cyrillic Capital Letter Neutral Yer" +42575 "Cyrillic Small Letter Neutral Yer" +42576 "Cyrillic Capital Letter Yeru With Back Yer" +42577 "Cyrillic Small Letter Yeru With Back Yer" +42578 "Cyrillic Capital Letter Iotified Yat" +42579 "Cyrillic Small Letter Iotified Yat" +42580 "Cyrillic Capital Letter Reversed Yu" +42581 "Cyrillic Small Letter Reversed Yu" +42582 "Cyrillic Capital Letter Iotified A" +42583 "Cyrillic Small Letter Iotified A" +42584 "Cyrillic Capital Letter Closed Little Yus" +42585 "Cyrillic Small Letter Closed Little Yus" +42586 "Cyrillic Capital Letter Blended Yus" +42587 "Cyrillic Small Letter Blended Yus" +42588 "Cyrillic Capital Letter Iotified Closed Little Yus" +42589 "Cyrillic Small Letter Iotified Closed Little Yus" +42590 "Cyrillic Capital Letter Yn" +42591 "Cyrillic Small Letter Yn" +42592 "Cyrillic Capital Letter Reversed Tse" +42593 "Cyrillic Small Letter Reversed Tse" +42594 "Cyrillic Capital Letter Soft De" +42595 "Cyrillic Small Letter Soft De" +42596 "Cyrillic Capital Letter Soft El" +42597 "Cyrillic Small Letter Soft El" +42598 "Cyrillic Capital Letter Soft Em" +42599 "Cyrillic Small Letter Soft Em" +42600 "Cyrillic Capital Letter Monocular O" +42601 "Cyrillic Small Letter Monocular O" +42602 "Cyrillic Capital Letter Binocular O" +42603 "Cyrillic Small Letter Binocular O" +42604 "Cyrillic Capital Letter Double Monocular O" +42605 "Cyrillic Small Letter Double Monocular O" +42606 "Cyrillic Letter Multiocular O" +42607 "Combining Cyrillic Vzmet" +42608 "Combining Cyrillic Ten Millions Sign" +42609 "Combining Cyrillic Hundred Millions Sign" +42610 "Combining Cyrillic Thousand Millions Sign" +42611 "Slavonic Asterisk" +42612 "Combining Cyrillic Letter Ukrainian Ie" +42613 "Combining Cyrillic Letter I" +42614 "Combining Cyrillic Letter Yi" +42615 "Combining Cyrillic Letter U" +42616 "Combining Cyrillic Letter Hard Sign" +42617 "Combining Cyrillic Letter Yeru" +42618 "Combining Cyrillic Letter Soft Sign" +42619 "Combining Cyrillic Letter Omega" +42620 "Combining Cyrillic Kavyka" +42621 "Combining Cyrillic Payerok" +42622 "Cyrillic Kavyka" +42623 "Cyrillic Payerok" +42624 "Cyrillic Capital Letter Dwe" +42625 "Cyrillic Small Letter Dwe" +42626 "Cyrillic Capital Letter Dzwe" +42627 "Cyrillic Small Letter Dzwe" +42628 "Cyrillic Capital Letter Zhwe" +42629 "Cyrillic Small Letter Zhwe" +42630 "Cyrillic Capital Letter Cche" +42631 "Cyrillic Small Letter Cche" +42632 "Cyrillic Capital Letter Dzze" +42633 "Cyrillic Small Letter Dzze" +42634 "Cyrillic Capital Letter Te With Middle Hook" +42635 "Cyrillic Small Letter Te With Middle Hook" +42636 "Cyrillic Capital Letter Twe" +42637 "Cyrillic Small Letter Twe" +42638 "Cyrillic Capital Letter Tswe" +42639 "Cyrillic Small Letter Tswe" +42640 "Cyrillic Capital Letter Tsse" +42641 "Cyrillic Small Letter Tsse" +42642 "Cyrillic Capital Letter Tche" +42643 "Cyrillic Small Letter Tche" +42644 "Cyrillic Capital Letter Hwe" +42645 "Cyrillic Small Letter Hwe" +42646 "Cyrillic Capital Letter Shwe" +42647 "Cyrillic Small Letter Shwe" +42655 "Combining Cyrillic Letter Iotified E" +42656 "Bamum Letter A" +42657 "Bamum Letter Ka" +42658 "Bamum Letter U" +42659 "Bamum Letter Ku" +42660 "Bamum Letter Ee" +42661 "Bamum Letter Ree" +42662 "Bamum Letter Tae" +42663 "Bamum Letter O" +42664 "Bamum Letter Nyi" +42665 "Bamum Letter I" +42666 "Bamum Letter La" +42667 "Bamum Letter Pa" +42668 "Bamum Letter Rii" +42669 "Bamum Letter Riee" +42670 "Bamum Letter Leeee" +42671 "Bamum Letter Meeee" +42672 "Bamum Letter Taa" +42673 "Bamum Letter Ndaa" +42674 "Bamum Letter Njaem" +42675 "Bamum Letter M" +42676 "Bamum Letter Suu" +42677 "Bamum Letter Mu" +42678 "Bamum Letter Shii" +42679 "Bamum Letter Si" +42680 "Bamum Letter Sheux" +42681 "Bamum Letter Seux" +42682 "Bamum Letter Kyee" +42683 "Bamum Letter Ket" +42684 "Bamum Letter Nuae" +42685 "Bamum Letter Nu" +42686 "Bamum Letter Njuae" +42687 "Bamum Letter Yoq" +42688 "Bamum Letter Shu" +42689 "Bamum Letter Yuq" +42690 "Bamum Letter Ya" +42691 "Bamum Letter Nsha" +42692 "Bamum Letter Keux" +42693 "Bamum Letter Peux" +42694 "Bamum Letter Njee" +42695 "Bamum Letter Ntee" +42696 "Bamum Letter Pue" +42697 "Bamum Letter Wue" +42698 "Bamum Letter Pee" +42699 "Bamum Letter Fee" +42700 "Bamum Letter Ru" +42701 "Bamum Letter Lu" +42702 "Bamum Letter Mi" +42703 "Bamum Letter Ni" +42704 "Bamum Letter Reux" +42705 "Bamum Letter Rae" +42706 "Bamum Letter Ken" +42707 "Bamum Letter Ngkwaen" +42708 "Bamum Letter Ngga" +42709 "Bamum Letter Nga" +42710 "Bamum Letter Sho" +42711 "Bamum Letter Puae" +42712 "Bamum Letter Fu" +42713 "Bamum Letter Fom" +42714 "Bamum Letter Wa" +42715 "Bamum Letter Na" +42716 "Bamum Letter Li" +42717 "Bamum Letter Pi" +42718 "Bamum Letter Loq" +42719 "Bamum Letter Ko" +42720 "Bamum Letter Mben" +42721 "Bamum Letter Ren" +42722 "Bamum Letter Men" +42723 "Bamum Letter Ma" +42724 "Bamum Letter Ti" +42725 "Bamum Letter Ki" +42726 "Bamum Letter Mo" +42727 "Bamum Letter Mbaa" +42728 "Bamum Letter Tet" +42729 "Bamum Letter Kpa" +42730 "Bamum Letter Ten" +42731 "Bamum Letter Ntuu" +42732 "Bamum Letter Samba" +42733 "Bamum Letter Faamae" +42734 "Bamum Letter Kovuu" +42735 "Bamum Letter Koghom" +42736 "Bamum Combining Mark Koqndon" +42737 "Bamum Combining Mark Tukwentis" +42738 "Bamum Njaemli" +42739 "Bamum Full Stop" +42740 "Bamum Colon" +42741 "Bamum Comma" +42742 "Bamum Semicolon" +42743 "Bamum Question Mark" +42752 "Modifier Letter Chinese Tone Yin Ping" +42753 "Modifier Letter Chinese Tone Yang Ping" +42754 "Modifier Letter Chinese Tone Yin Shang" +42755 "Modifier Letter Chinese Tone Yang Shang" +42756 "Modifier Letter Chinese Tone Yin Qu" +42757 "Modifier Letter Chinese Tone Yang Qu" +42758 "Modifier Letter Chinese Tone Yin Ru" +42759 "Modifier Letter Chinese Tone Yang Ru" +42760 "Modifier Letter Extra-High Dotted Tone Bar" +42761 "Modifier Letter High Dotted Tone Bar" +42762 "Modifier Letter Mid Dotted Tone Bar" +42763 "Modifier Letter Low Dotted Tone Bar" +42764 "Modifier Letter Extra-Low Dotted Tone Bar" +42765 "Modifier Letter Extra-High Dotted Left-Stem Tone Bar" +42766 "Modifier Letter High Dotted Left-Stem Tone Bar" +42767 "Modifier Letter Mid Dotted Left-Stem Tone Bar" +42768 "Modifier Letter Low Dotted Left-Stem Tone Bar" +42769 "Modifier Letter Extra-Low Dotted Left-Stem Tone Bar" +42770 "Modifier Letter Extra-High Left-Stem Tone Bar" +42771 "Modifier Letter High Left-Stem Tone Bar" +42772 "Modifier Letter Mid Left-Stem Tone Bar" +42773 "Modifier Letter Low Left-Stem Tone Bar" +42774 "Modifier Letter Extra-Low Left-Stem Tone Bar" +42775 "Modifier Letter Dot Vertical Bar" +42776 "Modifier Letter Dot Slash" +42777 "Modifier Letter Dot Horizontal Bar" +42778 "Modifier Letter Lower Right Corner Angle" +42779 "Modifier Letter Raised Up Arrow" +42780 "Modifier Letter Raised Down Arrow" +42781 "Modifier Letter Raised Exclamation Mark" +42782 "Modifier Letter Raised Inverted Exclamation Mark" +42783 "Modifier Letter Low Inverted Exclamation Mark" +42784 "Modifier Letter Stress And High Tone" +42785 "Modifier Letter Stress And Low Tone" +42786 "Latin Capital Letter Egyptological Alef" +42787 "Latin Small Letter Egyptological Alef" +42788 "Latin Capital Letter Egyptological Ain" +42789 "Latin Small Letter Egyptological Ain" +42790 "Latin Capital Letter Heng" +42791 "Latin Small Letter Heng" +42792 "Latin Capital Letter Tz" +42793 "Latin Small Letter Tz" +42794 "Latin Capital Letter Tresillo" +42795 "Latin Small Letter Tresillo" +42796 "Latin Capital Letter Cuatrillo" +42797 "Latin Small Letter Cuatrillo" +42798 "Latin Capital Letter Cuatrillo With Comma" +42799 "Latin Small Letter Cuatrillo With Comma" +42800 "Latin Letter Small Capital F" +42801 "Latin Letter Small Capital S" +42802 "Latin Capital Letter Aa" +42803 "Latin Small Letter Aa" +42804 "Latin Capital Letter Ao" +42805 "Latin Small Letter Ao" +42806 "Latin Capital Letter Au" +42807 "Latin Small Letter Au" +42808 "Latin Capital Letter Av" +42809 "Latin Small Letter Av" +42810 "Latin Capital Letter Av With Horizontal Bar" +42811 "Latin Small Letter Av With Horizontal Bar" +42812 "Latin Capital Letter Ay" +42813 "Latin Small Letter Ay" +42814 "Latin Capital Letter Reversed C With Dot" +42815 "Latin Small Letter Reversed C With Dot" +42816 "Latin Capital Letter K With Stroke" +42817 "Latin Small Letter K With Stroke" +42818 "Latin Capital Letter K With Diagonal Stroke" +42819 "Latin Small Letter K With Diagonal Stroke" +42820 "Latin Capital Letter K With Stroke And Diagonal Stroke" +42821 "Latin Small Letter K With Stroke And Diagonal Stroke" +42822 "Latin Capital Letter Broken L" +42823 "Latin Small Letter Broken L" +42824 "Latin Capital Letter L With High Stroke" +42825 "Latin Small Letter L With High Stroke" +42826 "Latin Capital Letter O With Long Stroke Overlay" +42827 "Latin Small Letter O With Long Stroke Overlay" +42828 "Latin Capital Letter O With Loop" +42829 "Latin Small Letter O With Loop" +42830 "Latin Capital Letter Oo" +42831 "Latin Small Letter Oo" +42832 "Latin Capital Letter P With Stroke Through Descender" +42833 "Latin Small Letter P With Stroke Through Descender" +42834 "Latin Capital Letter P With Flourish" +42835 "Latin Small Letter P With Flourish" +42836 "Latin Capital Letter P With Squirrel Tail" +42837 "Latin Small Letter P With Squirrel Tail" +42838 "Latin Capital Letter Q With Stroke Through Descender" +42839 "Latin Small Letter Q With Stroke Through Descender" +42840 "Latin Capital Letter Q With Diagonal Stroke" +42841 "Latin Small Letter Q With Diagonal Stroke" +42842 "Latin Capital Letter R Rotunda" +42843 "Latin Small Letter R Rotunda" +42844 "Latin Capital Letter Rum Rotunda" +42845 "Latin Small Letter Rum Rotunda" +42846 "Latin Capital Letter V With Diagonal Stroke" +42847 "Latin Small Letter V With Diagonal Stroke" +42848 "Latin Capital Letter Vy" +42849 "Latin Small Letter Vy" +42850 "Latin Capital Letter Visigothic Z" +42851 "Latin Small Letter Visigothic Z" +42852 "Latin Capital Letter Thorn With Stroke" +42853 "Latin Small Letter Thorn With Stroke" +42854 "Latin Capital Letter Thorn With Stroke Through Descender" +42855 "Latin Small Letter Thorn With Stroke Through Descender" +42856 "Latin Capital Letter Vend" +42857 "Latin Small Letter Vend" +42858 "Latin Capital Letter Et" +42859 "Latin Small Letter Et" +42860 "Latin Capital Letter Is" +42861 "Latin Small Letter Is" +42862 "Latin Capital Letter Con" +42863 "Latin Small Letter Con" +42864 "Modifier Letter Us" +42865 "Latin Small Letter Dum" +42866 "Latin Small Letter Lum" +42867 "Latin Small Letter Mum" +42868 "Latin Small Letter Num" +42869 "Latin Small Letter Rum" +42870 "Latin Letter Small Capital Rum" +42871 "Latin Small Letter Tum" +42872 "Latin Small Letter Um" +42873 "Latin Capital Letter Insular D" +42874 "Latin Small Letter Insular D" +42875 "Latin Capital Letter Insular F" +42876 "Latin Small Letter Insular F" +42877 "Latin Capital Letter Insular G" +42878 "Latin Capital Letter Turned Insular G" +42879 "Latin Small Letter Turned Insular G" +42880 "Latin Capital Letter Turned L" +42881 "Latin Small Letter Turned L" +42882 "Latin Capital Letter Insular R" +42883 "Latin Small Letter Insular R" +42884 "Latin Capital Letter Insular S" +42885 "Latin Small Letter Insular S" +42886 "Latin Capital Letter Insular T" +42887 "Latin Small Letter Insular T" +42888 "Modifier Letter Low Circumflex Accent" +42889 "Modifier Letter Colon" +42890 "Modifier Letter Short Equals Sign" +42891 "Latin Capital Letter Saltillo" +42892 "Latin Small Letter Saltillo" +42893 "Latin Capital Letter Turned H" +42894 "Latin Small Letter L With Retroflex Hook And Belt" +42896 "Latin Capital Letter N With Descender" +42897 "Latin Small Letter N With Descender" +42898 "Latin Capital Letter C With Bar" +42899 "Latin Small Letter C With Bar" +42912 "Latin Capital Letter G With Oblique Stroke" +42913 "Latin Small Letter G With Oblique Stroke" +42914 "Latin Capital Letter K With Oblique Stroke" +42915 "Latin Small Letter K With Oblique Stroke" +42916 "Latin Capital Letter N With Oblique Stroke" +42917 "Latin Small Letter N With Oblique Stroke" +42918 "Latin Capital Letter R With Oblique Stroke" +42919 "Latin Small Letter R With Oblique Stroke" +42920 "Latin Capital Letter S With Oblique Stroke" +42921 "Latin Small Letter S With Oblique Stroke" +42922 "Latin Capital Letter H With Hook" +43000 "Modifier Letter Capital H With Stroke" +43001 "Modifier Letter Small Ligature Oe" +43002 "Latin Letter Small Capital Turned M" +43003 "Latin Epigraphic Letter Reversed F" +43004 "Latin Epigraphic Letter Reversed P" +43005 "Latin Epigraphic Letter Inverted M" +43006 "Latin Epigraphic Letter I Longa" +43007 "Latin Epigraphic Letter Archaic M" +43008 "Syloti Nagri Letter A" +43009 "Syloti Nagri Letter I" +43010 "Syloti Nagri Sign Dvisvara" +43011 "Syloti Nagri Letter U" +43012 "Syloti Nagri Letter E" +43013 "Syloti Nagri Letter O" +43014 "Syloti Nagri Sign Hasanta" +43015 "Syloti Nagri Letter Ko" +43016 "Syloti Nagri Letter Kho" +43017 "Syloti Nagri Letter Go" +43018 "Syloti Nagri Letter Gho" +43019 "Syloti Nagri Sign Anusvara" +43020 "Syloti Nagri Letter Co" +43021 "Syloti Nagri Letter Cho" +43022 "Syloti Nagri Letter Jo" +43023 "Syloti Nagri Letter Jho" +43024 "Syloti Nagri Letter Tto" +43025 "Syloti Nagri Letter Ttho" +43026 "Syloti Nagri Letter Ddo" +43027 "Syloti Nagri Letter Ddho" +43028 "Syloti Nagri Letter To" +43029 "Syloti Nagri Letter Tho" +43030 "Syloti Nagri Letter Do" +43031 "Syloti Nagri Letter Dho" +43032 "Syloti Nagri Letter No" +43033 "Syloti Nagri Letter Po" +43034 "Syloti Nagri Letter Pho" +43035 "Syloti Nagri Letter Bo" +43036 "Syloti Nagri Letter Bho" +43037 "Syloti Nagri Letter Mo" +43038 "Syloti Nagri Letter Ro" +43039 "Syloti Nagri Letter Lo" +43040 "Syloti Nagri Letter Rro" +43041 "Syloti Nagri Letter So" +43042 "Syloti Nagri Letter Ho" +43043 "Syloti Nagri Vowel Sign A" +43044 "Syloti Nagri Vowel Sign I" +43045 "Syloti Nagri Vowel Sign U" +43046 "Syloti Nagri Vowel Sign E" +43047 "Syloti Nagri Vowel Sign Oo" +43048 "Syloti Nagri Poetry Mark-1" +43049 "Syloti Nagri Poetry Mark-2" +43050 "Syloti Nagri Poetry Mark-3" +43051 "Syloti Nagri Poetry Mark-4" +43056 "North Indic Fraction One Quarter" +43057 "North Indic Fraction One Half" +43058 "North Indic Fraction Three Quarters" +43059 "North Indic Fraction One Sixteenth" +43060 "North Indic Fraction One Eighth" +43061 "North Indic Fraction Three Sixteenths" +43062 "North Indic Quarter Mark" +43063 "North Indic Placeholder Mark" +43064 "North Indic Rupee Mark" +43065 "North Indic Quantity Mark" +43072 "Phags-Pa Letter Ka" +43073 "Phags-Pa Letter Kha" +43074 "Phags-Pa Letter Ga" +43075 "Phags-Pa Letter Nga" +43076 "Phags-Pa Letter Ca" +43077 "Phags-Pa Letter Cha" +43078 "Phags-Pa Letter Ja" +43079 "Phags-Pa Letter Nya" +43080 "Phags-Pa Letter Ta" +43081 "Phags-Pa Letter Tha" +43082 "Phags-Pa Letter Da" +43083 "Phags-Pa Letter Na" +43084 "Phags-Pa Letter Pa" +43085 "Phags-Pa Letter Pha" +43086 "Phags-Pa Letter Ba" +43087 "Phags-Pa Letter Ma" +43088 "Phags-Pa Letter Tsa" +43089 "Phags-Pa Letter Tsha" +43090 "Phags-Pa Letter Dza" +43091 "Phags-Pa Letter Wa" +43092 "Phags-Pa Letter Zha" +43093 "Phags-Pa Letter Za" +43094 "Phags-Pa Letter Small A" +43095 "Phags-Pa Letter Ya" +43096 "Phags-Pa Letter Ra" +43097 "Phags-Pa Letter La" +43098 "Phags-Pa Letter Sha" +43099 "Phags-Pa Letter Sa" +43100 "Phags-Pa Letter Ha" +43101 "Phags-Pa Letter A" +43102 "Phags-Pa Letter I" +43103 "Phags-Pa Letter U" +43104 "Phags-Pa Letter E" +43105 "Phags-Pa Letter O" +43106 "Phags-Pa Letter Qa" +43107 "Phags-Pa Letter Xa" +43108 "Phags-Pa Letter Fa" +43109 "Phags-Pa Letter Gga" +43110 "Phags-Pa Letter Ee" +43111 "Phags-Pa Subjoined Letter Wa" +43112 "Phags-Pa Subjoined Letter Ya" +43113 "Phags-Pa Letter Tta" +43114 "Phags-Pa Letter Ttha" +43115 "Phags-Pa Letter Dda" +43116 "Phags-Pa Letter Nna" +43117 "Phags-Pa Letter Alternate Ya" +43118 "Phags-Pa Letter Voiceless Sha" +43119 "Phags-Pa Letter Voiced Ha" +43120 "Phags-Pa Letter Aspirated Fa" +43121 "Phags-Pa Subjoined Letter Ra" +43122 "Phags-Pa Superfixed Letter Ra" +43123 "Phags-Pa Letter Candrabindu" +43124 "Phags-Pa Single Head Mark" +43125 "Phags-Pa Double Head Mark" +43126 "Phags-Pa Mark Shad" +43127 "Phags-Pa Mark Double Shad" +43136 "Saurashtra Sign Anusvara" +43137 "Saurashtra Sign Visarga" +43138 "Saurashtra Letter A" +43139 "Saurashtra Letter Aa" +43140 "Saurashtra Letter I" +43141 "Saurashtra Letter Ii" +43142 "Saurashtra Letter U" +43143 "Saurashtra Letter Uu" +43144 "Saurashtra Letter Vocalic R" +43145 "Saurashtra Letter Vocalic Rr" +43146 "Saurashtra Letter Vocalic L" +43147 "Saurashtra Letter Vocalic Ll" +43148 "Saurashtra Letter E" +43149 "Saurashtra Letter Ee" +43150 "Saurashtra Letter Ai" +43151 "Saurashtra Letter O" +43152 "Saurashtra Letter Oo" +43153 "Saurashtra Letter Au" +43154 "Saurashtra Letter Ka" +43155 "Saurashtra Letter Kha" +43156 "Saurashtra Letter Ga" +43157 "Saurashtra Letter Gha" +43158 "Saurashtra Letter Nga" +43159 "Saurashtra Letter Ca" +43160 "Saurashtra Letter Cha" +43161 "Saurashtra Letter Ja" +43162 "Saurashtra Letter Jha" +43163 "Saurashtra Letter Nya" +43164 "Saurashtra Letter Tta" +43165 "Saurashtra Letter Ttha" +43166 "Saurashtra Letter Dda" +43167 "Saurashtra Letter Ddha" +43168 "Saurashtra Letter Nna" +43169 "Saurashtra Letter Ta" +43170 "Saurashtra Letter Tha" +43171 "Saurashtra Letter Da" +43172 "Saurashtra Letter Dha" +43173 "Saurashtra Letter Na" +43174 "Saurashtra Letter Pa" +43175 "Saurashtra Letter Pha" +43176 "Saurashtra Letter Ba" +43177 "Saurashtra Letter Bha" +43178 "Saurashtra Letter Ma" +43179 "Saurashtra Letter Ya" +43180 "Saurashtra Letter Ra" +43181 "Saurashtra Letter La" +43182 "Saurashtra Letter Va" +43183 "Saurashtra Letter Sha" +43184 "Saurashtra Letter Ssa" +43185 "Saurashtra Letter Sa" +43186 "Saurashtra Letter Ha" +43187 "Saurashtra Letter Lla" +43188 "Saurashtra Consonant Sign Haaru" +43189 "Saurashtra Vowel Sign Aa" +43190 "Saurashtra Vowel Sign I" +43191 "Saurashtra Vowel Sign Ii" +43192 "Saurashtra Vowel Sign U" +43193 "Saurashtra Vowel Sign Uu" +43194 "Saurashtra Vowel Sign Vocalic R" +43195 "Saurashtra Vowel Sign Vocalic Rr" +43196 "Saurashtra Vowel Sign Vocalic L" +43197 "Saurashtra Vowel Sign Vocalic Ll" +43198 "Saurashtra Vowel Sign E" +43199 "Saurashtra Vowel Sign Ee" +43200 "Saurashtra Vowel Sign Ai" +43201 "Saurashtra Vowel Sign O" +43202 "Saurashtra Vowel Sign Oo" +43203 "Saurashtra Vowel Sign Au" +43204 "Saurashtra Sign Virama" +43214 "Saurashtra Danda" +43215 "Saurashtra Double Danda" +43216 "Saurashtra Digit Zero" +43217 "Saurashtra Digit One" +43218 "Saurashtra Digit Two" +43219 "Saurashtra Digit Three" +43220 "Saurashtra Digit Four" +43221 "Saurashtra Digit Five" +43222 "Saurashtra Digit Six" +43223 "Saurashtra Digit Seven" +43224 "Saurashtra Digit Eight" +43225 "Saurashtra Digit Nine" +43232 "Combining Devanagari Digit Zero" +43233 "Combining Devanagari Digit One" +43234 "Combining Devanagari Digit Two" +43235 "Combining Devanagari Digit Three" +43236 "Combining Devanagari Digit Four" +43237 "Combining Devanagari Digit Five" +43238 "Combining Devanagari Digit Six" +43239 "Combining Devanagari Digit Seven" +43240 "Combining Devanagari Digit Eight" +43241 "Combining Devanagari Digit Nine" +43242 "Combining Devanagari Letter A" +43243 "Combining Devanagari Letter U" +43244 "Combining Devanagari Letter Ka" +43245 "Combining Devanagari Letter Na" +43246 "Combining Devanagari Letter Pa" +43247 "Combining Devanagari Letter Ra" +43248 "Combining Devanagari Letter Vi" +43249 "Combining Devanagari Sign Avagraha" +43250 "Devanagari Sign Spacing Candrabindu" +43251 "Devanagari Sign Candrabindu Virama" +43252 "Devanagari Sign Double Candrabindu Virama" +43253 "Devanagari Sign Candrabindu Two" +43254 "Devanagari Sign Candrabindu Three" +43255 "Devanagari Sign Candrabindu Avagraha" +43256 "Devanagari Sign Pushpika" +43257 "Devanagari Gap Filler" +43258 "Devanagari Caret" +43259 "Devanagari Headstroke" +43264 "Kayah Li Digit Zero" +43265 "Kayah Li Digit One" +43266 "Kayah Li Digit Two" +43267 "Kayah Li Digit Three" +43268 "Kayah Li Digit Four" +43269 "Kayah Li Digit Five" +43270 "Kayah Li Digit Six" +43271 "Kayah Li Digit Seven" +43272 "Kayah Li Digit Eight" +43273 "Kayah Li Digit Nine" +43274 "Kayah Li Letter Ka" +43275 "Kayah Li Letter Kha" +43276 "Kayah Li Letter Ga" +43277 "Kayah Li Letter Nga" +43278 "Kayah Li Letter Sa" +43279 "Kayah Li Letter Sha" +43280 "Kayah Li Letter Za" +43281 "Kayah Li Letter Nya" +43282 "Kayah Li Letter Ta" +43283 "Kayah Li Letter Hta" +43284 "Kayah Li Letter Na" +43285 "Kayah Li Letter Pa" +43286 "Kayah Li Letter Pha" +43287 "Kayah Li Letter Ma" +43288 "Kayah Li Letter Da" +43289 "Kayah Li Letter Ba" +43290 "Kayah Li Letter Ra" +43291 "Kayah Li Letter Ya" +43292 "Kayah Li Letter La" +43293 "Kayah Li Letter Wa" +43294 "Kayah Li Letter Tha" +43295 "Kayah Li Letter Ha" +43296 "Kayah Li Letter Va" +43297 "Kayah Li Letter Ca" +43298 "Kayah Li Letter A" +43299 "Kayah Li Letter Oe" +43300 "Kayah Li Letter I" +43301 "Kayah Li Letter Oo" +43302 "Kayah Li Vowel Ue" +43303 "Kayah Li Vowel E" +43304 "Kayah Li Vowel U" +43305 "Kayah Li Vowel Ee" +43306 "Kayah Li Vowel O" +43307 "Kayah Li Tone Plophu" +43308 "Kayah Li Tone Calya" +43309 "Kayah Li Tone Calya Plophu" +43310 "Kayah Li Sign Cwi" +43311 "Kayah Li Sign Shya" +43312 "Rejang Letter Ka" +43313 "Rejang Letter Ga" +43314 "Rejang Letter Nga" +43315 "Rejang Letter Ta" +43316 "Rejang Letter Da" +43317 "Rejang Letter Na" +43318 "Rejang Letter Pa" +43319 "Rejang Letter Ba" +43320 "Rejang Letter Ma" +43321 "Rejang Letter Ca" +43322 "Rejang Letter Ja" +43323 "Rejang Letter Nya" +43324 "Rejang Letter Sa" +43325 "Rejang Letter Ra" +43326 "Rejang Letter La" +43327 "Rejang Letter Ya" +43328 "Rejang Letter Wa" +43329 "Rejang Letter Ha" +43330 "Rejang Letter Mba" +43331 "Rejang Letter Ngga" +43332 "Rejang Letter Nda" +43333 "Rejang Letter Nyja" +43334 "Rejang Letter A" +43335 "Rejang Vowel Sign I" +43336 "Rejang Vowel Sign U" +43337 "Rejang Vowel Sign E" +43338 "Rejang Vowel Sign Ai" +43339 "Rejang Vowel Sign O" +43340 "Rejang Vowel Sign Au" +43341 "Rejang Vowel Sign Eu" +43342 "Rejang Vowel Sign Ea" +43343 "Rejang Consonant Sign Ng" +43344 "Rejang Consonant Sign N" +43345 "Rejang Consonant Sign R" +43346 "Rejang Consonant Sign H" +43347 "Rejang Virama" +43359 "Rejang Section Mark" +43360 "Hangul Choseong Tikeut-Mieum" +43361 "Hangul Choseong Tikeut-Pieup" +43362 "Hangul Choseong Tikeut-Sios" +43363 "Hangul Choseong Tikeut-Cieuc" +43364 "Hangul Choseong Rieul-Kiyeok" +43365 "Hangul Choseong Rieul-Ssangkiyeok" +43366 "Hangul Choseong Rieul-Tikeut" +43367 "Hangul Choseong Rieul-Ssangtikeut" +43368 "Hangul Choseong Rieul-Mieum" +43369 "Hangul Choseong Rieul-Pieup" +43370 "Hangul Choseong Rieul-Ssangpieup" +43371 "Hangul Choseong Rieul-Kapyeounpieup" +43372 "Hangul Choseong Rieul-Sios" +43373 "Hangul Choseong Rieul-Cieuc" +43374 "Hangul Choseong Rieul-Khieukh" +43375 "Hangul Choseong Mieum-Kiyeok" +43376 "Hangul Choseong Mieum-Tikeut" +43377 "Hangul Choseong Mieum-Sios" +43378 "Hangul Choseong Pieup-Sios-Thieuth" +43379 "Hangul Choseong Pieup-Khieukh" +43380 "Hangul Choseong Pieup-Hieuh" +43381 "Hangul Choseong Ssangsios-Pieup" +43382 "Hangul Choseong Ieung-Rieul" +43383 "Hangul Choseong Ieung-Hieuh" +43384 "Hangul Choseong Ssangcieuc-Hieuh" +43385 "Hangul Choseong Ssangthieuth" +43386 "Hangul Choseong Phieuph-Hieuh" +43387 "Hangul Choseong Hieuh-Sios" +43388 "Hangul Choseong Ssangyeorinhieuh" +43392 "Javanese Sign Panyangga" +43393 "Javanese Sign Cecak" +43394 "Javanese Sign Layar" +43395 "Javanese Sign Wignyan" +43396 "Javanese Letter A" +43397 "Javanese Letter I Kawi" +43398 "Javanese Letter I" +43399 "Javanese Letter Ii" +43400 "Javanese Letter U" +43401 "Javanese Letter Pa Cerek" +43402 "Javanese Letter Nga Lelet" +43403 "Javanese Letter Nga Lelet Raswadi" +43404 "Javanese Letter E" +43405 "Javanese Letter Ai" +43406 "Javanese Letter O" +43407 "Javanese Letter Ka" +43408 "Javanese Letter Ka Sasak" +43409 "Javanese Letter Ka Murda" +43410 "Javanese Letter Ga" +43411 "Javanese Letter Ga Murda" +43412 "Javanese Letter Nga" +43413 "Javanese Letter Ca" +43414 "Javanese Letter Ca Murda" +43415 "Javanese Letter Ja" +43416 "Javanese Letter Nya Murda" +43417 "Javanese Letter Ja Mahaprana" +43418 "Javanese Letter Nya" +43419 "Javanese Letter Tta" +43420 "Javanese Letter Tta Mahaprana" +43421 "Javanese Letter Dda" +43422 "Javanese Letter Dda Mahaprana" +43423 "Javanese Letter Na Murda" +43424 "Javanese Letter Ta" +43425 "Javanese Letter Ta Murda" +43426 "Javanese Letter Da" +43427 "Javanese Letter Da Mahaprana" +43428 "Javanese Letter Na" +43429 "Javanese Letter Pa" +43430 "Javanese Letter Pa Murda" +43431 "Javanese Letter Ba" +43432 "Javanese Letter Ba Murda" +43433 "Javanese Letter Ma" +43434 "Javanese Letter Ya" +43435 "Javanese Letter Ra" +43436 "Javanese Letter Ra Agung" +43437 "Javanese Letter La" +43438 "Javanese Letter Wa" +43439 "Javanese Letter Sa Murda" +43440 "Javanese Letter Sa Mahaprana" +43441 "Javanese Letter Sa" +43442 "Javanese Letter Ha" +43443 "Javanese Sign Cecak Telu" +43444 "Javanese Vowel Sign Tarung" +43445 "Javanese Vowel Sign Tolong" +43446 "Javanese Vowel Sign Wulu" +43447 "Javanese Vowel Sign Wulu Melik" +43448 "Javanese Vowel Sign Suku" +43449 "Javanese Vowel Sign Suku Mendut" +43450 "Javanese Vowel Sign Taling" +43451 "Javanese Vowel Sign Dirga Mure" +43452 "Javanese Vowel Sign Pepet" +43453 "Javanese Consonant Sign Keret" +43454 "Javanese Consonant Sign Pengkal" +43455 "Javanese Consonant Sign Cakra" +43456 "Javanese Pangkon" +43457 "Javanese Left Rerenggan" +43458 "Javanese Right Rerenggan" +43459 "Javanese Pada Andap" +43460 "Javanese Pada Madya" +43461 "Javanese Pada Luhur" +43462 "Javanese Pada Windu" +43463 "Javanese Pada Pangkat" +43464 "Javanese Pada Lingsa" +43465 "Javanese Pada Lungsi" +43466 "Javanese Pada Adeg" +43467 "Javanese Pada Adeg Adeg" +43468 "Javanese Pada Piseleh" +43469 "Javanese Turned Pada Piseleh" +43471 "Javanese Pangrangkep" +43472 "Javanese Digit Zero" +43473 "Javanese Digit One" +43474 "Javanese Digit Two" +43475 "Javanese Digit Three" +43476 "Javanese Digit Four" +43477 "Javanese Digit Five" +43478 "Javanese Digit Six" +43479 "Javanese Digit Seven" +43480 "Javanese Digit Eight" +43481 "Javanese Digit Nine" +43486 "Javanese Pada Tirta Tumetes" +43487 "Javanese Pada Isen-Isen" +43520 "Cham Letter A" +43521 "Cham Letter I" +43522 "Cham Letter U" +43523 "Cham Letter E" +43524 "Cham Letter Ai" +43525 "Cham Letter O" +43526 "Cham Letter Ka" +43527 "Cham Letter Kha" +43528 "Cham Letter Ga" +43529 "Cham Letter Gha" +43530 "Cham Letter Ngue" +43531 "Cham Letter Nga" +43532 "Cham Letter Cha" +43533 "Cham Letter Chha" +43534 "Cham Letter Ja" +43535 "Cham Letter Jha" +43536 "Cham Letter Nhue" +43537 "Cham Letter Nha" +43538 "Cham Letter Nhja" +43539 "Cham Letter Ta" +43540 "Cham Letter Tha" +43541 "Cham Letter Da" +43542 "Cham Letter Dha" +43543 "Cham Letter Nue" +43544 "Cham Letter Na" +43545 "Cham Letter Dda" +43546 "Cham Letter Pa" +43547 "Cham Letter Ppa" +43548 "Cham Letter Pha" +43549 "Cham Letter Ba" +43550 "Cham Letter Bha" +43551 "Cham Letter Mue" +43552 "Cham Letter Ma" +43553 "Cham Letter Bba" +43554 "Cham Letter Ya" +43555 "Cham Letter Ra" +43556 "Cham Letter La" +43557 "Cham Letter Va" +43558 "Cham Letter Ssa" +43559 "Cham Letter Sa" +43560 "Cham Letter Ha" +43561 "Cham Vowel Sign Aa" +43562 "Cham Vowel Sign I" +43563 "Cham Vowel Sign Ii" +43564 "Cham Vowel Sign Ei" +43565 "Cham Vowel Sign U" +43566 "Cham Vowel Sign Oe" +43567 "Cham Vowel Sign O" +43568 "Cham Vowel Sign Ai" +43569 "Cham Vowel Sign Au" +43570 "Cham Vowel Sign Ue" +43571 "Cham Consonant Sign Ya" +43572 "Cham Consonant Sign Ra" +43573 "Cham Consonant Sign La" +43574 "Cham Consonant Sign Wa" +43584 "Cham Letter Final K" +43585 "Cham Letter Final G" +43586 "Cham Letter Final Ng" +43587 "Cham Consonant Sign Final Ng" +43588 "Cham Letter Final Ch" +43589 "Cham Letter Final T" +43590 "Cham Letter Final N" +43591 "Cham Letter Final P" +43592 "Cham Letter Final Y" +43593 "Cham Letter Final R" +43594 "Cham Letter Final L" +43595 "Cham Letter Final Ss" +43596 "Cham Consonant Sign Final M" +43597 "Cham Consonant Sign Final H" +43600 "Cham Digit Zero" +43601 "Cham Digit One" +43602 "Cham Digit Two" +43603 "Cham Digit Three" +43604 "Cham Digit Four" +43605 "Cham Digit Five" +43606 "Cham Digit Six" +43607 "Cham Digit Seven" +43608 "Cham Digit Eight" +43609 "Cham Digit Nine" +43612 "Cham Punctuation Spiral" +43613 "Cham Punctuation Danda" +43614 "Cham Punctuation Double Danda" +43615 "Cham Punctuation Triple Danda" +43616 "Myanmar Letter Khamti Ga" +43617 "Myanmar Letter Khamti Ca" +43618 "Myanmar Letter Khamti Cha" +43619 "Myanmar Letter Khamti Ja" +43620 "Myanmar Letter Khamti Jha" +43621 "Myanmar Letter Khamti Nya" +43622 "Myanmar Letter Khamti Tta" +43623 "Myanmar Letter Khamti Ttha" +43624 "Myanmar Letter Khamti Dda" +43625 "Myanmar Letter Khamti Ddha" +43626 "Myanmar Letter Khamti Dha" +43627 "Myanmar Letter Khamti Na" +43628 "Myanmar Letter Khamti Sa" +43629 "Myanmar Letter Khamti Ha" +43630 "Myanmar Letter Khamti Hha" +43631 "Myanmar Letter Khamti Fa" +43632 "Myanmar Modifier Letter Khamti Reduplication" +43633 "Myanmar Letter Khamti Xa" +43634 "Myanmar Letter Khamti Za" +43635 "Myanmar Letter Khamti Ra" +43636 "Myanmar Logogram Khamti Oay" +43637 "Myanmar Logogram Khamti Qn" +43638 "Myanmar Logogram Khamti Hm" +43639 "Myanmar Symbol Aiton Exclamation" +43640 "Myanmar Symbol Aiton One" +43641 "Myanmar Symbol Aiton Two" +43642 "Myanmar Letter Aiton Ra" +43643 "Myanmar Sign Pao Karen Tone" +43648 "Tai Viet Letter Low Ko" +43649 "Tai Viet Letter High Ko" +43650 "Tai Viet Letter Low Kho" +43651 "Tai Viet Letter High Kho" +43652 "Tai Viet Letter Low Khho" +43653 "Tai Viet Letter High Khho" +43654 "Tai Viet Letter Low Go" +43655 "Tai Viet Letter High Go" +43656 "Tai Viet Letter Low Ngo" +43657 "Tai Viet Letter High Ngo" +43658 "Tai Viet Letter Low Co" +43659 "Tai Viet Letter High Co" +43660 "Tai Viet Letter Low Cho" +43661 "Tai Viet Letter High Cho" +43662 "Tai Viet Letter Low So" +43663 "Tai Viet Letter High So" +43664 "Tai Viet Letter Low Nyo" +43665 "Tai Viet Letter High Nyo" +43666 "Tai Viet Letter Low Do" +43667 "Tai Viet Letter High Do" +43668 "Tai Viet Letter Low To" +43669 "Tai Viet Letter High To" +43670 "Tai Viet Letter Low Tho" +43671 "Tai Viet Letter High Tho" +43672 "Tai Viet Letter Low No" +43673 "Tai Viet Letter High No" +43674 "Tai Viet Letter Low Bo" +43675 "Tai Viet Letter High Bo" +43676 "Tai Viet Letter Low Po" +43677 "Tai Viet Letter High Po" +43678 "Tai Viet Letter Low Pho" +43679 "Tai Viet Letter High Pho" +43680 "Tai Viet Letter Low Fo" +43681 "Tai Viet Letter High Fo" +43682 "Tai Viet Letter Low Mo" +43683 "Tai Viet Letter High Mo" +43684 "Tai Viet Letter Low Yo" +43685 "Tai Viet Letter High Yo" +43686 "Tai Viet Letter Low Ro" +43687 "Tai Viet Letter High Ro" +43688 "Tai Viet Letter Low Lo" +43689 "Tai Viet Letter High Lo" +43690 "Tai Viet Letter Low Vo" +43691 "Tai Viet Letter High Vo" +43692 "Tai Viet Letter Low Ho" +43693 "Tai Viet Letter High Ho" +43694 "Tai Viet Letter Low O" +43695 "Tai Viet Letter High O" +43696 "Tai Viet Mai Kang" +43697 "Tai Viet Vowel Aa" +43698 "Tai Viet Vowel I" +43699 "Tai Viet Vowel Ue" +43700 "Tai Viet Vowel U" +43701 "Tai Viet Vowel E" +43702 "Tai Viet Vowel O" +43703 "Tai Viet Mai Khit" +43704 "Tai Viet Vowel Ia" +43705 "Tai Viet Vowel Uea" +43706 "Tai Viet Vowel Ua" +43707 "Tai Viet Vowel Aue" +43708 "Tai Viet Vowel Ay" +43709 "Tai Viet Vowel An" +43710 "Tai Viet Vowel Am" +43711 "Tai Viet Tone Mai Ek" +43712 "Tai Viet Tone Mai Nueng" +43713 "Tai Viet Tone Mai Tho" +43714 "Tai Viet Tone Mai Song" +43739 "Tai Viet Symbol Kon" +43740 "Tai Viet Symbol Nueng" +43741 "Tai Viet Symbol Sam" +43742 "Tai Viet Symbol Ho Hoi" +43743 "Tai Viet Symbol Koi Koi" +43744 "Meetei Mayek Letter E" +43745 "Meetei Mayek Letter O" +43746 "Meetei Mayek Letter Cha" +43747 "Meetei Mayek Letter Nya" +43748 "Meetei Mayek Letter Tta" +43749 "Meetei Mayek Letter Ttha" +43750 "Meetei Mayek Letter Dda" +43751 "Meetei Mayek Letter Ddha" +43752 "Meetei Mayek Letter Nna" +43753 "Meetei Mayek Letter Sha" +43754 "Meetei Mayek Letter Ssa" +43755 "Meetei Mayek Vowel Sign Ii" +43756 "Meetei Mayek Vowel Sign Uu" +43757 "Meetei Mayek Vowel Sign Aai" +43758 "Meetei Mayek Vowel Sign Au" +43759 "Meetei Mayek Vowel Sign Aau" +43760 "Meetei Mayek Cheikhan" +43761 "Meetei Mayek Ahang Khudam" +43762 "Meetei Mayek Anji" +43763 "Meetei Mayek Syllable Repetition Mark" +43764 "Meetei Mayek Word Repetition Mark" +43765 "Meetei Mayek Vowel Sign Visarga" +43766 "Meetei Mayek Virama" +43777 "Ethiopic Syllable Tthu" +43778 "Ethiopic Syllable Tthi" +43779 "Ethiopic Syllable Tthaa" +43780 "Ethiopic Syllable Tthee" +43781 "Ethiopic Syllable Tthe" +43782 "Ethiopic Syllable Ttho" +43785 "Ethiopic Syllable Ddhu" +43786 "Ethiopic Syllable Ddhi" +43787 "Ethiopic Syllable Ddhaa" +43788 "Ethiopic Syllable Ddhee" +43789 "Ethiopic Syllable Ddhe" +43790 "Ethiopic Syllable Ddho" +43793 "Ethiopic Syllable Dzu" +43794 "Ethiopic Syllable Dzi" +43795 "Ethiopic Syllable Dzaa" +43796 "Ethiopic Syllable Dzee" +43797 "Ethiopic Syllable Dze" +43798 "Ethiopic Syllable Dzo" +43808 "Ethiopic Syllable Cchha" +43809 "Ethiopic Syllable Cchhu" +43810 "Ethiopic Syllable Cchhi" +43811 "Ethiopic Syllable Cchhaa" +43812 "Ethiopic Syllable Cchhee" +43813 "Ethiopic Syllable Cchhe" +43814 "Ethiopic Syllable Cchho" +43816 "Ethiopic Syllable Bba" +43817 "Ethiopic Syllable Bbu" +43818 "Ethiopic Syllable Bbi" +43819 "Ethiopic Syllable Bbaa" +43820 "Ethiopic Syllable Bbee" +43821 "Ethiopic Syllable Bbe" +43822 "Ethiopic Syllable Bbo" +43968 "Meetei Mayek Letter Kok" +43969 "Meetei Mayek Letter Sam" +43970 "Meetei Mayek Letter Lai" +43971 "Meetei Mayek Letter Mit" +43972 "Meetei Mayek Letter Pa" +43973 "Meetei Mayek Letter Na" +43974 "Meetei Mayek Letter Chil" +43975 "Meetei Mayek Letter Til" +43976 "Meetei Mayek Letter Khou" +43977 "Meetei Mayek Letter Ngou" +43978 "Meetei Mayek Letter Thou" +43979 "Meetei Mayek Letter Wai" +43980 "Meetei Mayek Letter Yang" +43981 "Meetei Mayek Letter Huk" +43982 "Meetei Mayek Letter Un" +43983 "Meetei Mayek Letter I" +43984 "Meetei Mayek Letter Pham" +43985 "Meetei Mayek Letter Atiya" +43986 "Meetei Mayek Letter Gok" +43987 "Meetei Mayek Letter Jham" +43988 "Meetei Mayek Letter Rai" +43989 "Meetei Mayek Letter Ba" +43990 "Meetei Mayek Letter Jil" +43991 "Meetei Mayek Letter Dil" +43992 "Meetei Mayek Letter Ghou" +43993 "Meetei Mayek Letter Dhou" +43994 "Meetei Mayek Letter Bham" +43995 "Meetei Mayek Letter Kok Lonsum" +43996 "Meetei Mayek Letter Lai Lonsum" +43997 "Meetei Mayek Letter Mit Lonsum" +43998 "Meetei Mayek Letter Pa Lonsum" +43999 "Meetei Mayek Letter Na Lonsum" +44000 "Meetei Mayek Letter Til Lonsum" +44001 "Meetei Mayek Letter Ngou Lonsum" +44002 "Meetei Mayek Letter I Lonsum" +44003 "Meetei Mayek Vowel Sign Onap" +44004 "Meetei Mayek Vowel Sign Inap" +44005 "Meetei Mayek Vowel Sign Anap" +44006 "Meetei Mayek Vowel Sign Yenap" +44007 "Meetei Mayek Vowel Sign Sounap" +44008 "Meetei Mayek Vowel Sign Unap" +44009 "Meetei Mayek Vowel Sign Cheinap" +44010 "Meetei Mayek Vowel Sign Nung" +44011 "Meetei Mayek Cheikhei" +44012 "Meetei Mayek Lum Iyek" +44013 "Meetei Mayek Apun Iyek" +44016 "Meetei Mayek Digit Zero" +44017 "Meetei Mayek Digit One" +44018 "Meetei Mayek Digit Two" +44019 "Meetei Mayek Digit Three" +44020 "Meetei Mayek Digit Four" +44021 "Meetei Mayek Digit Five" +44022 "Meetei Mayek Digit Six" +44023 "Meetei Mayek Digit Seven" +44024 "Meetei Mayek Digit Eight" +44025 "Meetei Mayek Digit Nine" +44032 "" +55203 "" +55216 "Hangul Jungseong O-Yeo" +55217 "Hangul Jungseong O-O-I" +55218 "Hangul Jungseong Yo-A" +55219 "Hangul Jungseong Yo-Ae" +55220 "Hangul Jungseong Yo-Eo" +55221 "Hangul Jungseong U-Yeo" +55222 "Hangul Jungseong U-I-I" +55223 "Hangul Jungseong Yu-Ae" +55224 "Hangul Jungseong Yu-O" +55225 "Hangul Jungseong Eu-A" +55226 "Hangul Jungseong Eu-Eo" +55227 "Hangul Jungseong Eu-E" +55228 "Hangul Jungseong Eu-O" +55229 "Hangul Jungseong I-Ya-O" +55230 "Hangul Jungseong I-Yae" +55231 "Hangul Jungseong I-Yeo" +55232 "Hangul Jungseong I-Ye" +55233 "Hangul Jungseong I-O-I" +55234 "Hangul Jungseong I-Yo" +55235 "Hangul Jungseong I-Yu" +55236 "Hangul Jungseong I-I" +55237 "Hangul Jungseong Araea-A" +55238 "Hangul Jungseong Araea-E" +55243 "Hangul Jongseong Nieun-Rieul" +55244 "Hangul Jongseong Nieun-Chieuch" +55245 "Hangul Jongseong Ssangtikeut" +55246 "Hangul Jongseong Ssangtikeut-Pieup" +55247 "Hangul Jongseong Tikeut-Pieup" +55248 "Hangul Jongseong Tikeut-Sios" +55249 "Hangul Jongseong Tikeut-Sios-Kiyeok" +55250 "Hangul Jongseong Tikeut-Cieuc" +55251 "Hangul Jongseong Tikeut-Chieuch" +55252 "Hangul Jongseong Tikeut-Thieuth" +55253 "Hangul Jongseong Rieul-Ssangkiyeok" +55254 "Hangul Jongseong Rieul-Kiyeok-Hieuh" +55255 "Hangul Jongseong Ssangrieul-Khieukh" +55256 "Hangul Jongseong Rieul-Mieum-Hieuh" +55257 "Hangul Jongseong Rieul-Pieup-Tikeut" +55258 "Hangul Jongseong Rieul-Pieup-Phieuph" +55259 "Hangul Jongseong Rieul-Yesieung" +55260 "Hangul Jongseong Rieul-Yeorinhieuh-Hieuh" +55261 "Hangul Jongseong Kapyeounrieul" +55262 "Hangul Jongseong Mieum-Nieun" +55263 "Hangul Jongseong Mieum-Ssangnieun" +55264 "Hangul Jongseong Ssangmieum" +55265 "Hangul Jongseong Mieum-Pieup-Sios" +55266 "Hangul Jongseong Mieum-Cieuc" +55267 "Hangul Jongseong Pieup-Tikeut" +55268 "Hangul Jongseong Pieup-Rieul-Phieuph" +55269 "Hangul Jongseong Pieup-Mieum" +55270 "Hangul Jongseong Ssangpieup" +55271 "Hangul Jongseong Pieup-Sios-Tikeut" +55272 "Hangul Jongseong Pieup-Cieuc" +55273 "Hangul Jongseong Pieup-Chieuch" +55274 "Hangul Jongseong Sios-Mieum" +55275 "Hangul Jongseong Sios-Kapyeounpieup" +55276 "Hangul Jongseong Ssangsios-Kiyeok" +55277 "Hangul Jongseong Ssangsios-Tikeut" +55278 "Hangul Jongseong Sios-Pansios" +55279 "Hangul Jongseong Sios-Cieuc" +55280 "Hangul Jongseong Sios-Chieuch" +55281 "Hangul Jongseong Sios-Thieuth" +55282 "Hangul Jongseong Sios-Hieuh" +55283 "Hangul Jongseong Pansios-Pieup" +55284 "Hangul Jongseong Pansios-Kapyeounpieup" +55285 "Hangul Jongseong Yesieung-Mieum" +55286 "Hangul Jongseong Yesieung-Hieuh" +55287 "Hangul Jongseong Cieuc-Pieup" +55288 "Hangul Jongseong Cieuc-Ssangpieup" +55289 "Hangul Jongseong Ssangcieuc" +55290 "Hangul Jongseong Phieuph-Sios" +55291 "Hangul Jongseong Phieuph-Thieuth" +55296 "" +56191 "" +56192 "" +56319 "" +56320 "" +57343 "" +57344 "" +63743 "" +63744 "CJK Compatibility Ideograph-F900" +63745 "CJK Compatibility Ideograph-F901" +63746 "CJK Compatibility Ideograph-F902" +63747 "CJK Compatibility Ideograph-F903" +63748 "CJK Compatibility Ideograph-F904" +63749 "CJK Compatibility Ideograph-F905" +63750 "CJK Compatibility Ideograph-F906" +63751 "CJK Compatibility Ideograph-F907" +63752 "CJK Compatibility Ideograph-F908" +63753 "CJK Compatibility Ideograph-F909" +63754 "CJK Compatibility Ideograph-F90a" +63755 "CJK Compatibility Ideograph-F90b" +63756 "CJK Compatibility Ideograph-F90c" +63757 "CJK Compatibility Ideograph-F90d" +63758 "CJK Compatibility Ideograph-F90e" +63759 "CJK Compatibility Ideograph-F90f" +63760 "CJK Compatibility Ideograph-F910" +63761 "CJK Compatibility Ideograph-F911" +63762 "CJK Compatibility Ideograph-F912" +63763 "CJK Compatibility Ideograph-F913" +63764 "CJK Compatibility Ideograph-F914" +63765 "CJK Compatibility Ideograph-F915" +63766 "CJK Compatibility Ideograph-F916" +63767 "CJK Compatibility Ideograph-F917" +63768 "CJK Compatibility Ideograph-F918" +63769 "CJK Compatibility Ideograph-F919" +63770 "CJK Compatibility Ideograph-F91a" +63771 "CJK Compatibility Ideograph-F91b" +63772 "CJK Compatibility Ideograph-F91c" +63773 "CJK Compatibility Ideograph-F91d" +63774 "CJK Compatibility Ideograph-F91e" +63775 "CJK Compatibility Ideograph-F91f" +63776 "CJK Compatibility Ideograph-F920" +63777 "CJK Compatibility Ideograph-F921" +63778 "CJK Compatibility Ideograph-F922" +63779 "CJK Compatibility Ideograph-F923" +63780 "CJK Compatibility Ideograph-F924" +63781 "CJK Compatibility Ideograph-F925" +63782 "CJK Compatibility Ideograph-F926" +63783 "CJK Compatibility Ideograph-F927" +63784 "CJK Compatibility Ideograph-F928" +63785 "CJK Compatibility Ideograph-F929" +63786 "CJK Compatibility Ideograph-F92a" +63787 "CJK Compatibility Ideograph-F92b" +63788 "CJK Compatibility Ideograph-F92c" +63789 "CJK Compatibility Ideograph-F92d" +63790 "CJK Compatibility Ideograph-F92e" +63791 "CJK Compatibility Ideograph-F92f" +63792 "CJK Compatibility Ideograph-F930" +63793 "CJK Compatibility Ideograph-F931" +63794 "CJK Compatibility Ideograph-F932" +63795 "CJK Compatibility Ideograph-F933" +63796 "CJK Compatibility Ideograph-F934" +63797 "CJK Compatibility Ideograph-F935" +63798 "CJK Compatibility Ideograph-F936" +63799 "CJK Compatibility Ideograph-F937" +63800 "CJK Compatibility Ideograph-F938" +63801 "CJK Compatibility Ideograph-F939" +63802 "CJK Compatibility Ideograph-F93a" +63803 "CJK Compatibility Ideograph-F93b" +63804 "CJK Compatibility Ideograph-F93c" +63805 "CJK Compatibility Ideograph-F93d" +63806 "CJK Compatibility Ideograph-F93e" +63807 "CJK Compatibility Ideograph-F93f" +63808 "CJK Compatibility Ideograph-F940" +63809 "CJK Compatibility Ideograph-F941" +63810 "CJK Compatibility Ideograph-F942" +63811 "CJK Compatibility Ideograph-F943" +63812 "CJK Compatibility Ideograph-F944" +63813 "CJK Compatibility Ideograph-F945" +63814 "CJK Compatibility Ideograph-F946" +63815 "CJK Compatibility Ideograph-F947" +63816 "CJK Compatibility Ideograph-F948" +63817 "CJK Compatibility Ideograph-F949" +63818 "CJK Compatibility Ideograph-F94a" +63819 "CJK Compatibility Ideograph-F94b" +63820 "CJK Compatibility Ideograph-F94c" +63821 "CJK Compatibility Ideograph-F94d" +63822 "CJK Compatibility Ideograph-F94e" +63823 "CJK Compatibility Ideograph-F94f" +63824 "CJK Compatibility Ideograph-F950" +63825 "CJK Compatibility Ideograph-F951" +63826 "CJK Compatibility Ideograph-F952" +63827 "CJK Compatibility Ideograph-F953" +63828 "CJK Compatibility Ideograph-F954" +63829 "CJK Compatibility Ideograph-F955" +63830 "CJK Compatibility Ideograph-F956" +63831 "CJK Compatibility Ideograph-F957" +63832 "CJK Compatibility Ideograph-F958" +63833 "CJK Compatibility Ideograph-F959" +63834 "CJK Compatibility Ideograph-F95a" +63835 "CJK Compatibility Ideograph-F95b" +63836 "CJK Compatibility Ideograph-F95c" +63837 "CJK Compatibility Ideograph-F95d" +63838 "CJK Compatibility Ideograph-F95e" +63839 "CJK Compatibility Ideograph-F95f" +63840 "CJK Compatibility Ideograph-F960" +63841 "CJK Compatibility Ideograph-F961" +63842 "CJK Compatibility Ideograph-F962" +63843 "CJK Compatibility Ideograph-F963" +63844 "CJK Compatibility Ideograph-F964" +63845 "CJK Compatibility Ideograph-F965" +63846 "CJK Compatibility Ideograph-F966" +63847 "CJK Compatibility Ideograph-F967" +63848 "CJK Compatibility Ideograph-F968" +63849 "CJK Compatibility Ideograph-F969" +63850 "CJK Compatibility Ideograph-F96a" +63851 "CJK Compatibility Ideograph-F96b" +63852 "CJK Compatibility Ideograph-F96c" +63853 "CJK Compatibility Ideograph-F96d" +63854 "CJK Compatibility Ideograph-F96e" +63855 "CJK Compatibility Ideograph-F96f" +63856 "CJK Compatibility Ideograph-F970" +63857 "CJK Compatibility Ideograph-F971" +63858 "CJK Compatibility Ideograph-F972" +63859 "CJK Compatibility Ideograph-F973" +63860 "CJK Compatibility Ideograph-F974" +63861 "CJK Compatibility Ideograph-F975" +63862 "CJK Compatibility Ideograph-F976" +63863 "CJK Compatibility Ideograph-F977" +63864 "CJK Compatibility Ideograph-F978" +63865 "CJK Compatibility Ideograph-F979" +63866 "CJK Compatibility Ideograph-F97a" +63867 "CJK Compatibility Ideograph-F97b" +63868 "CJK Compatibility Ideograph-F97c" +63869 "CJK Compatibility Ideograph-F97d" +63870 "CJK Compatibility Ideograph-F97e" +63871 "CJK Compatibility Ideograph-F97f" +63872 "CJK Compatibility Ideograph-F980" +63873 "CJK Compatibility Ideograph-F981" +63874 "CJK Compatibility Ideograph-F982" +63875 "CJK Compatibility Ideograph-F983" +63876 "CJK Compatibility Ideograph-F984" +63877 "CJK Compatibility Ideograph-F985" +63878 "CJK Compatibility Ideograph-F986" +63879 "CJK Compatibility Ideograph-F987" +63880 "CJK Compatibility Ideograph-F988" +63881 "CJK Compatibility Ideograph-F989" +63882 "CJK Compatibility Ideograph-F98a" +63883 "CJK Compatibility Ideograph-F98b" +63884 "CJK Compatibility Ideograph-F98c" +63885 "CJK Compatibility Ideograph-F98d" +63886 "CJK Compatibility Ideograph-F98e" +63887 "CJK Compatibility Ideograph-F98f" +63888 "CJK Compatibility Ideograph-F990" +63889 "CJK Compatibility Ideograph-F991" +63890 "CJK Compatibility Ideograph-F992" +63891 "CJK Compatibility Ideograph-F993" +63892 "CJK Compatibility Ideograph-F994" +63893 "CJK Compatibility Ideograph-F995" +63894 "CJK Compatibility Ideograph-F996" +63895 "CJK Compatibility Ideograph-F997" +63896 "CJK Compatibility Ideograph-F998" +63897 "CJK Compatibility Ideograph-F999" +63898 "CJK Compatibility Ideograph-F99a" +63899 "CJK Compatibility Ideograph-F99b" +63900 "CJK Compatibility Ideograph-F99c" +63901 "CJK Compatibility Ideograph-F99d" +63902 "CJK Compatibility Ideograph-F99e" +63903 "CJK Compatibility Ideograph-F99f" +63904 "CJK Compatibility Ideograph-F9a0" +63905 "CJK Compatibility Ideograph-F9a1" +63906 "CJK Compatibility Ideograph-F9a2" +63907 "CJK Compatibility Ideograph-F9a3" +63908 "CJK Compatibility Ideograph-F9a4" +63909 "CJK Compatibility Ideograph-F9a5" +63910 "CJK Compatibility Ideograph-F9a6" +63911 "CJK Compatibility Ideograph-F9a7" +63912 "CJK Compatibility Ideograph-F9a8" +63913 "CJK Compatibility Ideograph-F9a9" +63914 "CJK Compatibility Ideograph-F9aa" +63915 "CJK Compatibility Ideograph-F9ab" +63916 "CJK Compatibility Ideograph-F9ac" +63917 "CJK Compatibility Ideograph-F9ad" +63918 "CJK Compatibility Ideograph-F9ae" +63919 "CJK Compatibility Ideograph-F9af" +63920 "CJK Compatibility Ideograph-F9b0" +63921 "CJK Compatibility Ideograph-F9b1" +63922 "CJK Compatibility Ideograph-F9b2" +63923 "CJK Compatibility Ideograph-F9b3" +63924 "CJK Compatibility Ideograph-F9b4" +63925 "CJK Compatibility Ideograph-F9b5" +63926 "CJK Compatibility Ideograph-F9b6" +63927 "CJK Compatibility Ideograph-F9b7" +63928 "CJK Compatibility Ideograph-F9b8" +63929 "CJK Compatibility Ideograph-F9b9" +63930 "CJK Compatibility Ideograph-F9ba" +63931 "CJK Compatibility Ideograph-F9bb" +63932 "CJK Compatibility Ideograph-F9bc" +63933 "CJK Compatibility Ideograph-F9bd" +63934 "CJK Compatibility Ideograph-F9be" +63935 "CJK Compatibility Ideograph-F9bf" +63936 "CJK Compatibility Ideograph-F9c0" +63937 "CJK Compatibility Ideograph-F9c1" +63938 "CJK Compatibility Ideograph-F9c2" +63939 "CJK Compatibility Ideograph-F9c3" +63940 "CJK Compatibility Ideograph-F9c4" +63941 "CJK Compatibility Ideograph-F9c5" +63942 "CJK Compatibility Ideograph-F9c6" +63943 "CJK Compatibility Ideograph-F9c7" +63944 "CJK Compatibility Ideograph-F9c8" +63945 "CJK Compatibility Ideograph-F9c9" +63946 "CJK Compatibility Ideograph-F9ca" +63947 "CJK Compatibility Ideograph-F9cb" +63948 "CJK Compatibility Ideograph-F9cc" +63949 "CJK Compatibility Ideograph-F9cd" +63950 "CJK Compatibility Ideograph-F9ce" +63951 "CJK Compatibility Ideograph-F9cf" +63952 "CJK Compatibility Ideograph-F9d0" +63953 "CJK Compatibility Ideograph-F9d1" +63954 "CJK Compatibility Ideograph-F9d2" +63955 "CJK Compatibility Ideograph-F9d3" +63956 "CJK Compatibility Ideograph-F9d4" +63957 "CJK Compatibility Ideograph-F9d5" +63958 "CJK Compatibility Ideograph-F9d6" +63959 "CJK Compatibility Ideograph-F9d7" +63960 "CJK Compatibility Ideograph-F9d8" +63961 "CJK Compatibility Ideograph-F9d9" +63962 "CJK Compatibility Ideograph-F9da" +63963 "CJK Compatibility Ideograph-F9db" +63964 "CJK Compatibility Ideograph-F9dc" +63965 "CJK Compatibility Ideograph-F9dd" +63966 "CJK Compatibility Ideograph-F9de" +63967 "CJK Compatibility Ideograph-F9df" +63968 "CJK Compatibility Ideograph-F9e0" +63969 "CJK Compatibility Ideograph-F9e1" +63970 "CJK Compatibility Ideograph-F9e2" +63971 "CJK Compatibility Ideograph-F9e3" +63972 "CJK Compatibility Ideograph-F9e4" +63973 "CJK Compatibility Ideograph-F9e5" +63974 "CJK Compatibility Ideograph-F9e6" +63975 "CJK Compatibility Ideograph-F9e7" +63976 "CJK Compatibility Ideograph-F9e8" +63977 "CJK Compatibility Ideograph-F9e9" +63978 "CJK Compatibility Ideograph-F9ea" +63979 "CJK Compatibility Ideograph-F9eb" +63980 "CJK Compatibility Ideograph-F9ec" +63981 "CJK Compatibility Ideograph-F9ed" +63982 "CJK Compatibility Ideograph-F9ee" +63983 "CJK Compatibility Ideograph-F9ef" +63984 "CJK Compatibility Ideograph-F9f0" +63985 "CJK Compatibility Ideograph-F9f1" +63986 "CJK Compatibility Ideograph-F9f2" +63987 "CJK Compatibility Ideograph-F9f3" +63988 "CJK Compatibility Ideograph-F9f4" +63989 "CJK Compatibility Ideograph-F9f5" +63990 "CJK Compatibility Ideograph-F9f6" +63991 "CJK Compatibility Ideograph-F9f7" +63992 "CJK Compatibility Ideograph-F9f8" +63993 "CJK Compatibility Ideograph-F9f9" +63994 "CJK Compatibility Ideograph-F9fa" +63995 "CJK Compatibility Ideograph-F9fb" +63996 "CJK Compatibility Ideograph-F9fc" +63997 "CJK Compatibility Ideograph-F9fd" +63998 "CJK Compatibility Ideograph-F9fe" +63999 "CJK Compatibility Ideograph-F9ff" +64000 "CJK Compatibility Ideograph-Fa00" +64001 "CJK Compatibility Ideograph-Fa01" +64002 "CJK Compatibility Ideograph-Fa02" +64003 "CJK Compatibility Ideograph-Fa03" +64004 "CJK Compatibility Ideograph-Fa04" +64005 "CJK Compatibility Ideograph-Fa05" +64006 "CJK Compatibility Ideograph-Fa06" +64007 "CJK Compatibility Ideograph-Fa07" +64008 "CJK Compatibility Ideograph-Fa08" +64009 "CJK Compatibility Ideograph-Fa09" +64010 "CJK Compatibility Ideograph-Fa0a" +64011 "CJK Compatibility Ideograph-Fa0b" +64012 "CJK Compatibility Ideograph-Fa0c" +64013 "CJK Compatibility Ideograph-Fa0d" +64014 "CJK Compatibility Ideograph-Fa0e" +64015 "CJK Compatibility Ideograph-Fa0f" +64016 "CJK Compatibility Ideograph-Fa10" +64017 "CJK Compatibility Ideograph-Fa11" +64018 "CJK Compatibility Ideograph-Fa12" +64019 "CJK Compatibility Ideograph-Fa13" +64020 "CJK Compatibility Ideograph-Fa14" +64021 "CJK Compatibility Ideograph-Fa15" +64022 "CJK Compatibility Ideograph-Fa16" +64023 "CJK Compatibility Ideograph-Fa17" +64024 "CJK Compatibility Ideograph-Fa18" +64025 "CJK Compatibility Ideograph-Fa19" +64026 "CJK Compatibility Ideograph-Fa1a" +64027 "CJK Compatibility Ideograph-Fa1b" +64028 "CJK Compatibility Ideograph-Fa1c" +64029 "CJK Compatibility Ideograph-Fa1d" +64030 "CJK Compatibility Ideograph-Fa1e" +64031 "CJK Compatibility Ideograph-Fa1f" +64032 "CJK Compatibility Ideograph-Fa20" +64033 "CJK Compatibility Ideograph-Fa21" +64034 "CJK Compatibility Ideograph-Fa22" +64035 "CJK Compatibility Ideograph-Fa23" +64036 "CJK Compatibility Ideograph-Fa24" +64037 "CJK Compatibility Ideograph-Fa25" +64038 "CJK Compatibility Ideograph-Fa26" +64039 "CJK Compatibility Ideograph-Fa27" +64040 "CJK Compatibility Ideograph-Fa28" +64041 "CJK Compatibility Ideograph-Fa29" +64042 "CJK Compatibility Ideograph-Fa2a" +64043 "CJK Compatibility Ideograph-Fa2b" +64044 "CJK Compatibility Ideograph-Fa2c" +64045 "CJK Compatibility Ideograph-Fa2d" +64046 "CJK Compatibility Ideograph-Fa2e" +64047 "CJK Compatibility Ideograph-Fa2f" +64048 "CJK Compatibility Ideograph-Fa30" +64049 "CJK Compatibility Ideograph-Fa31" +64050 "CJK Compatibility Ideograph-Fa32" +64051 "CJK Compatibility Ideograph-Fa33" +64052 "CJK Compatibility Ideograph-Fa34" +64053 "CJK Compatibility Ideograph-Fa35" +64054 "CJK Compatibility Ideograph-Fa36" +64055 "CJK Compatibility Ideograph-Fa37" +64056 "CJK Compatibility Ideograph-Fa38" +64057 "CJK Compatibility Ideograph-Fa39" +64058 "CJK Compatibility Ideograph-Fa3a" +64059 "CJK Compatibility Ideograph-Fa3b" +64060 "CJK Compatibility Ideograph-Fa3c" +64061 "CJK Compatibility Ideograph-Fa3d" +64062 "CJK Compatibility Ideograph-Fa3e" +64063 "CJK Compatibility Ideograph-Fa3f" +64064 "CJK Compatibility Ideograph-Fa40" +64065 "CJK Compatibility Ideograph-Fa41" +64066 "CJK Compatibility Ideograph-Fa42" +64067 "CJK Compatibility Ideograph-Fa43" +64068 "CJK Compatibility Ideograph-Fa44" +64069 "CJK Compatibility Ideograph-Fa45" +64070 "CJK Compatibility Ideograph-Fa46" +64071 "CJK Compatibility Ideograph-Fa47" +64072 "CJK Compatibility Ideograph-Fa48" +64073 "CJK Compatibility Ideograph-Fa49" +64074 "CJK Compatibility Ideograph-Fa4a" +64075 "CJK Compatibility Ideograph-Fa4b" +64076 "CJK Compatibility Ideograph-Fa4c" +64077 "CJK Compatibility Ideograph-Fa4d" +64078 "CJK Compatibility Ideograph-Fa4e" +64079 "CJK Compatibility Ideograph-Fa4f" +64080 "CJK Compatibility Ideograph-Fa50" +64081 "CJK Compatibility Ideograph-Fa51" +64082 "CJK Compatibility Ideograph-Fa52" +64083 "CJK Compatibility Ideograph-Fa53" +64084 "CJK Compatibility Ideograph-Fa54" +64085 "CJK Compatibility Ideograph-Fa55" +64086 "CJK Compatibility Ideograph-Fa56" +64087 "CJK Compatibility Ideograph-Fa57" +64088 "CJK Compatibility Ideograph-Fa58" +64089 "CJK Compatibility Ideograph-Fa59" +64090 "CJK Compatibility Ideograph-Fa5a" +64091 "CJK Compatibility Ideograph-Fa5b" +64092 "CJK Compatibility Ideograph-Fa5c" +64093 "CJK Compatibility Ideograph-Fa5d" +64094 "CJK Compatibility Ideograph-Fa5e" +64095 "CJK Compatibility Ideograph-Fa5f" +64096 "CJK Compatibility Ideograph-Fa60" +64097 "CJK Compatibility Ideograph-Fa61" +64098 "CJK Compatibility Ideograph-Fa62" +64099 "CJK Compatibility Ideograph-Fa63" +64100 "CJK Compatibility Ideograph-Fa64" +64101 "CJK Compatibility Ideograph-Fa65" +64102 "CJK Compatibility Ideograph-Fa66" +64103 "CJK Compatibility Ideograph-Fa67" +64104 "CJK Compatibility Ideograph-Fa68" +64105 "CJK Compatibility Ideograph-Fa69" +64106 "CJK Compatibility Ideograph-Fa6a" +64107 "CJK Compatibility Ideograph-Fa6b" +64108 "CJK Compatibility Ideograph-Fa6c" +64109 "CJK Compatibility Ideograph-Fa6d" +64112 "CJK Compatibility Ideograph-Fa70" +64113 "CJK Compatibility Ideograph-Fa71" +64114 "CJK Compatibility Ideograph-Fa72" +64115 "CJK Compatibility Ideograph-Fa73" +64116 "CJK Compatibility Ideograph-Fa74" +64117 "CJK Compatibility Ideograph-Fa75" +64118 "CJK Compatibility Ideograph-Fa76" +64119 "CJK Compatibility Ideograph-Fa77" +64120 "CJK Compatibility Ideograph-Fa78" +64121 "CJK Compatibility Ideograph-Fa79" +64122 "CJK Compatibility Ideograph-Fa7a" +64123 "CJK Compatibility Ideograph-Fa7b" +64124 "CJK Compatibility Ideograph-Fa7c" +64125 "CJK Compatibility Ideograph-Fa7d" +64126 "CJK Compatibility Ideograph-Fa7e" +64127 "CJK Compatibility Ideograph-Fa7f" +64128 "CJK Compatibility Ideograph-Fa80" +64129 "CJK Compatibility Ideograph-Fa81" +64130 "CJK Compatibility Ideograph-Fa82" +64131 "CJK Compatibility Ideograph-Fa83" +64132 "CJK Compatibility Ideograph-Fa84" +64133 "CJK Compatibility Ideograph-Fa85" +64134 "CJK Compatibility Ideograph-Fa86" +64135 "CJK Compatibility Ideograph-Fa87" +64136 "CJK Compatibility Ideograph-Fa88" +64137 "CJK Compatibility Ideograph-Fa89" +64138 "CJK Compatibility Ideograph-Fa8a" +64139 "CJK Compatibility Ideograph-Fa8b" +64140 "CJK Compatibility Ideograph-Fa8c" +64141 "CJK Compatibility Ideograph-Fa8d" +64142 "CJK Compatibility Ideograph-Fa8e" +64143 "CJK Compatibility Ideograph-Fa8f" +64144 "CJK Compatibility Ideograph-Fa90" +64145 "CJK Compatibility Ideograph-Fa91" +64146 "CJK Compatibility Ideograph-Fa92" +64147 "CJK Compatibility Ideograph-Fa93" +64148 "CJK Compatibility Ideograph-Fa94" +64149 "CJK Compatibility Ideograph-Fa95" +64150 "CJK Compatibility Ideograph-Fa96" +64151 "CJK Compatibility Ideograph-Fa97" +64152 "CJK Compatibility Ideograph-Fa98" +64153 "CJK Compatibility Ideograph-Fa99" +64154 "CJK Compatibility Ideograph-Fa9a" +64155 "CJK Compatibility Ideograph-Fa9b" +64156 "CJK Compatibility Ideograph-Fa9c" +64157 "CJK Compatibility Ideograph-Fa9d" +64158 "CJK Compatibility Ideograph-Fa9e" +64159 "CJK Compatibility Ideograph-Fa9f" +64160 "CJK Compatibility Ideograph-Faa0" +64161 "CJK Compatibility Ideograph-Faa1" +64162 "CJK Compatibility Ideograph-Faa2" +64163 "CJK Compatibility Ideograph-Faa3" +64164 "CJK Compatibility Ideograph-Faa4" +64165 "CJK Compatibility Ideograph-Faa5" +64166 "CJK Compatibility Ideograph-Faa6" +64167 "CJK Compatibility Ideograph-Faa7" +64168 "CJK Compatibility Ideograph-Faa8" +64169 "CJK Compatibility Ideograph-Faa9" +64170 "CJK Compatibility Ideograph-Faaa" +64171 "CJK Compatibility Ideograph-Faab" +64172 "CJK Compatibility Ideograph-Faac" +64173 "CJK Compatibility Ideograph-Faad" +64174 "CJK Compatibility Ideograph-Faae" +64175 "CJK Compatibility Ideograph-Faaf" +64176 "CJK Compatibility Ideograph-Fab0" +64177 "CJK Compatibility Ideograph-Fab1" +64178 "CJK Compatibility Ideograph-Fab2" +64179 "CJK Compatibility Ideograph-Fab3" +64180 "CJK Compatibility Ideograph-Fab4" +64181 "CJK Compatibility Ideograph-Fab5" +64182 "CJK Compatibility Ideograph-Fab6" +64183 "CJK Compatibility Ideograph-Fab7" +64184 "CJK Compatibility Ideograph-Fab8" +64185 "CJK Compatibility Ideograph-Fab9" +64186 "CJK Compatibility Ideograph-Faba" +64187 "CJK Compatibility Ideograph-Fabb" +64188 "CJK Compatibility Ideograph-Fabc" +64189 "CJK Compatibility Ideograph-Fabd" +64190 "CJK Compatibility Ideograph-Fabe" +64191 "CJK Compatibility Ideograph-Fabf" +64192 "CJK Compatibility Ideograph-Fac0" +64193 "CJK Compatibility Ideograph-Fac1" +64194 "CJK Compatibility Ideograph-Fac2" +64195 "CJK Compatibility Ideograph-Fac3" +64196 "CJK Compatibility Ideograph-Fac4" +64197 "CJK Compatibility Ideograph-Fac5" +64198 "CJK Compatibility Ideograph-Fac6" +64199 "CJK Compatibility Ideograph-Fac7" +64200 "CJK Compatibility Ideograph-Fac8" +64201 "CJK Compatibility Ideograph-Fac9" +64202 "CJK Compatibility Ideograph-Faca" +64203 "CJK Compatibility Ideograph-Facb" +64204 "CJK Compatibility Ideograph-Facc" +64205 "CJK Compatibility Ideograph-Facd" +64206 "CJK Compatibility Ideograph-Face" +64207 "CJK Compatibility Ideograph-Facf" +64208 "CJK Compatibility Ideograph-Fad0" +64209 "CJK Compatibility Ideograph-Fad1" +64210 "CJK Compatibility Ideograph-Fad2" +64211 "CJK Compatibility Ideograph-Fad3" +64212 "CJK Compatibility Ideograph-Fad4" +64213 "CJK Compatibility Ideograph-Fad5" +64214 "CJK Compatibility Ideograph-Fad6" +64215 "CJK Compatibility Ideograph-Fad7" +64216 "CJK Compatibility Ideograph-Fad8" +64217 "CJK Compatibility Ideograph-Fad9" +64256 "Latin Small Ligature Ff" +64257 "Latin Small Ligature Fi" +64258 "Latin Small Ligature Fl" +64259 "Latin Small Ligature Ffi" +64260 "Latin Small Ligature Ffl" +64261 "Latin Small Ligature Long S T" +64262 "Latin Small Ligature St" +64275 "Armenian Small Ligature Men Now" +64276 "Armenian Small Ligature Men Ech" +64277 "Armenian Small Ligature Men Ini" +64278 "Armenian Small Ligature Vew Now" +64279 "Armenian Small Ligature Men Xeh" +64285 "Hebrew Letter Yod With Hiriq" +64286 "Hebrew Point Judeo-Spanish Varika" +64287 "Hebrew Ligature Yiddish Yod Yod Patah" +64288 "Hebrew Letter Alternative Ayin" +64289 "Hebrew Letter Wide Alef" +64290 "Hebrew Letter Wide Dalet" +64291 "Hebrew Letter Wide He" +64292 "Hebrew Letter Wide Kaf" +64293 "Hebrew Letter Wide Lamed" +64294 "Hebrew Letter Wide Final Mem" +64295 "Hebrew Letter Wide Resh" +64296 "Hebrew Letter Wide Tav" +64297 "Hebrew Letter Alternative Plus Sign" +64298 "Hebrew Letter Shin With Shin Dot" +64299 "Hebrew Letter Shin With Sin Dot" +64300 "Hebrew Letter Shin With Dagesh And Shin Dot" +64301 "Hebrew Letter Shin With Dagesh And Sin Dot" +64302 "Hebrew Letter Alef With Patah" +64303 "Hebrew Letter Alef With Qamats" +64304 "Hebrew Letter Alef With Mapiq" +64305 "Hebrew Letter Bet With Dagesh" +64306 "Hebrew Letter Gimel With Dagesh" +64307 "Hebrew Letter Dalet With Dagesh" +64308 "Hebrew Letter He With Mapiq" +64309 "Hebrew Letter Vav With Dagesh" +64310 "Hebrew Letter Zayin With Dagesh" +64312 "Hebrew Letter Tet With Dagesh" +64313 "Hebrew Letter Yod With Dagesh" +64314 "Hebrew Letter Final Kaf With Dagesh" +64315 "Hebrew Letter Kaf With Dagesh" +64316 "Hebrew Letter Lamed With Dagesh" +64318 "Hebrew Letter Mem With Dagesh" +64320 "Hebrew Letter Nun With Dagesh" +64321 "Hebrew Letter Samekh With Dagesh" +64323 "Hebrew Letter Final Pe With Dagesh" +64324 "Hebrew Letter Pe With Dagesh" +64326 "Hebrew Letter Tsadi With Dagesh" +64327 "Hebrew Letter Qof With Dagesh" +64328 "Hebrew Letter Resh With Dagesh" +64329 "Hebrew Letter Shin With Dagesh" +64330 "Hebrew Letter Tav With Dagesh" +64331 "Hebrew Letter Vav With Holam" +64332 "Hebrew Letter Bet With Rafe" +64333 "Hebrew Letter Kaf With Rafe" +64334 "Hebrew Letter Pe With Rafe" +64335 "Hebrew Ligature Alef Lamed" +64336 "Arabic Letter Alef Wasla Isolated Form" +64337 "Arabic Letter Alef Wasla Final Form" +64338 "Arabic Letter Beeh Isolated Form" +64339 "Arabic Letter Beeh Final Form" +64340 "Arabic Letter Beeh Initial Form" +64341 "Arabic Letter Beeh Medial Form" +64342 "Arabic Letter Peh Isolated Form" +64343 "Arabic Letter Peh Final Form" +64344 "Arabic Letter Peh Initial Form" +64345 "Arabic Letter Peh Medial Form" +64346 "Arabic Letter Beheh Isolated Form" +64347 "Arabic Letter Beheh Final Form" +64348 "Arabic Letter Beheh Initial Form" +64349 "Arabic Letter Beheh Medial Form" +64350 "Arabic Letter Tteheh Isolated Form" +64351 "Arabic Letter Tteheh Final Form" +64352 "Arabic Letter Tteheh Initial Form" +64353 "Arabic Letter Tteheh Medial Form" +64354 "Arabic Letter Teheh Isolated Form" +64355 "Arabic Letter Teheh Final Form" +64356 "Arabic Letter Teheh Initial Form" +64357 "Arabic Letter Teheh Medial Form" +64358 "Arabic Letter Tteh Isolated Form" +64359 "Arabic Letter Tteh Final Form" +64360 "Arabic Letter Tteh Initial Form" +64361 "Arabic Letter Tteh Medial Form" +64362 "Arabic Letter Veh Isolated Form" +64363 "Arabic Letter Veh Final Form" +64364 "Arabic Letter Veh Initial Form" +64365 "Arabic Letter Veh Medial Form" +64366 "Arabic Letter Peheh Isolated Form" +64367 "Arabic Letter Peheh Final Form" +64368 "Arabic Letter Peheh Initial Form" +64369 "Arabic Letter Peheh Medial Form" +64370 "Arabic Letter Dyeh Isolated Form" +64371 "Arabic Letter Dyeh Final Form" +64372 "Arabic Letter Dyeh Initial Form" +64373 "Arabic Letter Dyeh Medial Form" +64374 "Arabic Letter Nyeh Isolated Form" +64375 "Arabic Letter Nyeh Final Form" +64376 "Arabic Letter Nyeh Initial Form" +64377 "Arabic Letter Nyeh Medial Form" +64378 "Arabic Letter Tcheh Isolated Form" +64379 "Arabic Letter Tcheh Final Form" +64380 "Arabic Letter Tcheh Initial Form" +64381 "Arabic Letter Tcheh Medial Form" +64382 "Arabic Letter Tcheheh Isolated Form" +64383 "Arabic Letter Tcheheh Final Form" +64384 "Arabic Letter Tcheheh Initial Form" +64385 "Arabic Letter Tcheheh Medial Form" +64386 "Arabic Letter Ddahal Isolated Form" +64387 "Arabic Letter Ddahal Final Form" +64388 "Arabic Letter Dahal Isolated Form" +64389 "Arabic Letter Dahal Final Form" +64390 "Arabic Letter Dul Isolated Form" +64391 "Arabic Letter Dul Final Form" +64392 "Arabic Letter Ddal Isolated Form" +64393 "Arabic Letter Ddal Final Form" +64394 "Arabic Letter Jeh Isolated Form" +64395 "Arabic Letter Jeh Final Form" +64396 "Arabic Letter Rreh Isolated Form" +64397 "Arabic Letter Rreh Final Form" +64398 "Arabic Letter Keheh Isolated Form" +64399 "Arabic Letter Keheh Final Form" +64400 "Arabic Letter Keheh Initial Form" +64401 "Arabic Letter Keheh Medial Form" +64402 "Arabic Letter Gaf Isolated Form" +64403 "Arabic Letter Gaf Final Form" +64404 "Arabic Letter Gaf Initial Form" +64405 "Arabic Letter Gaf Medial Form" +64406 "Arabic Letter Gueh Isolated Form" +64407 "Arabic Letter Gueh Final Form" +64408 "Arabic Letter Gueh Initial Form" +64409 "Arabic Letter Gueh Medial Form" +64410 "Arabic Letter Ngoeh Isolated Form" +64411 "Arabic Letter Ngoeh Final Form" +64412 "Arabic Letter Ngoeh Initial Form" +64413 "Arabic Letter Ngoeh Medial Form" +64414 "Arabic Letter Noon Ghunna Isolated Form" +64415 "Arabic Letter Noon Ghunna Final Form" +64416 "Arabic Letter Rnoon Isolated Form" +64417 "Arabic Letter Rnoon Final Form" +64418 "Arabic Letter Rnoon Initial Form" +64419 "Arabic Letter Rnoon Medial Form" +64420 "Arabic Letter Heh With Yeh Above Isolated Form" +64421 "Arabic Letter Heh With Yeh Above Final Form" +64422 "Arabic Letter Heh Goal Isolated Form" +64423 "Arabic Letter Heh Goal Final Form" +64424 "Arabic Letter Heh Goal Initial Form" +64425 "Arabic Letter Heh Goal Medial Form" +64426 "Arabic Letter Heh Doachashmee Isolated Form" +64427 "Arabic Letter Heh Doachashmee Final Form" +64428 "Arabic Letter Heh Doachashmee Initial Form" +64429 "Arabic Letter Heh Doachashmee Medial Form" +64430 "Arabic Letter Yeh Barree Isolated Form" +64431 "Arabic Letter Yeh Barree Final Form" +64432 "Arabic Letter Yeh Barree With Hamza Above Isolated Form" +64433 "Arabic Letter Yeh Barree With Hamza Above Final Form" +64434 "Arabic Symbol Dot Above" +64435 "Arabic Symbol Dot Below" +64436 "Arabic Symbol Two Dots Above" +64437 "Arabic Symbol Two Dots Below" +64438 "Arabic Symbol Three Dots Above" +64439 "Arabic Symbol Three Dots Below" +64440 "Arabic Symbol Three Dots Pointing Downwards Above" +64441 "Arabic Symbol Three Dots Pointing Downwards Below" +64442 "Arabic Symbol Four Dots Above" +64443 "Arabic Symbol Four Dots Below" +64444 "Arabic Symbol Double Vertical Bar Below" +64445 "Arabic Symbol Two Dots Vertically Above" +64446 "Arabic Symbol Two Dots Vertically Below" +64447 "Arabic Symbol Ring" +64448 "Arabic Symbol Small Tah Above" +64449 "Arabic Symbol Small Tah Below" +64467 "Arabic Letter Ng Isolated Form" +64468 "Arabic Letter Ng Final Form" +64469 "Arabic Letter Ng Initial Form" +64470 "Arabic Letter Ng Medial Form" +64471 "Arabic Letter U Isolated Form" +64472 "Arabic Letter U Final Form" +64473 "Arabic Letter Oe Isolated Form" +64474 "Arabic Letter Oe Final Form" +64475 "Arabic Letter Yu Isolated Form" +64476 "Arabic Letter Yu Final Form" +64477 "Arabic Letter U With Hamza Above Isolated Form" +64478 "Arabic Letter Ve Isolated Form" +64479 "Arabic Letter Ve Final Form" +64480 "Arabic Letter Kirghiz Oe Isolated Form" +64481 "Arabic Letter Kirghiz Oe Final Form" +64482 "Arabic Letter Kirghiz Yu Isolated Form" +64483 "Arabic Letter Kirghiz Yu Final Form" +64484 "Arabic Letter E Isolated Form" +64485 "Arabic Letter E Final Form" +64486 "Arabic Letter E Initial Form" +64487 "Arabic Letter E Medial Form" +64488 "Arabic Letter Uighur Kazakh Kirghiz Alef Maksura Initial Form" +64489 "Arabic Letter Uighur Kazakh Kirghiz Alef Maksura Medial Form" +64490 "Arabic Ligature Yeh With Hamza Above With Alef Isolated Form" +64491 "Arabic Ligature Yeh With Hamza Above With Alef Final Form" +64492 "Arabic Ligature Yeh With Hamza Above With Ae Isolated Form" +64493 "Arabic Ligature Yeh With Hamza Above With Ae Final Form" +64494 "Arabic Ligature Yeh With Hamza Above With Waw Isolated Form" +64495 "Arabic Ligature Yeh With Hamza Above With Waw Final Form" +64496 "Arabic Ligature Yeh With Hamza Above With U Isolated Form" +64497 "Arabic Ligature Yeh With Hamza Above With U Final Form" +64498 "Arabic Ligature Yeh With Hamza Above With Oe Isolated Form" +64499 "Arabic Ligature Yeh With Hamza Above With Oe Final Form" +64500 "Arabic Ligature Yeh With Hamza Above With Yu Isolated Form" +64501 "Arabic Ligature Yeh With Hamza Above With Yu Final Form" +64502 "Arabic Ligature Yeh With Hamza Above With E Isolated Form" +64503 "Arabic Ligature Yeh With Hamza Above With E Final Form" +64504 "Arabic Ligature Yeh With Hamza Above With E Initial Form" +64505 "Arabic Ligature Uighur Kirghiz Yeh With Hamza Above With Alef Maksura Isolated Form" +64506 "Arabic Ligature Uighur Kirghiz Yeh With Hamza Above With Alef Maksura Final Form" +64507 "Arabic Ligature Uighur Kirghiz Yeh With Hamza Above With Alef Maksura Initial Form" +64508 "Arabic Letter Farsi Yeh Isolated Form" +64509 "Arabic Letter Farsi Yeh Final Form" +64510 "Arabic Letter Farsi Yeh Initial Form" +64511 "Arabic Letter Farsi Yeh Medial Form" +64512 "Arabic Ligature Yeh With Hamza Above With Jeem Isolated Form" +64513 "Arabic Ligature Yeh With Hamza Above With Hah Isolated Form" +64514 "Arabic Ligature Yeh With Hamza Above With Meem Isolated Form" +64515 "Arabic Ligature Yeh With Hamza Above With Alef Maksura Isolated Form" +64516 "Arabic Ligature Yeh With Hamza Above With Yeh Isolated Form" +64517 "Arabic Ligature Beh With Jeem Isolated Form" +64518 "Arabic Ligature Beh With Hah Isolated Form" +64519 "Arabic Ligature Beh With Khah Isolated Form" +64520 "Arabic Ligature Beh With Meem Isolated Form" +64521 "Arabic Ligature Beh With Alef Maksura Isolated Form" +64522 "Arabic Ligature Beh With Yeh Isolated Form" +64523 "Arabic Ligature Teh With Jeem Isolated Form" +64524 "Arabic Ligature Teh With Hah Isolated Form" +64525 "Arabic Ligature Teh With Khah Isolated Form" +64526 "Arabic Ligature Teh With Meem Isolated Form" +64527 "Arabic Ligature Teh With Alef Maksura Isolated Form" +64528 "Arabic Ligature Teh With Yeh Isolated Form" +64529 "Arabic Ligature Theh With Jeem Isolated Form" +64530 "Arabic Ligature Theh With Meem Isolated Form" +64531 "Arabic Ligature Theh With Alef Maksura Isolated Form" +64532 "Arabic Ligature Theh With Yeh Isolated Form" +64533 "Arabic Ligature Jeem With Hah Isolated Form" +64534 "Arabic Ligature Jeem With Meem Isolated Form" +64535 "Arabic Ligature Hah With Jeem Isolated Form" +64536 "Arabic Ligature Hah With Meem Isolated Form" +64537 "Arabic Ligature Khah With Jeem Isolated Form" +64538 "Arabic Ligature Khah With Hah Isolated Form" +64539 "Arabic Ligature Khah With Meem Isolated Form" +64540 "Arabic Ligature Seen With Jeem Isolated Form" +64541 "Arabic Ligature Seen With Hah Isolated Form" +64542 "Arabic Ligature Seen With Khah Isolated Form" +64543 "Arabic Ligature Seen With Meem Isolated Form" +64544 "Arabic Ligature Sad With Hah Isolated Form" +64545 "Arabic Ligature Sad With Meem Isolated Form" +64546 "Arabic Ligature Dad With Jeem Isolated Form" +64547 "Arabic Ligature Dad With Hah Isolated Form" +64548 "Arabic Ligature Dad With Khah Isolated Form" +64549 "Arabic Ligature Dad With Meem Isolated Form" +64550 "Arabic Ligature Tah With Hah Isolated Form" +64551 "Arabic Ligature Tah With Meem Isolated Form" +64552 "Arabic Ligature Zah With Meem Isolated Form" +64553 "Arabic Ligature Ain With Jeem Isolated Form" +64554 "Arabic Ligature Ain With Meem Isolated Form" +64555 "Arabic Ligature Ghain With Jeem Isolated Form" +64556 "Arabic Ligature Ghain With Meem Isolated Form" +64557 "Arabic Ligature Feh With Jeem Isolated Form" +64558 "Arabic Ligature Feh With Hah Isolated Form" +64559 "Arabic Ligature Feh With Khah Isolated Form" +64560 "Arabic Ligature Feh With Meem Isolated Form" +64561 "Arabic Ligature Feh With Alef Maksura Isolated Form" +64562 "Arabic Ligature Feh With Yeh Isolated Form" +64563 "Arabic Ligature Qaf With Hah Isolated Form" +64564 "Arabic Ligature Qaf With Meem Isolated Form" +64565 "Arabic Ligature Qaf With Alef Maksura Isolated Form" +64566 "Arabic Ligature Qaf With Yeh Isolated Form" +64567 "Arabic Ligature Kaf With Alef Isolated Form" +64568 "Arabic Ligature Kaf With Jeem Isolated Form" +64569 "Arabic Ligature Kaf With Hah Isolated Form" +64570 "Arabic Ligature Kaf With Khah Isolated Form" +64571 "Arabic Ligature Kaf With Lam Isolated Form" +64572 "Arabic Ligature Kaf With Meem Isolated Form" +64573 "Arabic Ligature Kaf With Alef Maksura Isolated Form" +64574 "Arabic Ligature Kaf With Yeh Isolated Form" +64575 "Arabic Ligature Lam With Jeem Isolated Form" +64576 "Arabic Ligature Lam With Hah Isolated Form" +64577 "Arabic Ligature Lam With Khah Isolated Form" +64578 "Arabic Ligature Lam With Meem Isolated Form" +64579 "Arabic Ligature Lam With Alef Maksura Isolated Form" +64580 "Arabic Ligature Lam With Yeh Isolated Form" +64581 "Arabic Ligature Meem With Jeem Isolated Form" +64582 "Arabic Ligature Meem With Hah Isolated Form" +64583 "Arabic Ligature Meem With Khah Isolated Form" +64584 "Arabic Ligature Meem With Meem Isolated Form" +64585 "Arabic Ligature Meem With Alef Maksura Isolated Form" +64586 "Arabic Ligature Meem With Yeh Isolated Form" +64587 "Arabic Ligature Noon With Jeem Isolated Form" +64588 "Arabic Ligature Noon With Hah Isolated Form" +64589 "Arabic Ligature Noon With Khah Isolated Form" +64590 "Arabic Ligature Noon With Meem Isolated Form" +64591 "Arabic Ligature Noon With Alef Maksura Isolated Form" +64592 "Arabic Ligature Noon With Yeh Isolated Form" +64593 "Arabic Ligature Heh With Jeem Isolated Form" +64594 "Arabic Ligature Heh With Meem Isolated Form" +64595 "Arabic Ligature Heh With Alef Maksura Isolated Form" +64596 "Arabic Ligature Heh With Yeh Isolated Form" +64597 "Arabic Ligature Yeh With Jeem Isolated Form" +64598 "Arabic Ligature Yeh With Hah Isolated Form" +64599 "Arabic Ligature Yeh With Khah Isolated Form" +64600 "Arabic Ligature Yeh With Meem Isolated Form" +64601 "Arabic Ligature Yeh With Alef Maksura Isolated Form" +64602 "Arabic Ligature Yeh With Yeh Isolated Form" +64603 "Arabic Ligature Thal With Superscript Alef Isolated Form" +64604 "Arabic Ligature Reh With Superscript Alef Isolated Form" +64605 "Arabic Ligature Alef Maksura With Superscript Alef Isolated Form" +64606 "Arabic Ligature Shadda With Dammatan Isolated Form" +64607 "Arabic Ligature Shadda With Kasratan Isolated Form" +64608 "Arabic Ligature Shadda With Fatha Isolated Form" +64609 "Arabic Ligature Shadda With Damma Isolated Form" +64610 "Arabic Ligature Shadda With Kasra Isolated Form" +64611 "Arabic Ligature Shadda With Superscript Alef Isolated Form" +64612 "Arabic Ligature Yeh With Hamza Above With Reh Final Form" +64613 "Arabic Ligature Yeh With Hamza Above With Zain Final Form" +64614 "Arabic Ligature Yeh With Hamza Above With Meem Final Form" +64615 "Arabic Ligature Yeh With Hamza Above With Noon Final Form" +64616 "Arabic Ligature Yeh With Hamza Above With Alef Maksura Final Form" +64617 "Arabic Ligature Yeh With Hamza Above With Yeh Final Form" +64618 "Arabic Ligature Beh With Reh Final Form" +64619 "Arabic Ligature Beh With Zain Final Form" +64620 "Arabic Ligature Beh With Meem Final Form" +64621 "Arabic Ligature Beh With Noon Final Form" +64622 "Arabic Ligature Beh With Alef Maksura Final Form" +64623 "Arabic Ligature Beh With Yeh Final Form" +64624 "Arabic Ligature Teh With Reh Final Form" +64625 "Arabic Ligature Teh With Zain Final Form" +64626 "Arabic Ligature Teh With Meem Final Form" +64627 "Arabic Ligature Teh With Noon Final Form" +64628 "Arabic Ligature Teh With Alef Maksura Final Form" +64629 "Arabic Ligature Teh With Yeh Final Form" +64630 "Arabic Ligature Theh With Reh Final Form" +64631 "Arabic Ligature Theh With Zain Final Form" +64632 "Arabic Ligature Theh With Meem Final Form" +64633 "Arabic Ligature Theh With Noon Final Form" +64634 "Arabic Ligature Theh With Alef Maksura Final Form" +64635 "Arabic Ligature Theh With Yeh Final Form" +64636 "Arabic Ligature Feh With Alef Maksura Final Form" +64637 "Arabic Ligature Feh With Yeh Final Form" +64638 "Arabic Ligature Qaf With Alef Maksura Final Form" +64639 "Arabic Ligature Qaf With Yeh Final Form" +64640 "Arabic Ligature Kaf With Alef Final Form" +64641 "Arabic Ligature Kaf With Lam Final Form" +64642 "Arabic Ligature Kaf With Meem Final Form" +64643 "Arabic Ligature Kaf With Alef Maksura Final Form" +64644 "Arabic Ligature Kaf With Yeh Final Form" +64645 "Arabic Ligature Lam With Meem Final Form" +64646 "Arabic Ligature Lam With Alef Maksura Final Form" +64647 "Arabic Ligature Lam With Yeh Final Form" +64648 "Arabic Ligature Meem With Alef Final Form" +64649 "Arabic Ligature Meem With Meem Final Form" +64650 "Arabic Ligature Noon With Reh Final Form" +64651 "Arabic Ligature Noon With Zain Final Form" +64652 "Arabic Ligature Noon With Meem Final Form" +64653 "Arabic Ligature Noon With Noon Final Form" +64654 "Arabic Ligature Noon With Alef Maksura Final Form" +64655 "Arabic Ligature Noon With Yeh Final Form" +64656 "Arabic Ligature Alef Maksura With Superscript Alef Final Form" +64657 "Arabic Ligature Yeh With Reh Final Form" +64658 "Arabic Ligature Yeh With Zain Final Form" +64659 "Arabic Ligature Yeh With Meem Final Form" +64660 "Arabic Ligature Yeh With Noon Final Form" +64661 "Arabic Ligature Yeh With Alef Maksura Final Form" +64662 "Arabic Ligature Yeh With Yeh Final Form" +64663 "Arabic Ligature Yeh With Hamza Above With Jeem Initial Form" +64664 "Arabic Ligature Yeh With Hamza Above With Hah Initial Form" +64665 "Arabic Ligature Yeh With Hamza Above With Khah Initial Form" +64666 "Arabic Ligature Yeh With Hamza Above With Meem Initial Form" +64667 "Arabic Ligature Yeh With Hamza Above With Heh Initial Form" +64668 "Arabic Ligature Beh With Jeem Initial Form" +64669 "Arabic Ligature Beh With Hah Initial Form" +64670 "Arabic Ligature Beh With Khah Initial Form" +64671 "Arabic Ligature Beh With Meem Initial Form" +64672 "Arabic Ligature Beh With Heh Initial Form" +64673 "Arabic Ligature Teh With Jeem Initial Form" +64674 "Arabic Ligature Teh With Hah Initial Form" +64675 "Arabic Ligature Teh With Khah Initial Form" +64676 "Arabic Ligature Teh With Meem Initial Form" +64677 "Arabic Ligature Teh With Heh Initial Form" +64678 "Arabic Ligature Theh With Meem Initial Form" +64679 "Arabic Ligature Jeem With Hah Initial Form" +64680 "Arabic Ligature Jeem With Meem Initial Form" +64681 "Arabic Ligature Hah With Jeem Initial Form" +64682 "Arabic Ligature Hah With Meem Initial Form" +64683 "Arabic Ligature Khah With Jeem Initial Form" +64684 "Arabic Ligature Khah With Meem Initial Form" +64685 "Arabic Ligature Seen With Jeem Initial Form" +64686 "Arabic Ligature Seen With Hah Initial Form" +64687 "Arabic Ligature Seen With Khah Initial Form" +64688 "Arabic Ligature Seen With Meem Initial Form" +64689 "Arabic Ligature Sad With Hah Initial Form" +64690 "Arabic Ligature Sad With Khah Initial Form" +64691 "Arabic Ligature Sad With Meem Initial Form" +64692 "Arabic Ligature Dad With Jeem Initial Form" +64693 "Arabic Ligature Dad With Hah Initial Form" +64694 "Arabic Ligature Dad With Khah Initial Form" +64695 "Arabic Ligature Dad With Meem Initial Form" +64696 "Arabic Ligature Tah With Hah Initial Form" +64697 "Arabic Ligature Zah With Meem Initial Form" +64698 "Arabic Ligature Ain With Jeem Initial Form" +64699 "Arabic Ligature Ain With Meem Initial Form" +64700 "Arabic Ligature Ghain With Jeem Initial Form" +64701 "Arabic Ligature Ghain With Meem Initial Form" +64702 "Arabic Ligature Feh With Jeem Initial Form" +64703 "Arabic Ligature Feh With Hah Initial Form" +64704 "Arabic Ligature Feh With Khah Initial Form" +64705 "Arabic Ligature Feh With Meem Initial Form" +64706 "Arabic Ligature Qaf With Hah Initial Form" +64707 "Arabic Ligature Qaf With Meem Initial Form" +64708 "Arabic Ligature Kaf With Jeem Initial Form" +64709 "Arabic Ligature Kaf With Hah Initial Form" +64710 "Arabic Ligature Kaf With Khah Initial Form" +64711 "Arabic Ligature Kaf With Lam Initial Form" +64712 "Arabic Ligature Kaf With Meem Initial Form" +64713 "Arabic Ligature Lam With Jeem Initial Form" +64714 "Arabic Ligature Lam With Hah Initial Form" +64715 "Arabic Ligature Lam With Khah Initial Form" +64716 "Arabic Ligature Lam With Meem Initial Form" +64717 "Arabic Ligature Lam With Heh Initial Form" +64718 "Arabic Ligature Meem With Jeem Initial Form" +64719 "Arabic Ligature Meem With Hah Initial Form" +64720 "Arabic Ligature Meem With Khah Initial Form" +64721 "Arabic Ligature Meem With Meem Initial Form" +64722 "Arabic Ligature Noon With Jeem Initial Form" +64723 "Arabic Ligature Noon With Hah Initial Form" +64724 "Arabic Ligature Noon With Khah Initial Form" +64725 "Arabic Ligature Noon With Meem Initial Form" +64726 "Arabic Ligature Noon With Heh Initial Form" +64727 "Arabic Ligature Heh With Jeem Initial Form" +64728 "Arabic Ligature Heh With Meem Initial Form" +64729 "Arabic Ligature Heh With Superscript Alef Initial Form" +64730 "Arabic Ligature Yeh With Jeem Initial Form" +64731 "Arabic Ligature Yeh With Hah Initial Form" +64732 "Arabic Ligature Yeh With Khah Initial Form" +64733 "Arabic Ligature Yeh With Meem Initial Form" +64734 "Arabic Ligature Yeh With Heh Initial Form" +64735 "Arabic Ligature Yeh With Hamza Above With Meem Medial Form" +64736 "Arabic Ligature Yeh With Hamza Above With Heh Medial Form" +64737 "Arabic Ligature Beh With Meem Medial Form" +64738 "Arabic Ligature Beh With Heh Medial Form" +64739 "Arabic Ligature Teh With Meem Medial Form" +64740 "Arabic Ligature Teh With Heh Medial Form" +64741 "Arabic Ligature Theh With Meem Medial Form" +64742 "Arabic Ligature Theh With Heh Medial Form" +64743 "Arabic Ligature Seen With Meem Medial Form" +64744 "Arabic Ligature Seen With Heh Medial Form" +64745 "Arabic Ligature Sheen With Meem Medial Form" +64746 "Arabic Ligature Sheen With Heh Medial Form" +64747 "Arabic Ligature Kaf With Lam Medial Form" +64748 "Arabic Ligature Kaf With Meem Medial Form" +64749 "Arabic Ligature Lam With Meem Medial Form" +64750 "Arabic Ligature Noon With Meem Medial Form" +64751 "Arabic Ligature Noon With Heh Medial Form" +64752 "Arabic Ligature Yeh With Meem Medial Form" +64753 "Arabic Ligature Yeh With Heh Medial Form" +64754 "Arabic Ligature Shadda With Fatha Medial Form" +64755 "Arabic Ligature Shadda With Damma Medial Form" +64756 "Arabic Ligature Shadda With Kasra Medial Form" +64757 "Arabic Ligature Tah With Alef Maksura Isolated Form" +64758 "Arabic Ligature Tah With Yeh Isolated Form" +64759 "Arabic Ligature Ain With Alef Maksura Isolated Form" +64760 "Arabic Ligature Ain With Yeh Isolated Form" +64761 "Arabic Ligature Ghain With Alef Maksura Isolated Form" +64762 "Arabic Ligature Ghain With Yeh Isolated Form" +64763 "Arabic Ligature Seen With Alef Maksura Isolated Form" +64764 "Arabic Ligature Seen With Yeh Isolated Form" +64765 "Arabic Ligature Sheen With Alef Maksura Isolated Form" +64766 "Arabic Ligature Sheen With Yeh Isolated Form" +64767 "Arabic Ligature Hah With Alef Maksura Isolated Form" +64768 "Arabic Ligature Hah With Yeh Isolated Form" +64769 "Arabic Ligature Jeem With Alef Maksura Isolated Form" +64770 "Arabic Ligature Jeem With Yeh Isolated Form" +64771 "Arabic Ligature Khah With Alef Maksura Isolated Form" +64772 "Arabic Ligature Khah With Yeh Isolated Form" +64773 "Arabic Ligature Sad With Alef Maksura Isolated Form" +64774 "Arabic Ligature Sad With Yeh Isolated Form" +64775 "Arabic Ligature Dad With Alef Maksura Isolated Form" +64776 "Arabic Ligature Dad With Yeh Isolated Form" +64777 "Arabic Ligature Sheen With Jeem Isolated Form" +64778 "Arabic Ligature Sheen With Hah Isolated Form" +64779 "Arabic Ligature Sheen With Khah Isolated Form" +64780 "Arabic Ligature Sheen With Meem Isolated Form" +64781 "Arabic Ligature Sheen With Reh Isolated Form" +64782 "Arabic Ligature Seen With Reh Isolated Form" +64783 "Arabic Ligature Sad With Reh Isolated Form" +64784 "Arabic Ligature Dad With Reh Isolated Form" +64785 "Arabic Ligature Tah With Alef Maksura Final Form" +64786 "Arabic Ligature Tah With Yeh Final Form" +64787 "Arabic Ligature Ain With Alef Maksura Final Form" +64788 "Arabic Ligature Ain With Yeh Final Form" +64789 "Arabic Ligature Ghain With Alef Maksura Final Form" +64790 "Arabic Ligature Ghain With Yeh Final Form" +64791 "Arabic Ligature Seen With Alef Maksura Final Form" +64792 "Arabic Ligature Seen With Yeh Final Form" +64793 "Arabic Ligature Sheen With Alef Maksura Final Form" +64794 "Arabic Ligature Sheen With Yeh Final Form" +64795 "Arabic Ligature Hah With Alef Maksura Final Form" +64796 "Arabic Ligature Hah With Yeh Final Form" +64797 "Arabic Ligature Jeem With Alef Maksura Final Form" +64798 "Arabic Ligature Jeem With Yeh Final Form" +64799 "Arabic Ligature Khah With Alef Maksura Final Form" +64800 "Arabic Ligature Khah With Yeh Final Form" +64801 "Arabic Ligature Sad With Alef Maksura Final Form" +64802 "Arabic Ligature Sad With Yeh Final Form" +64803 "Arabic Ligature Dad With Alef Maksura Final Form" +64804 "Arabic Ligature Dad With Yeh Final Form" +64805 "Arabic Ligature Sheen With Jeem Final Form" +64806 "Arabic Ligature Sheen With Hah Final Form" +64807 "Arabic Ligature Sheen With Khah Final Form" +64808 "Arabic Ligature Sheen With Meem Final Form" +64809 "Arabic Ligature Sheen With Reh Final Form" +64810 "Arabic Ligature Seen With Reh Final Form" +64811 "Arabic Ligature Sad With Reh Final Form" +64812 "Arabic Ligature Dad With Reh Final Form" +64813 "Arabic Ligature Sheen With Jeem Initial Form" +64814 "Arabic Ligature Sheen With Hah Initial Form" +64815 "Arabic Ligature Sheen With Khah Initial Form" +64816 "Arabic Ligature Sheen With Meem Initial Form" +64817 "Arabic Ligature Seen With Heh Initial Form" +64818 "Arabic Ligature Sheen With Heh Initial Form" +64819 "Arabic Ligature Tah With Meem Initial Form" +64820 "Arabic Ligature Seen With Jeem Medial Form" +64821 "Arabic Ligature Seen With Hah Medial Form" +64822 "Arabic Ligature Seen With Khah Medial Form" +64823 "Arabic Ligature Sheen With Jeem Medial Form" +64824 "Arabic Ligature Sheen With Hah Medial Form" +64825 "Arabic Ligature Sheen With Khah Medial Form" +64826 "Arabic Ligature Tah With Meem Medial Form" +64827 "Arabic Ligature Zah With Meem Medial Form" +64828 "Arabic Ligature Alef With Fathatan Final Form" +64829 "Arabic Ligature Alef With Fathatan Isolated Form" +64830 "Ornate Left Parenthesis" +64831 "Ornate Right Parenthesis" +64848 "Arabic Ligature Teh With Jeem With Meem Initial Form" +64849 "Arabic Ligature Teh With Hah With Jeem Final Form" +64850 "Arabic Ligature Teh With Hah With Jeem Initial Form" +64851 "Arabic Ligature Teh With Hah With Meem Initial Form" +64852 "Arabic Ligature Teh With Khah With Meem Initial Form" +64853 "Arabic Ligature Teh With Meem With Jeem Initial Form" +64854 "Arabic Ligature Teh With Meem With Hah Initial Form" +64855 "Arabic Ligature Teh With Meem With Khah Initial Form" +64856 "Arabic Ligature Jeem With Meem With Hah Final Form" +64857 "Arabic Ligature Jeem With Meem With Hah Initial Form" +64858 "Arabic Ligature Hah With Meem With Yeh Final Form" +64859 "Arabic Ligature Hah With Meem With Alef Maksura Final Form" +64860 "Arabic Ligature Seen With Hah With Jeem Initial Form" +64861 "Arabic Ligature Seen With Jeem With Hah Initial Form" +64862 "Arabic Ligature Seen With Jeem With Alef Maksura Final Form" +64863 "Arabic Ligature Seen With Meem With Hah Final Form" +64864 "Arabic Ligature Seen With Meem With Hah Initial Form" +64865 "Arabic Ligature Seen With Meem With Jeem Initial Form" +64866 "Arabic Ligature Seen With Meem With Meem Final Form" +64867 "Arabic Ligature Seen With Meem With Meem Initial Form" +64868 "Arabic Ligature Sad With Hah With Hah Final Form" +64869 "Arabic Ligature Sad With Hah With Hah Initial Form" +64870 "Arabic Ligature Sad With Meem With Meem Final Form" +64871 "Arabic Ligature Sheen With Hah With Meem Final Form" +64872 "Arabic Ligature Sheen With Hah With Meem Initial Form" +64873 "Arabic Ligature Sheen With Jeem With Yeh Final Form" +64874 "Arabic Ligature Sheen With Meem With Khah Final Form" +64875 "Arabic Ligature Sheen With Meem With Khah Initial Form" +64876 "Arabic Ligature Sheen With Meem With Meem Final Form" +64877 "Arabic Ligature Sheen With Meem With Meem Initial Form" +64878 "Arabic Ligature Dad With Hah With Alef Maksura Final Form" +64879 "Arabic Ligature Dad With Khah With Meem Final Form" +64880 "Arabic Ligature Dad With Khah With Meem Initial Form" +64881 "Arabic Ligature Tah With Meem With Hah Final Form" +64882 "Arabic Ligature Tah With Meem With Hah Initial Form" +64883 "Arabic Ligature Tah With Meem With Meem Initial Form" +64884 "Arabic Ligature Tah With Meem With Yeh Final Form" +64885 "Arabic Ligature Ain With Jeem With Meem Final Form" +64886 "Arabic Ligature Ain With Meem With Meem Final Form" +64887 "Arabic Ligature Ain With Meem With Meem Initial Form" +64888 "Arabic Ligature Ain With Meem With Alef Maksura Final Form" +64889 "Arabic Ligature Ghain With Meem With Meem Final Form" +64890 "Arabic Ligature Ghain With Meem With Yeh Final Form" +64891 "Arabic Ligature Ghain With Meem With Alef Maksura Final Form" +64892 "Arabic Ligature Feh With Khah With Meem Final Form" +64893 "Arabic Ligature Feh With Khah With Meem Initial Form" +64894 "Arabic Ligature Qaf With Meem With Hah Final Form" +64895 "Arabic Ligature Qaf With Meem With Meem Final Form" +64896 "Arabic Ligature Lam With Hah With Meem Final Form" +64897 "Arabic Ligature Lam With Hah With Yeh Final Form" +64898 "Arabic Ligature Lam With Hah With Alef Maksura Final Form" +64899 "Arabic Ligature Lam With Jeem With Jeem Initial Form" +64900 "Arabic Ligature Lam With Jeem With Jeem Final Form" +64901 "Arabic Ligature Lam With Khah With Meem Final Form" +64902 "Arabic Ligature Lam With Khah With Meem Initial Form" +64903 "Arabic Ligature Lam With Meem With Hah Final Form" +64904 "Arabic Ligature Lam With Meem With Hah Initial Form" +64905 "Arabic Ligature Meem With Hah With Jeem Initial Form" +64906 "Arabic Ligature Meem With Hah With Meem Initial Form" +64907 "Arabic Ligature Meem With Hah With Yeh Final Form" +64908 "Arabic Ligature Meem With Jeem With Hah Initial Form" +64909 "Arabic Ligature Meem With Jeem With Meem Initial Form" +64910 "Arabic Ligature Meem With Khah With Jeem Initial Form" +64911 "Arabic Ligature Meem With Khah With Meem Initial Form" +64914 "Arabic Ligature Meem With Jeem With Khah Initial Form" +64915 "Arabic Ligature Heh With Meem With Jeem Initial Form" +64916 "Arabic Ligature Heh With Meem With Meem Initial Form" +64917 "Arabic Ligature Noon With Hah With Meem Initial Form" +64918 "Arabic Ligature Noon With Hah With Alef Maksura Final Form" +64919 "Arabic Ligature Noon With Jeem With Meem Final Form" +64920 "Arabic Ligature Noon With Jeem With Meem Initial Form" +64921 "Arabic Ligature Noon With Jeem With Alef Maksura Final Form" +64922 "Arabic Ligature Noon With Meem With Yeh Final Form" +64923 "Arabic Ligature Noon With Meem With Alef Maksura Final Form" +64924 "Arabic Ligature Yeh With Meem With Meem Final Form" +64925 "Arabic Ligature Yeh With Meem With Meem Initial Form" +64926 "Arabic Ligature Beh With Khah With Yeh Final Form" +64927 "Arabic Ligature Teh With Jeem With Yeh Final Form" +64928 "Arabic Ligature Teh With Jeem With Alef Maksura Final Form" +64929 "Arabic Ligature Teh With Khah With Yeh Final Form" +64930 "Arabic Ligature Teh With Khah With Alef Maksura Final Form" +64931 "Arabic Ligature Teh With Meem With Yeh Final Form" +64932 "Arabic Ligature Teh With Meem With Alef Maksura Final Form" +64933 "Arabic Ligature Jeem With Meem With Yeh Final Form" +64934 "Arabic Ligature Jeem With Hah With Alef Maksura Final Form" +64935 "Arabic Ligature Jeem With Meem With Alef Maksura Final Form" +64936 "Arabic Ligature Seen With Khah With Alef Maksura Final Form" +64937 "Arabic Ligature Sad With Hah With Yeh Final Form" +64938 "Arabic Ligature Sheen With Hah With Yeh Final Form" +64939 "Arabic Ligature Dad With Hah With Yeh Final Form" +64940 "Arabic Ligature Lam With Jeem With Yeh Final Form" +64941 "Arabic Ligature Lam With Meem With Yeh Final Form" +64942 "Arabic Ligature Yeh With Hah With Yeh Final Form" +64943 "Arabic Ligature Yeh With Jeem With Yeh Final Form" +64944 "Arabic Ligature Yeh With Meem With Yeh Final Form" +64945 "Arabic Ligature Meem With Meem With Yeh Final Form" +64946 "Arabic Ligature Qaf With Meem With Yeh Final Form" +64947 "Arabic Ligature Noon With Hah With Yeh Final Form" +64948 "Arabic Ligature Qaf With Meem With Hah Initial Form" +64949 "Arabic Ligature Lam With Hah With Meem Initial Form" +64950 "Arabic Ligature Ain With Meem With Yeh Final Form" +64951 "Arabic Ligature Kaf With Meem With Yeh Final Form" +64952 "Arabic Ligature Noon With Jeem With Hah Initial Form" +64953 "Arabic Ligature Meem With Khah With Yeh Final Form" +64954 "Arabic Ligature Lam With Jeem With Meem Initial Form" +64955 "Arabic Ligature Kaf With Meem With Meem Final Form" +64956 "Arabic Ligature Lam With Jeem With Meem Final Form" +64957 "Arabic Ligature Noon With Jeem With Hah Final Form" +64958 "Arabic Ligature Jeem With Hah With Yeh Final Form" +64959 "Arabic Ligature Hah With Jeem With Yeh Final Form" +64960 "Arabic Ligature Meem With Jeem With Yeh Final Form" +64961 "Arabic Ligature Feh With Meem With Yeh Final Form" +64962 "Arabic Ligature Beh With Hah With Yeh Final Form" +64963 "Arabic Ligature Kaf With Meem With Meem Initial Form" +64964 "Arabic Ligature Ain With Jeem With Meem Initial Form" +64965 "Arabic Ligature Sad With Meem With Meem Initial Form" +64966 "Arabic Ligature Seen With Khah With Yeh Final Form" +64967 "Arabic Ligature Noon With Jeem With Yeh Final Form" +65008 "Arabic Ligature Salla Used As Koranic Stop Sign Isolated Form" +65009 "Arabic Ligature Qala Used As Koranic Stop Sign Isolated Form" +65010 "Arabic Ligature Allah Isolated Form" +65011 "Arabic Ligature Akbar Isolated Form" +65012 "Arabic Ligature Mohammad Isolated Form" +65013 "Arabic Ligature Salam Isolated Form" +65014 "Arabic Ligature Rasoul Isolated Form" +65015 "Arabic Ligature Alayhe Isolated Form" +65016 "Arabic Ligature Wasallam Isolated Form" +65017 "Arabic Ligature Salla Isolated Form" +65018 "Arabic Ligature Sallallahou Alayhe Wasallam" +65019 "Arabic Ligature Jallajalalouhou" +65020 "Rial Sign" +65021 "Arabic Ligature Bismillah Ar-Rahman Ar-Raheem" +65024 "Variation Selector-1" +65025 "Variation Selector-2" +65026 "Variation Selector-3" +65027 "Variation Selector-4" +65028 "Variation Selector-5" +65029 "Variation Selector-6" +65030 "Variation Selector-7" +65031 "Variation Selector-8" +65032 "Variation Selector-9" +65033 "Variation Selector-10" +65034 "Variation Selector-11" +65035 "Variation Selector-12" +65036 "Variation Selector-13" +65037 "Variation Selector-14" +65038 "Variation Selector-15" +65039 "Variation Selector-16" +65040 "Presentation Form For Vertical Comma" +65041 "Presentation Form For Vertical Ideographic Comma" +65042 "Presentation Form For Vertical Ideographic Full Stop" +65043 "Presentation Form For Vertical Colon" +65044 "Presentation Form For Vertical Semicolon" +65045 "Presentation Form For Vertical Exclamation Mark" +65046 "Presentation Form For Vertical Question Mark" +65047 "Presentation Form For Vertical Left White Lenticular Bracket" +65048 "Presentation Form For Vertical Right White Lenticular Brakcet" +65049 "Presentation Form For Vertical Horizontal Ellipsis" +65056 "Combining Ligature Left Half" +65057 "Combining Ligature Right Half" +65058 "Combining Double Tilde Left Half" +65059 "Combining Double Tilde Right Half" +65060 "Combining Macron Left Half" +65061 "Combining Macron Right Half" +65062 "Combining Conjoining Macron" +65072 "Presentation Form For Vertical Two Dot Leader" +65073 "Presentation Form For Vertical Em Dash" +65074 "Presentation Form For Vertical En Dash" +65075 "Presentation Form For Vertical Low Line" +65076 "Presentation Form For Vertical Wavy Low Line" +65077 "Presentation Form For Vertical Left Parenthesis" +65078 "Presentation Form For Vertical Right Parenthesis" +65079 "Presentation Form For Vertical Left Curly Bracket" +65080 "Presentation Form For Vertical Right Curly Bracket" +65081 "Presentation Form For Vertical Left Tortoise Shell Bracket" +65082 "Presentation Form For Vertical Right Tortoise Shell Bracket" +65083 "Presentation Form For Vertical Left Black Lenticular Bracket" +65084 "Presentation Form For Vertical Right Black Lenticular Bracket" +65085 "Presentation Form For Vertical Left Double Angle Bracket" +65086 "Presentation Form For Vertical Right Double Angle Bracket" +65087 "Presentation Form For Vertical Left Angle Bracket" +65088 "Presentation Form For Vertical Right Angle Bracket" +65089 "Presentation Form For Vertical Left Corner Bracket" +65090 "Presentation Form For Vertical Right Corner Bracket" +65091 "Presentation Form For Vertical Left White Corner Bracket" +65092 "Presentation Form For Vertical Right White Corner Bracket" +65093 "Sesame Dot" +65094 "White Sesame Dot" +65095 "Presentation Form For Vertical Left Square Bracket" +65096 "Presentation Form For Vertical Right Square Bracket" +65097 "Dashed Overline" +65098 "Centreline Overline" +65099 "Wavy Overline" +65100 "Double Wavy Overline" +65101 "Dashed Low Line" +65102 "Centreline Low Line" +65103 "Wavy Low Line" +65104 "Small Comma" +65105 "Small Ideographic Comma" +65106 "Small Full Stop" +65108 "Small Semicolon" +65109 "Small Colon" +65110 "Small Question Mark" +65111 "Small Exclamation Mark" +65112 "Small Em Dash" +65113 "Small Left Parenthesis" +65114 "Small Right Parenthesis" +65115 "Small Left Curly Bracket" +65116 "Small Right Curly Bracket" +65117 "Small Left Tortoise Shell Bracket" +65118 "Small Right Tortoise Shell Bracket" +65119 "Small Number Sign" +65120 "Small Ampersand" +65121 "Small Asterisk" +65122 "Small Plus Sign" +65123 "Small Hyphen-Minus" +65124 "Small Less-Than Sign" +65125 "Small Greater-Than Sign" +65126 "Small Equals Sign" +65128 "Small Reverse Solidus" +65129 "Small Dollar Sign" +65130 "Small Percent Sign" +65131 "Small Commercial At" +65136 "Arabic Fathatan Isolated Form" +65137 "Arabic Tatweel With Fathatan Above" +65138 "Arabic Dammatan Isolated Form" +65139 "Arabic Tail Fragment" +65140 "Arabic Kasratan Isolated Form" +65142 "Arabic Fatha Isolated Form" +65143 "Arabic Fatha Medial Form" +65144 "Arabic Damma Isolated Form" +65145 "Arabic Damma Medial Form" +65146 "Arabic Kasra Isolated Form" +65147 "Arabic Kasra Medial Form" +65148 "Arabic Shadda Isolated Form" +65149 "Arabic Shadda Medial Form" +65150 "Arabic Sukun Isolated Form" +65151 "Arabic Sukun Medial Form" +65152 "Arabic Letter Hamza Isolated Form" +65153 "Arabic Letter Alef With Madda Above Isolated Form" +65154 "Arabic Letter Alef With Madda Above Final Form" +65155 "Arabic Letter Alef With Hamza Above Isolated Form" +65156 "Arabic Letter Alef With Hamza Above Final Form" +65157 "Arabic Letter Waw With Hamza Above Isolated Form" +65158 "Arabic Letter Waw With Hamza Above Final Form" +65159 "Arabic Letter Alef With Hamza Below Isolated Form" +65160 "Arabic Letter Alef With Hamza Below Final Form" +65161 "Arabic Letter Yeh With Hamza Above Isolated Form" +65162 "Arabic Letter Yeh With Hamza Above Final Form" +65163 "Arabic Letter Yeh With Hamza Above Initial Form" +65164 "Arabic Letter Yeh With Hamza Above Medial Form" +65165 "Arabic Letter Alef Isolated Form" +65166 "Arabic Letter Alef Final Form" +65167 "Arabic Letter Beh Isolated Form" +65168 "Arabic Letter Beh Final Form" +65169 "Arabic Letter Beh Initial Form" +65170 "Arabic Letter Beh Medial Form" +65171 "Arabic Letter Teh Marbuta Isolated Form" +65172 "Arabic Letter Teh Marbuta Final Form" +65173 "Arabic Letter Teh Isolated Form" +65174 "Arabic Letter Teh Final Form" +65175 "Arabic Letter Teh Initial Form" +65176 "Arabic Letter Teh Medial Form" +65177 "Arabic Letter Theh Isolated Form" +65178 "Arabic Letter Theh Final Form" +65179 "Arabic Letter Theh Initial Form" +65180 "Arabic Letter Theh Medial Form" +65181 "Arabic Letter Jeem Isolated Form" +65182 "Arabic Letter Jeem Final Form" +65183 "Arabic Letter Jeem Initial Form" +65184 "Arabic Letter Jeem Medial Form" +65185 "Arabic Letter Hah Isolated Form" +65186 "Arabic Letter Hah Final Form" +65187 "Arabic Letter Hah Initial Form" +65188 "Arabic Letter Hah Medial Form" +65189 "Arabic Letter Khah Isolated Form" +65190 "Arabic Letter Khah Final Form" +65191 "Arabic Letter Khah Initial Form" +65192 "Arabic Letter Khah Medial Form" +65193 "Arabic Letter Dal Isolated Form" +65194 "Arabic Letter Dal Final Form" +65195 "Arabic Letter Thal Isolated Form" +65196 "Arabic Letter Thal Final Form" +65197 "Arabic Letter Reh Isolated Form" +65198 "Arabic Letter Reh Final Form" +65199 "Arabic Letter Zain Isolated Form" +65200 "Arabic Letter Zain Final Form" +65201 "Arabic Letter Seen Isolated Form" +65202 "Arabic Letter Seen Final Form" +65203 "Arabic Letter Seen Initial Form" +65204 "Arabic Letter Seen Medial Form" +65205 "Arabic Letter Sheen Isolated Form" +65206 "Arabic Letter Sheen Final Form" +65207 "Arabic Letter Sheen Initial Form" +65208 "Arabic Letter Sheen Medial Form" +65209 "Arabic Letter Sad Isolated Form" +65210 "Arabic Letter Sad Final Form" +65211 "Arabic Letter Sad Initial Form" +65212 "Arabic Letter Sad Medial Form" +65213 "Arabic Letter Dad Isolated Form" +65214 "Arabic Letter Dad Final Form" +65215 "Arabic Letter Dad Initial Form" +65216 "Arabic Letter Dad Medial Form" +65217 "Arabic Letter Tah Isolated Form" +65218 "Arabic Letter Tah Final Form" +65219 "Arabic Letter Tah Initial Form" +65220 "Arabic Letter Tah Medial Form" +65221 "Arabic Letter Zah Isolated Form" +65222 "Arabic Letter Zah Final Form" +65223 "Arabic Letter Zah Initial Form" +65224 "Arabic Letter Zah Medial Form" +65225 "Arabic Letter Ain Isolated Form" +65226 "Arabic Letter Ain Final Form" +65227 "Arabic Letter Ain Initial Form" +65228 "Arabic Letter Ain Medial Form" +65229 "Arabic Letter Ghain Isolated Form" +65230 "Arabic Letter Ghain Final Form" +65231 "Arabic Letter Ghain Initial Form" +65232 "Arabic Letter Ghain Medial Form" +65233 "Arabic Letter Feh Isolated Form" +65234 "Arabic Letter Feh Final Form" +65235 "Arabic Letter Feh Initial Form" +65236 "Arabic Letter Feh Medial Form" +65237 "Arabic Letter Qaf Isolated Form" +65238 "Arabic Letter Qaf Final Form" +65239 "Arabic Letter Qaf Initial Form" +65240 "Arabic Letter Qaf Medial Form" +65241 "Arabic Letter Kaf Isolated Form" +65242 "Arabic Letter Kaf Final Form" +65243 "Arabic Letter Kaf Initial Form" +65244 "Arabic Letter Kaf Medial Form" +65245 "Arabic Letter Lam Isolated Form" +65246 "Arabic Letter Lam Final Form" +65247 "Arabic Letter Lam Initial Form" +65248 "Arabic Letter Lam Medial Form" +65249 "Arabic Letter Meem Isolated Form" +65250 "Arabic Letter Meem Final Form" +65251 "Arabic Letter Meem Initial Form" +65252 "Arabic Letter Meem Medial Form" +65253 "Arabic Letter Noon Isolated Form" +65254 "Arabic Letter Noon Final Form" +65255 "Arabic Letter Noon Initial Form" +65256 "Arabic Letter Noon Medial Form" +65257 "Arabic Letter Heh Isolated Form" +65258 "Arabic Letter Heh Final Form" +65259 "Arabic Letter Heh Initial Form" +65260 "Arabic Letter Heh Medial Form" +65261 "Arabic Letter Waw Isolated Form" +65262 "Arabic Letter Waw Final Form" +65263 "Arabic Letter Alef Maksura Isolated Form" +65264 "Arabic Letter Alef Maksura Final Form" +65265 "Arabic Letter Yeh Isolated Form" +65266 "Arabic Letter Yeh Final Form" +65267 "Arabic Letter Yeh Initial Form" +65268 "Arabic Letter Yeh Medial Form" +65269 "Arabic Ligature Lam With Alef With Madda Above Isolated Form" +65270 "Arabic Ligature Lam With Alef With Madda Above Final Form" +65271 "Arabic Ligature Lam With Alef With Hamza Above Isolated Form" +65272 "Arabic Ligature Lam With Alef With Hamza Above Final Form" +65273 "Arabic Ligature Lam With Alef With Hamza Below Isolated Form" +65274 "Arabic Ligature Lam With Alef With Hamza Below Final Form" +65275 "Arabic Ligature Lam With Alef Isolated Form" +65276 "Arabic Ligature Lam With Alef Final Form" +65279 "Zero Width No-Break Space" +65281 "Fullwidth Exclamation Mark" +65282 "Fullwidth Quotation Mark" +65283 "Fullwidth Number Sign" +65284 "Fullwidth Dollar Sign" +65285 "Fullwidth Percent Sign" +65286 "Fullwidth Ampersand" +65287 "Fullwidth Apostrophe" +65288 "Fullwidth Left Parenthesis" +65289 "Fullwidth Right Parenthesis" +65290 "Fullwidth Asterisk" +65291 "Fullwidth Plus Sign" +65292 "Fullwidth Comma" +65293 "Fullwidth Hyphen-Minus" +65294 "Fullwidth Full Stop" +65295 "Fullwidth Solidus" +65296 "Fullwidth Digit Zero" +65297 "Fullwidth Digit One" +65298 "Fullwidth Digit Two" +65299 "Fullwidth Digit Three" +65300 "Fullwidth Digit Four" +65301 "Fullwidth Digit Five" +65302 "Fullwidth Digit Six" +65303 "Fullwidth Digit Seven" +65304 "Fullwidth Digit Eight" +65305 "Fullwidth Digit Nine" +65306 "Fullwidth Colon" +65307 "Fullwidth Semicolon" +65308 "Fullwidth Less-Than Sign" +65309 "Fullwidth Equals Sign" +65310 "Fullwidth Greater-Than Sign" +65311 "Fullwidth Question Mark" +65312 "Fullwidth Commercial At" +65313 "Fullwidth Latin Capital Letter A" +65314 "Fullwidth Latin Capital Letter B" +65315 "Fullwidth Latin Capital Letter C" +65316 "Fullwidth Latin Capital Letter D" +65317 "Fullwidth Latin Capital Letter E" +65318 "Fullwidth Latin Capital Letter F" +65319 "Fullwidth Latin Capital Letter G" +65320 "Fullwidth Latin Capital Letter H" +65321 "Fullwidth Latin Capital Letter I" +65322 "Fullwidth Latin Capital Letter J" +65323 "Fullwidth Latin Capital Letter K" +65324 "Fullwidth Latin Capital Letter L" +65325 "Fullwidth Latin Capital Letter M" +65326 "Fullwidth Latin Capital Letter N" +65327 "Fullwidth Latin Capital Letter O" +65328 "Fullwidth Latin Capital Letter P" +65329 "Fullwidth Latin Capital Letter Q" +65330 "Fullwidth Latin Capital Letter R" +65331 "Fullwidth Latin Capital Letter S" +65332 "Fullwidth Latin Capital Letter T" +65333 "Fullwidth Latin Capital Letter U" +65334 "Fullwidth Latin Capital Letter V" +65335 "Fullwidth Latin Capital Letter W" +65336 "Fullwidth Latin Capital Letter X" +65337 "Fullwidth Latin Capital Letter Y" +65338 "Fullwidth Latin Capital Letter Z" +65339 "Fullwidth Left Square Bracket" +65340 "Fullwidth Reverse Solidus" +65341 "Fullwidth Right Square Bracket" +65342 "Fullwidth Circumflex Accent" +65343 "Fullwidth Low Line" +65344 "Fullwidth Grave Accent" +65345 "Fullwidth Latin Small Letter A" +65346 "Fullwidth Latin Small Letter B" +65347 "Fullwidth Latin Small Letter C" +65348 "Fullwidth Latin Small Letter D" +65349 "Fullwidth Latin Small Letter E" +65350 "Fullwidth Latin Small Letter F" +65351 "Fullwidth Latin Small Letter G" +65352 "Fullwidth Latin Small Letter H" +65353 "Fullwidth Latin Small Letter I" +65354 "Fullwidth Latin Small Letter J" +65355 "Fullwidth Latin Small Letter K" +65356 "Fullwidth Latin Small Letter L" +65357 "Fullwidth Latin Small Letter M" +65358 "Fullwidth Latin Small Letter N" +65359 "Fullwidth Latin Small Letter O" +65360 "Fullwidth Latin Small Letter P" +65361 "Fullwidth Latin Small Letter Q" +65362 "Fullwidth Latin Small Letter R" +65363 "Fullwidth Latin Small Letter S" +65364 "Fullwidth Latin Small Letter T" +65365 "Fullwidth Latin Small Letter U" +65366 "Fullwidth Latin Small Letter V" +65367 "Fullwidth Latin Small Letter W" +65368 "Fullwidth Latin Small Letter X" +65369 "Fullwidth Latin Small Letter Y" +65370 "Fullwidth Latin Small Letter Z" +65371 "Fullwidth Left Curly Bracket" +65372 "Fullwidth Vertical Line" +65373 "Fullwidth Right Curly Bracket" +65374 "Fullwidth Tilde" +65375 "Fullwidth Left White Parenthesis" +65376 "Fullwidth Right White Parenthesis" +65377 "Halfwidth Ideographic Full Stop" +65378 "Halfwidth Left Corner Bracket" +65379 "Halfwidth Right Corner Bracket" +65380 "Halfwidth Ideographic Comma" +65381 "Halfwidth Katakana Middle Dot" +65382 "Halfwidth Katakana Letter Wo" +65383 "Halfwidth Katakana Letter Small A" +65384 "Halfwidth Katakana Letter Small I" +65385 "Halfwidth Katakana Letter Small U" +65386 "Halfwidth Katakana Letter Small E" +65387 "Halfwidth Katakana Letter Small O" +65388 "Halfwidth Katakana Letter Small Ya" +65389 "Halfwidth Katakana Letter Small Yu" +65390 "Halfwidth Katakana Letter Small Yo" +65391 "Halfwidth Katakana Letter Small Tu" +65392 "Halfwidth Katakana-Hiragana Prolonged Sound Mark" +65393 "Halfwidth Katakana Letter A" +65394 "Halfwidth Katakana Letter I" +65395 "Halfwidth Katakana Letter U" +65396 "Halfwidth Katakana Letter E" +65397 "Halfwidth Katakana Letter O" +65398 "Halfwidth Katakana Letter Ka" +65399 "Halfwidth Katakana Letter Ki" +65400 "Halfwidth Katakana Letter Ku" +65401 "Halfwidth Katakana Letter Ke" +65402 "Halfwidth Katakana Letter Ko" +65403 "Halfwidth Katakana Letter Sa" +65404 "Halfwidth Katakana Letter Si" +65405 "Halfwidth Katakana Letter Su" +65406 "Halfwidth Katakana Letter Se" +65407 "Halfwidth Katakana Letter So" +65408 "Halfwidth Katakana Letter Ta" +65409 "Halfwidth Katakana Letter Ti" +65410 "Halfwidth Katakana Letter Tu" +65411 "Halfwidth Katakana Letter Te" +65412 "Halfwidth Katakana Letter To" +65413 "Halfwidth Katakana Letter Na" +65414 "Halfwidth Katakana Letter Ni" +65415 "Halfwidth Katakana Letter Nu" +65416 "Halfwidth Katakana Letter Ne" +65417 "Halfwidth Katakana Letter No" +65418 "Halfwidth Katakana Letter Ha" +65419 "Halfwidth Katakana Letter Hi" +65420 "Halfwidth Katakana Letter Hu" +65421 "Halfwidth Katakana Letter He" +65422 "Halfwidth Katakana Letter Ho" +65423 "Halfwidth Katakana Letter Ma" +65424 "Halfwidth Katakana Letter Mi" +65425 "Halfwidth Katakana Letter Mu" +65426 "Halfwidth Katakana Letter Me" +65427 "Halfwidth Katakana Letter Mo" +65428 "Halfwidth Katakana Letter Ya" +65429 "Halfwidth Katakana Letter Yu" +65430 "Halfwidth Katakana Letter Yo" +65431 "Halfwidth Katakana Letter Ra" +65432 "Halfwidth Katakana Letter Ri" +65433 "Halfwidth Katakana Letter Ru" +65434 "Halfwidth Katakana Letter Re" +65435 "Halfwidth Katakana Letter Ro" +65436 "Halfwidth Katakana Letter Wa" +65437 "Halfwidth Katakana Letter N" +65438 "Halfwidth Katakana Voiced Sound Mark" +65439 "Halfwidth Katakana Semi-Voiced Sound Mark" +65440 "Halfwidth Hangul Filler" +65441 "Halfwidth Hangul Letter Kiyeok" +65442 "Halfwidth Hangul Letter Ssangkiyeok" +65443 "Halfwidth Hangul Letter Kiyeok-Sios" +65444 "Halfwidth Hangul Letter Nieun" +65445 "Halfwidth Hangul Letter Nieun-Cieuc" +65446 "Halfwidth Hangul Letter Nieun-Hieuh" +65447 "Halfwidth Hangul Letter Tikeut" +65448 "Halfwidth Hangul Letter Ssangtikeut" +65449 "Halfwidth Hangul Letter Rieul" +65450 "Halfwidth Hangul Letter Rieul-Kiyeok" +65451 "Halfwidth Hangul Letter Rieul-Mieum" +65452 "Halfwidth Hangul Letter Rieul-Pieup" +65453 "Halfwidth Hangul Letter Rieul-Sios" +65454 "Halfwidth Hangul Letter Rieul-Thieuth" +65455 "Halfwidth Hangul Letter Rieul-Phieuph" +65456 "Halfwidth Hangul Letter Rieul-Hieuh" +65457 "Halfwidth Hangul Letter Mieum" +65458 "Halfwidth Hangul Letter Pieup" +65459 "Halfwidth Hangul Letter Ssangpieup" +65460 "Halfwidth Hangul Letter Pieup-Sios" +65461 "Halfwidth Hangul Letter Sios" +65462 "Halfwidth Hangul Letter Ssangsios" +65463 "Halfwidth Hangul Letter Ieung" +65464 "Halfwidth Hangul Letter Cieuc" +65465 "Halfwidth Hangul Letter Ssangcieuc" +65466 "Halfwidth Hangul Letter Chieuch" +65467 "Halfwidth Hangul Letter Khieukh" +65468 "Halfwidth Hangul Letter Thieuth" +65469 "Halfwidth Hangul Letter Phieuph" +65470 "Halfwidth Hangul Letter Hieuh" +65474 "Halfwidth Hangul Letter A" +65475 "Halfwidth Hangul Letter Ae" +65476 "Halfwidth Hangul Letter Ya" +65477 "Halfwidth Hangul Letter Yae" +65478 "Halfwidth Hangul Letter Eo" +65479 "Halfwidth Hangul Letter E" +65482 "Halfwidth Hangul Letter Yeo" +65483 "Halfwidth Hangul Letter Ye" +65484 "Halfwidth Hangul Letter O" +65485 "Halfwidth Hangul Letter Wa" +65486 "Halfwidth Hangul Letter Wae" +65487 "Halfwidth Hangul Letter Oe" +65490 "Halfwidth Hangul Letter Yo" +65491 "Halfwidth Hangul Letter U" +65492 "Halfwidth Hangul Letter Weo" +65493 "Halfwidth Hangul Letter We" +65494 "Halfwidth Hangul Letter Wi" +65495 "Halfwidth Hangul Letter Yu" +65498 "Halfwidth Hangul Letter Eu" +65499 "Halfwidth Hangul Letter Yi" +65500 "Halfwidth Hangul Letter I" +65504 "Fullwidth Cent Sign" +65505 "Fullwidth Pound Sign" +65506 "Fullwidth Not Sign" +65507 "Fullwidth Macron" +65508 "Fullwidth Broken Bar" +65509 "Fullwidth Yen Sign" +65510 "Fullwidth Won Sign" +65512 "Halfwidth Forms Light Vertical" +65513 "Halfwidth Leftwards Arrow" +65514 "Halfwidth Upwards Arrow" +65515 "Halfwidth Rightwards Arrow" +65516 "Halfwidth Downwards Arrow" +65517 "Halfwidth Black Square" +65518 "Halfwidth White Circle" +65529 "Interlinear Annotation Anchor" +65530 "Interlinear Annotation Separator" +65531 "Interlinear Annotation Terminator" +65532 "Object Replacement Character" +END diff --git a/dll/win32/kernel32/client/console/console.c b/dll/win32/kernel32/client/console/console.c index 249003e9b75..ddb7bdf6eb3 100644 --- a/dll/win32/kernel32/client/console/console.c +++ b/dll/win32/kernel32/client/console/console.c @@ -960,7 +960,7 @@ AllocConsole(VOID) InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo, &Parameters->ImagePathName); - AllocConsoleRequest->Console = NULL; + AllocConsoleRequest->ConsoleHandle = NULL; AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher; AllocConsoleRequest->PropDispatcher = PropDialogHandler; @@ -977,7 +977,7 @@ AllocConsole(VOID) return FALSE; } - Parameters->ConsoleHandle = AllocConsoleRequest->Console; + Parameters->ConsoleHandle = AllocConsoleRequest->ConsoleHandle; SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle ); SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle); SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle ); @@ -2174,7 +2174,7 @@ AttachConsole(DWORD dwProcessId) return FALSE; } - Parameters->ConsoleHandle = AttachConsoleRequest->Console; + Parameters->ConsoleHandle = AttachConsoleRequest->ConsoleHandle; SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle ); SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle); SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle ); diff --git a/dll/win32/kernel32/client/console/init.c b/dll/win32/kernel32/client/console/init.c index 33203b00942..a8735ae85f3 100644 --- a/dll/win32/kernel32/client/console/init.c +++ b/dll/win32/kernel32/client/console/init.c @@ -245,7 +245,7 @@ BasepInitConsole(VOID) } /* Now use the proper console handle */ - ConnectInfo.Console = Parameters->ConsoleHandle; + ConnectInfo.ConsoleHandle = Parameters->ConsoleHandle; /* Initialize the Console Ctrl Handler */ InitConsoleCtrlHandling(); @@ -290,7 +290,7 @@ BasepInitConsole(VOID) if (!ConnectInfo.ConsoleNeeded) return TRUE; /* We got the handles, let's set them */ - if ((Parameters->ConsoleHandle = ConnectInfo.Console)) + if ((Parameters->ConsoleHandle = ConnectInfo.ConsoleHandle)) { /* If we already had some, don't use the new ones */ if (!Parameters->StandardInput) diff --git a/dll/win32/kernel32/client/console/readwrite.c b/dll/win32/kernel32/client/console/readwrite.c index df78b9510ab..1b45d8d806a 100644 --- a/dll/win32/kernel32/client/console/readwrite.c +++ b/dll/win32/kernel32/client/console/readwrite.c @@ -60,11 +60,17 @@ IntReadConsole(HANDLE hConsoleInput, /* Set up the data to send to the Console Server */ ReadConsoleRequest->InputHandle = hConsoleInput; ReadConsoleRequest->Unicode = bUnicode; - ReadConsoleRequest->NrCharactersToRead = (WORD)nNumberOfCharsToRead; + ReadConsoleRequest->NrCharactersToRead = nNumberOfCharsToRead; ReadConsoleRequest->NrCharactersRead = 0; ReadConsoleRequest->CtrlWakeupMask = 0; if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL)) { + /* + * From MSDN (ReadConsole function), the description + * for pInputControl says: + * "This parameter requires Unicode input by default. + * For ANSI mode, set this parameter to NULL." + */ ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars; memcpy(ReadConsoleRequest->Buffer, lpBuffer, diff --git a/dll/win32/kernel32/client/file/rw.c b/dll/win32/kernel32/client/file/rw.c index 82dc7ca39eb..f430850297a 100644 --- a/dll/win32/kernel32/client/file/rw.c +++ b/dll/win32/kernel32/client/file/rw.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS system libraries * FILE: lib/kernel32/file/rw.c * PURPOSE: Read/write functions - * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) + * PROGRAMMER: Ariadne (ariadne@xs4all.nl) * UPDATE HISTORY: * Created 01/11/98 */ @@ -23,41 +23,38 @@ DEBUG_CHANNEL(kernel32file); BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, - IN DWORD nNumberOfBytesToWrite OPTIONAL, - OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, - IN LPOVERLAPPED lpOverlapped OPTIONAL) + IN DWORD nNumberOfBytesToWrite OPTIONAL, + OUT LPDWORD lpNumberOfBytesWritten OPTIONAL, + IN LPOVERLAPPED lpOverlapped OPTIONAL) { - NTSTATUS Status; + NTSTATUS Status; - TRACE("WriteFile(hFile %x)\n", hFile); + TRACE("WriteFile(hFile %x)\n", hFile); - if (lpNumberOfBytesWritten != NULL) - { - *lpNumberOfBytesWritten = 0; - } + if (lpNumberOfBytesWritten != NULL) *lpNumberOfBytesWritten = 0; - hFile = TranslateStdHandle(hFile); + hFile = TranslateStdHandle(hFile); - if (IsConsoleHandle(hFile)) - { - return WriteConsoleA(hFile, + if (IsConsoleHandle(hFile)) + { + return WriteConsoleA(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); - } + } - if (lpOverlapped != NULL) - { + if (lpOverlapped != NULL) + { LARGE_INTEGER Offset; PVOID ApcContext; Offset.u.LowPart = lpOverlapped->Offset; Offset.u.HighPart = lpOverlapped->OffsetHigh; - lpOverlapped->Internal = STATUS_PENDING; - ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); + lpOverlapped->Internal = STATUS_PENDING; + ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); - Status = NtWriteFile(hFile, + Status = NtWriteFile(hFile, lpOverlapped->hEvent, NULL, ApcContext, @@ -69,18 +66,16 @@ WriteFile(IN HANDLE hFile, /* return FALSE in case of failure and pending operations! */ if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) - { - BaseSetLastNTError(Status); - return FALSE; - } + { + BaseSetLastNTError(Status); + return FALSE; + } if (lpNumberOfBytesWritten != NULL) - { - *lpNumberOfBytesWritten = lpOverlapped->InternalHigh; - } - } - else - { + *lpNumberOfBytesWritten = lpOverlapped->InternalHigh; + } + else + { IO_STATUS_BLOCK Iosb; Status = NtWriteFile(hFile, @@ -93,34 +88,31 @@ WriteFile(IN HANDLE hFile, NULL, NULL); - /* wait in case operation is pending */ + /* Wait in case operation is pending */ if (Status == STATUS_PENDING) - { - Status = NtWaitForSingleObject(hFile, - FALSE, - NULL); - if (NT_SUCCESS(Status)) - { - Status = Iosb.Status; - } - } + { + Status = NtWaitForSingleObject(hFile, FALSE, NULL); + if (NT_SUCCESS(Status)) Status = Iosb.Status; + } if (NT_SUCCESS(Status)) - { - /* lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't - check that case either and crashes (only after the operation - completed) */ - *lpNumberOfBytesWritten = Iosb.Information; - } + { + /* + * lpNumberOfBytesWritten must not be NULL here, in fact Win doesn't + * check that case either and crashes (only after the operation + * completed). + */ + *lpNumberOfBytesWritten = Iosb.Information; + } else - { - BaseSetLastNTError(Status); - return FALSE; - } - } + { + BaseSetLastNTError(Status); + return FALSE; + } + } - TRACE("WriteFile() succeeded\n"); - return TRUE; + TRACE("WriteFile() succeeded\n"); + return TRUE; } @@ -131,56 +123,49 @@ BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, - OUT LPDWORD lpNumberOfBytesRead OPTIONAL, - IN LPOVERLAPPED lpOverlapped OPTIONAL) + OUT LPDWORD lpNumberOfBytesRead OPTIONAL, + IN LPOVERLAPPED lpOverlapped OPTIONAL) { - NTSTATUS Status; + NTSTATUS Status; - TRACE("ReadFile(hFile %x)\n", hFile); + TRACE("ReadFile(hFile %x)\n", hFile); - if (lpNumberOfBytesRead != NULL) - { - *lpNumberOfBytesRead = 0; - } + if (lpNumberOfBytesRead != NULL) *lpNumberOfBytesRead = 0; + if (!nNumberOfBytesToRead) return TRUE; - if (!nNumberOfBytesToRead) - { - return TRUE; - } + hFile = TranslateStdHandle(hFile); - hFile = TranslateStdHandle(hFile); - - if (IsConsoleHandle(hFile)) - { + if (IsConsoleHandle(hFile)) + { if (ReadConsoleA(hFile, - lpBuffer, - nNumberOfBytesToRead, - lpNumberOfBytesRead, - NULL)) - { - DWORD dwMode; - GetConsoleMode(hFile, &dwMode); - if ((dwMode & ENABLE_PROCESSED_INPUT) && *(char *)lpBuffer == 0x1a) - { - /* EOF character entered; simulate end-of-file */ - *lpNumberOfBytesRead = 0; - } - return TRUE; - } + lpBuffer, + nNumberOfBytesToRead, + lpNumberOfBytesRead, + NULL)) + { + DWORD dwMode; + GetConsoleMode(hFile, &dwMode); + if ((dwMode & ENABLE_PROCESSED_INPUT) && *(PCHAR)lpBuffer == 0x1a) + { + /* EOF character entered; simulate end-of-file */ + *lpNumberOfBytesRead = 0; + } + return TRUE; + } return FALSE; - } + } - if (lpOverlapped != NULL) - { + if (lpOverlapped != NULL) + { LARGE_INTEGER Offset; PVOID ApcContext; Offset.u.LowPart = lpOverlapped->Offset; Offset.u.HighPart = lpOverlapped->OffsetHigh; - lpOverlapped->Internal = STATUS_PENDING; - ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); + lpOverlapped->Internal = STATUS_PENDING; + ApcContext = (((ULONG_PTR)lpOverlapped->hEvent & 0x1) ? NULL : lpOverlapped); - Status = NtReadFile(hFile, + Status = NtReadFile(hFile, lpOverlapped->hEvent, NULL, ApcContext, @@ -192,24 +177,19 @@ ReadFile(IN HANDLE hFile, /* return FALSE in case of failure and pending operations! */ if (!NT_SUCCESS(Status) || Status == STATUS_PENDING) - { - if (Status == STATUS_END_OF_FILE && - lpNumberOfBytesRead != NULL) - { - *lpNumberOfBytesRead = 0; - } + { + if (Status == STATUS_END_OF_FILE && lpNumberOfBytesRead != NULL) + *lpNumberOfBytesRead = 0; - BaseSetLastNTError(Status); - return FALSE; - } + BaseSetLastNTError(Status); + return FALSE; + } if (lpNumberOfBytesRead != NULL) - { - *lpNumberOfBytesRead = lpOverlapped->InternalHigh; - } - } - else - { + *lpNumberOfBytesRead = lpOverlapped->InternalHigh; + } + else + { IO_STATUS_BLOCK Iosb; Status = NtReadFile(hFile, @@ -222,58 +202,57 @@ ReadFile(IN HANDLE hFile, NULL, NULL); - /* wait in case operation is pending */ + /* Wait in case operation is pending */ if (Status == STATUS_PENDING) - { - Status = NtWaitForSingleObject(hFile, - FALSE, - NULL); - if (NT_SUCCESS(Status)) - { - Status = Iosb.Status; - } - } + { + Status = NtWaitForSingleObject(hFile, FALSE, NULL); + if (NT_SUCCESS(Status)) Status = Iosb.Status; + } if (Status == STATUS_END_OF_FILE) - { - /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't - check that case either and crashes (only after the operation - completed) */ - *lpNumberOfBytesRead = 0; - return TRUE; - } + { + /* + * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't + * check that case either and crashes (only after the operation + * completed). + */ + *lpNumberOfBytesRead = 0; + return TRUE; + } if (NT_SUCCESS(Status)) - { - /* lpNumberOfBytesRead must not be NULL here, in fact Win doesn't - check that case either and crashes (only after the operation - completed) */ - *lpNumberOfBytesRead = Iosb.Information; - } + { + /* + * lpNumberOfBytesRead must not be NULL here, in fact Win doesn't + * check that case either and crashes (only after the operation + * completed). + */ + *lpNumberOfBytesRead = Iosb.Information; + } else - { - BaseSetLastNTError(Status); - return FALSE; - } - } + { + BaseSetLastNTError(Status); + return FALSE; + } + } - TRACE("ReadFile() succeeded\n"); - return TRUE; + TRACE("ReadFile() succeeded\n"); + return TRUE; } VOID WINAPI ApcRoutine(PVOID ApcContext, - struct _IO_STATUS_BLOCK* IoStatusBlock, - ULONG Reserved) + PIO_STATUS_BLOCK IoStatusBlock, + ULONG Reserved) { - DWORD dwErrorCode; - LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine = - (LPOVERLAPPED_COMPLETION_ROUTINE)ApcContext; + DWORD dwErrorCode; + LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine = + (LPOVERLAPPED_COMPLETION_ROUTINE)ApcContext; - dwErrorCode = RtlNtStatusToDosError(IoStatusBlock->Status); - lpCompletionRoutine(dwErrorCode, - IoStatusBlock->Information, - (LPOVERLAPPED)IoStatusBlock); + dwErrorCode = RtlNtStatusToDosError(IoStatusBlock->Status); + lpCompletionRoutine(dwErrorCode, + IoStatusBlock->Information, + (LPOVERLAPPED)IoStatusBlock); } @@ -283,34 +262,34 @@ ApcRoutine(PVOID ApcContext, BOOL WINAPI WriteFileEx(IN HANDLE hFile, IN LPCVOID lpBuffer, - IN DWORD nNumberOfBytesToWrite OPTIONAL, + IN DWORD nNumberOfBytesToWrite OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { - LARGE_INTEGER Offset; - NTSTATUS Status; + LARGE_INTEGER Offset; + NTSTATUS Status; - Offset.u.LowPart = lpOverlapped->Offset; - Offset.u.HighPart = lpOverlapped->OffsetHigh; - lpOverlapped->Internal = STATUS_PENDING; + Offset.u.LowPart = lpOverlapped->Offset; + Offset.u.HighPart = lpOverlapped->OffsetHigh; + lpOverlapped->Internal = STATUS_PENDING; - Status = NtWriteFile(hFile, - NULL, - ApcRoutine, - lpCompletionRoutine, - (PIO_STATUS_BLOCK)lpOverlapped, - (PVOID)lpBuffer, - nNumberOfBytesToWrite, - &Offset, - NULL); + Status = NtWriteFile(hFile, + NULL, + ApcRoutine, + lpCompletionRoutine, + (PIO_STATUS_BLOCK)lpOverlapped, + (PVOID)lpBuffer, + nNumberOfBytesToWrite, + &Offset, + NULL); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError(Status); - return FALSE; - } + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + return FALSE; + } - return TRUE; + return TRUE; } @@ -320,34 +299,34 @@ WriteFileEx(IN HANDLE hFile, BOOL WINAPI ReadFileEx(IN HANDLE hFile, IN LPVOID lpBuffer, - IN DWORD nNumberOfBytesToRead OPTIONAL, + IN DWORD nNumberOfBytesToRead OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { - LARGE_INTEGER Offset; - NTSTATUS Status; + LARGE_INTEGER Offset; + NTSTATUS Status; - Offset.u.LowPart = lpOverlapped->Offset; - Offset.u.HighPart = lpOverlapped->OffsetHigh; - lpOverlapped->Internal = STATUS_PENDING; + Offset.u.LowPart = lpOverlapped->Offset; + Offset.u.HighPart = lpOverlapped->OffsetHigh; + lpOverlapped->Internal = STATUS_PENDING; - Status = NtReadFile(hFile, - NULL, - ApcRoutine, - lpCompletionRoutine, - (PIO_STATUS_BLOCK)lpOverlapped, - lpBuffer, - nNumberOfBytesToRead, - &Offset, - NULL); + Status = NtReadFile(hFile, + NULL, + ApcRoutine, + lpCompletionRoutine, + (PIO_STATUS_BLOCK)lpOverlapped, + lpBuffer, + nNumberOfBytesToRead, + &Offset, + NULL); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError(Status); - return FALSE; - } + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + return FALSE; + } - return TRUE; + return TRUE; } diff --git a/dll/win32/kernel32/client/path.c b/dll/win32/kernel32/client/path.c index a1cce704dbe..a6e1692a909 100644 --- a/dll/win32/kernel32/client/path.c +++ b/dll/win32/kernel32/client/path.c @@ -990,7 +990,7 @@ GetFullPathNameA(IN LPCSTR lpFileName, OUT LPSTR *lpFilePart) { NTSTATUS Status; - PWCHAR Buffer; + PWCHAR Buffer = NULL; ULONG PathSize, FilePartSize; ANSI_STRING AnsiString; UNICODE_STRING FileNameString, UniString; diff --git a/dll/win32/kernel32/client/synch.c b/dll/win32/kernel32/client/synch.c index 5e19b6b8754..629e23adeca 100644 --- a/dll/win32/kernel32/client/synch.c +++ b/dll/win32/kernel32/client/synch.c @@ -590,7 +590,7 @@ CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, CreateNtObjectFromWin32Api(Event, Event, EVENT, lpEventAttributes, lpName, - bManualReset ? NotificationTimer : SynchronizationTimer, + bManualReset ? NotificationEvent : SynchronizationEvent, bInitialState); } diff --git a/dll/win32/kernel32/client/vdm.c b/dll/win32/kernel32/client/vdm.c index e41172982c9..bfbde543b6e 100644 --- a/dll/win32/kernel32/client/vdm.c +++ b/dll/win32/kernel32/client/vdm.c @@ -309,7 +309,7 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, { BOOL Result; ULONG RegionSize, EnvironmentSize = 0; - PWCHAR p, Environment, NewEnvironment; + PWCHAR p, Environment, NewEnvironment = NULL; NTSTATUS Status; /* Make sure we have both strings */ diff --git a/dll/win32/mshtml/CMakeLists.txt b/dll/win32/mshtml/CMakeLists.txt index 7f1d8b89ab0..a17e5694760 100644 --- a/dll/win32/mshtml/CMakeLists.txt +++ b/dll/win32/mshtml/CMakeLists.txt @@ -89,7 +89,11 @@ list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/mshtml_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/mshtml.def) -add_library(mshtml SHARED ${SOURCE}) +if(MSVC) + add_asm_files(mshtml_asm msvc.S) +endif() + +add_library(mshtml SHARED ${SOURCE} ${mshtml_asm}) list(APPEND mshtml_rc_deps ${CMAKE_CURRENT_SOURCE_DIR}/blank.htm diff --git a/dll/win32/mshtml/ifacewrap.c b/dll/win32/mshtml/ifacewrap.c index f8b5885643d..060db4a0242 100644 --- a/dll/win32/mshtml/ifacewrap.c +++ b/dll/win32/mshtml/ifacewrap.c @@ -90,6 +90,9 @@ static HRESULT WINAPI wrapper_Release(IUnknown *iface) #ifdef __i386__ +#ifdef _MSC_VER +#define DEFINE_WRAPPER_FUNC(n, off, x) HRESULT wrapper_func_##n(IUnknown*); +#else #define DEFINE_WRAPPER_FUNC(n, off, x) \ HRESULT wrapper_func_##n(IUnknown*); \ __ASM_GLOBAL_FUNC(wrapper_func_##n, \ @@ -98,6 +101,7 @@ static HRESULT WINAPI wrapper_Release(IUnknown *iface) "movl %eax, 4(%esp)\n\t" \ "movl 0(%eax), %eax\n\t" \ "jmp *" #off "(%eax)\n\t") +#endif #elif defined(__x86_64__) diff --git a/dll/win32/mshtml/msvc.S b/dll/win32/mshtml/msvc.S new file mode 100644 index 00000000000..9d210be115f --- /dev/null +++ b/dll/win32/mshtml/msvc.S @@ -0,0 +1,114 @@ + +#include + +.code + +MACRO(DEFINE_WRAPPER_FUNC, n, off, x) +PUBLIC _wrapper_func_&n& +_wrapper_func_&n&: +mov eax, [esp+4] +mov eax, [eax+4] +mov [esp+4], eax +mov eax, [eax] +jmp dword ptr [eax+off] +ENDM + +DEFINE_WRAPPER_FUNC 3, 12, 24 +DEFINE_WRAPPER_FUNC 4, 16, 32 +DEFINE_WRAPPER_FUNC 5, 20, 40 +DEFINE_WRAPPER_FUNC 6, 24, 48 +DEFINE_WRAPPER_FUNC 7, 28, 56 +DEFINE_WRAPPER_FUNC 8, 32, 64 +DEFINE_WRAPPER_FUNC 9, 36, 72 +DEFINE_WRAPPER_FUNC 10, 40, 80 +DEFINE_WRAPPER_FUNC 11, 44, 88 +DEFINE_WRAPPER_FUNC 12, 48, 96 +DEFINE_WRAPPER_FUNC 13, 52, 104 +DEFINE_WRAPPER_FUNC 14, 56, 112 +DEFINE_WRAPPER_FUNC 15, 60, 120 +DEFINE_WRAPPER_FUNC 16, 64, 128 +DEFINE_WRAPPER_FUNC 17, 68, 136 +DEFINE_WRAPPER_FUNC 18, 72, 144 +DEFINE_WRAPPER_FUNC 19, 76, 152 +DEFINE_WRAPPER_FUNC 20, 80, 160 +DEFINE_WRAPPER_FUNC 21, 84, 168 +DEFINE_WRAPPER_FUNC 22, 88, 176 +DEFINE_WRAPPER_FUNC 23, 92, 184 +DEFINE_WRAPPER_FUNC 24, 96, 192 +DEFINE_WRAPPER_FUNC 25, 100, 200 +DEFINE_WRAPPER_FUNC 26, 104, 208 +DEFINE_WRAPPER_FUNC 27, 108, 216 +DEFINE_WRAPPER_FUNC 28, 112, 224 +DEFINE_WRAPPER_FUNC 29, 116, 232 +DEFINE_WRAPPER_FUNC 30, 120, 240 +DEFINE_WRAPPER_FUNC 31, 124, 248 +DEFINE_WRAPPER_FUNC 32, 128, 256 +DEFINE_WRAPPER_FUNC 33, 132, 264 +DEFINE_WRAPPER_FUNC 34, 136, 272 +DEFINE_WRAPPER_FUNC 35, 140, 280 +DEFINE_WRAPPER_FUNC 36, 144, 288 +DEFINE_WRAPPER_FUNC 37, 148, 296 +DEFINE_WRAPPER_FUNC 38, 152, 304 +DEFINE_WRAPPER_FUNC 39, 156, 312 +DEFINE_WRAPPER_FUNC 40, 160, 320 +DEFINE_WRAPPER_FUNC 41, 164, 328 +DEFINE_WRAPPER_FUNC 42, 168, 336 +DEFINE_WRAPPER_FUNC 43, 172, 344 +DEFINE_WRAPPER_FUNC 44, 176, 352 +DEFINE_WRAPPER_FUNC 45, 180, 360 +DEFINE_WRAPPER_FUNC 46, 184, 368 +DEFINE_WRAPPER_FUNC 47, 188, 376 +DEFINE_WRAPPER_FUNC 48, 192, 384 +DEFINE_WRAPPER_FUNC 49, 196, 392 +DEFINE_WRAPPER_FUNC 50, 200, 400 +DEFINE_WRAPPER_FUNC 51, 204, 408 +DEFINE_WRAPPER_FUNC 52, 208, 416 +DEFINE_WRAPPER_FUNC 53, 212, 424 +DEFINE_WRAPPER_FUNC 54, 216, 432 +DEFINE_WRAPPER_FUNC 55, 220, 440 +DEFINE_WRAPPER_FUNC 56, 224, 448 +DEFINE_WRAPPER_FUNC 57, 228, 456 +DEFINE_WRAPPER_FUNC 58, 232, 464 +DEFINE_WRAPPER_FUNC 59, 236, 472 +DEFINE_WRAPPER_FUNC 60, 240, 480 +DEFINE_WRAPPER_FUNC 61, 244, 488 +DEFINE_WRAPPER_FUNC 62, 248, 496 +DEFINE_WRAPPER_FUNC 63, 252, 504 +DEFINE_WRAPPER_FUNC 64, 256, 512 +DEFINE_WRAPPER_FUNC 65, 260, 520 +DEFINE_WRAPPER_FUNC 66, 264, 528 +DEFINE_WRAPPER_FUNC 67, 268, 536 +DEFINE_WRAPPER_FUNC 68, 272, 544 +DEFINE_WRAPPER_FUNC 69, 276, 552 +DEFINE_WRAPPER_FUNC 70, 280, 560 +DEFINE_WRAPPER_FUNC 71, 284, 568 +DEFINE_WRAPPER_FUNC 72, 288, 576 +DEFINE_WRAPPER_FUNC 73, 292, 584 +DEFINE_WRAPPER_FUNC 74, 296, 592 +DEFINE_WRAPPER_FUNC 75, 300, 600 +DEFINE_WRAPPER_FUNC 76, 304, 608 +DEFINE_WRAPPER_FUNC 77, 308, 616 +DEFINE_WRAPPER_FUNC 78, 312, 624 +DEFINE_WRAPPER_FUNC 79, 316, 632 +DEFINE_WRAPPER_FUNC 80, 320, 640 +DEFINE_WRAPPER_FUNC 81, 324, 648 +DEFINE_WRAPPER_FUNC 82, 328, 656 +DEFINE_WRAPPER_FUNC 83, 332, 664 +DEFINE_WRAPPER_FUNC 84, 336, 672 +DEFINE_WRAPPER_FUNC 85, 340, 680 +DEFINE_WRAPPER_FUNC 86, 344, 688 +DEFINE_WRAPPER_FUNC 87, 348, 696 +DEFINE_WRAPPER_FUNC 88, 352, 704 +DEFINE_WRAPPER_FUNC 89, 356, 712 +DEFINE_WRAPPER_FUNC 90, 360, 720 +DEFINE_WRAPPER_FUNC 91, 364, 728 +DEFINE_WRAPPER_FUNC 92, 368, 736 +DEFINE_WRAPPER_FUNC 93, 372, 744 +DEFINE_WRAPPER_FUNC 94, 376, 752 +DEFINE_WRAPPER_FUNC 95, 380, 760 +DEFINE_WRAPPER_FUNC 96, 384, 768 +DEFINE_WRAPPER_FUNC 97, 388, 776 +DEFINE_WRAPPER_FUNC 98, 392, 784 +DEFINE_WRAPPER_FUNC 99, 396, 792 + +END diff --git a/dll/win32/msports/CMakeLists.txt b/dll/win32/msports/CMakeLists.txt index b67cedfe643..e94d107cdfe 100644 --- a/dll/win32/msports/CMakeLists.txt +++ b/dll/win32/msports/CMakeLists.txt @@ -6,6 +6,7 @@ list(APPEND SOURCE classinst.c comdb.c msports.c + parallel.c serial.c msports.rc ${CMAKE_CURRENT_BINARY_DIR}/msports_stubs.c diff --git a/dll/win32/msports/lang/bg-BG.rc b/dll/win32/msports/lang/bg-BG.rc index a195b9859f7..1d093b5425f 100644 --- a/dll/win32/msports/lang/bg-BG.rc +++ b/dll/win32/msports/lang/bg-BG.rc @@ -22,3 +22,12 @@ BEGIN PUSHBUTTON "Раз&ширени...",IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "&Връщане на под&разбираните",IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Настройки на излаза (порта)" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/lang/de-DE.rc b/dll/win32/msports/lang/de-DE.rc index 351d8793faf..10cd0fd92e7 100644 --- a/dll/win32/msports/lang/de-DE.rc +++ b/dll/win32/msports/lang/de-DE.rc @@ -1,4 +1,4 @@ - + LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL IDD_SERIALSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 @@ -19,3 +19,12 @@ BEGIN PUSHBUTTON "&Erweitert...",IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "Wieder&herstellen",IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Port Einstellungen" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/lang/en-US.rc b/dll/win32/msports/lang/en-US.rc index 5ea9aa24d5a..66e7c0b6821 100644 --- a/dll/win32/msports/lang/en-US.rc +++ b/dll/win32/msports/lang/en-US.rc @@ -19,3 +19,12 @@ BEGIN PUSHBUTTON "&Advanced...",IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "&Restore Defaults",IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Port Settings" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/lang/he-IL.rc b/dll/win32/msports/lang/he-IL.rc index 25aeeb1bc11..0cae3d3c6f3 100644 --- a/dll/win32/msports/lang/he-IL.rc +++ b/dll/win32/msports/lang/he-IL.rc @@ -19,3 +19,12 @@ BEGIN PUSHBUTTON "מתקדם...",IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "שחזר ברירת מחדל",IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "הגדרות יציאה" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/lang/pl-PL.rc b/dll/win32/msports/lang/pl-PL.rc index ff9e22c25c4..6fc36a9da43 100644 --- a/dll/win32/msports/lang/pl-PL.rc +++ b/dll/win32/msports/lang/pl-PL.rc @@ -26,3 +26,12 @@ BEGIN PUSHBUTTON "&Zaawansowane...",IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "P&rzywróć domyślne",IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Ustawienia portu" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/lang/ro-RO.rc b/dll/win32/msports/lang/ro-RO.rc index 135a6bf64dd..5257cec333e 100644 --- a/dll/win32/msports/lang/ro-RO.rc +++ b/dll/win32/msports/lang/ro-RO.rc @@ -25,3 +25,12 @@ BEGIN PUSHBUTTON "A&vansate…", IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "Valori i&mplicite", IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Configurația portului" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/lang/uk-UA.rc b/dll/win32/msports/lang/uk-UA.rc index a5ac1f08739..3b0881adcc5 100644 --- a/dll/win32/msports/lang/uk-UA.rc +++ b/dll/win32/msports/lang/uk-UA.rc @@ -26,3 +26,12 @@ BEGIN PUSHBUTTON "&Розширені...",IDC_SERIAL_ADVANCED, 111, 130, 65, 14,WS_GROUP PUSHBUTTON "&За замовчуванням",IDC_SERIAL_RESTORE, 180, 130, 65, 14, WS_GROUP END + + +IDD_PARALLELSETTINGS DIALOGEX DISCARDABLE 0, 0, 252, 218 +STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "Параметри порту" +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "TEST", -1, 74, 19, 62, 8, WS_GROUP +END diff --git a/dll/win32/msports/msports.spec b/dll/win32/msports/msports.spec index 3be8a92914e..24f2d723f87 100644 --- a/dll/win32/msports/msports.spec +++ b/dll/win32/msports/msports.spec @@ -6,7 +6,7 @@ @ stdcall ComDBReleasePort(ptr long) @ stdcall ComDBResizeDatabase(ptr long) @ stdcall LibMain(ptr long ptr) DllMain -@ stub ParallelPortPropPageProvider +@ stdcall ParallelPortPropPageProvider(ptr ptr long) @ stdcall PortsClassInstaller(long ptr ptr) @ stub SerialDisplayAdvancedSettings @ stdcall SerialPortPropPageProvider(ptr ptr long) diff --git a/dll/win32/msports/parallel.c b/dll/win32/msports/parallel.c new file mode 100644 index 00000000000..45b6bbcb713 --- /dev/null +++ b/dll/win32/msports/parallel.c @@ -0,0 +1,89 @@ +/* + * PROJECT: Ports installer library + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll\win32\msports\parallel.c + * PURPOSE: Parallel Port property functions + * COPYRIGHT: Copyright 2013 Eric Kohl + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msports); + + +static +BOOL +OnInitDialog(HWND hwnd, + WPARAM wParam, + LPARAM lParam) +{ + TRACE("Port_OnInit()\n"); + return TRUE; +} + + +static +INT_PTR +CALLBACK +ParallelSettingsDlgProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + TRACE("ParallelSettingsDlgProc()\n"); + + switch (uMsg) + { + case WM_INITDIALOG: + return OnInitDialog(hwnd, wParam, lParam); + } + + return FALSE; +} + + +BOOL +WINAPI +ParallelPortPropPageProvider(PSP_PROPSHEETPAGE_REQUEST lpPropSheetPageRequest, + LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc, + LPARAM lParam) +{ + PROPSHEETPAGEW PropSheetPage; + HPROPSHEETPAGE hPropSheetPage; + + TRACE("ParallelPortPropPageProvider(%p %p %lx)\n", + lpPropSheetPageRequest, lpfnAddPropSheetPageProc, lParam); + + if (lpPropSheetPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) + { + TRACE("SPPSR_ENUM_ADV_DEVICE_PROPERTIES\n"); + + PropSheetPage.dwSize = sizeof(PROPSHEETPAGEW); + PropSheetPage.dwFlags = 0; + PropSheetPage.hInstance = hInstance; + PropSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_PARALLELSETTINGS); + PropSheetPage.pfnDlgProc = ParallelSettingsDlgProc; + PropSheetPage.lParam = 0; + PropSheetPage.pfnCallback = NULL; + + hPropSheetPage = CreatePropertySheetPageW(&PropSheetPage); + if (hPropSheetPage == NULL) + { + TRACE("CreatePropertySheetPageW() failed!\n"); + return FALSE; + } + + if (!(*lpfnAddPropSheetPageProc)(hPropSheetPage, lParam)) + { + TRACE("lpfnAddPropSheetPageProc() failed!\n"); + DestroyPropertySheetPage(hPropSheetPage); + return FALSE; + } + } + + TRACE("Done!\n"); + + return TRUE; +} + +/* EOF */ diff --git a/dll/win32/msports/resource.h b/dll/win32/msports/resource.h index 6dc4a033e84..cde9b61b3aa 100644 --- a/dll/win32/msports/resource.h +++ b/dll/win32/msports/resource.h @@ -8,3 +8,5 @@ #define IDC_SERIAL_FLOWCONTROL 205 #define IDC_SERIAL_ADVANCED 206 #define IDC_SERIAL_RESTORE 207 + +#define IDD_PARALLELSETTINGS 220 diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c index 175014e9279..260b3583ca8 100644 --- a/dll/win32/msv1_0/msv1_0.c +++ b/dll/win32/msv1_0/msv1_0.c @@ -729,6 +729,41 @@ done: } +static +NTSTATUS +ChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest, + IN PVOID ProtocolSubmitBuffer, + IN PVOID ClientBufferBase, + IN ULONG SubmitBufferLength, + OUT PVOID *ProtocolReturnBuffer, + OUT PULONG ReturnBufferLength, + OUT PNTSTATUS ProtocolStatus) +{ + PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer; + ULONG_PTR PtrOffset; + + TRACE("()\n"); + + RequestBuffer = (PMSV1_0_CHANGEPASSWORD_REQUEST)ProtocolSubmitBuffer; + + /* Fix-up pointers in the request buffer info */ + PtrOffset = (ULONG_PTR)ProtocolSubmitBuffer - (ULONG_PTR)ClientBufferBase; + + RequestBuffer->DomainName.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->DomainName.Buffer + PtrOffset); + RequestBuffer->AccountName.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->AccountName.Buffer + PtrOffset); + RequestBuffer->OldPassword.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->OldPassword.Buffer + PtrOffset); + RequestBuffer->NewPassword.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->NewPassword.Buffer + PtrOffset); + + TRACE("Domain: %S\n", RequestBuffer->DomainName.Buffer); + TRACE("Account: %S\n", RequestBuffer->AccountName.Buffer); + TRACE("Old Password: %S\n", RequestBuffer->OldPassword.Buffer); + TRACE("New Password: %S\n", RequestBuffer->NewPassword.Buffer); + + + return STATUS_SUCCESS; +} + + /* * @unimplemented */ @@ -742,8 +777,53 @@ LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest, OUT PULONG ReturnBufferLength, OUT PNTSTATUS ProtocolStatus) { + ULONG MessageType; + NTSTATUS Status; + TRACE("()\n"); - return STATUS_NOT_IMPLEMENTED; + + if (SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE)) + return STATUS_INVALID_PARAMETER; + + MessageType = (ULONG)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE)ProtocolSubmitBuffer); + + *ProtocolReturnBuffer = NULL; + *ReturnBufferLength = 0; + + switch (MessageType) + { + case MsV1_0Lm20ChallengeRequest: + case MsV1_0Lm20GetChallengeResponse: + case MsV1_0EnumerateUsers: + case MsV1_0GetUserInfo: + case MsV1_0ReLogonUsers: + Status = STATUS_NOT_IMPLEMENTED; + break; + + case MsV1_0ChangePassword: + Status = ChangePassword(ClientRequest, + ProtocolSubmitBuffer, + ClientBufferBase, + SubmitBufferLength, + ProtocolReturnBuffer, + ReturnBufferLength, + ProtocolStatus); + break; + + case MsV1_0ChangeCachedPassword: + case MsV1_0GenericPassthrough: + case MsV1_0CacheLogon: + case MsV1_0SubAuth: + case MsV1_0DeriveCredential: + case MsV1_0CacheLookup: + Status = STATUS_NOT_IMPLEMENTED; + break; + + default: + return STATUS_INVALID_PARAMETER; + } + + return Status; } diff --git a/dll/win32/netapi32/CMakeLists.txt b/dll/win32/netapi32/CMakeLists.txt index 457eca53333..d5d48222812 100644 --- a/dll/win32/netapi32/CMakeLists.txt +++ b/dll/win32/netapi32/CMakeLists.txt @@ -31,7 +31,7 @@ target_link_libraries(netapi32 wine) add_importlibs(netapi32 iphlpapi ws2_32 advapi32 msvcrt kernel32 ntdll) -add_delay_importlibs(netapi32 samlib) +add_delay_importlibs(netapi32 samlib secur32) add_cd_file(TARGET netapi32 DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/netapi32/netapi32.h b/dll/win32/netapi32/netapi32.h index 9d7412a83dc..65970fc1867 100644 --- a/dll/win32/netapi32/netapi32.h +++ b/dll/win32/netapi32/netapi32.h @@ -25,6 +25,7 @@ #define NTOS_MODE_USER #include +#include #include #include diff --git a/dll/win32/netapi32/user.c b/dll/win32/netapi32/user.c index 5dd842a367f..7b5389a1a2e 100644 --- a/dll/win32/netapi32/user.c +++ b/dll/win32/netapi32/user.c @@ -20,7 +20,6 @@ /* * TODO: - * Implement NetUserChangePassword * Implement NetUserGetGroups * Implement NetUserSetGroups * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet. @@ -180,7 +179,9 @@ BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo, PUSER_INFO_1 UserInfo1; PUSER_INFO_2 UserInfo2; PUSER_INFO_3 UserInfo3; + PUSER_INFO_4 UserInfo4; PUSER_INFO_10 UserInfo10; + PUSER_INFO_11 UserInfo11; PUSER_INFO_20 UserInfo20; PUSER_INFO_23 UserInfo23; LPWSTR Ptr; @@ -280,7 +281,45 @@ BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo, Size += UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR); break; -// case 4: + case 4: + Size = sizeof(USER_INFO_4) + + UserInfo->UserName.Length + sizeof(WCHAR); + + if (UserInfo->HomeDirectory.Length > 0) + Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR); + + if (UserInfo->AdminComment.Length > 0) + Size += UserInfo->AdminComment.Length + sizeof(WCHAR); + + if (UserInfo->ScriptPath.Length > 0) + Size += UserInfo->ScriptPath.Length + sizeof(WCHAR); + + if (UserInfo->FullName.Length > 0) + Size += UserInfo->FullName.Length + sizeof(WCHAR); + + if (UserInfo->UserComment.Length > 0) + Size += UserInfo->UserComment.Length + sizeof(WCHAR); + + if (UserInfo->Parameters.Length > 0) + Size += UserInfo->Parameters.Length + sizeof(WCHAR); + + if (UserInfo->WorkStations.Length > 0) + Size += UserInfo->WorkStations.Length + sizeof(WCHAR); + + if (UserInfo->LogonHours.UnitsPerWeek > 0) + Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; + + if (LogonServer.Length > 0) + Size += LogonServer.Length + sizeof(WCHAR); + + /* FIXME: usri4_user_sid */ + + if (UserInfo->ProfilePath.Length > 0) + Size += UserInfo->ProfilePath.Length + sizeof(WCHAR); + + if (UserInfo->HomeDirectoryDrive.Length > 0) + Size += UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR); + break; case 10: Size = sizeof(USER_INFO_10) + @@ -296,7 +335,34 @@ BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo, Size += UserInfo->FullName.Length + sizeof(WCHAR); break; -// case 11: + case 11: + Size = sizeof(USER_INFO_11) + + UserInfo->UserName.Length + sizeof(WCHAR); + + if (UserInfo->AdminComment.Length > 0) + Size += UserInfo->AdminComment.Length + sizeof(WCHAR); + + if (UserInfo->UserComment.Length > 0) + Size += UserInfo->UserComment.Length + sizeof(WCHAR); + + if (UserInfo->FullName.Length > 0) + Size += UserInfo->FullName.Length + sizeof(WCHAR); + + if (UserInfo->HomeDirectory.Length > 0) + Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR); + + if (UserInfo->Parameters.Length > 0) + Size += UserInfo->Parameters.Length + sizeof(WCHAR); + + if (LogonServer.Length > 0) + Size += LogonServer.Length + sizeof(WCHAR); + + if (UserInfo->WorkStations.Length > 0) + Size += UserInfo->WorkStations.Length + sizeof(WCHAR); + + if (UserInfo->LogonHours.UnitsPerWeek > 0) + Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; + break; case 20: Size = sizeof(USER_INFO_20) + @@ -728,7 +794,184 @@ BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo, UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED); break; -// case 4: + case 4: + UserInfo4 = (PUSER_INFO_4)LocalBuffer; + + Ptr = (LPWSTR)((ULONG_PTR)UserInfo4 + sizeof(USER_INFO_4)); + + UserInfo4->usri4_name = Ptr; + + memcpy(UserInfo4->usri4_name, + UserInfo->UserName.Buffer, + UserInfo->UserName.Length); + UserInfo4->usri4_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); + + UserInfo4->usri4_password = NULL; + UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); + + /* FIXME: usri4_priv */ + + if (UserInfo->HomeDirectory.Length > 0) + { + UserInfo4->usri4_home_dir = Ptr; + + memcpy(UserInfo4->usri4_home_dir, + UserInfo->HomeDirectory.Buffer, + UserInfo->HomeDirectory.Length); + UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); + } + + if (UserInfo->AdminComment.Length > 0) + { + UserInfo4->usri4_comment = Ptr; + + memcpy(UserInfo4->usri4_comment, + UserInfo->AdminComment.Buffer, + UserInfo->AdminComment.Length); + UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); + } + + UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl); + + if (UserInfo->ScriptPath.Length > 0) + { + UserInfo4->usri4_script_path = Ptr; + + memcpy(UserInfo4->usri4_script_path, + UserInfo->ScriptPath.Buffer, + UserInfo->ScriptPath.Length); + UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR)); + } + + /* FIXME: usri4_auth_flags */ + + if (UserInfo->FullName.Length > 0) + { + UserInfo4->usri4_full_name = Ptr; + + memcpy(UserInfo4->usri4_full_name, + UserInfo->FullName.Buffer, + UserInfo->FullName.Length); + UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); + } + + if (UserInfo->UserComment.Length > 0) + { + UserInfo4->usri4_usr_comment = Ptr; + + memcpy(UserInfo4->usri4_usr_comment, + UserInfo->UserComment.Buffer, + UserInfo->UserComment.Length); + UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); + } + + if (UserInfo->Parameters.Length > 0) + { + UserInfo4->usri4_parms = Ptr; + + memcpy(UserInfo4->usri4_parms, + UserInfo->Parameters.Buffer, + UserInfo->Parameters.Length); + UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR)); + } + + if (UserInfo->WorkStations.Length > 0) + { + UserInfo4->usri4_workstations = Ptr; + + memcpy(UserInfo4->usri4_workstations, + UserInfo->WorkStations.Buffer, + UserInfo->WorkStations.Length); + UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR)); + } + + RtlTimeToSecondsSince1970(&UserInfo->LastLogon, + &UserInfo4->usri4_last_logon); + + RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, + &UserInfo4->usri4_last_logoff); + + RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, + &UserInfo4->usri4_acct_expires); + + UserInfo4->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; + UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek; + + if (UserInfo->LogonHours.UnitsPerWeek > 0) + { + UserInfo4->usri4_logon_hours = (PVOID)Ptr; + + memcpy(UserInfo4->usri4_logon_hours, + UserInfo->LogonHours.LogonHours, + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); + } + + UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount; + UserInfo4->usri4_num_logons = UserInfo->LogonCount; + + if (LogonServer.Length > 0) + { + UserInfo4->usri4_logon_server = Ptr; + + memcpy(UserInfo4->usri4_logon_server, + LogonServer.Buffer, + LogonServer.Length); + UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR)); + } + + UserInfo4->usri4_country_code = UserInfo->CountryCode; + UserInfo4->usri4_code_page = UserInfo->CodePage; + + /* FIXME: usri4_user_sid */ + + UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId; + + if (UserInfo->ProfilePath.Length > 0) + { + UserInfo4->usri4_profile = Ptr; + + memcpy(UserInfo4->usri4_profile, + UserInfo->ProfilePath.Buffer, + UserInfo->ProfilePath.Length); + UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR)); + } + + if (UserInfo->HomeDirectoryDrive.Length > 0) + { + UserInfo4->usri4_home_dir_drive = Ptr; + + memcpy(UserInfo4->usri4_home_dir_drive, + UserInfo->HomeDirectoryDrive.Buffer, + UserInfo->HomeDirectoryDrive.Length); + UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR)); + } + + UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED); + break; case 10: UserInfo10 = (PUSER_INFO_10)LocalBuffer; @@ -781,7 +1024,136 @@ BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo, } break; -// case 11: + case 11: + UserInfo11 = (PUSER_INFO_11)LocalBuffer; + + Ptr = (LPWSTR)((ULONG_PTR)UserInfo11 + sizeof(USER_INFO_11)); + + UserInfo11->usri11_name = Ptr; + + memcpy(UserInfo11->usri11_name, + UserInfo->UserName.Buffer, + UserInfo->UserName.Length); + UserInfo11->usri11_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); + + if (UserInfo->AdminComment.Length > 0) + { + UserInfo11->usri11_comment = Ptr; + + memcpy(UserInfo11->usri11_comment, + UserInfo->AdminComment.Buffer, + UserInfo->AdminComment.Length); + UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); + } + + if (UserInfo->UserComment.Length > 0) + { + UserInfo11->usri11_usr_comment = Ptr; + + memcpy(UserInfo11->usri11_usr_comment, + UserInfo->UserComment.Buffer, + UserInfo->UserComment.Length); + UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); + } + + if (UserInfo->FullName.Length > 0) + { + UserInfo11->usri11_full_name = Ptr; + + memcpy(UserInfo11->usri11_full_name, + UserInfo->FullName.Buffer, + UserInfo->FullName.Length); + UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); + } + + /* FIXME: usri11_priv */ + /* FIXME: usri11_auth_flags */ + + UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); + + if (UserInfo->HomeDirectory.Length > 0) + { + UserInfo11->usri11_home_dir = Ptr; + + memcpy(UserInfo11->usri11_home_dir, + UserInfo->HomeDirectory.Buffer, + UserInfo->HomeDirectory.Length); + UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); + } + + if (UserInfo->Parameters.Length > 0) + { + UserInfo11->usri11_parms = Ptr; + + memcpy(UserInfo11->usri11_parms, + UserInfo->Parameters.Buffer, + UserInfo->Parameters.Length); + UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR)); + } + + RtlTimeToSecondsSince1970(&UserInfo->LastLogon, + &UserInfo11->usri11_last_logon); + + RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, + &UserInfo11->usri11_last_logoff); + + UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount; + UserInfo11->usri11_num_logons = UserInfo->LogonCount; + + if (LogonServer.Length > 0) + { + UserInfo11->usri11_logon_server = Ptr; + + memcpy(UserInfo11->usri11_logon_server, + LogonServer.Buffer, + LogonServer.Length); + UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR)); + } + + UserInfo11->usri11_country_code = UserInfo->CountryCode; + + if (UserInfo->WorkStations.Length > 0) + { + UserInfo11->usri11_workstations = Ptr; + + memcpy(UserInfo11->usri11_workstations, + UserInfo->WorkStations.Buffer, + UserInfo->WorkStations.Length); + UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR)); + } + + UserInfo11->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; + UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek; + + if (UserInfo->LogonHours.UnitsPerWeek > 0) + { + UserInfo11->usri11_logon_hours = (PVOID)Ptr; + + memcpy(UserInfo11->usri11_logon_hours, + UserInfo->LogonHours.LogonHours, + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); + } + + UserInfo11->usri11_code_page = UserInfo->CodePage; + break; case 20: UserInfo20 = (PUSER_INFO_20)LocalBuffer; @@ -940,6 +1312,7 @@ SetUserInfo(SAM_HANDLE UserHandle, PUSER_INFO_1 UserInfo1; PUSER_INFO_2 UserInfo2; PUSER_INFO_3 UserInfo3; + PUSER_INFO_4 UserInfo4; PUSER_INFO_1003 UserInfo1003; PUSER_INFO_1006 UserInfo1006; PUSER_INFO_1007 UserInfo1007; @@ -949,6 +1322,11 @@ SetUserInfo(SAM_HANDLE UserHandle, PUSER_INFO_1012 UserInfo1012; PUSER_INFO_1013 UserInfo1013; PUSER_INFO_1014 UserInfo1014; + PUSER_INFO_1017 UserInfo1017; + PUSER_INFO_1018 UserInfo1018; + PUSER_INFO_1024 UserInfo1024; + PUSER_INFO_1025 UserInfo1025; + PUSER_INFO_1051 UserInfo1051; PUSER_INFO_1052 UserInfo1052; PUSER_INFO_1053 UserInfo1053; NET_API_STATUS ApiStatus = NERR_Success; @@ -1083,8 +1461,20 @@ SetUserInfo(SAM_HANDLE UserHandle, // usri2_last_logon ignored // usri2_last_logoff ignored -// UserInfo2->usri2_acct_expires; -// UserInfo2->usri2_max_storage; + if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER) + { + UserAllInfo.AccountExpires.LowPart = 0; + UserAllInfo.AccountExpires.HighPart = 0; + } + else + { + RtlSecondsSince1970ToTime(UserInfo2->usri2_acct_expires, + &UserAllInfo.AccountExpires); + } + UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; + + // usri2_max_storage ignored + // UserInfo2->usri2_units_per_week; // UserInfo2->usri2_logon_hours; @@ -1092,8 +1482,11 @@ SetUserInfo(SAM_HANDLE UserHandle, // usri2_num_logons ignored // usri2_logon_server ignored -// UserInfo2->usri2_country_code; -// UserInfo2->usri2_code_page; + UserAllInfo.CountryCode = UserInfo2->usri2_country_code; + UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; + + UserAllInfo.CodePage = UserInfo2->usri2_code_page; + UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; break; case 3: @@ -1170,8 +1563,20 @@ SetUserInfo(SAM_HANDLE UserHandle, // usri3_last_logon ignored // usri3_last_logoff ignored -// UserInfo3->usri3_acct_expires; -// UserInfo3->usri3_max_storage; + if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER) + { + UserAllInfo.AccountExpires.LowPart = 0; + UserAllInfo.AccountExpires.HighPart = 0; + } + else + { + RtlSecondsSince1970ToTime(UserInfo3->usri3_acct_expires, + &UserAllInfo.AccountExpires); + } + UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; + + // usri3_max_storage ignored + // UserInfo3->usri3_units_per_week; // UserInfo3->usri3_logon_hours; @@ -1179,12 +1584,16 @@ SetUserInfo(SAM_HANDLE UserHandle, // usri3_num_logons ignored // usri3_logon_server ignored -// UserInfo3->usri3_country_code; -// UserInfo3->usri3_code_page; + UserAllInfo.CountryCode = UserInfo3->usri3_country_code; + UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; + + UserAllInfo.CodePage = UserInfo3->usri3_code_page; + UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; // usri3_user_id ignored -// UserInfo3->usri3_primary_group_id; + UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id; + UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; if (UserInfo3->usri3_profile != NULL) { @@ -1200,10 +1609,134 @@ SetUserInfo(SAM_HANDLE UserHandle, UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; } -// UserInfo3->usri3_password_expired; + UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0); + UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED; + break; + + case 4: + UserInfo4 = (PUSER_INFO_4)UserInfo; + + // usri4_name ignored + + if (UserInfo4->usri4_password != NULL) + { + RtlInitUnicodeString(&UserAllInfo.NtPassword, + UserInfo4->usri4_password); + UserAllInfo.NtPasswordPresent = TRUE; + UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; + } + + // usri4_password_age ignored + +// UserInfo3->usri4_priv; + + if (UserInfo4->usri4_home_dir != NULL) + { + RtlInitUnicodeString(&UserAllInfo.HomeDirectory, + UserInfo4->usri4_home_dir); + UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; + } + + if (UserInfo4->usri4_comment != NULL) + { + RtlInitUnicodeString(&UserAllInfo.AdminComment, + UserInfo4->usri4_comment); + UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; + } + + UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags); + UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; + + if (UserInfo4->usri4_script_path != NULL) + { + RtlInitUnicodeString(&UserAllInfo.ScriptPath, + UserInfo4->usri4_script_path); + UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; + } + +// UserInfo4->usri4_auth_flags; + + if (UserInfo4->usri4_full_name != NULL) + { + RtlInitUnicodeString(&UserAllInfo.FullName, + UserInfo4->usri4_full_name); + UserAllInfo.WhichFields |= USER_ALL_FULLNAME; + } + + if (UserInfo4->usri4_usr_comment != NULL) + { + RtlInitUnicodeString(&UserAllInfo.UserComment, + UserInfo4->usri4_usr_comment); + UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; + } + + if (UserInfo4->usri4_parms != NULL) + { + RtlInitUnicodeString(&UserAllInfo.Parameters, + UserInfo4->usri4_parms); + UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; + } + + if (UserInfo4->usri4_workstations != NULL) + { + RtlInitUnicodeString(&UserAllInfo.WorkStations, + UserInfo4->usri4_workstations); + UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; + } + + // usri4_last_logon ignored + // usri4_last_logoff ignored + + if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER) + { + UserAllInfo.AccountExpires.LowPart = 0; + UserAllInfo.AccountExpires.HighPart = 0; + } + else + { + RtlSecondsSince1970ToTime(UserInfo4->usri4_acct_expires, + &UserAllInfo.AccountExpires); + } + UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; + + // usri4_max_storage ignored + +// UserInfo3->usri4_units_per_week; +// UserInfo3->usri4_logon_hours; + + // usri4_bad_pw_count ignored + // usri4_num_logons ignored + // usri4_logon_server ignored + + UserAllInfo.CountryCode = UserInfo4->usri4_country_code; + UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; + + UserAllInfo.CodePage = UserInfo4->usri4_code_page; + UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; + + // usri4_user_sid ignored + + UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id; + UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; + + if (UserInfo4->usri4_profile != NULL) + { + RtlInitUnicodeString(&UserAllInfo.ProfilePath, + UserInfo4->usri4_profile); + UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; + } + + if (UserInfo4->usri4_home_dir_drive != NULL) + { + RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, + UserInfo4->usri4_home_dir_drive); + UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; + } + + UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0); + UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED; break; -// case 4: // case 21: // case 22: @@ -1306,10 +1839,54 @@ SetUserInfo(SAM_HANDLE UserHandle, } break; -// case 1017: + case 1017: + UserInfo1017 = (PUSER_INFO_1017)UserInfo; + + if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER) + { + UserAllInfo.AccountExpires.LowPart = 0; + UserAllInfo.AccountExpires.HighPart = 0; + } + else + { + RtlSecondsSince1970ToTime(UserInfo1017->usri1017_acct_expires, + &UserAllInfo.AccountExpires); + } + UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; + break; + + case 1018: + UserInfo1018 = (PUSER_INFO_1018)UserInfo; + + if (UserInfo1018->usri1018_max_storage != USER_MAXSTORAGE_UNLIMITED) + { + // FIXME: Report error + return ERROR_INVALID_PARAMETER; + } + break; + // case 1020: -// case 1024: -// case 1051: + + case 1024: + UserInfo1024 = (PUSER_INFO_1024)UserInfo; + + UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code; + UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; + break; + + case 1025: + UserInfo1025 = (PUSER_INFO_1025)UserInfo; + + UserAllInfo.CodePage = UserInfo1025->usri1025_code_page; + UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; + break; + + case 1051: + UserInfo1051 = (PUSER_INFO_1051)UserInfo; + + UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id; + UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; + break; case 1052: UserInfo1052 = (PUSER_INFO_1052)UserInfo; @@ -1535,8 +2112,137 @@ NetUserChangePassword(LPCWSTR domainname, LPCWSTR oldpassword, LPCWSTR newpassword) { + PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL; + PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL; + ULONG RequestBufferSize; + ULONG ResponseBufferSize = 0; + LPWSTR Ptr; + ANSI_STRING PackageName; + ULONG AuthenticationPackage = 0; + HANDLE LsaHandle = NULL; + NET_API_STATUS ApiStatus = NERR_Success; + NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS ProtocolStatus; + TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username)); - return NERR_Success; + + /* FIXME: handle null domain or user name */ + + /* Check the parameters */ + if ((oldpassword == NULL) || + (newpassword == NULL)) + return ERROR_INVALID_PARAMETER; + + /* Connect to the LSA server */ + Status = LsaConnectUntrusted(&LsaHandle); + if (!NT_SUCCESS(Status)) + return NetpNtStatusToApiStatus(Status); + + /* Get the authentication package ID */ + RtlInitAnsiString(&PackageName, + MSV1_0_PACKAGE_NAME); + + Status = LsaLookupAuthenticationPackage(LsaHandle, + &PackageName, + &AuthenticationPackage); + if (!NT_SUCCESS(Status)) + { + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + /* Calculate the request buffer size */ + RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + + ((wcslen(domainname) + 1) * sizeof(WCHAR)) + + ((wcslen(username) + 1) * sizeof(WCHAR)) + + ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) + + ((wcslen(newpassword) + 1) * sizeof(WCHAR)); + + /* Allocate the request buffer */ + ApiStatus = NetApiBufferAllocate(RequestBufferSize, + (PVOID*)&RequestBuffer); + if (ApiStatus != NERR_Success) + goto done; + + /* Initialize the request buffer */ + RequestBuffer->MessageType = MsV1_0ChangePassword; + RequestBuffer->Impersonating = TRUE; + + Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST)); + + /* Pack the domain name */ + RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR); + RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR); + RequestBuffer->DomainName.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->DomainName.Buffer, + domainname, + RequestBuffer->DomainName.MaximumLength); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength); + + /* Pack the user name */ + RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR); + RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR); + RequestBuffer->AccountName.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->AccountName.Buffer, + username, + RequestBuffer->AccountName.MaximumLength); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength); + + /* Pack the old password */ + RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR); + RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR); + RequestBuffer->OldPassword.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->OldPassword.Buffer, + oldpassword, + RequestBuffer->OldPassword.MaximumLength); + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength); + + /* Pack the new password */ + RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR); + RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR); + RequestBuffer->NewPassword.Buffer = Ptr; + + RtlCopyMemory(RequestBuffer->NewPassword.Buffer, + newpassword, + RequestBuffer->NewPassword.MaximumLength); + + /* Call the authentication package */ + Status = LsaCallAuthenticationPackage(LsaHandle, + AuthenticationPackage, + RequestBuffer, + RequestBufferSize, + (PVOID*)&ResponseBuffer, + &ResponseBufferSize, + &ProtocolStatus); + if (!NT_SUCCESS(Status)) + { + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } + + if (!NT_SUCCESS(ProtocolStatus)) + { + ApiStatus = NetpNtStatusToApiStatus(ProtocolStatus); + goto done; + } + +done: + if (RequestBuffer != NULL) + NetApiBufferFree(RequestBuffer); + + if (ResponseBuffer != NULL) + LsaFreeReturnBuffer(ResponseBuffer); + + if (LsaHandle != NULL) + NtClose(LsaHandle); + + return ApiStatus; } @@ -2416,9 +3122,11 @@ NetUserSetInfo(LPCWSTR servername, case 1013: case 1014: // case 1017: +// case 1018: // case 1020: -// case 1024: -// case 1051: + case 1024: + case 1025: + case 1051: case 1052: case 1053: break; diff --git a/dll/win32/netshell/CMakeLists.txt b/dll/win32/netshell/CMakeLists.txt index ad3b61e7820..2e0dd3f4916 100644 --- a/dll/win32/netshell/CMakeLists.txt +++ b/dll/win32/netshell/CMakeLists.txt @@ -1,9 +1,11 @@ +set_cpp(WITH_RUNTIME) + remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) add_definitions(-D_NETSHELL_) -set_cpp() + spec2def(netshell.dll netshell.spec) list(APPEND SOURCE diff --git a/dll/win32/samlib/samlib.c b/dll/win32/samlib/samlib.c index 9225a8708b2..d27d9f92984 100644 --- a/dll/win32/samlib/samlib.c +++ b/dll/win32/samlib/samlib.c @@ -203,8 +203,95 @@ SamChangePasswordUser(IN SAM_HANDLE UserHandle, IN PUNICODE_STRING OldPassword, IN PUNICODE_STRING NewPassword) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + ENCRYPTED_NT_OWF_PASSWORD OldNtPassword; + ENCRYPTED_NT_OWF_PASSWORD NewNtPassword; + ENCRYPTED_LM_OWF_PASSWORD OldLmPassword; + ENCRYPTED_LM_OWF_PASSWORD NewLmPassword; + OEM_STRING LmPwdString; + CHAR LmPwdBuffer[15]; + BOOLEAN OldLmPasswordPresent = FALSE; + BOOLEAN NewLmPasswordPresent = FALSE; + NTSTATUS Status; + + /* Calculate the NT hash for the old password */ + Status = SystemFunction007(OldPassword, + (LPBYTE)&OldNtPassword); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); + return Status; + } + + /* Calculate the NT hash for the new password */ + Status = SystemFunction007(NewPassword, + (LPBYTE)&NewNtPassword); + if (!NT_SUCCESS(Status)) + { + TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); + return Status; + } + + /* Calculate the LM password and hash for the old password */ + LmPwdString.Length = 15; + LmPwdString.MaximumLength = 15; + LmPwdString.Buffer = LmPwdBuffer; + ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); + + Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, + OldPassword, + FALSE); + if (NT_SUCCESS(Status)) + { + /* Calculate the LM hash value of the password */ + Status = SystemFunction006(LmPwdString.Buffer, + (LPSTR)&OldLmPassword); + if (NT_SUCCESS(Status)) + { + OldLmPasswordPresent = TRUE; + } + } + + /* Calculate the LM password and hash for the new password */ + LmPwdString.Length = 15; + LmPwdString.MaximumLength = 15; + LmPwdString.Buffer = LmPwdBuffer; + ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); + + Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, + NewPassword, + FALSE); + if (NT_SUCCESS(Status)) + { + /* Calculate the LM hash value of the password */ + Status = SystemFunction006(LmPwdString.Buffer, + (LPSTR)&NewLmPassword); + if (NT_SUCCESS(Status)) + { + NewLmPasswordPresent = TRUE; + } + } + + RpcTryExcept + { + Status = SamrChangePasswordUser((SAMPR_HANDLE)UserHandle, + OldLmPasswordPresent && NewLmPasswordPresent, + &OldLmPassword, + &NewLmPassword, + TRUE, + &OldNtPassword, + &NewNtPassword, + FALSE, + NULL, + FALSE, + NULL); + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; } @@ -536,7 +623,7 @@ SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle, { Status = SamrEnumerateAliasesInDomain((SAMPR_HANDLE)DomainHandle, EnumerationContext, - (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + &EnumBuffer, PreferedMaximumLength, CountReturned); @@ -586,7 +673,7 @@ SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle, { Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle, EnumerationContext, - (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + &EnumBuffer, PreferedMaximumLength, CountReturned); @@ -634,7 +721,7 @@ SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle, { Status = SamrEnumerateGroupsInDomain((SAMPR_HANDLE)DomainHandle, EnumerationContext, - (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + &EnumBuffer, PreferedMaximumLength, CountReturned); if (EnumBuffer != NULL) @@ -681,7 +768,7 @@ SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle, Status = SamrEnumerateUsersInDomain((SAMPR_HANDLE)DomainHandle, EnumerationContext, UserAccountControl, - (PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer, + &EnumBuffer, PreferedMaximumLength, CountReturned); if (EnumBuffer != NULL) diff --git a/dll/win32/samsrv/CMakeLists.txt b/dll/win32/samsrv/CMakeLists.txt index c8fb5722d5d..83cacc1a542 100644 --- a/dll/win32/samsrv/CMakeLists.txt +++ b/dll/win32/samsrv/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND SOURCE registry.c samrpc.c samsrv.c + security.c setup.c user.c utils.c diff --git a/dll/win32/samsrv/database.c b/dll/win32/samsrv/database.c index 735af60d79d..35bc9bf649c 100644 --- a/dll/win32/samsrv/database.c +++ b/dll/win32/samsrv/database.c @@ -356,7 +356,6 @@ SampValidateDbObject(SAMPR_HANDLE Handle, NTSTATUS SampCloseDbObject(PSAM_DB_OBJECT DbObject) { - PSAM_DB_OBJECT ParentObject = NULL; NTSTATUS Status = STATUS_SUCCESS; DbObject->RefCount--; @@ -370,9 +369,6 @@ SampCloseDbObject(PSAM_DB_OBJECT DbObject) if (DbObject->MembersKeyHandle != NULL) SampRegCloseKey(DbObject->MembersKeyHandle); - if (DbObject->ParentObject != NULL) - ParentObject = DbObject->ParentObject; - if (DbObject->Name != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, DbObject->Name); diff --git a/dll/win32/samsrv/samrpc.c b/dll/win32/samsrv/samrpc.c index d7fdfcdd207..fe7929fc47e 100644 --- a/dll/win32/samsrv/samrpc.c +++ b/dll/win32/samsrv/samrpc.c @@ -6751,6 +6751,71 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle, } +static NTSTATUS +SampSetUserName(PSAM_DB_OBJECT UserObject, + PRPC_UNICODE_STRING NewUserName) +{ + UNICODE_STRING OldUserName = {0, 0, NULL}; + NTSTATUS Status; + + Status = SampGetObjectAttributeString(UserObject, + L"Name", + (PRPC_UNICODE_STRING)&OldUserName); + if (!NT_SUCCESS(Status)) + { + TRACE("SampGetObjectAttributeString failed (Status 0x%08lx)\n", Status); + goto done; + } + + if (!RtlEqualUnicodeString(&OldUserName, (PCUNICODE_STRING)NewUserName, TRUE)) + { + Status = SampCheckAccountNameInDomain(UserObject->ParentObject, + NewUserName->Buffer); + if (!NT_SUCCESS(Status)) + { + TRACE("User name \'%S\' already exists in domain (Status 0x%08lx)\n", + NewUserName->Buffer, Status); + goto done; + } + } + + Status = SampSetAccountNameInDomain(UserObject->ParentObject, + L"Users", + NewUserName->Buffer, + UserObject->RelativeId); + if (!NT_SUCCESS(Status)) + { + TRACE("SampSetAccountNameInDomain failed (Status 0x%08lx)\n", Status); + goto done; + } + + Status = SampRemoveAccountNameFromDomain(UserObject->ParentObject, + L"Users", + OldUserName.Buffer); + if (!NT_SUCCESS(Status)) + { + TRACE("SampRemoveAccountNameFromDomain failed (Status 0x%08lx)\n", Status); + goto done; + } + + Status = SampSetObjectAttribute(UserObject, + L"Name", + REG_SZ, + NewUserName->Buffer, + NewUserName->Length + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + { + TRACE("SampSetObjectAttribute failed (Status 0x%08lx)\n", Status); + } + +done: + if (OldUserName.Buffer != NULL) + midl_user_free(OldUserName.Buffer); + + return Status; +} + + static NTSTATUS SampSetUserGeneral(PSAM_DB_OBJECT UserObject, PSAMPR_USER_INFO_BUFFER Buffer) @@ -6778,11 +6843,8 @@ SampSetUserGeneral(PSAM_DB_OBJECT UserObject, if (!NT_SUCCESS(Status)) goto done; - Status = SampSetObjectAttribute(UserObject, - L"Name", - REG_SZ, - Buffer->General.UserName.Buffer, - Buffer->General.UserName.MaximumLength); + Status = SampSetUserName(UserObject, + &Buffer->General.UserName); if (!NT_SUCCESS(Status)) goto done; @@ -7011,11 +7073,8 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject, if (WhichFields & USER_ALL_USERNAME) { - Status = SampSetObjectAttribute(UserObject, - L"Name", - REG_SZ, - Buffer->All.UserName.Buffer, - Buffer->All.UserName.MaximumLength); + Status = SampSetUserName(UserObject, + &Buffer->All.UserName); if (!NT_SUCCESS(Status)) goto done; } @@ -7265,11 +7324,8 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, break; case UserNameInformation: - Status = SampSetObjectAttribute(UserObject, - L"Name", - REG_SZ, - Buffer->Name.UserName.Buffer, - Buffer->Name.UserName.MaximumLength); + Status = SampSetUserName(UserObject, + &Buffer->Name.UserName); if (!NT_SUCCESS(Status)) break; @@ -7281,11 +7337,8 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, break; case UserAccountNameInformation: - Status = SampSetObjectAttribute(UserObject, - L"Name", - REG_SZ, - Buffer->AccountName.UserName.Buffer, - Buffer->AccountName.UserName.MaximumLength); + Status = SampSetUserName(UserObject, + &Buffer->AccountName.UserName); break; case UserFullNameInformation: @@ -7416,8 +7469,148 @@ SamrChangePasswordUser(IN SAMPR_HANDLE UserHandle, IN unsigned char LmCrossEncryptionPresent, IN PENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithNewNt) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + ENCRYPTED_LM_OWF_PASSWORD StoredLmPassword; + ENCRYPTED_NT_OWF_PASSWORD StoredNtPassword; + PENCRYPTED_LM_OWF_PASSWORD OldLmPassword; + PENCRYPTED_LM_OWF_PASSWORD NewLmPassword; + PENCRYPTED_NT_OWF_PASSWORD OldNtPassword; + PENCRYPTED_NT_OWF_PASSWORD NewNtPassword; + PSAM_DB_OBJECT UserObject; + ULONG Length; + SAM_USER_FIXED_DATA FixedUserData; + NTSTATUS Status; + + TRACE("(%p %u %p %p %u %p %p %u %p %u %p)\n", + UserHandle, LmPresent, OldLmEncryptedWithNewLm, NewLmEncryptedWithOldLm, + NtPresent, OldNtEncryptedWithNewNt, NewNtEncryptedWithOldNt, NtCrossEncryptionPresent, + NewNtEncryptedWithNewLm, LmCrossEncryptionPresent, NewLmEncryptedWithNewNt); + + /* Validate the user handle */ + Status = SampValidateDbObject(UserHandle, + SamDbUserObject, + USER_CHANGE_PASSWORD, + &UserObject); + if (!NT_SUCCESS(Status)) + { + TRACE("SampValidateDbObject failed with status 0x%08lx\n", Status); + return Status; + } + + /* Retrieve the LM password */ + Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD); + Status = SampGetObjectAttribute(UserObject, + L"LMPwd", + NULL, + &StoredLmPassword, + &Length); + if (!NT_SUCCESS(Status)) + { + + } + + /* Retrieve the NT password */ + Length = sizeof(ENCRYPTED_NT_OWF_PASSWORD); + Status = SampGetObjectAttribute(UserObject, + L"NTPwd", + NULL, + &StoredNtPassword, + &Length); + if (!NT_SUCCESS(Status)) + { + + } + + /* FIXME: Decrypt passwords */ + OldLmPassword = OldLmEncryptedWithNewLm; + NewLmPassword = NewLmEncryptedWithOldLm; + OldNtPassword = OldNtEncryptedWithNewNt; + NewNtPassword = NewNtEncryptedWithOldNt; + + /* Check if the old passwords match the stored ones */ + if (NtPresent) + { + if (LmPresent) + { + if (!RtlEqualMemory(&StoredLmPassword, + OldLmPassword, + sizeof(ENCRYPTED_LM_OWF_PASSWORD))) + { + TRACE("Old LM Password does not match!\n"); + Status = STATUS_WRONG_PASSWORD; + } + else + { + if (!RtlEqualMemory(&StoredNtPassword, + OldNtPassword, + sizeof(ENCRYPTED_LM_OWF_PASSWORD))) + { + TRACE("Old NT Password does not match!\n"); + Status = STATUS_WRONG_PASSWORD; + } + } + } + else + { + if (!RtlEqualMemory(&StoredNtPassword, + OldNtPassword, + sizeof(ENCRYPTED_LM_OWF_PASSWORD))) + { + TRACE("Old NT Password does not match!\n"); + Status = STATUS_WRONG_PASSWORD; + } + } + } + else + { + if (LmPresent) + { + if (!RtlEqualMemory(&StoredLmPassword, + OldLmPassword, + sizeof(ENCRYPTED_LM_OWF_PASSWORD))) + { + TRACE("Old LM Password does not match!\n"); + Status = STATUS_WRONG_PASSWORD; + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } + + /* Store the new password hashes */ + if (NT_SUCCESS(Status)) + { + Status = SampSetUserPassword(UserObject, + NewNtPassword, + NtPresent, + NewLmPassword, + LmPresent); + if (NT_SUCCESS(Status)) + { + /* Get the fixed size user data */ + Length = sizeof(SAM_USER_FIXED_DATA); + Status = SampGetObjectAttribute(UserObject, + L"F", + NULL, + &FixedUserData, + &Length); + if (NT_SUCCESS(Status)) + { + /* Update PasswordLastSet */ + NtQuerySystemTime(&FixedUserData.PasswordLastSet); + + /* Set the fixed size user data */ + Status = SampSetObjectAttribute(UserObject, + L"F", + REG_BINARY, + &FixedUserData, + Length); + } + } + } + + return Status; } diff --git a/dll/win32/samsrv/samsrv.c b/dll/win32/samsrv/samsrv.c index d8f5cb653e5..0d17100b097 100644 --- a/dll/win32/samsrv/samsrv.c +++ b/dll/win32/samsrv/samsrv.c @@ -217,6 +217,20 @@ SamIFree_SAMPR_RETURNED_USTRING_ARRAY(PSAMPR_RETURNED_USTRING_ARRAY Ptr) } +VOID +NTAPI +SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR(PSAMPR_SR_SECURITY_DESCRIPTOR Ptr) +{ + if (Ptr != NULL) + { + if (Ptr->SecurityDescriptor != NULL) + MIDL_user_free(Ptr->SecurityDescriptor); + + MIDL_user_free(Ptr); + } +} + + VOID NTAPI SamIFree_SAMPR_ULONG_ARRAY(PSAMPR_ULONG_ARRAY Ptr) diff --git a/dll/win32/samsrv/samsrv.h b/dll/win32/samsrv/samsrv.h index 8d942fa7a56..a9508cef8e5 100644 --- a/dll/win32/samsrv/samsrv.h +++ b/dll/win32/samsrv/samsrv.h @@ -300,6 +300,13 @@ VOID SampStartRpcServer(VOID); +/* security.c */ + +NTSTATUS +SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd, + OUT PULONG Size); + + /* setup.c */ BOOL diff --git a/dll/win32/samsrv/samsrv.spec b/dll/win32/samsrv/samsrv.spec index 97f1b771ef4..39f86ef5da7 100644 --- a/dll/win32/samsrv/samsrv.spec +++ b/dll/win32/samsrv/samsrv.spec @@ -26,7 +26,7 @@ @ stub SamIFree_SAMPR_GROUP_INFO_BUFFER @ stdcall SamIFree_SAMPR_PSID_ARRAY(ptr) @ stdcall SamIFree_SAMPR_RETURNED_USTRING_ARRAY(ptr) -@ stub SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR +@ stdcall SamIFree_SAMPR_SR_SECURITY_DESCRIPTOR(ptr) @ stdcall SamIFree_SAMPR_ULONG_ARRAY(ptr) @ stdcall SamIFree_SAMPR_USER_INFO_BUFFER(ptr long) @ stub SamIFree_UserInternal6Information diff --git a/dll/win32/samsrv/security.c b/dll/win32/samsrv/security.c new file mode 100644 index 00000000000..eb3a4fbdf6e --- /dev/null +++ b/dll/win32/samsrv/security.c @@ -0,0 +1,286 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: Security Account Manager (SAM) Server + * FILE: reactos/dll/win32/samsrv/security.c + * PURPOSE: Security descriptor functions + * + * PROGRAMMERS: Eric Kohl + */ + +/* INCLUDES ****************************************************************/ + +#include "samsrv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(samsrv); + + +/* GLOBALS *****************************************************************/ + +static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; +static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; + + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd, + OUT PULONG Size) +{ + PSECURITY_DESCRIPTOR AbsSD = NULL; + PSECURITY_DESCRIPTOR RelSD = NULL; + PSID EveryoneSid = NULL; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG DaclSize; + ULONG SaclSize; + ULONG RelSDSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + /* Create the Everyone SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Anonymous SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Administrators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + + /* Allocate a buffer for the absolute SD */ + AbsSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SECURITY_DESCRIPTOR)); + if (AbsSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Create the absolute SD */ + Status = RtlCreateSecurityDescriptor(AbsSD, + SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the DACL */ + DaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AdministratorsSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + SAM_SERVER_READ | SAM_SERVER_EXECUTE, + EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + SAM_SERVER_ALL_ACCESS, + AdministratorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the DACL */ + Status = RtlSetDaclSecurityDescriptor(AbsSD, + TRUE, + Dacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the SACL */ + SaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AnonymousSid); + + Sacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Sacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Sacl, + SaclSize, + ACL_REVISION); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE | + SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_INITIALIZE | + SAM_SERVER_SHUTDOWN, + EveryoneSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AnonymousSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SACL */ + Status = RtlSetSaclSecurityDescriptor(AbsSD, + TRUE, + Sacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the owner SID */ + Status = RtlSetOwnerSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the group SID */ + Status = RtlSetGroupSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Get the reqired buffer size for the self-relative SD */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + /* Allocate a buffer for the self-relative SD */ + RelSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelSDSize); + if (RelSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Convert the absolute SD to self-relative format */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + RelSD, + &RelSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + *ServerSd = RelSD; + *Size = RelSDSize; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD); + } + + if (EveryoneSid != NULL) + RtlFreeSid(EveryoneSid); + + if (AnonymousSid != NULL) + RtlFreeSid(AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeSid(AdministratorsSid); + + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (Sacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl); + + if (AbsSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD); + + return Status; +} + +/* EOF */ diff --git a/dll/win32/samsrv/setup.c b/dll/win32/samsrv/setup.c index 200a81b1004..76a262f5a8c 100644 --- a/dll/win32/samsrv/setup.c +++ b/dll/win32/samsrv/setup.c @@ -88,63 +88,71 @@ SampSetupAddMemberToAlias(HKEY hDomainKey, } -static BOOL -SampSetupCreateAliasAccount(HKEY hDomainKey, +static +NTSTATUS +SampSetupCreateAliasAccount(HANDLE hDomainKey, LPCWSTR lpAccountName, LPCWSTR lpDescription, ULONG ulRelativeId) { - DWORD dwDisposition; WCHAR szAccountKeyName[32]; - HKEY hAccountKey = NULL; - HKEY hNamesKey = NULL; + HANDLE hAccountKey = NULL; + HANDLE hNamesKey = NULL; + NTSTATUS Status; swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId); - if (!RegCreateKeyExW(hDomainKey, - szAccountKeyName, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hAccountKey, - &dwDisposition)) + Status = SampRegCreateKey(hDomainKey, + szAccountKeyName, + KEY_ALL_ACCESS, + &hAccountKey); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegSetValue(hAccountKey, + L"Name", + REG_SZ, + (LPVOID)lpAccountName, + (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"Description", + REG_SZ, + (LPVOID)lpDescription, + (wcslen(lpDescription) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + + Status = SampRegOpenKey(hDomainKey, + L"Aliases\\Names", + KEY_ALL_ACCESS, + &hNamesKey); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hNamesKey, + lpAccountName, + REG_DWORD, + (LPVOID)&ulRelativeId, + sizeof(ULONG)); + +done: + if (hNamesKey != NULL) + SampRegCloseKey(hNamesKey); + + if (hAccountKey != NULL) { - RegSetValueEx(hAccountKey, - L"Name", - 0, - REG_SZ, - (LPVOID)lpAccountName, - (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); + SampRegCloseKey(hAccountKey); - RegSetValueEx(hAccountKey, - L"Description", - 0, - REG_SZ, - (LPVOID)lpDescription, - (wcslen(lpDescription) + 1) * sizeof(WCHAR)); - - RegCloseKey(hAccountKey); + if (!NT_SUCCESS(Status)) + SampRegDeleteKey(hDomainKey, + szAccountKeyName); } - if (!RegOpenKeyExW(hDomainKey, - L"Aliases\\Names", - 0, - KEY_ALL_ACCESS, - &hNamesKey)) - { - RegSetValueEx(hNamesKey, - lpAccountName, - 0, - REG_DWORD, - (LPVOID)&ulRelativeId, - sizeof(ULONG)); - - RegCloseKey(hNamesKey); - } - - return TRUE; + return Status; } @@ -310,8 +318,9 @@ done: } -static BOOL -SampSetupCreateUserAccount(HKEY hDomainKey, +static +NTSTATUS +SampSetupCreateUserAccount(HANDLE hDomainKey, LPCWSTR lpAccountName, LPCWSTR lpComment, ULONG ulRelativeId, @@ -321,10 +330,10 @@ SampSetupCreateUserAccount(HKEY hDomainKey, GROUP_MEMBERSHIP GroupMembership; UCHAR LogonHours[23]; LPWSTR lpEmptyString = L""; - DWORD dwDisposition; WCHAR szAccountKeyName[32]; - HKEY hAccountKey = NULL; - HKEY hNamesKey = NULL; + HANDLE hAccountKey = NULL; + HANDLE hNamesKey = NULL; + NTSTATUS Status; /* Initialize fixed user data */ FixedUserData.Version = 1; @@ -347,189 +356,213 @@ SampSetupCreateUserAccount(HKEY hDomainKey, swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId); - if (!RegCreateKeyExW(hDomainKey, - szAccountKeyName, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hAccountKey, - &dwDisposition)) + Status = SampRegCreateKey(hDomainKey, + szAccountKeyName, + KEY_ALL_ACCESS, + &hAccountKey); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegSetValue(hAccountKey, + L"F", + REG_BINARY, + (LPVOID)&FixedUserData, + sizeof(SAM_USER_FIXED_DATA)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"Name", + REG_SZ, + (LPVOID)lpAccountName, + (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"FullName", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"HomeDirectory", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"HomeDirectoryDrive", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"ScriptPath", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"ProfilePath", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"AdminComment", + REG_SZ, + (LPVOID)lpComment, + (wcslen(lpComment) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"UserComment", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"WorkStations", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hAccountKey, + L"Parameters", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set LogonHours attribute*/ + *((PUSHORT)LogonHours) = 168; + memset(&(LogonHours[2]), 0xff, 21); + + Status = SampRegSetValue(hAccountKey, + L"LogonHours", + REG_BINARY, + (LPVOID)LogonHours, + sizeof(LogonHours)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set Groups attribute*/ + GroupMembership.RelativeId = DOMAIN_GROUP_RID_USERS; + GroupMembership.Attributes = SE_GROUP_MANDATORY | + SE_GROUP_ENABLED | + SE_GROUP_ENABLED_BY_DEFAULT; + + Status = SampRegSetValue(hAccountKey, + L"Groups", + REG_BINARY, + (LPVOID)&GroupMembership, + sizeof(GROUP_MEMBERSHIP)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set LMPwd attribute*/ + Status = SampRegSetValue(hAccountKey, + L"LMPwd", + REG_BINARY, + (LPVOID)&EmptyLmHash, + sizeof(ENCRYPTED_LM_OWF_PASSWORD)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set NTPwd attribute*/ + Status = SampRegSetValue(hAccountKey, + L"NTPwd", + REG_BINARY, + (LPVOID)&EmptyNtHash, + sizeof(ENCRYPTED_NT_OWF_PASSWORD)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set LMPwdHistory attribute*/ + Status = SampRegSetValue(hAccountKey, + L"LMPwdHistory", + REG_BINARY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set NTPwdHistory attribute*/ + Status = SampRegSetValue(hAccountKey, + L"NTPwdHistory", + REG_BINARY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + goto done; + + /* FIXME: Set SecDesc attribute*/ + + + Status = SampRegOpenKey(hDomainKey, + L"Users\\Names", + KEY_ALL_ACCESS, + &hNamesKey); + if (!NT_SUCCESS(Status)) + goto done; + + Status = SampRegSetValue(hNamesKey, + lpAccountName, + REG_DWORD, + (LPVOID)&ulRelativeId, + sizeof(ULONG)); + +done: + if (hNamesKey != NULL) + SampRegCloseKey(hNamesKey); + + if (hAccountKey != NULL) { - RegSetValueEx(hAccountKey, - L"F", - 0, - REG_BINARY, - (LPVOID)&FixedUserData, - sizeof(SAM_USER_FIXED_DATA)); + SampRegCloseKey(hAccountKey); - RegSetValueEx(hAccountKey, - L"Name", - 0, - REG_SZ, - (LPVOID)lpAccountName, - (wcslen(lpAccountName) + 1) * sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"FullName", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"HomeDirectory", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"HomeDirectoryDrive", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"ScriptPath", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"ProfilePath", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"AdminComment", - 0, - REG_SZ, - (LPVOID)lpComment, - (wcslen(lpComment) + 1) * sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"UserComment", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"WorkStations", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - RegSetValueEx(hAccountKey, - L"Parameters", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); - - /* Set LogonHours attribute*/ - *((PUSHORT)LogonHours) = 168; - memset(&(LogonHours[2]), 0xff, 21); - - RegSetValueEx(hAccountKey, - L"LogonHours", - 0, - REG_BINARY, - (LPVOID)LogonHours, - sizeof(LogonHours)); - - /* Set Groups attribute*/ - GroupMembership.RelativeId = DOMAIN_GROUP_RID_USERS; - GroupMembership.Attributes = SE_GROUP_MANDATORY | - SE_GROUP_ENABLED | - SE_GROUP_ENABLED_BY_DEFAULT; - - RegSetValueEx(hAccountKey, - L"Groups", - 0, - REG_BINARY, - (LPVOID)&GroupMembership, - sizeof(GROUP_MEMBERSHIP)); - - /* Set LMPwd attribute*/ - RegSetValueEx(hAccountKey, - L"LMPwd", - 0, - REG_BINARY, - (LPVOID)&EmptyLmHash, - sizeof(ENCRYPTED_LM_OWF_PASSWORD)); - - /* Set NTPwd attribute*/ - RegSetValueEx(hAccountKey, - L"NTPwd", - 0, - REG_BINARY, - (LPVOID)&EmptyNtHash, - sizeof(ENCRYPTED_NT_OWF_PASSWORD)); - - /* Set LMPwdHistory attribute*/ - RegSetValueEx(hAccountKey, - L"LMPwdHistory", - 0, - REG_BINARY, - NULL, - 0); - - /* Set NTPwdHistory attribute*/ - RegSetValueEx(hAccountKey, - L"NTPwdHistory", - 0, - REG_BINARY, - NULL, - 0); - - /* FIXME: Set SecDesc attribute*/ - - RegCloseKey(hAccountKey); + if (!NT_SUCCESS(Status)) + SampRegDeleteKey(hDomainKey, + szAccountKeyName); } - if (!RegOpenKeyExW(hDomainKey, - L"Users\\Names", - 0, - KEY_ALL_ACCESS, - &hNamesKey)) - { - RegSetValueEx(hNamesKey, - lpAccountName, - 0, - REG_DWORD, - (LPVOID)&ulRelativeId, - sizeof(ULONG)); - - RegCloseKey(hNamesKey); - } - - return TRUE; + return Status; } -static BOOL -SampSetupCreateDomain(IN HKEY hDomainsKey, +static +NTSTATUS +SampSetupCreateDomain(IN HANDLE hServerKey, IN LPCWSTR lpKeyName, IN LPCWSTR lpDomainName, IN PSID lpDomainSid, - OUT PHKEY lpDomainKey) + OUT HANDLE *lpDomainKey) { SAM_DOMAIN_FIXED_DATA FixedData; + WCHAR szDomainKeyName[32]; LPWSTR lpEmptyString = L""; - DWORD dwDisposition; - HKEY hDomainKey = NULL; - HKEY hAliasesKey = NULL; - HKEY hGroupsKey = NULL; - HKEY hUsersKey = NULL; - HKEY hNamesKey = NULL; + HANDLE hDomainKey = NULL; + HANDLE hAliasesKey = NULL; + HANDLE hGroupsKey = NULL; + HANDLE hUsersKey = NULL; + HANDLE hNamesKey = NULL; + NTSTATUS Status; if (lpDomainKey != NULL) *lpDomainKey = NULL; @@ -554,137 +587,183 @@ SampSetupCreateDomain(IN HKEY hDomainsKey, FixedData.DomainServerRole = DomainServerRolePrimary; FixedData.UasCompatibilityRequired = TRUE; - if (RegCreateKeyExW(hDomainsKey, - lpKeyName, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hDomainKey, - &dwDisposition)) - return FALSE; + wcscpy(szDomainKeyName, L"Domains\\"); + wcscat(szDomainKeyName, lpKeyName); + + Status = SampRegCreateKey(hServerKey, + szDomainKeyName, + KEY_ALL_ACCESS, + &hDomainKey); + if (!NT_SUCCESS(Status)) + return Status; /* Set the fixed data value */ - if (RegSetValueEx(hDomainKey, - L"F", - 0, - REG_BINARY, - (LPVOID)&FixedData, - sizeof(SAM_DOMAIN_FIXED_DATA))) - return FALSE; + Status = SampRegSetValue(hDomainKey, + L"F", + REG_BINARY, + (LPVOID)&FixedData, + sizeof(SAM_DOMAIN_FIXED_DATA)); + if (!NT_SUCCESS(Status)) + goto done; if (lpDomainSid != NULL) { - RegSetValueEx(hDomainKey, - L"Name", - 0, - REG_SZ, - (LPVOID)lpDomainName, - (wcslen(lpDomainName) + 1) * sizeof(WCHAR)); + Status = SampRegSetValue(hDomainKey, + L"Name", + REG_SZ, + (LPVOID)lpDomainName, + (wcslen(lpDomainName) + 1) * sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; - RegSetValueEx(hDomainKey, - L"SID", - 0, - REG_BINARY, - (LPVOID)lpDomainSid, - RtlLengthSid(lpDomainSid)); + Status = SampRegSetValue(hDomainKey, + L"SID", + REG_BINARY, + (LPVOID)lpDomainSid, + RtlLengthSid(lpDomainSid)); + if (!NT_SUCCESS(Status)) + goto done; } - RegSetValueEx(hDomainKey, - L"OemInformation", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); + Status = SampRegSetValue(hDomainKey, + L"OemInformation", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; - RegSetValueEx(hDomainKey, - L"ReplicaSourceNodeName", - 0, - REG_SZ, - (LPVOID)lpEmptyString, - sizeof(WCHAR)); + Status = SampRegSetValue(hDomainKey, + L"ReplicaSourceNodeName", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; /* Create the Alias container */ - if (!RegCreateKeyExW(hDomainKey, - L"Aliases", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hAliasesKey, - &dwDisposition)) - { - if (!RegCreateKeyExW(hAliasesKey, - L"Names", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hNamesKey, - &dwDisposition)) - RegCloseKey(hNamesKey); + Status = SampRegCreateKey(hDomainKey, + L"Aliases", + KEY_ALL_ACCESS, + &hAliasesKey); + if (!NT_SUCCESS(Status)) + goto done; - RegCloseKey(hAliasesKey); - } + Status = SampRegCreateKey(hAliasesKey, + L"Names", + KEY_ALL_ACCESS, + &hNamesKey); + if (!NT_SUCCESS(Status)) + goto done; + + SampRegCloseKey(hNamesKey); /* Create the Groups container */ - if (!RegCreateKeyExW(hDomainKey, - L"Groups", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hGroupsKey, - &dwDisposition)) - { - if (!RegCreateKeyExW(hGroupsKey, - L"Names", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hNamesKey, - &dwDisposition)) - RegCloseKey(hNamesKey); + Status = SampRegCreateKey(hDomainKey, + L"Groups", + KEY_ALL_ACCESS, + &hGroupsKey); + if (!NT_SUCCESS(Status)) + goto done; - RegCloseKey(hGroupsKey); - } + Status = SampRegCreateKey(hGroupsKey, + L"Names", + KEY_ALL_ACCESS, + &hNamesKey); + if (!NT_SUCCESS(Status)) + goto done; + SampRegCloseKey(hNamesKey); /* Create the Users container */ - if (!RegCreateKeyExW(hDomainKey, - L"Users", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hUsersKey, - &dwDisposition)) - { - if (!RegCreateKeyExW(hUsersKey, - L"Names", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hNamesKey, - &dwDisposition)) - RegCloseKey(hNamesKey); + Status = SampRegCreateKey(hDomainKey, + L"Users", + KEY_ALL_ACCESS, + &hUsersKey); + if (!NT_SUCCESS(Status)) + goto done; - RegCloseKey(hUsersKey); - } + Status = SampRegCreateKey(hUsersKey, + L"Names", + KEY_ALL_ACCESS, + &hNamesKey); + if (!NT_SUCCESS(Status)) + goto done; + + SampRegCloseKey(hNamesKey); if (lpDomainKey != NULL) *lpDomainKey = hDomainKey; - return TRUE; +done: + if (hAliasesKey != NULL) + SampRegCloseKey(hAliasesKey); + + if (hGroupsKey != NULL) + SampRegCloseKey(hGroupsKey); + + if (hUsersKey != NULL) + SampRegCloseKey(hUsersKey); + + if (!NT_SUCCESS(Status)) + { + if (hDomainKey != NULL) + SampRegCloseKey(hDomainKey); + } + + return Status; +} + + +static +NTSTATUS +SampSetupCreateServer(IN HANDLE hSamKey, + OUT HANDLE *lpServerKey) +{ + HANDLE hServerKey = NULL; + HANDLE hDomainsKey = NULL; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; + NTSTATUS Status; + + Status = SampRegCreateKey(hSamKey, + L"SAM", + KEY_ALL_ACCESS, + &hServerKey); + if (!NT_SUCCESS(Status)) + return Status; + + Status = SampRegCreateKey(hServerKey, + L"Domains", + KEY_ALL_ACCESS, + &hDomainsKey); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the server SD */ + Status = SampCreateServerSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set SecDesc attribute*/ + Status = SampRegSetValue(hServerKey, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + SampRegCloseKey(hDomainsKey); + + *lpServerKey = hServerKey; + +done: + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + + return Status; } @@ -724,10 +803,10 @@ BOOL SampInitializeSAM(VOID) { PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL; - DWORD dwDisposition; - HKEY hSamKey = NULL; - HKEY hDomainsKey = NULL; - HKEY hDomainKey = NULL; + HANDLE hSamKey = NULL; + HANDLE hServerKey = NULL; + HANDLE hBuiltinDomainKey = NULL; + HANDLE hAccountDomainKey = NULL; PSID pBuiltinSid = NULL; BOOL bResult = TRUE; PSID pSid; @@ -740,38 +819,26 @@ SampInitializeSAM(VOID) hInstance = GetModuleHandleW(L"samsrv.dll"); - if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, - L"SAM\\SAM", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hSamKey, - &dwDisposition)) + /* Open the SAM key */ + Status = SampRegOpenKey(NULL, + L"\\Registry\\Machine\\SAM", + KEY_READ | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, + &hSamKey); + if (!NT_SUCCESS(Status)) { - ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError()); + ERR("Failed to open the SAM key (Status: 0x%08lx)\n", Status); return FALSE; } - if (RegCreateKeyExW(hSamKey, - L"Domains", - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hDomainsKey, - &dwDisposition)) + /* Create the SAM Server object */ + Status = SampSetupCreateServer(hSamKey, + &hServerKey); + if (!NT_SUCCESS(Status)) { - ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError()); bResult = FALSE; goto done; } - RegCloseKey(hSamKey); - hSamKey = NULL; - /* Create and initialize the Builtin Domain SID */ pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1)); if (pBuiltinSid == NULL) @@ -796,16 +863,21 @@ SampInitializeSAM(VOID) SampLoadString(hInstance, IDS_DOMAIN_BUILTIN_NAME, szName, 80); /* Create the Builtin domain */ - if (SampSetupCreateDomain(hDomainsKey, - L"Builtin", - szName, - pBuiltinSid, - &hDomainKey)) + Status = SampSetupCreateDomain(hServerKey, + L"Builtin", + szName, + pBuiltinSid, + &hBuiltinDomainKey); + if (!NT_SUCCESS(Status)) { - SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_NAME, szName, 80); - SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_COMMENT, szComment, 256); + bResult = FALSE; + goto done; + } - SampSetupCreateAliasAccount(hDomainKey, + SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_NAME, szName, 80); + SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_COMMENT, szComment, 256); + + SampSetupCreateAliasAccount(hBuiltinDomainKey, szName, szComment, DOMAIN_ALIAS_RID_ADMINS); @@ -813,7 +885,7 @@ SampInitializeSAM(VOID) SampLoadString(hInstance, IDS_ALIAS_USERS_NAME, szName, 80); SampLoadString(hInstance, IDS_ALIAS_USERS_COMMENT, szComment, 256); - SampSetupCreateAliasAccount(hDomainKey, + SampSetupCreateAliasAccount(hBuiltinDomainKey, szName, szComment, DOMAIN_ALIAS_RID_USERS); @@ -821,7 +893,7 @@ SampInitializeSAM(VOID) SampLoadString(hInstance, IDS_ALIAS_GUESTS_NAME, szName, 80); SampLoadString(hInstance, IDS_ALIAS_GUESTS_COMMENT, szComment, 256); - SampSetupCreateAliasAccount(hDomainKey, + SampSetupCreateAliasAccount(hBuiltinDomainKey, szName, szComment, DOMAIN_ALIAS_RID_GUESTS); @@ -829,7 +901,7 @@ SampInitializeSAM(VOID) SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_NAME, szName, 80); SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_COMMENT, szComment, 256); - SampSetupCreateAliasAccount(hDomainKey, + SampSetupCreateAliasAccount(hBuiltinDomainKey, szName, szComment, DOMAIN_ALIAS_RID_POWER_USERS); @@ -839,7 +911,7 @@ SampInitializeSAM(VOID) DOMAIN_USER_RID_ADMIN); if (pSid != NULL) { - SampSetupAddMemberToAlias(hDomainKey, + SampSetupAddMemberToAlias(hBuiltinDomainKey, DOMAIN_ALIAS_RID_ADMINS, pSid); @@ -851,27 +923,30 @@ SampInitializeSAM(VOID) DOMAIN_USER_RID_GUEST); if (pSid != NULL) { - SampSetupAddMemberToAlias(hDomainKey, + SampSetupAddMemberToAlias(hBuiltinDomainKey, DOMAIN_ALIAS_RID_GUESTS, pSid); RtlFreeHeap(RtlGetProcessHeap(), 0, pSid); } - RegCloseKey(hDomainKey); - } /* Create the Account domain */ - if (SampSetupCreateDomain(hDomainsKey, - L"Account", - L"", - AccountDomainInfo->DomainSid, - &hDomainKey)) + Status = SampSetupCreateDomain(hServerKey, + L"Account", + L"", + AccountDomainInfo->DomainSid, + &hAccountDomainKey); + if (!NT_SUCCESS(Status)) { + bResult = FALSE; + goto done; + } + SampLoadString(hInstance, IDS_GROUP_NONE_NAME, szName, 80); SampLoadString(hInstance, IDS_GROUP_NONE_COMMENT, szComment, 256); - SampSetupCreateGroupAccount(hDomainKey, + SampSetupCreateGroupAccount(hAccountDomainKey, szName, szComment, DOMAIN_GROUP_RID_USERS); @@ -879,32 +954,29 @@ SampInitializeSAM(VOID) SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_NAME, szName, 80); SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_COMMENT, szComment, 256); - SampSetupCreateUserAccount(hDomainKey, + SampSetupCreateUserAccount(hAccountDomainKey, szName, szComment, DOMAIN_USER_RID_ADMIN, USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT); - SampSetupAddMemberToGroup(hDomainKey, + SampSetupAddMemberToGroup(hAccountDomainKey, DOMAIN_GROUP_RID_USERS, DOMAIN_USER_RID_ADMIN); SampLoadString(hInstance, IDS_USER_GUEST_NAME, szName, 80); SampLoadString(hInstance, IDS_USER_GUEST_COMMENT, szComment, 256); - SampSetupCreateUserAccount(hDomainKey, + SampSetupCreateUserAccount(hAccountDomainKey, szName, szComment, DOMAIN_USER_RID_GUEST, USER_ACCOUNT_DISABLED | USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT); - SampSetupAddMemberToGroup(hDomainKey, + SampSetupAddMemberToGroup(hAccountDomainKey, DOMAIN_GROUP_RID_USERS, DOMAIN_USER_RID_GUEST); - RegCloseKey(hDomainKey); - } - done: if (AccountDomainInfo) LsaFreeMemory(AccountDomainInfo); @@ -912,11 +984,17 @@ done: if (pBuiltinSid) RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid); - if (hDomainsKey) - RegCloseKey(hDomainsKey); + if (hAccountDomainKey != NULL) + SampRegCloseKey(hAccountDomainKey); - if (hSamKey) - RegCloseKey(hSamKey); + if (hBuiltinDomainKey != NULL) + SampRegCloseKey(hBuiltinDomainKey); + + if (hServerKey != NULL) + SampRegCloseKey(hServerKey); + + if (hSamKey != NULL) + SampRegCloseKey(hSamKey); TRACE("SampInitializeSAM() done\n"); diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt index 6ee35190979..4a9c4e2907b 100644 --- a/dll/win32/shell32/CMakeLists.txt +++ b/dll/win32/shell32/CMakeLists.txt @@ -1,4 +1,5 @@ -set_cpp() + +set_cpp(WITH_RUNTIME) remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) diff --git a/dll/win32/wbemprox/CMakeLists.txt b/dll/win32/wbemprox/CMakeLists.txt new file mode 100644 index 00000000000..94724a7122f --- /dev/null +++ b/dll/win32/wbemprox/CMakeLists.txt @@ -0,0 +1,38 @@ + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) +add_definitions(-D__WINESRC__) + +remove_definitions(-D_WIN32_WINNT=0x502) +add_definitions(-D_WIN32_WINNT=0x600) + +spec2def(wbemprox.dll wbemprox.spec) + +list(APPEND SOURCE + builtin.c + class.c + main.c + process.c + qualifier.c + query.c + reg.c + service.c + services.c + table.c + wbemlocator.c + wql.tab.c + ${CMAKE_CURRENT_BINARY_DIR}/wbemprox.def) + +add_library(wbemprox SHARED ${SOURCE} wbemprox.rc) + +if(NOT MSVC) + # FIXME: http://www.cmake.org/Bug/view.php?id=12998 + #allow_warnings(wbemprox) + set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-error") +endif() + +set_source_files_properties(wbemprox.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/wbemprox.rgs) +set_module_type(wbemprox win32dll) +target_link_libraries(wbemprox wine) +add_importlibs(wbemprox iphlpapi dxgi oleaut32 ole32 advapi32 user32 gdi32 msvcrt kernel32 ntdll) +add_dependencies(wbemprox d3d_idl_headers) +add_cd_file(TARGET wbemprox DESTINATION reactos/system32/wbem FOR all) diff --git a/dll/win32/wbemprox/builtin.c b/dll/win32/wbemprox/builtin.c new file mode 100644 index 00000000000..cd229d3aef6 --- /dev/null +++ b/dll/win32/wbemprox/builtin.c @@ -0,0 +1,1428 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "config.h" +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "initguid.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" +#include "wbemprov.h" +#include "winsock2.h" +#include "iphlpapi.h" +#include "tlhelp32.h" +#include "d3d10.h" +#include "winternl.h" +#include "winioctl.h" +#include "winsvc.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +static const WCHAR class_baseboardW[] = + {'W','i','n','3','2','_','B','a','s','e','B','o','a','r','d',0}; +static const WCHAR class_biosW[] = + {'W','i','n','3','2','_','B','I','O','S',0}; +static const WCHAR class_cdromdriveW[] = + {'W','i','n','3','2','_','C','D','R','O','M','D','r','i','v','e',0}; +static const WCHAR class_compsysW[] = + {'W','i','n','3','2','_','C','o','m','p','u','t','e','r','S','y','s','t','e','m',0}; +static const WCHAR class_diskdriveW[] = + {'W','i','n','3','2','_','D','i','s','k','D','r','i','v','e',0}; +static const WCHAR class_diskpartitionW[] = + {'W','i','n','3','2','_','D','i','s','k','P','a','r','t','i','t','i','o','n',0}; +static const WCHAR class_logicaldiskW[] = + {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0}; +static const WCHAR class_networkadapterW[] = + {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0}; +static const WCHAR class_osW[] = + {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; +static const WCHAR class_paramsW[] = + {'_','_','P','A','R','A','M','E','T','E','R','S',0}; +static const WCHAR class_qualifiersW[] = + {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; +static const WCHAR class_process_getowner_outW[] = + {'_','_','W','I','N','3','2','_','P','R','O','C','E','S','S','_','G','E','T','O','W', + 'N','E','R','_','O','U','T',0}; +static const WCHAR class_processorW[] = + {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; +static const WCHAR class_sounddeviceW[] = + {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0}; +static const WCHAR class_videocontrollerW[] = + {'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0}; + +static const WCHAR prop_adaptertypeW[] = + {'A','d','a','p','t','e','r','T','y','p','e',0}; +static const WCHAR prop_acceptpauseW[] = + {'A','c','c','e','p','t','P','a','u','s','e',0}; +static const WCHAR prop_acceptstopW[] = + {'A','c','c','e','p','t','S','t','o','p',0}; +static const WCHAR prop_adapterramW[] = + {'A','d','a','p','t','e','r','R','A','M',0}; +static const WCHAR prop_bootableW[] = + {'B','o','o','t','a','b','l','e',0}; +static const WCHAR prop_captionW[] = + {'C','a','p','t','i','o','n',0}; +static const WCHAR prop_classW[] = + {'C','l','a','s','s',0}; +static const WCHAR prop_commandlineW[] = + {'C','o','m','m','a','n','d','L','i','n','e',0}; +static const WCHAR prop_cpustatusW[] = + {'C','p','u','S','t','a','t','u','s',0}; +static const WCHAR prop_csdversionW[] = + {'C','S','D','V','e','r','s','i','o','n',0}; +static const WCHAR prop_currentbitsperpixelW[] = + {'C','u','r','r','e','n','t','B','i','t','s','P','e','r','P','i','x','e','l',0}; +static const WCHAR prop_currenthorizontalresW[] = + {'C','u','r','r','e','n','t','H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR prop_currentverticalresW[] = + {'C','u','r','r','e','n','t','V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0}; +static const WCHAR prop_defaultvalueW[] = + {'D','e','f','a','u','l','t','V','a','l','u','e',0}; +static const WCHAR prop_descriptionW[] = + {'D','e','s','c','r','i','p','t','i','o','n',0}; +static const WCHAR prop_deviceidW[] = + {'D','e','v','i','c','e','I','d',0}; +static const WCHAR prop_directionW[] = + {'D','i','r','e','c','t','i','o','n',0}; +static const WCHAR prop_displaynameW[] = + {'D','i','s','p','l','a','y','N','a','m','e',0}; +static const WCHAR prop_diskindexW[] = + {'D','i','s','k','I','n','d','e','x',0}; +static const WCHAR prop_domainW[] = + {'D','o','m','a','i','n',0}; +static const WCHAR prop_domainroleW[] = + {'D','o','m','a','i','n','R','o','l','e',0}; +static const WCHAR prop_driveW[] = + {'D','r','i','v','e',0}; +static const WCHAR prop_drivetypeW[] = + {'D','r','i','v','e','T','y','p','e',0}; +static const WCHAR prop_filesystemW[] = + {'F','i','l','e','S','y','s','t','e','m',0}; +static const WCHAR prop_flavorW[] = + {'F','l','a','v','o','r',0}; +static const WCHAR prop_freespaceW[] = + {'F','r','e','e','S','p','a','c','e',0}; +static const WCHAR prop_handleW[] = + {'H','a','n','d','l','e',0}; +static const WCHAR prop_idW[] = + {'I','D',0}; +static const WCHAR prop_indexW[] = + {'I','n','d','e','x',0}; +static const WCHAR prop_interfaceindexW[] = + {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0}; +static const WCHAR prop_intvalueW[] = + {'I','n','t','e','g','e','r','V','a','l','u','e',0}; +static const WCHAR prop_lastbootuptimeW[] = + {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0}; +static const WCHAR prop_macaddressW[] = + {'M','A','C','A','d','d','r','e','s','s',0}; +static const WCHAR prop_manufacturerW[] = + {'M','a','n','u','f','a','c','t','u','r','e','r',0}; +static const WCHAR prop_maxclockspeedW[] = + {'M','a','x','C','l','o','c','k','S','p','e','e','d',0}; +static const WCHAR prop_memberW[] = + {'M','e','m','b','e','r',0}; +static const WCHAR prop_methodW[] = + {'M','e','t','h','o','d',0}; +static const WCHAR prop_modelW[] = + {'M','o','d','e','l',0}; +static const WCHAR prop_netconnectionstatusW[] = + {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0}; +static const WCHAR prop_numlogicalprocessorsW[] = + {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0}; +static const WCHAR prop_numprocessorsW[] = + {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0}; +static const WCHAR prop_osarchitectureW[] = + {'O','S','A','r','c','h','i','t','e','c','t','u','r','e',0}; +static const WCHAR prop_oslanguageW[] = + {'O','S','L','a','n','g','u','a','g','e',0}; +static const WCHAR prop_parameterW[] = + {'P','a','r','a','m','e','t','e','r',0}; +static const WCHAR prop_pnpdeviceidW[] = + {'P','N','P','D','e','v','i','c','e','I','D',0}; +static const WCHAR prop_pprocessidW[] = + {'P','a','r','e','n','t','P','r','o','c','e','s','s','I','D',0}; +static const WCHAR prop_processidW[] = + {'P','r','o','c','e','s','s','I','D',0}; +static const WCHAR prop_processoridW[] = + {'P','r','o','c','e','s','s','o','r','I','d',0}; +static const WCHAR prop_productnameW[] = + {'P','r','o','d','u','c','t','N','a','m','e',0}; +static const WCHAR prop_releasedateW[] = + {'R','e','l','e','a','s','e','D','a','t','e',0}; +static const WCHAR prop_serialnumberW[] = + {'S','e','r','i','a','l','N','u','m','b','e','r',0}; +static const WCHAR prop_servicetypeW[] = + {'S','e','r','v','i','c','e','T','y','p','e',0}; +static const WCHAR prop_startmodeW[] = + {'S','t','a','r','t','M','o','d','e',0}; +static const WCHAR prop_sizeW[] = + {'S','i','z','e',0}; +static const WCHAR prop_speedW[] = + {'S','p','e','e','d',0}; +static const WCHAR prop_startingoffsetW[] = + {'S','t','a','r','t','i','n','g','O','f','f','s','e','t',0}; +static const WCHAR prop_stateW[] = + {'S','t','a','t','e',0}; +static const WCHAR prop_strvalueW[] = + {'S','t','r','i','n','g','V','a','l','u','e',0}; +static const WCHAR prop_systemdirectoryW[] = + {'S','y','s','t','e','m','D','i','r','e','c','t','o','r','y',0}; +static const WCHAR prop_systemnameW[] = + {'S','y','s','t','e','m','N','a','m','e',0}; +static const WCHAR prop_tagW[] = + {'T','a','g',0}; +static const WCHAR prop_threadcountW[] = + {'T','h','r','e','a','d','C','o','u','n','t',0}; +static const WCHAR prop_totalphysicalmemoryW[] = + {'T','o','t','a','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; +static const WCHAR prop_typeW[] = + {'T','y','p','e',0}; +static const WCHAR prop_uniqueidW[] = + {'U','n','i','q','u','e','I','d',0}; +static const WCHAR prop_varianttypeW[] = + {'V','a','r','i','a','n','t','T','y','p','e',0}; +static const WCHAR prop_versionW[] = + {'V','e','r','s','i','o','n',0}; + +/* column definitions must be kept in sync with record structures below */ +static const struct column col_baseboard[] = +{ + { prop_manufacturerW, CIM_STRING }, + { prop_serialnumberW, CIM_STRING }, + { prop_tagW, CIM_STRING|COL_FLAG_KEY } +}; +static const struct column col_bios[] = +{ + { prop_descriptionW, CIM_STRING }, + { prop_manufacturerW, CIM_STRING }, + { prop_releasedateW, CIM_DATETIME }, + { prop_serialnumberW, CIM_STRING }, + { prop_versionW, CIM_STRING|COL_FLAG_KEY } +}; +static const struct column col_cdromdrive[] = +{ + { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, + { prop_driveW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_nameW, CIM_STRING }, + { prop_pnpdeviceidW, CIM_STRING } +}; +static const struct column col_compsys[] = +{ + { prop_descriptionW, CIM_STRING }, + { prop_domainW, CIM_STRING }, + { prop_domainroleW, CIM_UINT16 }, + { prop_manufacturerW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 }, + { prop_numprocessorsW, CIM_UINT32, VT_I4 }, + { prop_totalphysicalmemoryW, CIM_UINT64 } +}; +static const struct column col_diskdrive[] = +{ + { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, + { prop_manufacturerW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_serialnumberW, CIM_STRING } +}; +static const struct column col_diskpartition[] = +{ + { prop_bootableW, CIM_BOOLEAN }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_diskindexW, CIM_UINT32, VT_I4 }, + { prop_indexW, CIM_UINT32, VT_I4 }, + { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_sizeW, CIM_UINT64 }, + { prop_startingoffsetW, CIM_UINT64 }, + { prop_typeW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_logicaldisk[] = +{ + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_drivetypeW, CIM_UINT32, VT_I4 }, + { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_freespaceW, CIM_UINT64 }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_sizeW, CIM_UINT64 } +}; +static const struct column col_networkadapter[] = +{ + { prop_adaptertypeW, CIM_STRING }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_interfaceindexW, CIM_UINT32, VT_I4 }, + { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_manufacturerW, CIM_STRING }, + { prop_netconnectionstatusW, CIM_UINT16, VT_I4 }, + { prop_pnpdeviceidW, CIM_STRING }, + { prop_speedW, CIM_UINT64 } +}; +static const struct column col_os[] = +{ + { prop_captionW, CIM_STRING }, + { prop_csdversionW, CIM_STRING }, + { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, + { prop_osarchitectureW, CIM_STRING }, + { prop_oslanguageW, CIM_UINT32, VT_I4 }, + { prop_systemdirectoryW, CIM_STRING|COL_FLAG_DYNAMIC } +}; +static const struct column col_param[] = +{ + { prop_classW, CIM_STRING }, + { prop_methodW, CIM_STRING }, + { prop_directionW, CIM_SINT32 }, + { prop_parameterW, CIM_STRING }, + { prop_typeW, CIM_UINT32 }, + { prop_varianttypeW, CIM_UINT32 }, + { prop_defaultvalueW, CIM_UINT32 } +}; +static const struct column col_process[] = +{ + { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_commandlineW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_handleW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_pprocessidW, CIM_UINT32, VT_I4 }, + { prop_processidW, CIM_UINT32, VT_I4 }, + { prop_threadcountW, CIM_UINT32, VT_I4 }, + /* methods */ + { method_getownerW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } +}; +static const struct column col_processor[] = +{ + { prop_cpustatusW, CIM_UINT16 }, + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_manufacturerW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_maxclockspeedW, CIM_UINT32, VT_I4 }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_numlogicalprocessorsW, CIM_UINT32, VT_I4 }, + { prop_processoridW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_uniqueidW, CIM_STRING } +}; +static const struct column col_qualifier[] = +{ + { prop_classW, CIM_STRING }, + { prop_memberW, CIM_STRING }, + { prop_typeW, CIM_UINT32 }, + { prop_flavorW, CIM_SINT32 }, + { prop_nameW, CIM_STRING }, + { prop_intvalueW, CIM_SINT32 }, + { prop_strvalueW, CIM_STRING } +}; +static const struct column col_service[] = +{ + { prop_acceptpauseW, CIM_BOOLEAN }, + { prop_acceptstopW, CIM_BOOLEAN }, + { prop_displaynameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_processidW, CIM_UINT32 }, + { prop_servicetypeW, CIM_STRING }, + { prop_startmodeW, CIM_STRING }, + { prop_stateW, CIM_STRING }, + { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + /* methods */ + { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_startserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_stopserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } +}; +static const struct column col_sounddevice[] = +{ + { prop_productnameW, CIM_STRING } +}; +static const struct column col_stdregprov[] = +{ + { method_enumkeyW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_enumvaluesW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } +}; +static const struct column col_videocontroller[] = +{ + { prop_adapterramW, CIM_UINT32 }, + { prop_currentbitsperpixelW, CIM_UINT32 }, + { prop_currenthorizontalresW, CIM_UINT32 }, + { prop_currentverticalresW, CIM_UINT32 }, + { prop_descriptionW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_pnpdeviceidW, CIM_STRING|COL_FLAG_DYNAMIC } +}; + +static const WCHAR baseboard_manufacturerW[] = + {'I','n','t','e','l',' ','C','o','r','p','o','r','a','t','i','o','n',0}; +static const WCHAR baseboard_serialnumberW[] = + {'N','o','n','e',0}; +static const WCHAR baseboard_tagW[] = + {'B','a','s','e',' ','B','o','a','r','d',0}; +static const WCHAR bios_descriptionW[] = + {'D','e','f','a','u','l','t',' ','S','y','s','t','e','m',' ','B','I','O','S',0}; +static const WCHAR bios_manufacturerW[] = + {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; +static const WCHAR bios_releasedateW[] = + {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; +static const WCHAR bios_serialnumberW[] = + {'0',0}; +static const WCHAR bios_versionW[] = + {'W','I','N','E',' ',' ',' ','-',' ','1',0}; +static const WCHAR cdromdrive_nameW[] = + {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0}; +static const WCHAR cdromdrive_pnpdeviceidW[]= + {'I','D','E','\\','C','D','R','O','M','W','I','N','E','_','C','D','-','R','O','M', + '_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_', + '_','_','_','_','_','_','_','1','.','0','_','_','_','_','_','\\','5','&','3','A','2', + 'A','5','8','5','4','&','0','&','1','.','0','.','0',0}; +static const WCHAR compsys_descriptionW[] = + {'A','T','/','A','T',' ','C','O','M','P','A','T','I','B','L','E',0}; +static const WCHAR compsys_domainW[] = + {'W','O','R','K','G','R','O','U','P',0}; +static const WCHAR compsys_manufacturerW[] = + {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; +static const WCHAR compsys_modelW[] = + {'W','i','n','e',0}; +static const WCHAR diskdrive_deviceidW[] = + {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0}; +static const WCHAR diskdrive_modelW[] = + {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0}; +static const WCHAR diskdrive_manufacturerW[] = + {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0}; +static const WCHAR networkadapter_pnpdeviceidW[]= + {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&', + 'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\', + '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0}; +static const WCHAR os_captionW[] = + {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' ','X','P',' ', + 'V','e','r','s','i','o','n',' ','=',' ','5','.','1','.','2','6','0','0',0}; +static const WCHAR os_csdversionW[] = + {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','3',0}; +static const WCHAR os_32bitW[] = + {'3','2','-','b','i','t',0}; +static const WCHAR os_64bitW[] = + {'6','4','-','b','i','t',0}; +static const WCHAR sounddevice_productnameW[] = + {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0}; +static const WCHAR videocontroller_deviceidW[] = + {'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r','1',0}; + +#include "pshpack1.h" +struct record_baseboard +{ + const WCHAR *manufacturer; + const WCHAR *serialnumber; + const WCHAR *tag; +}; +struct record_bios +{ + const WCHAR *description; + const WCHAR *manufacturer; + const WCHAR *releasedate; + const WCHAR *serialnumber; + const WCHAR *version; +}; +struct record_cdromdrive +{ + const WCHAR *device_id; + const WCHAR *drive; + const WCHAR *name; + const WCHAR *pnpdevice_id; +}; +struct record_computersystem +{ + const WCHAR *description; + const WCHAR *domain; + UINT16 domainrole; + const WCHAR *manufacturer; + const WCHAR *model; + UINT32 num_logical_processors; + UINT32 num_processors; + UINT64 total_physical_memory; +}; +struct record_diskdrive +{ + const WCHAR *device_id; + const WCHAR *manufacturer; + const WCHAR *name; + const WCHAR *serialnumber; +}; +struct record_diskpartition +{ + int bootable; + const WCHAR *device_id; + UINT32 diskindex; + UINT32 index; + const WCHAR *pnpdevice_id; + UINT64 size; + UINT64 startingoffset; + const WCHAR *type; +}; +struct record_logicaldisk +{ + const WCHAR *device_id; + UINT32 drivetype; + const WCHAR *filesystem; + UINT64 freespace; + const WCHAR *name; + UINT64 size; +}; +struct record_networkadapter +{ + const WCHAR *adaptertype; + const WCHAR *device_id; + INT32 interface_index; + const WCHAR *mac_address; + const WCHAR *manufacturer; + UINT16 netconnection_status; + const WCHAR *pnpdevice_id; + UINT64 speed; +}; +struct record_operatingsystem +{ + const WCHAR *caption; + const WCHAR *csdversion; + const WCHAR *lastbootuptime; + const WCHAR *osarchitecture; + UINT32 oslanguage; + const WCHAR *systemdirectory; +}; +struct record_param +{ + const WCHAR *class; + const WCHAR *method; + INT32 direction; + const WCHAR *parameter; + UINT32 type; + UINT32 varianttype; + UINT32 defaultvalue; +}; +struct record_process +{ + const WCHAR *caption; + const WCHAR *commandline; + const WCHAR *description; + const WCHAR *handle; + UINT32 pprocess_id; + UINT32 process_id; + UINT32 thread_count; + /* methods */ + class_method *get_owner; +}; +struct record_processor +{ + UINT16 cpu_status; + const WCHAR *device_id; + const WCHAR *manufacturer; + UINT32 maxclockspeed; + const WCHAR *name; + UINT32 num_logical_processors; + const WCHAR *processor_id; + const WCHAR *unique_id; +}; +struct record_qualifier +{ + const WCHAR *class; + const WCHAR *member; + UINT32 type; + INT32 flavor; + const WCHAR *name; + INT32 intvalue; + const WCHAR *strvalue; +}; +struct record_service +{ + int accept_pause; + int accept_stop; + const WCHAR *displayname; + const WCHAR *name; + UINT32 process_id; + const WCHAR *servicetype; + const WCHAR *startmode; + const WCHAR *state; + const WCHAR *systemname; + /* methods */ + class_method *pause_service; + class_method *resume_service; + class_method *start_service; + class_method *stop_service; +}; +struct record_sounddevice +{ + const WCHAR *productname; +}; +struct record_stdregprov +{ + class_method *enumkey; + class_method *enumvalues; + class_method *getstringvalue; +}; +struct record_videocontroller +{ + UINT32 adapter_ram; + UINT32 current_bitsperpixel; + UINT32 current_horizontalres; + UINT32 current_verticalres; + const WCHAR *description; + const WCHAR *device_id; + const WCHAR *name; + const WCHAR *pnpdevice_id; +}; +#include "poppack.h" + +static const struct record_baseboard data_baseboard[] = +{ + { baseboard_manufacturerW, baseboard_serialnumberW, baseboard_tagW } +}; +static const struct record_bios data_bios[] = +{ + { bios_descriptionW, bios_manufacturerW, bios_releasedateW, bios_serialnumberW, bios_versionW } +}; +static const struct record_diskdrive data_diskdrive[] = +{ + { diskdrive_deviceidW, diskdrive_manufacturerW, diskdrive_modelW } +}; +static const struct record_param data_param[] = +{ + { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_processW, method_getownerW, -1, param_userW, CIM_STRING }, + { class_processW, method_getownerW, -1, param_domainW, CIM_STRING }, + { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, + { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING }, + { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_enumkeyW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY }, + { class_stdregprovW, method_enumvaluesW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, + { class_stdregprovW, method_enumvaluesW, 1, param_subkeynameW, CIM_STRING }, + { class_stdregprovW, method_enumvaluesW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_enumvaluesW, -1, param_namesW, CIM_STRING|CIM_FLAG_ARRAY }, + { class_stdregprovW, method_enumvaluesW, -1, param_typesW, CIM_SINT32|CIM_FLAG_ARRAY }, + { class_stdregprovW, method_getstringvalueW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, + { class_stdregprovW, method_getstringvalueW, 1, param_subkeynameW, CIM_STRING }, + { class_stdregprovW, method_getstringvalueW, 1, param_valuenameW, CIM_STRING }, + { class_stdregprovW, method_getstringvalueW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_stdregprovW, method_getstringvalueW, -1, param_valueW, CIM_STRING } +}; + +#define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\ + WBEM_FLAVOR_ORIGIN_PROPAGATED) + +static const struct record_qualifier data_qualifier[] = +{ + { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 }, + { class_process_getowner_outW, param_domainW, CIM_SINT32, FLAVOR_ID, prop_idW, 1 } +}; +static const struct record_sounddevice data_sounddevice[] = +{ + { sounddevice_productnameW } +}; +static const struct record_stdregprov data_stdregprov[] = +{ + { reg_enum_key, reg_enum_values, reg_get_stringvalue } +}; + +static void fill_cdromdrive( struct table *table ) +{ + static const WCHAR fmtW[] = {'%','c',':',0}; + WCHAR drive[3], root[] = {'A',':','\\',0}; + struct record_cdromdrive *rec; + UINT i, num_rows = 0, offset = 0, count = 1; + DWORD drives = GetLogicalDrives(); + + if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return; + + for (i = 0; i < sizeof(drives); i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + if (GetDriveTypeW( root ) != DRIVE_CDROM) + continue; + + if (num_rows > count) + { + BYTE *data; + count *= 2; + if (!(data = heap_realloc( table->data, count * sizeof(*rec) ))) return; + table->data = data; + } + rec = (struct record_cdromdrive *)(table->data + offset); + rec->device_id = cdromdrive_pnpdeviceidW; + sprintfW( drive, fmtW, 'A' + i ); + rec->drive = heap_strdupW( drive ); + rec->name = cdromdrive_nameW; + rec->pnpdevice_id = cdromdrive_pnpdeviceidW; + offset += sizeof(*rec); + num_rows++; + } + } + TRACE("created %u rows\n", num_rows); + table->num_rows = num_rows; +} + +static UINT get_processor_count(void) +{ + SYSTEM_BASIC_INFORMATION info; + + if (NtQuerySystemInformation( SystemBasicInformation, &info, sizeof(info), NULL )) return 1; + return info.NumberOfProcessors; +} + +static UINT get_logical_processor_count(void) +{ + SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info; + UINT i, j, count = 0; + NTSTATUS status; + ULONG len; + + status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len ); + if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count(); + + if (!(info = heap_alloc( len ))) return get_processor_count(); + status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len ); + if (status != STATUS_SUCCESS) + { + heap_free( info ); + return get_processor_count(); + } + for (i = 0; i < len / sizeof(*info); i++) + { + if (info[i].Relationship != RelationProcessorCore) continue; + for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++; + } + heap_free( info ); + return count; +} + +static UINT64 get_total_physical_memory(void) +{ + MEMORYSTATUSEX status; + + status.dwLength = sizeof(status); + if (!GlobalMemoryStatusEx( &status )) return 1024 * 1024 * 1024; + return status.ullTotalPhys; +} + +static void fill_compsys( struct table *table ) +{ + struct record_computersystem *rec; + + if (!(table->data = heap_alloc( sizeof(*rec) ))) return; + + rec = (struct record_computersystem *)table->data; + rec->description = compsys_descriptionW; + rec->domain = compsys_domainW; + rec->domainrole = 0; /* standalone workstation */ + rec->manufacturer = compsys_manufacturerW; + rec->model = compsys_modelW; + rec->num_logical_processors = get_logical_processor_count(); + rec->num_processors = get_processor_count(); + rec->total_physical_memory = get_total_physical_memory(); + + TRACE("created 1 row\n"); + table->num_rows = 1; +} + +static WCHAR *get_filesystem( const WCHAR *root ) +{ + static const WCHAR ntfsW[] = {'N','T','F','S',0}; + WCHAR buffer[MAX_PATH + 1]; + + if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 )) + return heap_strdupW( buffer ); + return heap_strdupW( ntfsW ); +} + +static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize ) +{ + WCHAR root[] = {'\\','\\','.','\\','A',':',0}; + ULARGE_INTEGER free; + DISK_GEOMETRY_EX info; + HANDLE handle; + + free.QuadPart = 512 * 1024 * 1024; + GetDiskFreeSpaceExW( dir, NULL, NULL, &free ); + + root[4] = dir[0]; + handle = CreateFileW( root, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); + if (handle != INVALID_HANDLE_VALUE) + { + if (DeviceIoControl( handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &info, sizeof(info), NULL, NULL )) + *disksize = info.DiskSize.QuadPart; + CloseHandle( handle ); + } + return free.QuadPart; +} + +static void fill_diskpartition( struct table *table ) +{ + static const WCHAR fmtW[] = + {'D','i','s','k',' ','#','%','u',',',' ','P','a','r','t','i','t','i','o','n',' ','#','0',0}; + WCHAR device_id[32], root[] = {'A',':','\\',0}; + struct record_diskpartition *rec; + UINT i, num_rows = 0, offset = 0, count = 4, type, index = 0; + UINT64 size = 1024 * 1024 * 1024; + DWORD drives = GetLogicalDrives(); + + if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return; + + for (i = 0; i < sizeof(drives); i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + type = GetDriveTypeW( root ); + if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE) + continue; + + if (num_rows > count) + { + BYTE *data; + count *= 2; + if (!(data = heap_realloc( table->data, count * sizeof(*rec) ))) return; + table->data = data; + } + rec = (struct record_diskpartition *)(table->data + offset); + rec->bootable = (i == 2) ? -1 : 0; + sprintfW( device_id, fmtW, index ); + rec->device_id = heap_strdupW( device_id ); + rec->diskindex = index; + rec->index = 0; + rec->pnpdevice_id = heap_strdupW( device_id ); + get_freespace( root, &size ); + rec->size = size; + rec->startingoffset = 0; + rec->type = get_filesystem( root ); + offset += sizeof(*rec); + num_rows++; + index++; + } + } + TRACE("created %u rows\n", num_rows); + table->num_rows = num_rows; +} + +static void fill_logicaldisk( struct table *table ) +{ + static const WCHAR fmtW[] = {'%','c',':',0}; + WCHAR device_id[3], root[] = {'A',':','\\',0}; + struct record_logicaldisk *rec; + UINT i, num_rows = 0, offset = 0, count = 4, type; + UINT64 size = 1024 * 1024 * 1024; + DWORD drives = GetLogicalDrives(); + + if (!(table->data = heap_alloc( count * sizeof(*rec) ))) return; + + for (i = 0; i < sizeof(drives); i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + type = GetDriveTypeW( root ); + if (type != DRIVE_FIXED && type != DRIVE_CDROM && type != DRIVE_REMOVABLE) + continue; + + if (num_rows > count) + { + BYTE *data; + count *= 2; + if (!(data = heap_realloc( table->data, count * sizeof(*rec) ))) return; + table->data = data; + } + rec = (struct record_logicaldisk *)(table->data + offset); + sprintfW( device_id, fmtW, 'A' + i ); + rec->device_id = heap_strdupW( device_id ); + rec->drivetype = type; + rec->filesystem = get_filesystem( root ); + rec->freespace = get_freespace( root, &size ); + rec->name = heap_strdupW( device_id ); + rec->size = size; + offset += sizeof(*rec); + num_rows++; + } + } + TRACE("created %u rows\n", num_rows); + table->num_rows = num_rows; +} + +static UINT16 get_connection_status( IF_OPER_STATUS status ) +{ + switch (status) + { + case IfOperStatusDown: + return 0; /* Disconnected */ + case IfOperStatusUp: + return 2; /* Connected */ + default: + ERR("unhandled status %u\n", status); + break; + } + return 0; +} +static WCHAR *get_mac_address( const BYTE *addr, DWORD len ) +{ + static const WCHAR fmtW[] = + {'%','0','2','x',':','%','0','2','x',':','%','0','2','x',':', + '%','0','2','x',':','%','0','2','x',':','%','0','2','x',0}; + WCHAR *ret; + + if (len != 6 || !(ret = heap_alloc( 18 * sizeof(WCHAR) ))) return NULL; + sprintfW( ret, fmtW, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] ); + return ret; +} +static const WCHAR *get_adaptertype( DWORD type ) +{ + static const WCHAR ethernetW[] = {'E','t','h','e','r','n','e','t',' ','8','0','2','.','3',0}; + static const WCHAR wirelessW[] = {'W','i','r','e','l','e','s','s',0}; + static const WCHAR firewireW[] = {'1','3','9','4',0}; + static const WCHAR tunnelW[] = {'T','u','n','n','e','l',0}; + + switch (type) + { + case IF_TYPE_ETHERNET_CSMACD: return ethernetW; + case IF_TYPE_IEEE80211: return wirelessW; + case IF_TYPE_IEEE1394: return firewireW; + case IF_TYPE_TUNNEL: return tunnelW; + default: break; + } + return NULL; +} + +static void fill_networkadapter( struct table *table ) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR device_id[11]; + struct record_networkadapter *rec; + IP_ADAPTER_ADDRESSES *aa, *buffer; + UINT num_rows = 0, offset = 0; + DWORD size = 0, ret; + + ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ); + if (ret != ERROR_BUFFER_OVERFLOW) return; + + if (!(buffer = heap_alloc( size ))) return; + if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size )) + { + heap_free( buffer ); + return; + } + for (aa = buffer; aa; aa = aa->Next) num_rows++; + if (!(table->data = heap_alloc( sizeof(*rec) * num_rows ))) + { + heap_free( buffer ); + return; + } + for (aa = buffer; aa; aa = aa->Next) + { + rec = (struct record_networkadapter *)(table->data + offset); + sprintfW( device_id, fmtW, aa->u.s.IfIndex ); + rec->adaptertype = get_adaptertype( aa->IfType ); + rec->device_id = heap_strdupW( device_id ); + rec->interface_index = aa->u.s.IfIndex; + rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); + rec->manufacturer = compsys_manufacturerW; + rec->netconnection_status = get_connection_status( aa->OperStatus ); + rec->pnpdevice_id = networkadapter_pnpdeviceidW; + rec->speed = 1000000; + offset += sizeof(*rec); + } + TRACE("created %u rows\n", num_rows); + table->num_rows = num_rows; + + heap_free( buffer ); +} + +static WCHAR *get_cmdline( DWORD process_id ) +{ + if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() ); + return NULL; /* FIXME handle different process case */ +} + +static void fill_process( struct table *table ) +{ + static const WCHAR fmtW[] = {'%','u',0}; + WCHAR handle[11]; + struct record_process *rec; + PROCESSENTRY32W entry; + HANDLE snap; + UINT num_rows = 0, offset = 0, count = 8; + + snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); + if (snap == INVALID_HANDLE_VALUE) return; + + entry.dwSize = sizeof(entry); + if (!Process32FirstW( snap, &entry )) goto done; + if (!(table->data = heap_alloc( count * sizeof(*rec) ))) goto done; + + do + { + if (num_rows > count) + { + BYTE *data; + count *= 2; + if (!(data = heap_realloc( table->data, count * sizeof(*rec) ))) goto done; + table->data = data; + } + rec = (struct record_process *)(table->data + offset); + rec->caption = heap_strdupW( entry.szExeFile ); + rec->commandline = get_cmdline( entry.th32ProcessID ); + rec->description = heap_strdupW( entry.szExeFile ); + sprintfW( handle, fmtW, entry.th32ProcessID ); + rec->handle = heap_strdupW( handle ); + rec->process_id = entry.th32ProcessID; + rec->pprocess_id = entry.th32ParentProcessID; + rec->thread_count = entry.cntThreads; + rec->get_owner = process_get_owner; + offset += sizeof(*rec); + num_rows++; + } while (Process32NextW( snap, &entry )); + + TRACE("created %u rows\n", num_rows); + table->num_rows = num_rows; + +done: + CloseHandle( snap ); +} + +static inline void do_cpuid( unsigned int ax, unsigned int *p ) +{ +#ifdef __i386__ +#ifdef _MSC_VER + __cpuid(p, ax); +#else + __asm__("pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%esi\n\t" + "popl %%ebx" + : "=a" (p[0]), "=S" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (ax)); +#endif +#endif +} + +static void get_processor_id( WCHAR *processor_id ) +{ + static const WCHAR fmtW[] = {'%','0','8','X','%','0','8','X',0}; + unsigned int regs[4] = {0, 0, 0, 0}; + + do_cpuid( 1, regs ); + sprintfW( processor_id, fmtW, regs[3], regs[0] ); +} +static void regs_to_str( unsigned int *regs, unsigned int len, WCHAR *buffer ) +{ + unsigned int i; + unsigned char *p = (unsigned char *)regs; + + for (i = 0; i < len; i++) + { + buffer[i] = *p++; + } + buffer[i] = 0; +} +static void get_processor_manufacturer( WCHAR *manufacturer ) +{ + unsigned int tmp, regs[4] = {0, 0, 0, 0}; + + do_cpuid( 0, regs ); + tmp = regs[2]; /* swap edx and ecx */ + regs[2] = regs[3]; + regs[3] = tmp; + + regs_to_str( regs + 1, 12, manufacturer ); +} +static void get_processor_name( WCHAR *name ) +{ + unsigned int regs[4] = {0, 0, 0, 0}; + + do_cpuid( 0x80000000, regs ); + if (regs[0] >= 0x80000004) + { + do_cpuid( 0x80000002, regs ); + regs_to_str( regs, 16, name ); + do_cpuid( 0x80000003, regs ); + regs_to_str( regs, 16, name + 16 ); + do_cpuid( 0x80000004, regs ); + regs_to_str( regs, 16, name + 32 ); + } +} +static UINT get_processor_maxclockspeed( void ) +{ + PROCESSOR_POWER_INFORMATION *info; + UINT ret = 1000, size = get_processor_count() * sizeof(PROCESSOR_POWER_INFORMATION); + NTSTATUS status; + + if ((info = heap_alloc( size ))) + { + status = NtPowerInformation( ProcessorInformation, NULL, 0, info, size ); + if (!status) ret = info[0].MaxMhz; + heap_free( info ); + } + return ret; +} + +static void fill_processor( struct table *table ) +{ + static const WCHAR fmtW[] = {'C','P','U','%','u',0}; + WCHAR device_id[14], processor_id[17], manufacturer[13], name[49] = {0}; + struct record_processor *rec; + UINT i, offset = 0, maxclockspeed, num_logical_processors, count = get_processor_count(); + + if (!(table->data = heap_alloc( sizeof(*rec) * count ))) return; + + get_processor_id( processor_id ); + get_processor_manufacturer( manufacturer ); + get_processor_name( name ); + + maxclockspeed = get_processor_maxclockspeed(); + num_logical_processors = get_logical_processor_count() / count; + + for (i = 0; i < count; i++) + { + rec = (struct record_processor *)(table->data + offset); + rec->cpu_status = 1; /* CPU Enabled */ + sprintfW( device_id, fmtW, i ); + rec->device_id = heap_strdupW( device_id ); + rec->manufacturer = heap_strdupW( manufacturer ); + rec->maxclockspeed = maxclockspeed; + rec->name = heap_strdupW( name ); + rec->num_logical_processors = num_logical_processors; + rec->processor_id = heap_strdupW( processor_id ); + rec->unique_id = NULL; + offset += sizeof(*rec); + } + + TRACE("created %u rows\n", count); + table->num_rows = count; +} + +static WCHAR *get_lastbootuptime(void) +{ + static const WCHAR fmtW[] = + {'%','0','4','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u','%','0','2','u', + '.','%','0','6','u','+','0','0','0',0}; + SYSTEM_TIMEOFDAY_INFORMATION ti; + TIME_FIELDS tf; + WCHAR *ret; + + if (!(ret = heap_alloc( 26 * sizeof(WCHAR) ))) return NULL; + + NtQuerySystemInformation( SystemTimeOfDayInformation, &ti, sizeof(ti), NULL ); + RtlTimeToTimeFields( &ti.liKeBootTime, &tf ); + sprintfW( ret, fmtW, tf.Year, tf.Month, tf.Day, tf.Hour, tf.Minute, tf.Second, tf.Milliseconds * 1000 ); + return ret; +} +static const WCHAR *get_osarchitecture(void) +{ + SYSTEM_INFO info; + GetNativeSystemInfo( &info ); + if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) return os_64bitW; + return os_32bitW; +} +static WCHAR *get_systemdirectory(void) +{ + void *redir; + WCHAR *ret; + + if (!(ret = heap_alloc( MAX_PATH * sizeof(WCHAR) ))) return NULL; + Wow64DisableWow64FsRedirection( &redir ); + GetSystemDirectoryW( ret, MAX_PATH ); + Wow64RevertWow64FsRedirection( redir ); + return ret; +} + +static void fill_os( struct table *table ) +{ + struct record_operatingsystem *rec; + + if (!(table->data = heap_alloc( sizeof(*rec) ))) return; + + rec = (struct record_operatingsystem *)table->data; + rec->caption = os_captionW; + rec->csdversion = os_csdversionW; + rec->lastbootuptime = get_lastbootuptime(); + rec->osarchitecture = get_osarchitecture(); + rec->oslanguage = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); + rec->systemdirectory = get_systemdirectory(); + + TRACE("created 1 row\n"); + table->num_rows = 1; +} + +static const WCHAR *get_service_type( DWORD type ) +{ + static const WCHAR filesystem_driverW[] = + {'F','i','l','e',' ','S','y','s','t','e','m',' ','D','r','i','v','e','r',0}; + static const WCHAR kernel_driverW[] = + {'K','e','r','n','e','l',' ','D','r','i','v','e','r',0}; + static const WCHAR own_processW[] = + {'O','w','n',' ','P','r','o','c','e','s','s',0}; + static const WCHAR share_processW[] = + {'S','h','a','r','e',' ','P','r','o','c','e','s','s',0}; + + if (type & SERVICE_KERNEL_DRIVER) return kernel_driverW; + else if (type & SERVICE_FILE_SYSTEM_DRIVER) return filesystem_driverW; + else if (type & SERVICE_WIN32_OWN_PROCESS) return own_processW; + else if (type & SERVICE_WIN32_SHARE_PROCESS) return share_processW; + else ERR("unhandled type 0x%08x\n", type); + return NULL; +} +static const WCHAR *get_service_state( DWORD state ) +{ + static const WCHAR runningW[] = + {'R','u','n','n','i','n','g',0}; + static const WCHAR start_pendingW[] = + {'S','t','a','r','t',' ','P','e','n','d','i','n','g',0}; + static const WCHAR stop_pendingW[] = + {'S','t','o','p',' ','P','e','n','d','i','n','g',0}; + static const WCHAR stoppedW[] = + {'S','t','o','p','p','e','d',0}; + static const WCHAR unknownW[] = + {'U','n','k','n','o','w','n',0}; + + switch (state) + { + case SERVICE_STOPPED: return stoppedW; + case SERVICE_START_PENDING: return start_pendingW; + case SERVICE_STOP_PENDING: return stop_pendingW; + case SERVICE_RUNNING: return runningW; + default: + ERR("unknown state %u\n", state); + return unknownW; + } +} + +static const WCHAR *get_service_startmode( DWORD mode ) +{ + static const WCHAR bootW[] = {'B','o','o','t',0}; + static const WCHAR systemW[] = {'S','y','s','t','e','m',0}; + static const WCHAR autoW[] = {'A','u','t','o',0}; + static const WCHAR manualW[] = {'M','a','n','u','a','l',0}; + static const WCHAR disabledW[] = {'D','i','s','a','b','l','e','d',0}; + static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',0}; + + switch (mode) + { + case SERVICE_BOOT_START: return bootW; + case SERVICE_SYSTEM_START: return systemW; + case SERVICE_AUTO_START: return autoW; + case SERVICE_DEMAND_START: return manualW; + case SERVICE_DISABLED: return disabledW; + default: + ERR("unknown mode 0x%x\n", mode); + return unknownW; + } +} + +static QUERY_SERVICE_CONFIGW *query_service_config( SC_HANDLE manager, const WCHAR *name ) +{ + QUERY_SERVICE_CONFIGW *config = NULL; + SC_HANDLE service; + DWORD size; + + if (!(service = OpenServiceW( manager, name, SERVICE_QUERY_CONFIG ))) return NULL; + QueryServiceConfigW( service, NULL, 0, &size ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; + if (!(config = heap_alloc( size ))) goto done; + if (QueryServiceConfigW( service, config, size, &size )) goto done; + heap_free( config ); + config = NULL; + +done: + CloseServiceHandle( service ); + return config; +} + +static void fill_service( struct table *table ) +{ + struct record_service *rec; + SC_HANDLE manager; + ENUM_SERVICE_STATUS_PROCESSW *tmp, *services = NULL; + SERVICE_STATUS_PROCESS *status; + WCHAR sysnameW[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD len = sizeof(sysnameW) / sizeof(sysnameW[0]); + UINT i, num_rows = 0, offset = 0, size = 256, needed, count; + BOOL ret; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) return; + if (!(services = heap_alloc( size ))) goto done; + + ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, + SERVICE_STATE_ALL, (BYTE *)services, size, &needed, + &count, NULL, NULL ); + if (!ret) + { + if (GetLastError() != ERROR_MORE_DATA) goto done; + size = needed; + if (!(tmp = heap_realloc( services, size ))) goto done; + services = tmp; + ret = EnumServicesStatusExW( manager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, + SERVICE_STATE_ALL, (BYTE *)services, size, &needed, + &count, NULL, NULL ); + if (!ret) goto done; + } + if (!(table->data = heap_alloc( sizeof(*rec) * count ))) goto done; + + GetComputerNameW( sysnameW, &len ); + + for (i = 0; i < count; i++) + { + QUERY_SERVICE_CONFIGW *config; + + if (!(config = query_service_config( manager, services[i].lpServiceName ))) continue; + + status = &services[i].ServiceStatusProcess; + rec = (struct record_service *)(table->data + offset); + rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0; + rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0; + rec->displayname = heap_strdupW( services[i].lpDisplayName ); + rec->name = heap_strdupW( services[i].lpServiceName ); + rec->process_id = status->dwProcessId; + rec->servicetype = get_service_type( status->dwServiceType ); + rec->startmode = get_service_startmode( config->dwStartType ); + rec->state = get_service_state( status->dwCurrentState ); + rec->systemname = heap_strdupW( sysnameW ); + rec->pause_service = service_pause_service; + rec->resume_service = service_resume_service; + rec->start_service = service_start_service; + rec->stop_service = service_stop_service; + heap_free( config ); + offset += sizeof(*rec); + num_rows++; + } + + TRACE("created %u rows\n", num_rows); + table->num_rows = num_rows; + +done: + CloseServiceHandle( manager ); + heap_free( services ); +} + +static UINT32 get_bits_per_pixel( UINT *hres, UINT *vres ) +{ + HDC hdc = GetDC( NULL ); + UINT32 ret; + + if (!hdc) return 32; + ret = GetDeviceCaps( hdc, BITSPIXEL ); + *hres = GetDeviceCaps( hdc, HORZRES ); + *vres = GetDeviceCaps( hdc, VERTRES ); + ReleaseDC( NULL, hdc ); + return ret; +} + +static WCHAR *get_pnpdeviceid( DXGI_ADAPTER_DESC *desc ) +{ + static const WCHAR fmtW[] = + {'P','C','I','\\','V','E','N','_','%','0','4','X','&','D','E','V','_','%','0','4','X', + '&','S','U','B','S','Y','S','_','%','0','8','X','&','R','E','V','_','%','0','2','X','\\', + '0','&','D','E','A','D','B','E','E','F','&','0','&','D','E','A','D',0}; + WCHAR *ret; + + if (!(ret = heap_alloc( sizeof(fmtW) + 2 * sizeof(WCHAR) ))) return NULL; + sprintfW( ret, fmtW, desc->VendorId, desc->DeviceId, desc->SubSysId, desc->Revision ); + return ret; +} + +static void fill_videocontroller( struct table *table ) +{ + + struct record_videocontroller *rec; + HRESULT hr; + IDXGIFactory *factory = NULL; + IDXGIAdapter *adapter = NULL; + DXGI_ADAPTER_DESC desc; + UINT hres = 1024, vres = 768, vidmem = 512 * 1024 * 1024; + const WCHAR *name = videocontroller_deviceidW; + + if (!(table->data = heap_alloc( sizeof(*rec) ))) return; + + hr = CreateDXGIFactory( &IID_IDXGIFactory, (void **)&factory ); + if (FAILED(hr)) goto done; + + hr = IDXGIFactory_EnumAdapters( factory, 0, &adapter ); + if (FAILED(hr)) goto done; + + hr = IDXGIAdapter_GetDesc( adapter, &desc ); + if (SUCCEEDED(hr)) + { + vidmem = desc.DedicatedVideoMemory; + name = desc.Description; + } + +done: + rec = (struct record_videocontroller *)table->data; + rec->adapter_ram = vidmem; + rec->current_bitsperpixel = get_bits_per_pixel( &hres, &vres ); + rec->current_horizontalres = hres; + rec->current_verticalres = vres; + rec->description = heap_strdupW( name ); + rec->device_id = videocontroller_deviceidW; + rec->name = heap_strdupW( name ); + rec->pnpdevice_id = get_pnpdeviceid( &desc ); + + TRACE("created 1 row\n"); + table->num_rows = 1; + + if (adapter) IDXGIAdapter_Release( adapter ); + if (factory) IDXGIFactory_Release( factory ); +} + +static struct table builtin_classes[] = +{ + { class_baseboardW, SIZEOF(col_baseboard), col_baseboard, SIZEOF(data_baseboard), (BYTE *)data_baseboard }, + { class_biosW, SIZEOF(col_bios), col_bios, SIZEOF(data_bios), (BYTE *)data_bios }, + { class_cdromdriveW, SIZEOF(col_cdromdrive), col_cdromdrive, 0, NULL, fill_cdromdrive }, + { class_compsysW, SIZEOF(col_compsys), col_compsys, 0, NULL, fill_compsys }, + { class_diskdriveW, SIZEOF(col_diskdrive), col_diskdrive, SIZEOF(data_diskdrive), (BYTE *)data_diskdrive }, + { class_diskpartitionW, SIZEOF(col_diskpartition), col_diskpartition, 0, NULL, fill_diskpartition }, + { class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, NULL, fill_logicaldisk }, + { class_networkadapterW, SIZEOF(col_networkadapter), col_networkadapter, 0, NULL, fill_networkadapter }, + { class_osW, SIZEOF(col_os), col_os, 0, NULL, fill_os }, + { class_paramsW, SIZEOF(col_param), col_param, SIZEOF(data_param), (BYTE *)data_param }, + { class_processW, SIZEOF(col_process), col_process, 0, NULL, fill_process }, + { class_processorW, SIZEOF(col_processor), col_processor, 0, NULL, fill_processor }, + { class_qualifiersW, SIZEOF(col_qualifier), col_qualifier, SIZEOF(data_qualifier), (BYTE *)data_qualifier }, + { class_serviceW, SIZEOF(col_service), col_service, 0, NULL, fill_service }, + { class_sounddeviceW, SIZEOF(col_sounddevice), col_sounddevice, SIZEOF(data_sounddevice), (BYTE *)data_sounddevice }, + { class_stdregprovW, SIZEOF(col_stdregprov), col_stdregprov, SIZEOF(data_stdregprov), (BYTE *)data_stdregprov }, + { class_videocontrollerW, SIZEOF(col_videocontroller), col_videocontroller, 0, NULL, fill_videocontroller } +}; + +void init_table_list( void ) +{ + static struct list tables = LIST_INIT( tables ); + UINT i; + + for (i = 0; i < SIZEOF(builtin_classes); i++) list_add_tail( &tables, &builtin_classes[i].entry ); + table_list = &tables; +} diff --git a/dll/win32/wbemprox/class.c b/dll/win32/wbemprox/class.c new file mode 100644 index 00000000000..3bbd0b1ba18 --- /dev/null +++ b/dll/win32/wbemprox/class.c @@ -0,0 +1,1039 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +struct enum_class_object +{ + IEnumWbemClassObject IEnumWbemClassObject_iface; + LONG refs; + struct query *query; + UINT index; +}; + +static inline struct enum_class_object *impl_from_IEnumWbemClassObject( + IEnumWbemClassObject *iface ) +{ + return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface); +} + +static ULONG WINAPI enum_class_object_AddRef( + IEnumWbemClassObject *iface ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + return InterlockedIncrement( &ec->refs ); +} + +static ULONG WINAPI enum_class_object_Release( + IEnumWbemClassObject *iface ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + LONG refs = InterlockedDecrement( &ec->refs ); + if (!refs) + { + TRACE("destroying %p\n", ec); + release_query( ec->query ); + heap_free( ec ); + } + return refs; +} + +static HRESULT WINAPI enum_class_object_QueryInterface( + IEnumWbemClassObject *iface, + REFIID riid, + void **ppvObject ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = ec; + } + else if ( IsEqualGUID( riid, &IID_IClientSecurity ) ) + { + *ppvObject = &client_security; + return S_OK; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IEnumWbemClassObject_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI enum_class_object_Reset( + IEnumWbemClassObject *iface ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + + TRACE("%p\n", iface); + + ec->index = 0; + return WBEM_S_NO_ERROR; +} + +static HRESULT WINAPI enum_class_object_Next( + IEnumWbemClassObject *iface, + LONG lTimeout, + ULONG uCount, + IWbemClassObject **apObjects, + ULONG *puReturned ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + struct view *view = ec->query->view; + HRESULT hr; + + TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned); + + if (!uCount) return WBEM_S_FALSE; + if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER; + if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n"); + + *puReturned = 0; + if (ec->index >= view->count) return WBEM_S_FALSE; + + hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects ); + if (hr != S_OK) return hr; + + ec->index++; + *puReturned = 1; + if (ec->index == view->count) return WBEM_S_FALSE; + if (uCount > 1) return WBEM_S_TIMEDOUT; + return WBEM_S_NO_ERROR; +} + +static HRESULT WINAPI enum_class_object_NextAsync( + IEnumWbemClassObject *iface, + ULONG uCount, + IWbemObjectSink *pSink ) +{ + FIXME("%p, %u, %p\n", iface, uCount, pSink); + return E_NOTIMPL; +} + +static HRESULT WINAPI enum_class_object_Clone( + IEnumWbemClassObject *iface, + IEnumWbemClassObject **ppEnum ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + + TRACE("%p, %p\n", iface, ppEnum); + + return EnumWbemClassObject_create( NULL, ec->query, (void **)ppEnum ); +} + +static HRESULT WINAPI enum_class_object_Skip( + IEnumWbemClassObject *iface, + LONG lTimeout, + ULONG nCount ) +{ + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); + struct view *view = ec->query->view; + + TRACE("%p, %d, %u\n", iface, lTimeout, nCount); + + if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n"); + + if (!view->count) return WBEM_S_FALSE; + + if (nCount > view->count - ec->index) + { + ec->index = view->count - 1; + return WBEM_S_FALSE; + } + ec->index += nCount; + return WBEM_S_NO_ERROR; +} + +static const IEnumWbemClassObjectVtbl enum_class_object_vtbl = +{ + enum_class_object_QueryInterface, + enum_class_object_AddRef, + enum_class_object_Release, + enum_class_object_Reset, + enum_class_object_Next, + enum_class_object_NextAsync, + enum_class_object_Clone, + enum_class_object_Skip +}; + +HRESULT EnumWbemClassObject_create( + IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj ) +{ + struct enum_class_object *ec; + + TRACE("%p, %p\n", pUnkOuter, ppObj); + + ec = heap_alloc( sizeof(*ec) ); + if (!ec) return E_OUTOFMEMORY; + + ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl; + ec->refs = 1; + ec->query = addref_query( query ); + ec->index = 0; + + *ppObj = &ec->IEnumWbemClassObject_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + +static struct record *create_record( struct table *table ) +{ + UINT i; + struct record *record; + + if (!(record = heap_alloc( sizeof(struct record) ))) return NULL; + if (!(record->fields = heap_alloc( table->num_cols * sizeof(struct field) ))) + { + heap_free( record ); + return NULL; + } + for (i = 0; i < table->num_cols; i++) + { + record->fields[i].type = table->columns[i].type; + record->fields[i].vartype = table->columns[i].vartype; + record->fields[i].u.ival = 0; + } + record->count = table->num_cols; + record->table = addref_table( table ); + return record; +} + +void destroy_array( struct array *array, CIMTYPE type ) +{ + UINT i, size; + + if (!array) return; + if (type == CIM_STRING || type == CIM_DATETIME) + { + size = get_type_size( type ); + for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * size) ); + } + heap_free( array->ptr ); + heap_free( array ); +} + +static void destroy_record( struct record *record ) +{ + UINT i; + + if (!record) return; + release_table( record->table ); + for (i = 0; i < record->count; i++) + { + if (record->fields[i].type == CIM_STRING || record->fields[i].type == CIM_DATETIME) + heap_free( record->fields[i].u.sval ); + else if (record->fields[i].type & CIM_FLAG_ARRAY) + destroy_array( record->fields[i].u.aval, record->fields[i].type & CIM_TYPE_MASK ); + } + heap_free( record->fields ); + heap_free( record ); +} + +struct class_object +{ + IWbemClassObject IWbemClassObject_iface; + LONG refs; + WCHAR *name; + IEnumWbemClassObject *iter; + UINT index; + UINT index_method; + UINT index_property; + struct record *record; /* uncommitted instance */ +}; + +static inline struct class_object *impl_from_IWbemClassObject( + IWbemClassObject *iface ) +{ + return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface); +} + +static ULONG WINAPI class_object_AddRef( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + return InterlockedIncrement( &co->refs ); +} + +static ULONG WINAPI class_object_Release( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + LONG refs = InterlockedDecrement( &co->refs ); + if (!refs) + { + TRACE("destroying %p\n", co); + if (co->iter) IEnumWbemClassObject_Release( co->iter ); + destroy_record( co->record ); + heap_free( co->name ); + heap_free( co ); + } + return refs; +} + +static HRESULT WINAPI class_object_QueryInterface( + IWbemClassObject *iface, + REFIID riid, + void **ppvObject ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemClassObject ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = co; + } + else if (IsEqualGUID( riid, &IID_IClientSecurity )) + { + *ppvObject = &client_security; + return S_OK; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemClassObject_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI class_object_GetQualifierSet( + IWbemClassObject *iface, + IWbemQualifierSet **ppQualSet ) +{ + FIXME("%p, %p\n", iface, ppQualSet); + return E_NOTIMPL; +} + +static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type ) +{ + VARTYPE vartype = record->fields[index].vartype; + + if (type) *type = record->fields[index].type; + + if (record->fields[index].type & CIM_FLAG_ARRAY) + { + V_VT( var ) = vartype ? vartype : to_vartype( record->fields[index].type & CIM_TYPE_MASK ) | VT_ARRAY; + V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & CIM_TYPE_MASK ); + return S_OK; + } + switch (record->fields[index].type) + { + case CIM_STRING: + case CIM_DATETIME: + if (!vartype) vartype = VT_BSTR; + V_BSTR( var ) = SysAllocString( record->fields[index].u.sval ); + break; + case CIM_SINT32: + if (!vartype) vartype = VT_I4; + V_I4( var ) = record->fields[index].u.ival; + break; + case CIM_UINT32: + if (!vartype) vartype = VT_UI4; + V_UI4( var ) = record->fields[index].u.ival; + break; + default: + FIXME("unhandled type %u\n", record->fields[index].type); + return WBEM_E_INVALID_PARAMETER; + } + V_VT( var ) = vartype; + return S_OK; +} + +static HRESULT WINAPI class_object_Get( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + VARIANT *pVal, + CIMTYPE *pType, + LONG *plFlavor ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + + TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor); + + if (co->record) + { + UINT index; + HRESULT hr; + + if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr; + return record_get_value( co->record, index, pVal, pType ); + } + return get_propval( ec->query->view, co->index, wszName, pVal, pType, plFlavor ); +} + +static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var ) +{ + LONGLONG val; + CIMTYPE type; + HRESULT hr; + + if ((hr = to_longlong( var, &val, &type )) != S_OK) return hr; + if (type != record->fields[index].type) return WBEM_E_TYPE_MISMATCH; + + if (type & CIM_FLAG_ARRAY) + { + record->fields[index].u.aval = (struct array *)(INT_PTR)val; + return S_OK; + } + switch (type) + { + case CIM_STRING: + case CIM_DATETIME: + record->fields[index].u.sval = (WCHAR *)(INT_PTR)val; + return S_OK; + case CIM_SINT16: + case CIM_UINT16: + case CIM_SINT32: + case CIM_UINT32: + record->fields[index].u.ival = val; + return S_OK; + default: + FIXME("unhandled type %u\n", type); + break; + } + return WBEM_E_INVALID_PARAMETER; +} + +static HRESULT WINAPI class_object_Put( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + VARIANT *pVal, + CIMTYPE Type ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + + TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type); + + if (co->record) + { + UINT index; + HRESULT hr; + + if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr; + return record_set_value( co->record, index, pVal ); + } + return put_propval( ec->query->view, co->index, wszName, pVal, Type ); +} + +static HRESULT WINAPI class_object_Delete( + IWbemClassObject *iface, + LPCWSTR wszName ) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_GetNames( + IWbemClassObject *iface, + LPCWSTR wszQualifierName, + LONG lFlags, + VARIANT *pQualifierVal, + SAFEARRAY **pNames ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + + TRACE("%p, %s, %08x, %s, %p\n", iface, debugstr_w(wszQualifierName), lFlags, + debugstr_variant(pQualifierVal), pNames); + + if (wszQualifierName || pQualifierVal) + { + FIXME("qualifier not supported\n"); + return E_NOTIMPL; + } + if (lFlags != WBEM_FLAG_ALWAYS) + { + FIXME("flags %08x not supported\n", lFlags); + return E_NOTIMPL; + } + return get_properties( ec->query->view, pNames ); +} + +static HRESULT WINAPI class_object_BeginEnumeration( + IWbemClassObject *iface, + LONG lEnumFlags ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %08x\n", iface, lEnumFlags); + + if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags); + + co->index_property = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_Next( + IWbemClassObject *iface, + LONG lFlags, + BSTR *strName, + VARIANT *pVal, + CIMTYPE *pType, + LONG *plFlavor ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + struct view *view = ec->query->view; + BSTR property; + HRESULT hr; + + TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor); + + if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA; + if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK)) + { + SysFreeString( property ); + return hr; + } + *strName = property; + co->index_property++; + return S_OK; +} + +static HRESULT WINAPI class_object_EndEnumeration( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p\n", iface); + + co->index_property = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_GetPropertyQualifierSet( + IWbemClassObject *iface, + LPCWSTR wszProperty, + IWbemQualifierSet **ppQualSet ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); + + return WbemQualifierSet_create( NULL, co->name, wszProperty, (void **)ppQualSet ); +} + +static HRESULT WINAPI class_object_Clone( + IWbemClassObject *iface, + IWbemClassObject **ppCopy ) +{ + FIXME("%p, %p\n", iface, ppCopy); + return E_NOTIMPL; +} + +static BSTR get_body_text( const struct table *table, UINT row, UINT *len ) +{ + static const WCHAR fmtW[] = {'\n','\t','%','s',' ','=',' ','%','s',';',0}; + BSTR value, ret; + WCHAR *p; + UINT i; + + *len = 0; + for (i = 0; i < table->num_cols; i++) + { + if ((value = get_value_bstr( table, row, i ))) + { + *len += sizeof(fmtW) / sizeof(fmtW[0]); + *len += strlenW( table->columns[i].name ); + *len += SysStringLen( value ); + SysFreeString( value ); + } + } + if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL; + p = ret; + for (i = 0; i < table->num_cols; i++) + { + if ((value = get_value_bstr( table, row, i ))) + { + p += sprintfW( p, fmtW, table->columns[i].name, value ); + SysFreeString( value ); + } + } + return ret; +} + +static BSTR get_object_text( const struct view *view, UINT index ) +{ + static const WCHAR fmtW[] = + {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0}; + UINT len, len_body, row = view->result[index]; + BSTR ret, body; + + len = sizeof(fmtW) / sizeof(fmtW[0]); + len += strlenW( view->table->name ); + if (!(body = get_body_text( view->table, row, &len_body ))) return NULL; + len += len_body; + + if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; + sprintfW( ret, fmtW, view->table->name, body ); + SysFreeString( body ); + return ret; +} + +static HRESULT WINAPI class_object_GetObjectText( + IWbemClassObject *iface, + LONG lFlags, + BSTR *pstrObjectText ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + struct view *view = ec->query->view; + BSTR text; + + TRACE("%p, %08x, %p\n", iface, lFlags, pstrObjectText); + + if (lFlags) FIXME("flags %08x not implemented\n", lFlags); + + if (!(text = get_object_text( view, co->index ))) return E_OUTOFMEMORY; + *pstrObjectText = text; + return S_OK; +} + +static HRESULT WINAPI class_object_SpawnDerivedClass( + IWbemClassObject *iface, + LONG lFlags, + IWbemClassObject **ppNewClass ) +{ + FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_SpawnInstance( + IWbemClassObject *iface, + LONG lFlags, + IWbemClassObject **ppNewInstance ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); + struct view *view = ec->query->view; + struct record *record; + + TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance); + + if (!(record = create_record( view->table ))) return E_OUTOFMEMORY; + + return create_class_object( co->name, NULL, 0, record, ppNewInstance ); +} + +static HRESULT WINAPI class_object_CompareTo( + IWbemClassObject *iface, + LONG lFlags, + IWbemClassObject *pCompareTo ) +{ + FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_GetPropertyOrigin( + IWbemClassObject *iface, + LPCWSTR wszName, + BSTR *pstrClassName ) +{ + FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_InheritsFrom( + IWbemClassObject *iface, + LPCWSTR strAncestor ) +{ + FIXME("%p, %s\n", iface, debugstr_w(strAncestor)); + return E_NOTIMPL; +} + +static UINT count_instances( IEnumWbemClassObject *iter ) +{ + UINT count = 0; + while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++; + IEnumWbemClassObject_Reset( iter ); + return count; +} + +static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr ) +{ + switch (type) + { + case CIM_SINT16: + *(INT16 *)ptr = val; + break; + case CIM_UINT16: + *(UINT16 *)ptr = val; + break; + case CIM_SINT32: + *(INT32 *)ptr = val; + break; + case CIM_UINT32: + *(UINT32 *)ptr = val; + break; + default: + FIXME("unhandled type %u\n", type); + break; + } +} + +static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols, + struct column **cols, BYTE **data ) +{ + static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0}; + static const WCHAR typeW[] = {'T','y','p','e',0}; + static const WCHAR varianttypeW[] = {'V','a','r','i','a','n','t','T','y','p','e',0}; + static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0}; + struct column *columns; + BYTE *row; + IWbemClassObject *param; + VARIANT val; + HRESULT hr = E_OUTOFMEMORY; + UINT offset = 0; + ULONG count; + int i = 0; + + count = count_instances( iter ); + if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY; + if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error; + + for (;;) + { + IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, ¶m, &count ); + if (!count) break; + + hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + columns[i].name = heap_strdupW( V_BSTR( &val ) ); + VariantClear( &val ); + + hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + columns[i].type = V_UI4( &val ); + + hr = IWbemClassObject_Get( param, varianttypeW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + columns[i].vartype = V_UI4( &val ); + + hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL ); + if (hr != S_OK) goto error; + if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset ); + offset += get_type_size( columns[i].type ); + + IWbemClassObject_Release( param ); + i++; + } + *num_cols = i; + *cols = columns; + *data = row; + return S_OK; + +error: + for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name ); + heap_free( columns ); + heap_free( row ); + return hr; +} + +static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name ) +{ + HRESULT hr; + struct table *table; + struct column *columns; + UINT num_cols; + BYTE *row; + + hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row ); + if (hr != S_OK) return hr; + + if (!(table = create_table( name, num_cols, columns, 1, row, NULL ))) + { + free_columns( columns, num_cols ); + heap_free( row ); + return E_OUTOFMEMORY; + } + if (!add_table( table )) free_table( table ); /* already exists */ + return S_OK; +} + +static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir ) +{ + static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0}; + static const WCHAR outW[] = {'O','U','T',0}; + static const WCHAR inW[] = {'I','N',0}; + UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method ); + WCHAR *ret; + + if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL; + sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW ); + return struprW( ret ); +} + +HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir, + IWbemClassObject **sig ) +{ + static const WCHAR selectW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', + '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ', + 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ', + 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ', + 'D','i','r','e','c','t','i','o','n','%','s',0}; + static const WCHAR geW[] = {'>','=','0',0}; + static const WCHAR leW[] = {'<','=','0',0}; + UINT len = SIZEOF(selectW) + SIZEOF(geW); + IEnumWbemClassObject *iter; + WCHAR *query, *name; + HRESULT hr; + + len += strlenW( class ) + strlenW( method ); + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW ); + + hr = exec_query( query, &iter ); + heap_free( query ); + if (hr != S_OK) return hr; + + if (!(name = build_signature_table_name( class, method, dir ))) + { + IEnumWbemClassObject_Release( iter ); + return E_OUTOFMEMORY; + } + hr = create_signature_table( iter, name ); + IEnumWbemClassObject_Release( iter ); + if (hr == S_OK) + hr = get_object( name, sig ); + + heap_free( name ); + return hr; +} + +static HRESULT WINAPI class_object_GetMethod( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + IWbemClassObject **ppInSignature, + IWbemClassObject **ppOutSignature ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + IWbemClassObject *in, *out; + HRESULT hr; + + TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature); + + hr = create_signature( co->name, wszName, PARAM_IN, &in ); + if (hr != S_OK) return hr; + + hr = create_signature( co->name, wszName, PARAM_OUT, &out ); + if (hr == S_OK) + { + if (ppInSignature) *ppInSignature = in; + else IWbemClassObject_Release( in ); + if (ppOutSignature) *ppOutSignature = out; + else IWbemClassObject_Release( out ); + } + else IWbemClassObject_Release( in ); + return hr; +} + +static HRESULT WINAPI class_object_PutMethod( + IWbemClassObject *iface, + LPCWSTR wszName, + LONG lFlags, + IWbemClassObject *pInSignature, + IWbemClassObject *pOutSignature ) +{ + FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_DeleteMethod( + IWbemClassObject *iface, + LPCWSTR wszName ) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_BeginMethodEnumeration( + IWbemClassObject *iface, + LONG lEnumFlags) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p, %08x\n", iface, lEnumFlags); + + if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags); + + if (co->iter) + { + WARN("not allowed on instance\n"); + return WBEM_E_ILLEGAL_OPERATION; + } + co->index_method = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_NextMethod( + IWbemClassObject *iface, + LONG lFlags, + BSTR *pstrName, + IWbemClassObject **ppInSignature, + IWbemClassObject **ppOutSignature) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + BSTR method; + HRESULT hr; + + TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature); + + if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA; + + hr = create_signature( co->name, method, PARAM_IN, ppInSignature ); + if (hr != S_OK) + { + SysFreeString( method ); + return hr; + } + hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature ); + if (hr != S_OK) + { + SysFreeString( method ); + IWbemClassObject_Release( *ppInSignature ); + } + else + { + *pstrName = method; + co->index_method++; + } + return hr; +} + +static HRESULT WINAPI class_object_EndMethodEnumeration( + IWbemClassObject *iface ) +{ + struct class_object *co = impl_from_IWbemClassObject( iface ); + + TRACE("%p\n", iface); + + co->index_method = 0; + return S_OK; +} + +static HRESULT WINAPI class_object_GetMethodQualifierSet( + IWbemClassObject *iface, + LPCWSTR wszMethod, + IWbemQualifierSet **ppQualSet) +{ + FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet); + return E_NOTIMPL; +} + +static HRESULT WINAPI class_object_GetMethodOrigin( + IWbemClassObject *iface, + LPCWSTR wszMethodName, + BSTR *pstrClassName) +{ + FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName); + return E_NOTIMPL; +} + +static const IWbemClassObjectVtbl class_object_vtbl = +{ + class_object_QueryInterface, + class_object_AddRef, + class_object_Release, + class_object_GetQualifierSet, + class_object_Get, + class_object_Put, + class_object_Delete, + class_object_GetNames, + class_object_BeginEnumeration, + class_object_Next, + class_object_EndEnumeration, + class_object_GetPropertyQualifierSet, + class_object_Clone, + class_object_GetObjectText, + class_object_SpawnDerivedClass, + class_object_SpawnInstance, + class_object_CompareTo, + class_object_GetPropertyOrigin, + class_object_InheritsFrom, + class_object_GetMethod, + class_object_PutMethod, + class_object_DeleteMethod, + class_object_BeginMethodEnumeration, + class_object_NextMethod, + class_object_EndMethodEnumeration, + class_object_GetMethodQualifierSet, + class_object_GetMethodOrigin +}; + +HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index, + struct record *record, IWbemClassObject **obj ) +{ + struct class_object *co; + + TRACE("%s, %p\n", debugstr_w(name), obj); + + co = heap_alloc( sizeof(*co) ); + if (!co) return E_OUTOFMEMORY; + + co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl; + co->refs = 1; + if (!name) co->name = NULL; + else if (!(co->name = heap_strdupW( name ))) + { + heap_free( co ); + return E_OUTOFMEMORY; + } + co->iter = iter; + co->index = index; + co->index_method = 0; + co->index_property = 0; + co->record = record; + if (iter) IEnumWbemClassObject_AddRef( iter ); + + *obj = &co->IWbemClassObject_iface; + + TRACE("returning iface %p\n", *obj); + return S_OK; +} diff --git a/dll/win32/wbemprox/main.c b/dll/win32/wbemprox/main.c new file mode 100644 index 00000000000..cbdc742f12b --- /dev/null +++ b/dll/win32/wbemprox/main.c @@ -0,0 +1,180 @@ +/* + * + * Copyright 2009 Austin English + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include "config.h" + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" +#include "wbemprov.h" +#include "rpcproxy.h" + +#include "wbemprox_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +static HINSTANCE instance; + +typedef HRESULT (*fnCreateInstance)( IUnknown *pUnkOuter, LPVOID *ppObj ); + +typedef struct +{ + IClassFactory IClassFactory_iface; + fnCreateInstance pfnCreateInstance; +} wbemprox_cf; + +static inline wbemprox_cf *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD(iface, wbemprox_cf, IClassFactory_iface); +} + +static HRESULT WINAPI wbemprox_cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI wbemprox_cf_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI wbemprox_cf_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI wbemprox_cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter, + REFIID riid, LPVOID *ppobj ) +{ + wbemprox_cf *This = impl_from_IClassFactory( iface ); + HRESULT r; + IUnknown *punk; + + TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (pOuter) + return CLASS_E_NOAGGREGATION; + + r = This->pfnCreateInstance( pOuter, (LPVOID *)&punk ); + if (FAILED(r)) + return r; + + r = IUnknown_QueryInterface( punk, riid, ppobj ); + if (FAILED(r)) + return r; + + IUnknown_Release( punk ); + return r; +} + +static HRESULT WINAPI wbemprox_cf_LockServer( IClassFactory *iface, BOOL dolock ) +{ + FIXME("(%p)->(%d)\n", iface, dolock); + return S_OK; +} + +static const struct IClassFactoryVtbl wbemprox_cf_vtbl = +{ + wbemprox_cf_QueryInterface, + wbemprox_cf_AddRef, + wbemprox_cf_Release, + wbemprox_cf_CreateInstance, + wbemprox_cf_LockServer +}; + +static wbemprox_cf wbem_locator_cf = { { &wbemprox_cf_vtbl }, WbemLocator_create }; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + switch (fdwReason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + instance = hinstDLL; + DisableThreadLibraryCalls(hinstDLL); + init_table_list(); + break; + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) +{ + IClassFactory *cf = NULL; + + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID( rclsid, &CLSID_WbemLocator ) || + IsEqualGUID( rclsid, &CLSID_WbemAdministrativeLocator )) + { + cf = &wbem_locator_cf.IClassFactory_iface; + } + if (!cf) return CLASS_E_CLASSNOTAVAILABLE; + return IClassFactory_QueryInterface( cf, iid, ppv ); +} + +/*********************************************************************** + * DllCanUnloadNow (WBEMPROX.@) + */ +HRESULT WINAPI DllCanUnloadNow( void ) +{ + return S_FALSE; +} + +/*********************************************************************** + * DllRegisterServer (WBEMPROX.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (WBEMPROX.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/dll/win32/wbemprox/process.c b/dll/win32/wbemprox/process.c new file mode 100644 index 00000000000..011d30c6863 --- /dev/null +++ b/dll/win32/wbemprox/process.c @@ -0,0 +1,108 @@ +/* + * Win32_Process methods implementation + * + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +static HRESULT get_owner( VARIANT *user, VARIANT *domain, VARIANT *retval ) +{ + DWORD len; + UINT error = 8; + + len = 0; + GetUserNameW( NULL, &len ); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done; + if (!(V_BSTR( user ) = heap_alloc( len * sizeof(WCHAR) ))) goto done; + if (!GetUserNameW( V_BSTR( user ), &len )) goto done; + V_VT( user ) = VT_BSTR; + + len = 0; + GetComputerNameW( NULL, &len ); + if (GetLastError() != ERROR_BUFFER_OVERFLOW) goto done; + if (!(V_BSTR( domain ) = heap_alloc( len * sizeof(WCHAR) ))) goto done; + if (!GetComputerNameW( V_BSTR( domain ), &len )) goto done; + V_VT( domain ) = VT_BSTR; + + error = 0; + +done: + if (error) + { + VariantClear( user ); + VariantClear( domain ); + } + set_variant( VT_UI4, error, NULL, retval ); + return S_OK; +} + +HRESULT process_get_owner( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT user, domain, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = create_signature( class_processW, method_getownerW, PARAM_OUT, &sig ); + if (hr != S_OK) return hr; + + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + IWbemClassObject_Release( sig ); + return hr; + } + VariantInit( &user ); + VariantInit( &domain ); + hr = get_owner( &user, &domain, &retval ); + if (hr != S_OK) goto done; + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( *out, param_userW, 0, &user, CIM_STRING ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_domainW, 0, &domain, CIM_STRING ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &user ); + VariantClear( &domain ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} diff --git a/dll/win32/wbemprox/qualifier.c b/dll/win32/wbemprox/qualifier.c new file mode 100644 index 00000000000..b2ed44fb112 --- /dev/null +++ b/dll/win32/wbemprox/qualifier.c @@ -0,0 +1,283 @@ +/* + * Copyright 2013 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +struct qualifier_set +{ + IWbemQualifierSet IWbemQualifierSet_iface; + LONG refs; + WCHAR *class; + WCHAR *member; +}; + +static inline struct qualifier_set *impl_from_IWbemQualifierSet( + IWbemQualifierSet *iface ) +{ + return CONTAINING_RECORD(iface, struct qualifier_set, IWbemQualifierSet_iface); +} + +static ULONG WINAPI qualifier_set_AddRef( + IWbemQualifierSet *iface ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + return InterlockedIncrement( &set->refs ); +} + +static ULONG WINAPI qualifier_set_Release( + IWbemQualifierSet *iface ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + LONG refs = InterlockedDecrement( &set->refs ); + if (!refs) + { + TRACE("destroying %p\n", set); + heap_free( set->class ); + heap_free( set->member ); + heap_free( set ); + } + return refs; +} + +static HRESULT WINAPI qualifier_set_QueryInterface( + IWbemQualifierSet *iface, + REFIID riid, + void **ppvObject ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + + TRACE("%p, %s, %p\n", set, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemQualifierSet ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = set; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemQualifierSet_AddRef( iface ); + return S_OK; +} + +static HRESULT create_qualifier_enum( const WCHAR *class, const WCHAR *member, const WCHAR *name, + IEnumWbemClassObject **iter ) +{ + static const WCHAR fmtW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L', + 'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=', + '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',' ', + 'A','N','D',' ','N','a','m','e','=','\'','%','s','\'',0}; + static const WCHAR fmt2W[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','_','_','Q','U','A','L', + 'I','F','I','E','R','S',' ','W','H','E','R','E',' ','C','l','a','s','s','=', + '\'','%','s','\'',' ','A','N','D',' ','M','e','m','b','e','r','=','\'','%','s','\'',0}; + static const WCHAR noneW[] = {'_','_','N','O','N','E',0}; + WCHAR *query; + HRESULT hr; + int len; + + if (!member) member = noneW; + len = strlenW( class ) + strlenW( member ); + if (name) len += strlenW( name ) + SIZEOF(fmtW); + else len += SIZEOF(fmt2W); + + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + if (name) sprintfW( query, fmtW, class, member, name ); + else sprintfW( query, fmt2W, class, member ); + + hr = exec_query( query, iter ); + heap_free( query ); + return hr; +} + +static HRESULT get_qualifier_value( const WCHAR *class, const WCHAR *member, const WCHAR *name, + VARIANT *val, LONG *flavor ) +{ + static const WCHAR qualifiersW[] = {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; + static const WCHAR intvalueW[] = {'I','n','t','e','g','e','r','V','a','l','u','e',0}; + static const WCHAR strvalueW[] = {'S','t','r','i','n','g','V','a','l','u','e',0}; + static const WCHAR flavorW[] = {'F','l','a','v','o','r',0}; + static const WCHAR typeW[] = {'T','y','p','e',0}; + IEnumWbemClassObject *iter; + IWbemClassObject *obj; + VARIANT var; + HRESULT hr; + + hr = create_qualifier_enum( class, member, name, &iter ); + if (FAILED( hr )) return hr; + + hr = create_class_object( qualifiersW, iter, 0, NULL, &obj ); + IEnumWbemClassObject_Release( iter ); + if (FAILED( hr )) return hr; + + if (flavor) + { + hr = IWbemClassObject_Get( obj, flavorW, 0, &var, NULL, NULL ); + if (hr != S_OK) goto done; + *flavor = V_I4( &var ); + } + hr = IWbemClassObject_Get( obj, typeW, 0, &var, NULL, NULL ); + if (hr != S_OK) goto done; + switch (V_UI4( &var )) + { + case CIM_STRING: + hr = IWbemClassObject_Get( obj, strvalueW, 0, val, NULL, NULL ); + break; + case CIM_SINT32: + hr = IWbemClassObject_Get( obj, intvalueW, 0, val, NULL, NULL ); + break; + default: + ERR("unhandled type %u\n", V_UI4( &var )); + break; + } + +done: + IWbemClassObject_Release( obj ); + return hr; +} + +static HRESULT WINAPI qualifier_set_Get( + IWbemQualifierSet *iface, + LPCWSTR wszName, + LONG lFlags, + VARIANT *pVal, + LONG *plFlavor ) +{ + struct qualifier_set *set = impl_from_IWbemQualifierSet( iface ); + + FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, plFlavor); + return get_qualifier_value( set->class, set->member, wszName, pVal, plFlavor ); +} + +static HRESULT WINAPI qualifier_set_Put( + IWbemQualifierSet *iface, + LPCWSTR wszName, + VARIANT *pVal, + LONG lFlavor ) +{ + FIXME("%p, %s, %p, %d\n", iface, debugstr_w(wszName), pVal, lFlavor); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_Delete( + IWbemQualifierSet *iface, + LPCWSTR wszName ) +{ + FIXME("%p, %s\n", iface, debugstr_w(wszName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_GetNames( + IWbemQualifierSet *iface, + LONG lFlags, + SAFEARRAY **pNames ) +{ + FIXME("%p, %08x, %p\n", iface, lFlags, pNames); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_BeginEnumeration( + IWbemQualifierSet *iface, + LONG lFlags ) +{ + FIXME("%p, %08x\n", iface, lFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_Next( + IWbemQualifierSet *iface, + LONG lFlags, + BSTR *pstrName, + VARIANT *pVal, + LONG *plFlavor ) +{ + FIXME("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, pVal, plFlavor); + return E_NOTIMPL; +} + +static HRESULT WINAPI qualifier_set_EndEnumeration( + IWbemQualifierSet *iface ) +{ + FIXME("%p\n", iface); + return E_NOTIMPL; +} + +static const IWbemQualifierSetVtbl qualifier_set_vtbl = +{ + qualifier_set_QueryInterface, + qualifier_set_AddRef, + qualifier_set_Release, + qualifier_set_Get, + qualifier_set_Put, + qualifier_set_Delete, + qualifier_set_GetNames, + qualifier_set_BeginEnumeration, + qualifier_set_Next, + qualifier_set_EndEnumeration +}; + +HRESULT WbemQualifierSet_create( + IUnknown *pUnkOuter, const WCHAR *class, const WCHAR *member, LPVOID *ppObj ) +{ + struct qualifier_set *set; + + TRACE("%p, %p\n", pUnkOuter, ppObj); + + if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY; + + set->IWbemQualifierSet_iface.lpVtbl = &qualifier_set_vtbl; + if (!(set->class = heap_strdupW( class ))) + { + heap_free( set ); + return E_OUTOFMEMORY; + } + if (!member) set->member = NULL; + else if (!(set->member = heap_strdupW( member ))) + { + heap_free( set->class ); + heap_free( set ); + return E_OUTOFMEMORY; + } + set->refs = 1; + + *ppObj = &set->IWbemQualifierSet_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/dll/win32/wbemprox/query.c b/dll/win32/wbemprox/query.c new file mode 100644 index 00000000000..6ad7f4d86cd --- /dev/null +++ b/dll/win32/wbemprox/query.c @@ -0,0 +1,887 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +HRESULT create_view( const struct property *proplist, const WCHAR *class, + const struct expr *cond, struct view **ret ) +{ + struct view *view = heap_alloc( sizeof(struct view) ); + + if (!view) return E_OUTOFMEMORY; + view->proplist = proplist; + view->table = grab_table( class ); + view->cond = cond; + view->result = NULL; + view->count = 0; + *ret = view; + return S_OK; +} + +void destroy_view( struct view *view ) +{ + if (!view) return; + if (view->table) release_table( view->table ); + heap_free( view->result ); + heap_free( view ); +} + +static BOOL eval_like( const WCHAR *lstr, const WCHAR *rstr ) +{ + const WCHAR *p = lstr, *q = rstr; + + while (*p && *q) + { + if (*q == '%') + { + while (*q == '%') q++; + if (!*q) return TRUE; + while (*p && toupperW( p[1] ) != toupperW( q[1] )) p++; + if (!*p) return TRUE; + } + if (toupperW( *p++ ) != toupperW( *q++ )) return FALSE; + } + return TRUE; +} + +static HRESULT eval_strcmp( UINT op, const WCHAR *lstr, const WCHAR *rstr, LONGLONG *val ) +{ + if (!lstr || !rstr) + { + *val = 0; + return S_OK; + } + switch (op) + { + case OP_EQ: + *val = !strcmpW( lstr, rstr ); + break; + case OP_GT: + *val = strcmpW( lstr, rstr ) > 0; + break; + case OP_LT: + *val = strcmpW( lstr, rstr ) < 0; + break; + case OP_LE: + *val = strcmpW( lstr, rstr ) <= 0; + break; + case OP_GE: + *val = strcmpW( lstr, rstr ) >= 0; + break; + case OP_NE: + *val = strcmpW( lstr, rstr ); + break; + case OP_LIKE: + *val = eval_like( lstr, rstr ); + break; + default: + ERR("unhandled operator %u\n", op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static inline BOOL is_strcmp( const struct complex_expr *expr ) +{ + return ((expr->left->type == EXPR_PROPVAL && expr->right->type == EXPR_SVAL) || + (expr->left->type == EXPR_SVAL && expr->right->type == EXPR_PROPVAL)); +} + +static HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG * ); + +static HRESULT eval_binary( const struct table *table, UINT row, const struct complex_expr *expr, + LONGLONG *val ) +{ + HRESULT lret, rret; + LONGLONG lval, rval; + + lret = eval_cond( table, row, expr->left, &lval ); + rret = eval_cond( table, row, expr->right, &rval ); + if (lret != S_OK || rret != S_OK) return WBEM_E_INVALID_QUERY; + + if (is_strcmp( expr )) + { + const WCHAR *lstr = (const WCHAR *)(INT_PTR)lval; + const WCHAR *rstr = (const WCHAR *)(INT_PTR)rval; + + return eval_strcmp( expr->op, lstr, rstr, val ); + } + switch (expr->op) + { + case OP_EQ: + *val = (lval == rval); + break; + case OP_AND: + *val = (lval && rval); + break; + case OP_OR: + *val = (lval || rval); + break; + case OP_GT: + *val = (lval > rval); + break; + case OP_LT: + *val = (lval < rval); + break; + case OP_LE: + *val = (lval <= rval); + break; + case OP_GE: + *val = (lval >= rval); + break; + case OP_NE: + *val = (lval != rval); + break; + default: + ERR("unhandled operator %u\n", expr->op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static HRESULT eval_unary( const struct table *table, UINT row, const struct complex_expr *expr, + LONGLONG *val ) + +{ + HRESULT hr; + UINT column; + LONGLONG lval; + + hr = get_column_index( table, expr->left->u.propval->name, &column ); + if (hr != S_OK) + return hr; + + hr = get_value( table, row, column, &lval ); + if (hr != S_OK) + return hr; + + switch (expr->op) + { + case OP_ISNULL: + *val = !lval; + break; + case OP_NOTNULL: + *val = lval; + break; + default: + ERR("unknown operator %u\n", expr->op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static HRESULT eval_propval( const struct table *table, UINT row, const struct property *propval, + LONGLONG *val ) + +{ + HRESULT hr; + UINT column; + + hr = get_column_index( table, propval->name, &column ); + if (hr != S_OK) + return hr; + + return get_value( table, row, column, val ); +} + +static HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, + LONGLONG *val ) +{ + if (!cond) + { + *val = 1; + return S_OK; + } + switch (cond->type) + { + case EXPR_COMPLEX: + return eval_binary( table, row, &cond->u.expr, val ); + case EXPR_UNARY: + return eval_unary( table, row, &cond->u.expr, val ); + case EXPR_PROPVAL: + return eval_propval( table, row, cond->u.propval, val ); + case EXPR_SVAL: + *val = (INT_PTR)cond->u.sval; + return S_OK; + case EXPR_IVAL: + case EXPR_BVAL: + *val = cond->u.ival; + return S_OK; + default: + ERR("invalid expression type\n"); + break; + } + return WBEM_E_INVALID_QUERY; +} + +static HRESULT execute_view( struct view *view ) +{ + UINT i, j = 0, len; + + if (!view->table || !view->table->num_rows) return S_OK; + + len = min( view->table->num_rows, 16 ); + if (!(view->result = heap_alloc( len * sizeof(UINT) ))) return E_OUTOFMEMORY; + + for (i = 0; i < view->table->num_rows; i++) + { + HRESULT hr; + LONGLONG val = 0; + + if (j >= len) + { + UINT *tmp; + len *= 2; + if (!(tmp = heap_realloc( view->result, len * sizeof(UINT) ))) return E_OUTOFMEMORY; + view->result = tmp; + } + if ((hr = eval_cond( view->table, i, view->cond, &val )) != S_OK) return hr; + if (val) view->result[j++] = i; + } + view->count = j; + return S_OK; +} + +static struct query *create_query(void) +{ + struct query *query; + + if (!(query = heap_alloc( sizeof(*query) ))) return NULL; + list_init( &query->mem ); + query->refs = 1; + return query; +} + +static void free_query( struct query *query ) +{ + struct list *mem, *next; + + destroy_view( query->view ); + LIST_FOR_EACH_SAFE( mem, next, &query->mem ) + { + heap_free( mem ); + } + heap_free( query ); +} + +struct query *addref_query( struct query *query ) +{ + InterlockedIncrement( &query->refs ); + return query; +} + +void release_query( struct query *query ) +{ + if (!InterlockedDecrement( &query->refs )) free_query( query ); +} + +HRESULT exec_query( const WCHAR *str, IEnumWbemClassObject **result ) +{ + HRESULT hr; + struct query *query; + + *result = NULL; + if (!(query = create_query())) return E_OUTOFMEMORY; + hr = parse_query( str, &query->view, &query->mem ); + if (hr != S_OK) goto done; + hr = execute_view( query->view ); + if (hr != S_OK) goto done; + hr = EnumWbemClassObject_create( NULL, query, (void **)result ); + +done: + release_query( query ); + return hr; +} + +static BOOL is_selected_prop( const struct view *view, const WCHAR *name ) +{ + const struct property *prop = view->proplist; + + if (!prop) return TRUE; + while (prop) + { + if (!strcmpiW( prop->name, name )) return TRUE; + prop = prop->next; + } + return FALSE; +} + +static BOOL is_system_prop( const WCHAR *name ) +{ + return (name[0] == '_' && name[1] == '_'); +} + +static BSTR build_servername( const struct view *view ) +{ + WCHAR server[MAX_COMPUTERNAME_LENGTH + 1], *p; + DWORD len = sizeof(server)/sizeof(server[0]); + + if (view->proplist) return NULL; + + if (!(GetComputerNameW( server, &len ))) return NULL; + for (p = server; *p; p++) *p = toupperW( *p ); + return SysAllocString( server ); +} + +static BSTR build_classname( const struct view *view ) +{ + return SysAllocString( view->table->name ); +} + +static BSTR build_namespace( const struct view *view ) +{ + static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0}; + + if (view->proplist) return NULL; + return SysAllocString( cimv2W ); +} + +static BSTR build_proplist( const struct view *view, UINT index, UINT count, UINT *len ) +{ + static const WCHAR fmtW[] = {'%','s','=','%','s',0}; + UINT i, j, offset, row = view->result[index]; + BSTR *values, ret = NULL; + + if (!(values = heap_alloc( count * sizeof(BSTR) ))) return NULL; + + *len = j = 0; + for (i = 0; i < view->table->num_cols; i++) + { + if (view->table->columns[i].type & COL_FLAG_KEY) + { + const WCHAR *name = view->table->columns[i].name; + + values[j] = get_value_bstr( view->table, row, i ); + *len += strlenW( fmtW ) + strlenW( name ) + strlenW( values[j] ); + j++; + } + } + if ((ret = SysAllocStringLen( NULL, *len ))) + { + offset = j = 0; + for (i = 0; i < view->table->num_cols; i++) + { + if (view->table->columns[i].type & COL_FLAG_KEY) + { + const WCHAR *name = view->table->columns[i].name; + + offset += sprintfW( ret + offset, fmtW, name, values[j] ); + if (j < count - 1) ret[offset++] = ','; + j++; + } + } + } + for (i = 0; i < count; i++) SysFreeString( values[i] ); + heap_free( values ); + return ret; +} + +static UINT count_key_columns( const struct view *view ) +{ + UINT i, num_keys = 0; + + for (i = 0; i < view->table->num_cols; i++) + { + if (view->table->columns[i].type & COL_FLAG_KEY) num_keys++; + } + return num_keys; +} + +static BSTR build_relpath( const struct view *view, UINT index, const WCHAR *name ) +{ + static const WCHAR fmtW[] = {'%','s','.','%','s',0}; + BSTR class, proplist, ret = NULL; + UINT num_keys, len; + + if (view->proplist) return NULL; + + if (!(class = build_classname( view ))) return NULL; + if (!(num_keys = count_key_columns( view ))) return class; + if (!(proplist = build_proplist( view, index, num_keys, &len ))) goto done; + + len += strlenW( fmtW ) + SysStringLen( class ); + if (!(ret = SysAllocStringLen( NULL, len ))) goto done; + sprintfW( ret, fmtW, class, proplist ); + +done: + SysFreeString( class ); + SysFreeString( proplist ); + return ret; +} + +static BSTR build_path( const struct view *view, UINT index, const WCHAR *name ) +{ + static const WCHAR fmtW[] = {'\\','\\','%','s','\\','%','s',':','%','s',0}; + BSTR server, namespace = NULL, relpath = NULL, ret = NULL; + UINT len; + + if (view->proplist) return NULL; + + if (!(server = build_servername( view ))) return NULL; + if (!(namespace = build_namespace( view ))) goto done; + if (!(relpath = build_relpath( view, index, name ))) goto done; + + len = strlenW( fmtW ) + SysStringLen( server ) + SysStringLen( namespace ) + SysStringLen( relpath ); + if (!(ret = SysAllocStringLen( NULL, len ))) goto done; + sprintfW( ret, fmtW, server, namespace, relpath ); + +done: + SysFreeString( server ); + SysFreeString( namespace ); + SysFreeString( relpath ); + return ret; +} + +static inline BOOL is_method( const struct table *table, UINT column ) +{ + return table->columns[column].type & COL_FLAG_METHOD; +} + +static UINT count_properties( const struct view *view ) +{ + UINT i, num_props = 0; + + for (i = 0; i < view->table->num_cols; i++) + { + if (!is_method( view->table, i)) num_props++; + } + return num_props; +} + +static UINT count_selected_properties( const struct view *view ) +{ + const struct property *prop = view->proplist; + UINT count; + + if (!prop) return count_properties( view ); + + count = 1; + while ((prop = prop->next)) count++; + return count; +} + +static HRESULT get_system_propval( const struct view *view, UINT index, const WCHAR *name, + VARIANT *ret, CIMTYPE *type, LONG *flavor ) +{ + static const WCHAR classW[] = {'_','_','C','L','A','S','S',0}; + static const WCHAR genusW[] = {'_','_','G','E','N','U','S',0}; + static const WCHAR pathW[] = {'_','_','P','A','T','H',0}; + static const WCHAR namespaceW[] = {'_','_','N','A','M','E','S','P','A','C','E',0}; + static const WCHAR propcountW[] = {'_','_','P','R','O','P','E','R','T','Y','_','C','O','U','N','T',0}; + static const WCHAR relpathW[] = {'_','_','R','E','L','P','A','T','H',0}; + static const WCHAR serverW[] = {'_','_','S','E','R','V','E','R',0}; + + if (flavor) *flavor = WBEM_FLAVOR_ORIGIN_SYSTEM; + + if (!strcmpiW( name, classW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_classname( view ); + if (type) *type = CIM_STRING; + return S_OK; + } + if (!strcmpiW( name, genusW )) + { + V_VT( ret ) = VT_I4; + V_I4( ret ) = WBEM_GENUS_INSTANCE; /* FIXME */ + if (type) *type = CIM_SINT32; + return S_OK; + } + else if (!strcmpiW( name, namespaceW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_namespace( view ); + if (type) *type = CIM_STRING; + return S_OK; + } + else if (!strcmpiW( name, pathW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_path( view, index, name ); + if (type) *type = CIM_STRING; + return S_OK; + } + if (!strcmpiW( name, propcountW )) + { + V_VT( ret ) = VT_I4; + V_I4( ret ) = count_selected_properties( view ); + if (type) *type = CIM_SINT32; + return S_OK; + } + else if (!strcmpiW( name, relpathW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_relpath( view, index, name ); + if (type) *type = CIM_STRING; + return S_OK; + } + else if (!strcmpiW( name, serverW )) + { + V_VT( ret ) = VT_BSTR; + V_BSTR( ret ) = build_servername( view ); + if (type) *type = CIM_STRING; + return S_OK; + } + FIXME("system property %s not implemented\n", debugstr_w(name)); + return WBEM_E_NOT_FOUND; +} + +VARTYPE to_vartype( CIMTYPE type ) +{ + switch (type) + { + case CIM_BOOLEAN: return VT_BOOL; + case CIM_STRING: + case CIM_DATETIME: return VT_BSTR; + case CIM_SINT16: return VT_I2; + case CIM_UINT16: return VT_UI2; + case CIM_SINT32: return VT_I4; + case CIM_UINT32: return VT_UI4; + case CIM_SINT64: return VT_I8; + case CIM_UINT64: return VT_UI8; + default: + ERR("unhandled type %u\n", type); + break; + } + return 0; +} + +SAFEARRAY *to_safearray( const struct array *array, CIMTYPE type ) +{ + SAFEARRAY *ret; + UINT size = get_type_size( type ); + VARTYPE vartype = to_vartype( type ); + LONG i; + + if (!(ret = SafeArrayCreateVector( vartype, 0, array->count ))) return NULL; + + for (i = 0; i < array->count; i++) + { + void *ptr = (char *)array->ptr + i * size; + if (vartype == VT_BSTR) + { + BSTR str = SysAllocString( *(const WCHAR **)ptr ); + if (!str || SafeArrayPutElement( ret, &i, str ) != S_OK) + { + SysFreeString( str ); + SafeArrayDestroy( ret ); + return NULL; + } + } + else if (SafeArrayPutElement( ret, &i, ptr ) != S_OK) + { + SafeArrayDestroy( ret ); + return NULL; + } + } + return ret; +} + +void set_variant( VARTYPE type, LONGLONG val, void *val_ptr, VARIANT *ret ) +{ + if (type & VT_ARRAY) + { + V_VT( ret ) = type; + V_ARRAY( ret ) = val_ptr; + return; + } + switch (type) + { + case VT_BOOL: + V_BOOL( ret ) = val; + break; + case VT_BSTR: + V_BSTR( ret ) = val_ptr; + break; + case VT_I2: + V_I2( ret ) = val; + break; + case VT_UI2: + V_UI2( ret ) = val; + break; + case VT_I4: + V_I4( ret ) = val; + break; + case VT_UI4: + V_UI4( ret ) = val; + break; + case VT_NULL: + break; + default: + ERR("unhandled variant type %u\n", type); + return; + } + V_VT( ret ) = type; +} + +HRESULT get_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *ret, + CIMTYPE *type, LONG *flavor ) +{ + HRESULT hr; + UINT column, row; + VARTYPE vartype; + void *val_ptr = NULL; + LONGLONG val; + + if (is_system_prop( name )) return get_system_propval( view, index, name, ret, type, flavor ); + if (!view->count || !is_selected_prop( view, name )) return WBEM_E_NOT_FOUND; + + hr = get_column_index( view->table, name, &column ); + if (hr != S_OK || is_method( view->table, column )) return WBEM_E_NOT_FOUND; + + row = view->result[index]; + hr = get_value( view->table, row, column, &val ); + if (hr != S_OK) return hr; + + vartype = view->table->columns[column].vartype; + if (view->table->columns[column].type & CIM_FLAG_ARRAY) + { + CIMTYPE basetype = view->table->columns[column].type & CIM_TYPE_MASK; + + val_ptr = to_safearray( (const struct array *)(INT_PTR)val, basetype ); + if (!vartype) vartype = to_vartype( basetype ) | VT_ARRAY; + goto done; + } + switch (view->table->columns[column].type & COL_TYPE_MASK) + { + case CIM_BOOLEAN: + if (!vartype) vartype = VT_BOOL; + break; + case CIM_STRING: + case CIM_DATETIME: + if (val) + { + vartype = VT_BSTR; + val_ptr = SysAllocString( (const WCHAR *)(INT_PTR)val ); + } + else + vartype = VT_NULL; + break; + case CIM_SINT16: + if (!vartype) vartype = VT_I2; + break; + case CIM_UINT16: + if (!vartype) vartype = VT_UI2; + break; + case CIM_SINT32: + if (!vartype) vartype = VT_I4; + break; + case CIM_UINT32: + if (!vartype) vartype = VT_UI4; + break; + case CIM_SINT64: + vartype = VT_BSTR; + val_ptr = get_value_bstr( view->table, row, column ); + break; + case CIM_UINT64: + vartype = VT_BSTR; + val_ptr = get_value_bstr( view->table, row, column ); + break; + default: + ERR("unhandled column type %u\n", view->table->columns[column].type); + return WBEM_E_FAILED; + } + +done: + set_variant( vartype, val, val_ptr, ret ); + if (type) *type = view->table->columns[column].type & COL_TYPE_MASK; + if (flavor) *flavor = 0; + return S_OK; +} + +static CIMTYPE to_cimtype( VARTYPE type ) +{ + switch (type) + { + case VT_BOOL: return CIM_BOOLEAN; + case VT_BSTR: return CIM_STRING; + case VT_I2: return CIM_SINT16; + case VT_UI2: return CIM_UINT16; + case VT_I4: return CIM_SINT32; + case VT_UI4: return CIM_UINT32; + case VT_I8: return CIM_SINT64; + case VT_UI8: return CIM_UINT64; + default: + ERR("unhandled type %u\n", type); + break; + } + return 0; +} + +static struct array *to_array( VARIANT *var, CIMTYPE *type ) +{ + struct array *ret; + LONG bound, i; + VARTYPE vartype; + CIMTYPE basetype; + UINT size; + + if (SafeArrayGetVartype( V_ARRAY( var ), &vartype ) != S_OK) return NULL; + if (!(basetype = to_cimtype( vartype ))) return NULL; + if (SafeArrayGetUBound( V_ARRAY( var ), 1, &bound ) != S_OK) return NULL; + if (!(ret = heap_alloc( sizeof(struct array) ))) return NULL; + + ret->count = bound + 1; + size = get_type_size( basetype ); + if (!(ret->ptr = heap_alloc_zero( ret->count * size ))) + { + heap_free( ret ); + return NULL; + } + for (i = 0; i < ret->count; i++) + { + void *ptr = (char *)ret->ptr + i * size; + if (vartype == VT_BSTR) + { + BSTR str; + if (SafeArrayGetElement( V_ARRAY( var ), &i, &str ) != S_OK) + { + destroy_array( ret, basetype ); + return NULL; + } + *(WCHAR **)ptr = heap_strdupW( str ); + SysFreeString( str ); + if (!*(WCHAR **)ptr) + { + destroy_array( ret, basetype ); + return NULL; + } + } + else if (SafeArrayGetElement( V_ARRAY( var ), &i, ptr ) != S_OK) + { + destroy_array( ret, basetype ); + return NULL; + } + } + *type = basetype | CIM_FLAG_ARRAY; + return ret; +} + +HRESULT to_longlong( VARIANT *var, LONGLONG *val, CIMTYPE *type ) +{ + if (!var) + { + *val = 0; + return S_OK; + } + if (V_VT( var ) & VT_ARRAY) + { + *val = (INT_PTR)to_array( var, type ); + if (!*val) return E_OUTOFMEMORY; + return S_OK; + } + switch (V_VT( var )) + { + case VT_BOOL: + *val = V_BOOL( var ); + *type = CIM_BOOLEAN; + break; + case VT_BSTR: + *val = (INT_PTR)heap_strdupW( V_BSTR( var ) ); + if (!*val) return E_OUTOFMEMORY; + *type = CIM_STRING; + break; + case VT_I2: + *val = V_I2( var ); + *type = CIM_SINT16; + break; + case VT_UI2: + *val = V_UI2( var ); + *type = CIM_UINT16; + break; + case VT_I4: + *val = V_I4( var ); + *type = CIM_SINT32; + break; + case VT_UI4: + *val = V_UI4( var ); + *type = CIM_UINT32; + break; + case VT_NULL: + *val = 0; + break; + default: + ERR("unhandled type %u\n", V_VT( var )); + return WBEM_E_FAILED; + } + return S_OK; +} + +HRESULT put_propval( const struct view *view, UINT index, const WCHAR *name, VARIANT *var, CIMTYPE type ) +{ + HRESULT hr; + UINT column, row = view->result[index]; + LONGLONG val; + + hr = get_column_index( view->table, name, &column ); + if (hr != S_OK) + { + FIXME("no support for creating new properties\n"); + return WBEM_E_FAILED; + } + if (is_method( view->table, column ) || !(view->table->columns[column].type & COL_FLAG_DYNAMIC)) + return WBEM_E_FAILED; + + hr = to_longlong( var, &val, &type ); + if (hr != S_OK) return hr; + + return set_value( view->table, row, column, val, type ); +} + +HRESULT get_properties( const struct view *view, SAFEARRAY **props ) +{ + SAFEARRAY *sa; + BSTR str; + LONG i; + UINT num_props = count_properties( view ); + + if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, num_props ))) return E_OUTOFMEMORY; + + for (i = 0; i < view->table->num_cols; i++) + { + if (is_method( view->table, i )) continue; + + str = SysAllocString( view->table->columns[i].name ); + if (!str || SafeArrayPutElement( sa, &i, str ) != S_OK) + { + SysFreeString( str ); + SafeArrayDestroy( sa ); + return E_OUTOFMEMORY; + } + } + *props = sa; + return S_OK; +} diff --git a/dll/win32/wbemprox/reg.c b/dll/win32/wbemprox/reg.c new file mode 100644 index 00000000000..becc6e11c6c --- /dev/null +++ b/dll/win32/wbemprox/reg.c @@ -0,0 +1,347 @@ +/* + * StdRegProv implementation + * + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +static HRESULT to_bstr_array( BSTR *strings, DWORD count, VARIANT *var ) +{ + SAFEARRAY *sa; + HRESULT hr; + LONG i; + + if (!(sa = SafeArrayCreateVector( VT_BSTR, 0, count ))) return E_OUTOFMEMORY; + for (i = 0; i < count; i++) + { + if ((hr = SafeArrayPutElement( sa, &i, strings[i] )) != S_OK) + { + SafeArrayDestroy( sa ); + return hr; + } + } + set_variant( VT_BSTR|VT_ARRAY, 0, sa, var ); + return S_OK; +} + +static HRESULT to_i4_array( DWORD *values, DWORD count, VARIANT *var ) +{ + SAFEARRAY *sa; + HRESULT hr; + LONG i; + + if (!(sa = SafeArrayCreateVector( VT_I4, 0, count ))) return E_OUTOFMEMORY; + for (i = 0; i < count; i++) + { + if ((hr = SafeArrayPutElement( sa, &i, &values[i] )) != S_OK) + { + SafeArrayDestroy( sa ); + return hr; + } + } + set_variant( VT_I4|VT_ARRAY, 0, sa, var ); + return S_OK; +} + +static HRESULT enum_key( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *retval ) +{ + HKEY hkey; + HRESULT hr = S_OK; + WCHAR buf[256]; + BSTR *strings, *tmp; + DWORD count = 2, len = sizeof(buf)/sizeof(buf[0]); + LONG res, i = 0; + + TRACE("%p, %s\n", root, debugstr_w(subkey)); + + if (!(strings = heap_alloc( count * sizeof(BSTR) ))) return E_OUTOFMEMORY; + if ((res = RegOpenKeyExW( root, subkey, 0, KEY_ENUMERATE_SUB_KEYS, &hkey ))) + { + set_variant( VT_UI4, res, NULL, retval ); + heap_free( strings ); + return S_OK; + } + for (;;) + { + if (i >= count) + { + count *= 2; + if (!(tmp = heap_realloc( strings, count * sizeof(BSTR) ))) + { + RegCloseKey( hkey ); + return E_OUTOFMEMORY; + } + strings = tmp; + } + if ((res = RegEnumKeyW( hkey, i, buf, len )) == ERROR_NO_MORE_ITEMS) + { + if (i) res = ERROR_SUCCESS; + break; + } + if (res) break; + if (!(strings[i] = SysAllocString( buf ))) + { + for (i--; i >= 0; i--) SysFreeString( strings[i] ); + hr = ERROR_OUTOFMEMORY; + break; + } + i++; + } + if (hr == S_OK && !res) hr = to_bstr_array( strings, i, names ); + set_variant( VT_UI4, res, NULL, retval ); + RegCloseKey( hkey ); + heap_free( strings ); + return hr; +} + +HRESULT reg_enum_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT defkey, subkey, names, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p\n", in, out); + + hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_stdregprovW, method_enumkeyW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &subkey ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + return hr; + } + VariantInit( &names ); + hr = enum_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &retval ); + if (hr != S_OK) goto done; + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( *out, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &names ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} + +static HRESULT enum_values( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *types, VARIANT *retval ) +{ + HKEY hkey = NULL; + HRESULT hr = S_OK; + BSTR *value_names = NULL; + DWORD count, buflen, len, *value_types = NULL; + LONG res, i = 0; + WCHAR *buf = NULL; + + TRACE("%p, %s\n", root, debugstr_w(subkey)); + + if ((res = RegOpenKeyExW( root, subkey, 0, KEY_QUERY_VALUE, &hkey ))) goto done; + if ((res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, &count, &buflen, NULL, NULL, NULL ))) + goto done; + + hr = E_OUTOFMEMORY; + if (!(buf = heap_alloc( (buflen + 1) * sizeof(WCHAR) ))) goto done; + if (!(value_names = heap_alloc( count * sizeof(BSTR) ))) goto done; + if (!(value_types = heap_alloc( count * sizeof(DWORD) ))) goto done; + + hr = S_OK; + for (;;) + { + len = buflen + 1; + res = RegEnumValueW( hkey, i, buf, &len, NULL, &value_types[i], NULL, NULL ); + if (res == ERROR_NO_MORE_ITEMS) + { + if (i) res = ERROR_SUCCESS; + break; + } + if (res) break; + if (!(value_names[i] = SysAllocString( buf ))) + { + for (i--; i >= 0; i--) SysFreeString( value_names[i] ); + hr = ERROR_OUTOFMEMORY; + break; + } + i++; + } + if (hr == S_OK && !res) + { + hr = to_bstr_array( value_names, i, names ); + if (hr == S_OK) hr = to_i4_array( value_types, i, types ); + } + +done: + set_variant( VT_UI4, res, NULL, retval ); + RegCloseKey( hkey ); + heap_free( value_names ); + heap_free( value_types ); + heap_free( buf ); + return hr; +} + +HRESULT reg_enum_values( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT defkey, subkey, names, types, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p\n", in, out); + + hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_stdregprovW, method_enumvaluesW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &subkey ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + return hr; + } + VariantInit( &names ); + VariantInit( &types ); + hr = enum_values( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &names, &types, &retval ); + if (hr != S_OK) goto done; + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( *out, param_namesW, 0, &names, CIM_STRING|CIM_FLAG_ARRAY ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_typesW, 0, &types, CIM_SINT32|CIM_FLAG_ARRAY ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &types ); + VariantClear( &names ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} + +static HRESULT get_stringvalue( HKEY root, const WCHAR *subkey, const WCHAR *name, VARIANT *value, VARIANT *retval ) +{ + HRESULT hr = S_OK; + WCHAR *buf = NULL; + DWORD size; + LONG res; + + TRACE("%p, %s, %s\n", root, debugstr_w(subkey), debugstr_w(name)); + + if ((res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, NULL, &size ))) goto done; + if (!(buf = heap_alloc( size ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + if (!(res = RegGetValueW( root, subkey, name, RRF_RT_REG_SZ, NULL, buf, &size ))) + set_variant( VT_BSTR, 0, buf, value ); + +done: + set_variant( VT_UI4, res, NULL, retval ); + heap_free( buf ); + return hr; +} + +HRESULT reg_get_stringvalue( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT defkey, subkey, name, value, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p\n", in, out); + + hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL ); + if (hr != S_OK) return hr; + hr = IWbemClassObject_Get( in, param_valuenameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_stdregprovW, method_getstringvalueW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + VariantClear( &subkey ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &name ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + return hr; + } + VariantInit( &value ); + hr = get_stringvalue( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), V_BSTR(&name), &value, &retval ); + if (hr != S_OK) goto done; + if (!V_UI4( &retval )) + { + hr = IWbemClassObject_Put( *out, param_valueW, 0, &value, CIM_STRING ); + if (hr != S_OK) goto done; + } + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + VariantClear( &subkey ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} diff --git a/dll/win32/wbemprox/service.c b/dll/win32/wbemprox/service.c new file mode 100644 index 00000000000..bde669c1275 --- /dev/null +++ b/dll/win32/wbemprox/service.c @@ -0,0 +1,248 @@ +/* + * Win32_Service methods implementation + * + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" +#include "winsvc.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +static UINT map_error( DWORD error ) +{ + switch (error) + { + case ERROR_SUCCESS: return 0; + case ERROR_ACCESS_DENIED: return 2; + case ERROR_DEPENDENT_SERVICES_RUNNING: return 3; + case ERROR_INVALID_SERVICE_CONTROL: return 4; + case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: return 5; + case ERROR_SERVICE_NOT_ACTIVE: return 6; + case ERROR_SERVICE_REQUEST_TIMEOUT: return 7; + case ERROR_SERVICE_ALREADY_RUNNING: return 10; + default: + WARN("unknown error %u\n", error); + break; + } + return 8; +} + +static HRESULT control_service( const WCHAR *name, DWORD control, VARIANT *retval ) +{ + SC_HANDLE manager, service = NULL; + SERVICE_STATUS status; + UINT error = 0; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!(service = OpenServiceW( manager, name, SERVICE_STOP|SERVICE_START|SERVICE_PAUSE_CONTINUE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!ControlService( service, control, &status )) error = map_error( GetLastError() ); + +done: + set_variant( VT_UI4, error, NULL, retval ); + CloseServiceHandle( service ); + CloseServiceHandle( manager ); + return S_OK; +} + +HRESULT service_pause_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_pauseserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + hr = control_service( V_BSTR(&name), SERVICE_CONTROL_PAUSE, &retval ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} + +HRESULT service_resume_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_resumeserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + hr = control_service( V_BSTR(&name), SERVICE_CONTROL_CONTINUE, &retval ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} + +static HRESULT start_service( const WCHAR *name, VARIANT *retval ) +{ + SC_HANDLE manager, service = NULL; + UINT error = 0; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!(service = OpenServiceW( manager, name, SERVICE_START ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() ); + +done: + set_variant( VT_UI4, error, NULL, retval ); + CloseServiceHandle( service ); + CloseServiceHandle( manager ); + return S_OK; +} + +HRESULT service_start_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_startserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + hr = start_service( V_BSTR(&name), &retval ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} + +HRESULT service_stop_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_stopserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + hr = control_service( V_BSTR(&name), SERVICE_CONTROL_STOP, &retval ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} diff --git a/dll/win32/wbemprox/services.c b/dll/win32/wbemprox/services.c new file mode 100644 index 00000000000..65ea433ac62 --- /dev/null +++ b/dll/win32/wbemprox/services.c @@ -0,0 +1,680 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +struct client_security +{ + IClientSecurity IClientSecurity_iface; +}; + +static inline struct client_security *impl_from_IClientSecurity( IClientSecurity *iface ) +{ + return CONTAINING_RECORD( iface, struct client_security, IClientSecurity_iface ); +} + +static HRESULT WINAPI client_security_QueryInterface( + IClientSecurity *iface, + REFIID riid, + void **ppvObject ) +{ + struct client_security *cs = impl_from_IClientSecurity( iface ); + + TRACE("%p %s %p\n", cs, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IClientSecurity ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = cs; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IClientSecurity_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI client_security_AddRef( + IClientSecurity *iface ) +{ + FIXME("%p\n", iface); + return 2; +} + +static ULONG WINAPI client_security_Release( + IClientSecurity *iface ) +{ + FIXME("%p\n", iface); + return 1; +} + +static HRESULT WINAPI client_security_QueryBlanket( + IClientSecurity *iface, + IUnknown *pProxy, + DWORD *pAuthnSvc, + DWORD *pAuthzSvc, + OLECHAR **pServerPrincName, + DWORD *pAuthnLevel, + DWORD *pImpLevel, + void **pAuthInfo, + DWORD *pCapabilities ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI client_security_SetBlanket( + IClientSecurity *iface, + IUnknown *pProxy, + DWORD AuthnSvc, + DWORD AuthzSvc, + OLECHAR *pServerPrincName, + DWORD AuthnLevel, + DWORD ImpLevel, + void *pAuthInfo, + DWORD Capabilities ) +{ + static const OLECHAR defaultW[] = + {'<','C','O','L','E','_','D','E','F','A','U','L','T','_','P','R','I','N','C','I','P','A','L','>',0}; + const OLECHAR *princname = (pServerPrincName == COLE_DEFAULT_PRINCIPAL) ? defaultW : pServerPrincName; + + FIXME("%p, %p, %u, %u, %s, %u, %u, %p, 0x%08x\n", iface, pProxy, AuthnSvc, AuthzSvc, + debugstr_w(princname), AuthnLevel, ImpLevel, pAuthInfo, Capabilities); + return WBEM_NO_ERROR; +} + +static HRESULT WINAPI client_security_CopyProxy( + IClientSecurity *iface, + IUnknown *pProxy, + IUnknown **ppCopy ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static const IClientSecurityVtbl client_security_vtbl = +{ + client_security_QueryInterface, + client_security_AddRef, + client_security_Release, + client_security_QueryBlanket, + client_security_SetBlanket, + client_security_CopyProxy +}; + +IClientSecurity client_security = { &client_security_vtbl }; + +struct wbem_services +{ + IWbemServices IWbemServices_iface; + LONG refs; + WCHAR *namespace; +}; + +static inline struct wbem_services *impl_from_IWbemServices( IWbemServices *iface ) +{ + return CONTAINING_RECORD( iface, struct wbem_services, IWbemServices_iface ); +} + +static ULONG WINAPI wbem_services_AddRef( + IWbemServices *iface ) +{ + struct wbem_services *ws = impl_from_IWbemServices( iface ); + return InterlockedIncrement( &ws->refs ); +} + +static ULONG WINAPI wbem_services_Release( + IWbemServices *iface ) +{ + struct wbem_services *ws = impl_from_IWbemServices( iface ); + LONG refs = InterlockedDecrement( &ws->refs ); + if (!refs) + { + TRACE("destroying %p\n", ws); + heap_free( ws->namespace ); + heap_free( ws ); + } + return refs; +} + +static HRESULT WINAPI wbem_services_QueryInterface( + IWbemServices *iface, + REFIID riid, + void **ppvObject ) +{ + struct wbem_services *ws = impl_from_IWbemServices( iface ); + + TRACE("%p %s %p\n", ws, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemServices ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = ws; + } + else if ( IsEqualGUID( riid, &IID_IClientSecurity ) ) + { + *ppvObject = &client_security; + return S_OK; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemServices_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI wbem_services_OpenNamespace( + IWbemServices *iface, + const BSTR strNamespace, + LONG lFlags, + IWbemContext *pCtx, + IWbemServices **ppWorkingNamespace, + IWbemCallResult **ppResult ) +{ + static const WCHAR cimv2W[] = {'c','i','m','v','2',0}; + static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0}; + struct wbem_services *ws = impl_from_IWbemServices( iface ); + + TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strNamespace), lFlags, + pCtx, ppWorkingNamespace, ppResult); + + if ((strcmpiW( strNamespace, cimv2W ) && strcmpiW( strNamespace, defaultW )) || ws->namespace) + return WBEM_E_INVALID_NAMESPACE; + + return WbemServices_create( NULL, cimv2W, (void **)ppWorkingNamespace ); +} + +static HRESULT WINAPI wbem_services_CancelAsyncCall( + IWbemServices *iface, + IWbemObjectSink *pSink ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_QueryObjectSink( + IWbemServices *iface, + LONG lFlags, + IWbemObjectSink **ppResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +struct path +{ + WCHAR *class; + UINT class_len; + WCHAR *filter; + UINT filter_len; +}; + +static HRESULT parse_path( const WCHAR *str, struct path **ret ) +{ + struct path *path; + const WCHAR *p = str, *q; + UINT len; + + if (!(path = heap_alloc_zero( sizeof(*path) ))) return E_OUTOFMEMORY; + + while (*p && *p != '.') p++; + + len = p - str; + if (!(path->class = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + heap_free( path ); + return E_OUTOFMEMORY; + } + memcpy( path->class, str, len * sizeof(WCHAR) ); + path->class[len] = 0; + path->class_len = len; + + if (p[0] == '.' && p[1]) + { + q = ++p; + while (*q) q++; + + len = q - p; + if (!(path->filter = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + heap_free( path->class ); + heap_free( path ); + return E_OUTOFMEMORY; + } + memcpy( path->filter, p, len * sizeof(WCHAR) ); + path->filter[len] = 0; + path->filter_len = len; + } + *ret = path; + return S_OK; +} + +static void free_path( struct path *path ) +{ + heap_free( path->class ); + heap_free( path->filter ); + heap_free( path ); +} + +static HRESULT create_instance_enum( const struct path *path, IEnumWbemClassObject **iter ) +{ + static const WCHAR selectW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','%','s',' ', + 'W','H','E','R','E',' ','%','s',0}; + static const WCHAR select_allW[] = + {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; + WCHAR *query; + HRESULT hr; + UINT len; + + if (path->filter) + { + len = path->class_len + path->filter_len + SIZEOF(selectW); + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + sprintfW( query, selectW, path->class, path->filter ); + } + else + { + len = path->class_len + SIZEOF(select_allW); + if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY; + strcpyW( query, select_allW ); + strcatW( query, path->class ); + } + hr = exec_query( query, iter ); + heap_free( query ); + return hr; +} + +HRESULT get_object( const WCHAR *object_path, IWbemClassObject **obj ) +{ + IEnumWbemClassObject *iter; + struct path *path; + HRESULT hr; + + hr = parse_path( object_path, &path ); + if (hr != S_OK) return hr; + + hr = create_instance_enum( path, &iter ); + if (hr != S_OK) + { + free_path( path ); + return hr; + } + hr = create_class_object( path->class, iter, 0, NULL, obj ); + IEnumWbemClassObject_Release( iter ); + free_path( path ); + return hr; +} + +static HRESULT WINAPI wbem_services_GetObject( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemClassObject **ppObject, + IWbemCallResult **ppCallResult ) +{ + TRACE("%p, %s, 0x%08x, %p, %p, %p\n", iface, debugstr_w(strObjectPath), lFlags, + pCtx, ppObject, ppCallResult); + + if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags); + + if (!strObjectPath || !strObjectPath[0]) + return create_class_object( NULL, NULL, 0, NULL, ppObject ); + + return get_object( strObjectPath, ppObject ); +} + +static HRESULT WINAPI wbem_services_GetObjectAsync( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutClass( + IWbemServices *iface, + IWbemClassObject *pObject, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutClassAsync( + IWbemServices *iface, + IWbemClassObject *pObject, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteClass( + IWbemServices *iface, + const BSTR strClass, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteClassAsync( + IWbemServices *iface, + const BSTR strClass, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_CreateClassEnum( + IWbemServices *iface, + const BSTR strSuperclass, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_CreateClassEnumAsync( + IWbemServices *iface, + const BSTR strSuperclass, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutInstance( + IWbemServices *iface, + IWbemClassObject *pInst, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_PutInstanceAsync( + IWbemServices *iface, + IWbemClassObject *pInst, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteInstance( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemCallResult **ppCallResult ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_DeleteInstanceAsync( + IWbemServices *iface, + const BSTR strObjectPath, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_CreateInstanceEnum( + IWbemServices *iface, + const BSTR strClass, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + struct path *path; + HRESULT hr; + + TRACE("%p, %s, 0%08x, %p, %p\n", iface, debugstr_w(strClass), lFlags, pCtx, ppEnum); + + if (lFlags) FIXME("unsupported flags 0x%08x\n", lFlags); + + hr = parse_path( strClass, &path ); + if (hr != S_OK) return hr; + + hr = create_instance_enum( path, ppEnum ); + free_path( path ); + return hr; +} + +static HRESULT WINAPI wbem_services_CreateInstanceEnumAsync( + IWbemServices *iface, + const BSTR strFilter, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_ExecQuery( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + static const WCHAR wqlW[] = {'W','Q','L',0}; + + TRACE("%p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strQueryLanguage), + debugstr_w(strQuery), lFlags, pCtx, ppEnum); + + if (!strQueryLanguage || !strQuery || !strQuery[0]) return WBEM_E_INVALID_PARAMETER; + if (strcmpiW( strQueryLanguage, wqlW )) return WBEM_E_INVALID_QUERY_TYPE; + return exec_query( strQuery, ppEnum ); +} + +static HRESULT WINAPI wbem_services_ExecQueryAsync( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_ExecNotificationQuery( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IEnumWbemClassObject **ppEnum ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_ExecNotificationQueryAsync( + IWbemServices *iface, + const BSTR strQueryLanguage, + const BSTR strQuery, + LONG lFlags, + IWbemContext *pCtx, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static HRESULT WINAPI wbem_services_ExecMethod( + IWbemServices *iface, + const BSTR strObjectPath, + const BSTR strMethodName, + LONG lFlags, + IWbemContext *pCtx, + IWbemClassObject *pInParams, + IWbemClassObject **ppOutParams, + IWbemCallResult **ppCallResult ) +{ + IWbemClassObject *obj; + struct table *table; + class_method *func; + struct path *path; + HRESULT hr; + + TRACE("%p, %s, %s, %08x, %p, %p, %p, %p\n", iface, debugstr_w(strObjectPath), + debugstr_w(strMethodName), lFlags, pCtx, pInParams, ppOutParams, ppCallResult); + + if (lFlags) FIXME("flags %08x not supported\n", lFlags); + + if ((hr = get_object( strObjectPath, &obj ))) return hr; + if ((hr = parse_path( strObjectPath, &path )) != S_OK) + { + IWbemClassObject_Release( obj ); + return hr; + } + table = grab_table( path->class ); + free_path( path ); + if (!table) + { + IWbemClassObject_Release( obj ); + return WBEM_E_NOT_FOUND; + } + hr = get_method( table, strMethodName, &func ); + release_table( table ); + if (hr != S_OK) + { + IWbemClassObject_Release( obj ); + return hr; + } + hr = func( obj, pInParams, ppOutParams ); + IWbemClassObject_Release( obj ); + return hr; +} + +static HRESULT WINAPI wbem_services_ExecMethodAsync( + IWbemServices *iface, + const BSTR strObjectPath, + const BSTR strMethodName, + LONG lFlags, + IWbemContext *pCtx, + IWbemClassObject *pInParams, + IWbemObjectSink *pResponseHandler ) +{ + FIXME("\n"); + return WBEM_E_FAILED; +} + +static const IWbemServicesVtbl wbem_services_vtbl = +{ + wbem_services_QueryInterface, + wbem_services_AddRef, + wbem_services_Release, + wbem_services_OpenNamespace, + wbem_services_CancelAsyncCall, + wbem_services_QueryObjectSink, + wbem_services_GetObject, + wbem_services_GetObjectAsync, + wbem_services_PutClass, + wbem_services_PutClassAsync, + wbem_services_DeleteClass, + wbem_services_DeleteClassAsync, + wbem_services_CreateClassEnum, + wbem_services_CreateClassEnumAsync, + wbem_services_PutInstance, + wbem_services_PutInstanceAsync, + wbem_services_DeleteInstance, + wbem_services_DeleteInstanceAsync, + wbem_services_CreateInstanceEnum, + wbem_services_CreateInstanceEnumAsync, + wbem_services_ExecQuery, + wbem_services_ExecQueryAsync, + wbem_services_ExecNotificationQuery, + wbem_services_ExecNotificationQueryAsync, + wbem_services_ExecMethod, + wbem_services_ExecMethodAsync +}; + +HRESULT WbemServices_create( IUnknown *pUnkOuter, const WCHAR *namespace, LPVOID *ppObj ) +{ + struct wbem_services *ws; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + ws = heap_alloc( sizeof(*ws) ); + if (!ws) return E_OUTOFMEMORY; + + ws->IWbemServices_iface.lpVtbl = &wbem_services_vtbl; + ws->refs = 1; + ws->namespace = heap_strdupW( namespace ); + + *ppObj = &ws->IWbemServices_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/dll/win32/wbemprox/table.c b/dll/win32/wbemprox/table.c new file mode 100644 index 00000000000..1eb76c5bc57 --- /dev/null +++ b/dll/win32/wbemprox/table.c @@ -0,0 +1,437 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +HRESULT get_column_index( const struct table *table, const WCHAR *name, UINT *column ) +{ + UINT i; + for (i = 0; i < table->num_cols; i++) + { + if (!strcmpiW( table->columns[i].name, name )) + { + *column = i; + return S_OK; + } + } + return WBEM_E_INVALID_QUERY; +} + +UINT get_type_size( CIMTYPE type ) +{ + if (type & CIM_FLAG_ARRAY) return sizeof(void *); + + switch (type) + { + case CIM_BOOLEAN: + return sizeof(int); + case CIM_SINT16: + case CIM_UINT16: + return sizeof(INT16); + case CIM_SINT32: + case CIM_UINT32: + return sizeof(INT32); + case CIM_SINT64: + case CIM_UINT64: + return sizeof(INT64); + case CIM_DATETIME: + case CIM_STRING: + return sizeof(WCHAR *); + default: + ERR("unhandled type %u\n", type); + break; + } + return sizeof(LONGLONG); +} + +static UINT get_column_size( const struct table *table, UINT column ) +{ + return get_type_size( table->columns[column].type & COL_TYPE_MASK ); +} + +static UINT get_column_offset( const struct table *table, UINT column ) +{ + UINT i, offset = 0; + for (i = 0; i < column; i++) offset += get_column_size( table, i ); + return offset; +} + +static UINT get_row_size( const struct table *table ) +{ + return get_column_offset( table, table->num_cols - 1 ) + get_column_size( table, table->num_cols - 1 ); +} + +HRESULT get_value( const struct table *table, UINT row, UINT column, LONGLONG *val ) +{ + UINT col_offset, row_size; + const BYTE *ptr; + + col_offset = get_column_offset( table, column ); + row_size = get_row_size( table ); + ptr = table->data + row * row_size + col_offset; + + if (table->columns[column].type & CIM_FLAG_ARRAY) + { + *val = (INT_PTR)*(const void **)ptr; + return S_OK; + } + switch (table->columns[column].type & COL_TYPE_MASK) + { + case CIM_BOOLEAN: + *val = *(const int *)ptr; + break; + case CIM_DATETIME: + case CIM_STRING: + *val = (INT_PTR)*(const WCHAR **)ptr; + break; + case CIM_SINT16: + *val = *(const INT16 *)ptr; + break; + case CIM_UINT16: + *val = *(const UINT16 *)ptr; + break; + case CIM_SINT32: + *val = *(const INT32 *)ptr; + break; + case CIM_UINT32: + *val = *(const UINT32 *)ptr; + break; + case CIM_SINT64: + *val = *(const INT64 *)ptr; + break; + case CIM_UINT64: + *val = *(const UINT64 *)ptr; + break; + default: + ERR("invalid column type %u\n", table->columns[column].type & COL_TYPE_MASK); + *val = 0; + break; + } + return S_OK; +} + +BSTR get_value_bstr( const struct table *table, UINT row, UINT column ) +{ + static const WCHAR fmt_signedW[] = {'%','d',0}; + static const WCHAR fmt_unsignedW[] = {'%','u',0}; + static const WCHAR fmt_signed64W[] = {'%','I','6','4','d',0}; + static const WCHAR fmt_unsigned64W[] = {'%','I','6','4','u',0}; + static const WCHAR fmt_strW[] = {'\"','%','s','\"',0}; + static const WCHAR trueW[] = {'T','R','U','E',0}; + static const WCHAR falseW[] = {'F','A','L','S','E',0}; + LONGLONG val; + BSTR ret; + WCHAR number[22]; + UINT len; + + if (table->columns[column].type & CIM_FLAG_ARRAY) + { + FIXME("array to string conversion not handled\n"); + return NULL; + } + if (get_value( table, row, column, &val ) != S_OK) return NULL; + + switch (table->columns[column].type & COL_TYPE_MASK) + { + case CIM_BOOLEAN: + if (val) return SysAllocString( trueW ); + else return SysAllocString( falseW ); + + case CIM_DATETIME: + case CIM_STRING: + if (!val) return NULL; + len = strlenW( (const WCHAR *)(INT_PTR)val ) + 2; + if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; + sprintfW( ret, fmt_strW, (const WCHAR *)(INT_PTR)val ); + return ret; + + case CIM_SINT16: + case CIM_SINT32: + sprintfW( number, fmt_signedW, val ); + return SysAllocString( number ); + + case CIM_UINT16: + case CIM_UINT32: + sprintfW( number, fmt_unsignedW, val ); + return SysAllocString( number ); + + case CIM_SINT64: + wsprintfW( number, fmt_signed64W, val ); + return SysAllocString( number ); + + case CIM_UINT64: + wsprintfW( number, fmt_unsigned64W, val ); + return SysAllocString( number ); + + default: + FIXME("unhandled column type %u\n", table->columns[column].type & COL_TYPE_MASK); + break; + } + return NULL; +} + +HRESULT set_value( const struct table *table, UINT row, UINT column, LONGLONG val, + CIMTYPE type ) +{ + UINT col_offset, row_size; + BYTE *ptr; + + if ((table->columns[column].type & COL_TYPE_MASK) != type) return WBEM_E_TYPE_MISMATCH; + + col_offset = get_column_offset( table, column ); + row_size = get_row_size( table ); + ptr = table->data + row * row_size + col_offset; + + switch (table->columns[column].type & COL_TYPE_MASK) + { + case CIM_DATETIME: + case CIM_STRING: + *(WCHAR **)ptr = (WCHAR *)(INT_PTR)val; + break; + case CIM_SINT16: + *(INT16 *)ptr = val; + break; + case CIM_UINT16: + *(UINT16 *)ptr = val; + break; + case CIM_SINT32: + *(INT32 *)ptr = val; + break; + case CIM_UINT32: + *(UINT32 *)ptr = val; + break; + case CIM_SINT64: + *(INT64 *)ptr = val; + break; + case CIM_UINT64: + *(UINT64 *)ptr = val; + break; + default: + FIXME("unhandled column type %u\n", type); + return WBEM_E_FAILED; + } + return S_OK; +} + +HRESULT get_method( const struct table *table, const WCHAR *name, class_method **func ) +{ + UINT i, j; + + for (i = 0; i < table->num_rows; i++) + { + for (j = 0; j < table->num_cols; j++) + { + if (table->columns[j].type & COL_FLAG_METHOD && !strcmpW( table->columns[j].name, name )) + { + HRESULT hr; + LONGLONG val; + + if ((hr = get_value( table, i, j, &val )) != S_OK) return hr; + *func = (class_method *)(INT_PTR)val; + return S_OK; + } + } + } + return WBEM_E_INVALID_METHOD; + +} + +static void clear_table( struct table *table ) +{ + UINT i, j, type; + LONGLONG val; + + if (!table->data) return; + + for (i = 0; i < table->num_rows; i++) + { + for (j = 0; j < table->num_cols; j++) + { + if (!(table->columns[j].type & COL_FLAG_DYNAMIC)) continue; + + type = table->columns[j].type & COL_TYPE_MASK; + if (type == CIM_STRING || type == CIM_DATETIME || (type & CIM_FLAG_ARRAY)) + { + if (get_value( table, i, j, &val ) == S_OK) heap_free( (void *)(INT_PTR)val ); + } + } + } + if (table->fill) + { + table->num_rows = 0; + heap_free( table->data ); + table->data = NULL; + } +} + +void free_columns( struct column *columns, UINT num_cols ) +{ + UINT i; + + for (i = 0; i < num_cols; i++) + { + heap_free( (WCHAR *)columns[i].name ); + } + heap_free( columns ); +} + +void free_table( struct table *table ) +{ + if (!table) return; + + clear_table( table ); + if (table->flags & TABLE_FLAG_DYNAMIC) + { + TRACE("destroying %p\n", table); + heap_free( (WCHAR *)table->name ); + free_columns( (struct column *)table->columns, table->num_cols ); + list_remove( &table->entry ); + heap_free( table ); + } +} + +void release_table( struct table *table ) +{ + if (!InterlockedDecrement( &table->refs )) free_table( table ); +} + +struct table *addref_table( struct table *table ) +{ + InterlockedIncrement( &table->refs ); + return table; +} + +struct table *grab_table( const WCHAR *name ) +{ + struct table *table; + + LIST_FOR_EACH_ENTRY( table, table_list, struct table, entry ) + { + if (!strcmpiW( table->name, name )) + { + if (table->fill && !table->data) table->fill( table ); + TRACE("returning %p\n", table); + return addref_table( table ); + } + } + return NULL; +} + +struct table *create_table( const WCHAR *name, UINT num_cols, const struct column *columns, + UINT num_rows, BYTE *data, void (*fill)(struct table *) ) +{ + struct table *table; + + if (!(table = heap_alloc( sizeof(*table) ))) return NULL; + table->name = heap_strdupW( name ); + table->num_cols = num_cols; + table->columns = columns; + table->num_rows = num_rows; + table->data = data; + table->fill = fill; + table->flags = TABLE_FLAG_DYNAMIC; + table->refs = 0; + list_init( &table->entry ); + return table; +} + +BOOL add_table( struct table *table ) +{ + struct table *iter; + + LIST_FOR_EACH_ENTRY( iter, table_list, struct table, entry ) + { + if (!strcmpiW( iter->name, table->name )) + { + TRACE("table %s already exists\n", debugstr_w(table->name)); + return FALSE; + } + } + list_add_tail( table_list, &table->entry ); + TRACE("added %p\n", table); + return TRUE; +} + +BSTR get_method_name( const WCHAR *class, UINT index ) +{ + struct table *table; + UINT i, count = 0; + BSTR ret; + + if (!(table = grab_table( class ))) return NULL; + + for (i = 0; i < table->num_cols; i++) + { + if (table->columns[i].type & COL_FLAG_METHOD) + { + if (index == count) + { + ret = SysAllocString( table->columns[i].name ); + release_table( table ); + return ret; + } + count++; + } + } + release_table( table ); + return NULL; +} + +BSTR get_property_name( const WCHAR *class, UINT index ) +{ + struct table *table; + UINT i, count = 0; + BSTR ret; + + if (!(table = grab_table( class ))) return NULL; + + for (i = 0; i < table->num_cols; i++) + { + if (!(table->columns[i].type & COL_FLAG_METHOD)) + { + if (index == count) + { + ret = SysAllocString( table->columns[i].name ); + release_table( table ); + return ret; + } + count++; + } + } + release_table( table ); + return NULL; +} diff --git a/dll/win32/wbemprox/wbemlocator.c b/dll/win32/wbemprox/wbemlocator.c new file mode 100644 index 00000000000..c92cdd48c7c --- /dev/null +++ b/dll/win32/wbemprox/wbemlocator.c @@ -0,0 +1,231 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +typedef struct +{ + IWbemLocator IWbemLocator_iface; + LONG refs; +} wbem_locator; + +static inline wbem_locator *impl_from_IWbemLocator( IWbemLocator *iface ) +{ + return CONTAINING_RECORD(iface, wbem_locator, IWbemLocator_iface); +} + +static ULONG WINAPI wbem_locator_AddRef( + IWbemLocator *iface ) +{ + wbem_locator *wl = impl_from_IWbemLocator( iface ); + return InterlockedIncrement( &wl->refs ); +} + +static ULONG WINAPI wbem_locator_Release( + IWbemLocator *iface ) +{ + wbem_locator *wl = impl_from_IWbemLocator( iface ); + LONG refs = InterlockedDecrement( &wl->refs ); + if (!refs) + { + TRACE("destroying %p\n", wl); + heap_free( wl ); + } + return refs; +} + +static HRESULT WINAPI wbem_locator_QueryInterface( + IWbemLocator *iface, + REFIID riid, + void **ppvObject ) +{ + wbem_locator *This = impl_from_IWbemLocator( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + if ( IsEqualGUID( riid, &IID_IWbemLocator ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + IWbemLocator_AddRef( iface ); + return S_OK; +} + +static BOOL is_local_machine( const WCHAR *server ) +{ + static const WCHAR dotW[] = {'.',0}; + WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD len = sizeof(buffer) / sizeof(buffer[0]); + + if (!server || !strcmpW( server, dotW )) return TRUE; + if (GetComputerNameW( buffer, &len ) && !strcmpiW( server, buffer )) return TRUE; + return FALSE; +} + +static HRESULT parse_resource( const WCHAR *resource, WCHAR **server, WCHAR **namespace ) +{ + static const WCHAR rootW[] = {'R','O','O','T'}; + static const WCHAR cimv2W[] = {'C','I','M','V','2'}; + HRESULT hr = WBEM_E_INVALID_NAMESPACE; + const WCHAR *p, *q; + unsigned int len; + + *server = NULL; + *namespace = NULL; + p = q = resource; + if (*p == '\\' || *p == '/') + { + p++; + if (*p == '\\' || *p == '/') p++; + if (!*p) return WBEM_E_INVALID_NAMESPACE; + if (*p == '\\' || *p == '/') return WBEM_E_INVALID_PARAMETER; + q = p + 1; + while (*q && *q != '\\' && *q != '/') q++; + if (!*q) return WBEM_E_INVALID_NAMESPACE; + len = q - p; + if (!(*server = heap_alloc( (len + 1) * sizeof(WCHAR) ))) + { + hr = E_OUTOFMEMORY; + goto done; + } + memcpy( *server, p, len * sizeof(WCHAR) ); + (*server)[len] = 0; + q++; + } + if (!*q) goto done; + p = q; + while (*q && *q != '\\' && *q != '/') q++; + len = q - p; + if (len >= sizeof(rootW) / sizeof(rootW[0]) && memicmpW( rootW, p, len )) goto done; + if (!*q) + { + hr = S_OK; + goto done; + } + q++; + if ((len = strlenW( q )) != sizeof(cimv2W) / sizeof(cimv2W[0]) || memicmpW( q, cimv2W, len )) + goto done; + if (!(*namespace = heap_alloc( (len + 1) * sizeof(WCHAR) ))) hr = E_OUTOFMEMORY; + else + { + memcpy( *namespace, p, len * sizeof(WCHAR) ); + (*namespace)[len] = 0; + hr = S_OK; + } + +done: + if (hr != S_OK) + { + heap_free( *server ); + heap_free( *namespace ); + } + return hr; +} + +static HRESULT WINAPI wbem_locator_ConnectServer( + IWbemLocator *iface, + const BSTR NetworkResource, + const BSTR User, + const BSTR Password, + const BSTR Locale, + LONG SecurityFlags, + const BSTR Authority, + IWbemContext *pCtx, + IWbemServices **ppNamespace) +{ + HRESULT hr; + WCHAR *server, *namespace; + + TRACE("%p, %s, %s, %s, %s, 0x%08x, %s, %p, %p)\n", iface, debugstr_w(NetworkResource), debugstr_w(User), + debugstr_w(Password), debugstr_w(Locale), SecurityFlags, debugstr_w(Authority), pCtx, ppNamespace); + + hr = parse_resource( NetworkResource, &server, &namespace ); + if (hr != S_OK) return hr; + + if (!is_local_machine( server )) + { + FIXME("remote computer not supported\n"); + heap_free( server ); + heap_free( namespace ); + return WBEM_E_TRANSPORT_FAILURE; + } + if (User || Password || Authority) + FIXME("authentication not supported\n"); + if (Locale) + FIXME("specific locale not supported\n"); + if (SecurityFlags) + FIXME("unsupported flags\n"); + + hr = WbemServices_create( NULL, namespace, (void **)ppNamespace ); + heap_free( namespace ); + if (SUCCEEDED( hr )) + return WBEM_NO_ERROR; + + return WBEM_E_FAILED; +} + +static const IWbemLocatorVtbl wbem_locator_vtbl = +{ + wbem_locator_QueryInterface, + wbem_locator_AddRef, + wbem_locator_Release, + wbem_locator_ConnectServer +}; + +HRESULT WbemLocator_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +{ + wbem_locator *wl; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + wl = heap_alloc( sizeof(*wl) ); + if (!wl) return E_OUTOFMEMORY; + + wl->IWbemLocator_iface.lpVtbl = &wbem_locator_vtbl; + wl->refs = 1; + + *ppObj = &wl->IWbemLocator_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} diff --git a/dll/win32/wbemprox/wbemprox.idl b/dll/win32/wbemprox/wbemprox.idl new file mode 100644 index 00000000000..4b19384bc7e --- /dev/null +++ b/dll/win32/wbemprox/wbemprox.idl @@ -0,0 +1,33 @@ +/* + * COM Classes for wbemprox + * + * Copyright 2010 Alexandre Julliard + * + * 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 + */ + +[ + helpstring("WBEM Locator"), + threading(both), + uuid(4590f811-1d3a-11d0-891f-00aa004b2e24) +] +coclass WbemLocator { interface IWbemLocator; } + +[ + helpstring("WBEM Administrative Locator"), + threading(both), + uuid(cb8555cc-9128-11d1-ad9b-00c04fd8fdff) +] +coclass WbemAdministrativeLocator { interface IWbemLocator; } diff --git a/dll/win32/wbemprox/wbemprox.rc b/dll/win32/wbemprox/wbemprox.rc new file mode 100644 index 00000000000..b22a92f0800 --- /dev/null +++ b/dll/win32/wbemprox/wbemprox.rc @@ -0,0 +1 @@ +1 WINE_REGISTRY wbemprox.rgs diff --git a/dll/win32/wbemprox/wbemprox.rgs b/dll/win32/wbemprox/wbemprox.rgs new file mode 100644 index 00000000000..7982412679b --- /dev/null +++ b/dll/win32/wbemprox/wbemprox.rgs @@ -0,0 +1,17 @@ +HKCR +{ + NoRemove Interface + { + } + NoRemove CLSID + { + '{4590F811-1D3A-11D0-891F-00AA004B2E24}' = s 'WBEM Locator' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + '{CB8555CC-9128-11D1-AD9B-00C04FD8FDFF}' = s 'WBEM Administrative Locator' + { + InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' } + } + } +} diff --git a/dll/win32/wbemprox/wbemprox.spec b/dll/win32/wbemprox/wbemprox.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/dll/win32/wbemprox/wbemprox.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() diff --git a/dll/win32/wbemprox/wbemprox_private.h b/dll/win32/wbemprox/wbemprox_private.h new file mode 100644 index 00000000000..efdde761eba --- /dev/null +++ b/dll/win32/wbemprox/wbemprox_private.h @@ -0,0 +1,297 @@ +/* + * Copyright 2009 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#include "wine/debug.h" +#include "wine/list.h" +#include "wine/unicode.h" + +IClientSecurity client_security; +struct list *table_list; + +#define SIZEOF(array) (sizeof(array)/sizeof((array)[0])) + +enum param_direction +{ + PARAM_OUT = -1, + PARAM_INOUT = 0, + PARAM_IN = 1 +}; + +#define CIM_TYPE_MASK 0x00000fff + +#define COL_TYPE_MASK 0x0000ffff +#define COL_FLAG_DYNAMIC 0x00010000 +#define COL_FLAG_KEY 0x00020000 +#define COL_FLAG_METHOD 0x00040000 + +typedef HRESULT (class_method)(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **); + +struct column +{ + const WCHAR *name; + UINT type; + VARTYPE vartype; /* 0 for default mapping */ +}; + +#define TABLE_FLAG_DYNAMIC 0x00000001 + +struct table +{ + const WCHAR *name; + UINT num_cols; + const struct column *columns; + UINT num_rows; + BYTE *data; + void (*fill)(struct table *); + UINT flags; + struct list entry; + LONG refs; +}; + +struct property +{ + const WCHAR *name; + const WCHAR *class; + const struct property *next; +}; + +struct array +{ + UINT count; + void *ptr; +}; + +struct field +{ + UINT type; + VARTYPE vartype; /* 0 for default mapping */ + union + { + LONGLONG ival; + WCHAR *sval; + struct array *aval; + } u; +}; + +struct record +{ + UINT count; + struct field *fields; + struct table *table; +}; + +enum operator +{ + OP_EQ = 1, + OP_AND = 2, + OP_OR = 3, + OP_GT = 4, + OP_LT = 5, + OP_LE = 6, + OP_GE = 7, + OP_NE = 8, + OP_ISNULL = 9, + OP_NOTNULL = 10, + OP_LIKE = 11 +}; + +struct expr; +struct complex_expr +{ + enum operator op; + struct expr *left; + struct expr *right; +}; + +enum expr_type +{ + EXPR_COMPLEX = 1, + EXPR_UNARY = 2, + EXPR_PROPVAL = 3, + EXPR_SVAL = 4, + EXPR_IVAL = 5, + EXPR_BVAL = 6 +}; + +struct expr +{ + enum expr_type type; + union + { + struct complex_expr expr; + const struct property *propval; + const WCHAR *sval; + int ival; + } u; +}; + +struct view +{ + const struct property *proplist; + struct table *table; + const struct expr *cond; + UINT *result; + UINT count; +}; + +struct query +{ + LONG refs; + struct view *view; + struct list mem; +}; + +struct query *addref_query( struct query * ) DECLSPEC_HIDDEN; +void release_query( struct query *query ) DECLSPEC_HIDDEN; +HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN; +HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN; +HRESULT create_view( const struct property *, const WCHAR *, const struct expr *, + struct view ** ) DECLSPEC_HIDDEN; +void destroy_view( struct view * ) DECLSPEC_HIDDEN; +void init_table_list( void ) DECLSPEC_HIDDEN; +struct table *grab_table( const WCHAR * ) DECLSPEC_HIDDEN; +struct table *addref_table( struct table * ) DECLSPEC_HIDDEN; +void release_table( struct table * ) DECLSPEC_HIDDEN; +struct table *create_table( const WCHAR *, UINT, const struct column *, UINT, + BYTE *, void (*)(struct table *)) DECLSPEC_HIDDEN; +BOOL add_table( struct table * ) DECLSPEC_HIDDEN; +void free_columns( struct column *, UINT ) DECLSPEC_HIDDEN; +void free_table( struct table * ) DECLSPEC_HIDDEN; +UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN; +HRESULT get_column_index( const struct table *, const WCHAR *, UINT * ) DECLSPEC_HIDDEN; +HRESULT get_value( const struct table *, UINT, UINT, LONGLONG * ) DECLSPEC_HIDDEN; +BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN; +HRESULT set_value( const struct table *, UINT, UINT, LONGLONG, CIMTYPE ) DECLSPEC_HIDDEN; +HRESULT get_method( const struct table *, const WCHAR *, class_method ** ) DECLSPEC_HIDDEN; +HRESULT get_propval( const struct view *, UINT, const WCHAR *, VARIANT *, + CIMTYPE *, LONG * ) DECLSPEC_HIDDEN; +HRESULT put_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYPE ) DECLSPEC_HIDDEN; +HRESULT to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN; +SAFEARRAY *to_safearray( const struct array *, CIMTYPE ) DECLSPEC_HIDDEN; +VARTYPE to_vartype( CIMTYPE ) DECLSPEC_HIDDEN; +void destroy_array( struct array *, CIMTYPE ) DECLSPEC_HIDDEN; +HRESULT get_properties( const struct view *, SAFEARRAY ** ) DECLSPEC_HIDDEN; +HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN; +BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; +BSTR get_property_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; +void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ) DECLSPEC_HIDDEN; +HRESULT create_signature( const WCHAR *, const WCHAR *, enum param_direction, + IWbemClassObject ** ) DECLSPEC_HIDDEN; + +HRESULT WbemLocator_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemServices_create(IUnknown *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT, + struct record *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemQualifierSet_create(IUnknown *, const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; + +HRESULT process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT reg_enum_values(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT reg_get_stringvalue(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_pause_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_resume_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_start_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_stop_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; + +static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static void *heap_realloc( void *mem, size_t len ) __WINE_ALLOC_SIZE(2); +static inline void *heap_realloc( void *mem, size_t len ) +{ + return HeapReAlloc( GetProcessHeap(), 0, mem, len ); +} + +static void *heap_alloc_zero( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc_zero( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +static inline WCHAR *heap_strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src ); + return dst; +} + +static inline const char *debugstr_variant( const VARIANT *v ) +{ + if (!v) return "(null)"; + switch (V_VT(v)) + { + case VT_EMPTY: + return "{VT_EMPTY}"; + case VT_NULL: + return "{VT_NULL}"; + case VT_I4: + return wine_dbg_sprintf( "{VT_I4: %d}", V_I4(v) ); + case VT_R8: + return wine_dbg_sprintf( "{VT_R8: %lf}", V_R8(v) ); + case VT_BSTR: + return wine_dbg_sprintf( "{VT_BSTR: %s}", debugstr_w(V_BSTR(v)) ); + case VT_DISPATCH: + return wine_dbg_sprintf( "{VT_DISPATCH: %p}", V_DISPATCH(v) ); + case VT_BOOL: + return wine_dbg_sprintf( "{VT_BOOL: %x}", V_BOOL(v) ); + case VT_UNKNOWN: + return wine_dbg_sprintf( "{VT_UNKNOWN: %p}", V_UNKNOWN(v) ); + case VT_UINT: + return wine_dbg_sprintf( "{VT_UINT: %u}", V_UINT(v) ); + case VT_BSTR|VT_BYREF: + return wine_dbg_sprintf( "{VT_BSTR|VT_BYREF: ptr %p, data %s}", + V_BSTRREF(v), V_BSTRREF(v) ? debugstr_w( *V_BSTRREF(v) ) : NULL ); + default: + return wine_dbg_sprintf( "{vt %d}", V_VT(v) ); + } +} + +static const WCHAR class_processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0}; +static const WCHAR class_serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e',0}; +static const WCHAR class_stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0}; + +static const WCHAR prop_nameW[] = {'N','a','m','e',0}; + +static const WCHAR method_enumkeyW[] = {'E','n','u','m','K','e','y',0}; +static const WCHAR method_enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0}; +static const WCHAR method_getownerW[] = {'G','e','t','O','w','n','e','r',0}; +static const WCHAR method_getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0}; +static const WCHAR method_pauseserviceW[] = {'P','a','u','s','e','S','e','r','v','i','c','e',0}; +static const WCHAR method_resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0}; +static const WCHAR method_startserviceW[] = {'S','t','a','r','t','S','e','r','v','i','c','e',0}; +static const WCHAR method_stopserviceW[] = {'S','t','o','p','S','e','r','v','i','c','e',0}; + +static const WCHAR param_defkeyW[] = {'h','D','e','f','K','e','y',0}; +static const WCHAR param_domainW[] = {'D','o','m','a','i','n',0}; +static const WCHAR param_namesW[] = {'s','N','a','m','e','s',0}; +static const WCHAR param_returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0}; +static const WCHAR param_subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0}; +static const WCHAR param_typesW[] = {'T','y','p','e','s',0}; +static const WCHAR param_userW[] = {'U','s','e','r',0}; +static const WCHAR param_valueW[] = {'s','V','a','l','u','e',0}; +static const WCHAR param_valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0}; diff --git a/dll/win32/wbemprox/wql.tab.c b/dll/win32/wbemprox/wql.tab.c new file mode 100644 index 00000000000..42b850b561b --- /dev/null +++ b/dll/win32/wbemprox/wql.tab.c @@ -0,0 +1,2437 @@ + +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse wql_parse +#define yylex wql_lex +#define yyerror wql_error +#define yylval wql_lval +#define yychar wql_char +#define yydebug wql_debug +#define yynerrs wql_nerrs + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "wql.y" + + +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "wbemcli.h" +#include "wbemprox_private.h" + +#include "wine/list.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +#define YYLEX_PARAM ctx +#define YYPARSE_PARAM ctx +#define YYERROR_DEBUG 1 +#define YYERROR_VERBOSE 1 + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +struct parser +{ + const WCHAR *cmd; + UINT idx; + UINT len; + HRESULT error; + struct view **view; + struct list *mem; +}; + +struct string +{ + const WCHAR *data; + int len; +}; + +static void *alloc_mem( struct parser *parser, UINT size ) +{ + struct list *mem = heap_alloc( sizeof(struct list) + size ); + list_add_tail( parser->mem, mem ); + return &mem[1]; +} + +static struct property *alloc_property( struct parser *parser, const WCHAR *class, const WCHAR *name ) +{ + struct property *prop = alloc_mem( parser, sizeof(*prop) ); + if (prop) + { + prop->name = name; + prop->class = class; + prop->next = NULL; + } + return prop; +} + +static WCHAR *get_string( struct parser *parser, const struct string *str ) +{ + const WCHAR *p = str->data; + int len = str->len; + WCHAR *ret; + + if ((p[0] == '\"' && p[len - 1] != '\"') || + (p[0] == '\'' && p[len - 1] != '\'')) return NULL; + if ((p[0] == '\"' && p[len - 1] == '\"') || + (p[0] == '\'' && p[len - 1] == '\'')) + { + p++; + len -= 2; + } + if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL; + memcpy( ret, p, len * sizeof(WCHAR) ); + ret[len] = 0; + return ret; +} + +static int get_int( struct parser *parser ) +{ + const WCHAR *p = &parser->cmd[parser->idx]; + int i, ret = 0; + + for (i = 0; i < parser->len; i++) + { + if (p[i] < '0' || p[i] > '9') + { + ERR("should only be numbers here!\n"); + break; + } + ret = (p[i] - '0') + ret * 10; + } + return ret; +} + +static struct expr *expr_complex( struct parser *parser, struct expr *l, UINT op, struct expr *r ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_COMPLEX; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = r; + } + return e; +} + +static struct expr *expr_unary( struct parser *parser, struct expr *l, UINT op ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_UNARY; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = NULL; + } + return e; +} + +static struct expr *expr_ival( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_IVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_sval( struct parser *parser, const struct string *str ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_SVAL; + e->u.sval = get_string( parser, str ); + if (!e->u.sval) + return NULL; /* e will be freed by query destructor */ + } + return e; +} + +static struct expr *expr_bval( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_BVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_propval( struct parser *parser, const struct property *prop ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_PROPVAL; + e->u.propval = prop; + } + return e; +} + +static int wql_error( const char *str ); +static int wql_lex( void *val, struct parser *parser ); + +#define PARSER_BUBBLE_UP_VIEW( parser, result, current_view ) \ + *parser->view = current_view; \ + result = current_view + + + +/* Line 189 of yacc.c */ +#line 274 "wql.tab.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + TK_SELECT = 258, + TK_FROM = 259, + TK_STAR = 260, + TK_COMMA = 261, + TK_DOT = 262, + TK_IS = 263, + TK_LP = 264, + TK_RP = 265, + TK_NULL = 266, + TK_FALSE = 267, + TK_TRUE = 268, + TK_INTEGER = 269, + TK_WHERE = 270, + TK_SPACE = 271, + TK_MINUS = 272, + TK_ILLEGAL = 273, + TK_BY = 274, + TK_STRING = 275, + TK_ID = 276, + TK_OR = 277, + TK_AND = 278, + TK_NOT = 279, + TK_LIKE = 280, + TK_GE = 281, + TK_LE = 282, + TK_GT = 283, + TK_LT = 284, + TK_NE = 285, + TK_EQ = 286 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 196 "wql.y" + + struct string str; + WCHAR *string; + struct property *proplist; + struct view *view; + struct expr *expr; + int integer; + + + +/* Line 214 of yacc.c */ +#line 352 "wql.tab.c" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 364 "wql.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 9 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 67 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 32 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 10 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 35 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 65 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 286 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 7, 12, 19, 21, 25, 27, 31, + 33, 35, 37, 41, 45, 49, 53, 57, 61, 65, + 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, + 110, 112, 114, 116, 118, 120 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 33, 0, -1, 3, 4, 36, -1, 3, 34, 4, + 36, -1, 3, 34, 4, 36, 15, 38, -1, 35, + -1, 35, 6, 34, -1, 5, -1, 36, 7, 36, + -1, 36, -1, 21, -1, 14, -1, 9, 38, 10, + -1, 38, 23, 38, -1, 38, 22, 38, -1, 40, + 31, 41, -1, 40, 28, 41, -1, 40, 29, 41, + -1, 40, 27, 41, -1, 40, 26, 41, -1, 40, + 30, 41, -1, 41, 31, 40, -1, 41, 28, 40, + -1, 41, 29, 40, -1, 41, 27, 40, -1, 41, + 26, 40, -1, 41, 30, 40, -1, 40, 25, 39, + -1, 40, 8, 11, -1, 40, 8, 24, 11, -1, + 20, -1, 35, -1, 37, -1, 20, -1, 13, -1, + 12, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 223, 223, 235, 247, 262, 263, 267, 274, 280, + 289, 298, 305, 311, 317, 323, 329, 335, 341, 347, + 353, 359, 365, 371, 377, 383, 389, 395, 401, 407, + 416, 425, 434, 440, 446, 452 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "TK_SELECT", "TK_FROM", "TK_STAR", + "TK_COMMA", "TK_DOT", "TK_IS", "TK_LP", "TK_RP", "TK_NULL", "TK_FALSE", + "TK_TRUE", "TK_INTEGER", "TK_WHERE", "TK_SPACE", "TK_MINUS", + "TK_ILLEGAL", "TK_BY", "TK_STRING", "TK_ID", "TK_OR", "TK_AND", "TK_NOT", + "TK_LIKE", "TK_GE", "TK_LE", "TK_GT", "TK_LT", "TK_NE", "TK_EQ", + "$accept", "select", "proplist", "prop", "id", "number", "expr", + "string_val", "prop_val", "const_val", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 32, 33, 33, 33, 34, 34, 34, 35, 35, + 36, 37, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 39, 40, 41, 41, 41, 41 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 3, 4, 6, 1, 3, 1, 3, 1, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, + 1, 1, 1, 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 7, 10, 0, 5, 9, 1, + 2, 0, 0, 0, 3, 6, 8, 0, 0, 35, + 34, 11, 33, 31, 32, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 14, 13, 28, 0, + 30, 27, 19, 18, 16, 17, 20, 15, 25, 24, + 22, 23, 26, 21, 29 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 6, 23, 8, 24, 25, 51, 26, 27 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -20 +static const yytype_int8 yypact[] = +{ + 2, 3, 6, -10, -20, -20, 24, 31, 33, -20, + -20, -10, 4, -10, 26, -20, -20, 18, 18, -20, + -20, -20, -20, -20, -20, -19, -8, 20, -9, 18, + 18, 5, 23, 22, 22, 22, 22, 22, 22, -10, + -10, -10, -10, -10, -10, -20, 41, -20, -20, 54, + -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, + -20, -20, -20, -20, -20 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -20, -20, 55, 14, -1, -20, 15, -20, 13, 25 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 31, 45, 10, 29, 30, 1, 9, 3, 4, 4, + 14, 5, 16, 29, 30, 7, 48, 32, 33, 34, + 35, 36, 37, 38, 5, 5, 7, 18, 11, 49, + 19, 20, 21, 28, 19, 20, 21, 12, 22, 5, + 13, 17, 22, 50, 46, 47, 39, 40, 41, 42, + 43, 44, 58, 59, 60, 61, 62, 63, 52, 53, + 54, 55, 56, 57, 30, 64, 0, 15 +}; + +static const yytype_int8 yycheck[] = +{ + 8, 10, 3, 22, 23, 3, 0, 4, 5, 5, + 11, 21, 13, 22, 23, 1, 11, 25, 26, 27, + 28, 29, 30, 31, 21, 21, 12, 9, 4, 24, + 12, 13, 14, 18, 12, 13, 14, 6, 20, 21, + 7, 15, 20, 20, 29, 30, 26, 27, 28, 29, + 30, 31, 39, 40, 41, 42, 43, 44, 33, 34, + 35, 36, 37, 38, 23, 11, -1, 12 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 33, 4, 5, 21, 34, 35, 36, 0, + 36, 4, 6, 7, 36, 34, 36, 15, 9, 12, + 13, 14, 20, 35, 37, 38, 40, 41, 38, 22, + 23, 8, 25, 26, 27, 28, 29, 30, 31, 26, + 27, 28, 29, 30, 31, 10, 38, 38, 11, 24, + 20, 39, 41, 41, 41, 41, 41, 41, 40, 40, + 40, 40, 40, 40, 11 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + +/* Line 1455 of yacc.c */ +#line 224 "wql.y" + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( NULL, (yyvsp[(3) - (3)].string), NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view ); + ;} + break; + + case 3: + +/* Line 1455 of yacc.c */ +#line 236 "wql.y" + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( (yyvsp[(2) - (4)].proplist), (yyvsp[(4) - (4)].string), NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view ); + ;} + break; + + case 4: + +/* Line 1455 of yacc.c */ +#line 248 "wql.y" + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( (yyvsp[(2) - (6)].proplist), (yyvsp[(4) - (6)].string), (yyvsp[(6) - (6)].expr), &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, (yyval.view), view ); + ;} + break; + + case 6: + +/* Line 1455 of yacc.c */ +#line 264 "wql.y" + { + (yyvsp[(1) - (3)].proplist)->next = (yyvsp[(3) - (3)].proplist); + ;} + break; + + case 7: + +/* Line 1455 of yacc.c */ +#line 268 "wql.y" + { + (yyval.proplist) = NULL; + ;} + break; + + case 8: + +/* Line 1455 of yacc.c */ +#line 275 "wql.y" + { + (yyval.proplist) = alloc_property( ctx, (yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string) ); + if (!(yyval.proplist)) + YYABORT; + ;} + break; + + case 9: + +/* Line 1455 of yacc.c */ +#line 281 "wql.y" + { + (yyval.proplist) = alloc_property( ctx, NULL, (yyvsp[(1) - (1)].string) ); + if (!(yyval.proplist)) + YYABORT; + ;} + break; + + case 10: + +/* Line 1455 of yacc.c */ +#line 290 "wql.y" + { + (yyval.string) = get_string( ctx, &(yyvsp[(1) - (1)].str) ); + if (!(yyval.string)) + YYABORT; + ;} + break; + + case 11: + +/* Line 1455 of yacc.c */ +#line 299 "wql.y" + { + (yyval.integer) = get_int( ctx ); + ;} + break; + + case 12: + +/* Line 1455 of yacc.c */ +#line 306 "wql.y" + { + (yyval.expr) = (yyvsp[(2) - (3)].expr); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 13: + +/* Line 1455 of yacc.c */ +#line 312 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_AND, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 14: + +/* Line 1455 of yacc.c */ +#line 318 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_OR, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 15: + +/* Line 1455 of yacc.c */ +#line 324 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 16: + +/* Line 1455 of yacc.c */ +#line 330 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 17: + +/* Line 1455 of yacc.c */ +#line 336 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 18: + +/* Line 1455 of yacc.c */ +#line 342 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 19: + +/* Line 1455 of yacc.c */ +#line 348 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 20: + +/* Line 1455 of yacc.c */ +#line 354 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 21: + +/* Line 1455 of yacc.c */ +#line 360 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 22: + +/* Line 1455 of yacc.c */ +#line 366 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 23: + +/* Line 1455 of yacc.c */ +#line 372 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 24: + +/* Line 1455 of yacc.c */ +#line 378 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 25: + +/* Line 1455 of yacc.c */ +#line 384 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 26: + +/* Line 1455 of yacc.c */ +#line 390 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 27: + +/* Line 1455 of yacc.c */ +#line 396 "wql.y" + { + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LIKE, (yyvsp[(3) - (3)].expr) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 28: + +/* Line 1455 of yacc.c */ +#line 402 "wql.y" + { + (yyval.expr) = expr_unary( ctx, (yyvsp[(1) - (3)].expr), OP_ISNULL ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 29: + +/* Line 1455 of yacc.c */ +#line 408 "wql.y" + { + (yyval.expr) = expr_unary( ctx, (yyvsp[(1) - (4)].expr), OP_NOTNULL ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 30: + +/* Line 1455 of yacc.c */ +#line 417 "wql.y" + { + (yyval.expr) = expr_sval( ctx, &(yyvsp[(1) - (1)].str) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 31: + +/* Line 1455 of yacc.c */ +#line 426 "wql.y" + { + (yyval.expr) = expr_propval( ctx, (yyvsp[(1) - (1)].proplist) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 32: + +/* Line 1455 of yacc.c */ +#line 435 "wql.y" + { + (yyval.expr) = expr_ival( ctx, (yyvsp[(1) - (1)].integer) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 33: + +/* Line 1455 of yacc.c */ +#line 441 "wql.y" + { + (yyval.expr) = expr_sval( ctx, &(yyvsp[(1) - (1)].str) ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 34: + +/* Line 1455 of yacc.c */ +#line 447 "wql.y" + { + (yyval.expr) = expr_bval( ctx, -1 ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + case 35: + +/* Line 1455 of yacc.c */ +#line 453 "wql.y" + { + (yyval.expr) = expr_bval( ctx, 0 ); + if (!(yyval.expr)) + YYABORT; + ;} + break; + + + +/* Line 1455 of yacc.c */ +#line 1980 "wql.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 460 "wql.y" + + +HRESULT parse_query( const WCHAR *str, struct view **view, struct list *mem ) +{ + struct parser parser; + int ret; + + *view = NULL; + + parser.cmd = str; + parser.idx = 0; + parser.len = 0; + parser.error = WBEM_E_INVALID_QUERY; + parser.view = view; + parser.mem = mem; + + ret = wql_parse( &parser ); + TRACE("wql_parse returned %d\n", ret); + if (ret) + { + if (*parser.view) + { + destroy_view( *parser.view ); + *parser.view = NULL; + } + return parser.error; + } + return S_OK; +} + +static const char id_char[] = +{ + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +struct keyword +{ + const WCHAR *name; + unsigned int len; + int type; +}; + +#define MAX_TOKEN_LEN 6 + +static const WCHAR andW[] = {'A','N','D'}; +static const WCHAR byW[] = {'B','Y'}; +static const WCHAR falseW[] = {'F','A','L','S','E'}; +static const WCHAR fromW[] = {'F','R','O','M'}; +static const WCHAR isW[] = {'I','S'}; +static const WCHAR likeW[] = {'L','I','K','E'}; +static const WCHAR notW[] = {'N','O','T'}; +static const WCHAR nullW[] = {'N','U','L','L'}; +static const WCHAR orW[] = {'O','R'}; +static const WCHAR selectW[] = {'S','E','L','E','C','T'}; +static const WCHAR trueW[] = {'T','R','U','E'}; +static const WCHAR whereW[] = {'W','H','E','R','E'}; + +static const struct keyword keyword_table[] = +{ + { andW, SIZEOF(andW), TK_AND }, + { byW, SIZEOF(byW), TK_BY }, + { falseW, SIZEOF(falseW), TK_FALSE }, + { fromW, SIZEOF(fromW), TK_FROM }, + { isW, SIZEOF(isW), TK_IS }, + { likeW, SIZEOF(likeW), TK_LIKE }, + { notW, SIZEOF(notW), TK_NOT }, + { nullW, SIZEOF(nullW), TK_NULL }, + { orW, SIZEOF(orW), TK_OR }, + { selectW, SIZEOF(selectW), TK_SELECT }, + { trueW, SIZEOF(trueW), TK_TRUE }, + { whereW, SIZEOF(whereW), TK_WHERE } +}; + +static int cmp_keyword( const void *arg1, const void *arg2 ) +{ + const struct keyword *key1 = arg1, *key2 = arg2; + int len = min( key1->len, key2->len ); + int ret; + + if ((ret = memicmpW( key1->name, key2->name, len ))) return ret; + if (key1->len < key2->len) return -1; + else if (key1->len > key2->len) return 1; + return 0; +} + +static int keyword_type( const WCHAR *str, unsigned int len ) +{ + struct keyword key, *ret; + + if (len > MAX_TOKEN_LEN) return TK_ID; + + key.name = str; + key.len = len; + key.type = 0; + ret = bsearch( &key, keyword_table, SIZEOF(keyword_table), sizeof(struct keyword), cmp_keyword ); + if (ret) return ret->type; + return TK_ID; +} + +static int get_token( const WCHAR *s, int *token ) +{ + int i; + + switch (*s) + { + case ' ': + case '\t': + case '\n': + for (i = 1; isspaceW( s[i] ); i++) {} + *token = TK_SPACE; + return i; + case '-': + if (!s[1]) return -1; + *token = TK_MINUS; + return 1; + case '(': + *token = TK_LP; + return 1; + case ')': + *token = TK_RP; + return 1; + case '*': + *token = TK_STAR; + return 1; + case '=': + *token = TK_EQ; + return 1; + case '<': + if (s[1] == '=' ) + { + *token = TK_LE; + return 2; + } + else if (s[1] == '>') + { + *token = TK_NE; + return 2; + } + else + { + *token = TK_LT; + return 1; + } + case '>': + if (s[1] == '=') + { + *token = TK_GE; + return 2; + } + else + { + *token = TK_GT; + return 1; + } + case '!': + if (s[1] != '=') + { + *token = TK_ILLEGAL; + return 2; + } + else + { + *token = TK_NE; + return 2; + } + case ',': + *token = TK_COMMA; + return 1; + case '\"': + case '\'': + { + for (i = 1; s[i]; i++) + { + if (s[i] == s[0]) break; + } + if (s[i]) i++; + *token = TK_STRING; + return i; + } + case '.': + if (!isdigitW( s[1] )) + { + *token = TK_DOT; + return 1; + } + /* fall through */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *token = TK_INTEGER; + for (i = 1; isdigitW( s[i] ); i++) {} + return i; + default: + if (!id_char[*s]) break; + + for (i = 1; id_char[s[i]]; i++) {} + *token = keyword_type( s, i ); + return i; + } + *token = TK_ILLEGAL; + return 1; +} + +static int wql_lex( void *p, struct parser *parser ) +{ + struct string *str = p; + int token = -1; + do + { + parser->idx += parser->len; + if (!parser->cmd[parser->idx]) return 0; + parser->len = get_token( &parser->cmd[parser->idx], &token ); + if (!parser->len) break; + + str->data = &parser->cmd[parser->idx]; + str->len = parser->len; + } while (token == TK_SPACE); + return token; +} + +static int wql_error( const char *str ) +{ + ERR("%s\n", str); + return 0; +} + diff --git a/dll/win32/wbemprox/wql.y b/dll/win32/wbemprox/wql.y new file mode 100644 index 00000000000..8e347c22e5b --- /dev/null +++ b/dll/win32/wbemprox/wql.y @@ -0,0 +1,698 @@ +%{ + +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#include "config.h" +#include + +#include "windef.h" +#include "winbase.h" +#include "wbemcli.h" +#include "wbemprox_private.h" + +#include "wine/list.h" +#include "wine/debug.h" +#include "wine/unicode.h" + +#define YYLEX_PARAM ctx +#define YYPARSE_PARAM ctx +#define YYERROR_DEBUG 1 +#define YYERROR_VERBOSE 1 + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +struct parser +{ + const WCHAR *cmd; + UINT idx; + UINT len; + HRESULT error; + struct view **view; + struct list *mem; +}; + +struct string +{ + const WCHAR *data; + int len; +}; + +static void *alloc_mem( struct parser *parser, UINT size ) +{ + struct list *mem = heap_alloc( sizeof(struct list) + size ); + list_add_tail( parser->mem, mem ); + return &mem[1]; +} + +static struct property *alloc_property( struct parser *parser, const WCHAR *class, const WCHAR *name ) +{ + struct property *prop = alloc_mem( parser, sizeof(*prop) ); + if (prop) + { + prop->name = name; + prop->class = class; + prop->next = NULL; + } + return prop; +} + +static WCHAR *get_string( struct parser *parser, const struct string *str ) +{ + const WCHAR *p = str->data; + int len = str->len; + WCHAR *ret; + + if ((p[0] == '\"' && p[len - 1] != '\"') || + (p[0] == '\'' && p[len - 1] != '\'')) return NULL; + if ((p[0] == '\"' && p[len - 1] == '\"') || + (p[0] == '\'' && p[len - 1] == '\'')) + { + p++; + len -= 2; + } + if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL; + memcpy( ret, p, len * sizeof(WCHAR) ); + ret[len] = 0; + return ret; +} + +static int get_int( struct parser *parser ) +{ + const WCHAR *p = &parser->cmd[parser->idx]; + int i, ret = 0; + + for (i = 0; i < parser->len; i++) + { + if (p[i] < '0' || p[i] > '9') + { + ERR("should only be numbers here!\n"); + break; + } + ret = (p[i] - '0') + ret * 10; + } + return ret; +} + +static struct expr *expr_complex( struct parser *parser, struct expr *l, UINT op, struct expr *r ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_COMPLEX; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = r; + } + return e; +} + +static struct expr *expr_unary( struct parser *parser, struct expr *l, UINT op ) +{ + struct expr *e = alloc_mem( parser, sizeof(*e) ); + if (e) + { + e->type = EXPR_UNARY; + e->u.expr.left = l; + e->u.expr.op = op; + e->u.expr.right = NULL; + } + return e; +} + +static struct expr *expr_ival( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_IVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_sval( struct parser *parser, const struct string *str ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_SVAL; + e->u.sval = get_string( parser, str ); + if (!e->u.sval) + return NULL; /* e will be freed by query destructor */ + } + return e; +} + +static struct expr *expr_bval( struct parser *parser, int val ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_BVAL; + e->u.ival = val; + } + return e; +} + +static struct expr *expr_propval( struct parser *parser, const struct property *prop ) +{ + struct expr *e = alloc_mem( parser, sizeof *e ); + if (e) + { + e->type = EXPR_PROPVAL; + e->u.propval = prop; + } + return e; +} + +static int wql_error( const char *str ); +static int wql_lex( void *val, struct parser *parser ); + +#define PARSER_BUBBLE_UP_VIEW( parser, result, current_view ) \ + *parser->view = current_view; \ + result = current_view + +%} + +%pure-parser + +%union +{ + struct string str; + WCHAR *string; + struct property *proplist; + struct view *view; + struct expr *expr; + int integer; +} + +%token TK_SELECT TK_FROM TK_STAR TK_COMMA TK_DOT TK_IS TK_LP TK_RP TK_NULL TK_FALSE TK_TRUE +%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY +%token TK_STRING TK_ID + +%type id +%type prop proplist +%type select +%type expr prop_val const_val string_val +%type number + +%left TK_OR +%left TK_AND +%left TK_NOT +%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE + +%% + +select: + TK_SELECT TK_FROM id + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( NULL, $3, NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, $$, view ); + } + | TK_SELECT proplist TK_FROM id + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( $2, $4, NULL, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, $$, view ); + } + | TK_SELECT proplist TK_FROM id TK_WHERE expr + { + HRESULT hr; + struct parser *parser = ctx; + struct view *view; + + hr = create_view( $2, $4, $6, &view ); + if (hr != S_OK) + YYABORT; + + PARSER_BUBBLE_UP_VIEW( parser, $$, view ); + } + ; + +proplist: + prop + | prop TK_COMMA proplist + { + $1->next = $3; + } + | TK_STAR + { + $$ = NULL; + } + ; + +prop: + id TK_DOT id + { + $$ = alloc_property( ctx, $1, $3 ); + if (!$$) + YYABORT; + } + | id + { + $$ = alloc_property( ctx, NULL, $1 ); + if (!$$) + YYABORT; + } + ; + +id: + TK_ID + { + $$ = get_string( ctx, &$1 ); + if (!$$) + YYABORT; + } + ; + +number: + TK_INTEGER + { + $$ = get_int( ctx ); + } + ; + +expr: + TK_LP expr TK_RP + { + $$ = $2; + if (!$$) + YYABORT; + } + | expr TK_AND expr + { + $$ = expr_complex( ctx, $1, OP_AND, $3 ); + if (!$$) + YYABORT; + } + | expr TK_OR expr + { + $$ = expr_complex( ctx, $1, OP_OR, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_EQ const_val + { + $$ = expr_complex( ctx, $1, OP_EQ, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_GT const_val + { + $$ = expr_complex( ctx, $1, OP_GT, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_LT const_val + { + $$ = expr_complex( ctx, $1, OP_LT, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_LE const_val + { + $$ = expr_complex( ctx, $1, OP_LE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_GE const_val + { + $$ = expr_complex( ctx, $1, OP_GE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_NE const_val + { + $$ = expr_complex( ctx, $1, OP_NE, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_EQ prop_val + { + $$ = expr_complex( ctx, $1, OP_EQ, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_GT prop_val + { + $$ = expr_complex( ctx, $1, OP_GT, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_LT prop_val + { + $$ = expr_complex( ctx, $1, OP_LT, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_LE prop_val + { + $$ = expr_complex( ctx, $1, OP_LE, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_GE prop_val + { + $$ = expr_complex( ctx, $1, OP_GE, $3 ); + if (!$$) + YYABORT; + } + | const_val TK_NE prop_val + { + $$ = expr_complex( ctx, $1, OP_NE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_LIKE string_val + { + $$ = expr_complex( ctx, $1, OP_LIKE, $3 ); + if (!$$) + YYABORT; + } + | prop_val TK_IS TK_NULL + { + $$ = expr_unary( ctx, $1, OP_ISNULL ); + if (!$$) + YYABORT; + } + | prop_val TK_IS TK_NOT TK_NULL + { + $$ = expr_unary( ctx, $1, OP_NOTNULL ); + if (!$$) + YYABORT; + } + ; + +string_val: + TK_STRING + { + $$ = expr_sval( ctx, &$1 ); + if (!$$) + YYABORT; + } + ; + +prop_val: + prop + { + $$ = expr_propval( ctx, $1 ); + if (!$$) + YYABORT; + } + ; + +const_val: + number + { + $$ = expr_ival( ctx, $1 ); + if (!$$) + YYABORT; + } + | TK_STRING + { + $$ = expr_sval( ctx, &$1 ); + if (!$$) + YYABORT; + } + | TK_TRUE + { + $$ = expr_bval( ctx, -1 ); + if (!$$) + YYABORT; + } + | TK_FALSE + { + $$ = expr_bval( ctx, 0 ); + if (!$$) + YYABORT; + } + ; + +%% + +HRESULT parse_query( const WCHAR *str, struct view **view, struct list *mem ) +{ + struct parser parser; + int ret; + + *view = NULL; + + parser.cmd = str; + parser.idx = 0; + parser.len = 0; + parser.error = WBEM_E_INVALID_QUERY; + parser.view = view; + parser.mem = mem; + + ret = wql_parse( &parser ); + TRACE("wql_parse returned %d\n", ret); + if (ret) + { + if (*parser.view) + { + destroy_view( *parser.view ); + *parser.view = NULL; + } + return parser.error; + } + return S_OK; +} + +static const char id_char[] = +{ + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +struct keyword +{ + const WCHAR *name; + unsigned int len; + int type; +}; + +#define MAX_TOKEN_LEN 6 + +static const WCHAR andW[] = {'A','N','D'}; +static const WCHAR byW[] = {'B','Y'}; +static const WCHAR falseW[] = {'F','A','L','S','E'}; +static const WCHAR fromW[] = {'F','R','O','M'}; +static const WCHAR isW[] = {'I','S'}; +static const WCHAR likeW[] = {'L','I','K','E'}; +static const WCHAR notW[] = {'N','O','T'}; +static const WCHAR nullW[] = {'N','U','L','L'}; +static const WCHAR orW[] = {'O','R'}; +static const WCHAR selectW[] = {'S','E','L','E','C','T'}; +static const WCHAR trueW[] = {'T','R','U','E'}; +static const WCHAR whereW[] = {'W','H','E','R','E'}; + +static const struct keyword keyword_table[] = +{ + { andW, SIZEOF(andW), TK_AND }, + { byW, SIZEOF(byW), TK_BY }, + { falseW, SIZEOF(falseW), TK_FALSE }, + { fromW, SIZEOF(fromW), TK_FROM }, + { isW, SIZEOF(isW), TK_IS }, + { likeW, SIZEOF(likeW), TK_LIKE }, + { notW, SIZEOF(notW), TK_NOT }, + { nullW, SIZEOF(nullW), TK_NULL }, + { orW, SIZEOF(orW), TK_OR }, + { selectW, SIZEOF(selectW), TK_SELECT }, + { trueW, SIZEOF(trueW), TK_TRUE }, + { whereW, SIZEOF(whereW), TK_WHERE } +}; + +static int cmp_keyword( const void *arg1, const void *arg2 ) +{ + const struct keyword *key1 = arg1, *key2 = arg2; + int len = min( key1->len, key2->len ); + int ret; + + if ((ret = memicmpW( key1->name, key2->name, len ))) return ret; + if (key1->len < key2->len) return -1; + else if (key1->len > key2->len) return 1; + return 0; +} + +static int keyword_type( const WCHAR *str, unsigned int len ) +{ + struct keyword key, *ret; + + if (len > MAX_TOKEN_LEN) return TK_ID; + + key.name = str; + key.len = len; + key.type = 0; + ret = bsearch( &key, keyword_table, SIZEOF(keyword_table), sizeof(struct keyword), cmp_keyword ); + if (ret) return ret->type; + return TK_ID; +} + +static int get_token( const WCHAR *s, int *token ) +{ + int i; + + switch (*s) + { + case ' ': + case '\t': + case '\n': + for (i = 1; isspaceW( s[i] ); i++) {} + *token = TK_SPACE; + return i; + case '-': + if (!s[1]) return -1; + *token = TK_MINUS; + return 1; + case '(': + *token = TK_LP; + return 1; + case ')': + *token = TK_RP; + return 1; + case '*': + *token = TK_STAR; + return 1; + case '=': + *token = TK_EQ; + return 1; + case '<': + if (s[1] == '=' ) + { + *token = TK_LE; + return 2; + } + else if (s[1] == '>') + { + *token = TK_NE; + return 2; + } + else + { + *token = TK_LT; + return 1; + } + case '>': + if (s[1] == '=') + { + *token = TK_GE; + return 2; + } + else + { + *token = TK_GT; + return 1; + } + case '!': + if (s[1] != '=') + { + *token = TK_ILLEGAL; + return 2; + } + else + { + *token = TK_NE; + return 2; + } + case ',': + *token = TK_COMMA; + return 1; + case '\"': + case '\'': + { + for (i = 1; s[i]; i++) + { + if (s[i] == s[0]) break; + } + if (s[i]) i++; + *token = TK_STRING; + return i; + } + case '.': + if (!isdigitW( s[1] )) + { + *token = TK_DOT; + return 1; + } + /* fall through */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *token = TK_INTEGER; + for (i = 1; isdigitW( s[i] ); i++) {} + return i; + default: + if (!id_char[*s]) break; + + for (i = 1; id_char[s[i]]; i++) {} + *token = keyword_type( s, i ); + return i; + } + *token = TK_ILLEGAL; + return 1; +} + +static int wql_lex( void *p, struct parser *parser ) +{ + struct string *str = p; + int token = -1; + do + { + parser->idx += parser->len; + if (!parser->cmd[parser->idx]) return 0; + parser->len = get_token( &parser->cmd[parser->idx], &token ); + if (!parser->len) break; + + str->data = &parser->cmd[parser->idx]; + str->len = parser->len; + } while (token == TK_SPACE); + return token; +} + +static int wql_error( const char *str ) +{ + ERR("%s\n", str); + return 0; +} diff --git a/drivers/base/CMakeLists.txt b/drivers/base/CMakeLists.txt index af805ceb1da..2a539a84aef 100644 --- a/drivers/base/CMakeLists.txt +++ b/drivers/base/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(beep) add_subdirectory(bootvid) +add_subdirectory(condrv) if(_WINKD_) add_subdirectory(kdcom) diff --git a/drivers/base/condrv/CMakeLists.txt b/drivers/base/condrv/CMakeLists.txt new file mode 100644 index 00000000000..ab53c8ebc5c --- /dev/null +++ b/drivers/base/condrv/CMakeLists.txt @@ -0,0 +1,18 @@ + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/drivers) + +## spec2def(condrv.sys condrv.spec ADD_IMPORTLIB) + +add_library(condrv SHARED + condrv.c + control.c + condrv.rc) + # ${CMAKE_CURRENT_BINARY_DIR}/condrv.def) + +add_pch(condrv condrv.h) + +set_module_type(condrv kernelmodedriver) +target_link_libraries(condrv ${PSEH_LIB}) +add_importlibs(condrv ntoskrnl hal) + +add_cd_file(TARGET condrv DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/drivers/base/condrv/condrv.c b/drivers/base/condrv/condrv.c new file mode 100644 index 00000000000..7d1e2367e30 --- /dev/null +++ b/drivers/base/condrv/condrv.c @@ -0,0 +1,173 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/condrv.c + * PURPOSE: Console Driver Management Functions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "condrv.h" + +#define NDEBUG +#include + + +/* FUNCTIONS ******************************************************************/ + +/* + * Callback functions prototypes + */ +DRIVER_INITIALIZE DriverEntry; +DRIVER_UNLOAD ConDrvUnload; +/* +DRIVER_DISPATCH ConDrvIoControl; +DRIVER_DISPATCH ConDrvCreate; +DRIVER_DISPATCH ConDrvClose; +DRIVER_DISPATCH ConDrvRead; +DRIVER_DISPATCH ConDrvWrite; +DRIVER_DISPATCH ConDrvCleanup; +*/ +DRIVER_DISPATCH ConDrvDispatch; + +NTSTATUS NTAPI +CompleteRequest(IN PIRP Irp, + IN NTSTATUS Status, + IN ULONG_PTR Information) +{ + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = Information; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +NTSTATUS NTAPI +ConDrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) +{ +#define HANDLE_CTRL_CODE(Code) \ + case Code : \ + { \ + DPRINT1("ConDrv: " #Code ", stack->FileObject = 0x%p\n", stack->FileObject); \ + if (stack->FileObject) \ + { \ + DPRINT1("stack->FileObject->FileName = %wZ\n", &stack->FileObject->FileName); \ + } \ + break; \ + } + + PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); + // ULONG ctrlCode = stack->Parameters.DeviceIoControl.IoControlCode; + ULONG MajorFunction = stack->MajorFunction; + + /* Just display all the IRP codes for now... */ + switch (MajorFunction) + { + HANDLE_CTRL_CODE(IRP_MJ_CREATE); + HANDLE_CTRL_CODE(IRP_MJ_CREATE_NAMED_PIPE); + HANDLE_CTRL_CODE(IRP_MJ_CLOSE); + HANDLE_CTRL_CODE(IRP_MJ_READ); + HANDLE_CTRL_CODE(IRP_MJ_WRITE); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_SET_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_EA); + HANDLE_CTRL_CODE(IRP_MJ_SET_EA); + HANDLE_CTRL_CODE(IRP_MJ_FLUSH_BUFFERS); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_VOLUME_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_SET_VOLUME_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_DIRECTORY_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_FILE_SYSTEM_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_DEVICE_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_INTERNAL_DEVICE_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_SHUTDOWN); + HANDLE_CTRL_CODE(IRP_MJ_LOCK_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_CLEANUP); + HANDLE_CTRL_CODE(IRP_MJ_CREATE_MAILSLOT); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_SECURITY); + HANDLE_CTRL_CODE(IRP_MJ_SET_SECURITY); + HANDLE_CTRL_CODE(IRP_MJ_POWER); + HANDLE_CTRL_CODE(IRP_MJ_SYSTEM_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_DEVICE_CHANGE); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_QUOTA); + HANDLE_CTRL_CODE(IRP_MJ_SET_QUOTA); + HANDLE_CTRL_CODE(IRP_MJ_PNP); + // case IRP_MJ_PNP_POWER: + // case IRP_MJ_MAXIMUM_FUNCTION: + + default: + { + DPRINT1("Unknown Major %lu\n", MajorFunction); + break; + } + } + + return CompleteRequest(Irp, STATUS_SUCCESS, 0); +} + +NTSTATUS NTAPI +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + NTSTATUS Status; + USHORT i; + PCONDRV_DRIVER DriverExtension = NULL; + + DPRINT1("Loading ReactOS Console Driver v0.0.1...\n"); + + DriverObject->DriverUnload = ConDrvUnload; + + /* Initialize the different callback function pointers */ + for (i = 0 ; i <= IRP_MJ_MAXIMUM_FUNCTION ; ++i) + DriverObject->MajorFunction[i] = ConDrvDispatch; + +#if 0 + DriverObject->MajorFunction[IRP_MJ_CREATE] = ConDrvCreate; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = ConDrvClose; + + /* temporary deactivated... + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ConDrvCleanup; + */ + DriverObject->MajorFunction[IRP_MJ_READ] = ConDrvRead; + DriverObject->MajorFunction[IRP_MJ_WRITE] = ConDrvWrite; + + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ConDrvIoControl; +#endif + + Status = IoAllocateDriverObjectExtension(DriverObject, + DriverObject, // Unique ID for the driver object extension ==> gives it its address ! + sizeof(CONDRV_DRIVER), + (PVOID*)&DriverExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); + return Status; + } + RtlZeroMemory(DriverExtension, sizeof(CONDRV_DRIVER)); + + Status = ConDrvCreateController(DriverObject, RegistryPath); + + DPRINT1("Done, Status = 0x%08lx\n", Status); + return Status; +} + +VOID NTAPI +ConDrvUnload(IN PDRIVER_OBJECT DriverObject) +{ + DPRINT1("Unloading ReactOS Console Driver v0.0.1...\n"); + + /* + * Delete the Controller device. This has as effect + * to delete also all the terminals. + */ + ConDrvDeleteController(DriverObject); + + /* Sanity check: No devices must exist at this point */ + ASSERT(DriverObject->DeviceObject == NULL); + + DPRINT1("Done\n"); + return; +} + + +/* EOF */ diff --git a/drivers/base/condrv/condrv.h b/drivers/base/condrv/condrv.h new file mode 100644 index 00000000000..85f4f2199f8 --- /dev/null +++ b/drivers/base/condrv/condrv.h @@ -0,0 +1,50 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/condrv.h + * PURPOSE: Console Driver Management Functions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#ifndef __CONDRV_H__ +#define __CONDRV_H__ + +/* This is needed for VisualDDK testing */ +// #define __USE_VISUALDDK_AT_HOME__ + +#ifdef __USE_VISUALDDK_AT_HOME__ + #pragma message("Disable __USE_VISUALDDK_AT_HOME__ before committing!!") + #include "VisualDDKHelpers.h" +#endif + + +#include +#include + + +#define CONDRV_TAG ' noC' +#define DD_CONDRV_TAG '1noC' +#define CONDRV_CONS_TAG '2noC' + + +// +// Console Driver object extension +// +typedef struct _CONDRV_DRIVER +{ + UNICODE_STRING RegistryPath; + PDEVICE_OBJECT Controller; // The unique Controller device for the driver. +} CONDRV_DRIVER, *PCONDRV_DRIVER; + + + +NTSTATUS NTAPI +ConDrvCreateController(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath); +NTSTATUS NTAPI +ConDrvDeleteController(IN PDRIVER_OBJECT DriverObject); + + +#endif // __CONDRV_H__ + +/* EOF */ diff --git a/drivers/base/condrv/condrv.rc b/drivers/base/condrv/condrv.rc new file mode 100644 index 00000000000..5e2148c08be --- /dev/null +++ b/drivers/base/condrv/condrv.rc @@ -0,0 +1,6 @@ + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Console Device Driver" +#define REACTOS_STR_INTERNAL_NAME "condrv" +#define REACTOS_STR_ORIGINAL_FILENAME "condrv.sys" +#include diff --git a/drivers/base/condrv/control.c b/drivers/base/condrv/control.c new file mode 100644 index 00000000000..819a098f6fc --- /dev/null +++ b/drivers/base/condrv/control.c @@ -0,0 +1,87 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/control.c + * PURPOSE: Console Driver - Controller Device + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "condrv.h" + +#define NDEBUG +#include + + +/* FUNCTIONS ******************************************************************/ + +NTSTATUS NTAPI +ConDrvCreateController(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + NTSTATUS Status = STATUS_SUCCESS; + UNICODE_STRING DeviceName, SymlinkName; + PCONDRV_DRIVER DriverExtension; + PDEVICE_OBJECT Controller = NULL; + + DPRINT1("Create the Controller device...\n"); + + RtlInitUnicodeString(&DeviceName , DD_CONDRV_CTRL_DEVICE_NAME_U); + RtlInitUnicodeString(&SymlinkName, DD_CONDRV_CTRL_SYMLNK_NAME_U); + + /* Get the driver extension */ + DriverExtension = (PCONDRV_DRIVER)IoGetDriverObjectExtension(DriverObject, + DriverObject); + + /* Create the Controller device, if it doesn't exist */ + Status = IoCreateDevice(DriverObject, + 0, + (PUNICODE_STRING)&DeviceName, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &Controller); + if (!NT_SUCCESS(Status)) goto Done; + + Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName); + if (!NT_SUCCESS(Status)) + { + IoDeleteDevice(Controller); + goto Done; + } + + Controller->Flags &= ~DO_DEVICE_INITIALIZING; + + /* Save the Controller device */ + DriverExtension->Controller = Controller; + +Done: + DPRINT1("Done, Status = 0x%08lx\n", Status); + return Status; +} + +NTSTATUS NTAPI +ConDrvDeleteController(IN PDRIVER_OBJECT DriverObject) +{ + NTSTATUS Status = STATUS_SUCCESS; + PDEVICE_OBJECT Controller; + UNICODE_STRING SymlinkName; + + DPRINT1("Delete the Controller device...\n"); + + /* Retrieve the Controller device */ + Controller = ((PCONDRV_DRIVER)IoGetDriverObjectExtension(DriverObject, DriverObject))->Controller; + if (!Controller) return STATUS_OBJECT_TYPE_MISMATCH; + + RtlInitUnicodeString(&SymlinkName, DD_CONDRV_CTRL_SYMLNK_NAME_U); + IoDeleteSymbolicLink(&SymlinkName); + + /* Delete the controller device itself */ + IoDeleteDevice(Controller); + + DPRINT1("Done, Status = 0x%08lx\n", Status); + return Status; +} + +/* EOF */ diff --git a/drivers/base/condrv/heap.h b/drivers/base/condrv/heap.h new file mode 100644 index 00000000000..d6bbbca4469 --- /dev/null +++ b/drivers/base/condrv/heap.h @@ -0,0 +1,22 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/heap.h + * PURPOSE: Heap Helpers + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#pragma once + +#define ConDrvAllocPoolNonPageable(Flags, Size, Tag) \ + __pragma(message("WARNING - Flags parameter ignored. You may encounter problems!")) \ + ExAllocatePoolWithTag(NonPagedPool, Size, Tag) + +#define ConDrvAllocPoolPageable(Flags, Size, Tag) \ + __pragma(message("WARNING - Flags parameter ignored. You may encounter problems!")) \ + ExAllocatePoolWithTag(PagedPool, Size, Tag) + +#define ConDrvFreePool(PoolBase, Tag) \ + ExFreePoolWithTag(PoolBase, Tag) + +/* EOF */ diff --git a/drivers/filesystems/ext2/CMakeLists.txt b/drivers/filesystems/ext2/CMakeLists.txt index f1dbab2007c..28bcea34eaa 100644 --- a/drivers/filesystems/ext2/CMakeLists.txt +++ b/drivers/filesystems/ext2/CMakeLists.txt @@ -22,6 +22,11 @@ list(APPEND SOURCE src/shutdown.c) add_library(ext2fs SHARED ${SOURCE}) + +if(NOT MSVC) + add_compile_flags("-Wno-unused-but-set-variable") +endif() + allow_warnings(ext2fs) target_link_libraries(ext2fs ${PSEH_LIB}) add_pch(ext2fs inc/ext2fsd.h) diff --git a/drivers/filesystems/mup/create.c b/drivers/filesystems/mup/create.c index e8da7466fea..7e8177383b1 100644 --- a/drivers/filesystems/mup/create.c +++ b/drivers/filesystems/mup/create.c @@ -51,9 +51,8 @@ MupCreate(PDEVICE_OBJECT DeviceObject, FileObject = Stack->FileObject; - DPRINT("FileName: '%wZ'\n", &FileObject->FileName); - - Status = STATUS_BAD_NETWORK_PATH; + DPRINT1("MUP - Unimplemented (FileName: '%wZ')\n", &FileObject->FileName); + Status = STATUS_OBJECT_NAME_INVALID; // STATUS_BAD_NETWORK_PATH; Irp->IoStatus.Information = (NT_SUCCESS(Status)) ? FILE_OPENED : 0; Irp->IoStatus.Status = Status; diff --git a/drivers/filesystems/npfs/create.c b/drivers/filesystems/npfs/create.c index ea6e52cf743..abdfe5e38d6 100644 --- a/drivers/filesystems/npfs/create.c +++ b/drivers/filesystems/npfs/create.c @@ -519,7 +519,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PNPFS_VCB Vcb; PNPFS_FCB Fcb; PNPFS_CCB Ccb; - PNAMED_PIPE_CREATE_PARAMETERS Buffer; + ULONG Disposition; + ULONG ShareAccess; + PNAMED_PIPE_CREATE_PARAMETERS Parameters; DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp); @@ -529,12 +531,16 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, DPRINT("FileObject %p\n", FileObject); DPRINT("Pipe name %wZ\n", &FileObject->FileName); - Buffer = IoStack->Parameters.CreatePipe.Parameters; + Disposition = (IoStack->Parameters.CreatePipe.Options >> 24) & 0xFF; + ShareAccess = IoStack->Parameters.CreatePipe.ShareAccess; + Parameters = IoStack->Parameters.CreatePipe.Parameters; Irp->IoStatus.Information = 0; - if (!(IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) || - (IoStack->Parameters.CreatePipe.ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))) + if ((Disposition == FILE_OVERWRITE) || + (Disposition == FILE_OVERWRITE_IF) || + !(ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) || + (ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -564,9 +570,10 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, return STATUS_INSTANCE_NOT_AVAILABLE; } - if (Fcb->MaximumInstances != Buffer->MaximumInstances || - Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart || - Fcb->PipeType != Buffer->NamedPipeType) + if (Disposition == FILE_CREATE || + Fcb->MaximumInstances != Parameters->MaximumInstances || + Fcb->TimeOut.QuadPart != Parameters->DefaultTimeout.QuadPart || + Fcb->PipeType != Parameters->NamedPipeType) { DPRINT("Asked for invalid pipe mode.\n"); NpfsDereferenceFcb(Fcb); @@ -612,13 +619,13 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, InitializeListHead(&Fcb->WaiterListHead); KeInitializeMutex(&Fcb->CcbListLock, 0); - Fcb->PipeType = Buffer->NamedPipeType; - Fcb->ServerReadMode = Buffer->ReadMode; + Fcb->PipeType = Parameters->NamedPipeType; + Fcb->ServerReadMode = Parameters->ReadMode; /* MSDN documentation reads that clients always start off in byte mode */ Fcb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE; - Fcb->CompletionMode = Buffer->CompletionMode; - switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) + Fcb->CompletionMode = Parameters->CompletionMode; + switch (ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) { case FILE_SHARE_READ: Fcb->PipeConfiguration = FILE_PIPE_OUTBOUND; @@ -630,19 +637,19 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, Fcb->PipeConfiguration = FILE_PIPE_FULL_DUPLEX; break; } - Fcb->MaximumInstances = Buffer->MaximumInstances; + Fcb->MaximumInstances = Parameters->MaximumInstances; Fcb->CurrentInstances = 0; - Fcb->TimeOut = Buffer->DefaultTimeout; + Fcb->TimeOut = Parameters->DefaultTimeout; if (!(Fcb->PipeConfiguration & FILE_PIPE_OUTBOUND) || Fcb->PipeConfiguration & FILE_PIPE_FULL_DUPLEX) { - if (Buffer->InboundQuota == 0) + if (Parameters->InboundQuota == 0) { Fcb->InboundQuota = Vcb->DefaultQuota; } else { - Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota); + Fcb->InboundQuota = PAGE_ROUND_UP(Parameters->InboundQuota); if (Fcb->InboundQuota < Vcb->MinQuota) { Fcb->InboundQuota = Vcb->MinQuota; @@ -660,13 +667,13 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, if (Fcb->PipeConfiguration & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND)) { - if (Buffer->OutboundQuota == 0) + if (Parameters->OutboundQuota == 0) { Fcb->OutboundQuota = Vcb->DefaultQuota; } else { - Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota); + Fcb->OutboundQuota = PAGE_ROUND_UP(Parameters->OutboundQuota); if (Fcb->OutboundQuota < Vcb->MinQuota) { Fcb->OutboundQuota = Vcb->MinQuota; diff --git a/drivers/network/dd/CMakeLists.txt b/drivers/network/dd/CMakeLists.txt index 61ce69d774b..ffa9635eca2 100644 --- a/drivers/network/dd/CMakeLists.txt +++ b/drivers/network/dd/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(ne2000) add_subdirectory(pcnet) +add_subdirectory(rtl8139) diff --git a/drivers/network/dd/rtl8139/CMakeLists.txt b/drivers/network/dd/rtl8139/CMakeLists.txt new file mode 100644 index 00000000000..9633348b239 --- /dev/null +++ b/drivers/network/dd/rtl8139/CMakeLists.txt @@ -0,0 +1,18 @@ + +add_definitions( + -DNDIS50_MINIPORT + -DNDIS_MINIPORT_DRIVER + -DNDIS_LEGACY_MINIPORT) + +list(APPEND SOURCE + ndis.c + hardware.c + info.c + interrupt.c + rtl8139.rc) + +add_library(rtl8139 SHARED ${SOURCE}) +add_pch(rtl8139 nic.h) +set_module_type(rtl8139 kernelmodedriver) +add_importlibs(rtl8139 ndis ntoskrnl hal) +add_cd_file(TARGET rtl8139 DESTINATION reactos/system32/drivers FOR all) diff --git a/drivers/network/dd/rtl8139/include/debug.h b/drivers/network/dd/rtl8139/debug.h similarity index 100% rename from drivers/network/dd/rtl8139/include/debug.h rename to drivers/network/dd/rtl8139/debug.h diff --git a/drivers/network/dd/rtl8139/hardware.c b/drivers/network/dd/rtl8139/hardware.c new file mode 100644 index 00000000000..e8b10647523 --- /dev/null +++ b/drivers/network/dd/rtl8139/hardware.c @@ -0,0 +1,235 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * 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. + * + */ + +#include "nic.h" + +#define NDEBUG +#include + +NDIS_STATUS +NTAPI +NICPowerOn ( + IN PRTL_ADAPTER Adapter + ) +{ + // + // Send 0x00 to the CONFIG_1 register (0x52) to set the LWAKE + LWPTN to active high. + // This should essentially *power on* the device. + // -- OSDev Wiki + // + NdisRawWritePortUchar(Adapter->IoBase + R_CFG1, 0x00); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICSoftReset ( + IN PRTL_ADAPTER Adapter + ) +{ + UCHAR commandReg; + UINT resetAttempts; + + // + // Sending 0x10 to the Command register (0x37) will send the RTL8139 into a software reset. + // Once that byte is sent, the RST bit must be checked to make sure that the chip has finished the reset. + // If the RST bit is high (1), then the reset is still in operation. + // -- OSDev Wiki + NdisRawWritePortUchar(Adapter->IoBase + R_CMD, B_CMD_RST); + + for (resetAttempts = 0; resetAttempts < MAX_RESET_ATTEMPTS; resetAttempts++) + { + NdisRawReadPortUchar(Adapter->IoBase + R_CMD, &commandReg); + + if (!(commandReg & B_CMD_RST)) + { + return NDIS_STATUS_SUCCESS; + } + + NdisMSleep(100); + } + + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +NICRegisterReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ) +{ + ASSERT(NdisGetPhysicalAddressHigh(Adapter->ReceiveBufferPa) == 0); + + NdisRawWritePortUlong(Adapter->IoBase + R_RXSA, Adapter->ReceiveBufferPa.LowPart); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICRemoveReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUlong(Adapter->IoBase + R_RXSA, 0); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICEnableTxRx ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUchar(Adapter->IoBase + R_CMD, B_CMD_TXE | B_CMD_RXE); + + // + // TX and RX must be enabled before setting these + // + NdisRawWritePortUlong(Adapter->IoBase + R_RC, RC_VAL); + NdisRawWritePortUlong(Adapter->IoBase + R_TC, TC_VAL); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress ( + IN PRTL_ADAPTER Adapter, + OUT PUCHAR MacAddress + ) +{ + UINT i; + + for (i = 0; i < IEEE_802_ADDR_LENGTH; i++) + { + NdisRawReadPortUchar(Adapter->IoBase + R_MAC + i, &MacAddress[i]); + } + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICApplyInterruptMask ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUshort(Adapter->IoBase + R_IM, Adapter->InterruptMask); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICDisableInterrupts ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUshort(Adapter->IoBase + R_IM, 0); + return NDIS_STATUS_SUCCESS; +} + +USHORT +NTAPI +NICInterruptRecognized ( + IN PRTL_ADAPTER Adapter, + OUT PBOOLEAN InterruptRecognized + ) +{ + USHORT interruptStatus; + + NdisRawReadPortUshort(Adapter->IoBase + R_IS, &interruptStatus); + + *InterruptRecognized = (interruptStatus & Adapter->InterruptMask) != 0; + + return (interruptStatus & Adapter->InterruptMask); +} + +VOID +NTAPI +NICAcknowledgeInterrupts ( + IN PRTL_ADAPTER Adapter + ) +{ + NdisRawWritePortUshort(Adapter->IoBase + R_IS, Adapter->InterruptPending); +} + +VOID +NTAPI +NICUpdateLinkStatus ( + IN PRTL_ADAPTER Adapter + ) +{ + UCHAR mediaState; + + NdisRawReadPortUchar(Adapter->IoBase + R_MS, &mediaState); + Adapter->MediaState = (mediaState & R_MS_LINKDWN) ? NdisMediaStateDisconnected : + NdisMediaStateConnected; + Adapter->LinkSpeedMbps = (mediaState & R_MS_SPEED_10) ? 10 : 100; +} + +NDIS_STATUS +NTAPI +NICApplyPacketFilter ( + IN PRTL_ADAPTER Adapter + ) +{ + ULONG filterMask; + + filterMask = RC_VAL; + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_DIRECTED) + { + filterMask |= B_RC_APM; + } + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_MULTICAST) + { + filterMask |= B_RC_AM; + } + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + { + filterMask |= B_RC_AB; + } + + if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + { + filterMask |= B_RC_AAP; + } + + NdisRawWritePortUlong(Adapter->IoBase + R_RC, filterMask); + + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS +NTAPI +NICTransmitPacket ( + IN PRTL_ADAPTER Adapter, + IN UCHAR TxDesc, + IN ULONG PhysicalAddress, + IN ULONG Length + ) +{ + NdisRawWritePortUlong(Adapter->IoBase + R_TXSAD0 + (TxDesc * sizeof(ULONG)), PhysicalAddress); + NdisRawWritePortUlong(Adapter->IoBase + R_TXSTS0 + (TxDesc * sizeof(ULONG)), Length); + return NDIS_STATUS_SUCCESS; +} diff --git a/drivers/network/dd/rtl8139/include/nic.h b/drivers/network/dd/rtl8139/include/nic.h deleted file mode 100644 index 74671929e2d..00000000000 --- a/drivers/network/dd/rtl8139/include/nic.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Novell Eagle 2000 driver - * FILE: include/ne2000.h - * PURPOSE: NE2000 driver definitions - */ - -#define NDIS_MINIPORT_DRIVER 1 -#define NDIS_LEGACY_MINIPORT 1 -#define NDIS51_MINIPORT 1 -#include -#include <8139.h> -#include - -/* Define NOCARD to test NDIS without a card */ -//#define NOCARD - -/* NE2000 sepcific constants */ -#define NIC_DATA 0x10 /* Data register */ -#define NIC_RESET 0x1F /* Reset register */ - - -/* Global constants */ - -#define DRIVER_NDIS_MAJOR_VERSION 0x05 -#define DRIVER_NDIS_MINOR_VERSION 0 - -#define DRIVER_DEFAULT_IO_BASE_ADDRESS 0x280 /* bochs default */ -#define DRIVER_DEFAULT_INTERRUPT_NUMBER 9 /* bochs default */ -#define DRIVER_DEFAULT_INTERRUPT_SHARED FALSE -#define DRIVER_DEFAULT_INTERRUPT_MODE NdisInterruptLatched - -#define DRIVER_MAX_MULTICAST_LIST_SIZE 8 - -#define DRIVER_VENDOR_DESCRIPTION "RTL 8139 Adapter." -#define DRIVER_VENDOR_DRIVER_VERSION 0x0100 /* 1.0 */ - -#define DRIVER_FRAME_SIZE 1514 /* Size of an ethernet frame */ -#define DRIVER_HEADER_SIZE 14 /* Size of an ethernet header */ -#define DRIVER_LENGTH_OF_ADDRESS 6 /* Size of an ethernet address */ - -/* Maximum lookahead buffer size */ -#define DRIVER_MAXIMUM_LOOKAHEAD (252 - DRIVER_HEADER_SIZE) - -/* Size of a block in a buffer ring */ -#define DRIVER_BLOCK_SIZE 256 - - -/* Default number of transmit buffers */ -#define DRIVER_DEFAULT_TX_BUFFER_COUNT 12 -#define BUFFERS_PER_TX_BUF 1 - -/* Interrupt Mask Register value */ -#define DRIVER_INTERRUPT_MASK IMR_ALLE - IMR_RDCE - -/* Maximum number of interrupts handled per call to MiniportHandleInterrupt */ -#define INTERRUPT_LIMIT 10 - -/* Global structures */ - -typedef struct _MINIPORT_RESERVED -{ - PNDIS_PACKET Next; -} MINIPORT_RESERVED, *PMINIPORT_RESERVED; - -#define RESERVED(Packet) ((PMINIPORT_RESERVED)((Packet)->MiniportReserved)) - -typedef UCHAR DRIVER_HARDWARE_ADDRESS[DRIVER_LENGTH_OF_ADDRESS]; - -/* Information about an adapter */ -typedef struct _NIC_ADAPTER -{ - /* Entry on global adapter list */ - LIST_ENTRY ListEntry; - /* Adapter handle */ - NDIS_HANDLE MiniportAdapterHandle; - /* NDIS interrupt object */ - NDIS_MINIPORT_INTERRUPT Interrupt; - - /* I/O base address and interrupt number of adapter */ - ULONG_PTR IoBaseAddress; - ULONG InterruptLevel; - ULONG InterruptVector; - BOOLEAN InterruptShared; - KINTERRUPT_MODE InterruptMode; - - /* Mapped address of the I/O base port */ - PUCHAR IOBase; - - /* TRUE if the NIC can transfer in word mode */ - BOOLEAN WordMode; - - /* Base address and size of the onboard memory window */ - PUCHAR RamBase; - UINT RamSize; - - /* Station Address PROM (SAPROM) */ - UCHAR SAPROM[16]; - - /* Onboard ethernet address from the manufacturer */ - DRIVER_HARDWARE_ADDRESS PermanentAddress; - - /* Ethernet address currently in use */ - DRIVER_HARDWARE_ADDRESS StationAddress; - - /* Maximum number of multicast addresses this adapter supports */ - ULONG MaxMulticastListSize; - - /* List of multicast addresses in use */ - DRIVER_HARDWARE_ADDRESS Addresses[DRIVER_MAX_MULTICAST_LIST_SIZE]; - - /* Current multicast address mask */ - UCHAR MulticastAddressMask[8]; - - /* Masked interrupts (IMR value) */ - ULONG InterruptMask; - - /* Interrupts that have occurred */ - UCHAR InterruptStatus; - - /* Current packet filter */ - ULONG PacketFilter; - - /* Lookahead buffer */ - UINT LookaheadSize; - UCHAR Lookahead[DRIVER_MAXIMUM_LOOKAHEAD + DRIVER_HEADER_SIZE]; - - /* Receive buffer ring */ - UINT PageStart; - UINT PageStop; - UINT CurrentPage; - UINT NextPacket; - - /* TRUE if there was a buffer overflow */ - BOOLEAN BufferOverflow; - - /* TRUE if an error occurred during reception of a packet */ - BOOLEAN ReceiveError; - - /* TRUE if an error occurred during transmission of a packet */ - BOOLEAN TransmitError; - - /* TRUE if a transmit interrupt is pending */ - BOOLEAN TransmitPending; - - /* Received packet header */ - PACKET_HEADER PacketHeader; - - /* Offset in onboard RAM of received packet */ - ULONG PacketOffset; - - /* TRUE if receive indications are done and should be completed */ - BOOLEAN DoneIndicating; - - /* Transmit buffers */ - UINT TXStart; /* Start block of transmit buffer ring */ - UINT TXCount; /* Number of blocks in transmit buffer ring */ - UINT TXFree; /* Number of free transmit buffers */ - UINT TXNext; /* Next buffer to use */ - /* Length of packet. 0 means buffer is unused */ - UINT TXSize[DRIVER_DEFAULT_TX_BUFFER_COUNT]; - INT TXCurrent; /* Current buffer beeing transmitted. -1 means none */ - - /* Head of transmit queue */ - PNDIS_PACKET TXQueueHead; - /* Tail of transmit queue */ - PNDIS_PACKET TXQueueTail; - - /* Statistics */ - ULONG FrameAlignmentErrors; - ULONG CrcErrors; - ULONG MissedPackets; - - /* Flags used for driver cleanup */ - BOOLEAN IOPortRangeRegistered; - BOOLEAN InterruptRegistered; - BOOLEAN ShutdownHandlerRegistered; -} NIC_ADAPTER, *PNIC_ADAPTER; - -/* Global driver information */ -typedef struct _DRIVER_INFORMATION -{ - NDIS_HANDLE NdisWrapperHandle; /* Returned from NdisInitializeWrapper */ - NDIS_HANDLE NdisMacHandle; /* Returned from NdisRegisterMac */ - LIST_ENTRY AdapterListHead; /* Adapters this driver control */ -} DRIVER_INFORMATION, *PDRIVER_INFORMATION; - - - -/* Global variable */ - -extern DRIVER_INFORMATION DriverInfo; -extern NDIS_PHYSICAL_ADDRESS HighestAcceptableMax; - - - -/* Prototypes */ - -BOOLEAN NICCheck( - PNIC_ADAPTER Adapter); - -NDIS_STATUS NICInitialize( - PNIC_ADAPTER Adapter); - -NDIS_STATUS NICSetup( - PNIC_ADAPTER Adapter); - -NDIS_STATUS NICStart( - PNIC_ADAPTER Adapter); - -NDIS_STATUS NICStop( - PNIC_ADAPTER Adapter); - -NDIS_STATUS NICReset( - PNIC_ADAPTER Adapter); - -VOID NICUpdateCounters( - PNIC_ADAPTER Adapter); - -VOID NICReadDataAlign( - PNIC_ADAPTER Adapter, - PUSHORT Target, - ULONG_PTR Source, - USHORT Length); - -VOID NICWriteDataAlign( - PNIC_ADAPTER Adapter, - ULONG_PTR Target, - PUSHORT Source, - USHORT Length); - -VOID NICReadData( - PNIC_ADAPTER Adapter, - PUCHAR Target, - ULONG_PTR Source, - USHORT Length); - -VOID NICWriteData( - PNIC_ADAPTER Adapter, - ULONG_PTR Target, - PUCHAR Source, - USHORT Length); - -VOID NICTransmit( - PNIC_ADAPTER Adapter); - -/* EOF */ diff --git a/drivers/network/dd/rtl8139/info.c b/drivers/network/dd/rtl8139/info.c new file mode 100644 index 00000000000..fd63c8c495f --- /dev/null +++ b/drivers/network/dd/rtl8139/info.c @@ -0,0 +1,394 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * 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. + * + */ + +#include "nic.h" + +#define NDEBUG +#include + +static ULONG SupportedOidList[] = +{ + OID_GEN_SUPPORTED_LIST, + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAC_OPTIONS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, + OID_GEN_RCV_CRC_ERROR, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_802_3_MAC_OPTIONS, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS +}; + +NDIS_STATUS +NTAPI +MiniportQueryInformation ( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG genericUlong; + ULONG copyLength; + PVOID copySource; + NDIS_STATUS status; + + status = NDIS_STATUS_SUCCESS; + copySource = &genericUlong; + copyLength = sizeof(ULONG); + + NdisAcquireSpinLock(&adapter->Lock); + + switch (Oid) + { + case OID_GEN_SUPPORTED_LIST: + copySource = (PVOID)&SupportedOidList; + copyLength = sizeof(SupportedOidList); + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + genericUlong = adapter->PacketFilter; + break; + + case OID_GEN_HARDWARE_STATUS: + genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + { + static const NDIS_MEDIUM medium = NdisMedium802_3; + copySource = (PVOID)&medium; + copyLength = sizeof(medium); + break; + } + + case OID_GEN_RECEIVE_BLOCK_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_CURRENT_LOOKAHEAD: + case OID_GEN_MAXIMUM_LOOKAHEAD: + case OID_GEN_MAXIMUM_FRAME_SIZE: + genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); + break; + + case OID_GEN_LINK_SPEED: + genericUlong = adapter->LinkSpeedMbps * 1000; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + genericUlong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: + genericUlong = RECEIVE_BUFFER_SIZE; + break; + + case OID_GEN_VENDOR_ID: + // + // The 3 bytes of the MAC address is the vendor ID + // + genericUlong = 0; + genericUlong |= (adapter->PermanentMacAddress[0] << 16); + genericUlong |= (adapter->PermanentMacAddress[1] << 8); + genericUlong |= (adapter->PermanentMacAddress[2] & 0xFF); + break; + + case OID_GEN_VENDOR_DESCRIPTION: + { + static UCHAR vendorDesc[] = "ReactOS Team"; + copySource = vendorDesc; + copyLength = sizeof(vendorDesc); + break; + } + + case OID_GEN_VENDOR_DRIVER_VERSION: + genericUlong = DRIVER_VERSION; + break; + + case OID_GEN_DRIVER_VERSION: + { + static const USHORT driverVersion = + (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; + copySource = (PVOID)&driverVersion; + copyLength = sizeof(driverVersion); + break; + } + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + genericUlong = MAXIMUM_FRAME_SIZE; + break; + + case OID_GEN_PROTOCOL_OPTIONS: + NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_PROTOCOL_OPTIONS is unimplemented\n")); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + + case OID_GEN_MAC_OPTIONS: + genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | + NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | + NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | + NDIS_MAC_OPTION_NO_LOOPBACK; + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: + genericUlong = adapter->MediaState; + break; + + case OID_GEN_MAXIMUM_SEND_PACKETS: + genericUlong = 1; + break; + + case OID_802_3_CURRENT_ADDRESS: + copySource = adapter->CurrentMacAddress; + copyLength = IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_PERMANENT_ADDRESS: + copySource = adapter->PermanentMacAddress; + copyLength = IEEE_802_ADDR_LENGTH; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + genericUlong = MAXIMUM_MULTICAST_ADDRESSES; + break; + + case OID_GEN_XMIT_OK: + genericUlong = adapter->TransmitOk; + break; + + case OID_GEN_RCV_OK: + genericUlong = adapter->ReceiveOk; + break; + + case OID_GEN_XMIT_ERROR: + genericUlong = adapter->TransmitError; + break; + + case OID_GEN_RCV_ERROR: + genericUlong = adapter->ReceiveError; + break; + + case OID_GEN_RCV_NO_BUFFER: + genericUlong = adapter->ReceiveNoBufferSpace; + break; + + case OID_GEN_RCV_CRC_ERROR: + genericUlong = adapter->ReceiveCrcError; + break; + + case OID_802_3_RCV_ERROR_ALIGNMENT: + genericUlong = adapter->ReceiveAlignmentError; + break; + + case OID_802_3_XMIT_ONE_COLLISION: + genericUlong = adapter->TransmitOneCollision; + break; + + case OID_802_3_XMIT_MORE_COLLISIONS: + genericUlong = adapter->TransmitMoreCollisions; + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID\n")); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + if (status == NDIS_STATUS_SUCCESS) + { + if (copyLength > InformationBufferLength) + { + *BytesNeeded = copyLength; + *BytesWritten = 0; + status = NDIS_STATUS_INVALID_LENGTH; + } + else + { + NdisMoveMemory(InformationBuffer, copySource, copyLength); + *BytesWritten = copyLength; + *BytesNeeded = copyLength; + } + } + else + { + *BytesWritten = 0; + *BytesNeeded = 0; + } + + NdisReleaseSpinLock(&adapter->Lock); + + NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n", + Oid, status, *BytesWritten, *BytesNeeded)); + + return status; +} + +NDIS_STATUS +NTAPI +MiniportSetInformation ( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG genericUlong; + NDIS_STATUS status; + + status = NDIS_STATUS_SUCCESS; + + NdisAcquireSpinLock(&adapter->Lock); + + switch (Oid) + { + case OID_GEN_CURRENT_PACKET_FILTER: + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); + + if (genericUlong & + (NDIS_PACKET_TYPE_ALL_FUNCTIONAL | + NDIS_PACKET_TYPE_FUNCTIONAL | + NDIS_PACKET_TYPE_GROUP | + NDIS_PACKET_TYPE_MAC_FRAME | + NDIS_PACKET_TYPE_SMT | + NDIS_PACKET_TYPE_SOURCE_ROUTING)) + { + *BytesRead = sizeof(ULONG); + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_NOT_SUPPORTED; + break; + } + + adapter->PacketFilter = genericUlong; + + status = NICApplyPacketFilter(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter\n")); + break; + } + + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + if (InformationBufferLength < sizeof(ULONG)) + { + *BytesRead = 0; + *BytesNeeded = sizeof(ULONG); + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); + + if (genericUlong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER)) + { + status = NDIS_STATUS_INVALID_DATA; + } + else + { + // Ignore this... + } + + break; + + case OID_802_3_MULTICAST_LIST: + if (InformationBufferLength % IEEE_802_ADDR_LENGTH) + { + *BytesRead = 0; + *BytesNeeded = InformationBufferLength + (InformationBufferLength % IEEE_802_ADDR_LENGTH); + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES) + { + *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH; + *BytesRead = 0; + status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + NdisMoveMemory(adapter->MulticastList, InformationBuffer, InformationBufferLength); + + // FIXME: Write to device + + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unknown OID\n")); + status = NDIS_STATUS_NOT_SUPPORTED; + *BytesRead = 0; + *BytesNeeded = 0; + break; + } + + if (status == NDIS_STATUS_SUCCESS) + { + *BytesRead = InformationBufferLength; + *BytesNeeded = 0; + } + + NdisReleaseSpinLock(&adapter->Lock); + + return status; +} + diff --git a/drivers/network/dd/rtl8139/interrupt.c b/drivers/network/dd/rtl8139/interrupt.c new file mode 100644 index 00000000000..659e72d4b34 --- /dev/null +++ b/drivers/network/dd/rtl8139/interrupt.c @@ -0,0 +1,218 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * 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. + * + */ + +#include "nic.h" + +#define NDEBUG +#include + +VOID +NTAPI +MiniportISR ( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG csConfig; + + // + // FIXME: We need to synchronize with this ISR for changes to InterruptPending, + // LinkChange, MediaState, and LinkSpeedMbps. We can get away with IRQL + // synchronization on non-SMP machines because we run a DIRQL here. + // + + adapter->InterruptPending |= NICInterruptRecognized(adapter, InterruptRecognized); + if (!(*InterruptRecognized)) + { + // + // This is not ours. + // + *QueueMiniportHandleInterrupt = FALSE; + return; + } + + // + // We have to check for a special link change interrupt before acknowledging + // + if (adapter->InterruptPending & R_I_RXUNDRUN) + { + NdisRawReadPortUlong(adapter->IoBase + R_CSCFG, &csConfig); + if (csConfig & R_CSCR_LINKCHNG) + { + adapter->LinkChange = TRUE; + NICUpdateLinkStatus(adapter); + } + } + + // + // Acknowledge the interrupt and mark the events pending service + // + NICAcknowledgeInterrupts(adapter); + *QueueMiniportHandleInterrupt = TRUE; +} + +VOID +NTAPI +MiniportHandleInterrupt ( + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + ULONG txStatus; + UCHAR command; + PPACKET_HEADER nicHeader; + PETH_HEADER ethHeader; + + NdisDprAcquireSpinLock(&adapter->Lock); + + NDIS_DbgPrint(MAX_TRACE, ("Interrupts pending: 0x%x\n", adapter->InterruptPending)); + + // + // Handle a link change + // + if (adapter->LinkChange) + { + NdisDprReleaseSpinLock(&adapter->Lock); + NdisMIndicateStatus(adapter->MiniportAdapterHandle, + adapter->MediaState == NdisMediaStateConnected ? + NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT, + NULL, + 0); + NdisMIndicateStatusComplete(adapter->MiniportAdapterHandle); + NdisDprAcquireSpinLock(&adapter->Lock); + adapter->LinkChange = FALSE; + } + + // + // Handle a TX interrupt + // + if (adapter->InterruptPending & (R_I_TXOK | R_I_TXERR)) + { + while (adapter->TxFull || adapter->DirtyTxDesc != adapter->CurrentTxDesc) + { + NdisRawReadPortUlong(adapter->IoBase + R_TXSTS0 + + (adapter->DirtyTxDesc * sizeof(ULONG)), &txStatus); + + if (!(txStatus & (R_TXS_STATOK | R_TXS_UNDERRUN | R_TXS_ABORTED))) + { + // + // Not sent yet + // + break; + } + + NDIS_DbgPrint(MAX_TRACE, ("Transmission for desc %d complete: 0x%x\n", + adapter->DirtyTxDesc, txStatus)); + + if (txStatus & R_TXS_STATOK) + { + adapter->TransmitOk++; + } + else + { + adapter->TransmitError++; + } + + adapter->DirtyTxDesc++; + adapter->DirtyTxDesc %= TX_DESC_COUNT; + adapter->InterruptPending &= ~(R_I_TXOK | R_I_TXERR); + adapter->TxFull = FALSE; + } + } + + // + // Handle a good RX interrupt + // + if (adapter->InterruptPending & (R_I_RXOK | R_I_RXERR)) + { + for (;;) + { + NdisRawReadPortUchar(adapter->IoBase + R_CMD, &command); + if (command & R_CMD_RXEMPTY) + { + // + // The buffer is empty + // + adapter->InterruptPending &= ~(R_I_RXOK | R_I_RXERR); + break; + } + + adapter->ReceiveOffset %= RECEIVE_BUFFER_SIZE; + + NDIS_DbgPrint(MAX_TRACE, ("Looking for a packet at offset 0x%x\n", + adapter->ReceiveOffset)); + nicHeader = (PPACKET_HEADER)(adapter->ReceiveBuffer + adapter->ReceiveOffset); + if (!(nicHeader->Status & RSR_ROK)) + { + // + // Receive failed + // + NDIS_DbgPrint(MIN_TRACE, ("Receive failed: 0x%x\n", nicHeader->Status)); + + if (nicHeader->Status & RSR_FAE) + { + adapter->ReceiveAlignmentError++; + } + else if (nicHeader->Status & RSR_CRC) + { + adapter->ReceiveCrcError++; + } + adapter->ReceiveError++; + + goto NextPacket; + } + + NDIS_DbgPrint(MAX_TRACE, ("Indicating %d byte packet to NDIS\n", + nicHeader->PacketLength - RECV_CRC_LENGTH)); + + ethHeader = (PETH_HEADER)(nicHeader + 1); + NdisMEthIndicateReceive(adapter->MiniportAdapterHandle, + NULL, + (PVOID)(ethHeader), + sizeof(ETH_HEADER), + (PVOID)(ethHeader + 1), + nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH, + nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH); + adapter->ReceiveOk++; + + NextPacket: + adapter->ReceiveOffset += nicHeader->PacketLength + sizeof(PACKET_HEADER); + adapter->ReceiveOffset = (adapter->ReceiveOffset + 3) & ~3; + NdisRawWritePortUshort(adapter->IoBase + R_CAPR, adapter->ReceiveOffset - 0x10); + + if (adapter->InterruptPending & (R_I_RXOVRFLW | R_I_FIFOOVR)) + { + // + // We can only clear these interrupts once CAPR has been reset + // + NdisRawWritePortUshort(adapter->IoBase + R_IS, R_I_RXOVRFLW | R_I_FIFOOVR); + adapter->InterruptPending &= ~(R_I_RXOVRFLW | R_I_FIFOOVR); + } + } + + NdisMEthIndicateReceiveComplete(adapter->MiniportAdapterHandle); + } + + NdisDprReleaseSpinLock(&adapter->Lock); +} + diff --git a/drivers/network/dd/rtl8139/ndis.c b/drivers/network/dd/rtl8139/ndis.c new file mode 100644 index 00000000000..6c245be21e4 --- /dev/null +++ b/drivers/network/dd/rtl8139/ndis.c @@ -0,0 +1,527 @@ +/* + * ReactOS Realtek 8139 Driver + * + * Copyright (C) 2013 Cameron Gutman + * + * 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. + * + */ + +#include "nic.h" + +#define NDEBUG +#include + +ULONG DebugTraceLevel = MIN_TRACE; + +NDIS_STATUS +NTAPI +MiniportReset ( + OUT PBOOLEAN AddressingReset, + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + *AddressingReset = FALSE; + return NDIS_STATUS_FAILURE; +} + +NDIS_STATUS +NTAPI +MiniportSend ( + IN NDIS_HANDLE MiniportAdapterContext, + IN PNDIS_PACKET Packet, + IN UINT Flags + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + NDIS_STATUS status; + PSCATTER_GATHER_LIST sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, + ScatterGatherListPacketInfo); + ULONG transmitLength; + ULONG transmitBuffer; + PNDIS_BUFFER firstBuffer; + PVOID firstBufferVa; + UINT firstBufferLength, totalBufferLength; + PUCHAR runtBuffer; + + ASSERT(sgList != NULL); + + ASSERT(sgList->NumberOfElements == 1); + ASSERT(sgList->Elements[0].Address.HighPart == 0); + ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0); + ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); + + NDIS_DbgPrint(MAX_TRACE, ("Sending %d byte packet\n", sgList->Elements[0].Length)); + + NdisAcquireSpinLock(&adapter->Lock); + + if (adapter->TxFull) + { + NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n")); + NdisReleaseSpinLock(&adapter->Lock); + return NDIS_STATUS_RESOURCES; + } + + NDIS_DbgPrint(MAX_TRACE, ("Sending packet on TX desc %d\n", adapter->CurrentTxDesc)); + + // + // If this is a runt, we need to pad it manually for the RTL8139 + // + if (sgList->Elements[0].Length < MINIMUM_FRAME_SIZE) + { + transmitLength = MINIMUM_FRAME_SIZE; + transmitBuffer = adapter->RuntTxBuffersPa.LowPart + + (MINIMUM_FRAME_SIZE * adapter->CurrentTxDesc); + + NdisGetFirstBufferFromPacketSafe(Packet, + &firstBuffer, + &firstBufferVa, + &firstBufferLength, + &totalBufferLength, + NormalPagePriority); + if (firstBufferVa == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to get buffer from packet\n")); + NdisReleaseSpinLock(&adapter->Lock); + return NDIS_STATUS_RESOURCES; + } + + ASSERT(firstBufferLength == totalBufferLength); + + runtBuffer = adapter->RuntTxBuffers + (MINIMUM_FRAME_SIZE * adapter->CurrentTxDesc); + RtlCopyMemory(runtBuffer, firstBufferVa, firstBufferLength); + RtlFillMemory(runtBuffer + firstBufferLength, MINIMUM_FRAME_SIZE - firstBufferLength, 0x00); + } + else + { + transmitLength = sgList->Elements[0].Length; + transmitBuffer = sgList->Elements[0].Address.LowPart; + } + + status = NICTransmitPacket(adapter, adapter->CurrentTxDesc, transmitBuffer, transmitLength); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n")); + NdisReleaseSpinLock(&adapter->Lock); + return status; + } + + adapter->CurrentTxDesc++; + adapter->CurrentTxDesc %= TX_DESC_COUNT; + + if (adapter->CurrentTxDesc == adapter->DirtyTxDesc) + { + NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n")); + adapter->TxFull = TRUE; + } + + NdisReleaseSpinLock(&adapter->Lock); + + return NDIS_STATUS_SUCCESS; +} + +VOID +NTAPI +MiniportHalt ( + IN NDIS_HANDLE MiniportAdapterContext + ) +{ + PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; + + ASSERT(adapter != NULL); + + // + // Interrupts need to stop first + // + if (adapter->InterruptRegistered != FALSE) + { + NdisMDeregisterInterrupt(&adapter->Interrupt); + } + + // + // If we have a mapped IO port range, we can talk to the NIC + // + if (adapter->IoBase != NULL) + { + if (adapter->ReceiveBuffer != NULL) + { + // + // Disassociate our shared buffer before freeing it to avoid + // NIC-induced memory corruption + // + NICRemoveReceiveBuffer(adapter); + + NdisMFreeSharedMemory(adapter->MiniportAdapterHandle, + adapter->ReceiveBufferLength, + FALSE, + adapter->ReceiveBuffer, + adapter->ReceiveBufferPa); + } + + if (adapter->RuntTxBuffers != NULL) + { + NdisMFreeSharedMemory(adapter->MiniportAdapterHandle, + MINIMUM_FRAME_SIZE * TX_DESC_COUNT, + FALSE, + adapter->RuntTxBuffers, + adapter->RuntTxBuffersPa); + } + + // + // Unregister the IO range + // + NdisMDeregisterIoPortRange(adapter->MiniportAdapterHandle, + adapter->IoRangeStart, + adapter->IoRangeLength, + adapter->IoBase); + } + + // + // Destroy the adapter context + // + NdisFreeMemory(adapter, sizeof(*adapter), 0); +} + +NDIS_STATUS +NTAPI +MiniportInitialize ( + OUT PNDIS_STATUS OpenErrorStatus, + OUT PUINT SelectedMediumIndex, + IN PNDIS_MEDIUM MediumArray, + IN UINT MediumArraySize, + IN NDIS_HANDLE MiniportAdapterHandle, + IN NDIS_HANDLE WrapperConfigurationContext + ) +{ + PRTL_ADAPTER adapter; + NDIS_STATUS status; + UINT i; + PNDIS_RESOURCE_LIST resourceList; + UINT resourceListSize; + + // + // Make sure the medium is supported + // + for (i = 0; i < MediumArraySize; i++) + { + if (MediumArray[i] == NdisMedium802_3) + { + *SelectedMediumIndex = i; + break; + } + } + + if (i == MediumArraySize) + { + NDIS_DbgPrint(MIN_TRACE, ("802.3 medium was not found in the medium array\n")); + return NDIS_STATUS_UNSUPPORTED_MEDIA; + } + + // + // Allocate our adapter context + // + status = NdisAllocateMemoryWithTag((PVOID*)&adapter, + sizeof(*adapter), + ADAPTER_TAG); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate adapter context\n")); + return NDIS_STATUS_RESOURCES; + } + + RtlZeroMemory(adapter, sizeof(*adapter)); + adapter->MiniportAdapterHandle = MiniportAdapterHandle; + NdisAllocateSpinLock(&adapter->Lock); + + // + // Notify NDIS of some characteristics of our NIC + // + NdisMSetAttributesEx(MiniportAdapterHandle, + adapter, + 0, + NDIS_ATTRIBUTE_BUS_MASTER, + NdisInterfacePci); + + // + // Get our resources for IRQ and IO base information + // + resourceList = NULL; + resourceListSize = 0; + NdisMQueryAdapterResources(&status, + WrapperConfigurationContext, + resourceList, + &resourceListSize); + if (status != NDIS_STATUS_RESOURCES) + { + NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #1\n")); + status = NDIS_STATUS_FAILURE; + goto Cleanup; + } + + status = NdisAllocateMemoryWithTag((PVOID*)&resourceList, + resourceListSize, + RESOURCE_LIST_TAG); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate resource list\n")); + goto Cleanup; + } + + NdisMQueryAdapterResources(&status, + WrapperConfigurationContext, + resourceList, + &resourceListSize); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #2\n")); + goto Cleanup; + } + + ASSERT(resourceList->Version == 1); + ASSERT(resourceList->Revision == 1); + + for (i = 0; i < resourceList->Count; i++) + { + switch (resourceList->PartialDescriptors[i].Type) + { + case CmResourceTypePort: + ASSERT(adapter->IoRangeStart == 0); + + ASSERT(resourceList->PartialDescriptors[i].u.Port.Start.HighPart == 0); + + adapter->IoRangeStart = resourceList->PartialDescriptors[i].u.Port.Start.LowPart; + adapter->IoRangeLength = resourceList->PartialDescriptors[i].u.Port.Length; + + NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n", + adapter->IoRangeStart, adapter->IoRangeStart + adapter->IoRangeLength)); + break; + + case CmResourceTypeInterrupt: + ASSERT(adapter->InterruptVector == 0); + ASSERT(adapter->InterruptLevel == 0); + + adapter->InterruptVector = resourceList->PartialDescriptors[i].u.Interrupt.Vector; + adapter->InterruptLevel = resourceList->PartialDescriptors[i].u.Interrupt.Level; + adapter->InterruptShared = (resourceList->PartialDescriptors[i].ShareDisposition == CmResourceShareShared); + adapter->InterruptFlags = resourceList->PartialDescriptors[i].Flags; + + NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", adapter->InterruptVector)); + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Unrecognized resource type: 0x%x\n", resourceList->PartialDescriptors[i].Type)); + break; + } + } + + NdisFreeMemory(resourceList, resourceListSize, 0); + resourceList = NULL; + + if (adapter->IoRangeStart == 0 || adapter->InterruptVector == 0) + { + NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n")); + goto Cleanup; + } + + // + // Allocate the DMA resources + // + status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, + FALSE, // RTL8139 only supports 32-bit addresses + MAXIMUM_FRAME_SIZE); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to configure DMA\n")); + goto Cleanup; + } + + adapter->ReceiveBufferLength = FULL_RECEIVE_BUFFER_SIZE; + NdisMAllocateSharedMemory(MiniportAdapterHandle, + adapter->ReceiveBufferLength, + FALSE, + (PVOID*)&adapter->ReceiveBuffer, + &adapter->ReceiveBufferPa); + if (adapter->ReceiveBuffer == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate receive buffer\n")); + status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + NdisMAllocateSharedMemory(MiniportAdapterHandle, + MINIMUM_FRAME_SIZE * TX_DESC_COUNT, + FALSE, + (PVOID*)&adapter->RuntTxBuffers, + &adapter->RuntTxBuffersPa); + if (adapter->RuntTxBuffers == NULL) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate runt TX buffer\n")); + status = NDIS_STATUS_RESOURCES; + goto Cleanup; + } + + // + // Register the I/O port range and configure the NIC + // + status = NdisMRegisterIoPortRange((PVOID*)&adapter->IoBase, + MiniportAdapterHandle, + adapter->IoRangeStart, + adapter->IoRangeLength); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to register IO port range (0x%x)\n", status)); + goto Cleanup; + } + + // + // Adapter setup + // + status = NICPowerOn(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to power on NIC (0x%x)\n", status)); + goto Cleanup; + } + + status = NICSoftReset(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to reset the NIC (0x%x)\n", status)); + goto Cleanup; + } + + status = NICGetPermanentMacAddress(adapter, adapter->PermanentMacAddress); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to get the fixed MAC address (0x%x)\n", status)); + goto Cleanup; + } + + RtlCopyMemory(adapter->CurrentMacAddress, adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH); + + // + // Update link state and speed + // + NICUpdateLinkStatus(adapter); + + status = NICRegisterReceiveBuffer(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to setup receive buffer (0x%x)\n", status)); + goto Cleanup; + } + + // + // We're ready to handle interrupts now + // + status = NdisMRegisterInterrupt(&adapter->Interrupt, + MiniportAdapterHandle, + adapter->InterruptVector, + adapter->InterruptLevel, + TRUE, // We always want ISR calls + adapter->InterruptShared, + (adapter->InterruptFlags & CM_RESOURCE_INTERRUPT_LATCHED) ? + NdisInterruptLatched : NdisInterruptLevelSensitive); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to register interrupt (0x%x)\n", status)); + goto Cleanup; + } + + adapter->InterruptRegistered = TRUE; + + // + // Enable interrupts on the NIC + // + adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; + status = NICApplyInterruptMask(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", status)); + goto Cleanup; + } + + // + // Turn on TX and RX now + // + status = NICEnableTxRx(adapter); + if (status != NDIS_STATUS_SUCCESS) + { + NDIS_DbgPrint(MIN_TRACE, ("Unable to enable TX and RX (0x%x)\n", status)); + goto Cleanup; + } + + return NDIS_STATUS_SUCCESS; + +Cleanup: + if (resourceList != NULL) + { + NdisFreeMemory(resourceList, resourceListSize, 0); + } + if (adapter != NULL) + { + MiniportHalt(adapter); + } + + return status; +} + +NTSTATUS +NTAPI +DriverEntry ( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + NDIS_HANDLE wrapperHandle; + NDIS_MINIPORT_CHARACTERISTICS characteristics; + NDIS_STATUS status; + + RtlZeroMemory(&characteristics, sizeof(characteristics)); + characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION; + characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION; + characteristics.CheckForHangHandler = NULL; + characteristics.DisableInterruptHandler = NULL; + characteristics.EnableInterruptHandler = NULL; + characteristics.HaltHandler = MiniportHalt; + characteristics.HandleInterruptHandler = MiniportHandleInterrupt; + characteristics.InitializeHandler = MiniportInitialize; + characteristics.ISRHandler = MiniportISR; + characteristics.QueryInformationHandler = MiniportQueryInformation; + characteristics.ReconfigureHandler = NULL; + characteristics.ResetHandler = MiniportReset; + characteristics.SendHandler = MiniportSend; + characteristics.SetInformationHandler = MiniportSetInformation; + characteristics.TransferDataHandler = NULL; + characteristics.ReturnPacketHandler = NULL; + characteristics.SendPacketsHandler = NULL; + characteristics.AllocateCompleteHandler = NULL; + + NdisMInitializeWrapper(&wrapperHandle, DriverObject, RegistryPath, NULL); + if (!wrapperHandle) + { + return NDIS_STATUS_FAILURE; + } + + status = NdisMRegisterMiniport(wrapperHandle, &characteristics, sizeof(characteristics)); + if (status != NDIS_STATUS_SUCCESS) + { + NdisTerminateWrapper(wrapperHandle, 0); + return NDIS_STATUS_FAILURE; + } + + return NDIS_STATUS_SUCCESS; +} + diff --git a/drivers/network/dd/rtl8139/nic.h b/drivers/network/dd/rtl8139/nic.h new file mode 100644 index 00000000000..bbd724ae8f3 --- /dev/null +++ b/drivers/network/dd/rtl8139/nic.h @@ -0,0 +1,205 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Realtek 8139 driver + * FILE: rtl8139.h + * PURPOSE: RTL8139 driver definitions + */ + +#include +#include + +#define ADAPTER_TAG 'Altr' +#define RESOURCE_LIST_TAG 'Rltr' + +#define MAX_RESET_ATTEMPTS 25 +#define RECEIVE_BUFFER_SIZE (32768) +// The full receive window requires 16 bytes of padding +// plus 2048 for receive overflows (because of WRAP) +#define FULL_RECEIVE_BUFFER_SIZE (32768 + 16 + 2048) +#define RECV_CRC_LENGTH 4 + +#define MINIMUM_FRAME_SIZE 60 +#define MAXIMUM_FRAME_SIZE 1514 + +#define DRIVER_VERSION 1 + +// 1/2 packet early RX, 512 byte FIFO threshold, 32K RX buffer, unlimited DMA bursts, WRAP +#define RC_VAL (0x800B780) + +// 2048 byte DMA bursts +#define TC_VAL (0x700) + +typedef struct _RTL_ADAPTER { + NDIS_HANDLE MiniportAdapterHandle; + NDIS_SPIN_LOCK Lock; + + ULONG IoRangeStart; + ULONG IoRangeLength; + + ULONG InterruptVector; + ULONG InterruptLevel; + BOOLEAN InterruptShared; + ULONG InterruptFlags; + + PUCHAR IoBase; + NDIS_MINIPORT_INTERRUPT Interrupt; + BOOLEAN InterruptRegistered; + + UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH]; + UCHAR CurrentMacAddress[IEEE_802_ADDR_LENGTH]; + struct { + UCHAR MacAddress[IEEE_802_ADDR_LENGTH]; + } MulticastList[MAXIMUM_MULTICAST_ADDRESSES]; + + ULONG ReceiveBufferLength; + PUCHAR ReceiveBuffer; + NDIS_PHYSICAL_ADDRESS ReceiveBufferPa; + USHORT ReceiveOffset; + + ULONG LinkSpeedMbps; + ULONG MediaState; + BOOLEAN LinkChange; + + ULONG PacketFilter; + + USHORT InterruptMask; + USHORT InterruptPending; + + UCHAR DirtyTxDesc; + UCHAR CurrentTxDesc; + BOOLEAN TxFull; + PUCHAR RuntTxBuffers; + NDIS_PHYSICAL_ADDRESS RuntTxBuffersPa; + + ULONG ReceiveOk; + ULONG TransmitOk; + ULONG ReceiveError; + ULONG TransmitError; + ULONG ReceiveNoBufferSpace; + ULONG ReceiveCrcError; + ULONG ReceiveAlignmentError; + ULONG TransmitOneCollision; + ULONG TransmitMoreCollisions; + +} RTL_ADAPTER, *PRTL_ADAPTER; + +NDIS_STATUS +NTAPI +NICPowerOn ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICSoftReset ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICRegisterReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICRemoveReceiveBuffer ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICEnableTxRx ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICGetPermanentMacAddress ( + IN PRTL_ADAPTER Adapter, + OUT PUCHAR MacAddress + ); + +NDIS_STATUS +NTAPI +NICApplyPacketFilter ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICApplyInterruptMask ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICDisableInterrupts ( + IN PRTL_ADAPTER Adapter + ); + +USHORT +NTAPI +NICInterruptRecognized ( + IN PRTL_ADAPTER Adapter, + OUT PBOOLEAN InterruptRecognized + ); + +VOID +NTAPI +NICAcknowledgeInterrupts ( + IN PRTL_ADAPTER Adapter + ); + +VOID +NTAPI +NICUpdateLinkStatus ( + IN PRTL_ADAPTER Adapter + ); + +NDIS_STATUS +NTAPI +NICTransmitPacket ( + IN PRTL_ADAPTER Adapter, + IN UCHAR TxDesc, + IN ULONG PhysicalAddress, + IN ULONG Length + ); + +NDIS_STATUS +NTAPI +MiniportSetInformation ( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesRead, + OUT PULONG BytesNeeded + ); + +NDIS_STATUS +NTAPI +MiniportQueryInformation ( + IN NDIS_HANDLE MiniportAdapterContext, + IN NDIS_OID Oid, + IN PVOID InformationBuffer, + IN ULONG InformationBufferLength, + OUT PULONG BytesWritten, + OUT PULONG BytesNeeded + ); + +VOID +NTAPI +MiniportISR ( + OUT PBOOLEAN InterruptRecognized, + OUT PBOOLEAN QueueMiniportHandleInterrupt, + IN NDIS_HANDLE MiniportAdapterContext + ); + +VOID +NTAPI +MiniportHandleInterrupt ( + IN NDIS_HANDLE MiniportAdapterContext + ); + +/* EOF */ diff --git a/drivers/network/dd/rtl8139/rtl8139.rc b/drivers/network/dd/rtl8139/rtl8139.rc new file mode 100644 index 00000000000..2fede1c9a91 --- /dev/null +++ b/drivers/network/dd/rtl8139/rtl8139.rc @@ -0,0 +1,6 @@ + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "Realtek 8139 Ethernet Driver\0" +#define REACTOS_STR_INTERNAL_NAME "rtl8139\0" +#define REACTOS_STR_ORIGINAL_FILENAME "rtl8139.sys\0" +#include diff --git a/drivers/network/dd/rtl8139/include/8139.h b/drivers/network/dd/rtl8139/rtlhw.h similarity index 69% rename from drivers/network/dd/rtl8139/include/8139.h rename to drivers/network/dd/rtl8139/rtlhw.h index b6a4bcd6cf1..622e72e12d2 100644 --- a/drivers/network/dd/rtl8139/include/8139.h +++ b/drivers/network/dd/rtl8139/rtlhw.h @@ -1,11 +1,18 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS RTL8139 Driver - * FILE: include/8139.h + * FILE: rtlhw.h * PURPOSE: 8139 NIC definitions */ #pragma once + +#define MAXIMUM_MULTICAST_ADDRESSES 8 +#define DEFAULT_INTERRUPT_MASK (R_I_RXOK | R_I_RXERR | R_I_TXOK | \ + R_I_TXERR | R_I_RXOVRFLW | R_I_RXUNDRUN | \ + R_I_FIFOOVR | R_I_PCSTMOUT | R_I_PCIERR) +#define TX_DESC_COUNT 4 + //Register addresses #define R_MAC 0x00 //MAC address uses bytes 0-5, 6 and 7 are reserved #define R_MCAST0 0x08 //Multicast registers @@ -28,7 +35,15 @@ #define R_ERXBC 0x34 //Early RX byte count register #define R_ERXSTS 0x36 //Early RX status register +#define R_TXS_HOSTOWNS 0x00002000 //Driver still owns the buffer +#define R_TXS_UNDERRUN 0x00004000 //TX underrun +#define R_TXS_STATOK 0x00008000 //Successful TX +#define R_TXS_OOW 0x20000000 //Out of window +#define R_TXS_ABORTED 0x40000000 //TX aborted +#define R_TXS_CARLOST 0x80000000 //Carrier lost + #define R_CMD 0x37 //Command register +#define R_CMD_RXEMPTY 0x01 //Receive buffer empty #define B_CMD_TXE 0x04 //Enable TX #define B_CMD_RXE 0x08 //Enable RX #define B_CMD_RST 0x10 //Reset bit @@ -39,6 +54,16 @@ #define R_IS 0x3E //Interrupt status register #define R_TC 0x40 //Transmit configuration register +#define R_I_RXOK 0x0001 //Receive OK +#define R_I_RXERR 0x0002 //Receive error +#define R_I_TXOK 0x0004 //Transmit OK +#define R_I_TXERR 0x0008 //Trasmit error +#define R_I_RXOVRFLW 0x0010 //Receive overflow +#define R_I_RXUNDRUN 0x0020 //Receive underrun +#define R_I_FIFOOVR 0x0040 //FIFO overflow +#define R_I_PCSTMOUT 0x4000 //PCS timeout +#define R_I_PCIERR 0x8000 //PCI error + #define R_RC 0x44 //Receive configuration register #define B_RC_AAP 0x01 //Accept all packets #define B_RC_APM 0x02 //Accept packets sent to device MAC @@ -53,6 +78,10 @@ #define R_CFG1 0x52 #define R_TINTR 0x54 //Timer interrupt register #define R_MS 0x58 //Media status register + +#define R_MS_LINKDWN 0x04 //Link is down +#define R_MS_SPEED_10 0x08 //Media is at 10mbps + #define R_CFG3 0x59 //Configuration register 3 #define R_CFG4 0x5A //Configuration register 4 #define R_MINTS 0x5C //Multiple interrupt select @@ -68,6 +97,10 @@ #define R_NWT 0x70 //N-way test register #define R_RXERRCTR 0x72 //RX error counter #define R_CSCFG 0x74 //CS configuration register + +#define R_CSCR_LINKOK 0x00400 //Link up +#define R_CSCR_LINKCHNG 0x00800 //Link changed + #define R_PHYP1 0x78 //PHY parameter 1 #define R_TWP 0x7C //Twister parameter #define R_PHYP2 0x80 //PHY parameter 2 @@ -88,13 +121,13 @@ #define R_WAKE6 0xBC #define R_WAKE7 0xC4 #define R_LSBCRC0 0xCC //LSB of the mask byte of wakeup frame 0 within offset 12 to 75 -#define R_LSBCRC0 0xCD -#define R_LSBCRC0 0xCE -#define R_LSBCRC0 0xCF -#define R_LSBCRC0 0xD0 -#define R_LSBCRC0 0xD1 -#define R_LSBCRC0 0xD2 -#define R_LSBCRC0 0xD3 +#define R_LSBCRC1 0xCD +#define R_LSBCRC2 0xCE +#define R_LSBCRC3 0xCF +#define R_LSBCRC4 0xD0 +#define R_LSBCRC5 0xD1 +#define R_LSBCRC6 0xD2 +#define R_LSBCRC7 0xD3 #define R_CFG5 0xD8 //Configuration register 5 //EEPROM Control Bytes @@ -108,12 +141,20 @@ //EEPROM Commands #define EE_READ_CMD 0x06 +#define RSR_MAR 0x8000 //Mulicast receive +#define RSR_PAM 0x4000 //Physical address match (directed packet) +#define RSR_BAR 0x2000 //Broadcast receive +#define RSR_ISE 0x0020 //Invalid symbol +#define RSR_RUNT 0x0010 //Runt packet +#define RSR_LONG 0x0008 //Long packet +#define RSR_CRC 0x0004 //CRC error +#define RSR_FAE 0x0002 //Frame alignment error +#define RSR_ROK 0x0001 //Receive OK /* NIC prepended structure to a received packet */ typedef struct _PACKET_HEADER { - UCHAR Status; /* See RSR_* constants */ - UCHAR NextPacket; /* Pointer to next packet in chain */ - USHORT PacketLength; /* Length of packet including this header */ + USHORT Status; /* See RSR_* constants */ + USHORT PacketLength; /* Length of packet NOT including this header */ } PACKET_HEADER, *PPACKET_HEADER; #define IEEE_802_ADDR_LENGTH 6 @@ -125,22 +166,4 @@ typedef struct _ETH_HEADER { USHORT PayloadType; } ETH_HEADER, *PETH_HEADER; -typedef struct _DISCARD_HEADER { - PACKET_HEADER HWHeader; - ETH_HEADER EthernetHeader; -} DISCARD_HEADER, *PDISCARD_HEADER; - -#define NICDisableInterrupts(Adapter) { \ - NDIS_DbgPrint(MAX_TRACE, ("NICDisableInterrupts()\n")); \ - NdisRawWritePortUchar((Adapter)->IOBase + PG0_IMR, 0x00); \ -} - -#define NICEnableInterrupts(Adapter) { \ - NDIS_DbgPrint(MAX_TRACE, ("NICEnableInterrupts() Mask (0x%X)\n", (Adapter)->InterruptMask)); \ - NdisRawWritePortUchar((Adapter)->IOBase + PG0_IMR, (Adapter)->InterruptMask); \ -} - -VOID NTAPI MiniportHandleInterrupt( - IN NDIS_HANDLE MiniportAdapterContext); - /* EOF */ diff --git a/drivers/network/ndis/ndis/io.c b/drivers/network/ndis/ndis/io.c index 71d4e93ed6e..2b972a5b837 100644 --- a/drivers/network/ndis/ndis/io.c +++ b/drivers/network/ndis/ndis/io.c @@ -1192,7 +1192,7 @@ NdisMInitializeScatterGatherDma( DeviceDesc.Version = DEVICE_DESCRIPTION_VERSION; DeviceDesc.Master = TRUE; DeviceDesc.ScatterGather = TRUE; - DeviceDesc.Dma32BitAddresses = !Dma64BitAddresses; + DeviceDesc.Dma32BitAddresses = TRUE; // All callers support 32-bit addresses DeviceDesc.Dma64BitAddresses = Dma64BitAddresses; DeviceDesc.BusNumber = Adapter->NdisMiniportBlock.BusNumber; DeviceDesc.InterfaceType = Adapter->NdisMiniportBlock.BusType; diff --git a/drivers/network/tcpip/include/titypes.h b/drivers/network/tcpip/include/titypes.h index 7f5d1dfdb9c..e9380ffc030 100644 --- a/drivers/network/tcpip/include/titypes.h +++ b/drivers/network/tcpip/include/titypes.h @@ -13,6 +13,7 @@ */ #define ReferenceObject(Object) \ { \ + ASSERT((Object)->RefCount); \ InterlockedIncrement(&((Object)->RefCount)); \ } @@ -22,6 +23,7 @@ */ #define DereferenceObject(Object) \ { \ + ASSERT((Object)->RefCount); \ if (InterlockedDecrement(&((Object)->RefCount)) == 0) \ (((Object)->Free)(Object)); \ } diff --git a/drivers/network/tcpip/tcpip/dispatch.c b/drivers/network/tcpip/tcpip/dispatch.c index 316fe4b6a6e..989b6315185 100644 --- a/drivers/network/tcpip/tcpip/dispatch.c +++ b/drivers/network/tcpip/tcpip/dispatch.c @@ -618,9 +618,11 @@ NTSTATUS DispTdiListen( Connection->AddressFile->Protocol ); } - if( NT_SUCCESS(Status) ) + if( NT_SUCCESS(Status) ) { + ReferenceObject(Connection->AddressFile->Listener); Status = TCPListen( Connection->AddressFile->Listener, 1024 ); /* BACKLOG */ + } } if( NT_SUCCESS(Status) ) { diff --git a/drivers/storage/ide/uniata/CMakeLists.txt b/drivers/storage/ide/uniata/CMakeLists.txt index 00128c2f8d8..a4bf4dd6083 100644 --- a/drivers/storage/ide/uniata/CMakeLists.txt +++ b/drivers/storage/ide/uniata/CMakeLists.txt @@ -1,12 +1,12 @@ +set_cpp() + include_directories( BEFORE ${CMAKE_CURRENT_SOURCE_DIR} inc) #add_definitions(-D_DEBUG) -set_cpp() - list(APPEND SOURCE id_ata.cpp id_badblock.cpp @@ -19,14 +19,11 @@ list(APPEND SOURCE add_library(uniata SHARED ${SOURCE} idedma.rc) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(uniata "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() + +if(NOT MSVC) + # FIXME: http://www.cmake.org/Bug/view.php?id=12998 #allow_warnings(uniata) - #add_target_compile_flags(uniata "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-error") + set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-error") endif() add_pch(uniata stdafx.h) diff --git a/drivers/usb/usbehci/CMakeLists.txt b/drivers/usb/usbehci/CMakeLists.txt index 828804b6f7e..8cf3944e827 100644 --- a/drivers/usb/usbehci/CMakeLists.txt +++ b/drivers/usb/usbehci/CMakeLists.txt @@ -21,16 +21,6 @@ target_link_libraries(usbehci libcntpr ${PSEH_LIB}) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(usbehci "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() - target_link_libraries(usbehci -lgcc) - #add_target_compile_flags(usbehci "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") -endif() - set_module_type(usbehci kernelmodedriver) add_importlibs(usbehci ntoskrnl hal usbd) diff --git a/drivers/usb/usbohci/CMakeLists.txt b/drivers/usb/usbohci/CMakeLists.txt index ead60c3c270..eab4dc0a0d0 100644 --- a/drivers/usb/usbohci/CMakeLists.txt +++ b/drivers/usb/usbohci/CMakeLists.txt @@ -21,16 +21,6 @@ target_link_libraries(usbohci libcntpr ${PSEH_LIB}) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(usbohci "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() - target_link_libraries(usbohci -lgcc) - #add_target_compile_flags(usbohci "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") -endif() - set_module_type(usbohci kernelmodedriver) add_importlibs(usbohci ntoskrnl hal usbd) diff --git a/drivers/usb/usbuhci/CMakeLists.txt b/drivers/usb/usbuhci/CMakeLists.txt index bc31a5f8a09..623daf03385 100644 --- a/drivers/usb/usbuhci/CMakeLists.txt +++ b/drivers/usb/usbuhci/CMakeLists.txt @@ -22,16 +22,6 @@ target_link_libraries(usbuhci libcntpr ${PSEH_LIB}) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(usbuhci "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() - target_link_libraries(usbuhci -lgcc) - #add_target_compile_flags(usbuhci "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") -endif() - set_module_type(usbuhci kernelmodedriver) add_importlibs(usbuhci ntoskrnl hal usbd) diff --git a/drivers/wdm/audio/backpln/portcls/CMakeLists.txt b/drivers/wdm/audio/backpln/portcls/CMakeLists.txt index 168dc75a869..1b96012fa2b 100644 --- a/drivers/wdm/audio/backpln/portcls/CMakeLists.txt +++ b/drivers/wdm/audio/backpln/portcls/CMakeLists.txt @@ -57,15 +57,6 @@ target_link_libraries(portcls libcntpr ${PSEH_LIB}) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(portcls "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() - #add_target_compile_flags(portcls "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") -endif() - set_module_type(portcls kernelmodedriver ENTRYPOINT 0 ) add_pch(portcls private.hpp) add_importlibs(portcls ntoskrnl ks drmk hal) diff --git a/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt b/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt index 714575f05a2..8c5e8cfb046 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt +++ b/drivers/wdm/audio/drivers/CMIDriver/CMakeLists.txt @@ -12,33 +12,23 @@ list(APPEND SOURCE adapter.cpp common.cpp mintopo.cpp - minwave.cpp -) + minwave.cpp) add_library(cmipci SHARED ${SOURCE} - cmipci.rc -) + cmipci.rc) -target_link_libraries(cmipci - stdunk - libcntpr -) +target_link_libraries(cmipci stdunk libcntpr) set_module_type(cmipci wdmdriver UNICODE ENTRYPOINT 0) -add_importlibs(cmipci - portcls - hal - ntoskrnl) +add_importlibs(cmipci portcls hal ntoskrnl) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(portcls "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() - #add_target_compile_flags(portcls "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti -Wno-write-strings -Wno-switch -Wno-error") +if(NOT MSVC) + # FIXME: http://www.cmake.org/Bug/view.php?id=12998 + #add_target_compile_flags(portcls "-Wno-write-strings -Wno-switch") + #allow_warnings(portcls) + set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-write-strings -Wno-switch -Wno-error") endif() add_cd_file(TARGET cmipci DESTINATION reactos/system32/drivers FOR all) diff --git a/drivers/wdm/audio/drivers/CMIDriver/cmicontrol/CMakeLists.txt b/drivers/wdm/audio/drivers/CMIDriver/cmicontrol/CMakeLists.txt index 2fb34fba7dc..a60725aa05a 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/cmicontrol/CMakeLists.txt +++ b/drivers/wdm/audio/drivers/CMIDriver/cmicontrol/CMakeLists.txt @@ -1,16 +1,13 @@ -include_directories(..) - set_cpp() +include_directories(..) + add_executable(cmicontrol main.cpp - window.rc -) + window.rc) -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 if(NOT MSVC) - #add_target_compile_flags(cmicontrol "-fno-exceptions -fno-rtti") set_source_files_properties(main.cpp PROPERTIES COMPILE_FLAGS "-Wno-write-strings") endif() @@ -25,9 +22,8 @@ add_importlibs(cmicontrol setupapi winmm msvcrt - kernel32 -) + kernel32) set_module_type(cmicontrol win32gui) -add_cd_file(TARGET cmicontrol DESTINATION reactos/system32/drivers FOR all) \ No newline at end of file +add_cd_file(TARGET cmicontrol DESTINATION reactos/system32/drivers FOR all) diff --git a/drivers/wdm/audio/drivers/CMIDriver/cpl/CMakeLists.txt b/drivers/wdm/audio/drivers/CMIDriver/cpl/CMakeLists.txt index e50243da0ce..a781d848ba3 100644 --- a/drivers/wdm/audio/drivers/CMIDriver/cpl/CMakeLists.txt +++ b/drivers/wdm/audio/drivers/CMIDriver/cpl/CMakeLists.txt @@ -3,19 +3,8 @@ set_cpp() add_library(cmicpl SHARED cmicpl.cpp - cmicpl.rc -) + cmicpl.rc) set_module_type(cmicpl cpl UNICODE) - -add_importlibs(cmicpl - shell32 - msvcrt - kernel32 -) - -if (NOT MSVC) - target_link_libraries(cmicpl -lgcc) -endif() - +add_importlibs(cmicpl shell32 msvcrt kernel32) add_cd_file(TARGET cmicpl DESTINATION reactos/system32/drivers FOR all) diff --git a/include/c++/stlport/stl/config/_reactos.h b/include/c++/stlport/stl/config/_reactos.h index b6951bdb201..a29415d63b1 100644 --- a/include/c++/stlport/stl/config/_reactos.h +++ b/include/c++/stlport/stl/config/_reactos.h @@ -214,7 +214,7 @@ // Uncomment to indicate that the compiler do not like static constant // definition. // Meaningfull only if _STLP_STATIC_CONST_INIT_BUG is not defined. -// # define _STLP_NO_STATIC_CONST_DEFINITION +# define _STLP_NO_STATIC_CONST_DEFINITION // Define if default constructor for builtin integer type fails to initialize it to 0 // In expression like new(&char) char(): diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h index 23dbe3f93cd..dffced42585 100644 --- a/include/ddk/ntifs.h +++ b/include/ddk/ntifs.h @@ -3557,25 +3557,25 @@ typedef struct _FILE_FS_CONTROL_INFORMATION { #if (_WIN32_WINNT >= 0x0500) #define FSCTL_FIND_FILES_BY_SID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 35, METHOD_NEITHER, FILE_ANY_ACCESS) -#define FSCTL_SET_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 38, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_SET_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 38, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) #define FSCTL_GET_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 39, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define FSCTL_DELETE_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 40, METHOD_BUFFERED, FILE_WRITE_DATA) -#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_DELETE_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 40, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) #define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) #define FSCTL_ENUM_USN_DATA CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 44, METHOD_NEITHER, FILE_READ_DATA) #define FSCTL_SECURITY_ID_CHECK CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 45, METHOD_NEITHER, FILE_READ_DATA) #define FSCTL_READ_USN_JOURNAL CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 46, METHOD_NEITHER, FILE_READ_DATA) -#define FSCTL_SET_OBJECT_ID_EXTENDED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 47, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_SET_OBJECT_ID_EXTENDED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 47, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) #define FSCTL_CREATE_OR_GET_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 48, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define FSCTL_SET_SPARSE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_SET_SPARSE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) #define FSCTL_SET_ZERO_DATA CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 50, METHOD_BUFFERED, FILE_WRITE_DATA) #define FSCTL_QUERY_ALLOCATED_RANGES CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA) #define FSCTL_ENABLE_UPGRADE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 52, METHOD_BUFFERED, FILE_WRITE_DATA) #define FSCTL_SET_ENCRYPTION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 53, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_ENCRYPTION_FSCTL_IO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 54, METHOD_NEITHER, FILE_ANY_ACCESS) -#define FSCTL_WRITE_RAW_ENCRYPTED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 55, METHOD_NEITHER, FILE_ANY_ACCESS) -#define FSCTL_READ_RAW_ENCRYPTED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 56, METHOD_NEITHER, FILE_ANY_ACCESS) +#define FSCTL_WRITE_RAW_ENCRYPTED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 55, METHOD_NEITHER, FILE_SPECIAL_ACCESS) +#define FSCTL_READ_RAW_ENCRYPTED CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 56, METHOD_NEITHER, FILE_SPECIAL_ACCESS) #define FSCTL_CREATE_USN_JOURNAL CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 57, METHOD_NEITHER, FILE_READ_DATA) #define FSCTL_READ_FILE_USN_DATA CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 58, METHOD_NEITHER, FILE_READ_DATA) #define FSCTL_WRITE_USN_CLOSE_RECORD CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 59, METHOD_NEITHER, FILE_READ_DATA) diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 2f0785c8df4..b7c9a63a563 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1878,7 +1878,7 @@ typedef enum _EX_POOL_PRIORITY { #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_)) #define LOOKASIDE_ALIGN #else -#define LOOKASIDE_ALIGN /* FIXME: DECLSPEC_CACHEALIGN */ +#define LOOKASIDE_ALIGN DECLSPEC_CACHEALIGN #endif typedef struct _LOOKASIDE_LIST_EX *PLOOKASIDE_LIST_EX; @@ -8333,7 +8333,7 @@ KeRestoreFloatingPointState(PVOID FloatingState) #define HIGH_LEVEL 15 #define KI_USER_SHARED_DATA ((ULONG_PTR)(KADDRESS_BASE + 0xFFFE0000)) -extern volatile LARGE_INTEGER KeTickCount; +extern DECLSPEC_CACHEALIGN volatile LARGE_INTEGER KeTickCount; #define PAUSE_PROCESSOR __yield(); diff --git a/include/dxsdk/CMakeLists.txt b/include/dxsdk/CMakeLists.txt index 9a842b81c13..d079f26a9b3 100644 --- a/include/dxsdk/CMakeLists.txt +++ b/include/dxsdk/CMakeLists.txt @@ -19,7 +19,6 @@ list(APPEND SOURCE mmstream.idl qedit.idl regbag.idl - strmif.idl tvratings.idl vidcap.idl videoacc.idl diff --git a/include/dxsdk/axextend.idl b/include/dxsdk/axextend.idl index 72e37ce47c7..9b472019836 100644 --- a/include/dxsdk/axextend.idl +++ b/include/dxsdk/axextend.idl @@ -45,6 +45,7 @@ interface IAMVfwCompressDialogs; interface IAMVideoCompression; interface IAMVideoDecimationProperties; interface IAMVideoProcAmp; +interface IAMGraphBuilderCallback; interface ICaptureGraphBuilder; interface ICaptureGraphBuilder2; interface IConfigAviMux; @@ -235,14 +236,14 @@ typedef struct { ULONG cPins; [size_is(cPins)] const REGFILTERPINS *rgPins; - } DUMMYSTRUCTNAME; + } DUMMYSTRUCTNAME1; [case(2)] struct { ULONG cPins2; [size_is(cPins2)] const REGFILTERPINS2 *rgPins2; - } DUMMYSTRUCTNAME1; + } DUMMYSTRUCTNAME2; [default] ; @@ -1070,6 +1071,21 @@ interface IAMFilterMiscFlags : IUnknown ULONG GetMiscFlags(); }; +[ + local, + object, + uuid(4995f511-9ddb-4f12-bd3b-f04611807b79), + pointer_default(unique) +] +interface IAMGraphBuilderCallback : IUnknown +{ + HRESULT SelectedFilter( + [in] IMoniker *pMon); + + HRESULT CreatedFilter( + [in] IBaseFilter *pFil); +}; + [ local, object, diff --git a/include/ndk/lpcfuncs.h b/include/ndk/lpcfuncs.h index e32fa18e59b..120e763a0f4 100644 --- a/include/ndk/lpcfuncs.h +++ b/include/ndk/lpcfuncs.h @@ -52,7 +52,7 @@ NTSYSCALLAPI NTSTATUS NTAPI NtAcceptConnectPort( - _In_ PHANDLE PortHandle, + _Out_ PHANDLE PortHandle, _In_opt_ PVOID PortContext, _In_ PPORT_MESSAGE ConnectionRequest, _In_ BOOLEAN AcceptConnection, @@ -71,11 +71,11 @@ NTSYSCALLAPI NTSTATUS NTAPI NtConnectPort( - _In_ PHANDLE PortHandle, + _Out_ PHANDLE PortHandle, _In_ PUNICODE_STRING PortName, _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _In_opt_ PPORT_VIEW ClientView, - _In_opt_ PREMOTE_PORT_VIEW ServerViewONAL, + _In_opt_ PREMOTE_PORT_VIEW ServerView, _In_opt_ PULONG MaxMessageLength, _In_opt_ PVOID ConnectionInformation, _In_opt_ PULONG ConnectionInformationLength @@ -85,7 +85,7 @@ NTSYSCALLAPI NTSTATUS NTAPI NtCreatePort( - _In_ PHANDLE PortHandle, + _Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG MaxConnectionInfoLength, _In_ ULONG MaxMessageLength, @@ -96,7 +96,7 @@ NTSYSCALLAPI NTSTATUS NTAPI NtCreateWaitablePort( - _In_ PHANDLE PortHandle, + _Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG MaxConnectInfoLength, _In_ ULONG MaxDataLength, @@ -206,9 +206,9 @@ NTSYSCALLAPI NTSTATUS NTAPI NtSecureConnectPort( - PHANDLE PortHandle, - PUNICODE_STRING PortName, - PSECURITY_QUALITY_OF_SERVICE SecurityQos, + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _In_opt_ PPORT_VIEW ClientView, _In_opt_ PSID Sid, _In_opt_ PREMOTE_PORT_VIEW ServerView, diff --git a/include/ndk/rtlfuncs.h b/include/ndk/rtlfuncs.h index c6e15e117df..c18303d1cd4 100644 --- a/include/ndk/rtlfuncs.h +++ b/include/ndk/rtlfuncs.h @@ -4112,6 +4112,7 @@ RtlUnlockBootStatusData( #endif #ifdef NTOS_MODE_USER +_Must_inspect_result_ NTSYSAPI NTSTATUS NTAPI @@ -4119,6 +4120,15 @@ RtlGUIDFromString( _In_ PUNICODE_STRING GuidString, _Out_ GUID *Guid); +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlStringFromGUID( + _In_ REFGUID Guid, + _Out_ _At_(GuidString->Buffer, __drv_allocatesMem(Mem)) + PUNICODE_STRING GuidString); + NTSYSAPI NTSTATUS NTAPI diff --git a/include/psdk/CMakeLists.txt b/include/psdk/CMakeLists.txt index feae9deecef..af6208daa02 100644 --- a/include/psdk/CMakeLists.txt +++ b/include/psdk/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND SOURCE docobj.idl docobjectservice.idl downloadmgr.idl + dxgi.idl # dyngraph.idl exdisp.idl fusion.idl @@ -107,6 +108,8 @@ list(APPEND SOURCE urlmon.idl vmr9.idl # vmrender.idl + wbemcli.idl + wbemprov.idl wia_lh.idl wia_xp.idl wincodec.idl @@ -119,16 +122,13 @@ list(APPEND SOURCE ctfutb.idl xmllite.idl) -if(NOT MSVC) - list(APPEND SOURCE - wbemcli.idl) -endif() - add_idl_headers(psdk ${SOURCE}) - add_typelib(stdole2.idl) add_custom_target(stdole2 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/stdole2.tlb) +add_idl_headers(d3d_idl_headers d3d10.idl d3dcommon.idl) + +add_iid_library(dxgi_uuids dxgi.idl) add_iid_library(wuguid wuapi.idl) add_iid_library(xml_uuids msxml2.idl) diff --git a/include/psdk/control.idl b/include/psdk/control.idl index 7d1c83b92c3..884c4109b53 100644 --- a/include/psdk/control.idl +++ b/include/psdk/control.idl @@ -19,228 +19,230 @@ import "oaidl.idl"; -interface IMediaControl; -interface IBasicAudio; -interface IBasicVideo; -interface IVideoWindow; -interface IMediaEvent; -interface IMediaEventEx; -interface IMediaPosition; - -typedef LONG OAFilterState; -typedef LONG_PTR OAHWND; -typedef LONG_PTR OAEVENT; - -cpp_quote("#ifndef REFTIME_DEFINED") -cpp_quote("#define REFTIME_DEFINED") -typedef DOUBLE REFTIME; -cpp_quote("#endif") - -/***************************************************************************** - * IMediaControl interface - */ [ - object, - uuid(56a868b1-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) + version(1.0), + uuid(56a868b0-0ad4-11ce-b03a-0020af0ba770) ] -interface IMediaControl : IDispatch +library QuartzTypeLib { - HRESULT Run(); - HRESULT Pause(); - HRESULT Stop(); - HRESULT GetState( [in] LONG msTimeout, [out] OAFilterState *pfs ); - HRESULT RenderFile( [in] BSTR strFilename ); - HRESULT AddSourceFilter( [in] BSTR strFilename, [out] IDispatch **ppUnk ); - [propget] HRESULT FilterCollection( [out] IDispatch **ppUnk ); - [propget] HRESULT RegFilterCollection( [out] IDispatch **ppUnk ); - HRESULT StopWhenReady(); -} + importlib("stdole2.tlb"); + + typedef LONG OAFilterState; + typedef LONG_PTR OAHWND; + typedef LONG_PTR OAEVENT; + + cpp_quote("#ifndef REFTIME_DEFINED") + cpp_quote("#define REFTIME_DEFINED") + typedef DOUBLE REFTIME; + cpp_quote("#endif") + + /*************************************************************************** + * IMediaControl interface + */ + [ + object, + uuid(56a868b1-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IMediaControl : IDispatch + { + HRESULT Run(); + HRESULT Pause(); + HRESULT Stop(); + HRESULT GetState( [in] LONG msTimeout, [out] OAFilterState *pfs ); + HRESULT RenderFile( [in] BSTR strFilename ); + HRESULT AddSourceFilter( [in] BSTR strFilename, [out] IDispatch **ppUnk ); + [propget] HRESULT FilterCollection( [out] IDispatch **ppUnk ); + [propget] HRESULT RegFilterCollection( [out] IDispatch **ppUnk ); + HRESULT StopWhenReady(); + } -/***************************************************************************** - * IBasicAudio interface - */ -[ - object, - uuid(56a868b3-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) -] -interface IBasicAudio : IDispatch -{ - [propput] HRESULT Volume( [in] LONG lVolume ); - [propget] HRESULT Volume( [out] LONG *plVolume ); - [propput] HRESULT Balance( [in] LONG lBalance ); - [propget] HRESULT Balance( [out] LONG *plBalance ); -} + /*************************************************************************** + * IBasicAudio interface + */ + [ + object, + uuid(56a868b3-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IBasicAudio : IDispatch + { + [propput] HRESULT Volume( [in] LONG lVolume ); + [propget] HRESULT Volume( [out] LONG *plVolume ); + [propput] HRESULT Balance( [in] LONG lBalance ); + [propget] HRESULT Balance( [out] LONG *plBalance ); + } -/***************************************************************************** - * IVideoWindow interface - */ -[ - object, - uuid(56a868b4-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) -] -interface IVideoWindow : IDispatch -{ - [propput] HRESULT Caption( [in] BSTR strCaption ); - [propget] HRESULT Caption( [out] BSTR *strCaption ); - [propput] HRESULT WindowStyle( [in] LONG WindowStyle ); - [propget] HRESULT WindowStyle( [out] LONG *WindowStyle ); - [propput] HRESULT WindowStyleEx( [in] LONG WindowStyleEx ); - [propget] HRESULT WindowStyleEx( [out] LONG *WindowStyleEx ); - [propput] HRESULT AutoShow( [in] LONG AutoShow ); - [propget] HRESULT AutoShow( [out] LONG *AutoShow ); - [propput] HRESULT WindowState( [in] LONG WindowState ); - [propget] HRESULT WindowState( [out] LONG *WindowState ); - [propput] HRESULT BackgroundPalette( [in] LONG BackgroundPalette ); - [propget] HRESULT BackgroundPalette( [out] LONG *pBackgroundPalette ); - [propput] HRESULT Visible( [in] LONG Visible ); - [propget] HRESULT Visible( [out] LONG *pVisible ); - [propput] HRESULT Left( [in] LONG Left ); - [propget] HRESULT Left( [out] LONG *pLeft ); - [propput] HRESULT Width( [in] LONG Width ); - [propget] HRESULT Width( [out] LONG *pWidth ); - [propput] HRESULT Top( [in] LONG Top ); - [propget] HRESULT Top( [out] LONG *pTop ); - [propput] HRESULT Height( [in] LONG Height ); - [propget] HRESULT Height( [out] LONG *pHeight ); - [propput] HRESULT Owner( [in] OAHWND Owner ); - [propget] HRESULT Owner( [out] OAHWND *Owner ); - [propput] HRESULT MessageDrain( [in] OAHWND Drain ); - [propget] HRESULT MessageDrain( [out] OAHWND *Drain ); - [propget] HRESULT BorderColor( [out] LONG *Color ); - [propput] HRESULT BorderColor( [in] LONG Color ); - [propget] HRESULT FullScreenMode( [out] LONG *FullScreenMode ); - [propput] HRESULT FullScreenMode( [in] LONG FullScreenMode ); - HRESULT SetWindowForeground( [in] LONG Focus ); - HRESULT NotifyOwnerMessage( [in] OAHWND hwnd, [in] LONG uMsg, [in] LONG_PTR wParam, [in] LONG_PTR lParam ); - HRESULT SetWindowPosition( [in] LONG Left, [in] LONG Top, [in] LONG Width, [in] LONG Height ); - HRESULT GetWindowPosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT GetMinIdealImageSize( [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT GetMaxIdealImageSize( [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT GetRestorePosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT HideCursor( [in] LONG HideCursor ); - HRESULT IsCursorHidden( [out] LONG *CursorHidden ); -} + /*************************************************************************** + * IVideoWindow interface + */ + [ + object, + uuid(56a868b4-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IVideoWindow : IDispatch + { + [propput] HRESULT Caption( [in] BSTR strCaption ); + [propget] HRESULT Caption( [out] BSTR *strCaption ); + [propput] HRESULT WindowStyle( [in] LONG WindowStyle ); + [propget] HRESULT WindowStyle( [out] LONG *WindowStyle ); + [propput] HRESULT WindowStyleEx( [in] LONG WindowStyleEx ); + [propget] HRESULT WindowStyleEx( [out] LONG *WindowStyleEx ); + [propput] HRESULT AutoShow( [in] LONG AutoShow ); + [propget] HRESULT AutoShow( [out] LONG *AutoShow ); + [propput] HRESULT WindowState( [in] LONG WindowState ); + [propget] HRESULT WindowState( [out] LONG *WindowState ); + [propput] HRESULT BackgroundPalette( [in] LONG BackgroundPalette ); + [propget] HRESULT BackgroundPalette( [out] LONG *pBackgroundPalette ); + [propput] HRESULT Visible( [in] LONG Visible ); + [propget] HRESULT Visible( [out] LONG *pVisible ); + [propput] HRESULT Left( [in] LONG Left ); + [propget] HRESULT Left( [out] LONG *pLeft ); + [propput] HRESULT Width( [in] LONG Width ); + [propget] HRESULT Width( [out] LONG *pWidth ); + [propput] HRESULT Top( [in] LONG Top ); + [propget] HRESULT Top( [out] LONG *pTop ); + [propput] HRESULT Height( [in] LONG Height ); + [propget] HRESULT Height( [out] LONG *pHeight ); + [propput] HRESULT Owner( [in] OAHWND Owner ); + [propget] HRESULT Owner( [out] OAHWND *Owner ); + [propput] HRESULT MessageDrain( [in] OAHWND Drain ); + [propget] HRESULT MessageDrain( [out] OAHWND *Drain ); + [propget] HRESULT BorderColor( [out] LONG *Color ); + [propput] HRESULT BorderColor( [in] LONG Color ); + [propget] HRESULT FullScreenMode( [out] LONG *FullScreenMode ); + [propput] HRESULT FullScreenMode( [in] LONG FullScreenMode ); + HRESULT SetWindowForeground( [in] LONG Focus ); + HRESULT NotifyOwnerMessage( [in] OAHWND hwnd, [in] LONG uMsg, [in] LONG_PTR wParam, [in] LONG_PTR lParam ); + HRESULT SetWindowPosition( [in] LONG Left, [in] LONG Top, [in] LONG Width, [in] LONG Height ); + HRESULT GetWindowPosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT GetMinIdealImageSize( [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT GetMaxIdealImageSize( [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT GetRestorePosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT HideCursor( [in] LONG HideCursor ); + HRESULT IsCursorHidden( [out] LONG *CursorHidden ); + } -/***************************************************************************** - * IBasicVideo interface - */ -[ - object, - uuid(56a868b5-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) -] -interface IBasicVideo : IDispatch -{ - [propget] HRESULT AvgTimePerFrame( [out] REFTIME *pAvgTimePerFrame ); - [propget] HRESULT BitRate( [out] LONG *pBitRate ); - [propget] HRESULT BitErrorRate( [out] LONG *pBitErrorRate ); - [propget] HRESULT VideoWidth( [out] LONG *pVideoWidth ); - [propget] HRESULT VideoHeight( [out] LONG *pVideoHeight ); - [propput] HRESULT SourceLeft( [in] LONG SourceLeft ); - [propget] HRESULT SourceLeft( [out] LONG *pSourceLeft ); - [propput] HRESULT SourceWidth( [in] LONG SourceWidth ); - [propget] HRESULT SourceWidth( [out] LONG *pSourceWidth ); - [propput] HRESULT SourceTop( [in] LONG SourceTop ); - [propget] HRESULT SourceTop( [out] LONG *pSourceTop ); - [propput] HRESULT SourceHeight( [in] LONG SourceHeight ); - [propget] HRESULT SourceHeight( [out] LONG *pSourceHeight ); - [propput] HRESULT DestinationLeft( [in] LONG DestinationLeft ); - [propget] HRESULT DestinationLeft( [out] LONG *pDestinationLeft ); - [propput] HRESULT DestinationWidth( [in] LONG DestinationWidth ); - [propget] HRESULT DestinationWidth( [out] LONG *pDestinationWidth ); - [propput] HRESULT DestinationTop( [in] LONG DestinationTop ); - [propget] HRESULT DestinationTop( [out] LONG *pDestinationTop ); - [propput] HRESULT DestinationHeight( [in] LONG DestinationHeight ); - [propget] HRESULT DestinationHeight( [out] LONG *pDestinationHeight ); - HRESULT SetSourcePosition( [in] LONG Left, [in] LONG Top, [in] LONG Width, [in] LONG Height ); - HRESULT GetSourcePosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT SetDefaultSourcePosition(); - HRESULT SetDestinationPosition( [in] LONG Left, [in] LONG Top, [in] LONG Width, [in] LONG Height ); - HRESULT GetDestinationPosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT SetDefaultDestinationPosition(); - HRESULT GetVideoSize( [out] LONG *pWidth, [out] LONG *pHeight ); - HRESULT GetVideoPaletteEntries( [in] LONG StartIndex, - [in] LONG Entries, - [out] LONG *pRetrieved, - [out, size_is(Entries), length_is(*pRetrieved)] LONG *pPalette ); - HRESULT GetCurrentImage( [in, out] LONG *pBufferSize, - [out, size_is(*pBufferSize), length_is(*pBufferSize)] LONG *pDIBImage ); - HRESULT IsUsingDefaultSource(); - HRESULT IsUsingDefaultDestination(); -} + /*************************************************************************** + * IBasicVideo interface + */ + [ + object, + uuid(56a868b5-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IBasicVideo : IDispatch + { + [propget] HRESULT AvgTimePerFrame( [out] REFTIME *pAvgTimePerFrame ); + [propget] HRESULT BitRate( [out] LONG *pBitRate ); + [propget] HRESULT BitErrorRate( [out] LONG *pBitErrorRate ); + [propget] HRESULT VideoWidth( [out] LONG *pVideoWidth ); + [propget] HRESULT VideoHeight( [out] LONG *pVideoHeight ); + [propput] HRESULT SourceLeft( [in] LONG SourceLeft ); + [propget] HRESULT SourceLeft( [out] LONG *pSourceLeft ); + [propput] HRESULT SourceWidth( [in] LONG SourceWidth ); + [propget] HRESULT SourceWidth( [out] LONG *pSourceWidth ); + [propput] HRESULT SourceTop( [in] LONG SourceTop ); + [propget] HRESULT SourceTop( [out] LONG *pSourceTop ); + [propput] HRESULT SourceHeight( [in] LONG SourceHeight ); + [propget] HRESULT SourceHeight( [out] LONG *pSourceHeight ); + [propput] HRESULT DestinationLeft( [in] LONG DestinationLeft ); + [propget] HRESULT DestinationLeft( [out] LONG *pDestinationLeft ); + [propput] HRESULT DestinationWidth( [in] LONG DestinationWidth ); + [propget] HRESULT DestinationWidth( [out] LONG *pDestinationWidth ); + [propput] HRESULT DestinationTop( [in] LONG DestinationTop ); + [propget] HRESULT DestinationTop( [out] LONG *pDestinationTop ); + [propput] HRESULT DestinationHeight( [in] LONG DestinationHeight ); + [propget] HRESULT DestinationHeight( [out] LONG *pDestinationHeight ); + HRESULT SetSourcePosition( [in] LONG Left, [in] LONG Top, [in] LONG Width, [in] LONG Height ); + HRESULT GetSourcePosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT SetDefaultSourcePosition(); + HRESULT SetDestinationPosition( [in] LONG Left, [in] LONG Top, [in] LONG Width, [in] LONG Height ); + HRESULT GetDestinationPosition( [out] LONG *pLeft, [out] LONG *pTop, [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT SetDefaultDestinationPosition(); + HRESULT GetVideoSize( [out] LONG *pWidth, [out] LONG *pHeight ); + HRESULT GetVideoPaletteEntries( [in] LONG StartIndex, + [in] LONG Entries, + [out] LONG *pRetrieved, + [out, size_is(Entries), length_is(*pRetrieved)] LONG *pPalette ); + HRESULT GetCurrentImage( [in, out] LONG *pBufferSize, + [out, size_is(*pBufferSize), length_is(*pBufferSize)] LONG *pDIBImage ); + HRESULT IsUsingDefaultSource(); + HRESULT IsUsingDefaultDestination(); + } -[ - uuid(329bb360-f6ea-11d1-9038-00a0c9697298), - helpstring("IBasicVideo2"), - odl -] + [ + uuid(329bb360-f6ea-11d1-9038-00a0c9697298), + helpstring("IBasicVideo2"), + odl + ] -interface IBasicVideo2 : IBasicVideo -{ - HRESULT GetPreferredAspectRatio([out] LONG *plAspectX, [out] LONG *plAspectY); -} + interface IBasicVideo2 : IBasicVideo + { + HRESULT GetPreferredAspectRatio([out] LONG *plAspectX, [out] LONG *plAspectY); + } -/***************************************************************************** - * IMediaEvent interface - */ -[ - object, - uuid(56a868b6-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) -] -interface IMediaEvent : IDispatch -{ - HRESULT GetEventHandle( [out] OAEVENT *hEvent ); - HRESULT GetEvent( [out] LONG *lEventCode, [out] LONG_PTR *lParam1, [out] LONG_PTR *lParam2, [in] LONG msTimeout ); - HRESULT WaitForCompletion( [in] LONG msTimeout, [out] LONG *pEvCode ); - HRESULT CancelDefaultHandling( [in] LONG lEvCode ); - HRESULT RestoreDefaultHandling( [in] LONG lEvCode ); - HRESULT FreeEventParams( [in] LONG lEvCode, [in] LONG_PTR lParam1, [in] LONG_PTR lParam2 ); -} + /*************************************************************************** + * IMediaEvent interface + */ + [ + object, + uuid(56a868b6-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IMediaEvent : IDispatch + { + HRESULT GetEventHandle( [out] OAEVENT *hEvent ); + HRESULT GetEvent( [out] LONG *lEventCode, [out] LONG_PTR *lParam1, [out] LONG_PTR *lParam2, [in] LONG msTimeout ); + HRESULT WaitForCompletion( [in] LONG msTimeout, [out] LONG *pEvCode ); + HRESULT CancelDefaultHandling( [in] LONG lEvCode ); + HRESULT RestoreDefaultHandling( [in] LONG lEvCode ); + HRESULT FreeEventParams( [in] LONG lEvCode, [in] LONG_PTR lParam1, [in] LONG_PTR lParam2 ); + } -/***************************************************************************** - * IMediaEventEx interface - */ -[ - object, - uuid(56a868c0-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) -] -interface IMediaEventEx : IMediaEvent -{ - HRESULT SetNotifyWindow( [in] OAHWND hwnd, [in] LONG lMsg, [in] LONG_PTR lInstanceData ); - HRESULT SetNotifyFlags( [in] LONG lNoNotifyFlags ); - HRESULT GetNotifyFlags( [out] LONG *lplNoNotifyFlags ); -} + /*************************************************************************** + * IMediaEventEx interface + */ + [ + object, + uuid(56a868c0-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IMediaEventEx : IMediaEvent + { + HRESULT SetNotifyWindow( [in] OAHWND hwnd, [in] LONG lMsg, [in] LONG_PTR lInstanceData ); + HRESULT SetNotifyFlags( [in] LONG lNoNotifyFlags ); + HRESULT GetNotifyFlags( [out] LONG *lplNoNotifyFlags ); + } -/***************************************************************************** - * IMediaPosition interface - */ -[ - object, - uuid(56a868b2-0ad4-11ce-b03a-0020af0ba770), - pointer_default(unique) -] -interface IMediaPosition : IDispatch -{ - HRESULT get_Duration( [out] REFTIME *plength ); - HRESULT put_CurrentPosition( [in] REFTIME llTime ); - HRESULT get_CurrentPosition( [out] REFTIME *pllTime ); - HRESULT get_StopTime( [out] REFTIME *pllTime ); - HRESULT put_StopTime( [in] REFTIME llTime ); - HRESULT get_PrerollTime( [out] REFTIME *pllTime ); - HRESULT put_PrerollTime( [in] REFTIME llTime ); - HRESULT put_Rate( [in] double dRate ); - HRESULT get_Rate( [out] double *pdRate ); - HRESULT CanSeekForward( [out] LONG *pCanSeekForward ); - HRESULT CanSeekBackward( [out] LONG *pCanSeekBackward ); -} + /*************************************************************************** + * IMediaPosition interface + */ + [ + object, + uuid(56a868b2-0ad4-11ce-b03a-0020af0ba770), + pointer_default(unique) + ] + interface IMediaPosition : IDispatch + { + HRESULT get_Duration( [out] REFTIME *plength ); + HRESULT put_CurrentPosition( [in] REFTIME llTime ); + HRESULT get_CurrentPosition( [out] REFTIME *pllTime ); + HRESULT get_StopTime( [out] REFTIME *pllTime ); + HRESULT put_StopTime( [in] REFTIME llTime ); + HRESULT get_PrerollTime( [out] REFTIME *pllTime ); + HRESULT put_PrerollTime( [in] REFTIME llTime ); + HRESULT put_Rate( [in] double dRate ); + HRESULT get_Rate( [out] double *pdRate ); + HRESULT CanSeekForward( [out] LONG *pCanSeekForward ); + HRESULT CanSeekBackward( [out] LONG *pCanSeekBackward ); + } + +} /* library QuartzTypeLib */ diff --git a/include/psdk/d3d10.idl b/include/psdk/d3d10.idl new file mode 100644 index 00000000000..73a9e62a650 --- /dev/null +++ b/include/psdk/d3d10.idl @@ -0,0 +1,1600 @@ +/* + * Copyright 2007 Andras Kovacs + * + * 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 + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgi.idl"; +import "d3dcommon.idl"; + +cpp_quote("#ifndef _D3D10_CONSTANTS") +cpp_quote("#define _D3D10_CONSTANTS") +const float D3D10_DEFAULT_BLEND_FACTOR_ALPHA = 1.0; +const float D3D10_DEFAULT_BLEND_FACTOR_BLUE = 1.0; +const float D3D10_DEFAULT_BLEND_FACTOR_GREEN = 1.0; +const float D3D10_DEFAULT_BLEND_FACTOR_RED = 1.0; +const float D3D10_DEFAULT_BORDER_COLOR_COMPONENT = 0.0; +const float D3D10_DEFAULT_SLOPE_SCALED_DEPTH_BIAS = 0.0; +const float D3D10_DEFAULT_DEPTH_BIAS_CLAMP = 0.0; +const float D3D10_DEFAULT_MAX_ANISOTROPY = 16.0; +const float D3D10_DEFAULT_MIP_LOD_BIAS = 0.0; +const float D3D10_DEFAULT_VIEWPORT_MAX_DEPTH = 0.0; +const float D3D10_DEFAULT_VIEWPORT_MIN_DEPTH = 0.0; +const float D3D10_FLOAT16_FUSED_TOLERANCE_IN_ULP = 0.6; +const float D3D10_FLOAT32_MAX = 3.402823466e+38; +const float D3D10_FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP = 0.6; +const float D3D10_FLOAT_TO_SRGB_EXPONENT_DENOMINATOR = 2.4; +const float D3D10_FLOAT_TO_SRGB_EXPONENT_NUMERATOR = 1.0; +const float D3D10_FLOAT_TO_SRGB_OFFSET = 0.055; +const float D3D10_FLOAT_TO_SRGB_SCALE_1 = 12.92; +const float D3D10_FLOAT_TO_SRGB_SCALE_2 = 1.055; +const float D3D10_FLOAT_TO_SRGB_THRESHOLD = 0.0031308; +const float D3D10_FTOI_INSTRUCTION_MAX_INPUT = 2147483647.999; +const float D3D10_FTOI_INSTRUCTION_MIN_INPUT = -2147483648.999; +const float D3D10_FTOU_INSTRUCTION_MAX_INPUT = 4294967295.999; +const float D3D10_FTOU_INSTRUCTION_MIN_INPUT = 0.0; +const float D3D10_LINEAR_GAMMA = 1.0; +const float D3D10_MAX_BORDER_COLOR_COMPONENT = 1.0; +const float D3D10_MAX_DEPTH = 1.0; +const float D3D10_MAX_POSITION_VALUE = 3.402823466e+34; +const float D3D10_MIN_BORDER_COLOR_COMPONENT = 0.0; +const float D3D10_MIN_DEPTH = 0.0; +const float D3D10_MIP_LOD_BIAS_MAX = 15.99; +const float D3D10_MIP_LOD_BIAS_MIN = -16.0; +const float D3D10_PS_PIXEL_CENTER_FRACTIONAL_COMPONENT = 0.5; +const float D3D10_MULTISAMPLE_ANTIALIAS_LINE_WIDTH = 1.4; +const float D3D10_SRGB_GAMMA = 2.2; +const float D3D10_SRGB_TO_FLOAT_DENOMINATOR_1 = 12.92; +const float D3D10_SRGB_TO_FLOAT_DENOMINATOR_2 = 1.055; +const float D3D10_SRGB_TO_FLOAT_EXPONENT = 2.4; +const float D3D10_SRGB_TO_FLOAT_OFFSET = 0.055; +const float D3D10_SRGB_TO_FLOAT_THRESHOLD = 0.04045; +const float D3D10_SRGB_TO_FLOAT_TOLERANCE_IN_ULP = 0.5; +const float D3D10_PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT = 0.0; +const float D3D_SPEC_VERSION = 1.050005; +const unsigned int D3D10_16BIT_INDEX_STRIP_CUT_VALUE = 0xffff; +const unsigned int D3D10_32BIT_INDEX_STRIP_CUT_VALUE = 0xffffffff; +const unsigned int D3D10_8BIT_INDEX_STRIP_CUT_VALUE = 0xff; +const unsigned int D3D10_ARRAY_AXIS_ADDRESS_RANGE_BIT_COUNT = 9; +const unsigned int D3D10_CLIP_OR_CULL_DISTANCE_COUNT = 8; +const unsigned int D3D10_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT = 2; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT = 14; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS = 4; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT = 15; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT = 15; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST = 1; +const unsigned int D3D10_COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_COMMONSHADER_FLOWCONTROL_NESTING_LIMIT = 64; +const unsigned int D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT = 1; +const unsigned int D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST = 1; +const unsigned int D3D10_COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS = 1; +const unsigned int D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT = 128; +const unsigned int D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST = 1; +const unsigned int D3D10_COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT = 128; +const unsigned int D3D10_COMMONSHADER_SAMPLER_REGISTER_COMPONENTS = 1; +const unsigned int D3D10_COMMONSHADER_SAMPLER_REGISTER_COUNT = 16; +const unsigned int D3D10_COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST = 1; +const unsigned int D3D10_COMMONSHADER_SAMPLER_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT = 16; +const unsigned int D3D10_COMMONSHADER_SUBROUTINE_NESTING_LIMIT = 32; +const unsigned int D3D10_COMMONSHADER_TEMP_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_COMMONSHADER_TEMP_REGISTER_COUNT = 4096; +const unsigned int D3D10_COMMONSHADER_TEMP_REGISTER_READS_PER_INST = 3; +const unsigned int D3D10_COMMONSHADER_TEMP_REGISTER_READ_PORTS = 3; +const unsigned int D3D10_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX = 10; +const int D3D10_COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN = -10; +const int D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE = -8; +const unsigned int D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE = 7; +const unsigned int D3D10_DEFAULT_DEPTH_BIAS = 0; +const unsigned int D3D10_DEFAULT_RENDER_TARGET_ARRAY_INDEX = 0; +const unsigned int D3D10_DEFAULT_SAMPLE_MASK = 0xffffffff; +const unsigned int D3D10_DEFAULT_SCISSOR_ENDX = 0; +const unsigned int D3D10_DEFAULT_SCISSOR_ENDY = 0; +const unsigned int D3D10_DEFAULT_SCISSOR_STARTX = 0; +const unsigned int D3D10_DEFAULT_SCISSOR_STARTY = 0; +const unsigned int D3D10_DEFAULT_STENCIL_READ_MASK = 0xff; +const unsigned int D3D10_DEFAULT_STENCIL_REFERENCE = 0; +const unsigned int D3D10_DEFAULT_STENCIL_WRITE_MASK = 0xff; +const unsigned int D3D10_DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX = 0; +const unsigned int D3D10_DEFAULT_VIEWPORT_HEIGHT = 0; +const unsigned int D3D10_DEFAULT_VIEWPORT_TOPLEFTX = 0; +const unsigned int D3D10_DEFAULT_VIEWPORT_TOPLEFTY = 0; +const unsigned int D3D10_DEFAULT_VIEWPORT_WIDTH = 0; +const unsigned int D3D10_GS_INPUT_PRIM_CONST_REGISTER_COMPONENTS = 1; +const unsigned int D3D10_GS_INPUT_PRIM_CONST_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_GS_INPUT_PRIM_CONST_REGISTER_COUNT = 1; +const unsigned int D3D10_GS_INPUT_PRIM_CONST_REGISTER_READS_PER_INST = 2; +const unsigned int D3D10_GS_INPUT_PRIM_CONST_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_GS_INPUT_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_GS_INPUT_REGISTER_COMPONENT_BIT_COUNT =32; +const unsigned int D3D10_GS_INPUT_REGISTER_COUNT = 16; +const unsigned int D3D10_GS_INPUT_REGISTER_READS_PER_INST = 2; +const unsigned int D3D10_GS_INPUT_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_GS_INPUT_REGISTER_VERTICES = 6; +const unsigned int D3D10_GS_OUTPUT_ELEMENTS = 32; +const unsigned int D3D10_GS_OUTPUT_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_GS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_GS_OUTPUT_REGISTER_COUNT = 32; +const unsigned int D3D10_IA_DEFAULT_INDEX_BUFFER_OFFSET_IN_BYTES = 0; +const unsigned int D3D10_IA_DEFAULT_PRIMITIVE_TOPOLOGY = 0; +const unsigned int D3D10_IA_DEFAULT_VERTEX_BUFFER_OFFSET_IN_BYTES = 0; +const unsigned int D3D10_IA_INDEX_INPUT_RESOURCE_SLOT_COUNT = 1; +const unsigned int D3D10_IA_INSTANCE_ID_BIT_COUNT = 32; +const unsigned int D3D10_IA_INTEGER_ARITHMETIC_BIT_COUNT = 32; +const unsigned int D3D10_IA_PRIMITIVE_ID_BIT_COUNT = 32; +const unsigned int D3D10_IA_VERTEX_ID_BIT_COUNT = 32; +const unsigned int D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 16; +const unsigned int D3D10_IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS = 64; +const unsigned int D3D10_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT = 16; +const unsigned int D3D10_INTEGER_DIVIDE_BY_ZERO_QUOTIENT = 0xffffffff; +const unsigned int D3D10_INTEGER_DIVIDE_BY_ZERO_REMAINDER = 0xffffffff; +const unsigned int D3D10_MAX_MAXANISOTROPY = 16; +const unsigned int D3D10_MAX_MULTISAMPLE_SAMPLE_COUNT = 32; +const unsigned int D3D10_MAX_TEXTURE_DIMENSION_2_TO_EXP = 17; +const unsigned int D3D10_MIN_MAXANISOTROPY = 0; +const unsigned int D3D10_MIP_LOD_FRACTIONAL_BIT_COUNT = 6; +const unsigned int D3D10_MIP_LOD_RANGE_BIT_COUNT = 8; +const unsigned int D3D10_NONSAMPLE_FETCH_OUT_OF_RANGE_ACCESS_RESULT = 0; +const unsigned int D3D10_PIXEL_ADDRESS_RANGE_BIT_COUNT = 13; +const unsigned int D3D10_PRE_SCISSOR_PIXEL_ADDRESS_RANGE_BIT_COUNT = 15; +const unsigned int D3D10_PS_FRONTFACING_DEFAULT_VALUE = 0xffffffff; +const unsigned int D3D10_PS_FRONTFACING_FALSE_VALUE = 0; +const unsigned int D3D10_PS_FRONTFACING_TRUE_VALUE = 0xffffffff; +const unsigned int D3D10_PS_INPUT_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_PS_INPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_PS_INPUT_REGISTER_COUNT = 32; +const unsigned int D3D10_PS_INPUT_REGISTER_READS_PER_INST = 2; +const unsigned int D3D10_PS_INPUT_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_PS_OUTPUT_DEPTH_REGISTER_COMPONENTS = 1; +const unsigned int D3D10_PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_PS_OUTPUT_DEPTH_REGISTER_COUNT = 1; +const unsigned int D3D10_PS_OUTPUT_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_PS_OUTPUT_REGISTER_COUNT = 8; +const unsigned int D3D10_REQ_BLEND_OBJECT_COUNT_PER_CONTEXT = 4096; +const unsigned int D3D10_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP = 27; +const unsigned int D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; +const unsigned int D3D10_REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_CONTEXT = 4096; +const unsigned int D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP = 32; +const unsigned int D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP = 32; +const unsigned int D3D10_REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION = 8192; +const unsigned int D3D10_REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT = 1024; +const unsigned int D3D10_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; +const unsigned int D3D10_REQ_MAXANISOTROPY = 16; +const unsigned int D3D10_REQ_MIP_LEVELS = 14; +const unsigned int D3D10_REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES = 2048; +const unsigned int D3D10_REQ_RASTERIZER_OBJECT_COUNT_PER_CONTEXT = 4096; +const unsigned int D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH = 8192; +const unsigned int D3D10_REQ_RESOURCE_SIZE_IN_MEGABYTES = 128; +const unsigned int D3D10_REQ_RESOURCE_VIEW_COUNT_PER_CONTEXT_2_TO_EXP = 20; +const unsigned int D3D10_REQ_SAMPLER_OBJECT_COUNT_PER_CONTEXT = 4096; +const unsigned int D3D10_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION = 512; +const unsigned int D3D10_REQ_TEXTURE1D_U_DIMENSION = 8192; +const unsigned int D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION = 512; +const unsigned int D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION = 8192; +const unsigned int D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION = 2048; +const unsigned int D3D10_REQ_TEXTURECUBE_DIMENSION = 8192; +const unsigned int D3D10_RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL = 0; +const unsigned int D3D10_SHADER_MAJOR_VERSION = 4; +const unsigned int D3D10_SHADER_MINOR_VERSION = 0; +const unsigned int D3D10_SHIFT_INSTRUCTION_PAD_VALUE = 0; +const unsigned int D3D10_SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT = 5; +const unsigned int D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT = 8; +const unsigned int D3D10_SO_BUFFER_MAX_STRIDE_IN_BYTES = 2048; +const unsigned int D3D10_SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES = 256; +const unsigned int D3D10_SO_BUFFER_SLOT_COUNT = 4; +const unsigned int D3D10_SO_DDI_REGISTER_INDEX_DENOTING_GAP = 0xffffffff; +const unsigned int D3D10_SO_MULTIPLE_BUFFER_ELEMENTS_PER_BUFFER = 1; +const unsigned int D3D10_SO_SINGLE_BUFFER_COMPONENT_LIMIT = 64; +const unsigned int D3D10_STANDARD_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_STANDARD_COMPONENT_BIT_COUNT_DOUBLED = 64; +const unsigned int D3D10_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4; +const unsigned int D3D10_STANDARD_PIXEL_COMPONENT_COUNT = 128; +const unsigned int D3D10_STANDARD_PIXEL_ELEMENT_COUNT = 32; +const unsigned int D3D10_STANDARD_VECTOR_SIZE = 4; +const unsigned int D3D10_STANDARD_VERTEX_ELEMENT_COUNT = 16; +const unsigned int D3D10_STANDARD_VERTEX_TOTAL_COMPONENT_COUNT = 64; +const unsigned int D3D10_SUBPIXEL_FRACTIONAL_BIT_COUNT = 8; +const unsigned int D3D10_SUBTEXEL_FRACTIONAL_BIT_COUNT = 6; +const unsigned int D3D10_TEXEL_ADDRESS_RANGE_BIT_COUNT = 18; +const unsigned int D3D10_UNBOUND_MEMORY_ACCESS_RESULT = 0; +const unsigned int D3D10_VIEWPORT_AND_SCISSORRECT_MAX_INDEX = 15; +const unsigned int D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; +const unsigned int D3D10_VIEWPORT_BOUNDS_MAX = 16383; +const int D3D10_VIEWPORT_BOUNDS_MIN = -16384; +const unsigned int D3D10_VS_INPUT_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_VS_INPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_VS_INPUT_REGISTER_COUNT = 16; +const unsigned int D3D10_VS_INPUT_REGISTER_READS_PER_INST = 2; +const unsigned int D3D10_VS_INPUT_REGISTER_READ_PORTS = 1; +const unsigned int D3D10_VS_OUTPUT_REGISTER_COMPONENTS = 4; +const unsigned int D3D10_VS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT = 32; +const unsigned int D3D10_VS_OUTPUT_REGISTER_COUNT = 16; +const unsigned int D3D10_WHQL_CONTEXT_COUNT_FOR_RESOURCE_LIMIT = 10; +const unsigned int D3D10_WHQL_DRAWINDEXED_INDEX_COUNT_2_TO_EXP = 25; +const unsigned int D3D10_WHQL_DRAW_VERTEX_COUNT_2_TO_EXP = 25; +const unsigned int D3D_MAJOR_VERSION = 10; +const unsigned int D3D_MINOR_VERSION = 0; +const unsigned int D3D_SPEC_DATE_DAY = 8; +const unsigned int D3D_SPEC_DATE_MONTH = 8; +const unsigned int D3D_SPEC_DATE_YEAR = 2006; +cpp_quote("#endif") + +const unsigned int D3D10_APPEND_ALIGNED_ELEMENT = 0xffffffff; +const unsigned int _FACD3D10 = 0x87; +const unsigned int _FACD3D10DEBUG = _FACD3D10 + 1; +const unsigned int D3D10_FILTER_TYPE_MASK = 0x3; +const unsigned int D3D10_SDK_VERSION = 29; + +cpp_quote("#define MAKE_D3D10_HRESULT(code) MAKE_HRESULT( 1, _FACD3D10, code)") +cpp_quote("#define MAKE_D3D10_STATUS(code) MAKE_HRESULT( 0, _FACD3D10, code)") +cpp_quote("#define D3D10_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS MAKE_D3D10_HRESULT(1)") +cpp_quote("#define D3D10_ERROR_FILE_NOT_FOUND MAKE_D3D10_HRESULT(2)") + +typedef enum D3D10_BLEND { + D3D10_BLEND_ZERO = 1, + D3D10_BLEND_ONE = 2, + D3D10_BLEND_SRC_COLOR = 3, + D3D10_BLEND_INV_SRC_COLOR = 4, + D3D10_BLEND_SRC_ALPHA = 5, + D3D10_BLEND_INV_SRC_ALPHA = 6, + D3D10_BLEND_DEST_ALPHA = 7, + D3D10_BLEND_INV_DEST_ALPHA = 8, + D3D10_BLEND_DEST_COLOR = 9, + D3D10_BLEND_INV_DEST_COLOR = 10, + D3D10_BLEND_SRC_ALPHA_SAT = 11, + D3D10_BLEND_BLEND_FACTOR = 14, + D3D10_BLEND_INV_BLEND_FACTOR = 15, + D3D10_BLEND_SRC1_COLOR = 16, + D3D10_BLEND_INV_SRC1_COLOR = 17, + D3D10_BLEND_SRC1_ALPHA = 18, + D3D10_BLEND_INV_SRC1_ALPHA = 19 +} D3D10_BLEND; + +typedef enum D3D10_BLEND_OP { + D3D10_BLEND_OP_ADD = 1, + D3D10_BLEND_OP_SUBTRACT, + D3D10_BLEND_OP_REV_SUBTRACT, + D3D10_BLEND_OP_MIN, + D3D10_BLEND_OP_MAX, +} D3D10_BLEND_OP; + +typedef struct D3D10_BLEND_DESC { + BOOL AlphaToCoverageEnable; + BOOL BlendEnable[8]; + D3D10_BLEND SrcBlend; + D3D10_BLEND DestBlend; + D3D10_BLEND_OP BlendOp; + D3D10_BLEND SrcBlendAlpha; + D3D10_BLEND DestBlendAlpha; + D3D10_BLEND_OP BlendOpAlpha; + UINT8 RenderTargetWriteMask[8]; +} D3D10_BLEND_DESC; + +typedef enum D3D10_DEPTH_WRITE_MASK { + D3D10_DEPTH_WRITE_MASK_ZERO, + D3D10_DEPTH_WRITE_MASK_ALL, +} D3D10_DEPTH_WRITE_MASK; + +typedef enum D3D10_COMPARISON_FUNC { + D3D10_COMPARISON_NEVER = 1, + D3D10_COMPARISON_LESS, + D3D10_COMPARISON_EQUAL, + D3D10_COMPARISON_LESS_EQUAL, + D3D10_COMPARISON_GREATER, + D3D10_COMPARISON_NOT_EQUAL, + D3D10_COMPARISON_GREATER_EQUAL, + D3D10_COMPARISON_ALWAYS, +} D3D10_COMPARISON_FUNC; + +typedef enum D3D10_STENCIL_OP { + D3D10_STENCIL_OP_KEEP = 1, + D3D10_STENCIL_OP_ZERO, + D3D10_STENCIL_OP_REPLACE, + D3D10_STENCIL_OP_INCR_SAT, + D3D10_STENCIL_OP_DECR_SAT, + D3D10_STENCIL_OP_INVERT, + D3D10_STENCIL_OP_INCR, + D3D10_STENCIL_OP_DECR, +} D3D10_STENCIL_OP; + +typedef struct D3D10_DEPTH_STENCILOP_DESC { + D3D10_STENCIL_OP StencilFailOp; + D3D10_STENCIL_OP StencilDepthFailOp; + D3D10_STENCIL_OP StencilPassOp; + D3D10_COMPARISON_FUNC StencilFunc; +} D3D10_DEPTH_STENCILOP_DESC; + +typedef struct D3D10_DEPTH_STENCIL_DESC { + BOOL DepthEnable; + D3D10_DEPTH_WRITE_MASK DepthWriteMask; + D3D10_COMPARISON_FUNC DepthFunc; + BOOL StencilEnable; + UINT8 StencilReadMask; + UINT8 StencilWriteMask; + D3D10_DEPTH_STENCILOP_DESC FrontFace; + D3D10_DEPTH_STENCILOP_DESC BackFace; +} D3D10_DEPTH_STENCIL_DESC; + +typedef enum D3D10_FILL_MODE { + D3D10_FILL_WIREFRAME = 2, + D3D10_FILL_SOLID, +} D3D10_FILL_MODE; + +typedef enum D3D10_CULL_MODE { + D3D10_CULL_NONE = 1, + D3D10_CULL_FRONT, + D3D10_CULL_BACK, +} D3D10_CULL_MODE; + +typedef struct D3D10_RASTERIZER_DESC { + D3D10_FILL_MODE FillMode; + D3D10_CULL_MODE CullMode; + BOOL FrontCounterClockwise; + INT DepthBias; + FLOAT DepthBiasClamp; + FLOAT SlopeScaledDepthBias; + BOOL DepthClipEnable; + BOOL ScissorEnable; + BOOL MultisampleEnable; + BOOL AntialiasedLineEnable; +} D3D10_RASTERIZER_DESC; + +typedef enum D3D10_FILTER { + D3D10_FILTER_MIN_MAG_MIP_POINT = 0, + D3D10_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1, + D3D10_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4, + D3D10_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5, + D3D10_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, + D3D10_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, + D3D10_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, + D3D10_FILTER_MIN_MAG_MIP_LINEAR = 0x15, + D3D10_FILTER_ANISOTROPIC = 0x55, + D3D10_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, + D3D10_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, + D3D10_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, + D3D10_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, + D3D10_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, + D3D10_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, + D3D10_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, + D3D10_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, + D3D10_FILTER_COMPARISON_ANISOTROPIC = 0xd5, + D3D10_FILTER_TEXT_1BIT = 0x80000000 +} D3D10_FILTER; + +typedef enum D3D10_TEXTURE_ADDRESS_MODE { + D3D10_TEXTURE_ADDRESS_WRAP = 1, + D3D10_TEXTURE_ADDRESS_MIRROR, + D3D10_TEXTURE_ADDRESS_CLAMP, + D3D10_TEXTURE_ADDRESS_BORDER, + D3D10_TEXTURE_ADDRESS_MIRROR_ONCE, +} D3D10_TEXTURE_ADDRESS_MODE; + +typedef struct D3D10_SAMPLER_DESC { + D3D10_FILTER Filter; + D3D10_TEXTURE_ADDRESS_MODE AddressU; + D3D10_TEXTURE_ADDRESS_MODE AddressV; + D3D10_TEXTURE_ADDRESS_MODE AddressW; + FLOAT MipLODBias; + UINT MaxAnisotropy; + D3D10_COMPARISON_FUNC ComparisonFunc; + FLOAT BorderColor[4]; + FLOAT MinLOD; + FLOAT MaxLOD; +} D3D10_SAMPLER_DESC; + +typedef enum D3D10_COUNTER { + D3D10_COUNTER_GPU_IDLE, + D3D10_COUNTER_VERTEX_PROCESSING, + D3D10_COUNTER_GEOMETRY_PROCESSING, + D3D10_COUNTER_PIXEL_PROCESSING, + D3D10_COUNTER_OTHER_GPU_PROCESSING, + D3D10_COUNTER_HOST_ADAPTER_BANDWIDTH_UTILIZATION, + D3D10_COUNTER_LOCAL_VIDMEM_BANDWIDTH_UTILIZATION, + D3D10_COUNTER_VERTEX_THROUGHPUT_UTILIZATION, + D3D10_COUNTER_TRIANGLE_SETUP_THROUGHPUT_UTILIZATION, + D3D10_COUNTER_FILLRATE_THROUGHPUT_UTILIZATION, + D3D10_COUNTER_VS_MEMORY_LIMITED, + D3D10_COUNTER_VS_COMPUTATION_LIMITED, + D3D10_COUNTER_GS_MEMORY_LIMITED, + D3D10_COUNTER_GS_COMPUTATION_LIMITED, + D3D10_COUNTER_PS_MEMORY_LIMITED, + D3D10_COUNTER_PS_COMPUTATION_LIMITED, + D3D10_COUNTER_POST_TRANSFORM_CACHE_HIT_RATE, + D3D10_COUNTER_TEXTURE_CACHE_HIT_RATE, + D3D10_COUNTER_DEVICE_DEPENDENT_0 = 0x40000000 +} D3D10_COUNTER; + +typedef struct D3D10_COUNTER_DESC { + D3D10_COUNTER Counter; + UINT MiscFlags; +} D3D10_COUNTER_DESC; + +typedef enum D3D10_COUNTER_TYPE { + D3D10_COUNTER_TYPE_FLOAT32, + D3D10_COUNTER_TYPE_UINT16, + D3D10_COUNTER_TYPE_UINT32, + D3D10_COUNTER_TYPE_UINT64, +} D3D10_COUNTER_TYPE; + +typedef struct D3D10_COUNTER_INFO { + D3D10_COUNTER LastDeviceDependentCounter; + UINT NumSimultaneousCounters; + UINT8 NumDetectableParallelUnits; +} D3D10_COUNTER_INFO; + +typedef enum D3D10_RESOURCE_DIMENSION { + D3D10_RESOURCE_DIMENSION_UNKNOWN, + D3D10_RESOURCE_DIMENSION_BUFFER, + D3D10_RESOURCE_DIMENSION_TEXTURE1D, + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + D3D10_RESOURCE_DIMENSION_TEXTURE3D, +} D3D10_RESOURCE_DIMENSION; + +typedef enum D3D10_USAGE { + D3D10_USAGE_DEFAULT, + D3D10_USAGE_IMMUTABLE, + D3D10_USAGE_DYNAMIC, + D3D10_USAGE_STAGING, +} D3D10_USAGE; + +typedef enum D3D10_BIND_FLAG { + D3D10_BIND_VERTEX_BUFFER = 0x1, + D3D10_BIND_INDEX_BUFFER = 0x2, + D3D10_BIND_CONSTANT_BUFFER = 0x4, + D3D10_BIND_SHADER_RESOURCE = 0x8, + D3D10_BIND_STREAM_OUTPUT = 0x10, + D3D10_BIND_RENDER_TARGET = 0x20, + D3D10_BIND_DEPTH_STENCIL = 0x40 +} D3D10_BIND_FLAG; + +typedef struct D3D10_BUFFER_DESC { + UINT ByteWidth; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D10_BUFFER_DESC; + +cpp_quote("#if !defined(D3D10_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D10_BUFFER_DESC : public D3D10_BUFFER_DESC {") +cpp_quote(" CD3D10_BUFFER_DESC() {}" ) +cpp_quote(" explicit CD3D10_BUFFER_DESC(const D3D10_BUFFER_DESC &o) : D3D10_BUFFER_DESC(o) {}") +cpp_quote(" explicit CD3D10_BUFFER_DESC(UINT byteWidth, UINT bindFlags, D3D10_USAGE usage = D3D10_USAGE_DEFAULT, UINT cpuaccessFlags = 0, UINT miscFlags = 0 ) {") +cpp_quote(" ByteWidth = byteWidth;") +cpp_quote(" Usage = usage;") +cpp_quote(" BindFlags = bindFlags;") +cpp_quote(" CPUAccessFlags = cpuaccessFlags;") +cpp_quote(" MiscFlags = miscFlags;") +cpp_quote(" }") +cpp_quote(" ~CD3D10_BUFFER_DESC() {}") +cpp_quote(" operator const D3D10_BUFFER_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + +typedef enum D3D10_MAP { + D3D10_MAP_READ = 1, + D3D10_MAP_WRITE, + D3D10_MAP_READ_WRITE, + D3D10_MAP_WRITE_DISCARD, + D3D10_MAP_WRITE_NO_OVERWRITE, +} D3D10_MAP; + +typedef struct D3D10_TEXTURE1D_DESC { + UINT Width; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D10_TEXTURE1D_DESC; + +cpp_quote("#if !defined(D3D10_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D10_TEXTURE1D_DESC : public D3D10_TEXTURE1D_DESC {") +cpp_quote(" CD3D10_TEXTURE1D_DESC() {}") +cpp_quote(" explicit CD3D10_TEXTURE1D_DESC(const D3D10_TEXTURE1D_DESC &o) : D3D10_TEXTURE1D_DESC(o) {}") +cpp_quote(" explicit CD3D10_TEXTURE1D_DESC(DXGI_FORMAT format, UINT width, UINT arraySize = 1, UINT mipLevels = 0,") +cpp_quote(" UINT bindFlags = D3D10_BIND_SHADER_RESOURCE, D3D10_USAGE usage = D3D10_USAGE_DEFAULT, UINT cpuaccessFlags = 0,") +cpp_quote(" UINT miscFlags = 0) {") +cpp_quote(" Width = width;") +cpp_quote(" MipLevels = mipLevels;") +cpp_quote(" ArraySize = arraySize;") +cpp_quote(" Format = format;") +cpp_quote(" Usage = usage;") +cpp_quote(" BindFlags = bindFlags;") +cpp_quote(" CPUAccessFlags = cpuaccessFlags;") +cpp_quote(" MiscFlags = miscFlags;") +cpp_quote(" }") +cpp_quote(" ~CD3D10_TEXTURE1D_DESC() {}") +cpp_quote(" operator const D3D10_TEXTURE1D_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D10_TEXTURE2D_DESC { + UINT Width; + UINT Height; + UINT MipLevels; + UINT ArraySize; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D10_TEXTURE2D_DESC; + +cpp_quote("#if !defined(D3D10_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D10_TEXTURE2D_DESC : public D3D10_TEXTURE2D_DESC {") +cpp_quote(" CD3D10_TEXTURE2D_DESC() {}" ) +cpp_quote(" explicit CD3D10_TEXTURE2D_DESC(const D3D10_TEXTURE2D_DESC &o) : D3D10_TEXTURE2D_DESC(o) {}") +cpp_quote(" explicit CD3D10_TEXTURE2D_DESC(DXGI_FORMAT format, UINT width, UINT height,") +cpp_quote(" UINT arraySize = 1,") +cpp_quote(" UINT mipLevels = 0,") +cpp_quote(" UINT bindFlags = D3D10_BIND_SHADER_RESOURCE,") +cpp_quote(" D3D10_USAGE usage = D3D10_USAGE_DEFAULT,") +cpp_quote(" UINT cpuaccessFlags = 0,") +cpp_quote(" UINT sampleCount = 1,") +cpp_quote(" UINT sampleQuality = 0,") +cpp_quote(" UINT miscFlags = 0) {") +cpp_quote(" Width = width;" ) +cpp_quote(" Height = height;" ) +cpp_quote(" MipLevels = mipLevels;" ) +cpp_quote(" ArraySize = arraySize;" ) +cpp_quote(" Format = format;" ) +cpp_quote(" SampleDesc.Count = sampleCount;" ) +cpp_quote(" SampleDesc.Quality = sampleQuality;" ) +cpp_quote(" Usage = usage;" ) +cpp_quote(" BindFlags = bindFlags;" ) +cpp_quote(" CPUAccessFlags = cpuaccessFlags;" ) +cpp_quote(" MiscFlags = miscFlags;" ) +cpp_quote(" }") +cpp_quote(" ~CD3D10_TEXTURE2D_DESC() {}") +cpp_quote(" operator const D3D10_TEXTURE2D_DESC&() const {") +cpp_quote(" return *this;") +cpp_quote(" }") +cpp_quote("};") +cpp_quote("#endif") + +typedef struct D3D10_TEXTURE3D_DESC { + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + DXGI_FORMAT Format; + D3D10_USAGE Usage; + UINT BindFlags; + UINT CPUAccessFlags; + UINT MiscFlags; +} D3D10_TEXTURE3D_DESC; + +typedef enum D3D10_DSV_DIMENSION +{ + D3D10_DSV_DIMENSION_UNKNOWN, + D3D10_DSV_DIMENSION_TEXTURE1D, + D3D10_DSV_DIMENSION_TEXTURE1DARRAY, + D3D10_DSV_DIMENSION_TEXTURE2D, + D3D10_DSV_DIMENSION_TEXTURE2DARRAY, + D3D10_DSV_DIMENSION_TEXTURE2DMS, + D3D10_DSV_DIMENSION_TEXTURE2DMSARRAY, +} D3D10_DSV_DIMENSION; + +typedef struct D3D10_TEX1D_DSV { + UINT MipSlice; +} D3D10_TEX1D_DSV; + +typedef struct D3D10_TEX1D_ARRAY_DSV { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX1D_ARRAY_DSV; + +typedef struct D3D10_TEX2D_DSV { + UINT MipSlice; +} D3D10_TEX2D_DSV; + +typedef struct D3D10_TEX2D_ARRAY_DSV { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX2D_ARRAY_DSV; + +typedef struct D3D10_TEX2DMS_DSV { + UINT UnusedField_NothingToDefine; +} D3D10_TEX2DMS_DSV; + +typedef struct D3D10_TEX2DMS_ARRAY_DSV { + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX2DMS_ARRAY_DSV; + +typedef struct D3D10_DEPTH_STENCIL_VIEW_DESC { + DXGI_FORMAT Format; + D3D10_DSV_DIMENSION ViewDimension; + union { + D3D10_TEX1D_DSV Texture1D; + D3D10_TEX1D_ARRAY_DSV Texture1DArray; + D3D10_TEX2D_DSV Texture2D; + D3D10_TEX2D_ARRAY_DSV Texture2DArray; + D3D10_TEX2DMS_DSV Texture2DMS; + D3D10_TEX2DMS_ARRAY_DSV Texture2DMSArray; + }; +} D3D10_DEPTH_STENCIL_VIEW_DESC; + +typedef enum D3D10_RTV_DIMENSION { + D3D10_RTV_DIMENSION_UNKNOWN, + D3D10_RTV_DIMENSION_BUFFER, + D3D10_RTV_DIMENSION_TEXTURE1D, + D3D10_RTV_DIMENSION_TEXTURE1DARRAY, + D3D10_RTV_DIMENSION_TEXTURE2D, + D3D10_RTV_DIMENSION_TEXTURE2DARRAY, + D3D10_RTV_DIMENSION_TEXTURE2DMS, + D3D10_RTV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_RTV_DIMENSION_TEXTURE3D, +} D3D10_RTV_DIMENSION; + +typedef struct D3D10_BUFFER_RTV { + UINT ElementOffset; + UINT ElementWidth; +} D3D10_BUFFER_RTV; + +typedef struct D3D10_TEX1D_RTV { + UINT MipSlice; +} D3D10_TEX1D_RTV; + +typedef struct D3D10_TEX1D_ARRAY_RTV { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX1D_ARRAY_RTV; + +typedef struct D3D10_TEX2D_RTV { + UINT MipSlice; +} D3D10_TEX2D_RTV; + +typedef struct D3D10_TEX2D_ARRAY_RTV { + UINT MipSlice; + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX2D_ARRAY_RTV; + +typedef struct D3D10_TEX2DMS_RTV { + UINT UnusedField_NothingToDefine; +} D3D10_TEX2DMS_RTV; + +typedef struct D3D10_TEX2DMS_ARRAY_RTV { + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX2DMS_ARRAY_RTV; + +typedef struct D3D10_TEX3D_RTV { + UINT MipSlice; + UINT FirstWSlice; + UINT WSize; +} D3D10_TEX3D_RTV; + +typedef struct D3D10_RENDER_TARGET_VIEW_DESC { + DXGI_FORMAT Format; + D3D10_RTV_DIMENSION ViewDimension; + union { + D3D10_BUFFER_RTV Buffer; + D3D10_TEX1D_RTV Texture1D; + D3D10_TEX1D_ARRAY_RTV Texture1DArray; + D3D10_TEX2D_RTV Texture2D; + D3D10_TEX2D_ARRAY_RTV Texture2DArray; + D3D10_TEX2DMS_RTV Texture2DMS; + D3D10_TEX2DMS_ARRAY_RTV Texture2DMSArray; + D3D10_TEX3D_RTV Texture3D; + }; +} D3D10_RENDER_TARGET_VIEW_DESC; + +typedef D3D_SRV_DIMENSION D3D10_SRV_DIMENSION; + +typedef struct D3D10_BUFFER_SRV { + UINT ElementOffset; + UINT ElementWidth; +} D3D10_BUFFER_SRV; + +typedef struct D3D10_TEX1D_SRV { + UINT MostDetailedMip; + UINT MipLevels; +} D3D10_TEX1D_SRV; + +typedef struct D3D10_TEX1D_ARRAY_SRV { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX1D_ARRAY_SRV; + +typedef struct D3D10_TEX2D_SRV { + UINT MostDetailedMip; + UINT MipLevels; +} D3D10_TEX2D_SRV; + +typedef struct D3D10_TEX2D_ARRAY_SRV { + UINT MostDetailedMip; + UINT MipLevels; + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX2D_ARRAY_SRV; + +typedef struct D3D10_TEX2DMS_SRV { + UINT UnusedField_NothingToDefine; +} D3D10_TEX2DMS_SRV; + +typedef struct D3D10_TEX2DMS_ARRAY_SRV { + UINT FirstArraySlice; + UINT ArraySize; +} D3D10_TEX2DMS_ARRAY_SRV; + +typedef struct D3D10_TEX3D_SRV { + UINT MostDetailedMip; + UINT MipLevels; +} D3D10_TEX3D_SRV; + +typedef struct D3D10_TEXCUBE_SRV { + UINT MostDetailedMip; + UINT MipLevels; +} D3D10_TEXCUBE_SRV; + +typedef struct D3D10_SHADER_RESOURCE_VIEW_DESC { + DXGI_FORMAT Format; + D3D10_SRV_DIMENSION ViewDimension; + union { + D3D10_BUFFER_SRV Buffer; + D3D10_TEX1D_SRV Texture1D; + D3D10_TEX1D_ARRAY_SRV Texture1DArray; + D3D10_TEX2D_SRV Texture2D; + D3D10_TEX2D_ARRAY_SRV Texture2DArray; + D3D10_TEX2DMS_SRV Texture2DMS; + D3D10_TEX2DMS_ARRAY_SRV Texture2DMSArray; + D3D10_TEX3D_SRV Texture3D; + D3D10_TEXCUBE_SRV TextureCube; + }; +} D3D10_SHADER_RESOURCE_VIEW_DESC; + +typedef struct D3D10_BOX { + UINT left; + UINT top; + UINT front; + UINT right; + UINT bottom; + UINT back; +} D3D10_BOX; + +typedef struct D3D10_SUBRESOURCE_DATA { + const void *pSysMem; + UINT SysMemPitch; + UINT SysMemSlicePitch; +} D3D10_SUBRESOURCE_DATA; + +typedef struct D3D10_SO_DECLARATION_ENTRY { + LPCSTR SemanticName; + UINT SemanticIndex; + BYTE StartComponent; + BYTE ComponentCount; + BYTE OutputSlot; +} D3D10_SO_DECLARATION_ENTRY; + +typedef enum D3D10_INPUT_CLASSIFICATION { + D3D10_INPUT_PER_VERTEX_DATA, + D3D10_INPUT_PER_INSTANCE_DATA, +} D3D10_INPUT_CLASSIFICATION; + +typedef struct D3D10_INPUT_ELEMENT_DESC { + LPCSTR SemanticName; + UINT SemanticIndex; + DXGI_FORMAT Format; + UINT InputSlot; + UINT AlignedByteOffset; + D3D10_INPUT_CLASSIFICATION InputSlotClass; + UINT InstanceDataStepRate; +} D3D10_INPUT_ELEMENT_DESC; + +typedef enum D3D10_QUERY { + D3D10_QUERY_EVENT, + D3D10_QUERY_OCCLUSION, + D3D10_QUERY_TIMESTAMP, + D3D10_QUERY_TIMESTAMP_DISJOINT, + D3D10_QUERY_PIPELINE_STATISTICS, + D3D10_QUERY_OCCLUSION_PREDICATE, + D3D10_QUERY_SO_STATISTICS, + D3D10_QUERY_SO_OVERFLOW_PREDICATE, +} D3D10_QUERY; + +typedef struct D3D10_QUERY_DESC { + D3D10_QUERY Query; + UINT MiscFlags; +} D3D10_QUERY_DESC; + +typedef D3D_PRIMITIVE_TOPOLOGY D3D10_PRIMITIVE_TOPOLOGY; + +typedef D3D_PRIMITIVE D3D10_PRIMITIVE; + +typedef RECT D3D10_RECT; + +typedef struct D3D10_VIEWPORT { + INT TopLeftX; + INT TopLeftY; + UINT Width; + UINT Height; + FLOAT MinDepth; + FLOAT MaxDepth; +} D3D10_VIEWPORT; + +typedef struct D3D10_MAPPED_TEXTURE2D { + void *pData; + UINT RowPitch; +} D3D10_MAPPED_TEXTURE2D; + +typedef struct D3D10_MAPPED_TEXTURE3D { + void *pData; + UINT RowPitch; + UINT DepthPitch; +} D3D10_MAPPED_TEXTURE3D; + +typedef enum D3D10_CPU_ACCESS_FLAG { + D3D10_CPU_ACCESS_WRITE = 0x10000, + D3D10_CPU_ACCESS_READ = 0x20000 +} D3D10_CPU_ACCESS_FLAG; + +typedef enum D3D10_RESOURCE_MISC_FLAG { + D3D10_RESOURCE_MISC_GENERATE_MIPS = 0x0001, + D3D10_RESOURCE_MISC_SHARED = 0x0002, + D3D10_RESOURCE_MISC_TEXTURECUBE = 0x0004, + D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x0010, + D3D10_RESOURCE_MISC_GDI_COMPATIBLE = 0x0020 +} D3D10_RESOURCE_MISC_FLAG; + +typedef enum D3D10_MAP_FLAG { + D3D10_MAP_FLAG_DO_NOT_WAIT = 0x100000, +} D3D10_MAP_FLAG; + +typedef enum D3D10_CLEAR_FLAG { + D3D10_CLEAR_DEPTH = 0x1, + D3D10_CLEAR_STENCIL = 0x2 +} D3D10_CLEAR_FLAG; + +typedef enum D3D10_COLOR_WRITE_ENABLE { + D3D10_COLOR_WRITE_ENABLE_RED = 0x1, + D3D10_COLOR_WRITE_ENABLE_GREEN = 0x2, + D3D10_COLOR_WRITE_ENABLE_BLUE = 0x4, + D3D10_COLOR_WRITE_ENABLE_ALPHA = 0x8, + D3D10_COLOR_WRITE_ENABLE_ALL = (D3D10_COLOR_WRITE_ENABLE_RED | D3D10_COLOR_WRITE_ENABLE_GREEN | + D3D10_COLOR_WRITE_ENABLE_BLUE | D3D10_COLOR_WRITE_ENABLE_ALPHA) +} D3D10_COLOR_WRITE_ENABLE; + +typedef enum D3D10_TEXTURECUBE_FACE { + D3D10_TEXTURECUBE_FACE_POSITIVE_X, + D3D10_TEXTURECUBE_FACE_NEGATIVE_X, + D3D10_TEXTURECUBE_FACE_POSITIVE_Y, + D3D10_TEXTURECUBE_FACE_NEGATIVE_Y, + D3D10_TEXTURECUBE_FACE_POSITIVE_Z, + D3D10_TEXTURECUBE_FACE_NEGATIVE_Z, +} D3D10_TEXTURECUBE_FACE; + +typedef enum D3D10_ASYNC_GETDATA_FLAG { + D3D10_ASYNC_GETDATA_DONOTFLUSH = 0x1, +} D3D10_ASYNC_GETDATA_FLAG; + +typedef enum D3D10_FILTER_TYPE { + D3D10_FILTER_TYPE_POINT, + D3D10_FILTER_TYPE_LINEAR +} D3D10_FILTER_TYPE; + +typedef enum D3D10_QUERY_MISC_FLAG { + D3D10_QUERY_MISC_PREDICATEHINT = 0x1 +} D3D10_QUERY_MISC_FLAG; + +typedef struct D3D10_QUERY_DATA_TIMESTAMP_DISJOINT { + UINT64 Frequency; + BOOL Disjoint; +} D3D10_QUERY_DATA_TIMESTAMP_DISJOINT; + +typedef struct D3D10_QUERY_DATA_PIPELINE_STATISTICS { + UINT64 IAVertices; + UINT64 IAPrimitives; + UINT64 VSInvocations; + UINT64 GSInvocations; + UINT64 GSPrimitives; + UINT64 CInvocations; + UINT64 CPrimitives; + UINT64 PSInvocations; +} D3D10_QUERY_DATA_PIPELINE_STATISTICS; + +typedef struct D3D10_QUERY_DATA_SO_STATISTICS { + UINT64 NumPrimitivesWritten; + UINT64 PrimitivesStorageNeeded; +} D3D10_QUERY_DATA_SO_STATISTICS; + +typedef enum D3D10_CREATE_DEVICE_FLAG { + D3D10_CREATE_DEVICE_SINGLETHREADED = 0x1, + D3D10_CREATE_DEVICE_DEBUG = 0x2, + D3D10_CREATE_DEVICE_SWITCH_TO_REF = 0x4, + D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 0x8, + D3D10_CREATE_DEVICE_ALLOW_NULL_FROM_MAP = 0x10, + D3D10_CREATE_DEVICE_BGRA_SUPPORT = 0x20, + D3D10_CREATE_DEVICE_STRICT_VALIDATION = 0x0200 +} D3D10_CREATE_DEVICE_FLAG; + +/* Core */ + +interface ID3D10Device; + +[ + object, + local, + uuid(9b7e4c00-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10DeviceChild : IUnknown +{ + void GetDevice( + [out] ID3D10Device **ppDevice); + HRESULT GetPrivateData( + [in] REFGUID guid, + [in, out] UINT *pDataSize, + [out] void *pData); + HRESULT SetPrivateData( + [in] REFGUID guid, + [in] UINT DataSize, + [in] const void *pData); + HRESULT SetPrivateDataInterface( + [in] REFGUID guid, + [in] const IUnknown *pData); +} + +/* Resource */ + +[ + object, + local, + uuid(9b7e4c01-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Resource : ID3D10DeviceChild +{ + void GetType( + [out] D3D10_RESOURCE_DIMENSION *rType); + void SetEvictionPriority( + [in] UINT EvictionPriority); + UINT GetEvictionPriority(); +} + +[ + object, + local, + uuid(9b7e4c02-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Buffer : ID3D10Resource +{ + HRESULT Map( + [in] D3D10_MAP MapType, + [in] UINT MapFlags, + [out] void **ppData); + void Unmap(); + void GetDesc( + [out] D3D10_BUFFER_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c03-342c-4106-a19f-4f2704f689F0) +] +interface ID3D10Texture1D : ID3D10Resource +{ + HRESULT Map( + [in] UINT Subresource, + [in] D3D10_MAP MapType, + [in] UINT MapFlags, + [out] void **ppData); + void Unmap( + [in] UINT Subresource); + void GetDesc( + [out] D3D10_TEXTURE1D_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c04-342c-4106-a19f-4f2704f689F0) +] +interface ID3D10Texture2D : ID3D10Resource +{ + HRESULT Map( + [in] UINT Subresource, + [in] D3D10_MAP MapType, + [in] UINT MapFlags, + [out] D3D10_MAPPED_TEXTURE2D *pMappedTex2D); + void Unmap( + [in] UINT Subresource); + void GetDesc( + [out] D3D10_TEXTURE2D_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c05-342c-4106-a19f-4f2704f689F0) +] +interface ID3D10Texture3D : ID3D10Resource +{ + HRESULT Map( + [in] UINT Subresource, + [in] D3D10_MAP MapType, + [in] UINT MapFlags, + [out] D3D10_MAPPED_TEXTURE3D *pMappedTex3D); + void Unmap( + [in] UINT Subresource); + void GetDesc( + [out] D3D10_TEXTURE3D_DESC *pDesc); +} + +[ + object, + local, + uuid(c902b03f-60a7-49ba-9936-2a3ab37a7e33) +] +interface ID3D10View : ID3D10DeviceChild +{ + void GetResource( + [out] ID3D10Resource **ppResource); +} + +[ + object, + local, + uuid(9b7e4c09-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10DepthStencilView : ID3D10View +{ + void GetDesc( + [out] D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc); +} + + +[ + object, + local, + uuid(9b7e4c08-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10RenderTargetView : ID3D10View +{ + void GetDesc( + [out] D3D10_RENDER_TARGET_VIEW_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c07-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10ShaderResourceView : ID3D10View +{ + void GetDesc( + [out] D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc); +} + +/* Resource End */ + +[ + object, + local, + uuid(edad8d19-8a35-4d6d-8566-2ea276cde161) +] +interface ID3D10BlendState : ID3D10DeviceChild +{ + void GetDesc( + [out] D3D10_BLEND_DESC *pDesc); +} + +[ + object, + local, + uuid(2b4b1cc8-a4ad-41f8-8322-ca86fc3ec675) +] +interface ID3D10DepthStencilState : ID3D10DeviceChild +{ + void GetDesc( + [out] D3D10_DEPTH_STENCIL_DESC *pDesc); +} + +[ + object, + local, + uuid(6316be88-54cd-4040-ab44-20461bc81f68) +] +interface ID3D10GeometryShader : ID3D10DeviceChild +{ +} + +[ + object, + local, + uuid(9b7e4c0b-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10InputLayout : ID3D10DeviceChild +{ +} + +[ + object, + local, + uuid(4968b601-9d00-4cde-8346-8e7f675819b6) +] +interface ID3D10PixelShader : ID3D10DeviceChild +{ +} + +[ + object, + local, + uuid(a2a07292-89af-4345-be2e-c53d9fbb6e9f) +] +interface ID3D10RasterizerState : ID3D10DeviceChild +{ + void GetDesc( + [out] D3D10_RASTERIZER_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c0c-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10SamplerState : ID3D10DeviceChild +{ + void GetDesc( + [out] D3D10_SAMPLER_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c0a-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10VertexShader : ID3D10DeviceChild +{ +} + +[ + object, + local, + uuid(9b7e4c0d-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Asynchronous : ID3D10DeviceChild +{ + void Begin(); + void End(); + HRESULT GetData( + [out] void *pData, + [in] UINT DataSize, + [in] UINT GetDataFlags); + UINT GetDataSize(); +} + +[ + object, + local, + uuid(9b7e4c11-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Counter : ID3D10Asynchronous +{ + void GetDesc( + [out] D3D10_COUNTER_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4C0e-342C-4106-a19f-4f2704f689f0) +] +interface ID3D10Query : ID3D10Asynchronous +{ + void GetDesc( + [out] D3D10_QUERY_DESC *pDesc); +} + +[ + object, + local, + uuid(9b7e4c10-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Predicate : ID3D10Query +{ +} + +[ + object, + local, + uuid(9b7e4c0f-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Device : IUnknown +{ + void VSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D10Buffer *const *ppConstantBuffers); + void PSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D10ShaderResourceView *const *ppShaderResourceViews); + void PSSetShader( + [in] ID3D10PixelShader *pPixelShader); + void PSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in]ID3D10SamplerState *const *ppSamplers); + void VSSetShader( + [in] ID3D10VertexShader *pVertexShader); + void DrawIndexed( + [in] UINT IndexCount, + [in] UINT StartIndexLocation, + [in] INT BaseVertexLocation); + void Draw( + [in] UINT VertexCount, + [in] UINT StartVertexLocation); + void PSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D10Buffer *const *ppConstantBuffers); + void IASetInputLayout( + [in] ID3D10InputLayout *pInputLayout); + void IASetVertexBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D10Buffer *const *ppVertexBuffers, + [in] const UINT *pStrides, + [in] const UINT *pOffsets); + void IASetIndexBuffer( + [in] ID3D10Buffer *pIndexBuffer, + [in] DXGI_FORMAT Format, + [in] UINT Offset); + void DrawIndexedInstanced( + [in] UINT IndexCountPerInstance, + [in] UINT InstanceCount, + [in] UINT StartIndexLocation, + [in] INT BaseVertexLocation, + [in] UINT StartInstanceLocation); + void DrawInstanced( + [in] UINT VertexCountPerInstance, + [in] UINT InstanceCount, + [in] UINT StartVertexLocation, + [in] UINT StartInstanceLocation); + void GSSetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [in] ID3D10Buffer *const *ppConstantBuffers); + void GSSetShader( + [in] ID3D10GeometryShader *pShader); + void IASetPrimitiveTopology( + [in] D3D10_PRIMITIVE_TOPOLOGY Topology); + void VSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D10ShaderResourceView *const *ppShaderResourceViews); + void VSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D10SamplerState *const *ppSamplers); + void SetPredication( + [in] ID3D10Predicate *pPredicate, + [in] BOOL PredicateValue); + void GSSetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [in] ID3D10ShaderResourceView * const *ppShaderResourceViews); + void GSSetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [in] ID3D10SamplerState *const *ppSamplers); + void OMSetRenderTargets( + [in] UINT NumViews, + [in] ID3D10RenderTargetView *const *ppRenderTargetViews, + [in] ID3D10DepthStencilView *pDepthStencilView); + void OMSetBlendState( + [in] ID3D10BlendState *pBlendState, + [in] const FLOAT BlendFactor[4], + [in] UINT SampleMask); + void OMSetDepthStencilState( + [in] ID3D10DepthStencilState *pDepthStencilState, + [in] UINT StencilRef); + void SOSetTargets( + [in] UINT NumBuffers, + [in] ID3D10Buffer *const *ppSOTargets, + [in] const UINT *pOffsets); + void DrawAuto(); + void RSSetState( + [in] ID3D10RasterizerState *pRasterizerState); + void RSSetViewports( + [in] UINT NumViewports, + [in] const D3D10_VIEWPORT *pViewports); + void RSSetScissorRects( + [in] UINT NumRects, + [in] const D3D10_RECT *pRects); + void CopySubresourceRegion( + [in] ID3D10Resource *pDstResource, + [in] UINT DstSubresource, + [in] UINT DstX, + [in] UINT DstY, + [in] UINT DstZ, + [in] ID3D10Resource *pSrcResource, + [in] UINT SrcSubresource, + [in] const D3D10_BOX *pSrcBox); + void CopyResource( + [in] ID3D10Resource *pDstResource, + [in] ID3D10Resource *pSrcResource); + void UpdateSubresource( + [in] ID3D10Resource *pDstResource, + [in] UINT DstSubresource, + [in] const D3D10_BOX *pDstBox, + [in] const void *pSrcData, + [in] UINT SrcRowPitch, + [in] UINT SrcDepthPitch); + void ClearRenderTargetView( + [in] ID3D10RenderTargetView *pRenderTargetView, + [in] const FLOAT ColorRGBA[4]); + void ClearDepthStencilView( + [in] ID3D10DepthStencilView *pDepthStencilView, + [in] UINT ClearFlags, + [in] FLOAT Depth, + [in] UINT8 Stencil); + void GenerateMips( + [in] ID3D10ShaderResourceView *pShaderResourceView); + void ResolveSubresource( + [in] ID3D10Resource *pDstResource, + [in] UINT DstSubresource, + [in] ID3D10Resource *pSrcResource, + [in] UINT SrcSubresource, + [in] DXGI_FORMAT Format); + void VSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D10Buffer **ppConstantBuffers); + void PSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D10ShaderResourceView **ppShaderResourceViews); + void PSGetShader( + [out] ID3D10PixelShader **ppPixelShader); + void PSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D10SamplerState **ppSamplers); + void VSGetShader( + [out] ID3D10VertexShader **ppVertexShader); + void PSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D10Buffer **ppConstantBuffers); + void IAGetInputLayout( + [out] ID3D10InputLayout **ppInputLayout); + void IAGetVertexBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D10Buffer **ppVertexBuffers, + [out] UINT *pStrides, + [out] UINT *pOffsets); + void IAGetIndexBuffer( + [out] ID3D10Buffer **pIndexBuffer, + [out] DXGI_FORMAT *Format, + [out] UINT *Offset); + void GSGetConstantBuffers( + [in] UINT StartSlot, + [in] UINT NumBuffers, + [out] ID3D10Buffer **ppConstantBuffers); + void GSGetShader( + [out] ID3D10GeometryShader **ppGeometryShader); + void IAGetPrimitiveTopology( + [out] D3D10_PRIMITIVE_TOPOLOGY *pTopology); + void VSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D10ShaderResourceView **ppShaderResourceViews); + void VSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D10SamplerState **ppSamplers); + void GetPredication( + [out] ID3D10Predicate **ppPredicate, + [out] BOOL *pPredicateValue); + void GSGetShaderResources( + [in] UINT StartSlot, + [in] UINT NumViews, + [out] ID3D10ShaderResourceView **ppShaderResourceViews); + void GSGetSamplers( + [in] UINT StartSlot, + [in] UINT NumSamplers, + [out] ID3D10SamplerState **ppSamplers); + void OMGetRenderTargets( + [in] UINT NumViews, + [out] ID3D10RenderTargetView **ppRenderTargetViews, + [out] ID3D10DepthStencilView **ppDepthStencilView); + void OMGetBlendState( + [out] ID3D10BlendState **ppBlendState, + [out] FLOAT BlendFactor[4], + [out] UINT *pSampleMask); + void OMGetDepthStencilState( + [out] ID3D10DepthStencilState **ppDepthStencilState, + [out] UINT *pStencilRef); + void SOGetTargets( + [in] UINT NumBuffers, + [out] ID3D10Buffer **ppSOTargets, + [out] UINT *pOffsets); + void RSGetState( + [out] ID3D10RasterizerState **ppRasterizerState); + void RSGetViewports( + [in, out] UINT *NumViewports, + [out] D3D10_VIEWPORT *pViewports); + void RSGetScissorRects( + [in, out] UINT *NumRects, + [out] D3D10_RECT *pRects); + HRESULT GetDeviceRemovedReason(); + HRESULT SetExceptionMode( + [in] UINT RaiseFlags); + UINT GetExceptionMode(); + HRESULT GetPrivateData( + [in] REFGUID guid, + [in, out] UINT *pDataSize, + [out] void *pData); + HRESULT SetPrivateData( + [in] REFGUID guid, + [in] UINT DataSize, + [in] const void *pData); + HRESULT SetPrivateDataInterface( + [in] REFGUID guid, + [in] const IUnknown *pData); + void ClearState(); + void Flush(); + HRESULT CreateBuffer( + [in] const D3D10_BUFFER_DESC *pDesc, + [in] const D3D10_SUBRESOURCE_DATA *pInitialData, + [out] ID3D10Buffer **ppBuffer); + HRESULT CreateTexture1D( + [in] const D3D10_TEXTURE1D_DESC *pDesc, + [in] const D3D10_SUBRESOURCE_DATA *pInitialData, + [out] ID3D10Texture1D **ppTexture1D); + HRESULT CreateTexture2D( + [in] const D3D10_TEXTURE2D_DESC *pDesc, + [in] const D3D10_SUBRESOURCE_DATA *pInitialData, + [out] ID3D10Texture2D **ppTexture2D); + HRESULT CreateTexture3D( + [in] const D3D10_TEXTURE3D_DESC *pDesc, + [in] const D3D10_SUBRESOURCE_DATA *pInitialData, + [out] ID3D10Texture3D **ppTexture3D); + HRESULT CreateShaderResourceView( + [in] ID3D10Resource *pResource, + [in] const D3D10_SHADER_RESOURCE_VIEW_DESC *pDesc, + [out] ID3D10ShaderResourceView **ppSRView); + HRESULT CreateRenderTargetView( + [in] ID3D10Resource *pResource, + [in] const D3D10_RENDER_TARGET_VIEW_DESC *pDesc, + [out] ID3D10RenderTargetView **ppRTView); + HRESULT CreateDepthStencilView( + [in] ID3D10Resource *pResource, + [in] const D3D10_DEPTH_STENCIL_VIEW_DESC *pDesc, + [out] ID3D10DepthStencilView **ppDepthStencilView); + HRESULT CreateInputLayout( + [in] const D3D10_INPUT_ELEMENT_DESC *pInputElementDescs, + [in] UINT NumElements, + [in] const void *pShaderBytecodeWithInputSignature, + [in] SIZE_T BytecodeLength, + [out] ID3D10InputLayout **ppInputLayout); + HRESULT CreateVertexShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [out] ID3D10VertexShader **ppVertexShader); + HRESULT CreateGeometryShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [out] ID3D10GeometryShader **ppGeometryShader); + HRESULT CreateGeometryShaderWithStreamOutput( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [in] const D3D10_SO_DECLARATION_ENTRY *pSODeclaration, + [in] UINT NumEntries, + [in] UINT OutputStreamStride, + [out] ID3D10GeometryShader **ppGeometryShader); + HRESULT CreatePixelShader( + [in] const void *pShaderBytecode, + [in] SIZE_T BytecodeLength, + [out] ID3D10PixelShader **ppPixelShader); + HRESULT CreateBlendState( + [in] const D3D10_BLEND_DESC *pBlendStateDesc, + [out] ID3D10BlendState **ppBlendState); + HRESULT CreateDepthStencilState( + [in] const D3D10_DEPTH_STENCIL_DESC *pDepthStencilDesc, + [out] ID3D10DepthStencilState **ppDepthStencilState); + HRESULT CreateRasterizerState( + [in] const D3D10_RASTERIZER_DESC *pRasterizerDesc, + [out] ID3D10RasterizerState **ppRasterizerState); + HRESULT CreateSamplerState( + [in] const D3D10_SAMPLER_DESC *pSamplerDesc, + [out] ID3D10SamplerState **ppSamplerState); + HRESULT CreateQuery( + [in] const D3D10_QUERY_DESC *pQueryDesc, + [out] ID3D10Query **ppQuery); + HRESULT CreatePredicate( + [in] const D3D10_QUERY_DESC *pPredicateDesc, + [out] ID3D10Predicate **ppPredicate); + HRESULT CreateCounter( + [in] const D3D10_COUNTER_DESC *pCounterDesc, + [out] ID3D10Counter **ppCounter); + HRESULT CheckFormatSupport( + [in] DXGI_FORMAT Format, + [out] UINT *pFormatSupport); + HRESULT CheckMultisampleQualityLevels( + [in] DXGI_FORMAT Format, + [in] UINT SampleCount, + [out] UINT *pNumQualityLevels); + void CheckCounterInfo( + [out] D3D10_COUNTER_INFO *pCounterInfo); + HRESULT CheckCounter( + [in] const D3D10_COUNTER_DESC *pDesc, + [out] D3D10_COUNTER_TYPE *pType, + [out] UINT *pActiveCounters, + [out] LPSTR szName, + [in, out] UINT *pNameLength, + [out] LPSTR szUnits, + [in, out] UINT *pUnitsLength, + [out] LPSTR szDescription, + [in, out] UINT *pDescriptionLength); + UINT GetCreationFlags(); + HRESULT OpenSharedResource( + [in] HANDLE hResource, + [in] REFIID ReturnedInterface, + [out] void **ppResource); + void SetTextFilterSize( + [in] UINT Width, + [in] UINT Height); + void GetTextFilterSize( + [out] UINT *pWidth, + [out] UINT *pHeight); +} + +[ + object, + local, + uuid(9b7e4e00-342c-4106-a19f-4f2704f689f0) +] +interface ID3D10Multithread : IUnknown +{ + void Enter(); + void Leave(); + BOOL SetMultithreadProtected( + [in] BOOL bMTProtect); + BOOL GetMultithreadProtected(); +} + +cpp_quote("#ifndef D3D10_IGNORE_SDK_LAYERS") +cpp_quote("/* FIXME: # include */") +cpp_quote("#endif") +cpp_quote("#include \"d3d10misc.h\"") +cpp_quote("#include \"d3d10shader.h\"") +cpp_quote("#include \"d3d10effect.h\"") diff --git a/include/psdk/d3d10effect.h b/include/psdk/d3d10effect.h new file mode 100644 index 00000000000..521cd4b7fff --- /dev/null +++ b/include/psdk/d3d10effect.h @@ -0,0 +1,857 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#ifndef __WINE_D3D10EFFECT_H +#define __WINE_D3D10EFFECT_H + +#include "d3d10.h" + +#define D3D10_EFFECT_VARIABLE_POOLED 0x1 +#define D3D10_EFFECT_VARIABLE_ANNOTATION 0x2 +#define D3D10_EFFECT_VARIABLE_EXPLICIT_BIND_POINT 0x4 + +#ifndef D3D10_BYTES_FROM_BITS +#define D3D10_BYTES_FROM_BITS(x) (((x) + 7) >> 3) +#endif + +typedef enum _D3D10_DEVICE_STATE_TYPES +{ + D3D10_DST_SO_BUFFERS = 1, + D3D10_DST_OM_RENDER_TARGETS, + D3D10_DST_DEPTH_STENCIL_STATE, + D3D10_DST_BLEND_STATE, + D3D10_DST_VS, + D3D10_DST_VS_SAMPLERS, + D3D10_DST_VS_SHADER_RESOURCES, + D3D10_DST_VS_CONSTANT_BUFFERS, + D3D10_DST_GS, + D3D10_DST_GS_SAMPLERS, + D3D10_DST_GS_SHADER_RESOURCES, + D3D10_DST_GS_CONSTANT_BUFFERS, + D3D10_DST_PS, + D3D10_DST_PS_SAMPLERS, + D3D10_DST_PS_SHADER_RESOURCES, + D3D10_DST_PS_CONSTANT_BUFFERS, + D3D10_DST_IA_VERTEX_BUFFERS, + D3D10_DST_IA_INDEX_BUFFER, + D3D10_DST_IA_INPUT_LAYOUT, + D3D10_DST_IA_PRIMITIVE_TOPOLOGY, + D3D10_DST_RS_VIEWPORTS, + D3D10_DST_RS_SCISSOR_RECTS, + D3D10_DST_RS_RASTERIZER_STATE, + D3D10_DST_PREDICATION, +} D3D10_DEVICE_STATE_TYPES; + +typedef struct _D3D10_EFFECT_TYPE_DESC +{ + LPCSTR TypeName; + D3D10_SHADER_VARIABLE_CLASS Class; + D3D10_SHADER_VARIABLE_TYPE Type; + UINT Elements; + UINT Members; + UINT Rows; + UINT Columns; + UINT PackedSize; + UINT UnpackedSize; + UINT Stride; +} D3D10_EFFECT_TYPE_DESC; + +typedef struct _D3D10_EFFECT_VARIABLE_DESC +{ + LPCSTR Name; + LPCSTR Semantic; + UINT Flags; + UINT Annotations; + UINT BufferOffset; + UINT ExplicitBindPoint; +} D3D10_EFFECT_VARIABLE_DESC; + +typedef struct _D3D10_TECHNIQUE_DESC +{ + LPCSTR Name; + UINT Passes; + UINT Annotations; +} D3D10_TECHNIQUE_DESC; + +typedef struct _D3D10_STATE_BLOCK_MASK +{ + BYTE VS; + BYTE VSSamplers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT)]; + BYTE VSShaderResources[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE VSConstantBuffers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)]; + BYTE GS; + BYTE GSSamplers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT)]; + BYTE GSShaderResources[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE GSConstantBuffers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)]; + BYTE PS; + BYTE PSSamplers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT)]; + BYTE PSShaderResources[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE PSConstantBuffers[D3D10_BYTES_FROM_BITS(D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)]; + BYTE IAVertexBuffers[D3D10_BYTES_FROM_BITS(D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT)]; + BYTE IAIndexBuffer; + BYTE IAInputLayout; + BYTE IAPrimitiveTopology; + BYTE OMRenderTargets; + BYTE OMDepthStencilState; + BYTE OMBlendState; + BYTE RSViewports; + BYTE RSScissorRects; + BYTE RSRasterizerState; + BYTE SOBuffers; + BYTE Predication; +} D3D10_STATE_BLOCK_MASK; + +typedef struct _D3D10_EFFECT_DESC +{ + BOOL IsChildEffect; + UINT ConstantBuffers; + UINT SharedConstantBuffers; + UINT GlobalVariables; + UINT SharedGlobalVariables; + UINT Techniques; +} D3D10_EFFECT_DESC; + +typedef struct _D3D10_EFFECT_SHADER_DESC +{ + const BYTE *pInputSignature; + BOOL IsInline; + const BYTE *pBytecode; + UINT BytecodeLength; + LPCSTR SODecl; + UINT NumInputSignatureEntries; + UINT NumOutputSignatureEntries; +} D3D10_EFFECT_SHADER_DESC; + +typedef struct _D3D10_PASS_DESC +{ + LPCSTR Name; + UINT Annotations; + BYTE *pIAInputSignature; + SIZE_T IAInputSignatureSize; + UINT StencilRef; + UINT SampleMask; + FLOAT BlendFactor[4]; +} D3D10_PASS_DESC; + +typedef struct _D3D10_PASS_SHADER_DESC +{ + struct ID3D10EffectShaderVariable *pShaderVariable; + UINT ShaderIndex; +} D3D10_PASS_SHADER_DESC; + +#define D3D10_EFFECT_COMPILE_CHILD_EFFECT 0x0001 +#define D3D10_EFFECT_COMPILE_ALLOW_SLOW_OPS 0x0002 +#define D3D10_EFFECT_SINGLE_THREADED 0x0008 + +DEFINE_GUID(IID_ID3D10EffectType, 0x4e9e1ddc, 0xcd9d, 0x4772, 0xa8, 0x37, 0x00, 0x18, 0x0b, 0x9b, 0x88, 0xfd); + +#define INTERFACE ID3D10EffectType +DECLARE_INTERFACE(ID3D10EffectType) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_TYPE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetMemberTypeByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetMemberTypeByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetMemberTypeBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(LPCSTR, GetMemberName)(THIS_ UINT index) PURE; + STDMETHOD_(LPCSTR, GetMemberSemantic)(THIS_ UINT index) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectVariable, 0xae897105, 0x00e6, 0x45bf, 0xbb, 0x8e, 0x28, 0x1d, 0xd6, 0xdb, 0x8e, 0x1b); + +#define INTERFACE ID3D10EffectVariable +DECLARE_INTERFACE(ID3D10EffectVariable) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectConstantBuffer, 0x56648f4d, 0xcc8b, 0x4444, 0xa5, 0xad, 0xb5, 0xa3, 0xd7, 0x6e, 0x91, 0xb3); + +#define INTERFACE ID3D10EffectConstantBuffer +DECLARE_INTERFACE_(ID3D10EffectConstantBuffer, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectConstantBuffer methods */ + STDMETHOD(SetConstantBuffer)(THIS_ ID3D10Buffer *buffer) PURE; + STDMETHOD(GetConstantBuffer)(THIS_ ID3D10Buffer **buffer) PURE; + STDMETHOD(SetTextureBuffer)(THIS_ ID3D10ShaderResourceView *view) PURE; + STDMETHOD(GetTextureBuffer)(THIS_ ID3D10ShaderResourceView **view) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectScalarVariable, 0x00e48f7b, 0xd2c8, 0x49e8, 0xa8, 0x6c, 0x02, 0x2d, 0xee, 0x53, 0x43, 0x1f); + +#define INTERFACE ID3D10EffectScalarVariable +DECLARE_INTERFACE_(ID3D10EffectScalarVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectScalarVariable methods */ + STDMETHOD(SetFloat)(THIS_ float value) PURE; + STDMETHOD(GetFloat)(THIS_ float *value) PURE; + STDMETHOD(SetFloatArray)(THIS_ float *values, UINT offset, UINT count) PURE; + STDMETHOD(GetFloatArray)(THIS_ float *values, UINT offset, UINT count) PURE; + STDMETHOD(SetInt)(THIS_ int value) PURE; + STDMETHOD(GetInt)(THIS_ int *value) PURE; + STDMETHOD(SetIntArray)(THIS_ int *values, UINT offset, UINT count) PURE; + STDMETHOD(GetIntArray)(THIS_ int *values, UINT offset, UINT count) PURE; + STDMETHOD(SetBool)(THIS_ BOOL value) PURE; + STDMETHOD(GetBool)(THIS_ BOOL *value) PURE; + STDMETHOD(SetBoolArray)(THIS_ BOOL *values, UINT offset, UINT count) PURE; + STDMETHOD(GetBoolArray)(THIS_ BOOL *values, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectVectorVariable, 0x62b98c44, 0x1f82, 0x4c67, 0xbc, 0xd0, 0x72, 0xcf, 0x8f, 0x21, 0x7e, 0x81); + +#define INTERFACE ID3D10EffectVectorVariable +DECLARE_INTERFACE_(ID3D10EffectVectorVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectVectorVariable methods */ + STDMETHOD(SetBoolVector)(THIS_ BOOL *value) PURE; + STDMETHOD(SetIntVector)(THIS_ int *value) PURE; + STDMETHOD(SetFloatVector)(THIS_ float *value) PURE; + STDMETHOD(GetBoolVector)(THIS_ BOOL *value) PURE; + STDMETHOD(GetIntVector)(THIS_ int *value) PURE; + STDMETHOD(GetFloatVector)(THIS_ float *value) PURE; + STDMETHOD(SetBoolVectorArray)(THIS_ BOOL *values, UINT offset, UINT count) PURE; + STDMETHOD(SetIntVectorArray)(THIS_ int *values, UINT offset, UINT count) PURE; + STDMETHOD(SetFloatVectorArray)(THIS_ float *values, UINT offset, UINT count) PURE; + STDMETHOD(GetBoolVectorArray)(THIS_ BOOL *values, UINT offset, UINT count) PURE; + STDMETHOD(GetIntVectorArray)(THIS_ int *values, UINT offset, UINT count) PURE; + STDMETHOD(GetFloatVectorArray)(THIS_ float *values, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectMatrixVariable, 0x50666c24, 0xb82f, 0x4eed, 0xa1, 0x72, 0x5b, 0x6e, 0x7e, 0x85, 0x22, 0xe0); + +#define INTERFACE ID3D10EffectMatrixVariable +DECLARE_INTERFACE_(ID3D10EffectMatrixVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectMatrixVariable methods */ + STDMETHOD(SetMatrix)(THIS_ float *data) PURE; + STDMETHOD(GetMatrix)(THIS_ float *data) PURE; + STDMETHOD(SetMatrixArray)(THIS_ float *data, UINT offset, UINT count) PURE; + STDMETHOD(GetMatrixArray)(THIS_ float *data, UINT offset, UINT count) PURE; + STDMETHOD(SetMatrixTranspose)(THIS_ float *data) PURE; + STDMETHOD(GetMatrixTranspose)(THIS_ float *data) PURE; + STDMETHOD(SetMatrixTransposeArray)(THIS_ float *data, UINT offset, UINT count) PURE; + STDMETHOD(GetMatrixTransposeArray)(THIS_ float *data, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectStringVariable, 0x71417501, 0x8df9, 0x4e0a, 0xa7, 0x8a, 0x25, 0x5f, 0x97, 0x56, 0xba, 0xff); + +#define INTERFACE ID3D10EffectStringVariable +DECLARE_INTERFACE_(ID3D10EffectStringVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectStringVariable methods */ + STDMETHOD(GetString)(THIS_ LPCSTR *str) PURE; + STDMETHOD(GetStringArray)(THIS_ LPCSTR *strs, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectShaderResourceVariable, + 0xc0a7157b, 0xd872, 0x4b1d, 0x80, 0x73, 0xef, 0xc2, 0xac, 0xd4, 0xb1, 0xfc); + +#define INTERFACE ID3D10EffectShaderResourceVariable +DECLARE_INTERFACE_(ID3D10EffectShaderResourceVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectShaderResourceVariable methods */ + STDMETHOD(SetResource)(THIS_ ID3D10ShaderResourceView *resource) PURE; + STDMETHOD(GetResource)(THIS_ ID3D10ShaderResourceView **resource) PURE; + STDMETHOD(SetResourceArray)(THIS_ ID3D10ShaderResourceView **resources, UINT offset, UINT count) PURE; + STDMETHOD(GetResourceArray)(THIS_ ID3D10ShaderResourceView **resources, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectRenderTargetViewVariable, + 0x28ca0cc3, 0xc2c9, 0x40bb, 0xb5, 0x7f, 0x67, 0xb7, 0x37, 0x12, 0x2b, 0x17); + +#define INTERFACE ID3D10EffectRenderTargetViewVariable +DECLARE_INTERFACE_(ID3D10EffectRenderTargetViewVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectRenderTargetViewVariable methods */ + STDMETHOD(SetRenderTarget)(THIS_ ID3D10RenderTargetView *view) PURE; + STDMETHOD(GetRenderTarget)(THIS_ ID3D10RenderTargetView **view) PURE; + STDMETHOD(SetRenderTargetArray)(THIS_ ID3D10RenderTargetView **views, UINT offset, UINT count) PURE; + STDMETHOD(GetRenderTargetArray)(THIS_ ID3D10RenderTargetView **views, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectDepthStencilViewVariable, + 0x3e02c918, 0xcc79, 0x4985, 0xb6, 0x22, 0x2d, 0x92, 0xad, 0x70, 0x16, 0x23); + +#define INTERFACE ID3D10EffectDepthStencilViewVariable +DECLARE_INTERFACE_(ID3D10EffectDepthStencilViewVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectDepthStencilViewVariable methods */ + STDMETHOD(SetDepthStencil)(THIS_ ID3D10DepthStencilView *view) PURE; + STDMETHOD(GetDepthStencil)(THIS_ ID3D10DepthStencilView **view) PURE; + STDMETHOD(SetDepthStencilArray)(THIS_ ID3D10DepthStencilView **views, UINT offset, UINT count) PURE; + STDMETHOD(GetDepthStencilArray)(THIS_ ID3D10DepthStencilView **views, UINT offset, UINT count) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectShaderVariable, 0x80849279, 0xc799, 0x4797, 0x8c, 0x33, 0x04, 0x07, 0xa0, 0x7d, 0x9e, 0x06); + +#define INTERFACE ID3D10EffectShaderVariable +DECLARE_INTERFACE_(ID3D10EffectShaderVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectShaderVariable methods */ + STDMETHOD(GetShaderDesc)(THIS_ UINT index, D3D10_EFFECT_SHADER_DESC *desc) PURE; + STDMETHOD(GetVertexShader)(THIS_ UINT index, ID3D10VertexShader **shader) PURE; + STDMETHOD(GetGeometryShader)(THIS_ UINT index, ID3D10GeometryShader **shader) PURE; + STDMETHOD(GetPixelShader)(THIS_ UINT index, ID3D10PixelShader **shader) PURE; + STDMETHOD(GetInputSignatureElementDesc)(THIS_ UINT shader_index, UINT element_index, + D3D10_SIGNATURE_PARAMETER_DESC *desc) PURE; + STDMETHOD(GetOutputSignatureElementDesc)(THIS_ UINT shader_index, UINT element_index, + D3D10_SIGNATURE_PARAMETER_DESC *desc) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectBlendVariable, 0x1fcd2294, 0xdf6d, 0x4eae, 0x86, 0xb3, 0x0e, 0x91, 0x60, 0xcf, 0xb0, 0x7b); + +#define INTERFACE ID3D10EffectBlendVariable +DECLARE_INTERFACE_(ID3D10EffectBlendVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectBlendVariable methods */ + STDMETHOD(GetBlendState)(THIS_ UINT index, ID3D10BlendState **blend_state) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT index, D3D10_BLEND_DESC *desc) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectDepthStencilVariable, + 0xaf482368, 0x330a, 0x46a5, 0x9a, 0x5c, 0x01, 0xc7, 0x1a, 0xf2, 0x4c, 0x8d); + +#define INTERFACE ID3D10EffectDepthStencilVariable +DECLARE_INTERFACE_(ID3D10EffectDepthStencilVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectDepthStencilVariable methods */ + STDMETHOD(GetDepthStencilState)(THIS_ UINT index, ID3D10DepthStencilState **depth_stencil_state) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT index, D3D10_DEPTH_STENCIL_DESC *desc) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectRasterizerVariable, + 0x21af9f0e, 0x4d94, 0x4ea9, 0x97, 0x85, 0x2c, 0xb7, 0x6b, 0x8c, 0x0b, 0x34); + +#define INTERFACE ID3D10EffectRasterizerVariable +DECLARE_INTERFACE_(ID3D10EffectRasterizerVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectRasterizerVariable methods */ + STDMETHOD(GetRasterizerState)(THIS_ UINT index, ID3D10RasterizerState **rasterizer_state) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT index, D3D10_RASTERIZER_DESC *desc) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectSamplerVariable, + 0x6530d5c7, 0x07e9, 0x4271, 0xa4, 0x18, 0xe7, 0xce, 0x4b, 0xd1, 0xe4, 0x80); + +#define INTERFACE ID3D10EffectSamplerVariable +DECLARE_INTERFACE_(ID3D10EffectSamplerVariable, ID3D10EffectVariable) +{ + /* ID3D10EffectVariable methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectType *, GetType)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetMemberBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetElement)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetParentConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectScalarVariable *, AsScalar)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectVectorVariable *, AsVector)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectMatrixVariable *, AsMatrix)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectStringVariable *, AsString)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderResourceVariable *, AsShaderResource)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRenderTargetViewVariable *, AsRenderTargetView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilViewVariable *, AsDepthStencilView)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, AsConstantBuffer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectShaderVariable *, AsShader)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectBlendVariable *, AsBlend)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectDepthStencilVariable *, AsDepthStencil)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectRasterizerVariable *, AsRasterizer)(THIS) PURE; + STDMETHOD_(struct ID3D10EffectSamplerVariable *, AsSampler)(THIS) PURE; + STDMETHOD(SetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + STDMETHOD(GetRawValue)(THIS_ void *data, UINT offset, UINT count) PURE; + /* ID3D10EffectSamplerVariable methods */ + STDMETHOD(GetSampler)(THIS_ UINT index, ID3D10SamplerState **sampler) PURE; + STDMETHOD(GetBackingStore)(THIS_ UINT index, D3D10_SAMPLER_DESC *desc) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectTechnique, 0xdb122ce8, 0xd1c9, 0x4292, 0xb2, 0x37, 0x24, 0xed, 0x3d, 0xe8, 0xb1, 0x75); + +#define INTERFACE ID3D10EffectTechnique +DECLARE_INTERFACE(ID3D10EffectTechnique) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_TECHNIQUE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectPass *, GetPassByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectPass *, GetPassByName)(THIS_ LPCSTR name) PURE; + STDMETHOD(ComputeStateBlockMask)(THIS_ D3D10_STATE_BLOCK_MASK *mask) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10Effect, 0x51b0ca8b, 0xec0b, 0x4519, 0x87, 0x0d, 0x8e, 0xe1, 0xcb, 0x50, 0x17, 0xc7); + +#define INTERFACE ID3D10Effect +DECLARE_INTERFACE_(ID3D10Effect, IUnknown) +{ + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *object) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + /* ID3D10Effect methods */ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD_(BOOL, IsPool)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ ID3D10Device **device) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_EFFECT_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetConstantBufferByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectConstantBuffer *, GetConstantBufferByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetVariableByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetVariableByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetVariableBySemantic)(THIS_ LPCSTR semantic) PURE; + STDMETHOD_(struct ID3D10EffectTechnique *, GetTechniqueByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectTechnique *, GetTechniqueByName)(THIS_ LPCSTR name) PURE; + STDMETHOD(Optimize)(THIS) PURE; + STDMETHOD_(BOOL, IsOptimized)(THIS) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectPool, 0x9537ab04, 0x3250, 0x412e, 0x82, 0x13, 0xfc, 0xd2, 0xf8, 0x67, 0x79, 0x33); + +#define INTERFACE ID3D10EffectPool +DECLARE_INTERFACE_(ID3D10EffectPool, IUnknown) +{ + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *object) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + /* ID3D10EffectPool methods */ + STDMETHOD_(struct ID3D10Effect *, AsEffect)(THIS) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10EffectPass, 0x5cfbeb89, 0x1a06, 0x46e0, 0xb2, 0x82, 0xe3, 0xf9, 0xbf, 0xa3, 0x6a, 0x54); + +#define INTERFACE ID3D10EffectPass +DECLARE_INTERFACE(ID3D10EffectPass) +{ + STDMETHOD_(BOOL, IsValid)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3D10_PASS_DESC *desc) PURE; + STDMETHOD(GetVertexShaderDesc)(THIS_ D3D10_PASS_SHADER_DESC *desc) PURE; + STDMETHOD(GetGeometryShaderDesc)(THIS_ D3D10_PASS_SHADER_DESC *desc) PURE; + STDMETHOD(GetPixelShaderDesc)(THIS_ D3D10_PASS_SHADER_DESC *desc) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10EffectVariable *, GetAnnotationByName)(THIS_ LPCSTR name) PURE; + STDMETHOD(Apply)(THIS_ UINT flags) PURE; + STDMETHOD(ComputeStateBlockMask)(THIS_ D3D10_STATE_BLOCK_MASK *mask) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10StateBlock, 0x0803425a, 0x57f5, 0x4dd6, 0x94, 0x65, 0xa8, 0x75, 0x70, 0x83, 0x4a, 0x08); + +#define INTERFACE ID3D10StateBlock +DECLARE_INTERFACE_(ID3D10StateBlock, IUnknown) +{ + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, void **object) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + /* ID3D10StateBlock methods */ + STDMETHOD(Capture)(THIS) PURE; + STDMETHOD(Apply)(THIS) PURE; + STDMETHOD(ReleaseAllDeviceObjects)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ ID3D10Device **device) PURE; +}; +#undef INTERFACE + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI D3D10CompileEffectFromMemory(void *data, SIZE_T data_size, const char *filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, UINT hlsl_flags, UINT fx_flags, + ID3D10Blob **effect, ID3D10Blob **errors); +HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT flags, + ID3D10Device *device, ID3D10EffectPool *effect_pool, ID3D10Effect **effect); +HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *device, + D3D10_STATE_BLOCK_MASK *mask, ID3D10StateBlock **stateblock); + +HRESULT WINAPI D3D10StateBlockMaskDifference(D3D10_STATE_BLOCK_MASK *mask_x, + D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result); +HRESULT WINAPI D3D10StateBlockMaskDisableAll(D3D10_STATE_BLOCK_MASK *mask); +HRESULT WINAPI D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT start_idx, UINT count); +HRESULT WINAPI D3D10StateBlockMaskEnableAll(D3D10_STATE_BLOCK_MASK *mask); +HRESULT WINAPI D3D10StateBlockMaskEnableCapture(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT start_idx, UINT count); +BOOL WINAPI D3D10StateBlockMaskGetSetting(D3D10_STATE_BLOCK_MASK *mask, + D3D10_DEVICE_STATE_TYPES state_type, UINT idx); +HRESULT WINAPI D3D10StateBlockMaskIntersect(D3D10_STATE_BLOCK_MASK *mask_x, + D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result); +HRESULT WINAPI D3D10StateBlockMaskUnion(D3D10_STATE_BLOCK_MASK *mask_x, + D3D10_STATE_BLOCK_MASK *mask_y, D3D10_STATE_BLOCK_MASK *result); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_D3D10EFFECT_H */ diff --git a/include/psdk/d3d10misc.h b/include/psdk/d3d10misc.h new file mode 100644 index 00000000000..9f7f8e97c8b --- /dev/null +++ b/include/psdk/d3d10misc.h @@ -0,0 +1,48 @@ +/* + * Copyright 2008 Henri Verbeet for CodeWeavers + * + * 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 + */ + +#ifndef __D3D10MISC_H__ +#define __D3D10MISC_H__ + +#include "d3d10.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum D3D10_DRIVER_TYPE { + D3D10_DRIVER_TYPE_HARDWARE = 0, + D3D10_DRIVER_TYPE_REFERENCE = 1, + D3D10_DRIVER_TYPE_NULL = 2, + D3D10_DRIVER_TYPE_SOFTWARE = 3, +} D3D10_DRIVER_TYPE; + +HRESULT WINAPI D3D10CreateDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, UINT sdk_version, ID3D10Device **device); + +HRESULT WINAPI D3D10CreateDeviceAndSwapChain(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, + HMODULE swrast, UINT flags, UINT sdk_version, DXGI_SWAP_CHAIN_DESC *swapchain_desc, + IDXGISwapChain **swapchain, ID3D10Device **device); + +HRESULT WINAPI D3D10CreateBlob(SIZE_T data_size, ID3D10Blob **blob); + +#ifdef __cplusplus +} +#endif + +#endif /* __D3D10MISC_H__ */ diff --git a/include/psdk/d3d10shader.h b/include/psdk/d3d10shader.h new file mode 100644 index 00000000000..06b4c3ea2e8 --- /dev/null +++ b/include/psdk/d3d10shader.h @@ -0,0 +1,233 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * 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 + * + */ + +#ifndef __WINE_D3D10SHADER_H +#define __WINE_D3D10SHADER_H + +#include "d3d10.h" + +#define D3D10_SHADER_DEBUG 0x0001 +#define D3D10_SHADER_SKIP_VALIDATION 0x0002 +#define D3D10_SHADER_SKIP_OPTIMIZATION 0x0004 +#define D3D10_SHADER_PACK_MATRIX_ROW_MAJOR 0x0008 +#define D3D10_SHADER_PACK_MATRIX_COLUMN_MAJOR 0x0010 +#define D3D10_SHADER_PARTIAL_PRECISION 0x0020 +#define D3D10_SHADER_FORCE_VS_SOFTWARE_NO_OPT 0x0040 +#define D3D10_SHADER_FORCE_PS_SOFTWARE_NO_OPT 0x0080 +#define D3D10_SHADER_NO_PRESHADER 0x0100 +#define D3D10_SHADER_AVOID_FLOW_CONTROL 0x0200 +#define D3D10_SHADER_PREFER_FLOW_CONTROL 0x0400 +#define D3D10_SHADER_ENABLE_STRICTNESS 0x0800 +#define D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY 0x1000 +#define D3D10_SHADER_IEEE_STRICTNESS 0x2000 +#define D3D10_SHADER_WARNINGS_ARE_ERRORS 0x40000 + +#define D3D10_SHADER_OPTIMIZATION_LEVEL0 0x4000 +#define D3D10_SHADER_OPTIMIZATION_LEVEL1 0x0000 +#define D3D10_SHADER_OPTIMIZATION_LEVEL2 0xC000 +#define D3D10_SHADER_OPTIMIZATION_LEVEL3 0x8000 + +/* These are defined as version-neutral in d3dcommon.h */ +typedef D3D_SHADER_MACRO D3D10_SHADER_MACRO; +typedef D3D_SHADER_MACRO *LPD3D10_SHADER_MACRO; + +typedef D3D_SHADER_VARIABLE_CLASS D3D10_SHADER_VARIABLE_CLASS; +typedef D3D_SHADER_VARIABLE_CLASS *LPD3D10_SHADER_VARIABLE_CLASS; + +typedef D3D_CBUFFER_TYPE D3D10_CBUFFER_TYPE; +typedef D3D_CBUFFER_TYPE *LPD3D10_CBUFFER_TYPE; + +typedef D3D_REGISTER_COMPONENT_TYPE D3D10_REGISTER_COMPONENT_TYPE; + +typedef D3D_RESOURCE_RETURN_TYPE D3D10_RESOURCE_RETURN_TYPE; + +typedef D3D_NAME D3D10_NAME; + +typedef D3D_SHADER_INPUT_TYPE D3D10_SHADER_INPUT_TYPE; +typedef D3D_SHADER_INPUT_TYPE *LPD3D10_SHADER_INPUT_TYPE; + +typedef D3D_SHADER_VARIABLE_TYPE D3D10_SHADER_VARIABLE_TYPE; +typedef D3D_SHADER_VARIABLE_TYPE *LPD3D10_SHADER_VARIABLE_TYPE; + +typedef D3D_INCLUDE_TYPE D3D10_INCLUDE_TYPE; +typedef ID3DInclude ID3D10Include; +typedef ID3DInclude *LPD3D10INCLUDE; +#define IID_ID3D10Include IID_ID3DInclude + +typedef struct _D3D10_SHADER_INPUT_BIND_DESC +{ + LPCSTR Name; + D3D10_SHADER_INPUT_TYPE Type; + UINT BindPoint; + UINT BindCount; + UINT uFlags; + D3D10_RESOURCE_RETURN_TYPE ReturnType; + D3D10_SRV_DIMENSION Dimension; + UINT NumSamples; +} D3D10_SHADER_INPUT_BIND_DESC; + +typedef struct _D3D10_SIGNATURE_PARAMETER_DESC +{ + LPCSTR SemanticName; + UINT SemanticIndex; + UINT Register; + D3D10_NAME SystemValueType; + D3D10_REGISTER_COMPONENT_TYPE ComponentType; + BYTE Mask; + BYTE ReadWriteMask; +} D3D10_SIGNATURE_PARAMETER_DESC; + +typedef struct _D3D10_SHADER_DESC +{ + UINT Version; + LPCSTR Creator; + UINT Flags; + UINT ConstantBuffers; + UINT BoundResources; + UINT InputParameters; + UINT OutputParameters; + UINT InstructionCount; + UINT TempRegisterCount; + UINT TempArrayCount; + UINT DefCount; + UINT DclCount; + UINT TextureNormalInstructions; + UINT TextureLoadInstructions; + UINT TextureCompInstructions; + UINT TextureBiasInstructions; + UINT TextureGradientInstructions; + UINT FloatInstructionCount; + UINT IntInstructionCount; + UINT UintInstructionCount; + UINT StaticFlowControlCount; + UINT DynamicFlowControlCount; + UINT MacroInstructionCount; + UINT ArrayInstructionCount; + UINT CutInstructionCount; + UINT EmitInstructionCount; + D3D10_PRIMITIVE_TOPOLOGY GSOutputTopology; + UINT GSMaxOutputVertexCount; +} D3D10_SHADER_DESC; + +typedef struct _D3D10_SHADER_BUFFER_DESC +{ + LPCSTR Name; + D3D10_CBUFFER_TYPE Type; + UINT Variables; + UINT Size; + UINT uFlags; +} D3D10_SHADER_BUFFER_DESC; + +typedef struct _D3D10_SHADER_VARIABLE_DESC +{ + LPCSTR Name; + UINT StartOffset; + UINT Size; + UINT uFlags; + LPVOID DefaultValue; +} D3D10_SHADER_VARIABLE_DESC; + +typedef struct _D3D10_SHADER_TYPE_DESC +{ + D3D10_SHADER_VARIABLE_CLASS Class; + D3D10_SHADER_VARIABLE_TYPE Type; + UINT Rows; + UINT Columns; + UINT Elements; + UINT Members; + UINT Offset; +} D3D10_SHADER_TYPE_DESC; + +DEFINE_GUID(IID_ID3D10ShaderReflectionType, 0xc530ad7d, 0x9b16, 0x4395, 0xa9, 0x79, 0xba, 0x2e, 0xcf, 0xf8, 0x3a, 0xdd); + +#define INTERFACE ID3D10ShaderReflectionType +DECLARE_INTERFACE(ID3D10ShaderReflectionType) +{ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_TYPE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionType *, GetMemberTypeByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionType *, GetMemberTypeByName)(THIS_ LPCSTR name) PURE; + STDMETHOD_(LPCSTR, GetMemberTypeName)(THIS_ UINT index) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10ShaderReflectionVariable, 0x1bf63c95, 0x2650, 0x405d, 0x99, 0xc1, 0x36, 0x36, 0xbd, 0x1d, 0xa0, 0xa1); + +#define INTERFACE ID3D10ShaderReflectionVariable +DECLARE_INTERFACE(ID3D10ShaderReflectionVariable) +{ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_VARIABLE_DESC *desc) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionType *, GetType)(THIS) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10ShaderReflectionConstantBuffer, 0x66c66a94, 0xdddd, 0x4b62, 0xa6, 0x6a, 0xf0, 0xda, 0x33, 0xc2, 0xb4, 0xd0); + +#define INTERFACE ID3D10ShaderReflectionConstantBuffer +DECLARE_INTERFACE(ID3D10ShaderReflectionConstantBuffer) +{ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_BUFFER_DESC *desc) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionVariable *, GetVariableByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionVariable *, GetVariableByName)(THIS_ LPCSTR name) PURE; +}; +#undef INTERFACE + +DEFINE_GUID(IID_ID3D10ShaderReflection, 0xd40e20b6, 0xf8f7, 0x42ad, 0xab, 0x20, 0x4b, 0xaf, 0x8f, 0x15, 0xdf, 0xaa); + +#define INTERFACE ID3D10ShaderReflection +DECLARE_INTERFACE_(ID3D10ShaderReflection, IUnknown) +{ + /* IUnknown methods */ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *object) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + /* ID3D10ShaderReflection methods */ + STDMETHOD(GetDesc)(THIS_ D3D10_SHADER_DESC *desc) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionConstantBuffer *, GetConstantBufferByIndex)(THIS_ UINT index) PURE; + STDMETHOD_(struct ID3D10ShaderReflectionConstantBuffer *, GetConstantBufferByName)(THIS_ LPCSTR name) PURE; + STDMETHOD(GetResourceBindingDesc)(THIS_ UINT index, D3D10_SHADER_INPUT_BIND_DESC *desc) PURE; + STDMETHOD(GetInputParameterDesc)(THIS_ UINT index, D3D10_SIGNATURE_PARAMETER_DESC *desc) PURE; + STDMETHOD(GetOutputParameterDesc)(THIS_ UINT index, D3D10_SIGNATURE_PARAMETER_DESC *desc) PURE; +}; +#undef INTERFACE + + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI D3D10CompileShader(LPCSTR data, SIZE_T data_size, LPCSTR filename, + const D3D10_SHADER_MACRO *defines, ID3D10Include *include, LPCSTR entrypoint, + LPCSTR profile, UINT flags, ID3D10Blob **shader, ID3D10Blob **error_messages); +HRESULT WINAPI D3D10DisassembleShader(const void *data, SIZE_T data_size, + BOOL color_code, const char *comments, ID3D10Blob **disassembly); +LPCSTR WINAPI D3D10GetVertexShaderProfile(ID3D10Device *device); +LPCSTR WINAPI D3D10GetGeometryShaderProfile(ID3D10Device *device); +LPCSTR WINAPI D3D10GetPixelShaderProfile(ID3D10Device *device); + +HRESULT WINAPI D3D10ReflectShader(const void *data, SIZE_T data_size, ID3D10ShaderReflection **reflector); +HRESULT WINAPI D3D10GetInputSignatureBlob(const void *data, SIZE_T data_size, ID3D10Blob **blob); +HRESULT WINAPI D3D10GetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3D10Blob **blob); +HRESULT WINAPI D3D10GetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3D10Blob **blob); +HRESULT WINAPI D3D10GetShaderDebugInfo(const void *data, SIZE_T data_size, ID3D10Blob **blob); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_D3D10SHADER_H */ diff --git a/include/psdk/d3dcommon.idl b/include/psdk/d3dcommon.idl new file mode 100644 index 00000000000..76f66f582b1 --- /dev/null +++ b/include/psdk/d3dcommon.idl @@ -0,0 +1,620 @@ +/* + * Copyright 2010 Matteo Bruni for CodeWeavers + * + * 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 + */ + +import "oaidl.idl"; +import "ocidl.idl"; + +typedef struct _D3D_SHADER_MACRO +{ + LPCSTR Name; + LPCSTR Definition; +} D3D_SHADER_MACRO; + +typedef struct _D3D_SHADER_MACRO* LPD3D_SHADER_MACRO; + +[ + object, + local, + uuid(8ba5fb08-5195-40e2-ac58-0d989c3a0102) +] +interface ID3D10Blob : IUnknown +{ + void *GetBufferPointer(); + SIZE_T GetBufferSize(); +} + +typedef ID3D10Blob* LPD3D10BLOB; +typedef ID3D10Blob ID3DBlob; +typedef ID3DBlob* LPD3DBLOB; +cpp_quote("#define IID_ID3DBlob IID_ID3D10Blob") + +typedef enum _D3D_INCLUDE_TYPE +{ + D3D_INCLUDE_LOCAL = 0, + D3D_INCLUDE_SYSTEM, + D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL, + D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM, + D3D_INCLUDE_FORCE_DWORD = 0x7fffffff +} D3D_INCLUDE_TYPE; + +[ + object, + local, +] +interface ID3DInclude +{ + HRESULT Open(D3D_INCLUDE_TYPE include_type, + const char *filename, + const void *parent_data, + const void **data, + UINT *bytes); + HRESULT Close(const void *data); +} + +typedef ID3DInclude* LPD3DINCLUDE; + +typedef enum D3D_DRIVER_TYPE +{ + D3D_DRIVER_TYPE_UNKNOWN, + D3D_DRIVER_TYPE_HARDWARE, + D3D_DRIVER_TYPE_REFERENCE, + D3D_DRIVER_TYPE_NULL, + D3D_DRIVER_TYPE_SOFTWARE, + D3D_DRIVER_TYPE_WARP, +} D3D_DRIVER_TYPE; + +typedef enum D3D_FEATURE_LEVEL +{ + D3D_FEATURE_LEVEL_9_1 = 0x9100, + D3D_FEATURE_LEVEL_9_2 = 0x9200, + D3D_FEATURE_LEVEL_9_3 = 0x9300, + D3D_FEATURE_LEVEL_10_0 = 0xa000, + D3D_FEATURE_LEVEL_10_1 = 0xa100, + D3D_FEATURE_LEVEL_11_0 = 0xb000, +} D3D_FEATURE_LEVEL; + +typedef enum _D3D_SHADER_VARIABLE_CLASS +{ + D3D_SVC_SCALAR, + D3D_SVC_VECTOR, + D3D_SVC_MATRIX_ROWS, + D3D_SVC_MATRIX_COLUMNS, + D3D_SVC_OBJECT, + D3D_SVC_STRUCT, + D3D_SVC_INTERFACE_CLASS, + D3D_SVC_INTERFACE_POINTER, + D3D10_SVC_SCALAR = 0, + D3D10_SVC_VECTOR, + D3D10_SVC_MATRIX_ROWS, + D3D10_SVC_MATRIX_COLUMNS, + D3D10_SVC_OBJECT, + D3D10_SVC_STRUCT, + D3D11_SVC_INTERFACE_CLASS, + D3D11_SVC_INTERFACE_POINTER, + D3D_SVC_FORCE_DWORD = 0x7fffffff, +} D3D_SHADER_VARIABLE_CLASS; + +typedef enum _D3D_SHADER_VARIABLE_TYPE +{ + D3D_SVT_VOID, + D3D_SVT_BOOL, + D3D_SVT_INT, + D3D_SVT_FLOAT, + D3D_SVT_STRING, + D3D_SVT_TEXTURE, + D3D_SVT_TEXTURE1D, + D3D_SVT_TEXTURE2D, + D3D_SVT_TEXTURE3D, + D3D_SVT_TEXTURECUBE, + D3D_SVT_SAMPLER, + D3D_SVT_SAMPLER1D, + D3D_SVT_SAMPLER2D, + D3D_SVT_SAMPLER3D, + D3D_SVT_SAMPLERCUBE, + D3D_SVT_PIXELSHADER, + D3D_SVT_VERTEXSHADER, + D3D_SVT_PIXELFRAGMENT, + D3D_SVT_VERTEXFRAGMENT, + D3D_SVT_UINT, + D3D_SVT_UINT8, + D3D_SVT_GEOMETRYSHADER, + D3D_SVT_RASTERIZER, + D3D_SVT_DEPTHSTENCIL, + D3D_SVT_BLEND, + D3D_SVT_BUFFER, + D3D_SVT_CBUFFER, + D3D_SVT_TBUFFER, + D3D_SVT_TEXTURE1DARRAY, + D3D_SVT_TEXTURE2DARRAY, + D3D_SVT_RENDERTARGETVIEW, + D3D_SVT_DEPTHSTENCILVIEW, + D3D_SVT_TEXTURE2DMS, + D3D_SVT_TEXTURE2DMSARRAY, + D3D_SVT_TEXTURECUBEARRAY, + D3D_SVT_HULLSHADER, + D3D_SVT_DOMAINSHADER, + D3D_SVT_INTERFACE_POINTER, + D3D_SVT_COMPUTESHADER, + D3D_SVT_DOUBLE, + D3D_SVT_RWTEXTURE1D, + D3D_SVT_RWTEXTURE1DARRAY, + D3D_SVT_RWTEXTURE2D, + D3D_SVT_RWTEXTURE2DARRAY, + D3D_SVT_RWTEXTURE3D, + D3D_SVT_RWBUFFER, + D3D_SVT_BYTEADDRESS_BUFFER, + D3D_SVT_RWBYTEADDRESS_BUFFER, + D3D_SVT_STRUCTURED_BUFFER, + D3D_SVT_RWSTRUCTURED_BUFFER, + D3D_SVT_APPEND_STRUCTURED_BUFFER, + D3D_SVT_CONSUME_STRUCTURED_BUFFER, + D3D10_SVT_VOID = 0, + D3D10_SVT_BOOL, + D3D10_SVT_INT, + D3D10_SVT_FLOAT, + D3D10_SVT_STRING, + D3D10_SVT_TEXTURE, + D3D10_SVT_TEXTURE1D, + D3D10_SVT_TEXTURE2D, + D3D10_SVT_TEXTURE3D, + D3D10_SVT_TEXTURECUBE, + D3D10_SVT_SAMPLER, + D3D10_SVT_SAMPLER1D, + D3D10_SVT_SAMPLER2D, + D3D10_SVT_SAMPLER3D, + D3D10_SVT_SAMPLERCUBE, + D3D10_SVT_PIXELSHADER, + D3D10_SVT_VERTEXSHADER, + D3D10_SVT_PIXELFRAGMENT, + D3D10_SVT_VERTEXFRAGMENT, + D3D10_SVT_UINT, + D3D10_SVT_UINT8, + D3D10_SVT_GEOMETRYSHADER, + D3D10_SVT_RASTERIZER, + D3D10_SVT_DEPTHSTENCIL, + D3D10_SVT_BLEND, + D3D10_SVT_BUFFER, + D3D10_SVT_CBUFFER, + D3D10_SVT_TBUFFER, + D3D10_SVT_TEXTURE1DARRAY, + D3D10_SVT_TEXTURE2DARRAY, + D3D10_SVT_RENDERTARGETVIEW, + D3D10_SVT_DEPTHSTENCILVIEW, + D3D10_SVT_TEXTURE2DMS, + D3D10_SVT_TEXTURE2DMSARRAY, + D3D10_SVT_TEXTURECUBEARRAY, + D3D11_SVT_HULLSHADER, + D3D11_SVT_DOMAINSHADER, + D3D11_SVT_INTERFACE_POINTER, + D3D11_SVT_COMPUTESHADER, + D3D11_SVT_DOUBLE, + D3D11_SVT_RWTEXTURE1D, + D3D11_SVT_RWTEXTURE1DARRAY, + D3D11_SVT_RWTEXTURE2D, + D3D11_SVT_RWTEXTURE2DARRAY, + D3D11_SVT_RWTEXTURE3D, + D3D11_SVT_RWBUFFER, + D3D11_SVT_BYTEADDRESS_BUFFER, + D3D11_SVT_RWBYTEADDRESS_BUFFER, + D3D11_SVT_STRUCTURED_BUFFER, + D3D11_SVT_RWSTRUCTURED_BUFFER, + D3D11_SVT_APPEND_STRUCTURED_BUFFER, + D3D11_SVT_CONSUME_STRUCTURED_BUFFER, + D3D_SVT_FORCE_DWORD = 0x7fffffff, +} D3D_SHADER_VARIABLE_TYPE; + +typedef enum D3D_PRIMITIVE +{ + D3D_PRIMITIVE_UNDEFINED, + D3D_PRIMITIVE_POINT, + D3D_PRIMITIVE_LINE, + D3D_PRIMITIVE_TRIANGLE, + D3D_PRIMITIVE_LINE_ADJ = 6, + D3D_PRIMITIVE_TRIANGLE_ADJ, + D3D_PRIMITIVE_1_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_2_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_3_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_4_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_5_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_6_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_7_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_8_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_9_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_10_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_11_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_12_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_13_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_14_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_15_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_16_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_17_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_18_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_19_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 28, + D3D_PRIMITIVE_21_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_22_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_23_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_24_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_25_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_26_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_27_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_28_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_29_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_30_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_31_CONTROL_POINT_PATCH, + D3D_PRIMITIVE_32_CONTROL_POINT_PATCH, + D3D10_PRIMITIVE_UNDEFINED = 0, + D3D10_PRIMITIVE_POINT, + D3D10_PRIMITIVE_LINE, + D3D10_PRIMITIVE_TRIANGLE, + D3D10_PRIMITIVE_LINE_ADJ = 6, + D3D10_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_UNDEFINED = 0, + D3D11_PRIMITIVE_POINT, + D3D11_PRIMITIVE_LINE, + D3D11_PRIMITIVE_TRIANGLE, + D3D11_PRIMITIVE_LINE_ADJ = 6, + D3D11_PRIMITIVE_TRIANGLE_ADJ, + D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_5_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_6_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_7_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_8_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_9_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_10_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_11_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_12_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_13_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_14_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_15_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_16_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_17_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_18_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_19_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_20_CONTROL_POINT_PATCH = 28, + D3D11_PRIMITIVE_21_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_22_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_23_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_24_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_25_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_26_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_27_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_28_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_29_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_30_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH, + D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH, +} D3D_PRIMITIVE; + +typedef enum D3D_PRIMITIVE_TOPOLOGY +{ + D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, + D3D_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D_PRIMITIVE_TOPOLOGY_LINELIST, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, + D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, + D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST, + D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + D3D10_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, + D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, + D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, + D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ, + D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, + D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, + D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST, +} D3D_PRIMITIVE_TOPOLOGY; + +typedef enum D3D_TESSELLATOR_DOMAIN +{ + D3D_TESSELLATOR_DOMAIN_UNDEFINED, + D3D_TESSELLATOR_DOMAIN_ISOLINE, + D3D_TESSELLATOR_DOMAIN_TRI, + D3D_TESSELLATOR_DOMAIN_QUAD, + D3D11_TESSELLATOR_DOMAIN_UNDEFINED = 0, + D3D11_TESSELLATOR_DOMAIN_ISOLINE, + D3D11_TESSELLATOR_DOMAIN_TRI, + D3D11_TESSELLATOR_DOMAIN_QUAD, +} D3D_TESSELLATOR_DOMAIN; + +typedef enum D3D_TESSELLATOR_PARTITIONING +{ + D3D_TESSELLATOR_PARTITIONING_UNDEFINED, + D3D_TESSELLATOR_PARTITIONING_INTEGER, + D3D_TESSELLATOR_PARTITIONING_POW2, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, + D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = 0, + D3D11_TESSELLATOR_PARTITIONING_INTEGER, + D3D11_TESSELLATOR_PARTITIONING_POW2, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, + D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, +} D3D_TESSELLATOR_PARTITIONING; + +typedef enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE +{ + D3D_TESSELLATOR_OUTPUT_UNDEFINED, + D3D_TESSELLATOR_OUTPUT_POINT, + D3D_TESSELLATOR_OUTPUT_LINE, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW, + D3D11_TESSELLATOR_OUTPUT_UNDEFINED = 0, + D3D11_TESSELLATOR_OUTPUT_POINT, + D3D11_TESSELLATOR_OUTPUT_LINE, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW, + D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW, +} D3D_TESSELLATOR_OUTPUT_PRIMITIVE; + +typedef enum D3D_CBUFFER_TYPE +{ + D3D_CT_CBUFFER, + D3D_CT_TBUFFER, + D3D_CT_INTERFACE_POINTERS, + D3D_CT_RESOURCE_BIND_INFO, + D3D10_CT_CBUFFER = 0, + D3D10_CT_TBUFFER, + D3D11_CT_CBUFFER = 0, + D3D11_CT_TBUFFER, + D3D11_CT_INTERFACE_POINTERS, + D3D11_CT_RESOURCE_BIND_INFO, +} D3D_CBUFFER_TYPE; + +typedef enum D3D_SRV_DIMENSION +{ + D3D_SRV_DIMENSION_UNKNOWN, + D3D_SRV_DIMENSION_BUFFER, + D3D_SRV_DIMENSION_TEXTURE1D, + D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D_SRV_DIMENSION_TEXTURE2D, + D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D_SRV_DIMENSION_TEXTURE3D, + D3D_SRV_DIMENSION_TEXTURECUBE, + D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D_SRV_DIMENSION_BUFFEREX, + D3D10_SRV_DIMENSION_UNKNOWN = 0, + D3D10_SRV_DIMENSION_BUFFER, + D3D10_SRV_DIMENSION_TEXTURE1D, + D3D10_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2D, + D3D10_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_SRV_DIMENSION_TEXTURE2DMS, + D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_SRV_DIMENSION_TEXTURE3D, + D3D10_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_UNKNOWN = 0, + D3D10_1_SRV_DIMENSION_BUFFER, + D3D10_1_SRV_DIMENSION_TEXTURE1D, + D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2D, + D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE2DMS, + D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D10_1_SRV_DIMENSION_TEXTURE3D, + D3D10_1_SRV_DIMENSION_TEXTURECUBE, + D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_UNKNOWN = 0, + D3D11_SRV_DIMENSION_BUFFER, + D3D11_SRV_DIMENSION_TEXTURE1D, + D3D11_SRV_DIMENSION_TEXTURE1DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2D, + D3D11_SRV_DIMENSION_TEXTURE2DARRAY, + D3D11_SRV_DIMENSION_TEXTURE2DMS, + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D11_SRV_DIMENSION_TEXTURE3D, + D3D11_SRV_DIMENSION_TEXTURECUBE, + D3D11_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D11_SRV_DIMENSION_BUFFEREX, +} D3D_SRV_DIMENSION; + +typedef enum D3D_REGISTER_COMPONENT_TYPE +{ + D3D_REGISTER_COMPONENT_UNKNOWN, + D3D_REGISTER_COMPONENT_UINT32, + D3D_REGISTER_COMPONENT_SINT32, + D3D_REGISTER_COMPONENT_FLOAT32, + D3D10_REGISTER_COMPONENT_UNKNOWN = 0, + D3D10_REGISTER_COMPONENT_UINT32, + D3D10_REGISTER_COMPONENT_SINT32, + D3D10_REGISTER_COMPONENT_FLOAT32, +} D3D_REGISTER_COMPONENT_TYPE; + +typedef enum D3D_RESOURCE_RETURN_TYPE +{ + D3D_RETURN_TYPE_UNORM = 1, + D3D_RETURN_TYPE_SNORM, + D3D_RETURN_TYPE_SINT, + D3D_RETURN_TYPE_UINT, + D3D_RETURN_TYPE_FLOAT, + D3D_RETURN_TYPE_MIXED, + D3D_RETURN_TYPE_DOUBLE, + D3D_RETURN_TYPE_CONTINUED, + D3D10_RETURN_TYPE_UNORM = 1, + D3D10_RETURN_TYPE_SNORM, + D3D10_RETURN_TYPE_SINT, + D3D10_RETURN_TYPE_UINT, + D3D10_RETURN_TYPE_FLOAT, + D3D10_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_UNORM = 1, + D3D11_RETURN_TYPE_SNORM, + D3D11_RETURN_TYPE_SINT, + D3D11_RETURN_TYPE_UINT, + D3D11_RETURN_TYPE_FLOAT, + D3D11_RETURN_TYPE_MIXED, + D3D11_RETURN_TYPE_DOUBLE, + D3D11_RETURN_TYPE_CONTINUED, +} D3D_RESOURCE_RETURN_TYPE; + +typedef enum D3D_NAME +{ + D3D_NAME_UNDEFINED, + D3D_NAME_POSITION, + D3D_NAME_CLIP_DISTANCE, + D3D_NAME_CULL_DISTANCE, + D3D_NAME_RENDER_TARGET_ARRAY_INDEX, + D3D_NAME_VIEWPORT_ARRAY_INDEX, + D3D_NAME_VERTEX_ID, + D3D_NAME_PRIMITIVE_ID, + D3D_NAME_INSTANCE_ID, + D3D_NAME_IS_FRONT_FACE, + D3D_NAME_SAMPLE_INDEX, + D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR, + D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR, + D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR, + D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR, + D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR, + D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR, + D3D_NAME_TARGET = 64, + D3D_NAME_DEPTH, + D3D_NAME_COVERAGE, + D3D_NAME_DEPTH_GREATER_EQUAL, + D3D_NAME_DEPTH_LESS_EQUAL, + D3D10_NAME_UNDEFINED = 0, + D3D10_NAME_POSITION, + D3D10_NAME_CLIP_DISTANCE, + D3D10_NAME_CULL_DISTANCE, + D3D10_NAME_RENDER_TARGET_ARRAY_INDEX, + D3D10_NAME_VIEWPORT_ARRAY_INDEX, + D3D10_NAME_VERTEX_ID, + D3D10_NAME_PRIMITIVE_ID, + D3D10_NAME_INSTANCE_ID, + D3D10_NAME_IS_FRONT_FACE, + D3D10_NAME_SAMPLE_INDEX, + D3D11_NAME_FINAL_QUAD_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_QUAD_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_EDGE_TESSFACTOR, + D3D11_NAME_FINAL_TRI_INSIDE_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DETAIL_TESSFACTOR, + D3D11_NAME_FINAL_LINE_DENSITY_TESSFACTOR, + D3D10_NAME_TARGET = 64, + D3D10_NAME_DEPTH, + D3D10_NAME_COVERAGE, + D3D11_NAME_DEPTH_GREATER_EQUAL, + D3D11_NAME_DEPTH_LESS_EQUAL, +} D3D_NAME; + +typedef enum _D3D_SHADER_INPUT_TYPE +{ + D3D_SIT_CBUFFER, + D3D_SIT_TBUFFER, + D3D_SIT_TEXTURE, + D3D_SIT_SAMPLER, + D3D_SIT_UAV_RWTYPED, + D3D_SIT_STRUCTURED, + D3D_SIT_UAV_RWSTRUCTURED, + D3D_SIT_BYTEADDRESS, + D3D_SIT_UAV_RWBYTEADDRESS, + D3D_SIT_UAV_APPEND_STRUCTURED, + D3D_SIT_UAV_CONSUME_STRUCTURED, + D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER, + D3D10_SIT_CBUFFER = 0, + D3D10_SIT_TBUFFER, + D3D10_SIT_TEXTURE, + D3D10_SIT_SAMPLER, + D3D11_SIT_UAV_RWTYPED, + D3D11_SIT_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED, + D3D11_SIT_BYTEADDRESS, + D3D11_SIT_UAV_RWBYTEADDRESS, + D3D11_SIT_UAV_APPEND_STRUCTURED, + D3D11_SIT_UAV_CONSUME_STRUCTURED, + D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER, +} D3D_SHADER_INPUT_TYPE; diff --git a/include/psdk/dxgi.idl b/include/psdk/dxgi.idl new file mode 100644 index 00000000000..d87a72c97de --- /dev/null +++ b/include/psdk/dxgi.idl @@ -0,0 +1,446 @@ +/* + * Copyright 2007 Andras Kovacs + * + * 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 + */ + +import "oaidl.idl"; +import "ocidl.idl"; +import "dxgitype.h"; + +const UINT _FACDXGI = 0x87a; + +cpp_quote("#define MAKE_DXGI_STATUS(x) MAKE_HRESULT(0, _FACDXGI, x)") +cpp_quote("#define DXGI_STATUS_OCCLUDED MAKE_DXGI_STATUS(1)") +cpp_quote("#define DXGI_STATUS_CLIPPED MAKE_DXGI_STATUS(2)") +cpp_quote("#define DXGI_STATUS_NO_REDIRECTION MAKE_DXGI_STATUS(4)") +cpp_quote("#define DXGI_STATUS_NO_DESKTOP_ACCESS MAKE_DXGI_STATUS(5)") +cpp_quote("#define DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE MAKE_DXGI_STATUS(6)") +cpp_quote("#define DXGI_STATUS_MODE_CHANGED MAKE_DXGI_STATUS(7)") +cpp_quote("#define DXGI_STATUS_MODE_CHANGE_IN_PROGRESS MAKE_DXGI_STATUS(8)") + +cpp_quote("#define MAKE_DXGI_HRESULT(x) MAKE_HRESULT(1, _FACDXGI, x)") +cpp_quote("#define DXGI_ERROR_INVALID_CALL MAKE_DXGI_HRESULT(1)") +cpp_quote("#define DXGI_ERROR_NOT_FOUND MAKE_DXGI_HRESULT(2)") +cpp_quote("#define DXGI_ERROR_MORE_DATA MAKE_DXGI_HRESULT(3)") +cpp_quote("#define DXGI_ERROR_UNSUPPORTED MAKE_DXGI_HRESULT(4)") +cpp_quote("#define DXGI_ERROR_DEVICE_REMOVED MAKE_DXGI_HRESULT(5)") +cpp_quote("#define DXGI_ERROR_DEVICE_HUNG MAKE_DXGI_HRESULT(6)") +cpp_quote("#define DXGI_ERROR_DEVICE_RESET MAKE_DXGI_HRESULT(7)") +cpp_quote("#define DXGI_ERROR_WAS_STILL_DRAWING MAKE_DXGI_HRESULT(10)") +cpp_quote("#define DXGI_ERROR_FRAME_STATISTICS_DISJOINT MAKE_DXGI_HRESULT(11)") +cpp_quote("#define DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE MAKE_DXGI_HRESULT(12)") +cpp_quote("#define DXGI_ERROR_DRIVER_INTERNAL_ERROR MAKE_DXGI_HRESULT(32)") +cpp_quote("#define DXGI_ERROR_NONEXCLUSIVE MAKE_DXGI_HRESULT(33)") +cpp_quote("#define DXGI_ERROR_NOT_CURRENTLY_AVAILABLE MAKE_DXGI_HRESULT(34)") + +cpp_quote("#if 0") +typedef HANDLE HMONITOR; +typedef struct _LUID { + DWORD LowPart; + LONG HighPart; +} LUID, *PLUID; +cpp_quote("#endif") + +typedef UINT DXGI_USAGE; +const DXGI_USAGE DXGI_USAGE_SHADER_INPUT = 0x10L; +const DXGI_USAGE DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x20L; +const DXGI_USAGE DXGI_USAGE_BACK_BUFFER = 0x40L; +const DXGI_USAGE DXGI_USAGE_SHARED = 0x80L; +const DXGI_USAGE DXGI_USAGE_READ_ONLY = 0x100L; + +const UINT DXGI_ENUM_MODES_INTERLACED = 1; +const UINT DXGI_ENUM_MODES_SCALING = 2; + +typedef enum DXGI_SWAP_EFFECT { + DXGI_SWAP_EFFECT_DISCARD = 0, + DXGI_SWAP_EFFECT_SEQUENTIAL = 1, +} DXGI_SWAP_EFFECT; + +typedef enum DXGI_RESIDENCY { + DXGI_RESIDENCY_FULLY_RESIDENT = 1, + DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY = 2, + DXGI_RESIDENCY_EVICTED_TO_DISK = 3, +} DXGI_RESIDENCY; + +typedef struct DXGI_SURFACE_DESC { + UINT Width; + UINT Height; + DXGI_FORMAT Format; + DXGI_SAMPLE_DESC SampleDesc; +} DXGI_SURFACE_DESC; + +typedef struct DXGI_MAPPED_RECT { + INT Pitch; + BYTE *pBits; +} DXGI_MAPPED_RECT; + +typedef struct DXGI_OUTPUT_DESC { + WCHAR DeviceName[32]; + RECT DesktopCoordinates; + BOOL AttachedToDesktop; + DXGI_MODE_ROTATION Rotation; + HMONITOR Monitor; +} DXGI_OUTPUT_DESC; + +typedef struct DXGI_FRAME_STATISTICS { + UINT PresentCount; + UINT PresentRefreshCount; + UINT SyncRefreshCount; + LARGE_INTEGER SyncQPCTime; + LARGE_INTEGER SyncGPUTime; +} DXGI_FRAME_STATISTICS; + +typedef struct DXGI_ADAPTER_DESC { + WCHAR Description[128]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; +} DXGI_ADAPTER_DESC; + +typedef enum DXGI_SWAP_CHAIN_FLAG { + DXGI_SWAP_CHAIN_FLAG_NONPREROTATED = 1, + DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH = 2, + DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE = 4 +} DXGI_SWAP_CHAIN_FLAG; + +typedef struct DXGI_SWAP_CHAIN_DESC { + DXGI_MODE_DESC BufferDesc; + DXGI_SAMPLE_DESC SampleDesc; + DXGI_USAGE BufferUsage; + UINT BufferCount; + HWND OutputWindow; + BOOL Windowed; + DXGI_SWAP_EFFECT SwapEffect; + UINT Flags; +} DXGI_SWAP_CHAIN_DESC; + +typedef struct DXGI_SHARED_RESOURCE { + HANDLE Handle; +} DXGI_SHARED_RESOURCE; + +[ + object, + local, + uuid(aec22fb8-76f3-4639-9be0-28eb43a67a2e) +] +interface IDXGIObject : IUnknown +{ + HRESULT SetPrivateData( + [in] REFGUID guid, + [in] UINT data_size, + [in] const void *data + ); + HRESULT SetPrivateDataInterface( + [in] REFGUID guid, + [in] const IUnknown *object + ); + HRESULT GetPrivateData( + [in] REFGUID guid, + [in, out] UINT *data_size, + [out] void *data + ); + HRESULT GetParent( + [in] REFIID riid, + [out] void **parent + ); +} + +[ + object, + local, + uuid(3d3e0379-f9de-4d58-bb6c-18d62992f1a6) +] +interface IDXGIDeviceSubObject : IDXGIObject +{ + HRESULT GetDevice( + [in] REFIID riid, + [out] void **device + ); +} + +[ + object, + uuid(035f3ab4-482e-4e50-b41f-8a7f8bd8960b), + local, + pointer_default(unique) +] +interface IDXGIResource : IDXGIDeviceSubObject +{ + HRESULT GetSharedHandle([out] HANDLE *pSharedHandle); + HRESULT GetUsage([out] DXGI_USAGE *pUsage); + HRESULT SetEvictionPriority([in] UINT EvictionPriority); + HRESULT GetEvictionPriority([out, retval] UINT *pEvictionPriority); +} + +[ + object, + uuid(9d8e1289-d7b3-465f-8126-250e349af85d), + local, + pointer_default(unique) +] +interface IDXGIKeyedMutex : IDXGIDeviceSubObject +{ + HRESULT AcquireSync([in] UINT64 Key, [in] DWORD dwMilliseconds); + HRESULT ReleaseSync([in] UINT64 Key); +} + +[ + object, + local, + uuid(cafcb56c-6ac3-4889-bf47-9e23bbd260ec) +] +interface IDXGISurface : IDXGIDeviceSubObject +{ + HRESULT GetDesc( + [out] DXGI_SURFACE_DESC *desc + ); + HRESULT Map( + [out] DXGI_MAPPED_RECT *mapped_rect, + [in] UINT flags + ); + HRESULT Unmap( + ); +} + +[ + object, + local, + uuid(ae02eedb-c735-4690-8d52-5a8dc20213aa) +] +interface IDXGIOutput : IDXGIObject +{ + HRESULT GetDesc( + [out] DXGI_OUTPUT_DESC *desc + ); + HRESULT GetDisplayModeList( + [in] DXGI_FORMAT format, + [in] UINT flags, + [in, out] UINT *mode_count, + [out] DXGI_MODE_DESC *desc + ); + HRESULT FindClosestMatchingMode( + [in] const DXGI_MODE_DESC *mode, + [out] DXGI_MODE_DESC *closest_match, + [in] IUnknown *device + ); + HRESULT WaitForVBlank( + ); + HRESULT TakeOwnership( + [in] IUnknown *device, + [in] BOOL exclusive + ); + void ReleaseOwnership( + ); + HRESULT GetGammaControlCapabilities( + [out] DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps + ); + HRESULT SetGammaControl( + [in] const DXGI_GAMMA_CONTROL *gamma_control + ); + HRESULT GetGammaControl( + [out] DXGI_GAMMA_CONTROL *gamma_control + ); + HRESULT SetDisplaySurface( + [in] IDXGISurface *surface + ); + HRESULT GetDisplaySurfaceData( + [in] IDXGISurface *surface + ); + HRESULT GetFrameStatistics( + [out] DXGI_FRAME_STATISTICS *stats + ); +} + +[ + object, + local, + uuid(2411e7e1-12ac-4ccf-bd14-9798e8534dc0) +] +interface IDXGIAdapter : IDXGIObject +{ + HRESULT EnumOutputs( + [in] UINT output_idx, + [in, out] IDXGIOutput **output + ); + HRESULT GetDesc( + [out] DXGI_ADAPTER_DESC *desc + ); + HRESULT CheckInterfaceSupport( + [in] REFGUID guid, + [out] LARGE_INTEGER *umd_version + ); +} + +[ + object, + local, + uuid(310d36a0-d2e7-4c0a-aa04-6a9d23b8886a) +] +interface IDXGISwapChain : IDXGIDeviceSubObject +{ + HRESULT Present( + [in] UINT sync_interval, + [in] UINT flags + ); + HRESULT GetBuffer( + [in] UINT buffer_idx, + [in] REFIID riid, + [in, out] void **surface + ); + HRESULT SetFullscreenState( + [in] BOOL fullscreen, + [in] IDXGIOutput *target + ); + HRESULT GetFullscreenState( + [out] BOOL *fullscreen, + [out] IDXGIOutput **target + ); + HRESULT GetDesc( + [out] DXGI_SWAP_CHAIN_DESC *desc + ); + HRESULT ResizeBuffers( + [in] UINT buffer_count, + [in] UINT width, + [in] UINT height, + [in] DXGI_FORMAT format, + [in] UINT flags + ); + HRESULT ResizeTarget( + [in] const DXGI_MODE_DESC *target_mode_desc + ); + HRESULT GetContainingOutput( + [out] IDXGIOutput **output + ); + HRESULT GetFrameStatistics( + [out] DXGI_FRAME_STATISTICS *stats + ); + HRESULT GetLastPresentCount( + [out] UINT *last_present_count + ); +} + +cpp_quote("#define DXGI_MWA_NO_WINDOW_CHANGES 0x1") +cpp_quote("#define DXGI_MWA_NO_ALT_ENTER 0x2") +cpp_quote("#define DXGI_MWA_NO_PRINT_SCREEN 0x4") +cpp_quote("#define DXGI_MWA_VALID 0x7") + +[ + object, + local, + uuid(7b7166ec-21c7-44ae-b21a-c9ae321ae369) +] +interface IDXGIFactory : IDXGIObject +{ + HRESULT EnumAdapters( + [in] UINT adapter_idx, + [out] IDXGIAdapter **adapter + ); + HRESULT MakeWindowAssociation( + [in] HWND window, + [in] UINT flags + ); + HRESULT GetWindowAssociation( + [in] HWND *window + ); + HRESULT CreateSwapChain( + [in] IUnknown *device, + [in] DXGI_SWAP_CHAIN_DESC *desc, + [out] IDXGISwapChain **swapchain + ); + HRESULT CreateSoftwareAdapter( + [in] HMODULE swrast, + [out] IDXGIAdapter **adapter + ); +} + +[local] HRESULT __stdcall CreateDXGIFactory(REFIID riid, void **factory); + +[ + object, + local, + uuid(54ec77fa-1377-44e6-8c32-88fd5f44c84c) +] +interface IDXGIDevice : IDXGIObject +{ + HRESULT GetAdapter( + [out] IDXGIAdapter **adapter + ); + HRESULT CreateSurface( + [in] const DXGI_SURFACE_DESC *desc, + [in] UINT surface_count, + [in] DXGI_USAGE usage, + [in] const DXGI_SHARED_RESOURCE *shared_resource, + [out] IDXGISurface **surface + ); + HRESULT QueryResourceResidency( + [in] IUnknown *const *resources, + [out] DXGI_RESIDENCY *residency, + [in] UINT resource_count + ); + HRESULT SetGPUThreadPriority( + [in] INT priority + ); + HRESULT GetGPUThreadPriority( + [out] INT *priority + ); +} + +typedef enum DXGI_ADAPTER_FLAG { + DXGI_ADAPTER_FLAG_NONE = 0, + DXGI_ADAPTER_FLAG_REMOTE = 1, + DXGI_ADAPTER_FLAG_FORCE_DWORD = 0xFFFFFFFF +} DXGI_ADAPTER_FLAG; + +typedef struct DXGI_ADAPTER_DESC1 { + WCHAR Description[128]; + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + SIZE_T DedicatedVideoMemory; + SIZE_T DedicatedSystemMemory; + SIZE_T SharedSystemMemory; + LUID AdapterLuid; + UINT Flags; +} DXGI_ADAPTER_DESC1; + +[ + object, + uuid(29038f61-3839-4626-91fd-086879011a05), + local, + pointer_default(unique) +] +interface IDXGIAdapter1 : IDXGIAdapter +{ + HRESULT GetDesc1([out] DXGI_ADAPTER_DESC1 *pDesc); +} + +[ + object, + uuid(770aae78-f26f-4dba-a829-253c83d1b387), + local, + pointer_default(unique) + ] +interface IDXGIFactory1 : IDXGIFactory +{ + HRESULT EnumAdapters1([in] UINT Adapter, [out] IDXGIAdapter1 **ppAdapter); + BOOL IsCurrent(); +} diff --git a/include/psdk/dxgiformat.h b/include/psdk/dxgiformat.h new file mode 100644 index 00000000000..5c7ad62140c --- /dev/null +++ b/include/psdk/dxgiformat.h @@ -0,0 +1,117 @@ +/* + * Copyright 2007 Andras Kovacs + * + * 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 + */ + +#ifndef __dxgiformat_h__ +#define __dxgiformat_h__ + +#define DXGI_FORMAT_DEFINED 1 + +typedef enum DXGI_FORMAT { + DXGI_FORMAT_UNKNOWN = 0, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS= 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + DXGI_FORMAT_R11G11B10_FLOAT = 26, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + DXGI_FORMAT_R1_UNORM = 66, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + DXGI_FORMAT_FORCE_UINT = 0xffffffff +} DXGI_FORMAT; + +#endif diff --git a/include/psdk/dxgitype.h b/include/psdk/dxgitype.h new file mode 100644 index 00000000000..e89e055c153 --- /dev/null +++ b/include/psdk/dxgitype.h @@ -0,0 +1,84 @@ +/* + * Copyright 2007 Andras Kovacs + * + * 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 + */ + +#ifndef __dxgitype_h__ +#define __dxgitype_h__ + +#include "dxgiformat.h" + +typedef struct DXGI_SAMPLE_DESC { + UINT Count; + UINT Quality; +} DXGI_SAMPLE_DESC; + +typedef enum DXGI_MODE_ROTATION { + DXGI_MODE_ROTATION_UNSPECIFIED = 0, + DXGI_MODE_ROTATION_IDENTITY = 1, + DXGI_MODE_ROTATION_ROTATE90 = 2, + DXGI_MODE_ROTATION_ROTATE180 = 3, + DXGI_MODE_ROTATION_ROTATE270 = 4, +} DXGI_MODE_ROTATION; + +typedef enum DXGI_MODE_SCANLINE_ORDER { + DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED = 0, + DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE = 1, + DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST = 2, + DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST = 3, +} DXGI_MODE_SCANLINE_ORDER; + +typedef enum DXGI_MODE_SCALING { + DXGI_MODE_SCALING_UNSPECIFIED = 0, + DXGI_MODE_SCALING_CENTERED = 1, + DXGI_MODE_SCALING_STRETCHED = 2, +} DXGI_MODE_SCALING; + +typedef struct DXGI_RATIONAL { + UINT Numerator; + UINT Denominator; +} DXGI_RATIONAL; + +typedef struct DXGI_MODE_DESC { + UINT Width; + UINT Height; + DXGI_RATIONAL RefreshRate; + DXGI_FORMAT Format; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; +} DXGI_MODE_DESC; + +typedef struct DXGI_GAMMA_CONTROL_CAPABILITIES { + BOOL ScaleAndOffsetSupported; + float MaxConvertedValue; + float MinConvertedValue; + UINT NumGammaControlPoints; + float ControlPointPositions[1025]; +} DXGI_GAMMA_CONTROL_CAPABILITIES; + +typedef struct DXGI_RGB { + float Red; + float Green; + float Blue; +} DXGI_RGB; + +typedef struct DXGI_GAMMA_CONTROL { + DXGI_RGB Scale; + DXGI_RGB Offset; + DXGI_RGB GammaCurve[1025]; +} DXGI_GAMMA_CONTROL; + +#endif diff --git a/include/psdk/ipifcons.h b/include/psdk/ipifcons.h index 9b560eb8810..30a304e2b4f 100644 --- a/include/psdk/ipifcons.h +++ b/include/psdk/ipifcons.h @@ -1,35 +1,251 @@ -#ifndef _IPIFCONS_H -#define _IPIFCONS_H +/* WINE ipifcons.h + * Copyright (C) 2003 Juan Lang + * + * 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 + */ +#ifndef WINE_IPIFCONS_H__ +#define WINE_IPIFCONS_H__ -#define IF_ADMIN_STATUS_UP 1 -#define IF_ADMIN_STATUS_DOWN 2 -#define IF_ADMIN_STATUS_TESTING 3 -#define IF_OPER_STATUS_NON_OPERATIONAL 0 -#define IF_OPER_STATUS_UNREACHABLE 1 -#define IF_OPER_STATUS_DISCONNECTED 2 -#define IF_OPER_STATUS_CONNECTING 3 -#define IF_OPER_STATUS_CONNECTED 4 -#define IF_OPER_STATUS_OPERATIONAL 5 +#define IF_TYPE_OTHER 1 +#define IF_TYPE_REGULAR_1822 2 +#define IF_TYPE_HDH_1822 3 +#define IF_TYPE_DDN_X25 4 +#define IF_TYPE_RFC877_X25 5 +#define IF_TYPE_ETHERNET_CSMACD 6 +#define IF_TYPE_IS088023_CSMACD 7 +#define IF_TYPE_ISO88024_TOKENBUS 8 +#define IF_TYPE_ISO88025_TOKENRING 9 +#define IF_TYPE_ISO88026_MAN 10 +#define IF_TYPE_STARLAN 11 +#define IF_TYPE_PROTEON_10MBIT 12 +#define IF_TYPE_PROTEON_80MBIT 13 +#define IF_TYPE_HYPERCHANNEL 14 +#define IF_TYPE_FDDI 15 +#define IF_TYPE_LAP_B 16 +#define IF_TYPE_SDLC 17 +#define IF_TYPE_DS1 18 +#define IF_TYPE_E1 19 +#define IF_TYPE_BASIC_ISDN 20 +#define IF_TYPE_PRIMARY_ISDN 21 +#define IF_TYPE_PROP_POINT2POINT_SERIAL 22 +#define IF_TYPE_PPP 23 +#define IF_TYPE_SOFTWARE_LOOPBACK 24 +#define IF_TYPE_EON 25 +#define IF_TYPE_ETHERNET_3MBIT 26 +#define IF_TYPE_NSIP 27 +#define IF_TYPE_SLIP 28 +#define IF_TYPE_ULTRA 29 +#define IF_TYPE_DS3 30 +#define IF_TYPE_SIP 31 +#define IF_TYPE_FRAMERELAY 32 +#define IF_TYPE_RS232 33 +#define IF_TYPE_PARA 34 +#define IF_TYPE_ARCNET 35 +#define IF_TYPE_ARCNET_PLUS 36 +#define IF_TYPE_ATM 37 +#define IF_TYPE_MIO_X25 38 +#define IF_TYPE_SONET 39 +#define IF_TYPE_X25_PLE 40 +#define IF_TYPE_ISO88022_LLC 41 +#define IF_TYPE_LOCALTALK 42 +#define IF_TYPE_SMDS_DXI 43 +#define IF_TYPE_FRAMERELAY_SERVICE 44 +#define IF_TYPE_V35 45 +#define IF_TYPE_HSSI 46 +#define IF_TYPE_HIPPI 47 +#define IF_TYPE_MODEM 48 +#define IF_TYPE_AAL5 49 +#define IF_TYPE_SONET_PATH 50 +#define IF_TYPE_SONET_VT 51 +#define IF_TYPE_SMDS_ICIP 52 +#define IF_TYPE_PROP_VIRTUAL 53 +#define IF_TYPE_PROP_MULTIPLEXOR 54 +#define IF_TYPE_IEEE80212 55 +#define IF_TYPE_FIBRECHANNEL 56 +#define IF_TYPE_HIPPIINTERFACE 57 +#define IF_TYPE_FRAMERELAY_INTERCONNECT 58 +#define IF_TYPE_AFLANE_8023 59 +#define IF_TYPE_AFLANE_8025 60 +#define IF_TYPE_CCTEMUL 61 +#define IF_TYPE_FASTETHER 62 +#define IF_TYPE_ISDN 63 +#define IF_TYPE_V11 64 +#define IF_TYPE_V36 65 +#define IF_TYPE_G703_64K 66 +#define IF_TYPE_G703_2MB 67 +#define IF_TYPE_QLLC 68 +#define IF_TYPE_FASTETHER_FX 69 +#define IF_TYPE_CHANNEL 70 +#define IF_TYPE_IEEE80211 71 +#define IF_TYPE_IBM370PARCHAN 72 +#define IF_TYPE_ESCON 73 +#define IF_TYPE_DLSW 74 +#define IF_TYPE_ISDN_S 75 +#define IF_TYPE_ISDN_U 76 +#define IF_TYPE_LAP_D 77 +#define IF_TYPE_IPSWITCH 78 +#define IF_TYPE_RSRB 79 +#define IF_TYPE_ATM_LOGICAL 80 +#define IF_TYPE_DS0 81 +#define IF_TYPE_DS0_BUNDLE 82 +#define IF_TYPE_BSC 83 +#define IF_TYPE_ASYNC 84 +#define IF_TYPE_CNR 85 +#define IF_TYPE_ISO88025R_DTR 86 +#define IF_TYPE_EPLRS 87 +#define IF_TYPE_ARAP 88 +#define IF_TYPE_PROP_CNLS 89 +#define IF_TYPE_HOSTPAD 90 +#define IF_TYPE_TERMPAD 91 +#define IF_TYPE_FRAMERELAY_MPI 92 +#define IF_TYPE_X213 93 +#define IF_TYPE_ADSL 94 +#define IF_TYPE_RADSL 95 +#define IF_TYPE_SDSL 96 +#define IF_TYPE_VDSL 97 +#define IF_TYPE_ISO88025_CRFPRINT 98 +#define IF_TYPE_MYRINET 99 +#define IF_TYPE_VOICE_EM 100 +#define IF_TYPE_VOICE_FXO 101 +#define IF_TYPE_VOICE_FXS 102 +#define IF_TYPE_VOICE_ENCAP 103 +#define IF_TYPE_VOICE_OVERIP 104 +#define IF_TYPE_ATM_DXI 105 +#define IF_TYPE_ATM_FUNI 106 +#define IF_TYPE_ATM_IMA 107 +#define IF_TYPE_PPPMULTILINKBUNDLE 108 +#define IF_TYPE_IPOVER_CDLC 109 +#define IF_TYPE_IPOVER_CLAW 110 +#define IF_TYPE_STACKTOSTACK 111 +#define IF_TYPE_VIRTUALIPADDRESS 112 +#define IF_TYPE_MPC 113 +#define IF_TYPE_IPOVER_ATM 114 +#define IF_TYPE_ISO88025_FIBER 115 +#define IF_TYPE_TDLC 116 +#define IF_TYPE_GIGABITETHERNET 117 +#define IF_TYPE_HDLC 118 +#define IF_TYPE_LAP_F 119 +#define IF_TYPE_V37 120 +#define IF_TYPE_X25_MLP 121 +#define IF_TYPE_X25_HUNTGROUP 122 +#define IF_TYPE_TRANSPHDLC 123 +#define IF_TYPE_INTERLEAVE 124 +#define IF_TYPE_FAST 125 +#define IF_TYPE_IP 126 +#define IF_TYPE_DOCSCABLE_MACLAYER 127 +#define IF_TYPE_DOCSCABLE_DOWNSTREAM 128 +#define IF_TYPE_DOCSCABLE_UPSTREAM 129 +#define IF_TYPE_A12MPPSWITCH 130 +#define IF_TYPE_TUNNEL 131 +#define IF_TYPE_COFFEE 132 +#define IF_TYPE_CES 133 +#define IF_TYPE_ATM_SUBINTERFACE 134 +#define IF_TYPE_L2_VLAN 135 +#define IF_TYPE_L3_IPVLAN 136 +#define IF_TYPE_L3_IPXVLAN 137 +#define IF_TYPE_DIGITALPOWERLINE 138 +#define IF_TYPE_MEDIAMAILOVERIP 139 +#define IF_TYPE_DTM 140 +#define IF_TYPE_DCN 141 +#define IF_TYPE_IPFORWARD 142 +#define IF_TYPE_MSDSL 143 +#define IF_TYPE_IEEE1394 144 +#define IF_TYPE_IF_GSN 145 +#define IF_TYPE_DVBRCC_MACLAYER 146 +#define IF_TYPE_DVBRCC_DOWNSTREAM 147 +#define IF_TYPE_DVBRCC_UPSTREAM 148 +#define IF_TYPE_ATM_VIRTUAL 149 +#define IF_TYPE_MPLS_TUNNEL 150 +#define IF_TYPE_SRP 151 +#define IF_TYPE_VOICEOVERATM 152 +#define IF_TYPE_VOICEOVERFRAMERELAY 153 +#define IF_TYPE_IDSL 154 +#define IF_TYPE_COMPOSITELINK 155 +#define IF_TYPE_SS7_SIGLINK 156 +#define IF_TYPE_PROP_WIRELESS_P2P 157 +#define IF_TYPE_FR_FORWARD 158 +#define IF_TYPE_RFC1483 159 +#define IF_TYPE_USB 160 +#define IF_TYPE_IEEE8023AD_LAG 161 +#define IF_TYPE_BGP_POLICY_ACCOUNTING 162 +#define IF_TYPE_FRF16_MFR_BUNDLE 163 +#define IF_TYPE_H323_GATEKEEPER 164 +#define IF_TYPE_H323_PROXY 165 +#define IF_TYPE_MPLS 166 +#define IF_TYPE_MF_SIGLINK 167 +#define IF_TYPE_HDSL2 168 +#define IF_TYPE_SHDSL 169 +#define IF_TYPE_DS1_FDL 170 +#define IF_TYPE_POS 171 +#define IF_TYPE_DVB_ASI_IN 172 +#define IF_TYPE_DVB_ASI_OUT 173 +#define IF_TYPE_PLC 175 +#define IF_TYPE_NFAS 175 +#define IF_TYPE_TR008 176 +#define IF_TYPE_GR303_RDT 177 +#define IF_TYPE_GR303_IDT 178 +#define IF_TYPE_ISUP 179 +#define IF_TYPE_PROP_DOCS_WIRELESS_MACLAYER 180 +#define IF_TYPE_PROP_DOCS_WIRELESS_DOWNSTREAM 181 +#define IF_TYPE_PROP_DOCS_WIRELESS_UPSTREAM 182 +#define IF_TYPE_HIPERLAN2 183 +#define IF_TYPE_PROP_BWA_P2MP 184 +#define IF_TYPE_SONET_OVERHEAD_CHANNEL 185 +#define IF_TYPE_DIGITAL_WRAPPER_OVERHEAD_CHANNEL 186 +#define IF_TYPE_AAL2 187 +#define IF_TYPE_RADIO_MAC 188 +#define IF_TYPE_ATM_RADIO 189 +#define IF_TYPE_IMT 190 +#define IF_TYPE_MVL 191 +#define IF_TYPE_REACH_DSL 192 +#define IF_TYPE_FR_DLCI_ENDPT 193 +#define IF_TYPE_ATM_VCI_ENDPT 194 +#define IF_TYPE_OPTICAL_CHANNEL 195 +#define IF_TYPE_OPTICAL_TRANSPORT 196 +#define IF_TYPE_IEEE80216_WANN 237 +#define IF_TYPE_WWANPP 243 +#define IF_TYPE_WWANPP2 244 +#define MAX_IF_TYPE 244 -#define MIB_IF_ADMIN_STATUS_UP 1 -#define MIB_IF_ADMIN_STATUS_DOWN 2 -#define MIB_IF_ADMIN_STATUS_TESTING 3 -#define MIB_IF_OPER_STATUS_NON_OPERATIONAL 0 -#define MIB_IF_OPER_STATUS_UNREACHABLE 1 -#define MIB_IF_OPER_STATUS_DISCONNECTED 2 -#define MIB_IF_OPER_STATUS_CONNECTING 3 -#define MIB_IF_OPER_STATUS_CONNECTED 4 -#define MIB_IF_OPER_STATUS_OPERATIONAL 5 -#define MIB_IF_TYPE_OTHER 1 -#define MIB_IF_TYPE_ETHERNET 6 -#define MIB_IF_TYPE_TOKENRING 9 -#define MIB_IF_TYPE_FDDI 15 -#define MIB_IF_TYPE_PPP 23 -#define MIB_IF_TYPE_LOOPBACK 24 -#define MIB_IF_TYPE_SLIP 28 +#define MIB_IF_TYPE_OTHER 1 +#define MIB_IF_TYPE_ETHERNET 6 +#define MIB_IF_TYPE_TOKENRING 9 +#define MIB_IF_TYPE_FDDI 15 +#define MIB_IF_TYPE_PPP 23 +#define MIB_IF_TYPE_LOOPBACK 24 +#define MIB_IF_TYPE_SLIP 28 -#define IF_TYPE_OTHER 1 -#define IF_TYPE_ETHERNET_CSMACD 6 -#define IF_TYPE_IEEE80211 71 +#define MIB_IF_ADMIN_STATUS_UP 1 +#define MIB_IF_ADMIN_STATUS_DOWN 2 +#define MIB_IF_ADMIN_STATUS_TESTING 3 -#endif /* _IPIFCONS_H */ +typedef enum _INTERNAL_IF_OPER_STATUS +{ + IF_OPER_STATUS_NON_OPERATIONAL = 0, + IF_OPER_STATUS_UNREACHABLE = 1, + IF_OPER_STATUS_DISCONNECTED = 2, + IF_OPER_STATUS_CONNECTING = 3, + IF_OPER_STATUS_CONNECTED = 4, + IF_OPER_STATUS_OPERATIONAL = 5, +} INTERNAL_IF_OPER_STATUS; + +#define MIB_IF_OPER_STATUS_NON_OPERATIONAL IF_OPER_STATUS_NON_OPERATIONAL +#define MIB_IF_OPER_STATUS_UNREACHABLE IF_OPER_STATUS_UNREACHABLE +#define MIB_IF_OPER_STATUS_DISCONNECTED IF_OPER_STATUS_DISCONNECTED +#define MIB_IF_OPER_STATUS_CONNECTING IF_OPER_STATUS_CONNECTING +#define MIB_IF_OPER_STATUS_CONNECTED IF_OPER_STATUS_CONNECTED +#define MIB_IF_OPER_STATUS_OPERATIONAL IF_OPER_STATUS_OPERATIONAL + +#endif /* WINE_IPIFCONS_H__ */ diff --git a/include/psdk/iptypes.h b/include/psdk/iptypes.h index 94d81263ad7..987e1c1a9dd 100644 --- a/include/psdk/iptypes.h +++ b/include/psdk/iptypes.h @@ -169,8 +169,8 @@ typedef struct _IP_ADAPTER_ADDRESSES { struct { ULONG Length; DWORD IfIndex; - }; - }; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; struct _IP_ADAPTER_ADDRESSES *Next; PCHAR AdapterName; PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; diff --git a/include/psdk/ntdef.h b/include/psdk/ntdef.h index 5f6a2583a32..d88b02b3dde 100644 --- a/include/psdk/ntdef.h +++ b/include/psdk/ntdef.h @@ -299,6 +299,18 @@ #endif #endif /* DECLSPEC_ALIGN */ +#ifndef SYSTEM_CACHE_ALIGNMENT_SIZE +#if defined(_AMD64_) || defined(_X86_) +#define SYSTEM_CACHE_ALIGNMENT_SIZE 64 +#else +#define SYSTEM_CACHE_ALIGNMENT_SIZE 128 +#endif +#endif + +#ifndef DECLSPEC_CACHEALIGN +#define DECLSPEC_CACHEALIGN DECLSPEC_ALIGN(SYSTEM_CACHE_ALIGNMENT_SIZE) +#endif + #ifndef DECLSPEC_SELECTANY #if (_MSC_VER >= 1100) || defined(__GNUC__) #define DECLSPEC_SELECTANY __declspec(selectany) diff --git a/include/psdk/shldisp.idl b/include/psdk/shldisp.idl index 3c300dbbdeb..519fa03befd 100644 --- a/include/psdk/shldisp.idl +++ b/include/psdk/shldisp.idl @@ -72,7 +72,7 @@ interface IAutoComplete : IUnknown [in] IUnknown *punkACL, [in] LPCOLESTR pwszRegKeyPath, [in] LPCOLESTR pwszQuickComplete); - + HRESULT Enable( [in] BOOL fEnable ); } @@ -310,6 +310,27 @@ interface FolderItem : IDispatch HRESULT InvokeVerb( [in, optional] VARIANT vVerb ); } +[ + object, + uuid(edc817aa-92b8-11d1-b075-00c04fc33aa5), + oleautomation, + dual +] +interface FolderItem2 : FolderItem +{ + HRESULT InvokeVerbEx( [in, optional] VARIANT vVerb, [in, optional] VARIANT vArgs ); + + HRESULT ExtendedProperty( [in] BSTR sPropName, [out, retval] VARIANT *pvRet ); +} + +[ + uuid(2fe352ea-fd1f-11d2-b1f4-00c04f8eeb3e) +] +coclass ShellFolderItem +{ + interface FolderItem2; +} + /***************************************************************************** * FolderItems interface */ diff --git a/include/psdk/shlguid.h b/include/psdk/shlguid.h index ccc6a532e93..849b886e29b 100644 --- a/include/psdk/shlguid.h +++ b/include/psdk/shlguid.h @@ -121,6 +121,7 @@ DEFINE_GUID(SID_SCommDlgBrowser, 0x80f30233, 0xb7df, 0x11d2, 0xa3, 0x3b, 0x00, DEFINE_GUID(IID_IDockingWindowSite, 0x2A342FC2, 0x7B26, 0x11D0, 0x8C, 0xA9, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); DEFINE_GUID(IID_IInputObject, 0x68284FAA, 0x6A48, 0x11D0, 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4); DEFINE_GUID(IID_IInputObjectSite, 0xF1DB8392, 0x7331, 0x11D0, 0x8C, 0x99, 0x00, 0xA0, 0xC9, 0x2D, 0xBF, 0xE8); +DEFINE_GUID(IID_IShellIconOverlayIdentifier, 0x0c6c4200L, 0xc589, 0x11d0, 0x99, 0x9a, 0x00, 0xc0, 0x4f, 0xd6, 0x55, 0xe1); /**************************************************************************** * the next IID's are the namespace elements of the pidls @@ -146,8 +147,6 @@ DEFINE_GUID(CLSID_DragDropHelper, 0x4657278a, 0x411b, 0x11d2, 0x83, 0x9a, 0x00, DEFINE_GUID(CLSID_ProgressDialog, 0xf8383852, 0xfcd3, 0x11d1, 0xa6, 0xb9, 0x0, 0x60, 0x97, 0xdf, 0x5b, 0xd4); -DEFINE_GUID(CLSID_ShellItem, 0x2fe352ea, 0xfd1f, 0x11d2, 0xb1, 0xf4, 0x00, 0xc0, 0x4f, 0x8e, 0xeb, 0x3e); - #define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0} DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0); #define PID_FINDDATA 0 diff --git a/include/psdk/shlguid_undoc.h b/include/psdk/shlguid_undoc.h index 63edd52ef18..24880ed8fdb 100644 --- a/include/psdk/shlguid_undoc.h +++ b/include/psdk/shlguid_undoc.h @@ -30,7 +30,7 @@ DEFINE_GUID(IID_IShellMenu2, 0x6F51C646, 0x0EFE, 0x4370, 0x88, 0x2A, DEFINE_GUID(IID_IWinEventHandler, 0xEA5F2D61, 0xE008, 0x11CF, 0x99, 0xCB, 0x00, 0xC0, 0x4F, 0xD6, 0x44, 0x97); DEFINE_GUID(IID_IShellMenuAcc, 0xFAF6FE96, 0xCE5E, 0x11D1, 0x83, 0x71, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0); DEFINE_GUID(IID_IShellBrowserService, 0x1307EE17, 0xEA83, 0x49EB, 0x96, 0xB2, 0x3A, 0x28, 0xE2, 0xD7, 0x04, 0x8A); -//DEFINE_GUID(IID_IFolderView, 0xCDE725B0, 0xCCC9, 0x4519, 0x91, 0x7E, 0x32, 0x5D, 0x72, 0xFA, 0xB4, 0xCE); +DEFINE_GUID(IID_IShellFolderView, 0x37A378C0, 0xF82D, 0x11CE, 0xAE, 0x65, 0x08, 0x00, 0x2B, 0x2E, 0x12, 0x62); DEFINE_GUID(SID_SProxyBrowser, 0x20C46561, 0x8491, 0x11CF, 0x96, 0x0C, 0x00, 0x80, 0xC7, 0xF4, 0xEE, 0x85); @@ -78,6 +78,9 @@ DEFINE_GUID(SID_IBandProxy, 0x80243AC1, 0x0569, 0x11D1, 0xA7, 0xA DEFINE_GUID(CLSID_ShellSearchExt, 0x169A0691, 0x8DF9, 0x11D1, 0xA1, 0xC4, 0x00, 0xC0, 0x4F, 0xD7, 0x5D, 0x13); DEFINE_GUID(CLSID_CommonButtons, 0x1E79697E, 0x9CC5, 0x11D1, 0xA8, 0x3F, 0x00, 0xC0, 0x4F, 0xC9, 0x9D, 0x61); +DEFINE_GUID(CLSID_CCommonBrowser, 0xAF604EFE, 0x8897, 0x11D1, 0xB9, 0x44, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1); +DEFINE_GUID(CLSID_DeskBar, 0xecd4fc4c, 0x521c, 0x11d0, 0xb7, 0x92, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1); +DEFINE_GUID(CLSID_DeskBarApp, 0x3ccf8a41, 0x5c85, 0x11d0, 0x97, 0x96, 0x00, 0xaa, 0x00, 0xb9, 0x0a, 0xdf); DEFINE_GUID(CGID_BrandCmdGroup, 0x25019D8C, 0x9EE0, 0x45C0, 0x88, 0x3B, 0x97, 0x2D, 0x48, 0x32, 0x5E, 0x18); @@ -102,17 +105,14 @@ DEFINE_GUID(CLSID_ShellFileDefExt, 0x21B22460, 0x3AEA, 0x1069, 0xA2, 0xD DEFINE_GUID(CLSID_ShellDrvDefExt, 0x5F5295E0, 0x429F, 0x1069, 0xA2, 0xE2, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); DEFINE_GUID(CLSID_ShellNetDefExt, 0x86422020, 0x42A0, 0x1069, 0xA2, 0xE5, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D); -// In theory, this is documented. But until I see an SDK header that defines it, it will be treated as undocumented... -DEFINE_GUID(CLSID_ShellItem, 0x2FE352EA, 0xFD1F, 0x11D2, 0xB1, 0xF4, 0x00, 0xC0, 0x4F, 0x8E, 0xEB, 0x3E); - #define CGID_IExplorerToolbar IID_IExplorerToolbar #define SID_IExplorerToolbar IID_IExplorerToolbar #define SID_ITargetFrame2 IID_ITargetFrame2 #define SID_IWebBrowserApp IID_IWebBrowserApp #define CGID_IDeskBand IID_IDeskBand #define CGID_MenuBand CLSID_MenuBand -#define SID_STravelLogCursor IID_ITravelLogStg -#define SID_IBandSite IID_IBandSite +#define SID_STravelLogCursor IID_ITravelLogStg +#define SID_IBandSite IID_IBandSite #define SID_IFolderView IID_IFolderView #define SID_IShellBrowser IID_IShellBrowser diff --git a/include/psdk/shlobj.h b/include/psdk/shlobj.h index dc56d23f0de..59824947499 100644 --- a/include/psdk/shlobj.h +++ b/include/psdk/shlobj.h @@ -1903,7 +1903,6 @@ HRESULT WINAPI SHOpenWithDialog( #define INTERFACE IShellIconOverlayIdentifier -DEFINE_GUID(IID_IShellIconOverlayIdentifier, 0x0c6c4200L, 0xc589, 0x11d0, 0x99, 0x9a, 0x00, 0xc0, 0x4f, 0xd6, 0x55, 0xe1); DECLARE_INTERFACE_(IShellIconOverlayIdentifier, IUnknown) { STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE; diff --git a/include/psdk/shobjidl.idl b/include/psdk/shobjidl.idl index f6fc83af9ea..c1dc2a30b64 100644 --- a/include/psdk/shobjidl.idl +++ b/include/psdk/shobjidl.idl @@ -1765,7 +1765,7 @@ interface INewShortcutHookA : IUnknown HRESULT GetExtension( [out] LPSTR pszExtension, [in] int cchExtension); -} +} /***************************************************************************** @@ -1796,7 +1796,7 @@ interface INewShortcutHookW : IUnknown HRESULT GetExtension( [out] LPWSTR pszExtension, [in] int cchExtension); -} +} /***************************************************************************** * IRunnableTask interface @@ -2281,7 +2281,7 @@ cpp_quote("#define SMC_SFDDRESTRICTED 0x00000030") ] interface IShellMenuCallback : IUnknown { - HRESULT CallbackSM( + HRESULT CallbackSM( [in, out] LPSMDATA psmd, [in] UINT uMsg, [in] WPARAM wParam, @@ -2317,48 +2317,48 @@ cpp_quote("#define SMINV_ID 0x00000008") ] interface IShellMenu : IUnknown { - HRESULT Initialize( + HRESULT Initialize( [in] IShellMenuCallback *psmc, [in] UINT uId, [in] UINT uIdAncestor, [in] DWORD dwFlags); - - HRESULT GetMenuInfo( + + HRESULT GetMenuInfo( [out] IShellMenuCallback **ppsmc, [out] UINT *puId, [out] UINT *puIdAncestor, [out] DWORD *pdwFlags); - - HRESULT SetShellFolder( + + HRESULT SetShellFolder( [in] IShellFolder *psf, [in] LPCITEMIDLIST pidlFolder, [in] HKEY hKey, [in] DWORD dwFlags); - - HRESULT GetShellFolder( + + HRESULT GetShellFolder( [out] DWORD *pdwFlags, [out] LPITEMIDLIST *ppidl, [in] REFIID riid, [out] void **ppv); - - HRESULT SetMenu( + + HRESULT SetMenu( [in] HMENU hmenu, [in] HWND hwnd, [in] DWORD dwFlags); - - HRESULT GetMenu( + + HRESULT GetMenu( [out] HMENU *phmenu, [out] HWND *phwnd, [out] DWORD *pdwFlags); - - HRESULT InvalidateItem( + + HRESULT InvalidateItem( [in] LPSMDATA psmd, [in] DWORD dwFlags); - - HRESULT GetState( + + HRESULT GetState( [out] LPSMDATA psmd); - - HRESULT SetMenuToolbar( + + HRESULT SetMenuToolbar( [in] IUnknown *punk, [in] DWORD dwFlags); } @@ -2970,12 +2970,12 @@ cpp_quote("#if (_WIN32_IE >= _WIN32_IE_IE60)") ] interface ITrackShellMenu : IShellMenu { - HRESULT SetObscured( + HRESULT SetObscured( [in] HWND hwndTB, [in] IUnknown *punkBand, DWORD dwSMSetFlags); - HRESULT Popup( + HRESULT Popup( [in] HWND hwnd, [in] POINTL *ppt, [in] RECTL *prcExclude, @@ -4485,4 +4485,11 @@ library ShellObjects coclass DestinationList { interface ICustomDestinationList; } + + [ + uuid(9ac9fbe1-e0a2-4ad6-b4ee-e212013ea917) + ] + coclass ShellItem { + interface IShellItem2; + } } diff --git a/include/psdk/strmif.idl b/include/psdk/strmif.idl index a1cad6ba00e..a06f99b7517 100644 --- a/include/psdk/strmif.idl +++ b/include/psdk/strmif.idl @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +import "unknwn.idl"; import "objidl.idl"; #include diff --git a/include/psdk/wbemcli.idl b/include/psdk/wbemcli.idl index db6a5ac28c8..af5e5bc2609 100644 --- a/include/psdk/wbemcli.idl +++ b/include/psdk/wbemcli.idl @@ -19,6 +19,7 @@ cpp_quote("DEFINE_GUID(CLSID_WbemLocator, 0x4590f811,0x1d3A,0x11d0,0x89,0x1f,0x00,0xaa,0x00,0x4b,0x2e,0x24);") cpp_quote("DEFINE_GUID(CLSID_WbemStatusCode, 0xeb87e1bd,0x3233,0x11d2,0xae,0xc9,0x00,0xc0,0x4f,0xb6,0x88,0x20);") +import "oaidl.idl"; import "objidl.idl"; interface IWbemContext; @@ -28,6 +29,7 @@ interface IWbemCallResult; interface IWbemObjectSink; interface IWbemClassObject; interface IEnumWbemClassObject; +interface IWbemQualifierSet; typedef [v1_enum] enum tag_WBEMSTATUS { @@ -174,6 +176,80 @@ typedef [v1_enum] enum tag_WBEMSTATUS WBEM_E_PROVIDER_DISABLED = 0x8004108a } WBEMSTATUS; +typedef [v1_enum] enum tag_WBEM_TIMEOUT_TYPE +{ + WBEM_NO_WAIT = 0, + WBEM_INFINITE = 0xffffffff +} WBEM_TIMEOUT_TYPE; + +typedef [v1_enum] enum tag_WBEM_CONDITION_FLAG_TYPE +{ + WBEM_FLAG_ALWAYS = 0, + WBEM_FLAG_ONLY_IF_TRUE = 0x1, + WBEM_FLAG_ONLY_IF_FALSE = 0x2, + WBEM_FLAG_ONLY_IF_IDENTICAL = 0x3, + WBEM_MASK_PRIMARY_CONDITION = 0x3, + WBEM_FLAG_KEYS_ONLY = 0x4, + WBEM_FLAG_REFS_ONLY = 0x8, + WBEM_FLAG_LOCAL_ONLY = 0x10, + WBEM_FLAG_PROPAGATED_ONLY = 0x20, + WBEM_FLAG_SYSTEM_ONLY = 0x30, + WBEM_FLAG_NONSYSTEM_ONLY = 0x40, + WBEM_MASK_CONDITION_ORIGIN = 0x70, + WBEM_FLAG_CLASS_OVERRIDES_ONLY = 0x100, + WBEM_FLAG_CLASS_LOCAL_AND_OVERRIDES = 0x200, + WBEM_MASK_CLASS_CONDITION = 0x300 +} WBEM_CONDITION_FLAG_TYPE; + +typedef [v1_enum] enum tag_WBEM_FLAVOR_TYPE +{ + WBEM_FLAVOR_DONT_PROPAGATE = 0, + WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE = 0x1, + WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS = 0x2, + WBEM_FLAVOR_MASK_PROPAGATION = 0xf, + WBEM_FLAVOR_OVERRIDABLE = 0, + WBEM_FLAVOR_NOT_OVERRIDABLE = 0x10, + WBEM_FLAVOR_MASK_PERMISSIONS = 0x10, + WBEM_FLAVOR_ORIGIN_LOCAL = 0, + WBEM_FLAVOR_ORIGIN_PROPAGATED = 0x20, + WBEM_FLAVOR_ORIGIN_SYSTEM = 0x40, + WBEM_FLAVOR_MASK_ORIGIN = 0x60, + WBEM_FLAVOR_NOT_AMENDED = 0, + WBEM_FLAVOR_AMENDED = 0x80, + WBEM_FLAVOR_MASK_AMENDED = 0x80 +} WBEM_FLAVOR_TYPE; + +typedef [v1_enum] enum tag_WBEM_GENUS_TYPE +{ + WBEM_GENUS_CLASS = 1, + WBEM_GENUS_INSTANCE = 2 +} WBEM_GENUS_TYPE; + +typedef [v1_enum] enum tag_CIMTYPE_ENUMERATION +{ + CIM_ILLEGAL = 0xfff, + CIM_EMPTY = 0, + CIM_SINT16 = 2, + CIM_SINT32 = 3, + CIM_REAL32 = 4, + CIM_REAL64 = 5, + CIM_STRING = 8, + CIM_BOOLEAN = 11, + CIM_OBJECT = 13, + CIM_SINT8 = 16, + CIM_UINT8 = 17, + CIM_UINT16 = 18, + CIM_UINT32 = 19, + CIM_SINT64 = 20, + CIM_UINT64 = 21, + CIM_DATETIME = 101, + CIM_REFERENCE = 102, + CIM_CHAR16 = 103, + CIM_FLAG_ARRAY = 0x2000 +} CIMTYPE_ENUMERATION; + +typedef long CIMTYPE; + [ object, restricted, @@ -214,6 +290,24 @@ interface IWbemStatusCodeText : IUnknown [out] BSTR *MessageText); }; +typedef [v1_enum] enum tag_WBEM_GENERIC_FLAG_TYPE +{ + WBEM_FLAG_RETURN_WBEM_COMPLETE = 0, + WBEM_FLAG_BIDIRECTIONAL = 0, + WBEM_FLAG_RETURN_ERROR_OBJECT = 0, + WBEM_FLAG_DONT_SEND_STATUS = 0, + WBEM_FLAG_SEND_ONLY_SELECTED = 0, + WBEM_FLAG_RETURN_IMMEDIATELY = 0x10, + WBEM_FLAG_FORWARD_ONLY = 0x20, + WBEM_FLAG_NO_ERROR_OBJECT = 0x40, + WBEM_FLAG_SEND_STATUS = 0x80, + WBEM_FLAG_ENSURE_LOCATABLE = 0x100, + WBEM_FLAG_DIRECT_READ = 0x200, + WBEM_MASK_RESERVED_FLAGS = 0x1f000, + WBEM_FLAG_USE_AMENDED_QUALIFIERS = 0x20000, + WBEM_FLAG_STRONG_VALIDATION = 0x100000 +} WBEM_GENERIC_FLAG_TYPE; + [ object, restricted, @@ -393,3 +487,151 @@ interface IEnumWbemClassObject : IUnknown [in] long lTimeout, [in] ULONG nCount); }; + +[ + object, + restricted, + local, + uuid(dc12a681-737f-11cf-884d-00aa004b2e24) +] +interface IWbemClassObject : IUnknown +{ + HRESULT GetQualifierSet( + [out] IWbemQualifierSet **ppQualSet); + + HRESULT Get( + [in,string] LPCWSTR wszName, + [in] long lFlags, + [out] VARIANT *pVal, + [out] CIMTYPE *pType, + [out] long *plFlavor); + + HRESULT Put( + [in,string] LPCWSTR wszName, + [in] long lFlags, + [in] VARIANT *pVal, + [in] CIMTYPE Type); + + HRESULT Delete( + [in,string] LPCWSTR wszName); + + HRESULT GetNames( + [in,string] LPCWSTR wszQualifierName, + [in] long lFlags, + [in] VARIANT *pQualifierVal, + [out] SAFEARRAY **pNames); + + HRESULT BeginEnumeration( + [in] long lEnumFlags); + + HRESULT Next( + [in] long lFlags, + [out] BSTR *strName, + [out] VARIANT *pVal, + [out] CIMTYPE *pType, + [out] long *plFlavor); + + HRESULT EndEnumeration(); + + HRESULT GetPropertyQualifierSet( + [in,string] LPCWSTR wszProperty, + [out] IWbemQualifierSet **ppQualSet); + + HRESULT Clone( + [out] IWbemClassObject **ppCopy); + + HRESULT GetObjectText( + [in] long lFlags, + [out] BSTR *pstrObjectText); + + HRESULT SpawnDerivedClass( + [in] long lFlags, + [out] IWbemClassObject **ppNewClass); + + HRESULT SpawnInstance( + [in] long lFlags, + [out] IWbemClassObject **ppNewInstance); + + HRESULT CompareTo( + [in] long lFlags, + [in] IWbemClassObject *pCompareTo); + + HRESULT GetPropertyOrigin( + [in,string] LPCWSTR wszName, + [out] BSTR *pstrClassName); + + HRESULT InheritsFrom( + [in] LPCWSTR strAncestor); + + HRESULT GetMethod( + [in,string] LPCWSTR wszName, + [in] long lFlags, + [out] IWbemClassObject **ppInSignature, + [out] IWbemClassObject **ppOutSignature); + + HRESULT PutMethod( + [in,string] LPCWSTR wszName, + [in] long lFlags, + [in] IWbemClassObject *pInSignature, + [in] IWbemClassObject *pOutSignature); + + HRESULT DeleteMethod( + [in,string] LPCWSTR wszName); + + HRESULT BeginMethodEnumeration( + [in] long lEnumFlags); + + HRESULT NextMethod( + [in] long lFlags, + [out] BSTR *pstrName, + [out] IWbemClassObject **ppInSignature, + [out] IWbemClassObject **ppOutSignature); + + HRESULT EndMethodEnumeration(); + + HRESULT GetMethodQualifierSet( + [in,string] LPCWSTR wszMethod, + [out] IWbemQualifierSet **ppQualSet); + + HRESULT GetMethodOrigin( + [in,string] LPCWSTR wszMethodName, + [out] BSTR *pstrClassName); +} + +[ + object, + restricted, + local, + uuid(dc12a680-737f-11cf-884d-00aa004b2e24) +] +interface IWbemQualifierSet : IUnknown +{ + HRESULT Get( + [in,string] LPCWSTR wszName, + [in] long lFlags, + [out] VARIANT *pVal, + [out] long *plFlavor); + + HRESULT Put( + [in,string] LPCWSTR wszName, + [in] VARIANT *pVal, + [in] long lFlavor); + + HRESULT Delete( + [in,string] LPCWSTR wszName); + + HRESULT GetNames( + [in] long lFlags, + [out] SAFEARRAY **pNames); + + HRESULT BeginEnumeration( + [in] long lFlags); + + HRESULT Next( + [in] long lFlags, + [out] BSTR *pstrName, + [out] VARIANT *pVal, + [out] long *plFlavor); + + HRESULT EndEnumeration(); +}; diff --git a/include/psdk/wbemprov.idl b/include/psdk/wbemprov.idl new file mode 100644 index 00000000000..bb9f1b16f46 --- /dev/null +++ b/include/psdk/wbemprov.idl @@ -0,0 +1,28 @@ +/* + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * 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 + */ + +[ + uuid(092df710-7010-11d1-ad90-00c04fd8fdff) +] +library WbemProviders_v1 +{ + [ + uuid(cb8555cc-9128-11d1-ad9b-00c04fd8fdff) + ] + coclass WbemAdministrativeLocator { interface IWbemLocator; } +} diff --git a/include/psdk/winbase.h b/include/psdk/winbase.h index a123ebd76ae..d826ec16ae6 100644 --- a/include/psdk/winbase.h +++ b/include/psdk/winbase.h @@ -768,10 +768,15 @@ typedef struct _DEBUG_EVENT { typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; - DWORD Offset; - DWORD OffsetHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + PVOID Pointer; + } DUMMYUNIONNAME; HANDLE hEvent; -} OVERLAPPED,*POVERLAPPED,*LPOVERLAPPED; +} OVERLAPPED, *POVERLAPPED, *LPOVERLAPPED; typedef struct _STARTUPINFOA { DWORD cb; diff --git a/include/psdk/winternl.h b/include/psdk/winternl.h index dd1a3903264..d181ce1b736 100644 --- a/include/psdk/winternl.h +++ b/include/psdk/winternl.h @@ -1084,19 +1084,17 @@ typedef struct _RTL_RWLOCK { typedef struct _SYSTEM_BASIC_INFORMATION { #ifdef __WINESRC__ - DWORD dwUnknown1; - ULONG uKeMaximumIncrement; - ULONG uPageSize; - ULONG uMmNumberOfPhysicalPages; - ULONG uMmLowestPhysicalPage; - ULONG uMmHighestPhysicalPage; - ULONG uAllocationGranularity; - PVOID pLowestUserAddress; - PVOID pMmHighestUserAddress; - ULONG uKeActiveProcessors; - BYTE bKeNumberProcessors; - BYTE bUnknown2; - WORD wUnknown3; + DWORD unknown; + ULONG KeMaximumIncrement; + ULONG PageSize; + ULONG MmNumberOfPhysicalPages; + ULONG MmLowestPhysicalPage; + ULONG MmHighestPhysicalPage; + ULONG_PTR AllocationGranularity; + PVOID LowestUserAddress; + PVOID HighestUserAddress; + ULONG_PTR ActiveProcessorsAffinityMask; + BYTE NumberOfProcessors; #else BYTE Reserved1[24]; PVOID Reserved2[4]; diff --git a/include/reactos/drivers/condrv/ntddcon.h b/include/reactos/drivers/condrv/ntddcon.h new file mode 100644 index 00000000000..589635091cb --- /dev/null +++ b/include/reactos/drivers/condrv/ntddcon.h @@ -0,0 +1,145 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: include/reactos/drivers/condrv/ntddcon.h + * PURPOSE: Console Driver IOCTL Interface + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#if (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef _NTDDCON_H_ +#define _NTDDCON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// FIXME: Redo all the drawing since this one is quite old... + +/************************************************************************************************ + * Architecture of the Generic Terminal Driver + ************************************************************************************************ + +IN = CONIN$ = stdin +OUT = CONOUT$ = stdout +ERR = stderr + + +------------------------------+ + +-------------+ | +-----------------+ | + | |----- ERR ---->| |------+ | + | Console App |----- OUT ---->| Virtual Console |----+ | | + | 1 |<---- IN -----| 1-1 |--+ | | | + +-------------+ | +-----------------+ | | | | + | | | \ | + +-------------+ | +-----------------+ | | >--X----- ERR ----> + | |----- ERR ---->| |--|-|-/ | + | Console App |----- OUT ---->| Virtual Console |--|-+-----X----- OUT ----> + | 2 |<---- IN -----| 1-2 |--+---\ | + +-------------+ ^ | +-----------------+ \--X<---- IN ----- + | | | ^ + --+ | | . . . | | +\Console +-- \CurrentIn | | | | | + +-- \CurrentOut +----+ | | | + \CurrentErr | | Terminal 1 | | + --+ | | | + +------------------------------+ | + | + +----+----+ + . . . | \Input | + \Output + \Error + +*/ + +/* + * Remarks on the symbolic links : + * + * - \DosDevices\ is an alias to \??\ + * + * - Using "\DosDevices\Global\" allows the driver to ALWAYS + * create the symbolic link in the global object namespace. Indeed, + * under Windows NT-2000, the \DosDevices\ directory was always + * global, but starting with Windows XP, it became local to a session. + * One would then use \GLOBAL??\ to access to the global directory. + * However, this name doesn't exist under Windows NT-2000. + * Therefore, we use the trick to use the 'Global' symbolic link + * defined both under Windows NT-2000 and Windows XP and later, + * which exists in \DosDevices\, to access to \??\ (global) under + * Windows NT-2000, and to \GLOBAL??\ under Windows XP and later. + */ + +// +// Controller device +// +#define DD_CONDRV_CTRL_DEVICE_NAME "\\Device\\ConDrv" +#define DD_CONDRV_CTRL_DEVICE_NAME_U L"\\Device\\ConDrv" +#define DD_CONDRV_CTRL_SYMLNK_NAME "\\DosDevices\\Global\\ConDrv" +#define DD_CONDRV_CTRL_SYMLNK_NAME_U L"\\DosDevices\\Global\\ConDrv" + + +// +// Console +// +#define DD_CONDRV_CONSOLE_DEVICE_NAME "\\Device\\Console" +#define DD_CONDRV_CONSOLE_DEVICE_NAME_U L"\\Device\\Console" +#define DD_CONDRV_CONSOLE_SYMLNK_NAME "\\DosDevices\\Global\\Console" +#define DD_CONDRV_CONSOLE_SYMLNK_NAME_U L"\\DosDevices\\Global\\Console" + + +#ifdef TELETYPE +// +// Virtual files associated with a given console +// +#define CONDRV_CONSOLE_FILE_CURRIN "\\CurrentIn" +#define CONDRV_CONSOLE_FILE_CURRIN_U L"\\CurrentIn" + +#define CONDRV_CONSOLE_FILE_CURROUT "\\CurrentOut" +#define CONDRV_CONSOLE_FILE_CURROUT_U L"\\CurrentOut" + +//#define CONDRV_CONSOLE_FILE_CURRERR "\\CurrentErr" +//#define CONDRV_CONSOLE_FILE_CURRERR_U L"\\CurrentErr" + +#define CONDRV_VC_FILE_SCRBUF "\\ScreenBuffer" +#define CONDRV_VC_FILE_SCRBUF_U L"\\ScreenBuffer" + +/*** Original names from Windows-8 condrv.sys *** + +L"\Connect" +L"\Reference" +L"\Server" +L"\Broker" + +L"\Console" +L"\Display" + +L"\Input" +L"\Output" +L"\CurrentIn" +L"\CurrentOut" +L"\ScreenBuffer" + +***/ + +#endif + + +// +// IO codes +// +#ifndef CTL_CODE + #error "CTL_CODE undefined. Include winioctl.h or wdm.h" +#endif + +#define IOCTL_CONDRV_CREATE_CONSOLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ALL_ACCESS) +#define IOCTL_CONDRV_DELETE_CONSOLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_WRITE_ACCESS) + +#ifdef __cplusplus +} +#endif + +#endif // _NTDDCON_H_ + +/* EOF */ diff --git a/include/reactos/libs/zlib/zconf.h b/include/reactos/libs/zlib/zconf.h index 8a46a58b30c..9987a775530 100644 --- a/include/reactos/libs/zlib/zconf.h +++ b/include/reactos/libs/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -21,6 +21,7 @@ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block @@ -77,6 +78,7 @@ # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread @@ -103,6 +105,7 @@ # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine @@ -388,20 +391,14 @@ typedef uLong FAR uLongf; typedef Byte *voidp; #endif -/* ./configure may #define Z_U4 here */ - #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) # include # if (UINT_MAX == 0xffffffffUL) # define Z_U4 unsigned -# else -# if (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# else -# if (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -# endif +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short # endif #endif @@ -425,8 +422,16 @@ typedef uLong FAR uLongf; # endif #endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + #ifdef _WIN32 -# include /* for wchar_t */ +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and @@ -435,7 +440,7 @@ typedef uLong FAR uLongf; * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ -#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif @@ -443,7 +448,7 @@ typedef uLong FAR uLongf; # define Z_HAVE_UNISTD_H #endif #ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE) +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) # include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include /* for off_t */ diff --git a/include/reactos/libs/zlib/zlib.h b/include/reactos/libs/zlib/zlib.h index 3edf3acdb57..3e0c7672ac5 100644 --- a/include/reactos/libs/zlib/zlib.h +++ b/include/reactos/libs/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.7, May 2nd, 2012 + version 1.2.8, April 28th, 2013 - Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.7" -#define ZLIB_VERNUM 0x1270 +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 7 +#define ZLIB_VER_REVISION 8 #define ZLIB_VER_SUBREVISION 0 /* @@ -839,6 +839,21 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a possible full flush point (see above @@ -846,7 +861,7 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); available input is skipped. No output is provided. inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurences of this + All full flush points have this pattern, but not all occurrences of this pattern are full flush points. inflateSync returns Z_OK if a possible full flush point has been found, @@ -1007,7 +1022,8 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, @@ -1015,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. @@ -1736,6 +1753,13 @@ ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, const char *mode)); #endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif #ifdef __cplusplus } diff --git a/include/reactos/subsys/win/conmsg.h b/include/reactos/subsys/win/conmsg.h index 0f75fcc373c..06cb931fc1c 100644 --- a/include/reactos/subsys/win/conmsg.h +++ b/include/reactos/subsys/win/conmsg.h @@ -133,7 +133,7 @@ typedef struct _CONSOLE_CONNECTION_INFO /* Adapted from CONSOLE_ALLOCCONSOLE */ CONSOLE_START_INFO ConsoleStartInfo; - HANDLE Console; // ConsoleHandle // On ReactOS, it is a PCONSOLE + HANDLE ConsoleHandle; HANDLE InputHandle; HANDLE OutputHandle; HANDLE ErrorHandle; @@ -167,8 +167,8 @@ typedef struct HANDLE InputHandle; BOOL Unicode; - WORD NrCharactersToRead; - WORD NrCharactersRead; + ULONG NrCharactersToRead; + ULONG NrCharactersRead; UNICODE_STRING ExeName; DWORD CtrlWakeupMask; @@ -182,7 +182,7 @@ typedef struct { PCONSOLE_START_INFO ConsoleStartInfo; - HANDLE Console; // ConsoleHandle // On ReactOS, it is a PCONSOLE + HANDLE ConsoleHandle; HANDLE InputHandle; HANDLE OutputHandle; HANDLE ErrorHandle; @@ -194,7 +194,7 @@ typedef struct typedef struct { DWORD ProcessId; // If ProcessId == ATTACH_PARENT_PROCESS == -1, then attach the current process to its parent process console. - HANDLE Console; // ConsoleHandle // On ReactOS, it is a PCONSOLE + HANDLE ConsoleHandle; HANDLE InputHandle; HANDLE OutputHandle; HANDLE ErrorHandle; diff --git a/include/reactos/version.cmake b/include/reactos/version.cmake index 641fb00eafb..027be3c584f 100644 --- a/include/reactos/version.cmake +++ b/include/reactos/version.cmake @@ -1,7 +1,9 @@ macro(today RESULT) if(CMAKE_HOST_WIN32) - execute_process(COMMAND "${REACTOS_SOURCE_DIR}/tools/getdate.exe" OUTPUT_VARIABLE ${RESULT}) - string(STRIP ${${RESULT}} ${RESULT}) + execute_process(COMMAND wmic os get LocalDateTime OUTPUT_VARIABLE RAWDATE) + string(REPLACE "\n" ";" RAWDATE ${RAWDATE}) + LIST(GET RAWDATE 1 RAWDATE) + string(SUBSTRING ${RAWDATE} 0 8 ${RESULT}) elseif(CMAKE_HOST_UNIX) execute_process(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE ${RESULT}) string(STRIP ${${RESULT}} ${RESULT}) diff --git a/include/reactos/wine/CMakeLists.txt b/include/reactos/wine/CMakeLists.txt index 228da16f35f..9b39c88cdb9 100644 --- a/include/reactos/wine/CMakeLists.txt +++ b/include/reactos/wine/CMakeLists.txt @@ -1,4 +1,3 @@ -add_idl_headers(wineheaders itss.idl) - +add_idl_headers(wineheaders itss.idl winedxgi.idl) add_iid_library(itss_guid itss.idl) diff --git a/include/reactos/wine/strmbase.h b/include/reactos/wine/strmbase.h new file mode 100644 index 00000000000..ecb53c41c6d --- /dev/null +++ b/include/reactos/wine/strmbase.h @@ -0,0 +1,660 @@ +/* + * Header file for Wine's strmbase implementation + * + * Copyright 2003 Robert Shearman + * Copyright 2010 Aric Stewart, CodeWeavers + * + * 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 + */ + +HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc); +void WINAPI FreeMediaType(AM_MEDIA_TYPE * pMediaType); +AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const * pSrc); +void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType); + +/* Pin functions */ + +typedef struct BasePin +{ + IPin IPin_iface; + LONG refCount; + LPCRITICAL_SECTION pCritSec; + PIN_INFO pinInfo; + IPin * pConnectedTo; + AM_MEDIA_TYPE mtCurrent; + REFERENCE_TIME tStart; + REFERENCE_TIME tStop; + double dRate; + + const struct BasePinFuncTable* pFuncsTable; +} BasePin; + +typedef HRESULT (WINAPI *BasePin_CheckMediaType)(BasePin *This, const AM_MEDIA_TYPE *pmt); +typedef HRESULT (WINAPI *BasePin_AttemptConnection)(BasePin *This, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); +typedef LONG (WINAPI *BasePin_GetMediaTypeVersion)(BasePin *This); +typedef HRESULT (WINAPI *BasePin_GetMediaType)(BasePin *This, int iPosition, AM_MEDIA_TYPE *amt); + +typedef struct BasePinFuncTable { + /* Required for Input Pins*/ + BasePin_CheckMediaType pfnCheckMediaType; + /* Required for Output Pins*/ + BasePin_AttemptConnection pfnAttemptConnection; + /* Required for BasePinImpl_EnumMediaTypes */ + BasePin_GetMediaTypeVersion pfnGetMediaTypeVersion; + BasePin_GetMediaType pfnGetMediaType; +} BasePinFuncTable; + +typedef struct BaseOutputPin +{ + /* inheritance C style! */ + BasePin pin; + IMemInputPin * pMemInputPin; + IMemAllocator * pAllocator; + + const struct BaseOutputPinFuncTable* pFuncsTable; +} BaseOutputPin; + +typedef HRESULT (WINAPI *BaseOutputPin_DecideBufferSize)(BaseOutputPin *This, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest); +typedef HRESULT (WINAPI *BaseOutputPin_DecideAllocator)(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc); +typedef HRESULT (WINAPI *BaseOutputPin_BreakConnect)(BaseOutputPin * This); + +typedef struct BaseOutputPinFuncTable { + /* Required for BaseOutputPinImpl_DecideAllocator */ + BaseOutputPin_DecideBufferSize pfnDecideBufferSize; + /* Required for BaseOutputPinImpl_AttemptConnection */ + BaseOutputPin_DecideAllocator pfnDecideAllocator; + BaseOutputPin_BreakConnect pfnBreakConnect; +} BaseOutputPinFuncTable; + +typedef struct BaseInputPin +{ + /* inheritance C style! */ + BasePin pin; + + IMemInputPin IMemInputPin_iface; + IMemAllocator * pAllocator; + BOOL flushing, end_of_stream; + IMemAllocator *preferred_allocator; + + const struct BaseInputPinFuncTable* pFuncsTable; +} BaseInputPin; + +typedef HRESULT (WINAPI *BaseInputPin_Receive)(BaseInputPin *This, IMediaSample *pSample); + +typedef struct BaseInputPinFuncTable { + /* Optional */ + BaseInputPin_Receive pfnReceive; +} BaseInputPinFuncTable; + +/* Base Pin */ +HRESULT WINAPI BasePinImpl_GetMediaType(BasePin *This, int iPosition, AM_MEDIA_TYPE *pmt); +LONG WINAPI BasePinImpl_GetMediaTypeVersion(BasePin *This); +ULONG WINAPI BasePinImpl_AddRef(IPin * iface); +HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface); +HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin); +HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo); +HRESULT WINAPI BasePinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir); +HRESULT WINAPI BasePinImpl_QueryId(IPin * iface, LPWSTR * Id); +HRESULT WINAPI BasePinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum); +HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin); +HRESULT WINAPI BasePinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + +/* Base Output Pin */ +HRESULT WINAPI BaseOutputPinImpl_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); +ULONG WINAPI BaseOutputPinImpl_Release(IPin * iface); +HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface); +HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface); +HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface); +HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface); + +HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(BaseOutputPin * This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags); +HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin * This, IMediaSample * pSample); +HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin * This); +HRESULT WINAPI BaseOutputPinImpl_Active(BaseOutputPin * This); +HRESULT WINAPI BaseOutputPinImpl_Inactive(BaseOutputPin * This); +HRESULT WINAPI BaseOutputPinImpl_InitAllocator(BaseOutputPin *This, IMemAllocator **pMemAlloc); +HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc); +HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(BasePin *This, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); + +HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, const BasePinFuncTable* pBaseFuncsTable, const BaseOutputPinFuncTable* pBaseOutputFuncsTable, LPCRITICAL_SECTION pCritSec, IPin ** ppPin); + +/* Base Input Pin */ +HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); +ULONG WINAPI BaseInputPinImpl_Release(IPin * iface); +HRESULT WINAPI BaseInputPinImpl_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BaseInputPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI BaseInputPinImpl_EndOfStream(IPin * iface); +HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin * iface); +HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin * iface); +HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + +HRESULT BaseInputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, const BasePinFuncTable* pBaseFuncsTable, const BaseInputPinFuncTable* pBaseInputFuncsTable, LPCRITICAL_SECTION pCritSec, IMemAllocator *, IPin ** ppPin); + +typedef struct BaseFilter +{ + IBaseFilter IBaseFilter_iface; + LONG refCount; + CRITICAL_SECTION csFilter; + + FILTER_STATE state; + REFERENCE_TIME rtStreamStart; + IReferenceClock * pClock; + FILTER_INFO filterInfo; + CLSID clsid; + LONG pinVersion; + + const struct BaseFilterFuncTable* pFuncsTable; +} BaseFilter; + +typedef IPin* (WINAPI *BaseFilter_GetPin)(BaseFilter* iface, int iPosition); +typedef LONG (WINAPI *BaseFilter_GetPinCount)(BaseFilter* iface); +typedef LONG (WINAPI *BaseFilter_GetPinVersion)(BaseFilter* iface); + +typedef struct BaseFilterFuncTable { + /* Required */ + BaseFilter_GetPin pfnGetPin; + BaseFilter_GetPinCount pfnGetPinCount; +} BaseFilterFuncTable; + +HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv); +ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface); +ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface); +HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid); +HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState ); +HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock); +HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock); +HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum); +HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo); +HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName ); +HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo); + +LONG WINAPI BaseFilterImpl_GetPinVersion(BaseFilter* This); +VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter* This); + +HRESULT WINAPI BaseFilter_Init(BaseFilter * This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseFilterFuncTable* pBaseFuncsTable); + +/* Enums */ +HRESULT WINAPI EnumMediaTypes_Construct(BasePin *iface, BasePin_GetMediaType enumFunc, BasePin_GetMediaTypeVersion versionFunc, IEnumMediaTypes ** ppEnum); + +HRESULT WINAPI EnumPins_Construct(BaseFilter *base, BaseFilter_GetPin receive_pin, BaseFilter_GetPinCount receive_pincount, BaseFilter_GetPinVersion receive_version, IEnumPins ** ppEnum); + +/* Transform Filter */ +typedef struct TransformFilter +{ + BaseFilter filter; + + IPin **ppPins; + ULONG npins; + AM_MEDIA_TYPE pmt; + CRITICAL_SECTION csReceive; + + const struct TransformFilterFuncTable * pFuncsTable; + struct QualityControlImpl *qcimpl; + /* IMediaSeeking and IMediaPosition are implemented by ISeekingPassThru */ + IUnknown *seekthru_unk; +} TransformFilter; + +typedef HRESULT (WINAPI *TransformFilter_DecideBufferSize) (TransformFilter *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest); +typedef HRESULT (WINAPI *TransformFilter_StartStreaming) (TransformFilter *iface); +typedef HRESULT (WINAPI *TransformFilter_StopStreaming) (TransformFilter *iface); +typedef HRESULT (WINAPI *TransformFilter_Receive) (TransformFilter* iface, IMediaSample* pIn); +typedef HRESULT (WINAPI *TransformFilter_CompleteConnect) (TransformFilter *iface, PIN_DIRECTION dir, IPin *pPin); +typedef HRESULT (WINAPI *TransformFilter_BreakConnect) (TransformFilter *iface, PIN_DIRECTION dir); +typedef HRESULT (WINAPI *TransformFilter_SetMediaType) (TransformFilter *iface, PIN_DIRECTION dir, const AM_MEDIA_TYPE *pMediaType); +typedef HRESULT (WINAPI *TransformFilter_CheckInputType) (TransformFilter *iface, const AM_MEDIA_TYPE *pMediaType); +typedef HRESULT (WINAPI *TransformFilter_EndOfStream) (TransformFilter *iface); +typedef HRESULT (WINAPI *TransformFilter_BeginFlush) (TransformFilter *iface); +typedef HRESULT (WINAPI *TransformFilter_EndFlush) (TransformFilter *iface); +typedef HRESULT (WINAPI *TransformFilter_NewSegment) (TransformFilter *iface, +REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); +typedef HRESULT (WINAPI *TransformFilter_Notify) (TransformFilter *iface, IBaseFilter *sender, Quality qm); + +typedef struct TransformFilterFuncTable { + /* Required */ + TransformFilter_DecideBufferSize pfnDecideBufferSize; + /* Optional */ + TransformFilter_StartStreaming pfnStartStreaming; + TransformFilter_Receive pfnReceive; + TransformFilter_StopStreaming pfnStopStreaming; + TransformFilter_CheckInputType pfnCheckInputType; + TransformFilter_SetMediaType pfnSetMediaType; + TransformFilter_CompleteConnect pfnCompleteConnect; + TransformFilter_BreakConnect pfnBreakConnect; + TransformFilter_EndOfStream pfnEndOfStream; + TransformFilter_BeginFlush pfnBeginFlush; + TransformFilter_EndFlush pfnEndFlush; + TransformFilter_NewSegment pfnNewSegment; + TransformFilter_Notify pfnNotify; +} TransformFilterFuncTable; + +HRESULT WINAPI TransformFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv); +ULONG WINAPI TransformFilterImpl_Release(IBaseFilter * iface); +HRESULT WINAPI TransformFilterImpl_Stop(IBaseFilter * iface); +HRESULT WINAPI TransformFilterImpl_Pause(IBaseFilter * iface); +HRESULT WINAPI TransformFilterImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart); +HRESULT WINAPI TransformFilterImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin); +HRESULT WINAPI TransformFilterImpl_Notify(TransformFilter *iface, IBaseFilter *sender, Quality qm); + +HRESULT TransformFilter_Construct( const IBaseFilterVtbl *filterVtbl, LONG filter_size, const CLSID* pClsid, const TransformFilterFuncTable* pFuncsTable, IBaseFilter ** ppTransformFilter); + +/* Source Seeking */ +typedef HRESULT (WINAPI *SourceSeeking_ChangeRate)(IMediaSeeking *iface); +typedef HRESULT (WINAPI *SourceSeeking_ChangeStart)(IMediaSeeking *iface); +typedef HRESULT (WINAPI *SourceSeeking_ChangeStop)(IMediaSeeking *iface); + +typedef struct SourceSeeking +{ + IMediaSeeking IMediaSeeking_iface; + + ULONG refCount; + SourceSeeking_ChangeStop fnChangeStop; + SourceSeeking_ChangeStart fnChangeStart; + SourceSeeking_ChangeRate fnChangeRate; + DWORD dwCapabilities; + double dRate; + LONGLONG llCurrent, llStop, llDuration; + GUID timeformat; + PCRITICAL_SECTION crst; +} SourceSeeking; + +HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, SourceSeeking_ChangeRate fnChangeRate, PCRITICAL_SECTION crit_sect); + +HRESULT WINAPI SourceSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities); +HRESULT WINAPI SourceSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities); +HRESULT WINAPI SourceSeekingImpl_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat); +HRESULT WINAPI SourceSeekingImpl_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat); +HRESULT WINAPI SourceSeekingImpl_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat); +HRESULT WINAPI SourceSeekingImpl_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat); +HRESULT WINAPI SourceSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat); +HRESULT WINAPI SourceSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration); +HRESULT WINAPI SourceSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop); +HRESULT WINAPI SourceSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent); +HRESULT WINAPI SourceSeekingImpl_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat); +HRESULT WINAPI SourceSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags); +HRESULT WINAPI SourceSeekingImpl_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop); +HRESULT WINAPI SourceSeekingImpl_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest); +HRESULT WINAPI SourceSeekingImpl_SetRate(IMediaSeeking * iface, double dRate); +HRESULT WINAPI SourceSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate); +HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll); + +/* PosPassThru */ +HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start); +HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface); +HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface); + +HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru); +HRESULT WINAPI PosPassThru_Construct(IUnknown* pUnkOuter, LPVOID *ppPassThru); + +/* Filter Registration */ + +typedef REGPINTYPES AMOVIESETUP_MEDIATYPE; +typedef REGFILTERPINS AMOVIESETUP_PIN; + +typedef struct AMOVIESETUP_FILTER { + const CLSID *clsid; + const WCHAR *name; + DWORD merit; + UINT pins; + const AMOVIESETUP_PIN *pPin; +} AMOVIESETUP_FILTER, *LPAMOVIESETUP_FILTER; + +typedef IUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr); +typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid); + +typedef struct tagFactoryTemplate { + const WCHAR *m_Name; + const CLSID *m_ClsID; + LPFNNewCOMObject m_lpfnNew; + LPFNInitRoutine m_lpfnInit; + const AMOVIESETUP_FILTER *m_pAMovieSetup_Filter; +} FactoryTemplate; + +HRESULT WINAPI AMovieDllRegisterServer2(BOOL bRegister); +HRESULT WINAPI AMovieSetupRegisterFilter2(const AMOVIESETUP_FILTER *pFilter, IFilterMapper2 *pIFM2, BOOL bRegister); + +/* Output Queue */ +typedef struct tagOutputQueue { + CRITICAL_SECTION csQueue; + + BaseOutputPin * pInputPin; + + HANDLE hThread; + HANDLE hProcessQueue; + + LONG lBatchSize; + BOOL bBatchExact; + BOOL bTerminate; + BOOL bSendAnyway; + + struct list *SampleList; + + const struct OutputQueueFuncTable* pFuncsTable; +} OutputQueue; + +typedef DWORD (WINAPI *OutputQueue_ThreadProc)(OutputQueue *This); + +typedef struct OutputQueueFuncTable +{ + OutputQueue_ThreadProc pfnThreadProc; +} OutputQueueFuncTable; + +HRESULT WINAPI OutputQueue_Construct( BaseOutputPin *pInputPin, BOOL bAuto, + BOOL bQueue, LONG lBatchSize, BOOL bBatchExact, DWORD dwPriority, + const OutputQueueFuncTable* pFuncsTable, OutputQueue **ppOutputQueue ); +HRESULT WINAPI OutputQueue_Destroy(OutputQueue *pOutputQueue); +HRESULT WINAPI OutputQueue_ReceiveMultiple(OutputQueue *pOutputQueue, IMediaSample **ppSamples, LONG nSamples, LONG *nSamplesProcessed); +HRESULT WINAPI OutputQueue_Receive(OutputQueue *pOutputQueue, IMediaSample *pSample); +VOID WINAPI OutputQueue_EOS(OutputQueue *pOutputQueue); +VOID WINAPI OutputQueue_SendAnyway(OutputQueue *pOutputQueue); +DWORD WINAPI OutputQueueImpl_ThreadProc(OutputQueue *pOutputQueue); + +typedef struct tagBaseWindow +{ + HWND hWnd; + LONG Width; + LONG Height; + HINSTANCE hInstance; + LPWSTR pClassName; + DWORD ClassStyles; + DWORD WindowStyles; + DWORD WindowStylesEx; + HDC hDC; + + const struct BaseWindowFuncTable* pFuncsTable; +} BaseWindow; + +typedef LPWSTR (WINAPI *BaseWindow_GetClassWindowStyles)(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx); +typedef RECT (WINAPI *BaseWindow_GetDefaultRect)(BaseWindow *This); +typedef BOOL (WINAPI *BaseWindow_PossiblyEatMessage)(BaseWindow *This, UINT uMsg, WPARAM wParam, LPARAM lParam); +typedef LRESULT (WINAPI *BaseWindow_OnReceiveMessage)(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam); +typedef BOOL (WINAPI *BaseWindow_OnSize)(BaseWindow *This, LONG Height, LONG Width); + +typedef struct BaseWindowFuncTable +{ + /* Required */ + BaseWindow_GetClassWindowStyles pfnGetClassWindowStyles; + BaseWindow_GetDefaultRect pfnGetDefaultRect; + /* Optional, WinProc Related */ + BaseWindow_OnReceiveMessage pfnOnReceiveMessage; + BaseWindow_PossiblyEatMessage pfnPossiblyEatMessage; + BaseWindow_OnSize pfnOnSize; +} BaseWindowFuncTable; + +HRESULT WINAPI BaseWindow_Init(BaseWindow *pBaseWindow, const BaseWindowFuncTable* pFuncsTable); +HRESULT WINAPI BaseWindow_Destroy(BaseWindow *pBaseWindow); + +HRESULT WINAPI BaseWindowImpl_PrepareWindow(BaseWindow *This); +HRESULT WINAPI BaseWindowImpl_DoneWithWindow(BaseWindow *This); +RECT WINAPI BaseWindowImpl_GetDefaultRect(BaseWindow *This); +LRESULT WINAPI BaseWindowImpl_OnReceiveMessage(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam); +BOOL WINAPI BaseWindowImpl_OnSize(BaseWindow *This, LONG Height, LONG Width); + +typedef struct{ + ITypeInfo *pTypeInfo; +} BaseDispatch; + +HRESULT WINAPI BaseDispatch_Init(BaseDispatch *This, REFIID riid); +HRESULT WINAPI BaseDispatch_Destroy(BaseDispatch *This); +HRESULT WINAPI BaseDispatchImpl_GetIDsOfNames(BaseDispatch *This, REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid); +HRESULT WINAPI BaseDispatchImpl_GetTypeInfo(BaseDispatch *This, REFIID riid, UINT itinfo, LCID lcid, ITypeInfo **pptinfo); +HRESULT WINAPI BaseDispatchImpl_GetTypeInfoCount(BaseDispatch *This, UINT *pctinfo); + +#ifdef __IVideoWindow_FWD_DEFINED__ +typedef struct tagBaseControlWindow +{ + BaseWindow baseWindow; + IVideoWindow IVideoWindow_iface; + BaseDispatch baseDispatch; + + BOOL AutoShow; + HWND hwndDrain; + HWND hwndOwner; + BaseFilter* pFilter; + CRITICAL_SECTION* pInterfaceLock; + BasePin* pPin; +} BaseControlWindow; + +HRESULT WINAPI BaseControlWindow_Init(BaseControlWindow *pControlWindow, const IVideoWindowVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseWindowFuncTable* pFuncsTable); +HRESULT WINAPI BaseControlWindow_Destroy(BaseControlWindow *pControlWindow); + +BOOL WINAPI BaseControlWindowImpl_PossiblyEatMessage(BaseWindow *This, UINT uMsg, WPARAM wParam, LPARAM lParam); +HRESULT WINAPI BaseControlWindowImpl_GetTypeInfoCount(IVideoWindow *iface, UINT*pctinfo); +HRESULT WINAPI BaseControlWindowImpl_GetTypeInfo(IVideoWindow *iface, UINT iTInfo, LCID lcid, ITypeInfo**ppTInfo); +HRESULT WINAPI BaseControlWindowImpl_GetIDsOfNames(IVideoWindow *iface, REFIID riid, LPOLESTR*rgszNames, UINT cNames, LCID lcid, DISPID*rgDispId); +HRESULT WINAPI BaseControlWindowImpl_Invoke(IVideoWindow *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS*pDispParams, VARIANT*pVarResult, EXCEPINFO*pExepInfo, UINT*puArgErr); +HRESULT WINAPI BaseControlWindowImpl_put_Caption(IVideoWindow *iface, BSTR strCaption); +HRESULT WINAPI BaseControlWindowImpl_get_Caption(IVideoWindow *iface, BSTR *strCaption); +HRESULT WINAPI BaseControlWindowImpl_put_WindowStyle(IVideoWindow *iface, LONG WindowStyle); +HRESULT WINAPI BaseControlWindowImpl_get_WindowStyle(IVideoWindow *iface, LONG *WindowStyle); +HRESULT WINAPI BaseControlWindowImpl_put_WindowStyleEx(IVideoWindow *iface, LONG WindowStyleEx); +HRESULT WINAPI BaseControlWindowImpl_get_WindowStyleEx(IVideoWindow *iface, LONG *WindowStyleEx); +HRESULT WINAPI BaseControlWindowImpl_put_AutoShow(IVideoWindow *iface, LONG AutoShow); +HRESULT WINAPI BaseControlWindowImpl_get_AutoShow(IVideoWindow *iface, LONG *AutoShow); +HRESULT WINAPI BaseControlWindowImpl_put_WindowState(IVideoWindow *iface, LONG WindowState); +HRESULT WINAPI BaseControlWindowImpl_get_WindowState(IVideoWindow *iface, LONG *WindowState); +HRESULT WINAPI BaseControlWindowImpl_put_BackgroundPalette(IVideoWindow *iface, LONG BackgroundPalette); +HRESULT WINAPI BaseControlWindowImpl_get_BackgroundPalette(IVideoWindow *iface, LONG *pBackgroundPalette); +HRESULT WINAPI BaseControlWindowImpl_put_Visible(IVideoWindow *iface, LONG Visible); +HRESULT WINAPI BaseControlWindowImpl_get_Visible(IVideoWindow *iface, LONG *pVisible); +HRESULT WINAPI BaseControlWindowImpl_put_Left(IVideoWindow *iface, LONG Left); +HRESULT WINAPI BaseControlWindowImpl_get_Left(IVideoWindow *iface, LONG *pLeft); +HRESULT WINAPI BaseControlWindowImpl_put_Width(IVideoWindow *iface, LONG Width); +HRESULT WINAPI BaseControlWindowImpl_get_Width(IVideoWindow *iface, LONG *pWidth); +HRESULT WINAPI BaseControlWindowImpl_put_Top(IVideoWindow *iface, LONG Top); +HRESULT WINAPI BaseControlWindowImpl_get_Top(IVideoWindow *iface, LONG *pTop); + +HRESULT WINAPI BaseControlWindowImpl_put_Height(IVideoWindow *iface, LONG Height); +HRESULT WINAPI BaseControlWindowImpl_get_Height(IVideoWindow *iface, LONG *pHeight); +HRESULT WINAPI BaseControlWindowImpl_put_Owner(IVideoWindow *iface, OAHWND Owner); +HRESULT WINAPI BaseControlWindowImpl_get_Owner(IVideoWindow *iface, OAHWND *Owner); +HRESULT WINAPI BaseControlWindowImpl_put_MessageDrain(IVideoWindow *iface, OAHWND Drain); +HRESULT WINAPI BaseControlWindowImpl_get_MessageDrain(IVideoWindow *iface, OAHWND *Drain); +HRESULT WINAPI BaseControlWindowImpl_get_BorderColor(IVideoWindow *iface, LONG *Color); +HRESULT WINAPI BaseControlWindowImpl_put_BorderColor(IVideoWindow *iface, LONG Color); +HRESULT WINAPI BaseControlWindowImpl_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode); +HRESULT WINAPI BaseControlWindowImpl_put_FullScreenMode(IVideoWindow *iface, LONG FullScreenMode); +HRESULT WINAPI BaseControlWindowImpl_SetWindowForeground(IVideoWindow *iface, LONG Focus); +HRESULT WINAPI BaseControlWindowImpl_SetWindowPosition(IVideoWindow *iface, LONG Left, LONG Top, LONG Width, LONG Height); +HRESULT WINAPI BaseControlWindowImpl_GetWindowPosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlWindowImpl_NotifyOwnerMessage(IVideoWindow *iface, OAHWND hwnd, LONG uMsg, LONG_PTR wParam, LONG_PTR lParam); +HRESULT WINAPI BaseControlWindowImpl_GetMinIdealImageSize(IVideoWindow *iface, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow *iface, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlWindowImpl_GetRestorePosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlWindowImpl_HideCursor(IVideoWindow *iface, LONG HideCursor); +HRESULT WINAPI BaseControlWindowImpl_IsCursorHidden(IVideoWindow *iface, LONG *CursorHidden); +#endif + +#ifdef __IBasicVideo_FWD_DEFINED__ +#ifdef __amvideo_h__ +typedef struct tagBaseControlVideo +{ + IBasicVideo IBasicVideo_iface; + BaseDispatch baseDispatch; + + BaseFilter* pFilter; + CRITICAL_SECTION* pInterfaceLock; + BasePin* pPin; + + const struct BaseControlVideoFuncTable* pFuncsTable; +} BaseControlVideo; + +typedef HRESULT (WINAPI *BaseControlVideo_GetSourceRect)(BaseControlVideo* This, RECT *pSourceRect); +typedef HRESULT (WINAPI *BaseControlVideo_GetStaticImage)(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage); +typedef HRESULT (WINAPI *BaseControlVideo_GetTargetRect)(BaseControlVideo* This, RECT *pTargetRect); +typedef VIDEOINFOHEADER* (WINAPI *BaseControlVideo_GetVideoFormat)(BaseControlVideo* This); +typedef HRESULT (WINAPI *BaseControlVideo_IsDefaultSourceRect)(BaseControlVideo* This); +typedef HRESULT (WINAPI *BaseControlVideo_IsDefaultTargetRect)(BaseControlVideo* This); +typedef HRESULT (WINAPI *BaseControlVideo_SetDefaultSourceRect)(BaseControlVideo* This); +typedef HRESULT (WINAPI *BaseControlVideo_SetDefaultTargetRect)(BaseControlVideo* This); +typedef HRESULT (WINAPI *BaseControlVideo_SetSourceRect)(BaseControlVideo* This, RECT *pSourceRect); +typedef HRESULT (WINAPI *BaseControlVideo_SetTargetRect)(BaseControlVideo* This, RECT *pTargetRect); + +typedef struct BaseControlVideoFuncTable { + /* Required */ + BaseControlVideo_GetSourceRect pfnGetSourceRect; + BaseControlVideo_GetStaticImage pfnGetStaticImage; + BaseControlVideo_GetTargetRect pfnGetTargetRect; + BaseControlVideo_GetVideoFormat pfnGetVideoFormat; + BaseControlVideo_IsDefaultSourceRect pfnIsDefaultSourceRect; + BaseControlVideo_IsDefaultTargetRect pfnIsDefaultTargetRect; + BaseControlVideo_SetDefaultSourceRect pfnSetDefaultSourceRect; + BaseControlVideo_SetDefaultTargetRect pfnSetDefaultTargetRect; + BaseControlVideo_SetSourceRect pfnSetSourceRect; + BaseControlVideo_SetTargetRect pfnSetTargetRect; +} BaseControlVideoFuncTable; + +HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBasicVideoVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseControlVideoFuncTable* pFuncsTable); +HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo); + +HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT*pctinfo); +HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo**ppTInfo); +HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR*rgszNames, UINT cNames, LCID lcid, DISPID*rgDispId); +HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS*pDispParams, VARIANT*pVarResult, EXCEPINFO*pExepInfo, UINT*puArgErr); +HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame); +HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate); +HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate); +HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth); +HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight); +HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft); +HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft); +HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth); +HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth); +HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop); +HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop); +HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight); +HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight); +HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft); +HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft); +HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth); +HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth); +HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop); +HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop); +HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight); +HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight); +HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height); +HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface); +HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height); +HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface); +HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight); +HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette); +HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage); +HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface); +HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface); +#endif +#endif + +/* BaseRenderer Filter */ +typedef struct BaseRendererTag +{ + BaseFilter filter; + + BaseInputPin *pInputPin; + IUnknown *pPosition; + CRITICAL_SECTION csRenderLock; + HANDLE evComplete; + HANDLE ThreadSignal; + HANDLE RenderEvent; + IMediaSample *pMediaSample; + + IQualityControl *pQSink; + struct QualityControlImpl *qcimpl; + + const struct BaseRendererFuncTable * pFuncsTable; +} BaseRenderer; + +typedef HRESULT (WINAPI *BaseRenderer_CheckMediaType)(BaseRenderer *This, const AM_MEDIA_TYPE *pmt); +typedef HRESULT (WINAPI *BaseRenderer_DoRenderSample)(BaseRenderer *This, IMediaSample *pMediaSample); +typedef VOID (WINAPI *BaseRenderer_OnReceiveFirstSample)(BaseRenderer *This, IMediaSample *pMediaSample); +typedef VOID (WINAPI *BaseRenderer_OnRenderEnd)(BaseRenderer *This, IMediaSample *pMediaSample); +typedef VOID (WINAPI *BaseRenderer_OnRenderStart)(BaseRenderer *This, IMediaSample *pMediaSample); +typedef VOID (WINAPI *BaseRenderer_OnStartStreaming)(BaseRenderer *This); +typedef VOID (WINAPI *BaseRenderer_OnStopStreaming)(BaseRenderer *This); +typedef VOID (WINAPI *BaseRenderer_OnWaitEnd)(BaseRenderer *This); +typedef VOID (WINAPI *BaseRenderer_OnWaitStart)(BaseRenderer *This); +typedef VOID (WINAPI *BaseRenderer_PrepareRender)(BaseRenderer *This); +typedef HRESULT (WINAPI *BaseRenderer_ShouldDrawSampleNow)(BaseRenderer *This, IMediaSample *pMediaSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime); +typedef HRESULT (WINAPI *BaseRenderer_PrepareReceive)(BaseRenderer *This, IMediaSample *pMediaSample); +typedef HRESULT (WINAPI *BaseRenderer_EndOfStream)(BaseRenderer *This); +typedef HRESULT (WINAPI *BaseRenderer_BeginFlush) (BaseRenderer *This); +typedef HRESULT (WINAPI *BaseRenderer_EndFlush) (BaseRenderer *This); +typedef HRESULT (WINAPI *BaseRenderer_BreakConnect) (BaseRenderer *This); +typedef HRESULT (WINAPI *BaseRenderer_CompleteConnect) (BaseRenderer *This, IPin *pReceivePin); + +typedef struct BaseRendererFuncTable { + /* Required */ + BaseRenderer_CheckMediaType pfnCheckMediaType; + BaseRenderer_DoRenderSample pfnDoRenderSample; + /* Optional, Data Handlers */ + BaseRenderer_OnReceiveFirstSample pfnOnReceiveFirstSample; + BaseRenderer_OnRenderEnd pfnOnRenderEnd; + BaseRenderer_OnRenderStart pfnOnRenderStart; + BaseRenderer_OnStartStreaming pfnOnStartStreaming; + BaseRenderer_OnStopStreaming pfnOnStopStreaming; + BaseRenderer_OnWaitEnd pfnOnWaitEnd; + BaseRenderer_OnWaitStart pfnOnWaitStart; + BaseRenderer_PrepareRender pfnPrepareRender; + BaseRenderer_ShouldDrawSampleNow pfnShouldDrawSampleNow; + BaseRenderer_PrepareReceive pfnPrepareReceive; + /* Optional, Input Pin */ + BaseRenderer_CompleteConnect pfnCompleteConnect; + BaseRenderer_BreakConnect pfnBreakConnect; + BaseRenderer_EndOfStream pfnEndOfStream; + BaseRenderer_BeginFlush pfnBeginFlush; + BaseRenderer_EndFlush pfnEndFlush; +} BaseRendererFuncTable; + +HRESULT WINAPI BaseRendererImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv); +ULONG WINAPI BaseRendererImpl_Release(IBaseFilter * iface); +HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample); +HRESULT WINAPI BaseRendererImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin); +HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface); +HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart); +HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface); +HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock); +HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState); +HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer* iface); +HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface); +HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface); +HRESULT WINAPI BaseRendererImpl_ClearPendingSample(BaseRenderer *iface); + +HRESULT WINAPI BaseRenderer_Init(BaseRenderer *This, const IBaseFilterVtbl *Vtbl, IUnknown *pUnkOuter, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseRendererFuncTable* pBaseFuncsTable); + +#ifdef __IBasicAudio_FWD_DEFINED__ +typedef struct tagBasicAudio +{ + IBasicAudio IBasicAudio_iface; + BaseDispatch baseDispatch; +} BasicAudio; + +HRESULT WINAPI BasicAudio_Init(BasicAudio *This, const IBasicAudioVtbl *Vtbl); +HRESULT WINAPI BasicAudio_Destroy(BasicAudio *pBasicAudio); + +HRESULT WINAPI BasicAudioImpl_GetTypeInfoCount(IBasicAudio *iface, UINT*pctinfo); +HRESULT WINAPI BasicAudioImpl_GetTypeInfo(IBasicAudio *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); +HRESULT WINAPI BasicAudioImpl_GetIDsOfNames(IBasicAudio *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); +HRESULT WINAPI BasicAudioImpl_Invoke(IBasicAudio *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr); +#endif + +/* Dll Functions */ +BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv); +HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv); +HRESULT WINAPI STRMBASE_DllCanUnloadNow(void); diff --git a/include/reactos/wine/winedxgi.idl b/include/reactos/wine/winedxgi.idl new file mode 100644 index 00000000000..363030a0018 --- /dev/null +++ b/include/reactos/wine/winedxgi.idl @@ -0,0 +1,70 @@ +/* + * Copyright 2008-2009 Henri Verbeet for CodeWeavers + * + * 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 + */ + +import "dxgi.idl"; + +[ + object, + local, + uuid(a07ad9ab-fb01-4574-8bfb-0a70a7373f04) +] +interface IWineDXGIFactory : IDXGIFactory +{ + struct wined3d *get_wined3d(); +} + +[ + object, + local, + uuid(ab1de34c-2963-4ffd-8493-40f580e510e5) +] +interface IWineDXGIAdapter : IDXGIAdapter +{ + UINT get_ordinal(); +} + +[ + object, + local, + uuid(3e1ff30b-c951-48c3-b010-0fb49f3dca71) +] +interface IWineDXGIDevice : IDXGIDevice +{ + struct wined3d_device *get_wined3d_device(); + HRESULT create_surface( + [in] const DXGI_SURFACE_DESC *desc, + [in] DXGI_USAGE usage, + [in] const DXGI_SHARED_RESOURCE *shared_resource, + [in] IUnknown *outer, + [out] void **surface + ); + HRESULT create_swapchain( + [in] struct wined3d_swapchain_desc *desc, + [out] struct wined3d_swapchain **wined3d_swapchain + ); +} + +[ + object, + local, + uuid(f2b918f3-603f-430a-9ccd-55872b6e85df) +] +interface IWineDXGIDeviceParent : IUnknown +{ + struct wined3d_device_parent *get_wined3d_device_parent(); +} diff --git a/include/xdk/extypes.h b/include/xdk/extypes.h index 4d9bcb952c7..ae252d375ed 100644 --- a/include/xdk/extypes.h +++ b/include/xdk/extypes.h @@ -51,7 +51,7 @@ typedef enum _EX_POOL_PRIORITY { #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_)) #define LOOKASIDE_ALIGN #else -#define LOOKASIDE_ALIGN /* FIXME: DECLSPEC_CACHEALIGN */ +#define LOOKASIDE_ALIGN DECLSPEC_CACHEALIGN #endif typedef struct _LOOKASIDE_LIST_EX *PLOOKASIDE_LIST_EX; diff --git a/lib/3rdparty/stlport/CMakeLists.txt b/lib/3rdparty/stlport/CMakeLists.txt index b1cf3c8bcbe..4a60835710a 100644 --- a/lib/3rdparty/stlport/CMakeLists.txt +++ b/lib/3rdparty/stlport/CMakeLists.txt @@ -2,13 +2,13 @@ #uncomment this if you want to test c++ compilation #add_subdirectory(test) +set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL) + add_definitions( -D_STLP_USE_EXCEPTIONS -D_DLL -D__USE_CRTIMP -D_BUILD_STLPORT) -set_cpp() - list(APPEND SOURCE src/allocators.cpp src/bitset.cpp diff --git a/lib/3rdparty/strmbase/CMakeLists.txt b/lib/3rdparty/strmbase/CMakeLists.txt new file mode 100644 index 00000000000..b8ec39a1cc6 --- /dev/null +++ b/lib/3rdparty/strmbase/CMakeLists.txt @@ -0,0 +1,23 @@ + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) +add_definitions(-D__WINESRC__) + +list(APPEND SOURCE + audio.c + dispatch.c + dllfunc.c + enumpins.c + filter.c + mediatype.c + outputqueue.c + pin.c + pospass.c + qualitycontrol.c + renderer.c + seeking.c + transform.c + video.c + window.c) + +add_library(strmbase ${SOURCE}) +add_dependencies(strmbase psdk dxsdk) diff --git a/lib/3rdparty/strmbase/audio.c b/lib/3rdparty/strmbase/audio.c new file mode 100644 index 00000000000..e167a794019 --- /dev/null +++ b/lib/3rdparty/strmbase/audio.c @@ -0,0 +1,84 @@ +/* + * Generic Implementation of strmbase audio classes + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include +#include "dshow.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" + + +static inline BasicAudio *impl_from_IBasicAudio(IBasicAudio *iface) +{ + return CONTAINING_RECORD(iface, BasicAudio, IBasicAudio_iface); +} + +HRESULT WINAPI BasicAudio_Init(BasicAudio *pBasicAudio, const IBasicAudioVtbl *lpVtbl) +{ + pBasicAudio->IBasicAudio_iface.lpVtbl = lpVtbl; + BaseDispatch_Init(&pBasicAudio->baseDispatch, &IID_IBasicAudio); + + return S_OK; +} + +HRESULT WINAPI BasicAudio_Destroy(BasicAudio *pBasicAudio) +{ + return BaseDispatch_Destroy(&pBasicAudio->baseDispatch); +} + +HRESULT WINAPI BasicAudioImpl_GetTypeInfoCount(IBasicAudio *iface, UINT *pctinfo) +{ + BasicAudio *This = impl_from_IBasicAudio(iface); + + return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo); +} + +HRESULT WINAPI BasicAudioImpl_GetTypeInfo(IBasicAudio *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + BasicAudio *This = impl_from_IBasicAudio(iface); + + return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo); +} + +HRESULT WINAPI BasicAudioImpl_GetIDsOfNames(IBasicAudio *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + BasicAudio *This = impl_from_IBasicAudio(iface); + + return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId); +} + +HRESULT WINAPI BasicAudioImpl_Invoke(IBasicAudio *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr) +{ + BasicAudio *This = impl_from_IBasicAudio(iface); + HRESULT hr = S_OK; + ITypeInfo *pTypeInfo; + + hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicAudio_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); + ITypeInfo_Release(pTypeInfo); + } + + return hr; +} diff --git a/lib/3rdparty/strmbase/dispatch.c b/lib/3rdparty/strmbase/dispatch.c new file mode 100644 index 00000000000..8f7aa058b17 --- /dev/null +++ b/lib/3rdparty/strmbase/dispatch.c @@ -0,0 +1,79 @@ +/* + * Generic Implementation of IDispatch for strmbase classes + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include + +HRESULT WINAPI BaseDispatch_Init(BaseDispatch *This, REFIID riid) +{ + HRESULT hr = E_FAIL; + ITypeLib *pTypeLib; + + This->pTypeInfo = NULL; + hr = LoadRegTypeLib(&LIBID_QuartzTypeLib, 1, 0, LOCALE_SYSTEM_DEFAULT, &pTypeLib); + if (SUCCEEDED(hr)) + { + hr = ITypeLib_GetTypeInfoOfGuid(pTypeLib, riid, &This->pTypeInfo); + + if (pTypeLib) + ITypeLib_Release(pTypeLib); + } + return hr; +} + +HRESULT WINAPI BaseDispatch_Destroy(BaseDispatch *This) +{ + if (This->pTypeInfo) + ITypeInfo_Release(This->pTypeInfo); + return S_OK; +} + +HRESULT WINAPI BaseDispatchImpl_GetIDsOfNames(BaseDispatch *This, REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid) +{ + if (This->pTypeInfo) + return ITypeInfo_GetIDsOfNames(This->pTypeInfo, rgszNames, cNames, rgdispid); + return E_NOTIMPL; +} + +HRESULT WINAPI BaseDispatchImpl_GetTypeInfo(BaseDispatch *This, REFIID riid, UINT itinfo, LCID lcid, ITypeInfo **pptinfo) +{ + if (This->pTypeInfo) + { + ITypeInfo_AddRef(This->pTypeInfo); + *pptinfo = This->pTypeInfo; + return S_OK; + } + return E_NOTIMPL; +} + +HRESULT WINAPI BaseDispatchImpl_GetTypeInfoCount(BaseDispatch *This, UINT *pctinfo) +{ + if (This->pTypeInfo) + *pctinfo = 1; + else + *pctinfo = 0; + return S_OK; +} diff --git a/lib/3rdparty/strmbase/dllfunc.c b/lib/3rdparty/strmbase/dllfunc.c new file mode 100644 index 00000000000..23e71db4743 --- /dev/null +++ b/lib/3rdparty/strmbase/dllfunc.c @@ -0,0 +1,469 @@ +/* + * Strmbase DLL functions + * + * Copyright (C) 2005 Rolf Kalbermatter + * Copyright (C) 2010 Aric Stewart, CodeWeavers +* + * 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 + */ +#include "config.h" + +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "winreg.h" +#include "objbase.h" +#include "uuids.h" +#include "strmif.h" + +#include "wine/unicode.h" +#include "wine/debug.h" +#include "wine/strmbase.h" + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +extern const int g_cTemplates; +extern const FactoryTemplate g_Templates[]; + +static HINSTANCE g_hInst = NULL; +static LONG server_locks = 0; + +/* + * defines and constants + */ +#define MAX_KEY_LEN 260 + +static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0 }; +static const WCHAR ips32_keyname[] = {'I','n','P','r','o','c','S','e','r','v','e','r','3','2',0}; +static const WCHAR tmodel_keyname[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; +static const WCHAR tmodel_both[] = {'B','o','t','h',0}; + +#ifdef __REACTOS__ +static LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey) +{ + LONG ret; + DWORD dwMaxSubkeyLen, dwMaxValueLen; + DWORD dwMaxLen, dwSize; + WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf; + HKEY hSubKey = hKey; + + TRACE("(hkey=%p,%p %s)\n", hKey, lpszSubKey, debugstr_w(lpszSubKey)); + + if(lpszSubKey) + { + ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey); + if (ret) return ret; + } + + /* Get highest length for keys, values */ + ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, + &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL); + if (ret) goto cleanup; + + dwMaxSubkeyLen++; + dwMaxValueLen++; + dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen); + if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR)) + { + /* Name too big: alloc a buffer for it */ + if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR)))) + { + ret = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + } + + + /* Recursively delete all the subkeys */ + while (TRUE) + { + dwSize = dwMaxLen; + if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, + NULL, NULL, NULL)) break; + + ret = RegDeleteTreeW(hSubKey, lpszName); + if (ret) goto cleanup; + } + + if (lpszSubKey) + ret = RegDeleteKeyW(hKey, lpszSubKey); + else + while (TRUE) + { + dwSize = dwMaxLen; + if (RegEnumValueW(hKey, 0, lpszName, &dwSize, + NULL, NULL, NULL, NULL)) break; + + ret = RegDeleteValueW(hKey, lpszName); + if (ret) goto cleanup; + } + +cleanup: + /* Free buffer if allocated */ + if (lpszName != szNameBuf) + HeapFree( GetProcessHeap(), 0, lpszName); + if(lpszSubKey) + RegCloseKey(hSubKey); + return ret; +} +#endif + +/* + * SetupRegisterClass() + */ +static HRESULT SetupRegisterClass(HKEY clsid, LPCWSTR szCLSID, + LPCWSTR szDescription, + LPCWSTR szFileName, + LPCWSTR szServerType, + LPCWSTR szThreadingModel) +{ + HKEY hkey, hsubkey = NULL; + LONG ret = RegCreateKeyW(clsid, szCLSID, &hkey); + if (ERROR_SUCCESS != ret) + return HRESULT_FROM_WIN32(ret); + + /* set description string */ + ret = RegSetValueW(hkey, NULL, REG_SZ, szDescription, + sizeof(WCHAR) * (lstrlenW(szDescription) + 1)); + if (ERROR_SUCCESS != ret) + goto err_out; + + /* create CLSID\\{"CLSID"}\\"ServerType" key, using key to CLSID\\{"CLSID"} + passed back by last call to RegCreateKeyW(). */ + ret = RegCreateKeyW(hkey, szServerType, &hsubkey); + if (ERROR_SUCCESS != ret) + goto err_out; + + /* set server path */ + ret = RegSetValueW(hsubkey, NULL, REG_SZ, szFileName, + sizeof(WCHAR) * (lstrlenW(szFileName) + 1)); + if (ERROR_SUCCESS != ret) + goto err_out; + + /* set threading model */ + ret = RegSetValueExW(hsubkey, tmodel_keyname, 0L, REG_SZ, + (const BYTE*)szThreadingModel, + sizeof(WCHAR) * (lstrlenW(szThreadingModel) + 1)); +err_out: + if (hsubkey) + RegCloseKey(hsubkey); + RegCloseKey(hkey); + return HRESULT_FROM_WIN32(ret); +} + +/* + * RegisterAllClasses() + */ +static HRESULT SetupRegisterAllClasses(const FactoryTemplate * pList, int num, + LPCWSTR szFileName, BOOL bRegister) +{ + HRESULT hr = NOERROR; + HKEY hkey; + OLECHAR szCLSID[CHARS_IN_GUID]; + LONG i, ret = RegCreateKeyW(HKEY_CLASSES_ROOT, clsid_keyname, &hkey); + if (ERROR_SUCCESS != ret) + return HRESULT_FROM_WIN32(ret); + + for (i = 0; i < num; i++, pList++) + { + /* (un)register CLSID and InprocServer32 */ + hr = StringFromGUID2(pList->m_ClsID, szCLSID, CHARS_IN_GUID); + if (SUCCEEDED(hr)) + { + if (bRegister ) + hr = SetupRegisterClass(hkey, szCLSID, + pList->m_Name, szFileName, + ips32_keyname, tmodel_both); + else + hr = RegDeleteTreeW(hkey, szCLSID); + } + } + RegCloseKey(hkey); + return hr; +} + +HRESULT WINAPI AMovieSetupRegisterFilter2(const AMOVIESETUP_FILTER *pFilter, IFilterMapper2 *pIFM2, BOOL bRegister) +{ + if (!pFilter) + return S_OK; + + if (bRegister) + { + { + REGFILTER2 rf2; + rf2.dwVersion = 1; + rf2.dwMerit = pFilter->merit; + rf2.cPins = pFilter->pins; + rf2.rgPins = pFilter->pPin; + + return IFilterMapper2_RegisterFilter(pIFM2, pFilter->clsid, pFilter->name, NULL, &CLSID_LegacyAmFilterCategory, NULL, &rf2); + } + } + else + return IFilterMapper2_UnregisterFilter(pIFM2, &CLSID_LegacyAmFilterCategory, NULL, pFilter->clsid); +} + +HRESULT WINAPI AMovieDllRegisterServer2(BOOL bRegister) +{ + HRESULT hr; + int i; + IFilterMapper2 *pIFM2 = NULL; + WCHAR szFileName[MAX_PATH]; + + if (!GetModuleFileNameW(g_hInst, szFileName, MAX_PATH)) + { + ERR("Failed to get module file name for registration\n"); + return E_FAIL; + } + + if (bRegister) + hr = SetupRegisterAllClasses(g_Templates, g_cTemplates, szFileName, TRUE ); + + hr = CoInitialize(NULL); + + TRACE("Getting IFilterMapper2\r\n"); + hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void **)&pIFM2); + + for (i = 0; SUCCEEDED(hr) && i < g_cTemplates; i++) + hr = AMovieSetupRegisterFilter2(g_Templates[i].m_pAMovieSetup_Filter, pIFM2, bRegister); + + /* release interface */ + if (pIFM2) + IFilterMapper2_Release(pIFM2); + + /* and clear up */ + CoFreeUnusedLibraries(); + CoUninitialize(); + + /* if unregistering, unregister all OLE servers */ + if (SUCCEEDED(hr) && !bRegister) + hr = SetupRegisterAllClasses(g_Templates, g_cTemplates, szFileName, FALSE); + + return hr; +} + +/**************************************************************************** + * SetupInitializeServers + * + * This function is table driven using the static members of the + * CFactoryTemplate class defined in the Dll. + * + * It calls the initialize function for any class in CFactoryTemplate with + * one defined. + * + ****************************************************************************/ +static void SetupInitializeServers(const FactoryTemplate * pList, int num, + BOOL bLoading) +{ + int i; + + for (i = 0; i < num; i++, pList++) + { + if (pList->m_lpfnInit) + pList->m_lpfnInit(bLoading, pList->m_ClsID); + } +} + +BOOL WINAPI STRMBASE_DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + g_hInst = hInstDLL; + DisableThreadLibraryCalls(hInstDLL); + SetupInitializeServers(g_Templates, g_cTemplates, TRUE); + break; + case DLL_PROCESS_DETACH: + SetupInitializeServers(g_Templates, g_cTemplates, FALSE); + break; + } + return TRUE; +} + +/****************************************************************************** + * DLL ClassFactory + */ +typedef struct { + IClassFactory IClassFactory_iface; + LONG ref; + LPFNNewCOMObject pfnCreateInstance; +} IClassFactoryImpl; + +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + +static HRESULT WINAPI DSCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *ppobj = iface; + return S_OK; + } + + *ppobj = NULL; + WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI DSCF_AddRef(IClassFactory *iface) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI DSCF_Release(IClassFactory *iface) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, + REFIID riid, void **ppobj) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + HRESULT hres = ERROR_SUCCESS; + LPUNKNOWN punk; + + TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj); + + if (!ppobj) + return E_POINTER; + + /* Enforce the normal OLE rules regarding interfaces and delegation */ + if (pOuter && !IsEqualGUID(riid, &IID_IUnknown)) + return E_NOINTERFACE; + + *ppobj = NULL; + punk = This->pfnCreateInstance(pOuter, &hres); + if (!punk) + { + /* No object created, update error if it isn't done already and return */ + if (SUCCEEDED(hres)) + hres = E_OUTOFMEMORY; + return hres; + } + + if (SUCCEEDED(hres)) + { + hres = IUnknown_QueryInterface(punk, riid, ppobj); + } + /* Releasing the object. If everything was successful, QueryInterface + should have incremented the refcount once more, otherwise this will + purge the object. */ + IUnknown_Release(punk); + return hres; +} + +static HRESULT WINAPI DSCF_LockServer(IClassFactory *iface, BOOL dolock) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); + TRACE("(%p)->(%d)\n",This, dolock); + + if (dolock) + InterlockedIncrement(&server_locks); + else + InterlockedDecrement(&server_locks); + return S_OK; +} + +static const IClassFactoryVtbl DSCF_Vtbl = +{ + DSCF_QueryInterface, + DSCF_AddRef, + DSCF_Release, + DSCF_CreateInstance, + DSCF_LockServer +}; + +/*********************************************************************** + * DllGetClassObject + */ +HRESULT WINAPI STRMBASE_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + const FactoryTemplate *pList = g_Templates; + IClassFactoryImpl *factory; + int i; + + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if (!ppv) + return E_POINTER; + + *ppv = NULL; + + if (!IsEqualGUID(&IID_IClassFactory, riid) && + !IsEqualGUID(&IID_IUnknown, riid)) + return E_NOINTERFACE; + + for (i = 0; i < g_cTemplates; i++, pList++) + { + if (IsEqualGUID(pList->m_ClsID, rclsid)) + break; + } + + if (i == g_cTemplates) + { + char dllname[MAX_PATH]; + if (!GetModuleFileNameA(g_hInst, dllname, sizeof(dllname))) + strcpy(dllname, "???"); + ERR("%s: no class found in %s.\n", debugstr_guid(rclsid), dllname); + return CLASS_E_CLASSNOTAVAILABLE; + } + else if (!pList->m_lpfnNew) + { + FIXME("%s: class not implemented yet.\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; + } + + factory = HeapAlloc(GetProcessHeap(), 0, sizeof(IClassFactoryImpl)); + if (!factory) + return E_OUTOFMEMORY; + + factory->IClassFactory_iface.lpVtbl = &DSCF_Vtbl; + factory->ref = 1; + + factory->pfnCreateInstance = pList->m_lpfnNew; + + *ppv = &factory->IClassFactory_iface; + return S_OK; +} + +/*********************************************************************** + * DllCanUnloadNow + */ +HRESULT WINAPI STRMBASE_DllCanUnloadNow(void) +{ + TRACE("\n"); + + if (server_locks == 0) + return S_OK; + return S_FALSE; +} diff --git a/dll/directx/quartz/enumpins.c b/lib/3rdparty/strmbase/enumpins.c similarity index 63% rename from dll/directx/quartz/enumpins.c rename to lib/3rdparty/strmbase/enumpins.c index 7f3c6440df5..eab4d5b0e8a 100644 --- a/dll/directx/quartz/enumpins.c +++ b/lib/3rdparty/strmbase/enumpins.c @@ -2,6 +2,7 @@ * Implementation of IEnumPins Interface * * Copyright 2003 Robert Shearman + * Copyright 2010 Aric Stewart, CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,25 +19,34 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "quartz_private.h" +#define COBJMACROS -#include +#include "dshow.h" +#include "wine/strmbase.h" +#include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(quartz); +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); typedef struct IEnumPinsImpl { - const IEnumPinsVtbl * lpVtbl; + IEnumPins IEnumPins_iface; LONG refCount; ULONG uIndex; - IBaseFilter *base; - FNOBTAINPIN receive_pin; - DWORD synctime; + BaseFilter *base; + BaseFilter_GetPin receive_pin; + BaseFilter_GetPinCount receive_pincount; + BaseFilter_GetPinVersion receive_version; + DWORD Version; } IEnumPinsImpl; +static inline IEnumPinsImpl *impl_from_IEnumPins(IEnumPins *iface) +{ + return CONTAINING_RECORD(iface, IEnumPinsImpl, IEnumPins_iface); +} + static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl; -HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base) +HRESULT WINAPI EnumPins_Construct(BaseFilter *base, BaseFilter_GetPin receive_pin, BaseFilter_GetPinCount receive_pincount, BaseFilter_GetPinVersion receive_version, IEnumPins ** ppEnum) { IEnumPinsImpl * pEnumPins; @@ -49,15 +59,16 @@ HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IB *ppEnum = NULL; return E_OUTOFMEMORY; } - pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl; + pEnumPins->IEnumPins_iface.lpVtbl = &IEnumPinsImpl_Vtbl; pEnumPins->refCount = 1; pEnumPins->uIndex = 0; pEnumPins->receive_pin = receive_pin; + pEnumPins->receive_pincount = receive_pincount; + pEnumPins->receive_version = receive_version; pEnumPins->base = base; - IBaseFilter_AddRef(base); - *ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl); - - receive_pin(base, ~0, NULL, &pEnumPins->synctime); + IBaseFilter_AddRef(&base->IBaseFilter_iface); + *ppEnum = &pEnumPins->IEnumPins_iface; + pEnumPins->Version = receive_version(base); TRACE("Created new enumerator (%p)\n", *ppEnum); return S_OK; @@ -65,7 +76,7 @@ HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IB static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID riid, LPVOID * ppv) { - TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); *ppv = NULL; @@ -80,14 +91,14 @@ static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID rii return S_OK; } - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); + FIXME("No interface for %s!\n", debugstr_guid(riid)); return E_NOINTERFACE; } static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface) { - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; + IEnumPinsImpl *This = impl_from_IEnumPins(iface); ULONG refCount = InterlockedIncrement(&This->refCount); TRACE("(%p)->() AddRef from %d\n", This, refCount - 1); @@ -97,14 +108,14 @@ static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface) static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface) { - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; + IEnumPinsImpl *This = impl_from_IEnumPins(iface); ULONG refCount = InterlockedDecrement(&This->refCount); TRACE("(%p)->() Release from %d\n", This, refCount + 1); if (!refCount) { - IBaseFilter_Release(This->base); + IBaseFilter_Release(&This->base->IBaseFilter_iface); CoTaskMemFree(This); return 0; } @@ -114,8 +125,7 @@ static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface) static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** ppPins, ULONG * pcFetched) { - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - DWORD synctime = This->synctime; + IEnumPinsImpl *This = impl_from_IEnumPins(iface); HRESULT hr = S_OK; ULONG i = 0; @@ -130,20 +140,21 @@ static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** if (pcFetched) *pcFetched = 0; + if (This->Version != This->receive_version(This->base)) + return VFW_E_ENUM_OUT_OF_SYNC; + while (i < cPins && hr == S_OK) { - hr = This->receive_pin(This->base, This->uIndex + i, &ppPins[i], &synctime); + IPin *pin; + pin = This->receive_pin(This->base, This->uIndex + i); - if (hr == S_OK) - ++i; - - if (synctime != This->synctime) - break; + if (!pin) + break; + else + ppPins[i] = pin; + ++i; } - if (!i && synctime != This->synctime) - return VFW_E_ENUM_OUT_OF_SYNC; - if (pcFetched) *pcFetched = i; This->uIndex += i; @@ -155,32 +166,26 @@ static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins) { - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - DWORD synctime = This->synctime; - HRESULT hr; - IPin *pin = NULL; + IEnumPinsImpl *This = impl_from_IEnumPins(iface); TRACE("(%u)\n", cPins); - hr = This->receive_pin(This->base, This->uIndex + cPins, &pin, &synctime); - if (pin) - IPin_Release(pin); - - if (synctime != This->synctime) + if (This->Version != This->receive_version(This->base)) return VFW_E_ENUM_OUT_OF_SYNC; - if (hr == S_OK) - This->uIndex += cPins; + if (This->receive_pincount(This->base) >= This->uIndex + cPins) + return S_FALSE; - return hr; + This->uIndex += cPins; + return S_OK; } static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface) { - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; + IEnumPinsImpl *This = impl_from_IEnumPins(iface); TRACE("IEnumPinsImpl::Reset()\n"); - This->receive_pin(This->base, ~0, NULL, &This->synctime); + This->Version = This->receive_version(This->base); This->uIndex = 0; return S_OK; @@ -189,11 +194,11 @@ static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface) static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins * iface, IEnumPins ** ppEnum) { HRESULT hr; - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; + IEnumPinsImpl *This = impl_from_IEnumPins(iface); TRACE("(%p)\n", ppEnum); - hr = IEnumPinsImpl_Construct(ppEnum, This->receive_pin, This->base); + hr = EnumPins_Construct(This->base, This->receive_pin, This->receive_pincount, This->receive_version, ppEnum); if (FAILED(hr)) return hr; return IEnumPins_Skip(*ppEnum, This->uIndex); diff --git a/lib/3rdparty/strmbase/filter.c b/lib/3rdparty/strmbase/filter.c new file mode 100644 index 00000000000..67f7c9ff226 --- /dev/null +++ b/lib/3rdparty/strmbase/filter.c @@ -0,0 +1,228 @@ +/* + * Generic Implementation of IBaseFilter Interface + * + * Copyright 2010 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static inline BaseFilter *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface); +} + +HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv); + + *ppv = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = This; + else if (IsEqualIID(riid, &IID_IPersist)) + *ppv = This; + else if (IsEqualIID(riid, &IID_IMediaFilter)) + *ppv = This; + else if (IsEqualIID(riid, &IID_IBaseFilter)) + *ppv = This; + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + ULONG refCount = InterlockedIncrement(&This->refCount); + + TRACE("(%p)->() AddRef from %d\n", This, refCount - 1); + + return refCount; +} + +ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + ULONG refCount = InterlockedDecrement(&This->refCount); + + TRACE("(%p)->() Release from %d\n", This, refCount + 1); + + if (!refCount) + { + if (This->pClock) + IReferenceClock_Release(This->pClock); + + This->IBaseFilter_iface.lpVtbl = NULL; + This->csFilter.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->csFilter); + } + + return refCount; +} + +HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%p)\n", This, pClsid); + + *pClsid = This->clsid; + + return S_OK; +} + +HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState ) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState); + + EnterCriticalSection(&This->csFilter); + { + *pState = This->state; + } + LeaveCriticalSection(&This->csFilter); + + return S_OK; +} + +HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%p)\n", This, pClock); + + EnterCriticalSection(&This->csFilter); + { + if (This->pClock) + IReferenceClock_Release(This->pClock); + This->pClock = pClock; + if (This->pClock) + IReferenceClock_AddRef(This->pClock); + } + LeaveCriticalSection(&This->csFilter); + + return S_OK; +} + +HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%p)\n", This, ppClock); + + EnterCriticalSection(&This->csFilter); + { + *ppClock = This->pClock; + if (This->pClock) + IReferenceClock_AddRef(This->pClock); + } + LeaveCriticalSection(&This->csFilter); + + return S_OK; +} + +HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + + TRACE("(%p)->(%p)\n", iface, ppEnum); + + return EnumPins_Construct(This, This->pFuncsTable->pfnGetPin, This->pFuncsTable->pfnGetPinCount, BaseFilterImpl_GetPinVersion, ppEnum); +} + + +HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo) +{ + BaseFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%p)\n", This, pInfo); + + strcpyW(pInfo->achName, This->filterInfo.achName); + pInfo->pGraph = This->filterInfo.pGraph; + + if (pInfo->pGraph) + IFilterGraph_AddRef(pInfo->pGraph); + + return S_OK; +} + +HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName ) +{ + HRESULT hr = S_OK; + BaseFilter *This = impl_from_IBaseFilter(iface); + + TRACE("(%p)->(%p, %s)\n", This, pGraph, debugstr_w(pName)); + + EnterCriticalSection(&This->csFilter); + { + if (pName) + strcpyW(This->filterInfo.achName, pName); + else + *This->filterInfo.achName = '\0'; + This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */ + } + LeaveCriticalSection(&This->csFilter); + + return hr; +} + +HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo) +{ + TRACE("(%p)->(%p)\n", iface, pVendorInfo); + return E_NOTIMPL; +} + +LONG WINAPI BaseFilterImpl_GetPinVersion(BaseFilter * This) +{ + TRACE("(%p)\n", This); + return This->pinVersion; +} + +VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter * This) +{ + InterlockedIncrement(&This->pinVersion); + TRACE("(%p) -> New pinVersion %i\n", This,This->pinVersion); +} + +HRESULT WINAPI BaseFilter_Init(BaseFilter * This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseFilterFuncTable* pBaseFuncsTable) +{ + This->IBaseFilter_iface.lpVtbl = Vtbl; + This->refCount = 1; + InitializeCriticalSection(&This->csFilter); + This->state = State_Stopped; + This->rtStreamStart = 0; + This->pClock = NULL; + ZeroMemory(&This->filterInfo, sizeof(FILTER_INFO)); + This->clsid = *pClsid; + This->csFilter.DebugInfo->Spare[0] = DebugInfo; + This->pinVersion = 1; + + This->pFuncsTable = pBaseFuncsTable; + + return S_OK; +} diff --git a/lib/3rdparty/strmbase/mediatype.c b/lib/3rdparty/strmbase/mediatype.c new file mode 100644 index 00000000000..d100cc9e8c9 --- /dev/null +++ b/lib/3rdparty/strmbase/mediatype.c @@ -0,0 +1,307 @@ +/* + * Implementation of MedaType utility functions + * + * Copyright 2003 Robert Shearman + * Copyright 2010 Aric Stewart, CodeWeavers + * + * 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 + */ +#include + +#define COBJMACROS +#include "dshow.h" + +#include "wine/strmbase.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *dest, const AM_MEDIA_TYPE *src) +{ + *dest = *src; + if (src->pbFormat) + { + dest->pbFormat = CoTaskMemAlloc(src->cbFormat); + if (!dest->pbFormat) + return E_OUTOFMEMORY; + memcpy(dest->pbFormat, src->pbFormat, src->cbFormat); + } + if (dest->pUnk) + IUnknown_AddRef(dest->pUnk); + return S_OK; +} + +void WINAPI FreeMediaType(AM_MEDIA_TYPE * pMediaType) +{ + if (pMediaType->pbFormat) + { + CoTaskMemFree(pMediaType->pbFormat); + pMediaType->pbFormat = NULL; + } + if (pMediaType->pUnk) + { + IUnknown_Release(pMediaType->pUnk); + pMediaType->pUnk = NULL; + } +} + +AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const * pSrc) +{ + AM_MEDIA_TYPE * pDest; + + pDest = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); + if (!pDest) + return NULL; + + if (FAILED(CopyMediaType(pDest, pSrc))) + { + CoTaskMemFree(pDest); + return NULL; + } + + return pDest; +} + +void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType) +{ + FreeMediaType(pMediaType); + CoTaskMemFree(pMediaType); +} + +typedef struct tagENUMEDIADETAILS +{ + ULONG cMediaTypes; + AM_MEDIA_TYPE * pMediaTypes; +} ENUMMEDIADETAILS; + +typedef struct IEnumMediaTypesImpl +{ + IEnumMediaTypes IEnumMediaTypes_iface; + LONG refCount; + BasePin *basePin; + BasePin_GetMediaType enumMediaFunction; + BasePin_GetMediaTypeVersion mediaVersionFunction; + LONG currentVersion; + ENUMMEDIADETAILS enumMediaDetails; + ULONG uIndex; +} IEnumMediaTypesImpl; + +static inline IEnumMediaTypesImpl *impl_from_IEnumMediaTypes(IEnumMediaTypes *iface) +{ + return CONTAINING_RECORD(iface, IEnumMediaTypesImpl, IEnumMediaTypes_iface); +} + +static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl; + +HRESULT WINAPI EnumMediaTypes_Construct(BasePin *basePin, BasePin_GetMediaType enumFunc, BasePin_GetMediaTypeVersion versionFunc, IEnumMediaTypes ** ppEnum) +{ + ULONG i; + IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl)); + AM_MEDIA_TYPE amt; + + if (!pEnumMediaTypes) + { + *ppEnum = NULL; + return E_OUTOFMEMORY; + } + pEnumMediaTypes->IEnumMediaTypes_iface.lpVtbl = &IEnumMediaTypesImpl_Vtbl; + pEnumMediaTypes->refCount = 1; + pEnumMediaTypes->uIndex = 0; + pEnumMediaTypes->enumMediaFunction = enumFunc; + pEnumMediaTypes->mediaVersionFunction = versionFunc; + IPin_AddRef(&basePin->IPin_iface); + pEnumMediaTypes->basePin = basePin; + + i = 0; + while (enumFunc(basePin, i, &amt) == S_OK) i++; + + pEnumMediaTypes->enumMediaDetails.cMediaTypes = i; + pEnumMediaTypes->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * i); + for (i = 0; i < pEnumMediaTypes->enumMediaDetails.cMediaTypes; i++) + { + enumFunc(basePin,i,&amt); + if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &amt))) + { + while (i--) + FreeMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i]); + CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes); + return E_OUTOFMEMORY; + } + } + *ppEnum = &pEnumMediaTypes->IEnumMediaTypes_iface; + pEnumMediaTypes->currentVersion = versionFunc(basePin); + return S_OK; +} + +static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, REFIID riid, void ** ret_iface) +{ + TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IEnumMediaTypes)) + { + IEnumMediaTypes_AddRef(iface); + *ret_iface = iface; + return S_OK; + } + + *ret_iface = NULL; + + WARN("No interface for %s\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface) +{ + IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface); + ULONG ref = InterlockedIncrement(&This->refCount); + + TRACE("(%p)->(): new ref = %u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface) +{ + IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface); + ULONG ref = InterlockedDecrement(&This->refCount); + + TRACE("(%p)->(): new ref = %u\n", iface, ref); + + if (!ref) + { + ULONG i; + for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++) + FreeMediaType(&This->enumMediaDetails.pMediaTypes[i]); + CoTaskMemFree(This->enumMediaDetails.pMediaTypes); + IPin_Release(&This->basePin->IPin_iface); + CoTaskMemFree(This); + } + return ref; +} + +static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched) +{ + ULONG cFetched; + IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface); + + TRACE("(%p)->(%u, %p, %p)\n", iface, cMediaTypes, ppMediaTypes, pcFetched); + + cFetched = min(This->enumMediaDetails.cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex; + + if (This->currentVersion != This->mediaVersionFunction(This->basePin)) + return VFW_E_ENUM_OUT_OF_SYNC; + + TRACE("Next uIndex: %u, cFetched: %u\n", This->uIndex, cFetched); + + if (cFetched > 0) + { + ULONG i; + for (i = 0; i < cFetched; i++) + if (!(ppMediaTypes[i] = CreateMediaType(&This->enumMediaDetails.pMediaTypes[This->uIndex + i]))) + { + while (i--) + DeleteMediaType(ppMediaTypes[i]); + *pcFetched = 0; + return E_OUTOFMEMORY; + } + } + + if ((cMediaTypes != 1) || pcFetched) + *pcFetched = cFetched; + + This->uIndex += cFetched; + + if (cFetched != cMediaTypes) + return S_FALSE; + return S_OK; +} + +static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes) +{ + IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface); + + TRACE("(%p)->(%u)\n", iface, cMediaTypes); + + if (This->currentVersion != This->mediaVersionFunction(This->basePin)) + return VFW_E_ENUM_OUT_OF_SYNC; + + if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes) + { + This->uIndex += cMediaTypes; + return S_OK; + } + return S_FALSE; +} + +static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface) +{ + ULONG i; + AM_MEDIA_TYPE amt; + IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface); + + TRACE("(%p)->()\n", iface); + + for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++) + FreeMediaType(&This->enumMediaDetails.pMediaTypes[i]); + CoTaskMemFree(This->enumMediaDetails.pMediaTypes); + + i = 0; + while (This->enumMediaFunction(This->basePin, i, &amt) == S_OK) i++; + + This->enumMediaDetails.cMediaTypes = i; + This->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * i); + for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++) + { + This->enumMediaFunction(This->basePin, i,&amt); + if (FAILED(CopyMediaType(&This->enumMediaDetails.pMediaTypes[i], &amt))) + { + while (i--) + FreeMediaType(&This->enumMediaDetails.pMediaTypes[i]); + CoTaskMemFree(This->enumMediaDetails.pMediaTypes); + return E_OUTOFMEMORY; + } + } + + This->currentVersion = This->mediaVersionFunction(This->basePin); + This->uIndex = 0; + + return S_OK; +} + +static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum) +{ + HRESULT hr; + IEnumMediaTypesImpl *This = impl_from_IEnumMediaTypes(iface); + + TRACE("(%p)->(%p)\n", iface, ppEnum); + + hr = EnumMediaTypes_Construct(This->basePin, This->enumMediaFunction, This->mediaVersionFunction, ppEnum); + if (FAILED(hr)) + return hr; + return IEnumMediaTypes_Skip(*ppEnum, This->uIndex); +} + +static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl = +{ + IEnumMediaTypesImpl_QueryInterface, + IEnumMediaTypesImpl_AddRef, + IEnumMediaTypesImpl_Release, + IEnumMediaTypesImpl_Next, + IEnumMediaTypesImpl_Skip, + IEnumMediaTypesImpl_Reset, + IEnumMediaTypesImpl_Clone +}; diff --git a/lib/3rdparty/strmbase/outputqueue.c b/lib/3rdparty/strmbase/outputqueue.c new file mode 100644 index 00000000000..cbcd9640766 --- /dev/null +++ b/lib/3rdparty/strmbase/outputqueue.c @@ -0,0 +1,310 @@ +/* + * Generic Implementation of COutputQueue + * + * Copyright 2011 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/list.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +enum {SAMPLE_PACKET, EOS_PACKET}; + +typedef struct tagQueuedEvent { + int type; + struct list entry; + + IMediaSample *pSample; +} QueuedEvent; + +static DWORD WINAPI OutputQueue_InitialThreadProc(LPVOID data) +{ + OutputQueue *This = (OutputQueue *)data; + return This->pFuncsTable->pfnThreadProc(This); +} + +static void OutputQueue_FreeSamples(OutputQueue *pOutputQueue) +{ + struct list *cursor, *cursor2; + LIST_FOR_EACH_SAFE(cursor, cursor2, pOutputQueue->SampleList) + { + QueuedEvent *qev = LIST_ENTRY(cursor, QueuedEvent, entry); + list_remove(cursor); + HeapFree(GetProcessHeap(),0,qev); + } +} + +HRESULT WINAPI OutputQueue_Construct( + BaseOutputPin *pInputPin, + BOOL bAuto, + BOOL bQueue, + LONG lBatchSize, + BOOL bBatchExact, + DWORD dwPriority, + const OutputQueueFuncTable* pFuncsTable, + OutputQueue **ppOutputQueue ) + +{ + HRESULT hr = S_OK; + BOOL threaded = FALSE; + DWORD tid; + + OutputQueue *This; + + if (!pInputPin || !pFuncsTable || !ppOutputQueue) + return E_INVALIDARG; + + *ppOutputQueue = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OutputQueue)); + if (!*ppOutputQueue) + return E_OUTOFMEMORY; + + This = *ppOutputQueue; + This->pFuncsTable = pFuncsTable; + This->lBatchSize = lBatchSize; + This->bBatchExact = bBatchExact; + InitializeCriticalSection(&This->csQueue); + This->csQueue.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OutputQueue.csQueue"); + This->SampleList = HeapAlloc(GetProcessHeap(),0,sizeof(struct list)); + if (!This->SampleList) + { + OutputQueue_Destroy(This); + *ppOutputQueue = NULL; + return E_OUTOFMEMORY; + } + list_init(This->SampleList); + + This->pInputPin = pInputPin; + IPin_AddRef(&pInputPin->pin.IPin_iface); + + EnterCriticalSection(&This->csQueue); + if (bAuto && pInputPin->pMemInputPin) + threaded = IMemInputPin_ReceiveCanBlock(pInputPin->pMemInputPin); + else + threaded = bQueue; + + if (threaded) + { + This->hThread = CreateThread(NULL, 0, OutputQueue_InitialThreadProc, This, 0, &tid); + if (This->hThread) + { + SetThreadPriority(This->hThread, dwPriority); + This->hProcessQueue = CreateEventW(NULL, 0, 0, NULL); + } + } + LeaveCriticalSection(&This->csQueue); + + return hr; +} + +HRESULT WINAPI OutputQueue_Destroy(OutputQueue *pOutputQueue) +{ + EnterCriticalSection(&pOutputQueue->csQueue); + OutputQueue_FreeSamples(pOutputQueue); + pOutputQueue->bTerminate = TRUE; + SetEvent(pOutputQueue->hProcessQueue); + LeaveCriticalSection(&pOutputQueue->csQueue); + + pOutputQueue->csQueue.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&pOutputQueue->csQueue); + CloseHandle(pOutputQueue->hProcessQueue); + + HeapFree(GetProcessHeap(),0,pOutputQueue->SampleList); + + IPin_Release(&pOutputQueue->pInputPin->pin.IPin_iface); + HeapFree(GetProcessHeap(),0,pOutputQueue); + return S_OK; +} + +HRESULT WINAPI OutputQueue_ReceiveMultiple(OutputQueue *pOutputQueue, IMediaSample **ppSamples, LONG nSamples, LONG *nSamplesProcessed) +{ + HRESULT hr = S_OK; + int i; + + if (!pOutputQueue->pInputPin->pin.pConnectedTo || !pOutputQueue->pInputPin->pMemInputPin) + return VFW_E_NOT_CONNECTED; + + if (!pOutputQueue->hThread) + { + IMemInputPin_AddRef(pOutputQueue->pInputPin->pMemInputPin); + hr = IMemInputPin_ReceiveMultiple(pOutputQueue->pInputPin->pMemInputPin,ppSamples, nSamples, nSamplesProcessed); + IMemInputPin_Release(pOutputQueue->pInputPin->pMemInputPin); + } + else + { + EnterCriticalSection(&pOutputQueue->csQueue); + *nSamplesProcessed = 0; + + for (i = 0; i < nSamples; i++) + { + QueuedEvent *qev = HeapAlloc(GetProcessHeap(),0,sizeof(QueuedEvent)); + if (!qev) + { + ERR("Out of Memory\n"); + hr = E_OUTOFMEMORY; + break; + } + qev->type = SAMPLE_PACKET; + qev->pSample = ppSamples[i]; + IMediaSample_AddRef(ppSamples[i]); + list_add_tail(pOutputQueue->SampleList, &qev->entry); + (*nSamplesProcessed)++; + } + + if (!pOutputQueue->bBatchExact || list_count(pOutputQueue->SampleList) >= pOutputQueue->lBatchSize) + SetEvent(pOutputQueue->hProcessQueue); + LeaveCriticalSection(&pOutputQueue->csQueue); + } + return hr; +} + +HRESULT WINAPI OutputQueue_Receive(OutputQueue *pOutputQueue, IMediaSample *pSample) +{ + LONG processed; + return OutputQueue_ReceiveMultiple(pOutputQueue,&pSample,1,&processed); +} + +VOID WINAPI OutputQueue_SendAnyway(OutputQueue *pOutputQueue) +{ + if (pOutputQueue->hThread) + { + EnterCriticalSection(&pOutputQueue->csQueue); + if (!list_empty(pOutputQueue->SampleList)) + { + pOutputQueue->bSendAnyway = TRUE; + SetEvent(pOutputQueue->hProcessQueue); + } + LeaveCriticalSection(&pOutputQueue->csQueue); + } +} + +VOID WINAPI OutputQueue_EOS(OutputQueue *pOutputQueue) +{ + EnterCriticalSection(&pOutputQueue->csQueue); + if (pOutputQueue->hThread) + { + QueuedEvent *qev = HeapAlloc(GetProcessHeap(),0,sizeof(QueuedEvent)); + if (!qev) + { + ERR("Out of Memory\n"); + LeaveCriticalSection(&pOutputQueue->csQueue); + return; + } + qev->type = EOS_PACKET; + qev->pSample = NULL; + list_add_tail(pOutputQueue->SampleList, &qev->entry); + } + else + { + IPin* ppin = NULL; + IPin_ConnectedTo(&pOutputQueue->pInputPin->pin.IPin_iface, &ppin); + if (ppin) + { + IPin_EndOfStream(ppin); + IPin_Release(ppin); + } + } + LeaveCriticalSection(&pOutputQueue->csQueue); + /* Covers sending the Event to the worker Thread */ + OutputQueue_SendAnyway(pOutputQueue); +} + +DWORD WINAPI OutputQueueImpl_ThreadProc(OutputQueue *pOutputQueue) +{ + do + { + EnterCriticalSection(&pOutputQueue->csQueue); + if (!list_empty(pOutputQueue->SampleList) && + (!pOutputQueue->bBatchExact || + list_count(pOutputQueue->SampleList) >= pOutputQueue->lBatchSize || + pOutputQueue->bSendAnyway + ) + ) + { + while (!list_empty(pOutputQueue->SampleList)) + { + IMediaSample **ppSamples; + LONG nSamples; + LONG nSamplesProcessed; + struct list *cursor, *cursor2; + int i = 0; + + /* First Pass Process Samples */ + i = list_count(pOutputQueue->SampleList); + ppSamples = HeapAlloc(GetProcessHeap(),0,sizeof(IMediaSample*) * i); + nSamples = 0; + LIST_FOR_EACH_SAFE(cursor, cursor2, pOutputQueue->SampleList) + { + QueuedEvent *qev = LIST_ENTRY(cursor, QueuedEvent, entry); + if (qev->type == SAMPLE_PACKET) + ppSamples[nSamples++] = qev->pSample; + else + break; + list_remove(cursor); + HeapFree(GetProcessHeap(),0,qev); + } + + if (pOutputQueue->pInputPin->pin.pConnectedTo && pOutputQueue->pInputPin->pMemInputPin) + { + IMemInputPin_AddRef(pOutputQueue->pInputPin->pMemInputPin); + LeaveCriticalSection(&pOutputQueue->csQueue); + IMemInputPin_ReceiveMultiple(pOutputQueue->pInputPin->pMemInputPin, ppSamples, nSamples, &nSamplesProcessed); + EnterCriticalSection(&pOutputQueue->csQueue); + IMemInputPin_Release(pOutputQueue->pInputPin->pMemInputPin); + } + for (i = 0; i < nSamples; i++) + IMediaSample_Release(ppSamples[i]); + HeapFree(GetProcessHeap(),0,ppSamples); + + /* Process Non-Samples */ + LIST_FOR_EACH_SAFE(cursor, cursor2, pOutputQueue->SampleList) + { + QueuedEvent *qev = LIST_ENTRY(cursor, QueuedEvent, entry); + if (qev->type == EOS_PACKET) + { + IPin* ppin = NULL; + IPin_ConnectedTo(&pOutputQueue->pInputPin->pin.IPin_iface, &ppin); + if (ppin) + { + IPin_EndOfStream(ppin); + IPin_Release(ppin); + } + } + else if (qev->type == SAMPLE_PACKET) + break; + else + FIXME("Unhandled Event type %i\n",qev->type); + list_remove(cursor); + HeapFree(GetProcessHeap(),0,qev); + } + } + pOutputQueue->bSendAnyway = FALSE; + } + LeaveCriticalSection(&pOutputQueue->csQueue); + WaitForSingleObject(pOutputQueue->hProcessQueue, INFINITE); + } + while (!pOutputQueue->bTerminate); + return S_OK; +} diff --git a/lib/3rdparty/strmbase/pin.c b/lib/3rdparty/strmbase/pin.c new file mode 100644 index 00000000000..750752e733e --- /dev/null +++ b/lib/3rdparty/strmbase/pin.c @@ -0,0 +1,1269 @@ +/* + * Generic Implementation of IPin Interface + * + * Copyright 2003 Robert Shearman + * Copyright 2010 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static const IPinVtbl InputPin_Vtbl; +static const IPinVtbl OutputPin_Vtbl; +static const IMemInputPinVtbl MemInputPin_Vtbl; + +typedef HRESULT (*SendPinFunc)( IPin *to, LPVOID arg ); + +static inline BasePin *impl_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BasePin, IPin_iface); +} + +/** Helper function, there are a lot of places where the error code is inherited + * The following rules apply: + * + * Return the first received error code (E_NOTIMPL is ignored) + * If no errors occur: return the first received non-error-code that isn't S_OK + */ +static HRESULT updatehres( HRESULT original, HRESULT new ) +{ + if (FAILED( original ) || new == E_NOTIMPL) + return original; + + if (FAILED( new ) || original == S_OK) + return new; + + return original; +} + +/** Sends a message from a pin further to other, similar pins + * fnMiddle is called on each pin found further on the stream. + * fnEnd (can be NULL) is called when the message can't be sent any further (this is a renderer or source) + * + * If the pin given is an input pin, the message will be sent downstream to other input pins + * If the pin given is an output pin, the message will be sent upstream to other output pins + */ +static HRESULT SendFurther( IPin *from, SendPinFunc fnMiddle, LPVOID arg, SendPinFunc fnEnd ) +{ + PIN_INFO pin_info; + ULONG amount = 0; + HRESULT hr = S_OK; + HRESULT hr_return = S_OK; + IEnumPins *enumpins = NULL; + BOOL foundend = TRUE; + PIN_DIRECTION from_dir; + + IPin_QueryDirection( from, &from_dir ); + + hr = IPin_QueryInternalConnections( from, NULL, &amount ); + if (hr != E_NOTIMPL && amount) + FIXME("Use QueryInternalConnections!\n"); + hr = S_OK; + + pin_info.pFilter = NULL; + hr = IPin_QueryPinInfo( from, &pin_info ); + if (FAILED(hr)) + goto out; + + hr = IBaseFilter_EnumPins( pin_info.pFilter, &enumpins ); + if (FAILED(hr)) + goto out; + + hr = IEnumPins_Reset( enumpins ); + while (hr == S_OK) { + IPin *pin = NULL; + hr = IEnumPins_Next( enumpins, 1, &pin, NULL ); + if (hr == VFW_E_ENUM_OUT_OF_SYNC) + { + hr = IEnumPins_Reset( enumpins ); + continue; + } + if (pin) + { + PIN_DIRECTION dir; + + IPin_QueryDirection( pin, &dir ); + if (dir != from_dir) + { + IPin *connected = NULL; + + foundend = FALSE; + IPin_ConnectedTo( pin, &connected ); + if (connected) + { + HRESULT hr_local; + + hr_local = fnMiddle( connected, arg ); + hr_return = updatehres( hr_return, hr_local ); + IPin_Release(connected); + } + } + IPin_Release( pin ); + } + else + { + hr = S_OK; + break; + } + } + + if (!foundend) + hr = hr_return; + else if (fnEnd) { + HRESULT hr_local; + + hr_local = fnEnd( from, arg ); + hr_return = updatehres( hr_return, hr_local ); + } + IEnumPins_Release(enumpins); + +out: + if (pin_info.pFilter) + IBaseFilter_Release( pin_info.pFilter ); + return hr; +} + +static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc) +{ + /* Tempting to just do a memcpy, but the name field is + 128 characters long! We will probably never exceed 10 + most of the time, so we are better off copying + each field manually */ + strcpyW(pDest->achName, pSrc->achName); + pDest->dir = pSrc->dir; + pDest->pFilter = pSrc->pFilter; +} + +static void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt) +{ + if (!pmt) + return; + TRACE("\t%s\n\t%s\n\t...\n\t%s\n", debugstr_guid(&pmt->majortype), debugstr_guid(&pmt->subtype), debugstr_guid(&pmt->formattype)); +} + +static BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards) +{ + TRACE("pmt1: "); + dump_AM_MEDIA_TYPE(pmt1); + TRACE("pmt2: "); + dump_AM_MEDIA_TYPE(pmt2); + return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) && + ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL) || IsEqualGUID(&pmt2->subtype, &GUID_NULL))) || IsEqualGUID(&pmt1->subtype, &pmt2->subtype))); +} + +/*** Common Base Pin function */ +HRESULT WINAPI BasePinImpl_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt) +{ + if (iPosition < 0) + return E_INVALIDARG; + return VFW_S_NO_MORE_ITEMS; +} + +LONG WINAPI BasePinImpl_GetMediaTypeVersion(BasePin *iface) +{ + return 1; +} + +ULONG WINAPI BasePinImpl_AddRef(IPin * iface) +{ + BasePin *This = impl_from_IPin(iface); + ULONG refCount = InterlockedIncrement(&This->refCount); + + TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1); + + return refCount; +} + +HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface) +{ + HRESULT hr; + BasePin *This = impl_from_IPin(iface); + + TRACE("()\n"); + + EnterCriticalSection(This->pCritSec); + { + if (This->pConnectedTo) + { + IPin_Release(This->pConnectedTo); + This->pConnectedTo = NULL; + FreeMediaType(&This->mtCurrent); + ZeroMemory(&This->mtCurrent, sizeof(This->mtCurrent)); + hr = S_OK; + } + else + hr = S_FALSE; + } + LeaveCriticalSection(This->pCritSec); + + return hr; +} + +HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin) +{ + HRESULT hr; + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p)\n", ppPin); + + EnterCriticalSection(This->pCritSec); + { + if (This->pConnectedTo) + { + *ppPin = This->pConnectedTo; + IPin_AddRef(*ppPin); + hr = S_OK; + } + else + { + hr = VFW_E_NOT_CONNECTED; + *ppPin = NULL; + } + } + LeaveCriticalSection(This->pCritSec); + + return hr; +} + +HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt) +{ + HRESULT hr; + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pmt); + + EnterCriticalSection(This->pCritSec); + { + if (This->pConnectedTo) + { + CopyMediaType(pmt, &This->mtCurrent); + hr = S_OK; + } + else + { + ZeroMemory(pmt, sizeof(*pmt)); + hr = VFW_E_NOT_CONNECTED; + } + } + LeaveCriticalSection(This->pCritSec); + + return hr; +} + +HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo) +{ + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); + + Copy_PinInfo(pInfo, &This->pinInfo); + IBaseFilter_AddRef(pInfo->pFilter); + + return S_OK; +} + +HRESULT WINAPI BasePinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir) +{ + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pPinDir); + + *pPinDir = This->pinInfo.dir; + + return S_OK; +} + +HRESULT WINAPI BasePinImpl_QueryId(IPin * iface, LPWSTR * Id) +{ + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, Id); + + *Id = CoTaskMemAlloc((strlenW(This->pinInfo.achName) + 1) * sizeof(WCHAR)); + if (!*Id) + return E_OUTOFMEMORY; + + strcpyW(*Id, This->pinInfo.achName); + + return S_OK; +} + +HRESULT WINAPI BasePinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt) +{ + TRACE("(%p)->(%p)\n", iface, pmt); + + return S_OK; +} + +HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum) +{ + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); + + /* override this method to allow enumeration of your types */ + + return EnumMediaTypes_Construct(This, This->pFuncsTable->pfnGetMediaType, This->pFuncsTable->pfnGetMediaTypeVersion , ppEnum); +} + +HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin) +{ + BasePin *This = impl_from_IPin(iface); + + TRACE("(%p/%p)->(%p, %p)\n", This, iface, apPin, cPin); + + return E_NOTIMPL; /* to tell caller that all input pins connected to all output pins */ +} + +HRESULT WINAPI BasePinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ + BasePin *This = impl_from_IPin(iface); + + TRACE("(%x%08x, %x%08x, %e)\n", (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate); + + This->tStart = tStart; + This->tStop = tStop; + This->dRate = dRate; + + return S_OK; +} + +/*** OutputPin implementation ***/ + +static inline BaseOutputPin *impl_BaseOutputPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BaseOutputPin, pin.IPin_iface); +} + +static inline BaseOutputPin *impl_BaseOutputPin_from_BasePin( BasePin *iface ) +{ + return CONTAINING_RECORD(iface, BaseOutputPin, pin); +} + +HRESULT WINAPI BaseOutputPinImpl_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) +{ + BaseOutputPin *This = impl_BaseOutputPin_from_IPin(iface); + + TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv); + + *ppv = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = iface; + else if (IsEqualIID(riid, &IID_IPin)) + *ppv = iface; + else if (IsEqualIID(riid, &IID_IMediaSeeking) || + IsEqualIID(riid, &IID_IQualityControl)) + { + return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, riid, ppv); + } + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + FIXME("No interface for %s!\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +ULONG WINAPI BaseOutputPinImpl_Release(IPin * iface) +{ + BaseOutputPin *This = impl_BaseOutputPin_from_IPin(iface); + ULONG refCount = InterlockedDecrement(&This->pin.refCount); + + TRACE("(%p)->() Release from %d\n", iface, refCount + 1); + + if (!refCount) + { + FreeMediaType(&This->pin.mtCurrent); + if (This->pAllocator) + IMemAllocator_Release(This->pAllocator); + This->pAllocator = NULL; + CoTaskMemFree(This); + return 0; + } + return refCount; +} + +HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + HRESULT hr; + BaseOutputPin *This = impl_BaseOutputPin_from_IPin(iface); + + TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt); + dump_AM_MEDIA_TYPE(pmt); + + /* If we try to connect to ourselves, we will definitely deadlock. + * There are other cases where we could deadlock too, but this + * catches the obvious case */ + assert(pReceivePin != iface); + + EnterCriticalSection(This->pin.pCritSec); + { + /* if we have been a specific type to connect with, then we can either connect + * with that or fail. We cannot choose different AM_MEDIA_TYPE */ + if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL)) + hr = This->pin.pFuncsTable->pfnAttemptConnection(&This->pin, pReceivePin, pmt); + else + { + /* negotiate media type */ + + IEnumMediaTypes * pEnumCandidates; + AM_MEDIA_TYPE * pmtCandidate = NULL; /* Candidate media type */ + + if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates))) + { + hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ + + /* try this filter's media types first */ + while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) + { + assert(pmtCandidate); + dump_AM_MEDIA_TYPE(pmtCandidate); + if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype) + && !IsEqualGUID(&GUID_NULL, &pmtCandidate->formattype)) + assert(pmtCandidate->pbFormat); + if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && + (This->pin.pFuncsTable->pfnAttemptConnection(&This->pin, pReceivePin, pmtCandidate) == S_OK)) + { + hr = S_OK; + DeleteMediaType(pmtCandidate); + break; + } + DeleteMediaType(pmtCandidate); + pmtCandidate = NULL; + } + IEnumMediaTypes_Release(pEnumCandidates); + } + + /* then try receiver filter's media types */ + if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */ + { + hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ + + while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) + { + assert(pmtCandidate); + dump_AM_MEDIA_TYPE(pmtCandidate); + if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && + (This->pin.pFuncsTable->pfnAttemptConnection(&This->pin, pReceivePin, pmtCandidate) == S_OK)) + { + hr = S_OK; + DeleteMediaType(pmtCandidate); + break; + } + DeleteMediaType(pmtCandidate); + pmtCandidate = NULL; + } /* while */ + IEnumMediaTypes_Release(pEnumCandidates); + } /* if not found */ + } /* if negotiate media type */ + } /* if succeeded */ + LeaveCriticalSection(This->pin.pCritSec); + + TRACE(" -- %x\n", hr); + return hr; +} + +HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + ERR("Incoming connection on an output pin! (%p, %p)\n", pReceivePin, pmt); + + return E_UNEXPECTED; +} + +HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface) +{ + HRESULT hr; + BaseOutputPin *This = impl_BaseOutputPin_from_IPin(iface); + + TRACE("()\n"); + + EnterCriticalSection(This->pin.pCritSec); + { + if (This->pMemInputPin) + { + IMemInputPin_Release(This->pMemInputPin); + This->pMemInputPin = NULL; + } + if (This->pin.pConnectedTo) + { + IPin_Release(This->pin.pConnectedTo); + This->pin.pConnectedTo = NULL; + FreeMediaType(&This->pin.mtCurrent); + ZeroMemory(&This->pin.mtCurrent, sizeof(This->pin.mtCurrent)); + hr = S_OK; + } + else + hr = S_FALSE; + } + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface) +{ + TRACE("()\n"); + + /* not supposed to do anything in an output pin */ + + return E_UNEXPECTED; +} + +HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface) +{ + TRACE("(%p)->()\n", iface); + + /* not supposed to do anything in an output pin */ + + return E_UNEXPECTED; +} + +HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface) +{ + TRACE("(%p)->()\n", iface); + + /* not supposed to do anything in an output pin */ + + return E_UNEXPECTED; +} + +static const IPinVtbl OutputPin_Vtbl = +{ + BaseOutputPinImpl_QueryInterface, + BasePinImpl_AddRef, + BaseOutputPinImpl_Release, + BaseOutputPinImpl_Connect, + BaseOutputPinImpl_ReceiveConnection, + BaseOutputPinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BasePinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment +}; + +HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(BaseOutputPin *This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags) +{ + HRESULT hr; + + TRACE("(%p, %p, %p, %x)\n", ppSample, tStart, tStop, dwFlags); + + if (!This->pin.pConnectedTo) + hr = VFW_E_NOT_CONNECTED; + else + { + hr = IMemAllocator_GetBuffer(This->pAllocator, ppSample, tStart, tStop, dwFlags); + + if (SUCCEEDED(hr)) + hr = IMediaSample_SetTime(*ppSample, tStart, tStop); + } + + return hr; +} + +/* replaces OutputPin_SendSample */ +HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample * pSample) +{ + HRESULT hr = S_OK; + IMemInputPin * pMemConnected = NULL; + PIN_INFO pinInfo; + + EnterCriticalSection(This->pin.pCritSec); + { + if (!This->pin.pConnectedTo || !This->pMemInputPin) + hr = VFW_E_NOT_CONNECTED; + else + { + /* we don't have the lock held when using This->pMemInputPin, + * so we need to AddRef it to stop it being deleted while we are + * using it. Same with its filter. */ + pMemConnected = This->pMemInputPin; + IMemInputPin_AddRef(pMemConnected); + hr = IPin_QueryPinInfo(This->pin.pConnectedTo, &pinInfo); + } + } + LeaveCriticalSection(This->pin.pCritSec); + + if (SUCCEEDED(hr)) + { + /* NOTE: if we are in a critical section when Receive is called + * then it causes some problems (most notably with the native Video + * Renderer) if we are re-entered for whatever reason */ + hr = IMemInputPin_Receive(pMemConnected, pSample); + + /* If the filter's destroyed, tell upstream to stop sending data */ + if(IBaseFilter_Release(pinInfo.pFilter) == 0 && SUCCEEDED(hr)) + hr = S_FALSE; + } + if (pMemConnected) + IMemInputPin_Release(pMemConnected); + + return hr; +} + +/* replaces OutputPin_CommitAllocator */ +HRESULT WINAPI BaseOutputPinImpl_Active(BaseOutputPin *This) +{ + HRESULT hr = S_OK; + + TRACE("(%p)->()\n", This); + + EnterCriticalSection(This->pin.pCritSec); + { + if (!This->pin.pConnectedTo || !This->pMemInputPin) + hr = VFW_E_NOT_CONNECTED; + else + hr = IMemAllocator_Commit(This->pAllocator); + } + LeaveCriticalSection(This->pin.pCritSec); + + TRACE("--> %08x\n", hr); + return hr; +} + +/* replaces OutputPin_DecommitAllocator */ +HRESULT WINAPI BaseOutputPinImpl_Inactive(BaseOutputPin *This) +{ + HRESULT hr = S_OK; + + TRACE("(%p)->()\n", This); + + EnterCriticalSection(This->pin.pCritSec); + { + if (!This->pin.pConnectedTo || !This->pMemInputPin) + hr = VFW_E_NOT_CONNECTED; + else + hr = IMemAllocator_Decommit(This->pAllocator); + } + LeaveCriticalSection(This->pin.pCritSec); + + TRACE("--> %08x\n", hr); + return hr; +} + +/* replaces OutputPin_DeliverDisconnect */ +HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin *This) +{ + HRESULT hr; + + TRACE("(%p)->()\n", This); + + EnterCriticalSection(This->pin.pCritSec); + { + if (!This->pin.pConnectedTo || !This->pMemInputPin) + hr = VFW_E_NOT_CONNECTED; + else + { + hr = IMemAllocator_Decommit(This->pAllocator); + + if (SUCCEEDED(hr)) + hr = IPin_Disconnect(This->pin.pConnectedTo); + } + IPin_Disconnect(&This->pin.IPin_iface); + } + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +HRESULT WINAPI BaseOutputPinImpl_InitAllocator(BaseOutputPin *This, IMemAllocator **pMemAlloc) +{ + return CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)pMemAlloc); +} + +HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc) +{ + HRESULT hr; + + hr = IMemInputPin_GetAllocator(pPin, pAlloc); + + if (hr == VFW_E_NO_ALLOCATOR) + /* Input pin provides no allocator, use standard memory allocator */ + hr = BaseOutputPinImpl_InitAllocator(This, pAlloc); + + if (SUCCEEDED(hr)) + { + ALLOCATOR_PROPERTIES rProps; + ZeroMemory(&rProps, sizeof(ALLOCATOR_PROPERTIES)); + + IMemInputPin_GetAllocatorRequirements(pPin, &rProps); + hr = This->pFuncsTable->pfnDecideBufferSize(This, *pAlloc, &rProps); + } + + if (SUCCEEDED(hr)) + hr = IMemInputPin_NotifyAllocator(pPin, *pAlloc, FALSE); + + return hr; +} + +/*** The Construct functions ***/ + +/* Function called as a helper to IPin_Connect */ +/* specific AM_MEDIA_TYPE - it cannot be NULL */ +HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(BasePin* iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + BaseOutputPin *This = impl_BaseOutputPin_from_BasePin(iface); + HRESULT hr; + IMemAllocator * pMemAlloc = NULL; + + TRACE("(%p, %p)\n", pReceivePin, pmt); + dump_AM_MEDIA_TYPE(pmt); + + /* FIXME: call queryacceptproc */ + + This->pin.pConnectedTo = pReceivePin; + IPin_AddRef(pReceivePin); + CopyMediaType(&This->pin.mtCurrent, pmt); + + hr = IPin_ReceiveConnection(pReceivePin, &iface->IPin_iface, pmt); + + /* get the IMemInputPin interface we will use to deliver samples to the + * connected pin */ + if (SUCCEEDED(hr)) + { + This->pMemInputPin = NULL; + hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin); + + if (SUCCEEDED(hr)) + { + hr = This->pFuncsTable->pfnDecideAllocator(This, This->pMemInputPin, &pMemAlloc); + if (SUCCEEDED(hr)) + This->pAllocator = pMemAlloc; + else if (pMemAlloc) + IMemAllocator_Release(pMemAlloc); + } + + /* break connection if we couldn't get the allocator */ + if (FAILED(hr)) + { + if (This->pMemInputPin) + IMemInputPin_Release(This->pMemInputPin); + This->pMemInputPin = NULL; + + IPin_Disconnect(pReceivePin); + } + } + + if (FAILED(hr)) + { + IPin_Release(This->pin.pConnectedTo); + This->pin.pConnectedTo = NULL; + FreeMediaType(&This->pin.mtCurrent); + } + + TRACE(" -- %x\n", hr); + return hr; +} + +static HRESULT OutputPin_Init(const IPinVtbl *OutputPin_Vtbl, const PIN_INFO * pPinInfo, const BasePinFuncTable* pBaseFuncsTable, const BaseOutputPinFuncTable* pBaseOutputFuncsTable, LPCRITICAL_SECTION pCritSec, BaseOutputPin * pPinImpl) +{ + TRACE("\n"); + + /* Common attributes */ + pPinImpl->pin.IPin_iface.lpVtbl = OutputPin_Vtbl; + pPinImpl->pin.refCount = 1; + pPinImpl->pin.pConnectedTo = NULL; + pPinImpl->pin.pCritSec = pCritSec; + pPinImpl->pin.tStart = 0; + pPinImpl->pin.tStop = 0; + pPinImpl->pin.dRate = 1.0; + Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo); + pPinImpl->pin.pFuncsTable = pBaseFuncsTable; + ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); + + /* Output pin attributes */ + pPinImpl->pMemInputPin = NULL; + pPinImpl->pAllocator = NULL; + pPinImpl->pFuncsTable = pBaseOutputFuncsTable; + + return S_OK; +} + +HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, const BasePinFuncTable* pBaseFuncsTable, const BaseOutputPinFuncTable* pBaseOutputFuncsTable, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) +{ + BaseOutputPin * pPinImpl; + + *ppPin = NULL; + + if (pPinInfo->dir != PINDIR_OUTPUT) + { + ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir); + return E_INVALIDARG; + } + + assert(outputpin_size >= sizeof(BaseOutputPin)); + assert(pBaseFuncsTable->pfnAttemptConnection); + + pPinImpl = CoTaskMemAlloc(outputpin_size); + + if (!pPinImpl) + return E_OUTOFMEMORY; + + if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, pBaseFuncsTable, pBaseOutputFuncsTable, pCritSec, pPinImpl))) + { + *ppPin = &pPinImpl->pin.IPin_iface; + return S_OK; + } + + CoTaskMemFree(pPinImpl); + return E_FAIL; +} + +/*** Input Pin implementation ***/ + +static inline BaseInputPin *impl_BaseInputPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BaseInputPin, pin.IPin_iface); +} + +static inline BaseInputPin *impl_BaseInputPin_from_BasePin( BasePin *iface ) +{ + return CONTAINING_RECORD(iface, BaseInputPin, pin); +} + +HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + + TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv); + + *ppv = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = iface; + else if (IsEqualIID(riid, &IID_IPin)) + *ppv = iface; + else if (IsEqualIID(riid, &IID_IMemInputPin)) + *ppv = &This->IMemInputPin_iface; + else if (IsEqualIID(riid, &IID_IMediaSeeking)) + { + return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv); + } + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + + FIXME("No interface for %s!\n", debugstr_guid(riid)); + + return E_NOINTERFACE; +} + +ULONG WINAPI BaseInputPinImpl_Release(IPin * iface) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + ULONG refCount = InterlockedDecrement(&This->pin.refCount); + + TRACE("(%p)->() Release from %d\n", iface, refCount + 1); + + if (!refCount) + { + FreeMediaType(&This->pin.mtCurrent); + if (This->pAllocator) + IMemAllocator_Release(This->pAllocator); + This->pAllocator = NULL; + This->pin.IPin_iface.lpVtbl = NULL; + CoTaskMemFree(This); + return 0; + } + else + return refCount; +} + +HRESULT WINAPI BaseInputPinImpl_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt) +{ + ERR("Outgoing connection on an input pin! (%p, %p)\n", pConnector, pmt); + + return E_UNEXPECTED; +} + + +HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + PIN_DIRECTION pindirReceive; + HRESULT hr = S_OK; + + TRACE("(%p, %p)\n", pReceivePin, pmt); + dump_AM_MEDIA_TYPE(pmt); + + EnterCriticalSection(This->pin.pCritSec); + { + if (This->pin.pConnectedTo) + hr = VFW_E_ALREADY_CONNECTED; + + if (SUCCEEDED(hr) && This->pin.pFuncsTable->pfnCheckMediaType(&This->pin, pmt) != S_OK) + hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto + * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */ + + if (SUCCEEDED(hr)) + { + IPin_QueryDirection(pReceivePin, &pindirReceive); + + if (pindirReceive != PINDIR_OUTPUT) + { + ERR("Can't connect from non-output pin\n"); + hr = VFW_E_INVALID_DIRECTION; + } + } + + if (SUCCEEDED(hr)) + { + CopyMediaType(&This->pin.mtCurrent, pmt); + This->pin.pConnectedTo = pReceivePin; + IPin_AddRef(pReceivePin); + } + } + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +static HRESULT deliver_endofstream(IPin* pin, LPVOID unused) +{ + return IPin_EndOfStream( pin ); +} + +HRESULT WINAPI BaseInputPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pmt); + + return (This->pin.pFuncsTable->pfnCheckMediaType(&This->pin, pmt) == S_OK ? S_OK : S_FALSE); +} + +HRESULT WINAPI BaseInputPinImpl_EndOfStream(IPin * iface) +{ + HRESULT hr = S_OK; + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + + TRACE("(%p)\n", This); + + EnterCriticalSection(This->pin.pCritSec); + if (This->flushing) + hr = S_FALSE; + else + This->end_of_stream = 1; + LeaveCriticalSection(This->pin.pCritSec); + + if (hr == S_OK) + hr = SendFurther( iface, deliver_endofstream, NULL, NULL ); + return hr; +} + +static HRESULT deliver_beginflush(IPin* pin, LPVOID unused) +{ + return IPin_BeginFlush( pin ); +} + +HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin * iface) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + HRESULT hr; + TRACE("() semi-stub\n"); + + EnterCriticalSection(This->pin.pCritSec); + This->flushing = 1; + + hr = SendFurther( iface, deliver_beginflush, NULL, NULL ); + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +static HRESULT deliver_endflush(IPin* pin, LPVOID unused) +{ + return IPin_EndFlush( pin ); +} + +HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin * iface) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + HRESULT hr; + TRACE("(%p)\n", This); + + EnterCriticalSection(This->pin.pCritSec); + This->flushing = This->end_of_stream = 0; + + hr = SendFurther( iface, deliver_endflush, NULL, NULL ); + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +typedef struct newsegmentargs +{ + REFERENCE_TIME tStart, tStop; + double rate; +} newsegmentargs; + +static HRESULT deliver_newsegment(IPin *pin, LPVOID data) +{ + newsegmentargs *args = data; + return IPin_NewSegment(pin, args->tStart, args->tStop, args->rate); +} + +HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + newsegmentargs args; + + TRACE("(%x%08x, %x%08x, %e)\n", (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate); + + args.tStart = This->pin.tStart = tStart; + args.tStop = This->pin.tStop = tStop; + args.rate = This->pin.dRate = dRate; + + return SendFurther( iface, deliver_newsegment, &args, NULL ); +} + +static const IPinVtbl InputPin_Vtbl = +{ + BaseInputPinImpl_QueryInterface, + BasePinImpl_AddRef, + BaseInputPinImpl_Release, + BaseInputPinImpl_Connect, + BaseInputPinImpl_ReceiveConnection, + BasePinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BaseInputPinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseInputPinImpl_EndOfStream, + BaseInputPinImpl_BeginFlush, + BaseInputPinImpl_EndFlush, + BaseInputPinImpl_NewSegment +}; + +/*** IMemInputPin implementation ***/ + +static inline BaseInputPin *impl_from_IMemInputPin( IMemInputPin *iface ) +{ + return CONTAINING_RECORD(iface, BaseInputPin, IMemInputPin_iface); +} + +static HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + return IPin_QueryInterface(&This->pin.IPin_iface, riid, ppv); +} + +static ULONG WINAPI MemInputPin_AddRef(IMemInputPin * iface) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + return IPin_AddRef(&This->pin.IPin_iface); +} + +static ULONG WINAPI MemInputPin_Release(IMemInputPin * iface) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + return IPin_Release(&This->pin.IPin_iface); +} + +static HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocator ** ppAllocator) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, ppAllocator); + + *ppAllocator = This->pAllocator; + if (*ppAllocator) + IMemAllocator_AddRef(*ppAllocator); + + return *ppAllocator ? S_OK : VFW_E_NO_ALLOCATOR; +} + +static HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllocator * pAllocator, BOOL bReadOnly) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + TRACE("(%p/%p)->(%p, %d)\n", This, iface, pAllocator, bReadOnly); + + if (bReadOnly) + FIXME("Read only flag not handled yet!\n"); + + /* FIXME: Should we release the allocator on disconnection? */ + if (!pAllocator) + { + WARN("Null allocator\n"); + return E_POINTER; + } + + if (This->preferred_allocator && pAllocator != This->preferred_allocator) + return E_FAIL; + + if (This->pAllocator) + IMemAllocator_Release(This->pAllocator); + This->pAllocator = pAllocator; + if (This->pAllocator) + IMemAllocator_AddRef(This->pAllocator); + + return S_OK; +} + +static HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface, ALLOCATOR_PROPERTIES * pProps) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pProps); + + /* override this method if you have any specific requirements */ + + return E_NOTIMPL; +} + +static HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * pSample) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + HRESULT hr = S_FALSE; + + /* this trace commented out for performance reasons */ + /*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/ + if (This->pFuncsTable->pfnReceive) + hr = This->pFuncsTable->pfnReceive(This, pSample); + return hr; +} + +static HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, LONG nSamples, LONG *nSamplesProcessed) +{ + HRESULT hr = S_OK; + BaseInputPin *This = impl_from_IMemInputPin(iface); + + TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pSamples, nSamples, nSamplesProcessed); + + for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; (*nSamplesProcessed)++) + { + hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]); + if (hr != S_OK) + break; + } + + return hr; +} + +static HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface) +{ + BaseInputPin *This = impl_from_IMemInputPin(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return S_OK; +} + +static const IMemInputPinVtbl MemInputPin_Vtbl = +{ + MemInputPin_QueryInterface, + MemInputPin_AddRef, + MemInputPin_Release, + MemInputPin_GetAllocator, + MemInputPin_NotifyAllocator, + MemInputPin_GetAllocatorRequirements, + MemInputPin_Receive, + MemInputPin_ReceiveMultiple, + MemInputPin_ReceiveCanBlock +}; + +static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, + const BasePinFuncTable* pBaseFuncsTable, const BaseInputPinFuncTable* pBaseInputFuncsTable, + LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, BaseInputPin * pPinImpl) +{ + TRACE("\n"); + + /* Common attributes */ + pPinImpl->pin.refCount = 1; + pPinImpl->pin.pConnectedTo = NULL; + pPinImpl->pin.pCritSec = pCritSec; + pPinImpl->pin.tStart = 0; + pPinImpl->pin.tStop = 0; + pPinImpl->pin.dRate = 1.0; + Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo); + ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); + pPinImpl->pin.pFuncsTable = pBaseFuncsTable; + + /* Input pin attributes */ + pPinImpl->pFuncsTable = pBaseInputFuncsTable; + pPinImpl->pAllocator = pPinImpl->preferred_allocator = allocator; + if (pPinImpl->preferred_allocator) + IMemAllocator_AddRef(pPinImpl->preferred_allocator); + pPinImpl->pin.IPin_iface.lpVtbl = InputPin_Vtbl; + pPinImpl->IMemInputPin_iface.lpVtbl = &MemInputPin_Vtbl; + pPinImpl->flushing = pPinImpl->end_of_stream = 0; + + return S_OK; +} + +HRESULT BaseInputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, + const BasePinFuncTable* pBaseFuncsTable, const BaseInputPinFuncTable* pBaseInputFuncsTable, + LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, IPin ** ppPin) +{ + BaseInputPin * pPinImpl; + + *ppPin = NULL; + + assert(pBaseFuncsTable->pfnCheckMediaType); + + if (pPinInfo->dir != PINDIR_INPUT) + { + ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir); + return E_INVALIDARG; + } + + pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl)); + + if (!pPinImpl) + return E_OUTOFMEMORY; + + if (SUCCEEDED(InputPin_Init(InputPin_Vtbl, pPinInfo, pBaseFuncsTable, pBaseInputFuncsTable, pCritSec, allocator, pPinImpl))) + { + *ppPin = (IPin *)pPinImpl; + return S_OK; + } + + CoTaskMemFree(pPinImpl); + return E_FAIL; +} diff --git a/lib/3rdparty/strmbase/pospass.c b/lib/3rdparty/strmbase/pospass.c new file mode 100644 index 00000000000..71c1dc67d17 --- /dev/null +++ b/lib/3rdparty/strmbase/pospass.c @@ -0,0 +1,938 @@ +/* + * Filter Seeking and Control Interfaces + * + * Copyright 2003 Robert Shearman + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ +/* FIXME: critical sections */ + +#define COBJMACROS + +#include "dshow.h" +#include "uuids.h" + +#include "wine/debug.h" +#include "wine/strmbase.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl; +static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl; + +typedef struct PassThruImpl { + IUnknown IUnknown_inner; + ISeekingPassThru ISeekingPassThru_iface; + IMediaSeeking IMediaSeeking_iface; + IMediaPosition IMediaPosition_iface; + BaseDispatch baseDispatch; + + LONG ref; + IUnknown * outer_unk; + IPin * pin; + BOOL bUnkOuterValid; + BOOL bAggregatable; + BOOL renderer; + CRITICAL_SECTION time_cs; + BOOL timevalid; + REFERENCE_TIME time_earliest; +} PassThruImpl; + +static inline PassThruImpl *impl_from_IUnknown_inner(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, PassThruImpl, IUnknown_inner); +} + +static inline PassThruImpl *impl_from_ISeekingPassThru(ISeekingPassThru *iface) +{ + return CONTAINING_RECORD(iface, PassThruImpl, ISeekingPassThru_iface); +} + +static inline PassThruImpl *impl_from_IMediaSeeking(IMediaSeeking *iface) +{ + return CONTAINING_RECORD(iface, PassThruImpl, IMediaSeeking_iface); +} + +static inline PassThruImpl *impl_from_IMediaPosition(IMediaPosition *iface) +{ + return CONTAINING_RECORD(iface, PassThruImpl, IMediaPosition_iface); +} + +static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface, + REFIID riid, + LPVOID *ppvObj) { + PassThruImpl *This = impl_from_IUnknown_inner(iface); + TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj); + + if (This->bAggregatable) + This->bUnkOuterValid = TRUE; + + if (IsEqualGUID(&IID_IUnknown, riid)) + { + *ppvObj = &(This->IUnknown_inner); + TRACE(" returning IUnknown interface (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) { + *ppvObj = &(This->ISeekingPassThru_iface); + TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) { + *ppvObj = &(This->IMediaSeeking_iface); + TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_IMediaPosition, riid)) { + *ppvObj = &(This->IMediaPosition_iface); + TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj); + } else { + *ppvObj = NULL; + FIXME("unknown interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)(*ppvObj)); + return S_OK; +} + +static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) { + PassThruImpl *This = impl_from_IUnknown_inner(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(): new ref = %d\n", This, ref); + + return ref; +} + +static ULONG WINAPI SeekInner_Release(IUnknown * iface) { + PassThruImpl *This = impl_from_IUnknown_inner(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(): new ref = %d\n", This, ref); + + if (ref == 0) + { + BaseDispatch_Destroy(&This->baseDispatch); + This->time_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->time_cs); + CoTaskMemFree(This); + } + return ref; +} + +static const IUnknownVtbl IInner_VTable = +{ + SeekInner_QueryInterface, + SeekInner_AddRef, + SeekInner_Release +}; + +/* Generic functions for aggregation */ +static HRESULT SeekOuter_QueryInterface(PassThruImpl *This, REFIID riid, LPVOID *ppv) +{ + if (This->bAggregatable) + This->bUnkOuterValid = TRUE; + + if (This->outer_unk) + { + if (This->bAggregatable) + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); + + if (IsEqualIID(riid, &IID_IUnknown)) + { + HRESULT hr; + + IUnknown_AddRef((IUnknown *)&(This->IUnknown_inner)); + hr = IUnknown_QueryInterface((IUnknown *)&(This->IUnknown_inner), riid, ppv); + IUnknown_Release((IUnknown *)&(This->IUnknown_inner)); + This->bAggregatable = TRUE; + return hr; + } + + *ppv = NULL; + return E_NOINTERFACE; + } + + return IUnknown_QueryInterface((IUnknown *)&(This->IUnknown_inner), riid, ppv); +} + +static ULONG SeekOuter_AddRef(PassThruImpl *This) +{ + if (This->outer_unk && This->bUnkOuterValid) + return IUnknown_AddRef(This->outer_unk); + return IUnknown_AddRef((IUnknown *)&(This->IUnknown_inner)); +} + +static ULONG SeekOuter_Release(PassThruImpl *This) +{ + if (This->outer_unk && This->bUnkOuterValid) + return IUnknown_Release(This->outer_unk); + return IUnknown_Release((IUnknown *)&(This->IUnknown_inner)); +} + +static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID riid, LPVOID *ppvObj) +{ + PassThruImpl *This = impl_from_ISeekingPassThru(iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return SeekOuter_QueryInterface(This, riid, ppvObj); +} + +static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface) +{ + PassThruImpl *This = impl_from_ISeekingPassThru(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return SeekOuter_AddRef(This); +} + +static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface) +{ + PassThruImpl *This = impl_from_ISeekingPassThru(iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return SeekOuter_Release(This); +} + +static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin) +{ + PassThruImpl *This = impl_from_ISeekingPassThru(iface); + + TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin); + + if (This->pin) + FIXME("Re-initializing?\n"); + + This->renderer = renderer; + This->pin = pin; + + return S_OK; +} + +static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl = +{ + SeekingPassThru_QueryInterface, + SeekingPassThru_AddRef, + SeekingPassThru_Release, + SeekingPassThru_Init +}; + +HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru) +{ + HRESULT hr; + ISeekingPassThru *passthru; + + hr = CoCreateInstance(&CLSID_SeekingPassThru, pUnkOuter, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppPassThru); + + IUnknown_QueryInterface(*ppPassThru, &IID_ISeekingPassThru, (void**)&passthru); + hr = ISeekingPassThru_Init(passthru, bRenderer, pPin); + ISeekingPassThru_Release(passthru); + + return hr; +} + +HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru) +{ + PassThruImpl *fimpl; + + TRACE("(%p,%p)\n", pUnkOuter, ppPassThru); + + *ppPassThru = fimpl = CoTaskMemAlloc(sizeof(*fimpl)); + if (!fimpl) + return E_OUTOFMEMORY; + + fimpl->outer_unk = pUnkOuter; + fimpl->bUnkOuterValid = FALSE; + fimpl->bAggregatable = FALSE; + fimpl->IUnknown_inner.lpVtbl = &IInner_VTable; + fimpl->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl; + fimpl->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl; + fimpl->IMediaPosition_iface.lpVtbl = &IMediaPositionPassThru_Vtbl; + fimpl->ref = 1; + fimpl->pin = NULL; + fimpl->timevalid = 0; + InitializeCriticalSection(&fimpl->time_cs); + fimpl->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs"); + BaseDispatch_Init(&fimpl->baseDispatch, &IID_IMediaPosition); + return S_OK; +} + +static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID riid, LPVOID *ppvObj) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return SeekOuter_QueryInterface(This, riid, ppvObj); +} + +static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p/%p)->()\n", iface, This); + + return SeekOuter_AddRef(This); +} + +static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p/%p)->()\n", iface, This); + + return SeekOuter_Release(This); +} + +static HRESULT get_connected(PassThruImpl *This, REFIID riid, LPVOID *ppvObj) { + HRESULT hr; + IPin *pin; + *ppvObj = NULL; + hr = IPin_ConnectedTo(This->pin, &pin); + if (FAILED(hr)) + return VFW_E_NOT_CONNECTED; + hr = IPin_QueryInterface(pin, riid, ppvObj); + IPin_Release(pin); + if (FAILED(hr)) + hr = E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetCapabilities(seek, pCapabilities); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_CheckCapabilities(seek, pCapabilities); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat)); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_IsFormatSupported(seek, pFormat); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, pFormat); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_QueryPreferredFormat(seek, pFormat); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, pFormat); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetTimeFormat(seek, pFormat); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat)); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_IsUsingTimeFormat(seek, pFormat); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat)); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_SetTimeFormat(seek, pFormat); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, pDuration); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetDuration(seek, pDuration); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, pStop); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetStopPosition(seek, pStop); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr = S_OK; + TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent); + if (!pCurrent) + return E_POINTER; + EnterCriticalSection(&This->time_cs); + if (This->timevalid) + *pCurrent = This->time_earliest; + else + hr = E_FAIL; + LeaveCriticalSection(&This->time_cs); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_ConvertTimeFormat(iface, pCurrent, NULL, *pCurrent, &TIME_FORMAT_MEDIA_TIME); + return hr; + } + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetCurrentPosition(seek, pCurrent); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface, This, pTarget, debugstr_guid(pTargetFormat), (DWORD)(Source>>32), (DWORD)Source, debugstr_guid(pSourceFormat)); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_ConvertTimeFormat(seek, pTarget, pTargetFormat, Source, pSourceFormat); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface, This, pCurrent, dwCurrentFlags, pStop, dwStopFlags); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_SetPositions(seek, pCurrent, dwCurrentFlags, pStop, dwStopFlags); + IMediaSeeking_Release(seek); + } else if (hr == VFW_E_NOT_CONNECTED) + hr = S_OK; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetPositions(seek, pCurrent, pStop); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetAvailable(seek, pEarliest, pLatest); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%e)\n", iface, This, dRate); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_SetRate(seek, dRate); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p/%p)->(%p)\n", iface, This, dRate); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetRate(seek, dRate); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll) +{ + PassThruImpl *This = impl_from_IMediaSeeking(iface); + IMediaSeeking *seek; + HRESULT hr; + TRACE("(%p)\n", pPreroll); + hr = get_connected(This, &IID_IMediaSeeking, (LPVOID*)&seek); + if (SUCCEEDED(hr)) { + hr = IMediaSeeking_GetPreroll(seek, pPreroll); + IMediaSeeking_Release(seek); + } + else + return E_NOTIMPL; + return hr; +} + +HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start) +{ + PassThruImpl *This = impl_from_IUnknown_inner(iface); + EnterCriticalSection(&This->time_cs); + This->time_earliest = start; + This->timevalid = 1; + LeaveCriticalSection(&This->time_cs); + return S_OK; +} + +HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface) +{ + PassThruImpl *This = impl_from_IUnknown_inner(iface); + EnterCriticalSection(&This->time_cs); + This->timevalid = 0; + LeaveCriticalSection(&This->time_cs); + return S_OK; +} + +HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface) +{ + PassThruImpl *This = impl_from_IUnknown_inner(iface); + REFERENCE_TIME time; + HRESULT hr; + hr = IMediaSeeking_GetStopPosition(&This->IMediaSeeking_iface, &time); + EnterCriticalSection(&This->time_cs); + if (SUCCEEDED(hr)) { + This->timevalid = 1; + This->time_earliest = time; + } else + This->timevalid = 0; + LeaveCriticalSection(&This->time_cs); + return hr; +} + +static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl = +{ + MediaSeekingPassThru_QueryInterface, + MediaSeekingPassThru_AddRef, + MediaSeekingPassThru_Release, + MediaSeekingPassThru_GetCapabilities, + MediaSeekingPassThru_CheckCapabilities, + MediaSeekingPassThru_IsFormatSupported, + MediaSeekingPassThru_QueryPreferredFormat, + MediaSeekingPassThru_GetTimeFormat, + MediaSeekingPassThru_IsUsingTimeFormat, + MediaSeekingPassThru_SetTimeFormat, + MediaSeekingPassThru_GetDuration, + MediaSeekingPassThru_GetStopPosition, + MediaSeekingPassThru_GetCurrentPosition, + MediaSeekingPassThru_ConvertTimeFormat, + MediaSeekingPassThru_SetPositions, + MediaSeekingPassThru_GetPositions, + MediaSeekingPassThru_GetAvailable, + MediaSeekingPassThru_SetRate, + MediaSeekingPassThru_GetRate, + MediaSeekingPassThru_GetPreroll +}; + +static HRESULT WINAPI MediaPositionPassThru_QueryInterface(IMediaPosition *iface, REFIID riid, LPVOID *ppvObj) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return SeekOuter_QueryInterface(This, riid, ppvObj); +} + +static ULONG WINAPI MediaPositionPassThru_AddRef(IMediaPosition *iface) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + + TRACE("(%p/%p)->()\n", iface, This); + + return SeekOuter_AddRef(This); +} + +static ULONG WINAPI MediaPositionPassThru_Release(IMediaPosition *iface) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + + TRACE("(%p/%p)->()\n", iface, This); + + return SeekOuter_Release(This); +} + +static HRESULT WINAPI MediaPositionPassThru_GetTypeInfoCount(IMediaPosition *iface, UINT*pctinfo) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + + return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo); +} + +static HRESULT WINAPI MediaPositionPassThru_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo**ppTInfo) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + + return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI MediaPositionPassThru_GetIDsOfNames(IMediaPosition *iface, REFIID riid, LPOLESTR*rgszNames, UINT cNames, LCID lcid, DISPID*rgDispId) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + + return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI MediaPositionPassThru_Invoke(IMediaPosition *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS*pDispParams, VARIANT*pVarResult, EXCEPINFO*pExepInfo, UINT*puArgErr) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + HRESULT hr = S_OK; + ITypeInfo *pTypeInfo; + + hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(pTypeInfo, &This->IMediaPosition_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); + ITypeInfo_Release(pTypeInfo); + } + + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_get_Duration(IMediaPosition *iface, REFTIME *plength) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", plength); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_get_Duration(pos, plength); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_put_CurrentPosition(IMediaPosition *iface, REFTIME llTime) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%s)\n", wine_dbgstr_longlong(llTime)); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_put_CurrentPosition(pos, llTime); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_get_CurrentPosition(IMediaPosition *iface, REFTIME *pllTime) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", pllTime); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_get_CurrentPosition(pos, pllTime); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_get_StopTime(IMediaPosition *iface, REFTIME *pllTime) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", pllTime); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_get_StopTime(pos, pllTime); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_put_StopTime(IMediaPosition *iface, REFTIME llTime) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%s)\n", wine_dbgstr_longlong(llTime)); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_put_StopTime(pos, llTime); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_get_PrerollTime(IMediaPosition *iface, REFTIME *pllTime) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", pllTime); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_get_PrerollTime(pos, pllTime); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_put_PrerollTime(IMediaPosition *iface, REFTIME llTime) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%s)\n", wine_dbgstr_longlong(llTime)); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_put_PrerollTime(pos, llTime); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_put_Rate(IMediaPosition *iface, double dRate) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%f)\n", dRate); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_put_Rate(pos, dRate); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_get_Rate(IMediaPosition *iface, double *pdRate) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", pdRate); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_get_Rate(pos, pdRate); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_CanSeekForward(IMediaPosition *iface, LONG *pCanSeekForward) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", pCanSeekForward); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_CanSeekForward(pos, pCanSeekForward); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static HRESULT WINAPI MediaPositionPassThru_CanSeekBackward(IMediaPosition *iface, LONG *pCanSeekBackward) +{ + PassThruImpl *This = impl_from_IMediaPosition(iface); + IMediaPosition *pos; + HRESULT hr; + + TRACE("(%p)\n", pCanSeekBackward); + + hr = get_connected(This, &IID_IMediaPosition, (LPVOID*)&pos); + if (SUCCEEDED(hr)) { + hr = IMediaPosition_CanSeekBackward(pos, pCanSeekBackward); + IMediaPosition_Release(pos); + } + else + return E_NOTIMPL; + return hr; +} + +static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl = +{ + MediaPositionPassThru_QueryInterface, + MediaPositionPassThru_AddRef, + MediaPositionPassThru_Release, + MediaPositionPassThru_GetTypeInfoCount, + MediaPositionPassThru_GetTypeInfo, + MediaPositionPassThru_GetIDsOfNames, + MediaPositionPassThru_Invoke, + MediaPositionPassThru_get_Duration, + MediaPositionPassThru_put_CurrentPosition, + MediaPositionPassThru_get_CurrentPosition, + MediaPositionPassThru_get_StopTime, + MediaPositionPassThru_put_StopTime, + MediaPositionPassThru_get_PrerollTime, + MediaPositionPassThru_put_PrerollTime, + MediaPositionPassThru_put_Rate, + MediaPositionPassThru_get_Rate, + MediaPositionPassThru_CanSeekForward, + MediaPositionPassThru_CanSeekBackward +}; diff --git a/lib/3rdparty/strmbase/qualitycontrol.c b/lib/3rdparty/strmbase/qualitycontrol.c new file mode 100644 index 00000000000..f96ed64a2a2 --- /dev/null +++ b/lib/3rdparty/strmbase/qualitycontrol.c @@ -0,0 +1,318 @@ +/* + * Quality Control Interfaces + * + * Copyright 2010 Maarten Lankhorst for CodeWeavers + * + * rendering qos functions based on, the original can be found at + * gstreamer/libs/gst/base/gstbasesink.c which has copyright notice: + * + * Copyright (C) 2005-2007 Wim Taymans + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/strmbase.h" +#include "strmbase_private.h" + +#include "uuids.h" +#include "wine/debug.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase_qc); + +HRESULT QualityControlImpl_Create(IPin *input, IBaseFilter *self, QualityControlImpl **ppv) { + QualityControlImpl *This; + *ppv = HeapAlloc(GetProcessHeap(),0,sizeof(QualityControlImpl)); + if (!*ppv) + return E_OUTOFMEMORY; + This = *ppv; + This->input = input; + This->self = self; + This->tonotify = NULL; + This->clock = NULL; + return S_OK; +} + +HRESULT QualityControlImpl_Destroy(QualityControlImpl *This) +{ + return HeapFree(GetProcessHeap(),0,This); +} + +HRESULT WINAPI QualityControlImpl_QueryInterface(IQualityControl *iface, REFIID riid, void **ppv) { + QualityControlImpl *This = (QualityControlImpl*)iface; + return IBaseFilter_QueryInterface(This->self, riid, ppv); +} + +ULONG WINAPI QualityControlImpl_AddRef(IQualityControl *iface) { + QualityControlImpl *This = (QualityControlImpl*)iface; + return IBaseFilter_AddRef(This->self); +} + +ULONG WINAPI QualityControlImpl_Release(IQualityControl *iface) { + QualityControlImpl *This = (QualityControlImpl*)iface; + return IBaseFilter_Release(This->self); +} + +HRESULT WINAPI QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) { + HRESULT hr = S_FALSE; + QualityControlImpl *This = (QualityControlImpl*)iface; + if (This->tonotify) + return IQualityControl_Notify(This->tonotify, This->self, qm); + if (This->input) { + IPin *to = NULL; + IPin_ConnectedTo(This->input, &to); + if (to) { + IQualityControl *qc = NULL; + IPin_QueryInterface(to, &IID_IQualityControl, (void**)&qc); + if (qc) { + hr = IQualityControl_Notify(qc, This->self, qm); + IQualityControl_Release(qc); + } + IPin_Release(to); + } + } + return hr; +} + +HRESULT WINAPI QualityControlImpl_SetSink(IQualityControl *iface, IQualityControl *tonotify) { + QualityControlImpl *This = (QualityControlImpl*)iface; + This->tonotify = tonotify; + return S_OK; +} + +/* Macros copied from gstreamer, weighted average between old average and new ones */ +#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size)) + +/* generic running average, this has a neutral window size */ +#define UPDATE_RUNNING_AVG(avg,val) DO_RUNNING_AVG(avg,val,8) + +/* the windows for these running averages are experimentally obtained. + * possitive values get averaged more while negative values use a small + * window so we can react faster to badness. */ +#define UPDATE_RUNNING_AVG_P(avg,val) DO_RUNNING_AVG(avg,val,16) +#define UPDATE_RUNNING_AVG_N(avg,val) DO_RUNNING_AVG(avg,val,4) + +void QualityControlRender_Start(QualityControlImpl *This, REFERENCE_TIME tStart) { + This->avg_render = This->last_in_time = This->last_left = This->avg_duration = This->avg_pt = -1; + This->clockstart = tStart; + This->avg_rate = -1.0; + This->rendered = This->dropped = This->is_dropped = 0; + This->qos_handled = 1; /* Lie that will be corrected on first adjustment */ +} + + +void QualityControlRender_SetClock(QualityControlImpl *This, IReferenceClock *clock) { + This->clock = clock; +} + +static BOOL QualityControlRender_IsLate(QualityControlImpl *This, REFERENCE_TIME jitter, + REFERENCE_TIME start, REFERENCE_TIME stop) +{ + REFERENCE_TIME max_lateness = 200000; + + /* we can add a valid stop time */ + if (stop >= start) + max_lateness += stop; + else + max_lateness += start; + + /* if the jitter bigger than duration and lateness we are too late */ + if (start + jitter > max_lateness) { + WARN("buffer is too late %i > %i\n", (int)((start + jitter)/10000), (int)(max_lateness/10000)); + /* !!emergency!!, if we did not receive anything valid for more than a + * second, render it anyway so the user sees something */ + if (This->last_in_time < 0 || + start - This->last_in_time < 10000000) + return TRUE; + FIXME("A lot of buffers are being dropped.\n"); + FIXME("There may be a timestamping problem, or this computer is too slow.\n"); + } + This->last_in_time = start; + return FALSE; +} + +HRESULT QualityControlRender_WaitFor(QualityControlImpl *This, IMediaSample *sample, HANDLE ev) { + REFERENCE_TIME start = -1, stop = -1, jitter = 0; + This->current_rstart = This->current_rstop = -1; + This->current_jitter = 0; + if (!This->clock || FAILED(IMediaSample_GetTime(sample, &start, &stop))) + return S_OK; + + if (start >= 0) { + REFERENCE_TIME now; + IReferenceClock_GetTime(This->clock, &now); + now -= This->clockstart; + + jitter = now - start; + if (jitter <= -10000) { + DWORD_PTR cookie; + IReferenceClock_AdviseTime(This->clock, This->clockstart, start, (HEVENT)ev, &cookie); + WaitForSingleObject(ev, INFINITE); + IReferenceClock_Unadvise(This->clock, cookie); + } + } + else + start = stop = -1; + This->current_rstart = start; + This->current_rstop = stop > start ? stop : start; + This->current_jitter = jitter; + This->is_dropped = QualityControlRender_IsLate(This, jitter, start, stop); + TRACE("Dropped: %i %i %i %i\n", This->is_dropped, (int)(start/10000), (int)(stop/10000), (int)(jitter / 10000)); + if (This->is_dropped) { + This->dropped++; + if (!This->qos_handled) + return S_FALSE; + } else + This->rendered++; + return S_OK; +} + +void QualityControlRender_DoQOS(QualityControlImpl *priv) +{ + REFERENCE_TIME start, stop, jitter, pt, entered, left, duration; + double rate; + + if (!priv->clock || priv->current_rstart < 0) + return; + + start = priv->current_rstart; + stop = priv->current_rstop; + jitter = priv->current_jitter; + + if (jitter < 0) { + /* this is the time the buffer entered the sink */ + if (start < -jitter) + entered = 0; + else + entered = start + jitter; + left = start; + } else { + /* this is the time the buffer entered the sink */ + entered = start + jitter; + /* this is the time the buffer left the sink */ + left = start + jitter; + } + + /* calculate duration of the buffer */ + if (stop >= start) + duration = stop - start; + else + duration = 0; + + /* if we have the time when the last buffer left us, calculate + * processing time */ + if (priv->last_left >= 0) { + if (entered > priv->last_left) { + pt = entered - priv->last_left; + } else { + pt = 0; + } + } else { + pt = priv->avg_pt; + } + +#define XTIME(u) (int)(u/10000000), (int)((u / 10000)%1000) + TRACE("start: %u.%03u, entered %u.%03u, left %u.%03u, pt: %u.%03u, " + "duration %u.%03u, jitter %u.%03u\n", XTIME(start), XTIME(entered), + XTIME(left), XTIME(pt), XTIME(duration), XTIME(jitter)); + + TRACE("avg_duration: %u.%03u, avg_pt: %u.%03u, avg_rate: %g\n", + XTIME(priv->avg_duration), XTIME(priv->avg_pt), priv->avg_rate); +#undef XTIME + + /* collect running averages. for first observations, we copy the + * values */ + if (priv->avg_duration < 0) + priv->avg_duration = duration; + else + priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration); + + if (priv->avg_pt < 0) + priv->avg_pt = pt; + else + priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt); + + if (priv->avg_duration != 0) + rate = + (double)priv->avg_pt / + (double)priv->avg_duration; + else + rate = 0.0; + + if (priv->last_left >= 0) { + if (priv->is_dropped || priv->avg_rate < 0.0) { + priv->avg_rate = rate; + } else { + if (rate > 1.0) + priv->avg_rate = UPDATE_RUNNING_AVG_N (priv->avg_rate, rate); + else + priv->avg_rate = UPDATE_RUNNING_AVG_P (priv->avg_rate, rate); + } + } + + if (priv->avg_rate >= 0.0) { + HRESULT hr; + Quality q; + /* if we have a valid rate, start sending QoS messages */ + if (priv->current_jitter < 0) { + /* make sure we never go below 0 when adding the jitter to the + * timestamp. */ + if (priv->current_rstart < -priv->current_jitter) + priv->current_jitter = -priv->current_rstart; + } + else + priv->current_jitter += (priv->current_rstop - priv->current_rstart); + q.Type = (jitter > 0 ? Famine : Flood); + q.Proportion = (LONG)(1000. / priv->avg_rate); + if (q.Proportion < 200) + q.Proportion = 200; + else if (q.Proportion > 5000) + q.Proportion = 5000; + q.Late = priv->current_jitter; + q.TimeStamp = priv->current_rstart; + TRACE("Late: %i from %i, rate: %g\n", (int)(q.Late/10000), (int)(q.TimeStamp/10000), 1./priv->avg_rate); + hr = IQualityControl_Notify((IQualityControl *)priv, priv->self, q); + priv->qos_handled = hr == S_OK; + } + + /* record when this buffer will leave us */ + priv->last_left = left; +} + + +void QualityControlRender_BeginRender(QualityControlImpl *This) { + This->start = -1; + if (!This->clock) + return; + IReferenceClock_GetTime(This->clock, &This->start); +} + +void QualityControlRender_EndRender(QualityControlImpl *This) { + REFERENCE_TIME elapsed; + if (!This->clock || This->start < 0 || FAILED(IReferenceClock_GetTime(This->clock, &This->stop))) + return; + + elapsed = This->start - This->stop; + if (elapsed < 0) + return; + if (This->avg_render < 0) + This->avg_render = elapsed; + else + This->avg_render = UPDATE_RUNNING_AVG (This->avg_render, elapsed); +} diff --git a/lib/3rdparty/strmbase/renderer.c b/lib/3rdparty/strmbase/renderer.c new file mode 100644 index 00000000000..8bbb1f81130 --- /dev/null +++ b/lib/3rdparty/strmbase/renderer.c @@ -0,0 +1,614 @@ +/* + * Generic Implementation of strmbase Base Renderer classes + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include "strmbase_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; +static const WCHAR wcsAltInputPinName[] = {'I','n',0}; + +static inline BaseInputPin *impl_BaseInputPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BaseInputPin, pin.IPin_iface); +} + +static inline BaseRenderer *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, BaseRenderer, filter.IBaseFilter_iface); +} + +static inline BaseRenderer *impl_from_BaseFilter(BaseFilter *iface) +{ + return CONTAINING_RECORD(iface, BaseRenderer, filter); +} + +static const IQualityControlVtbl Renderer_QualityControl_Vtbl = { + QualityControlImpl_QueryInterface, + QualityControlImpl_AddRef, + QualityControlImpl_Release, + QualityControlImpl_Notify, + QualityControlImpl_SetSink +}; + +static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + BaseRenderer *renderer = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + HRESULT hr = S_OK; + + TRACE("(%p/%p)->(%p, %p)\n", This, renderer, pReceivePin, pmt); + + EnterCriticalSection(This->pin.pCritSec); + hr = BaseInputPinImpl_ReceiveConnection(iface, pReceivePin, pmt); + if (SUCCEEDED(hr)) + { + if (renderer->pFuncsTable->pfnCompleteConnect) + hr = renderer->pFuncsTable->pfnCompleteConnect(renderer, pReceivePin); + } + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +static HRESULT WINAPI BaseRenderer_InputPin_Disconnect(IPin * iface) +{ + BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + BaseRenderer *renderer = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + HRESULT hr; + + TRACE("(%p/%p)\n", This, renderer); + + EnterCriticalSection(This->pin.pCritSec); + hr = BasePinImpl_Disconnect(iface); + if (SUCCEEDED(hr)) + { + if (renderer->pFuncsTable->pfnBreakConnect) + hr = renderer->pFuncsTable->pfnBreakConnect(renderer); + } + BaseRendererImpl_ClearPendingSample(renderer); + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +static HRESULT WINAPI BaseRenderer_InputPin_EndOfStream(IPin * iface) +{ + HRESULT hr = S_OK; + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + BaseRenderer *pFilter = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + + TRACE("(%p/%p)->()\n", This, pFilter); + + EnterCriticalSection(&pFilter->filter.csFilter); + EnterCriticalSection(&pFilter->csRenderLock); + hr = BaseInputPinImpl_EndOfStream(iface); + EnterCriticalSection(This->pin.pCritSec); + if (SUCCEEDED(hr)) + { + if (pFilter->pFuncsTable->pfnEndOfStream) + hr = pFilter->pFuncsTable->pfnEndOfStream(pFilter); + else + hr = BaseRendererImpl_EndOfStream(pFilter); + } + LeaveCriticalSection(This->pin.pCritSec); + LeaveCriticalSection(&pFilter->csRenderLock); + LeaveCriticalSection(&pFilter->filter.csFilter); + return hr; +} + +static HRESULT WINAPI BaseRenderer_InputPin_BeginFlush(IPin * iface) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + BaseRenderer *pFilter = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + HRESULT hr = S_OK; + + TRACE("(%p/%p)->()\n", This, iface); + + EnterCriticalSection(&pFilter->filter.csFilter); + EnterCriticalSection(&pFilter->csRenderLock); + EnterCriticalSection(This->pin.pCritSec); + hr = BaseInputPinImpl_BeginFlush(iface); + if (SUCCEEDED(hr)) + { + if (pFilter->pFuncsTable->pfnBeginFlush) + hr = pFilter->pFuncsTable->pfnBeginFlush(pFilter); + else + hr = BaseRendererImpl_BeginFlush(pFilter); + } + LeaveCriticalSection(This->pin.pCritSec); + LeaveCriticalSection(&pFilter->filter.csFilter); + LeaveCriticalSection(&pFilter->csRenderLock); + return hr; +} + +static HRESULT WINAPI BaseRenderer_InputPin_EndFlush(IPin * iface) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + BaseRenderer *pFilter = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + HRESULT hr = S_OK; + + TRACE("(%p/%p)->()\n", This, pFilter); + + EnterCriticalSection(&pFilter->filter.csFilter); + EnterCriticalSection(&pFilter->csRenderLock); + EnterCriticalSection(This->pin.pCritSec); + hr = BaseInputPinImpl_EndFlush(iface); + if (SUCCEEDED(hr)) + { + if (pFilter->pFuncsTable->pfnEndFlush) + hr = pFilter->pFuncsTable->pfnEndFlush(pFilter); + else + hr = BaseRendererImpl_EndFlush(pFilter); + } + LeaveCriticalSection(This->pin.pCritSec); + LeaveCriticalSection(&pFilter->csRenderLock); + LeaveCriticalSection(&pFilter->filter.csFilter); + return hr; +} + +static const IPinVtbl BaseRenderer_InputPin_Vtbl = +{ + BaseInputPinImpl_QueryInterface, + BasePinImpl_AddRef, + BaseInputPinImpl_Release, + BaseInputPinImpl_Connect, + BaseRenderer_InputPin_ReceiveConnection, + BaseRenderer_InputPin_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BaseInputPinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseRenderer_InputPin_EndOfStream, + BaseRenderer_InputPin_BeginFlush, + BaseRenderer_InputPin_EndFlush, + BaseInputPinImpl_NewSegment +}; + +static IPin* WINAPI BaseRenderer_GetPin(BaseFilter *iface, int pos) +{ + BaseRenderer *This = impl_from_BaseFilter(iface); + + if (pos >= 1 || pos < 0) + return NULL; + + IPin_AddRef(&This->pInputPin->pin.IPin_iface); + return &This->pInputPin->pin.IPin_iface; +} + +static LONG WINAPI BaseRenderer_GetPinCount(BaseFilter *iface) +{ + return 1; +} + +static HRESULT WINAPI BaseRenderer_Input_CheckMediaType(BasePin *pin, const AM_MEDIA_TYPE * pmt) +{ + BaseRenderer *This = impl_from_IBaseFilter(pin->pinInfo.pFilter); + return This->pFuncsTable->pfnCheckMediaType(This, pmt); +} + +static HRESULT WINAPI BaseRenderer_Receive(BaseInputPin *pin, IMediaSample * pSample) +{ + BaseRenderer *This = impl_from_IBaseFilter(pin->pin.pinInfo.pFilter); + return BaseRendererImpl_Receive(This, pSample); +} + +static const BaseFilterFuncTable RendererBaseFilterFuncTable = { + BaseRenderer_GetPin, + BaseRenderer_GetPinCount +}; + +static const BasePinFuncTable input_BaseFuncTable = { + BaseRenderer_Input_CheckMediaType, + NULL, + BasePinImpl_GetMediaTypeVersion, + BasePinImpl_GetMediaType +}; + +static const BaseInputPinFuncTable input_BaseInputFuncTable = { + BaseRenderer_Receive +}; + + +HRESULT WINAPI BaseRenderer_Init(BaseRenderer * This, const IBaseFilterVtbl *Vtbl, IUnknown *pUnkOuter, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseRendererFuncTable* pBaseFuncsTable) +{ + PIN_INFO piInput; + HRESULT hr; + + BaseFilter_Init(&This->filter, Vtbl, pClsid, DebugInfo, &RendererBaseFilterFuncTable); + + This->pFuncsTable = pBaseFuncsTable; + + /* construct input pin */ + piInput.dir = PINDIR_INPUT; + piInput.pFilter = &This->filter.IBaseFilter_iface; + lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); + + hr = BaseInputPin_Construct(&BaseRenderer_InputPin_Vtbl, &piInput, &input_BaseFuncTable, &input_BaseInputFuncTable, &This->filter.csFilter, NULL, (IPin **)&This->pInputPin); + + if (SUCCEEDED(hr)) + { + hr = CreatePosPassThru(pUnkOuter ? pUnkOuter: (IUnknown*)This, TRUE, &This->pInputPin->pin.IPin_iface, &This->pPosition); + if (FAILED(hr)) + return hr; + + InitializeCriticalSection(&This->csRenderLock); + This->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": BaseRenderer.csRenderLock"); + This->evComplete = CreateEventW(NULL, TRUE, TRUE, NULL); + This->ThreadSignal = CreateEventW(NULL, TRUE, TRUE, NULL); + This->RenderEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + This->pMediaSample = NULL; + + QualityControlImpl_Create(&This->pInputPin->pin.IPin_iface, &This->filter.IBaseFilter_iface, &This->qcimpl); + This->qcimpl->IQualityControl_iface.lpVtbl = &Renderer_QualityControl_Vtbl; + } + + return hr; +} + +HRESULT WINAPI BaseRendererImpl_QueryInterface(IBaseFilter* iface, REFIID riid, LPVOID * ppv) +{ + BaseRenderer *This = impl_from_IBaseFilter(iface); + + if (IsEqualIID(riid, &IID_IMediaSeeking) || IsEqualIID(riid, &IID_IMediaPosition)) + return IUnknown_QueryInterface(This->pPosition, riid, ppv); + else if (IsEqualIID(riid, &IID_IQualityControl)) + { + *ppv = &This->qcimpl->IQualityControl_iface; + IUnknown_AddRef((IUnknown *)(*ppv)); + return S_OK; + } + else + return BaseFilterImpl_QueryInterface(iface, riid, ppv); +} + +ULONG WINAPI BaseRendererImpl_Release(IBaseFilter* iface) +{ + BaseRenderer *This = impl_from_IBaseFilter(iface); + ULONG refCount = BaseFilterImpl_Release(iface); + + if (!refCount) + { + IPin *pConnectedTo; + + if (SUCCEEDED(IPin_ConnectedTo(&This->pInputPin->pin.IPin_iface, &pConnectedTo))) + { + IPin_Disconnect(pConnectedTo); + IPin_Release(pConnectedTo); + } + IPin_Disconnect(&This->pInputPin->pin.IPin_iface); + IPin_Release(&This->pInputPin->pin.IPin_iface); + + if (This->pPosition) + IUnknown_Release(This->pPosition); + + This->csRenderLock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->csRenderLock); + + BaseRendererImpl_ClearPendingSample(This); + CloseHandle(This->evComplete); + CloseHandle(This->ThreadSignal); + CloseHandle(This->RenderEvent); + QualityControlImpl_Destroy(This->qcimpl); + } + return refCount; +} + +HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample) +{ + HRESULT hr = S_OK; + REFERENCE_TIME start, stop; + AM_MEDIA_TYPE *pmt; + + TRACE("(%p)->%p\n", This, pSample); + + if (This->pInputPin->end_of_stream || This->pInputPin->flushing) + return S_FALSE; + + if (This->filter.state == State_Stopped) + return VFW_E_WRONG_STATE; + + if (IMediaSample_GetMediaType(pSample, &pmt) == S_OK) + { + if (FAILED(This->pFuncsTable->pfnCheckMediaType(This, pmt))) + { + return VFW_E_TYPE_NOT_ACCEPTED; + } + } + + This->pMediaSample = pSample; + IMediaSample_AddRef(pSample); + + if (This->pFuncsTable->pfnPrepareReceive) + hr = This->pFuncsTable->pfnPrepareReceive(This, pSample); + if (FAILED(hr)) + { + if (hr == VFW_E_SAMPLE_REJECTED) + return S_OK; + else + return hr; + } + + if (This->pFuncsTable->pfnPrepareRender) + This->pFuncsTable->pfnPrepareRender(This); + + EnterCriticalSection(&This->csRenderLock); + if ( This->filter.state == State_Paused ) + { + if (This->pFuncsTable->pfnOnReceiveFirstSample) + This->pFuncsTable->pfnOnReceiveFirstSample(This, pSample); + + SetEvent(This->evComplete); + } + + /* Wait for render Time */ + if (SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop))) + { + hr = S_FALSE; + RendererPosPassThru_RegisterMediaTime(This->pPosition, start); + if (This->pFuncsTable->pfnShouldDrawSampleNow) + hr = This->pFuncsTable->pfnShouldDrawSampleNow(This, pSample, &start, &stop); + + if (hr == S_OK) + ;/* Do not wait: drop through */ + else if (hr == S_FALSE) + { + if (This->pFuncsTable->pfnOnWaitStart) + This->pFuncsTable->pfnOnWaitStart(This); + + LeaveCriticalSection(&This->csRenderLock); + hr = QualityControlRender_WaitFor(This->qcimpl, pSample, This->RenderEvent); + EnterCriticalSection(&This->csRenderLock); + + if (This->pFuncsTable->pfnOnWaitEnd) + This->pFuncsTable->pfnOnWaitEnd(This); + } + else + { + LeaveCriticalSection(&This->csRenderLock); + /* Drop Sample */ + return S_OK; + } + } + + if (SUCCEEDED(hr)) + { + QualityControlRender_BeginRender(This->qcimpl); + hr = This->pFuncsTable->pfnDoRenderSample(This, pSample); + QualityControlRender_EndRender(This->qcimpl); + } + + QualityControlRender_DoQOS(This->qcimpl); + + BaseRendererImpl_ClearPendingSample(This); + LeaveCriticalSection(&This->csRenderLock); + + return hr; +} + +HRESULT WINAPI BaseRendererImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) +{ + BaseRenderer *This = impl_from_IBaseFilter(iface); + + TRACE("(%p)->(%s,%p)\n", This, debugstr_w(Id), ppPin); + + if (!Id || !ppPin) + return E_POINTER; + + if (!lstrcmpiW(Id,wcsInputPinName) || !lstrcmpiW(Id,wcsAltInputPinName)) + { + *ppPin = &This->pInputPin->pin.IPin_iface; + IPin_AddRef(*ppPin); + return S_OK; + } + *ppPin = NULL; + return VFW_E_NOT_FOUND; +} + +HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface) +{ + BaseRenderer *This = impl_from_IBaseFilter(iface); + + TRACE("(%p)->()\n", This); + + EnterCriticalSection(&This->csRenderLock); + { + RendererPosPassThru_ResetMediaTime(This->pPosition); + if (This->pFuncsTable->pfnOnStopStreaming) + This->pFuncsTable->pfnOnStopStreaming(This); + This->filter.state = State_Stopped; + SetEvent(This->evComplete); + SetEvent(This->ThreadSignal); + SetEvent(This->RenderEvent); + } + LeaveCriticalSection(&This->csRenderLock); + + return S_OK; +} + +HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) +{ + HRESULT hr = S_OK; + BaseRenderer *This = impl_from_IBaseFilter(iface); + TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart)); + + EnterCriticalSection(&This->csRenderLock); + This->filter.rtStreamStart = tStart; + if (This->filter.state == State_Running) + goto out; + + SetEvent(This->evComplete); + ResetEvent(This->ThreadSignal); + + if (This->pInputPin->pin.pConnectedTo) + { + This->pInputPin->end_of_stream = 0; + } + else if (This->filter.filterInfo.pGraph) + { + IMediaEventSink *pEventSink; + hr = IFilterGraph_QueryInterface(This->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); + if (SUCCEEDED(hr)) + { + hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, (LONG_PTR)This); + IMediaEventSink_Release(pEventSink); + } + hr = S_OK; + } + if (SUCCEEDED(hr)) + { + QualityControlRender_Start(This->qcimpl, This->filter.rtStreamStart); + if (This->pFuncsTable->pfnOnStartStreaming) + This->pFuncsTable->pfnOnStartStreaming(This); + if (This->filter.state == State_Stopped) + BaseRendererImpl_ClearPendingSample(This); + SetEvent(This->RenderEvent); + This->filter.state = State_Running; + } +out: + LeaveCriticalSection(&This->csRenderLock); + + return hr; +} + +HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface) +{ + BaseRenderer *This = impl_from_IBaseFilter(iface); + + TRACE("(%p)->()\n", This); + + EnterCriticalSection(&This->csRenderLock); + { + if (This->filter.state != State_Paused) + { + if (This->filter.state == State_Stopped) + { + if (This->pInputPin->pin.pConnectedTo) + ResetEvent(This->evComplete); + This->pInputPin->end_of_stream = 0; + } + else if (This->pFuncsTable->pfnOnStopStreaming) + This->pFuncsTable->pfnOnStopStreaming(This); + + if (This->filter.state == State_Stopped) + BaseRendererImpl_ClearPendingSample(This); + ResetEvent(This->RenderEvent); + This->filter.state = State_Paused; + } + } + ResetEvent(This->ThreadSignal); + LeaveCriticalSection(&This->csRenderLock); + + return S_OK; +} + +HRESULT WINAPI BaseRendererImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock) +{ + BaseRenderer *This = impl_from_IBaseFilter(iface); + HRESULT hr; + + EnterCriticalSection(&This->filter.csFilter); + QualityControlRender_SetClock(This->qcimpl, clock); + hr = BaseFilterImpl_SetSyncSource(iface, clock); + LeaveCriticalSection(&This->filter.csFilter); + return hr; +} + + +HRESULT WINAPI BaseRendererImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) +{ + HRESULT hr; + BaseRenderer *This = impl_from_IBaseFilter(iface); + + TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState); + + if (WaitForSingleObject(This->evComplete, dwMilliSecsTimeout) == WAIT_TIMEOUT) + hr = VFW_S_STATE_INTERMEDIATE; + else + hr = S_OK; + + BaseFilterImpl_GetState(iface, dwMilliSecsTimeout, pState); + + return hr; +} + +HRESULT WINAPI BaseRendererImpl_EndOfStream(BaseRenderer* iface) +{ + IMediaEventSink* pEventSink; + IFilterGraph *graph; + HRESULT hr = S_OK; + + TRACE("(%p)\n", iface); + + graph = iface->filter.filterInfo.pGraph; + if (graph) + { hr = IFilterGraph_QueryInterface(iface->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); + if (SUCCEEDED(hr)) + { + hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, (LONG_PTR)iface); + IMediaEventSink_Release(pEventSink); + } + } + RendererPosPassThru_EOS(iface->pPosition); + SetEvent(iface->evComplete); + + return hr; +} + +HRESULT WINAPI BaseRendererImpl_BeginFlush(BaseRenderer* iface) +{ + TRACE("(%p)\n", iface); + BaseRendererImpl_ClearPendingSample(iface); + SetEvent(iface->ThreadSignal); + SetEvent(iface->RenderEvent); + return S_OK; +} + +HRESULT WINAPI BaseRendererImpl_EndFlush(BaseRenderer* iface) +{ + TRACE("(%p)\n", iface); + QualityControlRender_Start(iface->qcimpl, iface->filter.rtStreamStart); + RendererPosPassThru_ResetMediaTime(iface->pPosition); + ResetEvent(iface->ThreadSignal); + ResetEvent(iface->RenderEvent); + return S_OK; +} + +HRESULT WINAPI BaseRendererImpl_ClearPendingSample(BaseRenderer *iface) +{ + if (iface->pMediaSample) + { + IMediaSample_Release(iface->pMediaSample); + iface->pMediaSample = NULL; + } + return S_OK; +} diff --git a/lib/3rdparty/strmbase/seeking.c b/lib/3rdparty/strmbase/seeking.c new file mode 100644 index 00000000000..c31699c2099 --- /dev/null +++ b/lib/3rdparty/strmbase/seeking.c @@ -0,0 +1,325 @@ +/* + * Filter Seeking and Control Interfaces + * + * Copyright 2003 Robert Shearman + * Copyright 2010 Aric Stewart, CodeWeavers + * + * 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 + */ +/* FIXME: critical sections */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/strmbase.h" + +#include "uuids.h" +#include "wine/debug.h" + +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static inline SourceSeeking *impl_from_IMediaSeeking(IMediaSeeking *iface) +{ + return CONTAINING_RECORD(iface, SourceSeeking, IMediaSeeking_iface); +} + +HRESULT SourceSeeking_Init(SourceSeeking *pSeeking, const IMediaSeekingVtbl *Vtbl, SourceSeeking_ChangeStop fnChangeStop, SourceSeeking_ChangeStart fnChangeStart, SourceSeeking_ChangeRate fnChangeRate, PCRITICAL_SECTION crit_sect) +{ + assert(fnChangeStop && fnChangeStart && fnChangeRate); + + pSeeking->IMediaSeeking_iface.lpVtbl = Vtbl; + pSeeking->refCount = 1; + pSeeking->fnChangeRate = fnChangeRate; + pSeeking->fnChangeStop = fnChangeStop; + pSeeking->fnChangeStart = fnChangeStart; + pSeeking->dwCapabilities = AM_SEEKING_CanSeekForwards | + AM_SEEKING_CanSeekBackwards | + AM_SEEKING_CanSeekAbsolute | + AM_SEEKING_CanGetStopPos | + AM_SEEKING_CanGetDuration; + pSeeking->llCurrent = 0; + pSeeking->llStop = ((ULONGLONG)0x80000000) << 32; + pSeeking->llDuration = pSeeking->llStop; + pSeeking->dRate = 1.0; + pSeeking->timeformat = TIME_FORMAT_MEDIA_TIME; + pSeeking->crst = crit_sect; + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p)\n", pCapabilities); + + *pCapabilities = This->dwCapabilities; + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + HRESULT hr; + DWORD dwCommonCaps; + + TRACE("(%p)\n", pCapabilities); + + if (!pCapabilities) + return E_POINTER; + + dwCommonCaps = *pCapabilities & This->dwCapabilities; + + if (!dwCommonCaps) + hr = E_FAIL; + else + hr = (*pCapabilities == dwCommonCaps) ? S_OK : S_FALSE; + *pCapabilities = dwCommonCaps; + return hr; +} + +HRESULT WINAPI SourceSeekingImpl_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat) +{ + TRACE("(%s)\n", debugstr_guid(pFormat)); + + return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE); +} + +HRESULT WINAPI SourceSeekingImpl_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat) +{ + TRACE("(%s)\n", debugstr_guid(pFormat)); + + *pFormat = TIME_FORMAT_MEDIA_TIME; + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + TRACE("(%s)\n", debugstr_guid(pFormat)); + + EnterCriticalSection(This->crst); + *pFormat = This->timeformat; + LeaveCriticalSection(This->crst); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + HRESULT hr = S_OK; + + TRACE("(%s)\n", debugstr_guid(pFormat)); + + EnterCriticalSection(This->crst); + if (!IsEqualIID(pFormat, &This->timeformat)) + hr = S_FALSE; + LeaveCriticalSection(This->crst); + + return hr; +} + +HRESULT WINAPI SourceSeekingImpl_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + TRACE("%p %s\n", This, debugstr_guid(pFormat)); + return (IsEqualIID(pFormat, &TIME_FORMAT_MEDIA_TIME) ? S_OK : E_INVALIDARG); +} + + +HRESULT WINAPI SourceSeekingImpl_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p)\n", pDuration); + + EnterCriticalSection(This->crst); + *pDuration = This->llDuration; + LeaveCriticalSection(This->crst); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p)\n", pStop); + + EnterCriticalSection(This->crst); + *pStop = This->llStop; + LeaveCriticalSection(This->crst); + + return S_OK; +} + +/* FIXME: Make use of the info the filter should expose */ +HRESULT WINAPI SourceSeekingImpl_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p)\n", pCurrent); + + EnterCriticalSection(This->crst); + *pCurrent = This->llCurrent; + LeaveCriticalSection(This->crst); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + if (!pTargetFormat) + pTargetFormat = &This->timeformat; + if (!pSourceFormat) + pSourceFormat = &This->timeformat; + if (IsEqualIID(pTargetFormat, &TIME_FORMAT_MEDIA_TIME) && IsEqualIID(pSourceFormat, &TIME_FORMAT_MEDIA_TIME)) + { + *pTarget = Source; + return S_OK; + } + /* FIXME: clear pTarget? */ + return E_INVALIDARG; +} + +static inline LONGLONG Adjust(LONGLONG value, const LONGLONG * pModifier, DWORD dwFlags) +{ + switch (dwFlags & AM_SEEKING_PositioningBitsMask) + { + case AM_SEEKING_NoPositioning: + return value; + case AM_SEEKING_AbsolutePositioning: + return *pModifier; + case AM_SEEKING_RelativePositioning: + case AM_SEEKING_IncrementalPositioning: + return value + *pModifier; + default: + assert(FALSE); + return 0; + } +} + +HRESULT WINAPI SourceSeekingImpl_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + BOOL bChangeCurrent = FALSE, bChangeStop = FALSE; + LONGLONG llNewCurrent, llNewStop; + + TRACE("(%p, %x, %p, %x)\n", pCurrent, dwCurrentFlags, pStop, dwStopFlags); + EnterCriticalSection(This->crst); + + llNewCurrent = Adjust(This->llCurrent, pCurrent, dwCurrentFlags); + llNewStop = Adjust(This->llStop, pStop, dwStopFlags); + + if (pCurrent) + bChangeCurrent = TRUE; + if (llNewStop != This->llStop) + bChangeStop = TRUE; + + TRACE("Old: %u, New: %u\n", (DWORD)(This->llCurrent/10000000), (DWORD)(llNewCurrent/10000000)); + + This->llCurrent = llNewCurrent; + This->llStop = llNewStop; + + if (pCurrent && (dwCurrentFlags & AM_SEEKING_ReturnTime)) + *pCurrent = llNewCurrent; + if (pStop && (dwStopFlags & AM_SEEKING_ReturnTime)) + *pStop = llNewStop; + LeaveCriticalSection(This->crst); + + if (bChangeCurrent) + This->fnChangeStart(iface); + if (bChangeStop) + This->fnChangeStop(iface); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p, %p)\n", pCurrent, pStop); + + EnterCriticalSection(This->crst); + IMediaSeeking_GetCurrentPosition(iface, pCurrent); + IMediaSeeking_GetStopPosition(iface, pStop); + LeaveCriticalSection(This->crst); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p, %p)\n", pEarliest, pLatest); + + EnterCriticalSection(This->crst); + *pEarliest = 0; + *pLatest = This->llDuration; + LeaveCriticalSection(This->crst); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_SetRate(IMediaSeeking * iface, double dRate) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + BOOL bChangeRate = (dRate != This->dRate); + HRESULT hr = S_OK; + + TRACE("(%e)\n", dRate); + + if (dRate > 100 || dRate < .001) + { + FIXME("Excessive rate %e, ignoring\n", dRate); + return VFW_E_UNSUPPORTED_AUDIO; + } + + EnterCriticalSection(This->crst); + This->dRate = dRate; + if (bChangeRate) + hr = This->fnChangeRate(iface); + LeaveCriticalSection(This->crst); + + return hr; +} + +HRESULT WINAPI SourceSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate) +{ + SourceSeeking *This = impl_from_IMediaSeeking(iface); + + TRACE("(%p)\n", dRate); + + EnterCriticalSection(This->crst); + /* Forward? */ + *dRate = This->dRate; + LeaveCriticalSection(This->crst); + + return S_OK; +} + +HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll) +{ + TRACE("(%p)\n", pPreroll); + + *pPreroll = 0; + return S_OK; +} diff --git a/lib/3rdparty/strmbase/strmbase_private.h b/lib/3rdparty/strmbase/strmbase_private.h new file mode 100644 index 00000000000..6363bf5307d --- /dev/null +++ b/lib/3rdparty/strmbase/strmbase_private.h @@ -0,0 +1,50 @@ +/* + * Header file for private strmbase implementations + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ + +/* Quality Control */ +typedef struct QualityControlImpl { + IQualityControl IQualityControl_iface; + IPin *input; + IBaseFilter *self; + IQualityControl *tonotify; + + /* Render stuff */ + IReferenceClock *clock; + REFERENCE_TIME last_in_time, last_left, avg_duration, avg_pt, avg_render, start, stop; + REFERENCE_TIME current_jitter, current_rstart, current_rstop, clockstart; + double avg_rate; + LONG64 rendered, dropped; + BOOL qos_handled, is_dropped; +} QualityControlImpl; + +HRESULT QualityControlImpl_Create(IPin *input, IBaseFilter *self, QualityControlImpl **ppv); +HRESULT QualityControlImpl_Destroy(QualityControlImpl *This); +HRESULT WINAPI QualityControlImpl_QueryInterface(IQualityControl *iface, REFIID riid, void **ppv); +ULONG WINAPI QualityControlImpl_AddRef(IQualityControl *iface); +ULONG WINAPI QualityControlImpl_Release(IQualityControl *iface); +HRESULT WINAPI QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm); +HRESULT WINAPI QualityControlImpl_SetSink(IQualityControl *iface, IQualityControl *tonotify); + +void QualityControlRender_Start(QualityControlImpl *This, REFERENCE_TIME tStart); +void QualityControlRender_SetClock(QualityControlImpl *This, IReferenceClock *clock); +HRESULT QualityControlRender_WaitFor(QualityControlImpl *This, IMediaSample *sample, HANDLE ev); +void QualityControlRender_DoQOS(QualityControlImpl *priv); +void QualityControlRender_BeginRender(QualityControlImpl *This); +void QualityControlRender_EndRender(QualityControlImpl *This); diff --git a/lib/3rdparty/strmbase/transform.c b/lib/3rdparty/strmbase/transform.c new file mode 100644 index 00000000000..0e014b07756 --- /dev/null +++ b/lib/3rdparty/strmbase/transform.c @@ -0,0 +1,641 @@ +/* + * Transform Filter (Base for decoders, etc...) + * + * Copyright 2005 Christian Costa + * Copyright 2010 Aric Stewart, CodeWeavers + * + * 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 + */ +#include "config.h" +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "dshow.h" +#include "amvideo.h" +#include "strmif.h" +#include "vfw.h" + +#include + +#include "wine/unicode.h" +#include "wine/debug.h" +#include "wine/strmbase.h" +#include "strmbase_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; +static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0}; + +static const IBaseFilterVtbl TransformFilter_Vtbl; +static const IPinVtbl TransformFilter_InputPin_Vtbl; +static const IPinVtbl TransformFilter_OutputPin_Vtbl; +static const IQualityControlVtbl TransformFilter_QualityControl_Vtbl; + +static inline BaseInputPin *impl_BaseInputPin_from_BasePin( BasePin *iface ) +{ + return CONTAINING_RECORD(iface, BaseInputPin, pin); +} + +static inline BasePin *impl_BasePin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BasePin, IPin_iface); +} + +static inline BaseInputPin *impl_BaseInputPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BaseInputPin, pin.IPin_iface); +} + +static inline BaseOutputPin *impl_BaseOutputPin_from_IPin( IPin *iface ) +{ + return CONTAINING_RECORD(iface, BaseOutputPin, pin.IPin_iface); +} + +static inline TransformFilter *impl_from_IBaseFilter( IBaseFilter *iface ) +{ + return CONTAINING_RECORD(iface, TransformFilter, filter.IBaseFilter_iface); +} + +static inline TransformFilter *impl_from_BaseFilter( BaseFilter *iface ) +{ + return CONTAINING_RECORD(iface, TransformFilter, filter); +} + +static HRESULT WINAPI TransformFilter_Input_CheckMediaType(BasePin *iface, const AM_MEDIA_TYPE * pmt) +{ + BaseInputPin* This = impl_BaseInputPin_from_BasePin(iface); + TransformFilter * pTransform; + + TRACE("%p\n", iface); + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + + if (pTransform->pFuncsTable->pfnCheckInputType) + return pTransform->pFuncsTable->pfnCheckInputType(pTransform, pmt); + /* Assume OK if there's no query method (the connection will fail if + needed) */ + return S_OK; +} + +static HRESULT WINAPI TransformFilter_Input_Receive(BaseInputPin *This, IMediaSample *pInSample) +{ + HRESULT hr = S_FALSE; + TransformFilter * pTransform; + TRACE("%p\n", This); + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + + EnterCriticalSection(&pTransform->csReceive); + if (pTransform->filter.state == State_Stopped) + { + LeaveCriticalSection(&pTransform->csReceive); + return VFW_E_WRONG_STATE; + } + + if (This->end_of_stream || This->flushing) + { + LeaveCriticalSection(&pTransform->csReceive); + return S_FALSE; + } + + LeaveCriticalSection(&pTransform->csReceive); + if (pTransform->pFuncsTable->pfnReceive) + hr = pTransform->pFuncsTable->pfnReceive(pTransform, pInSample); + else + hr = S_FALSE; + + return hr; +} + +static HRESULT WINAPI TransformFilter_Output_QueryAccept(IPin *iface, const AM_MEDIA_TYPE * pmt) +{ + BasePin *This = impl_BasePin_from_IPin(iface); + TransformFilter *pTransformFilter = impl_from_IBaseFilter(This->pinInfo.pFilter); + AM_MEDIA_TYPE* outpmt = &pTransformFilter->pmt; + TRACE("%p\n", iface); + + if (IsEqualIID(&pmt->majortype, &outpmt->majortype) + && (IsEqualIID(&pmt->subtype, &outpmt->subtype) || IsEqualIID(&outpmt->subtype, &GUID_NULL))) + return S_OK; + return S_FALSE; +} + +static HRESULT WINAPI TransformFilter_Output_DecideBufferSize(BaseOutputPin *This, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) +{ + TransformFilter *pTransformFilter = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + return pTransformFilter->pFuncsTable->pfnDecideBufferSize(pTransformFilter, pAlloc, ppropInputRequest); +} + +static HRESULT WINAPI TransformFilter_Output_GetMediaType(BasePin *This, int iPosition, AM_MEDIA_TYPE *pmt) +{ + TransformFilter *pTransform = impl_from_IBaseFilter(This->pinInfo.pFilter); + + if (iPosition < 0) + return E_INVALIDARG; + if (iPosition > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(pmt, &pTransform->pmt); + return S_OK; +} + +static IPin* WINAPI TransformFilter_GetPin(BaseFilter *iface, int pos) +{ + TransformFilter *This = impl_from_BaseFilter(iface); + + if (pos >= This->npins || pos < 0) + return NULL; + + IPin_AddRef(This->ppPins[pos]); + return This->ppPins[pos]; +} + +static LONG WINAPI TransformFilter_GetPinCount(BaseFilter *iface) +{ + TransformFilter *This = impl_from_BaseFilter(iface); + + return (This->npins+1); +} + +static const BaseFilterFuncTable tfBaseFuncTable = { + TransformFilter_GetPin, + TransformFilter_GetPinCount +}; + +static const BasePinFuncTable tf_input_BaseFuncTable = { + TransformFilter_Input_CheckMediaType, + NULL, + BasePinImpl_GetMediaTypeVersion, + BasePinImpl_GetMediaType +}; + +static const BaseInputPinFuncTable tf_input_BaseInputFuncTable = { + TransformFilter_Input_Receive +}; + +static const BasePinFuncTable tf_output_BaseFuncTable = { + NULL, + BaseOutputPinImpl_AttemptConnection, + BasePinImpl_GetMediaTypeVersion, + TransformFilter_Output_GetMediaType +}; + +static const BaseOutputPinFuncTable tf_output_BaseOutputFuncTable = { + TransformFilter_Output_DecideBufferSize, + BaseOutputPinImpl_DecideAllocator, + BaseOutputPinImpl_BreakConnect +}; + +static HRESULT TransformFilter_Init(const IBaseFilterVtbl *pVtbl, const CLSID* pClsid, const TransformFilterFuncTable* pFuncsTable, TransformFilter* pTransformFilter) +{ + HRESULT hr; + PIN_INFO piInput; + PIN_INFO piOutput; + + BaseFilter_Init(&pTransformFilter->filter, pVtbl, pClsid, (DWORD_PTR)(__FILE__ ": TransformFilter.csFilter"), &tfBaseFuncTable); + + InitializeCriticalSection(&pTransformFilter->csReceive); + pTransformFilter->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": TransformFilter.csReceive"); + + /* pTransformFilter is already allocated */ + pTransformFilter->pFuncsTable = pFuncsTable; + ZeroMemory(&pTransformFilter->pmt, sizeof(pTransformFilter->pmt)); + pTransformFilter->npins = 2; + + pTransformFilter->ppPins = CoTaskMemAlloc(2 * sizeof(IPin *)); + + /* construct input pin */ + piInput.dir = PINDIR_INPUT; + piInput.pFilter = &pTransformFilter->filter.IBaseFilter_iface; + lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); + piOutput.dir = PINDIR_OUTPUT; + piOutput.pFilter = &pTransformFilter->filter.IBaseFilter_iface; + lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0])); + + hr = BaseInputPin_Construct(&TransformFilter_InputPin_Vtbl, &piInput, &tf_input_BaseFuncTable, &tf_input_BaseInputFuncTable, &pTransformFilter->filter.csFilter, NULL, &pTransformFilter->ppPins[0]); + + if (SUCCEEDED(hr)) + { + hr = BaseOutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(BaseOutputPin), &piOutput, &tf_output_BaseFuncTable, &tf_output_BaseOutputFuncTable, &pTransformFilter->filter.csFilter, &pTransformFilter->ppPins[1]); + + if (FAILED(hr)) + ERR("Cannot create output pin (%x)\n", hr); + else { + QualityControlImpl_Create( pTransformFilter->ppPins[0], &pTransformFilter->filter.IBaseFilter_iface, &pTransformFilter->qcimpl); + pTransformFilter->qcimpl->IQualityControl_iface.lpVtbl = &TransformFilter_QualityControl_Vtbl; + } + } + + if (SUCCEEDED(hr)) + { + ISeekingPassThru *passthru; + pTransformFilter->seekthru_unk = NULL; + hr = CoCreateInstance(&CLSID_SeekingPassThru, (IUnknown*)pTransformFilter, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&pTransformFilter->seekthru_unk); + if (SUCCEEDED(hr)) + { + IUnknown_QueryInterface(pTransformFilter->seekthru_unk, &IID_ISeekingPassThru, (void**)&passthru); + ISeekingPassThru_Init(passthru, FALSE, pTransformFilter->ppPins[0]); + ISeekingPassThru_Release(passthru); + } + } + + if (FAILED(hr)) + { + CoTaskMemFree(pTransformFilter->ppPins); + BaseFilterImpl_Release(&pTransformFilter->filter.IBaseFilter_iface); + } + + return hr; +} + +HRESULT TransformFilter_Construct(const IBaseFilterVtbl *pVtbl, LONG filter_size, const CLSID* pClsid, const TransformFilterFuncTable* pFuncsTable, IBaseFilter ** ppTransformFilter) +{ + TransformFilter* pTf; + + *ppTransformFilter = NULL; + + assert(filter_size >= sizeof(TransformFilter)); + + pTf = CoTaskMemAlloc(filter_size); + + if (!pTf) + return E_OUTOFMEMORY; + + ZeroMemory(pTf, filter_size); + + if (SUCCEEDED(TransformFilter_Init(pVtbl, pClsid, pFuncsTable, pTf))) + { + *ppTransformFilter = &pTf->filter.IBaseFilter_iface; + return S_OK; + } + + CoTaskMemFree(pTf); + return E_FAIL; +} + +HRESULT WINAPI TransformFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) +{ + HRESULT hr; + TransformFilter *This = impl_from_IBaseFilter(iface); + TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv); + + if (IsEqualIID(riid, &IID_IQualityControl)) { + *ppv = (IQualityControl*)This->qcimpl; + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + else if (IsEqualIID(riid, &IID_IMediaSeeking) || + IsEqualIID(riid, &IID_IMediaPosition)) + { + return IUnknown_QueryInterface(This->seekthru_unk, riid, ppv); + } + hr = BaseFilterImpl_QueryInterface(iface, riid, ppv); + + if (FAILED(hr) && !IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow) && + !IsEqualIID(riid, &IID_IAMFilterMiscFlags)) + FIXME("No interface for %s!\n", debugstr_guid(riid)); + + return hr; +} + +ULONG WINAPI TransformFilterImpl_Release(IBaseFilter * iface) +{ + TransformFilter *This = impl_from_IBaseFilter(iface); + ULONG refCount = BaseFilterImpl_Release(iface); + + TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); + + if (!refCount) + { + ULONG i; + + for (i = 0; i < This->npins; i++) + { + IPin *pConnectedTo; + + if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[i], &pConnectedTo))) + { + IPin_Disconnect(pConnectedTo); + IPin_Release(pConnectedTo); + } + IPin_Disconnect(This->ppPins[i]); + + IPin_Release(This->ppPins[i]); + } + + CoTaskMemFree(This->ppPins); + + TRACE("Destroying transform filter\n"); + This->csReceive.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&This->csReceive); + FreeMediaType(&This->pmt); + QualityControlImpl_Destroy(This->qcimpl); + CoTaskMemFree(This); + IUnknown_Release(This->seekthru_unk); + + return 0; + } + else + return refCount; +} + +/** IMediaFilter methods **/ + +HRESULT WINAPI TransformFilterImpl_Stop(IBaseFilter * iface) +{ + TransformFilter *This = impl_from_IBaseFilter(iface); + HRESULT hr = S_OK; + + TRACE("(%p/%p)\n", This, iface); + + EnterCriticalSection(&This->csReceive); + { + This->filter.state = State_Stopped; + if (This->pFuncsTable->pfnStopStreaming) + hr = This->pFuncsTable->pfnStopStreaming(This); + } + LeaveCriticalSection(&This->csReceive); + + return hr; +} + +HRESULT WINAPI TransformFilterImpl_Pause(IBaseFilter * iface) +{ + TransformFilter *This = impl_from_IBaseFilter(iface); + HRESULT hr; + + TRACE("(%p/%p)->()\n", This, iface); + + EnterCriticalSection(&This->csReceive); + { + if (This->filter.state == State_Stopped) + hr = IBaseFilter_Run(iface, -1); + else + hr = S_OK; + + if (SUCCEEDED(hr)) + This->filter.state = State_Paused; + } + LeaveCriticalSection(&This->csReceive); + + return hr; +} + +HRESULT WINAPI TransformFilterImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) +{ + HRESULT hr = S_OK; + TransformFilter *This = impl_from_IBaseFilter(iface); + + TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart)); + + EnterCriticalSection(&This->csReceive); + { + if (This->filter.state == State_Stopped) + { + impl_BaseInputPin_from_IPin(This->ppPins[0])->end_of_stream = 0; + if (This->pFuncsTable->pfnStartStreaming) + hr = This->pFuncsTable->pfnStartStreaming(This); + if (SUCCEEDED(hr)) + hr = BaseOutputPinImpl_Active(impl_BaseOutputPin_from_IPin(This->ppPins[1])); + } + + if (SUCCEEDED(hr)) + { + This->filter.rtStreamStart = tStart; + This->filter.state = State_Running; + } + } + LeaveCriticalSection(&This->csReceive); + + return hr; +} + +HRESULT WINAPI TransformFilterImpl_Notify(TransformFilter *iface, IBaseFilter *sender, Quality qm) +{ + return QualityControlImpl_Notify((IQualityControl*)iface->qcimpl, sender, qm); +} + +/** IBaseFilter implementation **/ + +HRESULT WINAPI TransformFilterImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) +{ + TransformFilter *This = impl_from_IBaseFilter(iface); + + TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_w(Id), ppPin); + + return E_NOTIMPL; +} + +static const IBaseFilterVtbl TransformFilter_Vtbl = +{ + TransformFilterImpl_QueryInterface, + BaseFilterImpl_AddRef, + TransformFilterImpl_Release, + BaseFilterImpl_GetClassID, + TransformFilterImpl_Stop, + TransformFilterImpl_Pause, + TransformFilterImpl_Run, + BaseFilterImpl_GetState, + BaseFilterImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + TransformFilterImpl_FindPin, + BaseFilterImpl_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + BaseFilterImpl_QueryVendorInfo +}; + +static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + TransformFilter* pTransform; + IPin* ppin; + HRESULT hr; + + TRACE("(%p)->()\n", iface); + + /* Since we process samples synchronously, just forward notification downstream */ + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + if (!pTransform) + hr = E_FAIL; + else + hr = IPin_ConnectedTo(pTransform->ppPins[1], &ppin); + if (SUCCEEDED(hr)) + { + hr = IPin_EndOfStream(ppin); + IPin_Release(ppin); + } + + if (FAILED(hr)) + ERR("%x\n", hr); + return hr; +} + +static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + TransformFilter* pTransform; + HRESULT hr = S_OK; + + TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt); + + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + + if (pTransform->pFuncsTable->pfnSetMediaType) + hr = pTransform->pFuncsTable->pfnSetMediaType(pTransform, PINDIR_INPUT, pmt); + + if (SUCCEEDED(hr) && pTransform->pFuncsTable->pfnCompleteConnect) + hr = pTransform->pFuncsTable->pfnCompleteConnect(pTransform, PINDIR_INPUT, pReceivePin); + + if (SUCCEEDED(hr)) + { + hr = BaseInputPinImpl_ReceiveConnection(iface, pReceivePin, pmt); + if (FAILED(hr) && pTransform->pFuncsTable->pfnBreakConnect) + pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT); + } + + return hr; +} + +static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + TransformFilter* pTransform; + + TRACE("(%p)->()\n", iface); + + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + if (pTransform->pFuncsTable->pfnBreakConnect) + pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT); + + return BasePinImpl_Disconnect(iface); +} + +static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + TransformFilter* pTransform; + HRESULT hr = S_OK; + + TRACE("(%p)->()\n", iface); + + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + EnterCriticalSection(&pTransform->filter.csFilter); + if (pTransform->pFuncsTable->pfnBeginFlush) + hr = pTransform->pFuncsTable->pfnBeginFlush(pTransform); + if (SUCCEEDED(hr)) + hr = BaseInputPinImpl_BeginFlush(iface); + LeaveCriticalSection(&pTransform->filter.csFilter); + return hr; +} + +static HRESULT WINAPI TransformFilter_InputPin_EndFlush(IPin * iface) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + TransformFilter* pTransform; + HRESULT hr = S_OK; + + TRACE("(%p)->()\n", iface); + + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + EnterCriticalSection(&pTransform->filter.csFilter); + if (pTransform->pFuncsTable->pfnEndFlush) + hr = pTransform->pFuncsTable->pfnEndFlush(pTransform); + if (SUCCEEDED(hr)) + hr = BaseInputPinImpl_EndFlush(iface); + LeaveCriticalSection(&pTransform->filter.csFilter); + return hr; +} + +static HRESULT WINAPI TransformFilter_InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ + BaseInputPin* This = impl_BaseInputPin_from_IPin(iface); + TransformFilter* pTransform; + HRESULT hr = S_OK; + + TRACE("(%p)->()\n", iface); + + pTransform = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); + EnterCriticalSection(&pTransform->filter.csFilter); + if (pTransform->pFuncsTable->pfnNewSegment) + hr = pTransform->pFuncsTable->pfnNewSegment(pTransform, tStart, tStop, dRate); + if (SUCCEEDED(hr)) + hr = BaseInputPinImpl_NewSegment(iface, tStart, tStop, dRate); + LeaveCriticalSection(&pTransform->filter.csFilter); + return hr; +} + +static const IPinVtbl TransformFilter_InputPin_Vtbl = +{ + BaseInputPinImpl_QueryInterface, + BasePinImpl_AddRef, + BaseInputPinImpl_Release, + BaseInputPinImpl_Connect, + TransformFilter_InputPin_ReceiveConnection, + TransformFilter_InputPin_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BaseInputPinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + TransformFilter_InputPin_EndOfStream, + TransformFilter_InputPin_BeginFlush, + TransformFilter_InputPin_EndFlush, + TransformFilter_InputPin_NewSegment +}; + +static const IPinVtbl TransformFilter_OutputPin_Vtbl = +{ + BaseOutputPinImpl_QueryInterface, + BasePinImpl_AddRef, + BaseOutputPinImpl_Release, + BaseOutputPinImpl_Connect, + BaseOutputPinImpl_ReceiveConnection, + BaseOutputPinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + TransformFilter_Output_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment +}; + +static HRESULT WINAPI TransformFilter_QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) { + QualityControlImpl *qc = (QualityControlImpl*)iface; + TransformFilter *This = impl_from_IBaseFilter(qc->self); + + if (This->pFuncsTable->pfnNotify) + return This->pFuncsTable->pfnNotify(This, sender, qm); + else + return TransformFilterImpl_Notify(This, sender, qm); +} + +static const IQualityControlVtbl TransformFilter_QualityControl_Vtbl = { + QualityControlImpl_QueryInterface, + QualityControlImpl_AddRef, + QualityControlImpl_Release, + TransformFilter_QualityControlImpl_Notify, + QualityControlImpl_SetSink +}; diff --git a/lib/3rdparty/strmbase/video.c b/lib/3rdparty/strmbase/video.c new file mode 100644 index 00000000000..1c4f3606f67 --- /dev/null +++ b/lib/3rdparty/strmbase/video.c @@ -0,0 +1,488 @@ +/* + * Generic Implementation of strmbase video classes + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include +#include "dshow.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static inline BaseControlVideo *impl_from_IBasicVideo(IBasicVideo *iface) +{ + return CONTAINING_RECORD(iface, BaseControlVideo, IBasicVideo_iface); +} + +HRESULT WINAPI BaseControlVideo_Init(BaseControlVideo *pControlVideo, const IBasicVideoVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin, const BaseControlVideoFuncTable* pFuncsTable) +{ + pControlVideo->IBasicVideo_iface.lpVtbl = lpVtbl; + pControlVideo->pFilter = owner; + pControlVideo->pInterfaceLock = lock; + pControlVideo->pPin = pPin; + pControlVideo->pFuncsTable = pFuncsTable; + + BaseDispatch_Init(&pControlVideo->baseDispatch, &IID_IBasicVideo); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideo_Destroy(BaseControlVideo *pControlVideo) +{ + return BaseDispatch_Destroy(&pControlVideo->baseDispatch); +} + +HRESULT WINAPI BaseControlVideoImpl_GetTypeInfoCount(IBasicVideo *iface, UINT *pctinfo) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo); +} + +HRESULT WINAPI BaseControlVideoImpl_GetTypeInfo(IBasicVideo *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo); +} + +HRESULT WINAPI BaseControlVideoImpl_GetIDsOfNames(IBasicVideo *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId); +} + +HRESULT WINAPI BaseControlVideoImpl_Invoke(IBasicVideo *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + HRESULT hr = S_OK; + ITypeInfo *pTypeInfo; + + hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(pTypeInfo, &This->IBasicVideo_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); + ITypeInfo_Release(pTypeInfo); + } + + return hr; +} + +HRESULT WINAPI BaseControlVideoImpl_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *pAvgTimePerFrame) +{ + VIDEOINFOHEADER *vih; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + if (!This->pPin->pConnectedTo) + return VFW_E_NOT_CONNECTED; + + TRACE("(%p/%p)->(%p)\n", This, iface, pAvgTimePerFrame); + + vih = This->pFuncsTable->pfnGetVideoFormat(This); + *pAvgTimePerFrame = vih->AvgTimePerFrame; + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_BitRate(IBasicVideo *iface, LONG *pBitRate) +{ + VIDEOINFOHEADER *vih; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pBitRate); + + if (!This->pPin->pConnectedTo) + return VFW_E_NOT_CONNECTED; + + vih = This->pFuncsTable->pfnGetVideoFormat(This); + *pBitRate = vih->dwBitRate; + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_BitErrorRate(IBasicVideo *iface, LONG *pBitErrorRate) +{ + VIDEOINFOHEADER *vih; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pBitErrorRate); + + if (!This->pPin->pConnectedTo) + return VFW_E_NOT_CONNECTED; + + vih = This->pFuncsTable->pfnGetVideoFormat(This); + *pBitErrorRate = vih->dwBitErrorRate; + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_VideoWidth(IBasicVideo *iface, LONG *pVideoWidth) +{ + VIDEOINFOHEADER *vih; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth); + + vih = This->pFuncsTable->pfnGetVideoFormat(This); + *pVideoWidth = vih->bmiHeader.biWidth; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_VideoHeight(IBasicVideo *iface, LONG *pVideoHeight) +{ + VIDEOINFOHEADER *vih; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight); + + vih = This->pFuncsTable->pfnGetVideoFormat(This); + *pVideoHeight = abs(vih->bmiHeader.biHeight); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_SourceLeft(IBasicVideo *iface, LONG SourceLeft) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, SourceLeft); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + SourceRect.left = SourceLeft; + This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_SourceLeft(IBasicVideo *iface, LONG *pSourceLeft) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + *pSourceLeft = SourceRect.left; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_SourceWidth(IBasicVideo *iface, LONG SourceWidth) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, SourceWidth); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + SourceRect.right = SourceRect.left + SourceWidth; + This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_SourceWidth(IBasicVideo *iface, LONG *pSourceWidth) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + *pSourceWidth = SourceRect.right - SourceRect.left; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_SourceTop(IBasicVideo *iface, LONG SourceTop) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, SourceTop); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + SourceRect.top = SourceTop; + This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_SourceTop(IBasicVideo *iface, LONG *pSourceTop) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + *pSourceTop = SourceRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_SourceHeight(IBasicVideo *iface, LONG SourceHeight) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, SourceHeight); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + SourceRect.bottom = SourceRect.top + SourceHeight; + This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_SourceHeight(IBasicVideo *iface, LONG *pSourceHeight) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + + *pSourceHeight = SourceRect.bottom - SourceRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_DestinationLeft(IBasicVideo *iface, LONG DestinationLeft) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, DestinationLeft); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + DestRect.left = DestinationLeft; + This->pFuncsTable->pfnSetTargetRect(This, &DestRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_DestinationLeft(IBasicVideo *iface, LONG *pDestinationLeft) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + *pDestinationLeft = DestRect.left; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_DestinationWidth(IBasicVideo *iface, LONG DestinationWidth) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, DestinationWidth); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + DestRect.right = DestRect.left + DestinationWidth; + This->pFuncsTable->pfnSetTargetRect(This, &DestRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_DestinationWidth(IBasicVideo *iface, LONG *pDestinationWidth) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + *pDestinationWidth = DestRect.right - DestRect.left; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_DestinationTop(IBasicVideo *iface, LONG DestinationTop) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, DestinationTop); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + DestRect.top = DestinationTop; + This->pFuncsTable->pfnSetTargetRect(This, &DestRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_DestinationTop(IBasicVideo *iface, LONG *pDestinationTop) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + *pDestinationTop = DestRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_put_DestinationHeight(IBasicVideo *iface, LONG DestinationHeight) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, DestinationHeight); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + DestRect.right = DestRect.left + DestinationHeight; + This->pFuncsTable->pfnSetTargetRect(This, &DestRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_get_DestinationHeight(IBasicVideo *iface, LONG *pDestinationHeight) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + *pDestinationHeight = DestRect.right - DestRect.left; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_SetSourcePosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); + SourceRect.left = Left; + SourceRect.top = Top; + SourceRect.right = Left + Width; + SourceRect.bottom = Top + Height; + This->pFuncsTable->pfnSetSourceRect(This, &SourceRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_GetSourcePosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) +{ + RECT SourceRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); + This->pFuncsTable->pfnGetSourceRect(This, &SourceRect); + + *pLeft = SourceRect.left; + *pTop = SourceRect.top; + *pWidth = SourceRect.right - SourceRect.left; + *pHeight = SourceRect.bottom - SourceRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_SetDefaultSourcePosition(IBasicVideo *iface) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->()\n", This, iface); + return This->pFuncsTable->pfnSetDefaultSourceRect(This); +} + +HRESULT WINAPI BaseControlVideoImpl_SetDestinationPosition(IBasicVideo *iface, LONG Left, LONG Top, LONG Width, LONG Height) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); + + DestRect.left = Left; + DestRect.top = Top; + DestRect.right = Left + Width; + DestRect.bottom = Top + Height; + This->pFuncsTable->pfnSetTargetRect(This, &DestRect); + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_GetDestinationPosition(IBasicVideo *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) +{ + RECT DestRect; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); + This->pFuncsTable->pfnGetTargetRect(This, &DestRect); + + *pLeft = DestRect.left; + *pTop = DestRect.top; + *pWidth = DestRect.right - DestRect.left; + *pHeight = DestRect.bottom - DestRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_SetDefaultDestinationPosition(IBasicVideo *iface) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->()\n", This, iface); + return This->pFuncsTable->pfnSetDefaultTargetRect(This); +} + +HRESULT WINAPI BaseControlVideoImpl_GetVideoSize(IBasicVideo *iface, LONG *pWidth, LONG *pHeight) +{ + VIDEOINFOHEADER *vih; + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); + + vih = This->pFuncsTable->pfnGetVideoFormat(This); + *pHeight = vih->bmiHeader.biHeight; + *pWidth = vih->bmiHeader.biWidth; + + return S_OK; +} + +HRESULT WINAPI BaseControlVideoImpl_GetVideoPaletteEntries(IBasicVideo *iface, LONG StartIndex, LONG Entries, LONG *pRetrieved, LONG *pPalette) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This, iface, StartIndex, Entries, pRetrieved, pPalette); + + if (pRetrieved) + *pRetrieved = 0; + return VFW_E_NO_PALETTE_AVAILABLE; +} + +HRESULT WINAPI BaseControlVideoImpl_GetCurrentImage(IBasicVideo *iface, LONG *pBufferSize, LONG *pDIBImage) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + return This->pFuncsTable->pfnGetStaticImage(This, pBufferSize, pDIBImage); +} + +HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultSource(IBasicVideo *iface) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + return This->pFuncsTable->pfnIsDefaultSourceRect(This); +} + +HRESULT WINAPI BaseControlVideoImpl_IsUsingDefaultDestination(IBasicVideo *iface) +{ + BaseControlVideo *This = impl_from_IBasicVideo(iface); + + return This->pFuncsTable->pfnIsDefaultTargetRect(This); +} diff --git a/lib/3rdparty/strmbase/window.c b/lib/3rdparty/strmbase/window.c new file mode 100644 index 00000000000..cb448e347b1 --- /dev/null +++ b/lib/3rdparty/strmbase/window.c @@ -0,0 +1,738 @@ +/* + * Generic Implementation of strmbase window classes + * + * Copyright 2012 Aric Stewart, CodeWeavers + * + * 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 + */ + +#define COBJMACROS + +#include "dshow.h" +#include "wine/debug.h" +#include "wine/unicode.h" +#include "wine/strmbase.h" +#include "uuids.h" +#include "vfwmsgs.h" +#include + +WINE_DEFAULT_DEBUG_CHANNEL(strmbase); + +static inline BaseControlWindow *impl_from_IVideoWindow( IVideoWindow *iface) +{ + return CONTAINING_RECORD(iface, BaseControlWindow, IVideoWindow_iface); +} + +static inline BaseControlWindow *impl_from_BaseWindow(BaseWindow *iface) +{ + return CONTAINING_RECORD(iface, BaseControlWindow, baseWindow); +} + +static LRESULT CALLBACK WndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + BaseWindow* This = (BaseWindow*)GetWindowLongPtrW(hwnd, 0); + + if (!This) + return DefWindowProcW(hwnd, uMsg, wParam, lParam); + + if (This->pFuncsTable->pfnOnReceiveMessage) + return This->pFuncsTable->pfnOnReceiveMessage(This, hwnd, uMsg, wParam, lParam); + else + return BaseWindowImpl_OnReceiveMessage(This, hwnd, uMsg, wParam, lParam); +} + +LRESULT WINAPI BaseWindowImpl_OnReceiveMessage(BaseWindow *This, HWND hwnd, INT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (This->pFuncsTable->pfnPossiblyEatMessage && This->pFuncsTable->pfnPossiblyEatMessage(This, uMsg, wParam, lParam)) + return 0; + + switch (uMsg) + { + case WM_SIZE: + if (This->pFuncsTable->pfnOnSize) + return This->pFuncsTable->pfnOnSize(This, LOWORD(lParam), HIWORD(lParam)); + else + return BaseWindowImpl_OnSize(This, LOWORD(lParam), HIWORD(lParam)); + } + + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +} + +BOOL WINAPI BaseWindowImpl_OnSize(BaseWindow *This, LONG Width, LONG Height) +{ + This->Width = Width; + This->Height = Height; + return TRUE; +} + +HRESULT WINAPI BaseWindow_Init(BaseWindow *pBaseWindow, const BaseWindowFuncTable* pFuncsTable) +{ + if (!pFuncsTable) + return E_INVALIDARG; + + ZeroMemory(pBaseWindow,sizeof(BaseWindow)); + pBaseWindow->pFuncsTable = pFuncsTable; + + return S_OK; +} + +HRESULT WINAPI BaseWindow_Destroy(BaseWindow *This) +{ + if (This->hWnd) + BaseWindowImpl_DoneWithWindow(This); + + HeapFree(GetProcessHeap(), 0, This); + return S_OK; +} + +HRESULT WINAPI BaseWindowImpl_PrepareWindow(BaseWindow *This) +{ + WNDCLASSW winclass; + static const WCHAR windownameW[] = { 'A','c','t','i','v','e','M','o','v','i','e',' ','W','i','n','d','o','w',0 }; + + This->pClassName = This->pFuncsTable->pfnGetClassWindowStyles(This, &This->ClassStyles, &This->WindowStyles, &This->WindowStylesEx); + + winclass.style = This->ClassStyles; + winclass.lpfnWndProc = WndProcW; + winclass.cbClsExtra = 0; + winclass.cbWndExtra = sizeof(BaseWindow*); + winclass.hInstance = This->hInstance; + winclass.hIcon = NULL; + winclass.hCursor = NULL; + winclass.hbrBackground = GetStockObject(BLACK_BRUSH); + winclass.lpszMenuName = NULL; + winclass.lpszClassName = This->pClassName; + if (!RegisterClassW(&winclass) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + ERR("Unable to register window class: %u\n", GetLastError()); + return E_FAIL; + } + + This->hWnd = CreateWindowExW(This->WindowStylesEx, + This->pClassName, windownameW, + This->WindowStyles, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, NULL, NULL, This->hInstance, + NULL); + + if (!This->hWnd) + { + ERR("Unable to create window\n"); + return E_FAIL; + } + + SetWindowLongPtrW(This->hWnd, 0, (LONG_PTR)This); + + This->hDC = GetDC(This->hWnd); + + return S_OK; +} + +HRESULT WINAPI BaseWindowImpl_DoneWithWindow(BaseWindow *This) +{ + if (!This->hWnd) + return S_OK; + + if (This->hDC) + ReleaseDC(This->hWnd, This->hDC); + This->hDC = NULL; + + DestroyWindow(This->hWnd); + This->hWnd = NULL; + + return S_OK; +} + +RECT WINAPI BaseWindowImpl_GetDefaultRect(BaseWindow *This) +{ + static RECT defRect = {0, 0, 800, 600}; + return defRect; +} + +BOOL WINAPI BaseControlWindowImpl_PossiblyEatMessage(BaseWindow *This, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + BaseControlWindow* pControlWindow = impl_from_BaseWindow(This); + + if (pControlWindow->hwndDrain) + { + switch(uMsg) + { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MOUSEACTIVATE: + case WM_MOUSEMOVE: + case WM_NCLBUTTONDBLCLK: + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + case WM_NCMBUTTONDBLCLK: + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONUP: + case WM_NCMOUSEMOVE: + case WM_NCRBUTTONDBLCLK: + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + PostMessageW(pControlWindow->hwndDrain, uMsg, wParam, lParam); + return TRUE; + default: + break; + } + } + return FALSE; +} + +HRESULT WINAPI BaseControlWindow_Init(BaseControlWindow *pControlWindow, const IVideoWindowVtbl *lpVtbl, BaseFilter *owner, CRITICAL_SECTION *lock, BasePin* pPin,const BaseWindowFuncTable *pFuncsTable) +{ + HRESULT hr; + + hr = BaseWindow_Init(&pControlWindow->baseWindow, pFuncsTable); + if (SUCCEEDED(hr)) + { + BaseDispatch_Init(&pControlWindow->baseDispatch, &IID_IVideoWindow); + pControlWindow->IVideoWindow_iface.lpVtbl = lpVtbl; + pControlWindow->AutoShow = TRUE; + pControlWindow->hwndDrain = NULL; + pControlWindow->hwndOwner = NULL; + pControlWindow->pFilter = owner; + pControlWindow->pInterfaceLock = lock; + pControlWindow->pPin = pPin; + } + return hr; +} + +HRESULT WINAPI BaseControlWindow_Destroy(BaseControlWindow *pControlWindow) +{ + BaseWindowImpl_DoneWithWindow(&pControlWindow->baseWindow); + return BaseDispatch_Destroy(&pControlWindow->baseDispatch); +} + +HRESULT WINAPI BaseControlWindowImpl_GetTypeInfoCount(IVideoWindow *iface, UINT *pctinfo) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + return BaseDispatchImpl_GetTypeInfoCount(&This->baseDispatch, pctinfo); +} + +HRESULT WINAPI BaseControlWindowImpl_GetTypeInfo(IVideoWindow *iface, UINT iTInfo, LCID lcid, ITypeInfo**ppTInfo) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + return BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, &IID_NULL, iTInfo, lcid, ppTInfo); +} + +HRESULT WINAPI BaseControlWindowImpl_GetIDsOfNames(IVideoWindow *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) + { + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + return BaseDispatchImpl_GetIDsOfNames(&This->baseDispatch, riid, rgszNames, cNames, lcid, rgDispId); +} + +HRESULT WINAPI BaseControlWindowImpl_Invoke(IVideoWindow *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + HRESULT hr = S_OK; + ITypeInfo *pTypeInfo; + + hr = BaseDispatchImpl_GetTypeInfo(&This->baseDispatch, riid, 1, lcid, &pTypeInfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(pTypeInfo, &This->IVideoWindow_iface, dispIdMember, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); + ITypeInfo_Release(pTypeInfo); + } + + return hr; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Caption(IVideoWindow *iface, BSTR strCaption) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption); + + if (!SetWindowTextW(This->baseWindow.hWnd, strCaption)) + return E_FAIL; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Caption(IVideoWindow *iface, BSTR *strCaption) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, strCaption); + + GetWindowTextW(This->baseWindow.hWnd, (LPWSTR)strCaption, 100); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_WindowStyle(IVideoWindow *iface, LONG WindowStyle) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + LONG old; + + old = GetWindowLongW(This->baseWindow.hWnd, GWL_STYLE); + + TRACE("(%p/%p)->(%x -> %x)\n", This, iface, old, WindowStyle); + + if (WindowStyle & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) + return E_INVALIDARG; + + SetWindowLongW(This->baseWindow.hWnd, GWL_STYLE, WindowStyle); + SetWindowPos(This->baseWindow.hWnd,0,0,0,0,0,SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOZORDER); + This->baseWindow.WindowStyles = WindowStyle; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_WindowStyle(IVideoWindow *iface, LONG *WindowStyle) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle); + + *WindowStyle = This->baseWindow.WindowStyles; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_WindowStyleEx(IVideoWindow *iface, LONG WindowStyleEx) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, WindowStyleEx); + + if (!SetWindowLongW(This->baseWindow.hWnd, GWL_EXSTYLE, WindowStyleEx)) + return E_FAIL; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_WindowStyleEx(IVideoWindow *iface, LONG *WindowStyleEx) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx); + + *WindowStyleEx = GetWindowLongW(This->baseWindow.hWnd, GWL_EXSTYLE); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_AutoShow(IVideoWindow *iface, LONG AutoShow) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow); + + This->AutoShow = AutoShow; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_AutoShow(IVideoWindow *iface, LONG *AutoShow) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow); + + *AutoShow = This->AutoShow; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_WindowState(IVideoWindow *iface, LONG WindowState) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, WindowState); + ShowWindow(This->baseWindow.hWnd, WindowState); + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_WindowState(IVideoWindow *iface, LONG *WindowState) +{ + WINDOWPLACEMENT place; + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + place.length = sizeof(place); + GetWindowPlacement(This->baseWindow.hWnd, &place); + TRACE("(%p/%p)->(%p)\n", This, iface, WindowState); + *WindowState = place.showCmd; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_BackgroundPalette(IVideoWindow *iface, LONG BackgroundPalette) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, BackgroundPalette); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_BackgroundPalette(IVideoWindow *iface, LONG *pBackgroundPalette) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Visible(IVideoWindow *iface, LONG Visible) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, Visible); + + ShowWindow(This->baseWindow.hWnd, Visible ? SW_SHOW : SW_HIDE); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Visible(IVideoWindow *iface, LONG *pVisible) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pVisible); + + *pVisible = IsWindowVisible(This->baseWindow.hWnd); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Left(IVideoWindow *iface, LONG Left) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT WindowPos; + + TRACE("(%p/%p)->(%d)\n", This, iface, Left); + + GetWindowRect(This->baseWindow.hWnd, &WindowPos); + if (!SetWindowPos(This->baseWindow.hWnd, NULL, Left, WindowPos.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) + return E_FAIL; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Left(IVideoWindow *iface, LONG *pLeft) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT WindowPos; + + TRACE("(%p/%p)->(%p)\n", This, iface, pLeft); + GetWindowRect(This->baseWindow.hWnd, &WindowPos); + + *pLeft = WindowPos.left; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Width(IVideoWindow *iface, LONG Width) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, Width); + + if (!SetWindowPos(This->baseWindow.hWnd, NULL, 0, 0, Width, This->baseWindow.Height, SWP_NOZORDER|SWP_NOMOVE)) + return E_FAIL; + + This->baseWindow.Width = Width; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Width(IVideoWindow *iface, LONG *pWidth) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pWidth); + + *pWidth = This->baseWindow.Width; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Top(IVideoWindow *iface, LONG Top) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT WindowPos; + + TRACE("(%p/%p)->(%d)\n", This, iface, Top); + GetWindowRect(This->baseWindow.hWnd, &WindowPos); + + if (!SetWindowPos(This->baseWindow.hWnd, NULL, WindowPos.left, Top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) + return E_FAIL; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Top(IVideoWindow *iface, LONG *pTop) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT WindowPos; + + TRACE("(%p/%p)->(%p)\n", This, iface, pTop); + GetWindowRect(This->baseWindow.hWnd, &WindowPos); + + *pTop = WindowPos.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Height(IVideoWindow *iface, LONG Height) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d)\n", This, iface, Height); + + if (!SetWindowPos(This->baseWindow.hWnd, NULL, 0, 0, This->baseWindow.Width, Height, SWP_NOZORDER|SWP_NOMOVE)) + return E_FAIL; + + This->baseWindow.Height = Height; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Height(IVideoWindow *iface, LONG *pHeight) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pHeight); + + *pHeight = This->baseWindow.Height; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_Owner(IVideoWindow *iface, OAHWND Owner) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner); + + This->hwndOwner = (HWND)Owner; + SetParent(This->baseWindow.hWnd, This->hwndOwner); + if (This->baseWindow.WindowStyles & WS_CHILD) + { + LONG old = GetWindowLongW(This->baseWindow.hWnd, GWL_STYLE); + if (old != This->baseWindow.WindowStyles) + { + SetWindowLongW(This->baseWindow.hWnd, GWL_STYLE, This->baseWindow.WindowStyles); + SetWindowPos(This->baseWindow.hWnd,0,0,0,0,0,SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOZORDER); + } + } + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_Owner(IVideoWindow *iface, OAHWND *Owner) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, Owner); + + *(HWND*)Owner = This->hwndOwner; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_MessageDrain(IVideoWindow *iface, OAHWND Drain) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain); + + This->hwndDrain = (HWND)Drain; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_MessageDrain(IVideoWindow *iface, OAHWND *Drain) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, Drain); + + *Drain = (OAHWND)This->hwndDrain; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_BorderColor(IVideoWindow *iface, LONG *Color) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_put_BorderColor(IVideoWindow *iface, LONG Color) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, Color); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode) +{ + TRACE("(%p)->(%p)\n", iface, FullScreenMode); + + return E_NOTIMPL; +} + +HRESULT WINAPI BaseControlWindowImpl_put_FullScreenMode(IVideoWindow *iface, LONG FullScreenMode) +{ + TRACE("(%p)->(%d)\n", iface, FullScreenMode); + return E_NOTIMPL; +} + +HRESULT WINAPI BaseControlWindowImpl_SetWindowForeground(IVideoWindow *iface, LONG Focus) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + BOOL ret; + IPin* pPin; + HRESULT hr; + + TRACE("(%p/%p)->(%d)\n", This, iface, Focus); + + if ((Focus != FALSE) && (Focus != TRUE)) + return E_INVALIDARG; + + hr = IPin_ConnectedTo(&This->pPin->IPin_iface, &pPin); + if ((hr != S_OK) || !pPin) + return VFW_E_NOT_CONNECTED; + + if (Focus) + ret = SetForegroundWindow(This->baseWindow.hWnd); + else + ret = SetWindowPos(This->baseWindow.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + + if (!ret) + return E_FAIL; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_SetWindowPosition(IVideoWindow *iface, LONG Left, LONG Top, LONG Width, LONG Height) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This, iface, Left, Top, Width, Height); + + if (!SetWindowPos(This->baseWindow.hWnd, NULL, Left, Top, Width, Height, SWP_NOZORDER)) + return E_FAIL; + + This->baseWindow.Width = Width; + This->baseWindow.Height = Height; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_GetWindowPosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT WindowPos; + + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); + GetWindowRect(This->baseWindow.hWnd, &WindowPos); + + *pLeft = WindowPos.left; + *pTop = WindowPos.top; + *pWidth = This->baseWindow.Width; + *pHeight = This->baseWindow.Height; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_NotifyOwnerMessage(IVideoWindow *iface, OAHWND hwnd, LONG uMsg, LONG_PTR wParam, LONG_PTR lParam) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This, iface, hwnd, uMsg, wParam, lParam); + + if (!PostMessageW(This->baseWindow.hWnd, uMsg, wParam, lParam)) + return E_FAIL; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_GetMinIdealImageSize(IVideoWindow *iface, LONG *pWidth, LONG *pHeight) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT defaultRect; + + TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); + defaultRect = This->baseWindow.pFuncsTable->pfnGetDefaultRect(&This->baseWindow); + + *pWidth = defaultRect.right - defaultRect.left; + *pHeight = defaultRect.bottom - defaultRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow *iface, LONG *pWidth, LONG *pHeight) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + RECT defaultRect; + + TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); + defaultRect = This->baseWindow.pFuncsTable->pfnGetDefaultRect(&This->baseWindow); + + *pWidth = defaultRect.right - defaultRect.left; + *pHeight = defaultRect.bottom - defaultRect.top; + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_GetRestorePosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_HideCursor(IVideoWindow *iface, LONG HideCursor) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, HideCursor); + + return S_OK; +} + +HRESULT WINAPI BaseControlWindowImpl_IsCursorHidden(IVideoWindow *iface, LONG *CursorHidden) +{ + BaseControlWindow* This = impl_from_IVideoWindow(iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden); + + return S_OK; +} diff --git a/lib/3rdparty/zlib/ChangeLog b/lib/3rdparty/zlib/ChangeLog index c2c643a1a9b..f22aabaef53 100644 --- a/lib/3rdparty/zlib/ChangeLog +++ b/lib/3rdparty/zlib/ChangeLog @@ -1,6 +1,69 @@ ChangeLog file for zlib +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Ro] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix unintialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Suport i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + Changes in 1.2.7 (2 May 2012) - Replace use of memmove() with a simple copy for portability - Test for existence of strerror diff --git a/lib/3rdparty/zlib/Makefile.in b/lib/3rdparty/zlib/Makefile.in index 241deed83ae..c61aa3008d4 100644 --- a/lib/3rdparty/zlib/Makefile.in +++ b/lib/3rdparty/zlib/Makefile.in @@ -1,5 +1,5 @@ # Makefile for zlib -# Copyright (C) 1995-2011 Jean-loup Gailly. +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler # For conditions of distribution and use, see copyright notice in zlib.h # To compile and test, type: @@ -32,7 +32,7 @@ CPP=$(CC) -E STATICLIB=libz.a SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.7 +SHAREDLIBV=libz.so.1.2.8 SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) @@ -83,7 +83,7 @@ check: test test: all teststatic testshared teststatic: static - @TMPST=`mktemp fooXXXXXX`; \ + @TMPST=tmpst_$$; \ if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \ echo ' *** zlib test OK ***'; \ else \ @@ -96,7 +96,7 @@ testshared: shared LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ - TMPSH=`mktemp fooXXXXXX`; \ + TMPSH=tmpsh_$$; \ if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \ echo ' *** zlib shared test OK ***'; \ else \ @@ -105,7 +105,7 @@ testshared: shared rm -f $$TMPSH test64: all64 - @TMP64=`mktemp fooXXXXXX`; \ + @TMP64=tmp64_$$; \ if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \ echo ' *** zlib 64-bit test OK ***'; \ else \ @@ -216,13 +216,13 @@ install: install-libs chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h uninstall: - cd $(DESTDIR)$(includedir); rm -f zlib.h zconf.h - cd $(DESTDIR)$(libdir); rm -f libz.a; \ + cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h + cd $(DESTDIR)$(libdir) && rm -f libz.a; \ if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ fi - cd $(DESTDIR)$(man3dir); rm -f zlib.3 - cd $(DESTDIR)$(pkgconfigdir); rm -f zlib.pc + cd $(DESTDIR)$(man3dir) && rm -f zlib.3 + cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc docs: zlib.3.pdf @@ -230,7 +230,7 @@ zlib.3.pdf: zlib.3 groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf zconf.h.cmakein: zconf.h.in - -@ TEMPFILE=`mktemp __XXXXXX`; \ + -@ TEMPFILE=zconfh_$$; \ echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\ touch -r zconf.h.in zconf.h.cmakein &&\ diff --git a/lib/3rdparty/zlib/README b/lib/3rdparty/zlib/README index 6f1255ffe48..5ca9d127eda 100644 --- a/lib/3rdparty/zlib/README +++ b/lib/3rdparty/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.7 is a general purpose data compression library. All the code is +zlib 1.2.8 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.7 are documented in the file ChangeLog. +The changes made in version 1.2.8 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -84,7 +84,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2012 Jean-loup Gailly and Mark Adler + (C) 1995-2013 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/lib/3rdparty/zlib/compress.c b/lib/3rdparty/zlib/compress.c index ea4dfbe9d7b..6e9762676a0 100644 --- a/lib/3rdparty/zlib/compress.c +++ b/lib/3rdparty/zlib/compress.c @@ -29,7 +29,7 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K /* Check for source > 64K on 16-bit machine: */ diff --git a/lib/3rdparty/zlib/configure b/lib/3rdparty/zlib/configure index 36c7d8ec215..b77a8a8cf95 100644 --- a/lib/3rdparty/zlib/configure +++ b/lib/3rdparty/zlib/configure @@ -70,6 +70,7 @@ shared=1 solo=0 cover=0 zprefix=0 +zconst=0 build64=0 gcc=0 old_cc="$CC" @@ -77,13 +78,26 @@ old_cflags="$CFLAGS" OBJC='$(OBJZ) $(OBJG)' PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)' +# leave this script, optionally in a bad way +leave() +{ + if test "$*" != "0"; then + echo "** $0 aborting." | tee -a configure.log + fi + rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + echo -------------------- >> configure.log + echo >> configure.log + echo >> configure.log + exit $1 +} + # process command line options while test $# -ge 1 do case "$1" in -h* | --help) echo 'usage:' | tee -a configure.log - echo ' configure [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log exit 0 ;; @@ -106,13 +120,18 @@ case "$1" in -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;; --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; - *) echo "unknown option: $1"; echo "$0 --help for help" | tee -a configure.log; exit 1 ;; + -c* | --const) zconst=1; shift ;; + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log + leave 1;; esac done -# define functions for testing compiler and library characteristics and logging the results +# temporary file name test=ztest$$ +# put arguments in log, also put test file in log if used in arguments show() { case "$*" in @@ -124,43 +143,6 @@ show() echo $* >> configure.log } -cat > $test.c </dev/null; then - try() - { - show $* - test "`( $* ) 2>&1 | tee -a configure.log`" = "" - } - echo - using any output from compiler to indicate an error >> configure.log -else - try() - { - show $* - ( $* ) >> configure.log 2>&1 - ret=$? - if test $ret -ne 0; then - echo "(exit code "$ret")" >> configure.log - fi - return $ret - } -fi - -tryboth() -{ - show $* - got=`( $* ) 2>&1` - ret=$? - printf %s "$got" >> configure.log - if test $ret -ne 0; then - return $ret - fi - test "$got" = "" -} - -echo >> configure.log - # check for gcc vs. cc and set compile and link flags based on the system identified by uname cat > $test.c <&1` in *gcc*) gcc=1 ;; esac -show $cc -c $cflags $test.c -if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then +show $cc -c $test.c +if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then echo ... using gcc >> configure.log CC="$cc" CFLAGS="${CFLAGS--O3} ${ARCHS}" @@ -191,7 +173,11 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then SFLAGS="${SFLAGS} -m64" fi if test "${ZLIBGCCWARN}" = "YES"; then - CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + if test "$zconst" -eq 1; then + CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST" + else + CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + fi fi if test -z "$uname"; then uname=`(uname -s || echo unknown) 2>/dev/null` @@ -208,7 +194,7 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then # temporary bypass rm -f $test.[co] $test $test$shared_ext echo "Please use win32/Makefile.gcc instead." | tee -a configure.log - exit 1 + leave 1 LDSHARED=${LDSHARED-"$cc -shared"} LDSHAREDLIBC="" EXE='.exe' ;; @@ -231,7 +217,11 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) >> configure.log 2>&1; then SHAREDLIBV=libz.$VER$shared_ext SHAREDLIBM=libz.$VER1$shared_ext LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} - AR="/usr/bin/libtool" + if libtool -V 2>&1 | grep Apple > /dev/null; then + AR="libtool" + else + AR="/usr/bin/libtool" + fi ARFLAGS="-o" ;; *) LDSHARED=${LDSHARED-"$cc -shared"} ;; esac @@ -334,7 +324,61 @@ SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} echo >> configure.log +# define functions for testing compiler and library characteristics and logging the results + +cat > $test.c </dev/null; then + try() + { + show $* + test "`( $* ) 2>&1 | tee -a configure.log`" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else +try() +{ + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code "$ret")" >> configure.log + fi + return $ret +} +fi + +tryboth() +{ + show $* + got=`( $* ) 2>&1` + ret=$? + printf %s "$got" >> configure.log + if test $ret -ne 0; then + return $ret + fi + test "$got" = "" +} + +cat > $test.c << EOF +int foo() { return 0; } +EOF +echo "Checking for obsessive-compulsive compiler options..." >> configure.log +if try $CC -c $CFLAGS $test.c; then + : +else + echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log + leave 1 +fi + +echo >> configure.log + # see if shared library build supported +cat > $test.c <> configure.log - # check for underscores in external names for use by assembler code CPP=${CPP-"$CC -E"} case $CFLAGS in @@ -698,35 +740,6 @@ EOF fi fi -echo >> configure.log - -# find a four-byte unsiged integer type for crc calculations -cat > $test.c < -#define is32(n,t) for(n=1,k=0;n;n<<=1,k++);if(k==32){puts(t);return 0;} -int main() { - int k; - unsigned i; - unsigned long l; - unsigned short s; - is32(i, "unsigned") - is32(l, "unsigned long") - is32(s, "unsigned short") - return 1; -} -EOF -Z_U4="" -if try $CC $CFLAGS $test.c -o $test && Z_U4=`./$test` && test -n "$Z_U4"; then - sed < zconf.h "/#define Z_U4/s/\/\* \.\/configure may/#define Z_U4 $Z_U4 \/* .\/configure put the/" > zconf.temp.h - mv zconf.temp.h zconf.h - echo "Looking for a four-byte integer type... Found." | tee -a configure.log -else - echo "Looking for a four-byte integer type... Not found." | tee -a configure.log -fi - -# clean up files produced by running the compiler and linker -rm -f $test.[co] $test $test$shared_ext $test.gcno - # show the results in the log echo >> configure.log echo ALL = $ALL >> configure.log @@ -758,9 +771,6 @@ echo mandir = $mandir >> configure.log echo prefix = $prefix >> configure.log echo sharedlibdir = $sharedlibdir >> configure.log echo uname = $uname >> configure.log -echo -------------------- >> configure.log -echo >> configure.log -echo >> configure.log # udpate Makefile with the configure results sed < Makefile.in " @@ -816,3 +826,6 @@ sed < zlib.pc.in " " | sed -e " s/\@VERSION\@/$VER/g; " > zlib.pc + +# done +leave 0 diff --git a/lib/3rdparty/zlib/deflate.c b/lib/3rdparty/zlib/deflate.c index 9e4c2cbc8af..696957705b7 100644 --- a/lib/3rdparty/zlib/deflate.c +++ b/lib/3rdparty/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -305,7 +305,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + strm->msg = ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } @@ -329,7 +329,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) uInt str, n; int wrap; unsigned avail; - unsigned char *next; + z_const unsigned char *next; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) return Z_STREAM_ERROR; @@ -359,7 +359,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) avail = strm->avail_in; next = strm->next_in; strm->avail_in = dictLength; - strm->next_in = (Bytef *)dictionary; + strm->next_in = (z_const Bytef *)dictionary; fill_window(s); while (s->lookahead >= MIN_MATCH) { str = s->strstart; @@ -513,6 +513,8 @@ int ZEXPORT deflateParams(strm, level, strategy) strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_BLOCK); + if (err == Z_BUF_ERROR && s->pending == 0) + err = Z_OK; } if (s->level != level) { s->level = level; diff --git a/lib/3rdparty/zlib/deflate.h b/lib/3rdparty/zlib/deflate.h index fbac44d908e..ce0299edd19 100644 --- a/lib/3rdparty/zlib/deflate.h +++ b/lib/3rdparty/zlib/deflate.h @@ -104,7 +104,7 @@ typedef struct internal_state { int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ + Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ diff --git a/lib/3rdparty/zlib/gzguts.h b/lib/3rdparty/zlib/gzguts.h index ee3f281aa57..d87659d0319 100644 --- a/lib/3rdparty/zlib/gzguts.h +++ b/lib/3rdparty/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -35,6 +35,13 @@ # include #endif +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + #ifdef NO_DEFLATE /* for compatibility with old definition */ # define NO_GZCOMPRESS #endif @@ -60,7 +67,7 @@ #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ + but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ @@ -88,6 +95,14 @@ # endif #endif +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + #ifndef local # define local static #endif @@ -127,7 +142,8 @@ # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif -/* default i/o buffer size -- double this for output when reading */ +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ #define GZBUFSIZE 8192 /* gzip modes, also provide a little integrity check on the passed structure */ diff --git a/lib/3rdparty/zlib/gzlib.c b/lib/3rdparty/zlib/gzlib.c index ca55c6ea926..fae202ef890 100644 --- a/lib/3rdparty/zlib/gzlib.c +++ b/lib/3rdparty/zlib/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -108,7 +108,7 @@ local gzFile gz_open(path, fd, mode) return NULL; /* allocate gzFile structure to return */ - state = malloc(sizeof(gz_state)); + state = (gz_statep)malloc(sizeof(gz_state)); if (state == NULL) return NULL; state->size = 0; /* no buffers allocated yet */ @@ -162,8 +162,10 @@ local gzFile gz_open(path, fd, mode) break; case 'F': state->strategy = Z_FIXED; + break; case 'T': state->direct = 1; + break; default: /* could consider as an error, but just ignore */ ; } @@ -194,8 +196,8 @@ local gzFile gz_open(path, fd, mode) } else #endif - len = strlen(path); - state->path = malloc(len + 1); + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); if (state->path == NULL) { free(state); return NULL; @@ -208,7 +210,11 @@ local gzFile gz_open(path, fd, mode) *(state->path) = 0; else #endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->path, len + 1, "%s", (const char *)path); +#else strcpy(state->path, path); +#endif /* compute the flags for open() */ oflag = @@ -236,7 +242,7 @@ local gzFile gz_open(path, fd, mode) #ifdef _WIN32 fd == -2 ? _wopen(path, oflag, 0666) : #endif - open(path, oflag, 0666)); + open((const char *)path, oflag, 0666)); if (state->fd == -1) { free(state->path); free(state); @@ -282,9 +288,13 @@ gzFile ZEXPORT gzdopen(fd, mode) char *path; /* identifier for error messages */ gzFile gz; - if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ +#else sprintf(path, "", fd); /* for debugging */ +#endif gz = gz_open(path, fd, mode); free(path); return gz; @@ -531,7 +541,8 @@ const char * ZEXPORT gzerror(file, errnum) /* return error information */ if (errnum != NULL) *errnum = state->err; - return state->msg == NULL ? "" : state->msg; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); } /* -- see zlib.h -- */ @@ -582,21 +593,24 @@ void ZLIB_INTERNAL gz_error(state, err, msg) if (msg == NULL) return; - /* for an out of memory error, save as static string */ - if (err == Z_MEM_ERROR) { - state->msg = (char *)msg; + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) return; - } /* construct error message with path */ - if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { state->err = Z_MEM_ERROR; - state->msg = (char *)"out of memory"; return; } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else strcpy(state->msg, state->path); strcat(state->msg, ": "); strcat(state->msg, msg); +#endif return; } diff --git a/lib/3rdparty/zlib/gzread.c b/lib/3rdparty/zlib/gzread.c index 3493d34d4ea..bf4538eb274 100644 --- a/lib/3rdparty/zlib/gzread.c +++ b/lib/3rdparty/zlib/gzread.c @@ -1,5 +1,5 @@ /* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -58,7 +58,8 @@ local int gz_avail(state) return -1; if (state->eof == 0) { if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in, *q = strm->next_in; + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; unsigned n = strm->avail_in; do { *p++ = *q++; @@ -90,8 +91,8 @@ local int gz_look(state) /* allocate read buffers and inflate memory */ if (state->size == 0) { /* allocate buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want << 1); + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); if (state->in == NULL || state->out == NULL) { if (state->out != NULL) free(state->out); @@ -352,14 +353,14 @@ int ZEXPORT gzread(file, buf, len) /* large len -- read directly into user buffer */ else if (state->how == COPY) { /* read directly */ - if (gz_load(state, buf, len, &n) == -1) + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) return -1; } /* large len -- decompress directly into user buffer */ else { /* state->how == GZIP */ strm->avail_out = len; - strm->next_out = buf; + strm->next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) return -1; n = state->x.have; @@ -378,7 +379,11 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ -#undef gzgetc +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif int ZEXPORT gzgetc(file) gzFile file; { @@ -518,7 +523,7 @@ char * ZEXPORT gzgets(file, buf, len) /* look for end-of-line in current output buffer */ n = state->x.have > left ? left : state->x.have; - eol = memchr(state->x.next, '\n', n); + eol = (unsigned char *)memchr(state->x.next, '\n', n); if (eol != NULL) n = (unsigned)(eol - state->x.next) + 1; diff --git a/lib/3rdparty/zlib/gzwrite.c b/lib/3rdparty/zlib/gzwrite.c index 27cb3428e32..aa767fbf63e 100644 --- a/lib/3rdparty/zlib/gzwrite.c +++ b/lib/3rdparty/zlib/gzwrite.c @@ -1,5 +1,5 @@ /* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -19,7 +19,7 @@ local int gz_init(state) z_streamp strm = &(state->strm); /* allocate input buffer */ - state->in = malloc(state->want); + state->in = (unsigned char *)malloc(state->want); if (state->in == NULL) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; @@ -28,7 +28,7 @@ local int gz_init(state) /* only need output buffer and deflate state if compressing */ if (!state->direct) { /* allocate output buffer */ - state->out = malloc(state->want); + state->out = (unsigned char *)malloc(state->want); if (state->out == NULL) { free(state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); @@ -168,7 +168,6 @@ int ZEXPORT gzwrite(file, buf, len) unsigned len; { unsigned put = len; - unsigned n; gz_statep state; z_streamp strm; @@ -208,16 +207,19 @@ int ZEXPORT gzwrite(file, buf, len) if (len < state->size) { /* copy to input buffer, compress when full */ do { + unsigned have, copy; + if (strm->avail_in == 0) strm->next_in = state->in; - n = state->size - strm->avail_in; - if (n > len) - n = len; - memcpy(strm->next_in + strm->avail_in, buf, n); - strm->avail_in += n; - state->x.pos += n; - buf = (char *)buf + n; - len -= n; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + strm->avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; if (len && gz_comp(state, Z_NO_FLUSH) == -1) return 0; } while (len); @@ -229,7 +231,7 @@ int ZEXPORT gzwrite(file, buf, len) /* directly compress user buffer to file */ strm->avail_in = len; - strm->next_in = (voidp)buf; + strm->next_in = (z_const Bytef *)buf; state->x.pos += len; if (gz_comp(state, Z_NO_FLUSH) == -1) return 0; @@ -244,6 +246,7 @@ int ZEXPORT gzputc(file, c) gzFile file; int c; { + unsigned have; unsigned char buf[1]; gz_statep state; z_streamp strm; @@ -267,12 +270,16 @@ int ZEXPORT gzputc(file, c) /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ - if (strm->avail_in < state->size) { + if (state->size) { if (strm->avail_in == 0) strm->next_in = state->in; - strm->next_in[strm->avail_in++] = c; - state->x.pos++; - return c & 0xff; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } } /* no room in buffer or not initialized, use gz_write() */ @@ -300,12 +307,11 @@ int ZEXPORT gzputs(file, str) #include /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { int size, len; gz_statep state; z_streamp strm; - va_list va; /* get internal structure */ if (file == NULL) @@ -335,25 +341,20 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) /* do the printf() into the input buffer, put length in len */ size = (int)(state->size); state->in[size - 1] = 0; - va_start(va, format); #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void (void)vsprintf((char *)(state->in), format, va); - va_end(va); for (len = 0; len < size; len++) if (state->in[len] == 0) break; # else len = vsprintf((char *)(state->in), format, va); - va_end(va); # endif #else # ifdef HAS_vsnprintf_void (void)vsnprintf((char *)(state->in), size, format, va); - va_end(va); len = strlen((char *)(state->in)); # else len = vsnprintf((char *)(state->in), size, format, va); - va_end(va); # endif #endif @@ -368,6 +369,17 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) return len; } +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ @@ -547,9 +559,9 @@ int ZEXPORT gzclose_w(file) } /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; if (state->size) { - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; if (!state->direct) { (void)deflateEnd(&(state->strm)); free(state->out); diff --git a/lib/3rdparty/zlib/infback.c b/lib/3rdparty/zlib/infback.c index 981aff17c2d..f3833c2e434 100644 --- a/lib/3rdparty/zlib/infback.c +++ b/lib/3rdparty/zlib/infback.c @@ -255,7 +255,7 @@ out_func out; void FAR *out_desc; { struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ + z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ diff --git a/lib/3rdparty/zlib/inffast.c b/lib/3rdparty/zlib/inffast.c index 2f1d60b43b8..bda59ceb6a1 100644 --- a/lib/3rdparty/zlib/inffast.c +++ b/lib/3rdparty/zlib/inffast.c @@ -1,5 +1,5 @@ /* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler + * Copyright (C) 1995-2008, 2010, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -69,8 +69,8 @@ z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ diff --git a/lib/3rdparty/zlib/inflate.c b/lib/3rdparty/zlib/inflate.c index 47418a1e1e1..870f89bb4d3 100644 --- a/lib/3rdparty/zlib/inflate.c +++ b/lib/3rdparty/zlib/inflate.c @@ -93,11 +93,12 @@ /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); #ifdef BUILDFIXED void makefixed OF((void)); #endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateResetKeep(strm) @@ -375,12 +376,13 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, out) +local int updatewindow(strm, end, copy) z_streamp strm; -unsigned out; +const Bytef *end; +unsigned copy; { struct inflate_state FAR *state; - unsigned copy, dist; + unsigned dist; state = (struct inflate_state FAR *)strm->state; @@ -400,19 +402,18 @@ unsigned out; } /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + zmemcpy(state->window, end - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + zmemcpy(state->window + state->wnext, end - copy, dist); copy -= dist; if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); + zmemcpy(state->window, end - copy, copy); state->wnext = copy; state->whave = state->wsize; } @@ -606,7 +607,7 @@ z_streamp strm; int flush; { struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ + z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ @@ -920,7 +921,7 @@ int flush; while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; - state->lencode = (code const FAR *)(state->next); + state->lencode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); @@ -994,7 +995,7 @@ int flush; values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; - state->lencode = (code const FAR *)(state->next); + state->lencode = (const code FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); @@ -1003,7 +1004,7 @@ int flush; state->mode = BAD; break; } - state->distcode = (code const FAR *)(state->next); + state->distcode = (const code FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); @@ -1230,7 +1231,7 @@ int flush; RESTORE(); if (state->wsize || (out != strm->avail_out && state->mode < BAD && (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, out)) { + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } @@ -1264,6 +1265,29 @@ z_streamp strm; return Z_OK; } +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; @@ -1271,8 +1295,6 @@ uInt dictLength; { struct inflate_state FAR *state; unsigned long dictid; - unsigned char *next; - unsigned avail; int ret; /* check state */ @@ -1291,13 +1313,7 @@ uInt dictLength; /* copy dictionary to window using updatewindow(), which will amend the existing dictionary if appropriate */ - next = strm->next_out; - avail = strm->avail_out; - strm->next_out = (Bytef *)dictionary + dictLength; - strm->avail_out = 0; - ret = updatewindow(strm, dictLength); - strm->avail_out = avail; - strm->next_out = next; + ret = updatewindow(strm, dictionary + dictLength, dictLength); if (ret) { state->mode = MEM; return Z_MEM_ERROR; @@ -1337,7 +1353,7 @@ gz_headerp head; */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; -unsigned char FAR *buf; +const unsigned char FAR *buf; unsigned len; { unsigned got; diff --git a/lib/3rdparty/zlib/inftrees.c b/lib/3rdparty/zlib/inftrees.c index abcd7c45ed3..44d89cf24e1 100644 --- a/lib/3rdparty/zlib/inftrees.c +++ b/lib/3rdparty/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2012 Mark Adler + * Copyright (C) 1995-2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.7 Copyright 1995-2012 Mark Adler "; + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 78, 68}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, @@ -208,8 +208,8 @@ unsigned short FAR *work; mask = used - 1; /* mask for comparing low */ /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ @@ -277,8 +277,8 @@ unsigned short FAR *work; /* check for enough space */ used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ diff --git a/lib/3rdparty/zlib/trees.c b/lib/3rdparty/zlib/trees.c index 8c32b214b1d..1fd7759ef00 100644 --- a/lib/3rdparty/zlib/trees.c +++ b/lib/3rdparty/zlib/trees.c @@ -146,8 +146,8 @@ local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); @@ -972,7 +972,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif @@ -980,7 +981,8 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif @@ -1057,8 +1059,8 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) */ local void compress_block(s, ltree, dtree) deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ diff --git a/lib/3rdparty/zlib/uncompr.c b/lib/3rdparty/zlib/uncompr.c index ad98be3a5d8..242e9493dff 100644 --- a/lib/3rdparty/zlib/uncompr.c +++ b/lib/3rdparty/zlib/uncompr.c @@ -30,7 +30,7 @@ int ZEXPORT uncompress (dest, destLen, source, sourceLen) z_stream stream; int err; - stream.next_in = (Bytef*)source; + stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; diff --git a/lib/3rdparty/zlib/zutil.c b/lib/3rdparty/zlib/zutil.c index 65e0d3b72b0..23d2ebef008 100644 --- a/lib/3rdparty/zlib/zutil.c +++ b/lib/3rdparty/zlib/zutil.c @@ -14,7 +14,7 @@ struct internal_state {int dummy;}; /* for buggy compilers */ #endif -const char * const z_errmsg[10] = { +z_const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ diff --git a/lib/3rdparty/zlib/zutil.h b/lib/3rdparty/zlib/zutil.h index 4e3dcc6ae9f..24ab06b1cf6 100644 --- a/lib/3rdparty/zlib/zutil.h +++ b/lib/3rdparty/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2012 Jean-loup Gailly. + * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -44,13 +44,13 @@ typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) + return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ @@ -168,7 +168,8 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif /* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif diff --git a/lib/atl/CMakeLists.txt b/lib/atl/CMakeLists.txt index ea353fe542f..031ce279d62 100644 --- a/lib/atl/CMakeLists.txt +++ b/lib/atl/CMakeLists.txt @@ -1,4 +1,6 @@ +set_cpp(WITH_RTTI) + add_definitions( -DUNICODE -D_UNICODE -DROS_Headers) diff --git a/lib/atl/atlbase.h b/lib/atl/atlbase.h index df2175c0ea0..232507bcdc5 100644 --- a/lib/atl/atlbase.h +++ b/lib/atl/atlbase.h @@ -595,6 +595,7 @@ public: ATLASSERT(ppv != NULL); if (ppv == NULL) return E_POINTER; + *ppv = NULL; hResult = S_OK; if (m_pObjMap != NULL) { @@ -617,6 +618,11 @@ public: objectMapEntry++; } } + if (hResult == S_OK && *ppv == NULL) + { + // FIXME: call AtlComModuleGetClassObject + hResult = CLASS_E_CLASSNOTAVAILABLE; + } return hResult; } diff --git a/lib/drivers/libusb/CMakeLists.txt b/lib/drivers/libusb/CMakeLists.txt index afbcd3ff3e2..25106b9f070 100644 --- a/lib/drivers/libusb/CMakeLists.txt +++ b/lib/drivers/libusb/CMakeLists.txt @@ -1,3 +1,4 @@ + set_cpp() remove_definitions(-D_WIN32_WINNT=0x502) @@ -18,12 +19,3 @@ list(APPEND SOURCE add_library(libusb ${SOURCE}) add_dependencies(libusb bugcodes) - -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - #add_target_compile_flags(libusb "/GR-") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/GR-") -else() - #add_target_compile_flags(libusb "-fno-exceptions -fno-rtti") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") -endif() diff --git a/lib/drivers/lwip/src/rostcp.c b/lib/drivers/lwip/src/rostcp.c index 1e7374828b0..57c8876c29d 100755 --- a/lib/drivers/lwip/src/rostcp.c +++ b/lib/drivers/lwip/src/rostcp.c @@ -248,13 +248,15 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er return ERR_OK; } +/* This function MUST return an error value that is not ERR_ABRT or ERR_OK if the connection + * is not accepted to avoid leaking the new PCB */ static err_t InternalAcceptEventHandler(void *arg, PTCP_PCB newpcb, const err_t err) { /* Make sure the socket didn't get closed */ if (!arg) - return ERR_ABRT; + return ERR_CLSD; TCPAcceptEventHandler(arg, newpcb); @@ -262,7 +264,7 @@ InternalAcceptEventHandler(void *arg, PTCP_PCB newpcb, const err_t err) if (newpcb->callback_arg) return ERR_OK; else - return ERR_ABRT; + return ERR_CLSD; } static diff --git a/lib/drivers/sound/stdunk/CMakeLists.txt b/lib/drivers/sound/stdunk/CMakeLists.txt index 0e2c29d49f2..9a19e7f7d19 100644 --- a/lib/drivers/sound/stdunk/CMakeLists.txt +++ b/lib/drivers/sound/stdunk/CMakeLists.txt @@ -2,9 +2,3 @@ set_cpp() add_library(stdunk STATIC cunknown.cpp) - -if(MSVC) - add_target_compile_flags(stdunk "/GR-") -else() - add_target_compile_flags(stdunk "-fno-exceptions -fno-rtti") -endif() diff --git a/lib/lsalib/lsa.c b/lib/lsalib/lsa.c index f1745120272..30938ce4ea0 100644 --- a/lib/lsalib/lsa.c +++ b/lib/lsalib/lsa.c @@ -66,13 +66,50 @@ LsaDeregisterLogonProcess(HANDLE LsaHandle) /* - * @unimplemented + * @implemented */ NTSTATUS WINAPI LsaConnectUntrusted(PHANDLE LsaHandle) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNICODE_STRING PortName; // = RTL_CONSTANT_STRING(L"\\LsaAuthenticationPort"); + SECURITY_QUALITY_OF_SERVICE SecurityQos; + LSA_CONNECTION_INFO ConnectInfo; + ULONG ConnectInfoLength = sizeof(ConnectInfo); + NTSTATUS Status; + + DPRINT1("LsaConnectUntrusted(%p)\n", LsaHandle); + + RtlInitUnicodeString(&PortName, + L"\\LsaAuthenticationPort"); + + SecurityQos.Length = sizeof(SecurityQos); + SecurityQos.ImpersonationLevel = SecurityIdentification; + SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; + SecurityQos.EffectiveOnly = TRUE; + + RtlZeroMemory(&ConnectInfo, + ConnectInfoLength); + + Status = ZwConnectPort(LsaHandle, + &PortName, + &SecurityQos, + NULL, + NULL, + NULL, + &ConnectInfo, + &ConnectInfoLength); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ZwConnectPort failed (Status 0x%08lx)\n", Status); + return Status; + } + + if (!NT_SUCCESS(ConnectInfo.Status)) + { + DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status); + } + + return ConnectInfo.Status; } @@ -122,56 +159,6 @@ LsaCallAuthenticationPackage(HANDLE LsaHandle, *ProtocolStatus = ApiMessage.CallAuthenticationPackage.Reply.ProtocolStatus; return Status; - - -#if 0 - PLSASS_REQUEST Request; - PLSASS_REPLY Reply; - LSASS_REQUEST RawRequest; - LSASS_REPLY RawReply; - NTSTATUS Status; - ULONG OutBufferSize; - - Request = (PLSASS_REQUEST)&RawRequest; - Reply = (PLSASS_REPLY)&RawReply; - - Request->Header.u1.s1.DataLength = sizeof(LSASS_REQUEST) + SubmitBufferLength - - sizeof(PORT_MESSAGE); - Request->Header.u1.s1.TotalLength = - Request->Header.u1.s1.DataLength + sizeof(PORT_MESSAGE); - Request->Type = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE; - Request->d.CallAuthenticationPackageRequest.AuthenticationPackage = - AuthenticationPackage; - Request->d.CallAuthenticationPackageRequest.InBufferLength = - SubmitBufferLength; - memcpy(Request->d.CallAuthenticationPackageRequest.InBuffer, - ProtocolSubmitBuffer, - SubmitBufferLength); - - Status = ZwRequestWaitReplyPort(LsaHandle, - &Request->Header, - &Reply->Header); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - if (!NT_SUCCESS(Reply->Status)) - { - return Reply->Status; - } - - OutBufferSize = Reply->d.CallAuthenticationPackageReply.OutBufferLength; - *ProtocolReturnBuffer = RtlAllocateHeap(Secur32Heap, - 0, - OutBufferSize); - *ReturnBufferLength = OutBufferSize; - memcpy(*ProtocolReturnBuffer, - Reply->d.CallAuthenticationPackageReply.OutBuffer, - *ReturnBufferLength); - - return Status; -#endif } @@ -297,91 +284,6 @@ LsaLogonUser(HANDLE LsaHandle, *SubStatus = ApiMessage.LogonUser.Reply.SubStatus; return Status; - -#if 0 - ULONG RequestLength; - ULONG CurrentLength; - PLSASS_REQUEST Request; - LSASS_REQUEST RawMessage; - PLSASS_REPLY Reply; - LSASS_REPLY RawReply; - NTSTATUS Status; - - RequestLength = sizeof(LSASS_REQUEST) - sizeof(PORT_MESSAGE); - RequestLength = RequestLength + (OriginName->Length * sizeof(WCHAR)); - RequestLength = RequestLength + AuthenticationInformationLength; - RequestLength = RequestLength + - (LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES)); - - CurrentLength = 0; - Request = (PLSASS_REQUEST)&RawMessage; - - Request->d.LogonUserRequest.OriginNameLength = OriginName->Length; - Request->d.LogonUserRequest.OriginName = (PWSTR)&RawMessage + CurrentLength; - memcpy((PWSTR)&RawMessage + CurrentLength, - OriginName->Buffer, - OriginName->Length * sizeof(WCHAR)); - CurrentLength = CurrentLength + (OriginName->Length * sizeof(WCHAR)); - - Request->d.LogonUserRequest.LogonType = LogonType; - - Request->d.LogonUserRequest.AuthenticationPackage = - AuthenticationPackage; - - Request->d.LogonUserRequest.AuthenticationInformation = - (PVOID)((ULONG_PTR)&RawMessage + CurrentLength); - Request->d.LogonUserRequest.AuthenticationInformationLength = - AuthenticationInformationLength; - memcpy((PVOID)((ULONG_PTR)&RawMessage + CurrentLength), - AuthenticationInformation, - AuthenticationInformationLength); - CurrentLength = CurrentLength + AuthenticationInformationLength; - - Request->d.LogonUserRequest.LocalGroupsCount = LocalGroups->GroupCount; - Request->d.LogonUserRequest.LocalGroups = - (PSID_AND_ATTRIBUTES)&RawMessage + CurrentLength; - memcpy((PSID_AND_ATTRIBUTES)&RawMessage + CurrentLength, - LocalGroups->Groups, - LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES)); - - Request->d.LogonUserRequest.SourceContext = *SourceContext; - - Request->Type = LSASS_REQUEST_LOGON_USER; - Request->Header.u1.s1.DataLength = RequestLength - sizeof(PORT_MESSAGE); - Request->Header.u1.s1.TotalLength = RequestLength + sizeof(PORT_MESSAGE); - - Reply = (PLSASS_REPLY)&RawReply; - - Status = ZwRequestWaitReplyPort(LsaHandle, - &Request->Header, - &Reply->Header); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - *SubStatus = Reply->d.LogonUserReply.SubStatus; - - if (!NT_SUCCESS(Reply->Status)) - { - return Status; - } - - *ProfileBuffer = RtlAllocateHeap(Secur32Heap, - 0, - Reply->d.LogonUserReply.ProfileBufferLength); - memcpy(*ProfileBuffer, - (PVOID)((ULONG_PTR)Reply->d.LogonUserReply.Data + - (ULONG_PTR)Reply->d.LogonUserReply.ProfileBuffer), - Reply->d.LogonUserReply.ProfileBufferLength); - *LogonId = Reply->d.LogonUserReply.LogonId; - *Token = Reply->d.LogonUserReply.Token; - memcpy(Quotas, - &Reply->d.LogonUserReply.Quotas, - sizeof(Reply->d.LogonUserReply.Quotas)); - - return Status; -#endif } @@ -436,7 +338,7 @@ LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName, DPRINT("ConnectInfo.OperationalMode: 0x%08lx\n", ConnectInfo.OperationalMode); *OperationalMode = ConnectInfo.OperationalMode; - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(ConnectInfo.Status)) { DPRINT1("ConnectInfo.Status: 0x%08lx\n", ConnectInfo.Status); } diff --git a/lib/rtl/error.c b/lib/rtl/error.c index bcbf3e3e0a4..1c5b5f21b9b 100644 --- a/lib/rtl/error.c +++ b/lib/rtl/error.c @@ -3,6 +3,7 @@ * * Copyright 2000 Alexandre Julliard * Copyright 2002 Andriy Palamarchuk + * Copyright 2010 André Hentschel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -251,10 +252,10 @@ static const DWORD table_00000102[32] = ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY /* 00000121 (STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY) */ }; -static const DWORD table_40000002[12] = +static const DWORD table_40000002[36] = { ERROR_INVALID_PARAMETER, /* 40000002 (STATUS_WORKING_SET_LIMIT_RANGE) */ - 0, /* 40000003 (STATUS_IMAGE_NOT_AT_BASE) */ + ERROR_IMAGE_NOT_AT_BASE, /* 40000003 (STATUS_IMAGE_NOT_AT_BASE) */ 0, /* 40000004 (STATUS_RXACT_STATE_CREATED) */ 0, /* 40000005 (STATUS_SEGMENT_NOTIFICATION) */ ERROR_LOCAL_USER_SESSION_KEY, /* 40000006 (STATUS_LOCAL_USER_SESSION_KEY) */ @@ -264,7 +265,31 @@ static const DWORD table_40000002[12] = 0, /* 4000000a (STATUS_FT_READ_RECOVERY_FROM_BACKUP) */ 0, /* 4000000b (STATUS_FT_WRITE_RECOVERY) */ ERROR_COUNTER_TIMEOUT, /* 4000000c (STATUS_SERIAL_COUNTER_TIMEOUT) */ - ERROR_NULL_LM_PASSWORD /* 4000000d (STATUS_NULL_LM_PASSWORD) */ + ERROR_NULL_LM_PASSWORD, /* 4000000d (STATUS_NULL_LM_PASSWORD) */ + ERROR_IMAGE_MACHINE_TYPE_MISMATCH, /* 4000000e (STATUS_IMAGE_MACHINE_TYPE_MISMATCH) */ + ERROR_RECEIVE_PARTIAL, /* 4000000f (STATUS_RECEIVE_PARTIAL) */ + ERROR_RECEIVE_EXPEDITED, /* 40000010 (STATUS_RECEIVE_EXPEDITED) */ + ERROR_RECEIVE_PARTIAL_EXPEDITED, /* 40000011 (STATUS_RECEIVE_PARTIAL_EXPEDITED) */ + ERROR_EVENT_DONE, /* 40000012 (STATUS_EVENT_DONE) */ + ERROR_EVENT_PENDING, /* 40000013 (STATUS_EVENT_PENDING) */ + ERROR_CHECKING_FILE_SYSTEM, /* 40000014 (STATUS_CHECKING_FILE_SYSTEM) */ + ERROR_FATAL_APP_EXIT, /* 40000015 (STATUS_FATAL_APP_EXIT) */ + ERROR_PREDEFINED_HANDLE, /* 40000016 (STATUS_PREDEFINED_HANDLE) */ + ERROR_WAS_UNLOCKED, /* 40000017 (STATUS_WAS_UNLOCKED) */ + ERROR_SERVICE_NOTIFICATION, /* 40000018 (STATUS_SERVICE_NOTIFICATION) */ + ERROR_WAS_LOCKED, /* 40000019 (STATUS_WAS_LOCKED) */ + ERROR_LOG_HARD_ERROR, /* 4000001a (STATUS_LOG_HARD_ERROR) */ + ERROR_ALREADY_WIN32, /* 4000001b (STATUS_ALREADY_WIN32) */ + 0, /* 4000001c (STATUS_WX86_UNSIMULATE) */ + 0, /* 4000001d (STATUS_WX86_CONTINUE) */ + 0, /* 4000001e (STATUS_WX86_SINGLE_STEP) */ + 0, /* 4000001f (STATUS_WX86_BREAKPOINT) */ + 0, /* 40000020 (STATUS_WX86_EXCEPTION_CONTINUE) */ + 0, /* 40000021 (STATUS_WX86_EXCEPTION_LASTCHANCE) */ + 0, /* 40000022 (STATUS_WX86_EXCEPTION_CHAIN) */ + ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE, /* 40000023 (STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE) */ + ERROR_NO_YIELD_PERFORMED, /* 40000024 (STATUS_NO_YIELD_PERFORMED) */ + ERROR_TIMER_RESUME_IGNORED /* 40000025 (STATUS_TIMER_RESUME_IGNORED) */ }; static const DWORD table_40000370[1] = @@ -293,7 +318,7 @@ static const DWORD table_80000001[39] = 0, /* 80000007 (STATUS_WAKE_SYSTEM_DEBUGGER) */ 0, /* 80000008 */ 0, /* 80000009 */ - 0, /* 8000000a (STATUS_HANDLES_CLOSED) */ + ERROR_HANDLES_CLOSED, /* 8000000a (STATUS_HANDLES_CLOSED) */ ERROR_NO_INHERITANCE, /* 8000000b (STATUS_NO_INHERITANCE) */ 0, /* 8000000c (STATUS_GUID_SUBSTITUTION_MADE) */ ERROR_PARTIAL_COPY, /* 8000000d (STATUS_PARTIAL_COPY) */ @@ -710,9 +735,9 @@ static const DWORD table_c0000001[411] = 0, /* c0000115 (STATUS_ABIOS_SELECTOR_NOT_AVAILABLE) */ 0, /* c0000116 (STATUS_ABIOS_INVALID_SELECTOR) */ ERROR_INVALID_THREAD_ID, /* c0000117 (STATUS_NO_LDT) */ - 0, /* c0000118 (STATUS_INVALID_LDT_SIZE) */ - 0, /* c0000119 (STATUS_INVALID_LDT_OFFSET) */ - 0, /* c000011a (STATUS_INVALID_LDT_DESCRIPTOR) */ + ERROR_INVALID_LDT_SIZE, /* c0000118 (STATUS_INVALID_LDT_SIZE) */ + ERROR_INVALID_LDT_OFFSET, /* c0000119 (STATUS_INVALID_LDT_OFFSET) */ + ERROR_INVALID_LDT_DESCRIPTOR, /* c000011a (STATUS_INVALID_LDT_DESCRIPTOR) */ ERROR_BAD_EXE_FORMAT, /* c000011b (STATUS_INVALID_IMAGE_NE_FORMAT) */ ERROR_RXACT_INVALID_STATE, /* c000011c (STATUS_RXACT_INVALID_STATE) */ ERROR_RXACT_COMMIT_FAILURE, /* c000011d (STATUS_RXACT_COMMIT_FAILURE) */ @@ -740,11 +765,11 @@ static const DWORD table_c0000001[411] = ERROR_TIME_SKEW, /* c0000133 (STATUS_TIME_DIFFERENCE_AT_DC) */ 0, /* c0000134 (STATUS_SYNCHRONIZATION_REQUIRED) */ ERROR_MOD_NOT_FOUND, /* c0000135 (STATUS_DLL_NOT_FOUND) */ - 0, /* c0000136 (STATUS_OPEN_FAILED) */ - 0, /* c0000137 (STATUS_IO_PRIVILEGE_FAILED) */ + ERROR_NET_OPEN_FAILED, /* c0000136 (STATUS_OPEN_FAILED) */ + ERROR_IO_PRIVILEGE_FAILED, /* c0000137 (STATUS_IO_PRIVILEGE_FAILED) */ ERROR_INVALID_ORDINAL, /* c0000138 (STATUS_ORDINAL_NOT_FOUND) */ ERROR_PROC_NOT_FOUND, /* c0000139 (STATUS_ENTRYPOINT_NOT_FOUND) */ - 0, /* c000013a (STATUS_CONTROL_C_EXIT) */ + ERROR_CONTROL_C_EXIT, /* c000013a (STATUS_CONTROL_C_EXIT) */ ERROR_NETNAME_DELETED, /* c000013b (STATUS_LOCAL_DISCONNECT) */ ERROR_NETNAME_DELETED, /* c000013c (STATUS_REMOTE_DISCONNECT) */ ERROR_REM_NOT_LIST, /* c000013d (STATUS_REMOTE_RESOURCES) */ @@ -753,18 +778,18 @@ static const DWORD table_c0000001[411] = ERROR_UNEXP_NET_ERR, /* c0000140 (STATUS_INVALID_CONNECTION) */ ERROR_UNEXP_NET_ERR, /* c0000141 (STATUS_INVALID_ADDRESS) */ ERROR_DLL_INIT_FAILED, /* c0000142 (STATUS_DLL_INIT_FAILED) */ - 0, /* c0000143 (STATUS_MISSING_SYSTEMFILE) */ - 0, /* c0000144 (STATUS_UNHANDLED_EXCEPTION) */ - 0, /* c0000145 (STATUS_APP_INIT_FAILURE) */ - 0, /* c0000146 (STATUS_PAGEFILE_CREATE_FAILED) */ - 0, /* c0000147 (STATUS_NO_PAGEFILE) */ + ERROR_MISSING_SYSTEMFILE, /* c0000143 (STATUS_MISSING_SYSTEMFILE) */ + ERROR_UNHANDLED_EXCEPTION, /* c0000144 (STATUS_UNHANDLED_EXCEPTION) */ + ERROR_APP_INIT_FAILURE, /* c0000145 (STATUS_APP_INIT_FAILURE) */ + ERROR_PAGEFILE_CREATE_FAILED, /* c0000146 (STATUS_PAGEFILE_CREATE_FAILED) */ + ERROR_NO_PAGEFILE, /* c0000147 (STATUS_NO_PAGEFILE) */ ERROR_INVALID_LEVEL, /* c0000148 (STATUS_INVALID_LEVEL) */ ERROR_INVALID_PASSWORD, /* c0000149 (STATUS_WRONG_PASSWORD_CORE) */ - 0, /* c000014a (STATUS_ILLEGAL_FLOAT_CONTEXT) */ + ERROR_ILLEGAL_FLOAT_CONTEXT, /* c000014a (STATUS_ILLEGAL_FLOAT_CONTEXT) */ ERROR_BROKEN_PIPE, /* c000014b (STATUS_PIPE_BROKEN) */ ERROR_BADDB, /* c000014c (STATUS_REGISTRY_CORRUPT) */ ERROR_REGISTRY_IO_FAILED, /* c000014d (STATUS_REGISTRY_IO_FAILED) */ - 0, /* c000014e (STATUS_NO_EVENT_PAIR) */ + ERROR_NO_EVENT_PAIR, /* c000014e (STATUS_NO_EVENT_PAIR) */ ERROR_UNRECOGNIZED_VOLUME, /* c000014f (STATUS_UNRECOGNIZED_VOLUME) */ ERROR_SERIAL_NO_DEVICE, /* c0000150 (STATUS_SERIAL_NO_DEVICE_INITED) */ ERROR_NO_SUCH_ALIAS, /* c0000151 (STATUS_NO_SUCH_ALIAS) */ @@ -780,7 +805,7 @@ static const DWORD table_c0000001[411] = ERROR_LOGON_TYPE_NOT_GRANTED, /* c000015b (STATUS_LOGON_TYPE_NOT_GRANTED) */ ERROR_NOT_REGISTRY_FILE, /* c000015c (STATUS_NOT_REGISTRY_FILE) */ ERROR_NT_CROSS_ENCRYPTION_REQUIRED, /* c000015d (STATUS_NT_CROSS_ENCRYPTION_REQUIRED) */ - 0, /* c000015e (STATUS_DOMAIN_CTRLR_CONFIG_ERROR) */ + ERROR_DOMAIN_CTRLR_CONFIG_ERROR, /* c000015e (STATUS_DOMAIN_CTRLR_CONFIG_ERROR) */ ERROR_IO_DEVICE, /* c000015f (STATUS_FT_MISSING_MEMBER) */ 0, /* c0000160 (STATUS_ILL_FORMED_SERVICE_ENTRY) */ 0, /* c0000161 (STATUS_ILLEGAL_CHARACTER) */ @@ -886,8 +911,8 @@ static const DWORD table_c0000202[396] = 0, /* c0000227 (STATUS_RECOVERY_FAILURE) */ 0, /* c0000228 (STATUS_STACK_OVERFLOW_READ) */ ERROR_INVALID_PARAMETER, /* c0000229 (STATUS_FAIL_CHECK) */ - STATUS_DUPLICATE_OBJECTID, /* c000022a (STATUS_DUPLICATE_OBJECTID) */ - STATUS_OBJECTID_EXISTS, /* c000022b (STATUS_OBJECTID_EXISTS) */ + ERROR_OBJECT_ALREADY_EXISTS, /* c000022a (STATUS_DUPLICATE_OBJECTID) */ + ERROR_OBJECT_ALREADY_EXISTS, /* c000022b (STATUS_OBJECTID_EXISTS) */ 0, /* c000022c (STATUS_CONVERT_TO_LARGE) */ ERROR_RETRY, /* c000022d (STATUS_RETRY) */ 0, /* c000022e (STATUS_FOUND_OUT_OF_SCOPE) */ @@ -927,7 +952,7 @@ static const DWORD table_c0000202[396] = 0, /* c0000250 (STATUS_INSUFFICIENT_LOGON_INFO) */ 0, /* c0000251 (STATUS_BAD_DLL_ENTRYPOINT) */ 0, /* c0000252 (STATUS_BAD_SERVICE_ENTRYPOINT) */ - ERROR_INTERNAL_ERROR, /* c0000253 (STATUS_LPC_REPLY_LOST) */ + ERROR_CONNECTION_ABORTED, /* c0000253 (STATUS_LPC_REPLY_LOST) */ 0, /* c0000254 (STATUS_IP_ADDRESS_CONFLICT1) */ 0, /* c0000255 (STATUS_IP_ADDRESS_CONFLICT2) */ 0, /* c0000256 (STATUS_REGISTRY_QUOTA_LIMIT) */ @@ -1460,7 +1485,7 @@ static const DWORD table_c0130001[22] = ERROR_CLUSTER_NETWORK_NOT_INTERNAL /* c0130016 (STATUS_CLUSTER_NETWORK_NOT_INTERNAL) */ }; -static const DWORD table_c0150001[14] = +static const DWORD table_c0150001[39] = { ERROR_SXS_SECTION_NOT_FOUND, /* c0150001 (STATUS_SXS_SECTION_NOT_FOUND) */ ERROR_SXS_CANT_GEN_ACTCTX, /* c0150002 (STATUS_SXS_CANT_GEN_ACTCTX) */ @@ -1470,18 +1495,43 @@ static const DWORD table_c0150001[14] = ERROR_SXS_MANIFEST_PARSE_ERROR, /* c0150006 (STATUS_SXS_MANIFEST_PARSE_ERROR) */ ERROR_SXS_ACTIVATION_CONTEXT_DISABLED, /* c0150007 (STATUS_SXS_ACTIVATION_CONTEXT_DISABLED) */ ERROR_SXS_KEY_NOT_FOUND, /* c0150008 (STATUS_SXS_KEY_NOT_FOUND) */ - 0, /* c0150009 (STATUS_SXS_VERSION_CONFLICT) */ + ERROR_SXS_VERSION_CONFLICT, /* c0150009 (STATUS_SXS_VERSION_CONFLICT) */ ERROR_SXS_WRONG_SECTION_TYPE, /* c015000a (STATUS_SXS_WRONG_SECTION_TYPE) */ ERROR_SXS_THREAD_QUERIES_DISABLED, /* c015000b (STATUS_SXS_THREAD_QUERIES_DISABLED) */ - 0, /* c015000c (STATUS_SXS_ASSEMBLY_MISSING) */ + ERROR_SXS_ASSEMBLY_MISSING, /* c015000c (STATUS_SXS_ASSEMBLY_MISSING) */ 0, /* c015000d */ - ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET /* c015000e (STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET) */ + ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET, /* c015000e (STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET) */ + ERROR_SXS_EARLY_DEACTIVATION, /* c015000f (STATUS_SXS_EARLY_DEACTIVATION) */ + ERROR_SXS_INVALID_DEACTIVATION, /* c0150010 (STATUS_SXS_INVALID_DEACTIVATION) */ + ERROR_SXS_MULTIPLE_DEACTIVATION, /* c0150011 (STATUS_SXS_MULTIPLE_DEACTIVATION) */ + ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY, /* c0150012 (STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY) */ + ERROR_SXS_PROCESS_TERMINATION_REQUESTED, /* c0150013 (STATUS_SXS_PROCESS_TERMINATION_REQUESTED) */ + ERROR_SXS_CORRUPT_ACTIVATION_STACK, /* c0150014 (STATUS_SXS_CORRUPT_ACTIVATION_STACK) */ + ERROR_SXS_CORRUPTION, /* c0150015 (STATUS_SXS_CORRUPTION) */ + ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE, /* c0150016 (STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE) */ + ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME, /* c0150017 (STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME) */ + ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE, /* c0150018 (STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE) */ + ERROR_SXS_IDENTITY_PARSE_ERROR, /* c0150019 (STATUS_SXS_IDENTITY_PARSE_ERROR) */ + ERROR_SXS_COMPONENT_STORE_CORRUPT, /* c015001a (STATUS_SXS_COMPONENT_STORE_CORRUPT) */ + ERROR_SXS_FILE_HASH_MISMATCH, /* c015001b (STATUS_SXS_FILE_HASH_MISMATCH) */ + ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT, /* c015001c (STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT) */ + ERROR_SXS_IDENTITIES_DIFFERENT, /* c015001d (STATUS_SXS_IDENTITIES_DIFFERENT) */ + ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT, /* c015001e (STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT) */ + ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY, /* c015001f (STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY) */ + ERROR_ADVANCED_INSTALLER_FAILED, /* c0150020 (STATUS_ADVANCED_INSTALLER_FAILED) */ + ERROR_XML_ENCODING_MISMATCH, /* c0150021 (STATUS_XML_ENCODING_MISMATCH) */ + ERROR_SXS_MANIFEST_TOO_BIG, /* c0150022 (STATUS_SXS_MANIFEST_TOO_BIG) */ + ERROR_SXS_SETTING_NOT_REGISTERED, /* c0150023 (STATUS_SXS_SETTING_NOT_REGISTERED) */ + ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE, /* c0150024 (STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE) */ + ERROR_SMI_PRIMITIVE_INSTALLER_FAILED, /* c0150025 (STATUS_SXS_PRIMITIVE_INSTALLER_FAILED) */ + ERROR_GENERIC_COMMAND_FAILED, /* c0150026 (STATUS_GENERIC_COMMAND_FAILED) */ + ERROR_SXS_FILE_HASH_MISSING /* c0150027 (STATUS_SXS_FILE_HASH_MISSING) */ }; static const struct error_table error_table[] = { { 0x00000102, 0x00000122, table_00000102 }, - { 0x40000002, 0x4000000e, table_40000002 }, + { 0x40000002, 0x40000026, table_40000002 }, { 0x40000370, 0x40000371, table_40000370 }, { 0x40020056, 0x40020057, table_40020056 }, { 0x400200af, 0x400200b0, table_400200af }, @@ -1498,7 +1548,6 @@ static const struct error_table error_table[] = { 0xc0030059, 0xc0030062, table_c0030059 }, { 0xc00a0001, 0xc00a0037, table_c00a0001 }, { 0xc0130001, 0xc0130017, table_c0130001 }, - { 0xc0150001, 0xc015000f, table_c0150001 }, - { 0, 0, 0 } /* last entry */ -}; - + { 0xc0150001, 0xc0150028, table_c0150001 }, + { 0, 0, NULL } /* last entry */ +}; \ No newline at end of file diff --git a/lib/rtl/path.c b/lib/rtl/path.c index 6b9bc32f47c..1ab1a622d4c 100644 --- a/lib/rtl/path.c +++ b/lib/rtl/path.c @@ -141,7 +141,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString) { /* Stop if we hit something else than a space or period */ c = PathCopy.Buffer[PathChars - 1]; - if ((c != '.') && (c != ' ')) break; + if ((c != L'.') && (c != L' ')) break; /* Fixup the lengths */ PathCopy.Length -= sizeof(WCHAR); @@ -160,7 +160,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString) { /* Check if the character is a path or drive separator */ c = *End; - if (IS_PATH_SEPARATOR(c) || ((c == ':') && (End == PathCopy.Buffer + 1))) + if (IS_PATH_SEPARATOR(c) || ((c == L':') && (End == PathCopy.Buffer + 1))) { /* Get the next lower case character */ End++; @@ -168,7 +168,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString) /* Check if it's a DOS device (LPT, COM, PRN, AUX, or NUL) */ if ((End < &PathCopy.Buffer[OriginalLength / sizeof(WCHAR)]) && - ((c == 'l') || (c == 'c') || (c == 'p') || (c == 'a') || (c == 'n'))) + ((c == L'l') || (c == L'c') || (c == L'p') || (c == L'a') || (c == L'n'))) { /* Calculate the offset */ ReturnOffset = (USHORT)((PCHAR)End - (PCHAR)PathCopy.Buffer); @@ -191,7 +191,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString) /* Get the next lower case character and check if it's a DOS device */ c = RtlDowncaseUnicodeChar(*PathCopy.Buffer); - if ((c != 'l') && (c != 'c') && (c != 'p') && (c != 'a') && (c != 'n')) + if ((c != L'l') && (c != L'c') && (c != L'p') && (c != L'a') && (c != L'n')) { /* Not LPT, COM, PRN, AUX, or NUL */ return 0; @@ -204,12 +204,12 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString) while (Start < End) { c = *Start; - if ((c == '.') || (c == ':')) break; + if ((c == L'.') || (c == L':')) break; Start++; } /* And then go backwards to get rid of spaces */ - while ((Start > PathCopy.Buffer) && (Start[-1] == ' ')) --Start; + while ((Start > PathCopy.Buffer) && (Start[-1] == L' ')) --Start; /* Finally see how many characters are left, and that's our size */ PathChars = (USHORT)(Start - PathCopy.Buffer); @@ -217,7 +217,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString) /* Check if this is a COM or LPT port, which has a digit after it */ if ((PathChars == 4) && - (iswdigit(PathCopy.Buffer[3]) && (PathCopy.Buffer[3] != '0'))) + (iswdigit(PathCopy.Buffer[3]) && (PathCopy.Buffer[3] != L'0'))) { /* Don't compare the number part, just check for LPT or COM */ PathCopy.Length -= sizeof(WCHAR); @@ -284,6 +284,122 @@ RtlpCheckDeviceName(IN PUNICODE_STRING FileName, return Status; } + + +/****************************************************************** + * RtlpCollapsePath (from WINE) + * + * Helper for RtlGetFullPathName_U. + * 1) Convert slashes into backslashes + * 2) Get rid of duplicate backslashes + * 3) Get rid of . and .. components in the path. + */ +static VOID +RtlpCollapsePath(PWSTR path, ULONG mark, BOOLEAN SkipTrailingPathSeparators) +{ + PWSTR p, next; + + /* convert every / into a \ */ + for (p = path; *p; p++) + { + if (*p == L'/') *p = L'\\'; + } + + /* collapse duplicate backslashes */ + next = path + max( 1, mark ); + for (p = next; *p; p++) + { + if (*p != L'\\' || next[-1] != L'\\') *next++ = *p; + } + *next = UNICODE_NULL; + + p = path + mark; + while (*p) + { + if (*p == L'.') + { + switch(p[1]) + { + case UNICODE_NULL: /* final . */ + if (p > path + mark) p--; + *p = UNICODE_NULL; + continue; + case L'\\': /* .\ component */ + next = p + 2; + RtlMoveMemory( p, next, (wcslen(next) + 1) * sizeof(WCHAR) ); + continue; + case L'.': + if (p[2] == L'\\') /* ..\ component */ + { + next = p + 3; + if (p > path + mark) + { + p--; + while (p > path + mark && p[-1] != L'\\') p--; + } + RtlMoveMemory( p, next, (wcslen(next) + 1) * sizeof(WCHAR) ); + continue; + } + else if (!p[2]) /* final .. */ + { + if (p > path + mark) + { + p--; + while (p > path + mark && p[-1] != L'\\') p--; + if (p > path + mark) p--; + } + *p = UNICODE_NULL; + continue; + } + break; + } + } + /* skip to the next component */ + while (*p && *p != L'\\') p++; + if (*p == L'\\') + { + /* remove last dot in previous dir name */ + if (p > path + mark && p[-1] == L'.') + RtlMoveMemory( p-1, p, (wcslen(p) + 1) * sizeof(WCHAR) ); + else + p++; + } + } + + /* Remove trailing backslashes if needed (after the UNC part if it exists) */ + if (SkipTrailingPathSeparators) + { + while (p > path + mark && IS_PATH_SEPARATOR(p[-1])) *p-- = UNICODE_NULL; + } + + /* Remove trailing spaces and dots (for all the path) */ + while (p > path && (p[-1] == L' ' || p[-1] == L'.')) *p-- = UNICODE_NULL; + + /* Null-terminate the string */ + *p = UNICODE_NULL; +} + +/****************************************************************** + * RtlpSkipUNCPrefix (from WINE) + * + * Helper for RtlGetFullPathName_U + * Skip the \\share\dir part of a file name and return the new position + * (which can point on the last backslash of "dir\") + */ +static SIZE_T +RtlpSkipUNCPrefix(PCWSTR FileNameBuffer) +{ + PCWSTR UncPath = FileNameBuffer + 2; + DPRINT("RtlpSkipUNCPrefix(%S)\n", FileNameBuffer); + + while (*UncPath && !IS_PATH_SEPARATOR(*UncPath)) UncPath++; /* share name */ + while (IS_PATH_SEPARATOR(*UncPath)) UncPath++; + while (*UncPath && !IS_PATH_SEPARATOR(*UncPath)) UncPath++; /* dir name */ + /* while (IS_PATH_SEPARATOR(*UncPath)) UncPath++; */ + + return (UncPath - FileNameBuffer); +} + ULONG NTAPI RtlGetFullPathName_Ustr( @@ -294,10 +410,26 @@ RtlGetFullPathName_Ustr( _Out_opt_ PBOOLEAN InvalidName, _Out_ RTL_PATH_TYPE *PathType) { + NTSTATUS Status; PWCHAR FileNameBuffer; ULONG FileNameLength, FileNameChars, DosLength, DosLengthOffset, FullLength; + BOOLEAN SkipTrailingPathSeparators; WCHAR c; - NTSTATUS Status; + + + ULONG reqsize = 0; + PCWSTR ptr; + + PCUNICODE_STRING CurDirName; + UNICODE_STRING EnvVarName, EnvVarValue; + WCHAR EnvVarNameBuffer[4]; + + ULONG PrefixCut = 0; // Where the path really starts (after the skipped prefix) + PWCHAR Prefix = NULL; // pointer to the string to be inserted as the new path prefix + ULONG PrefixLength = 0; + PWCHAR Source; + ULONG SourceLength; + /* For now, assume the name is valid */ DPRINT("Filename: %wZ\n", FileName); @@ -306,39 +438,48 @@ RtlGetFullPathName_Ustr( /* Handle initial path type and failure case */ *PathType = RtlPathTypeUnknown; - if (!(FileName->Length) || (FileName->Buffer[0] == UNICODE_NULL)) return 0; + if ((FileName->Length == 0) || (FileName->Buffer[0] == UNICODE_NULL)) return 0; /* Break filename into component parts */ FileNameBuffer = FileName->Buffer; FileNameLength = FileName->Length; - FileNameChars = FileNameLength / sizeof(WCHAR); + FileNameChars = FileNameLength / sizeof(WCHAR); /* Kill trailing spaces */ c = FileNameBuffer[FileNameChars - 1]; - while ((FileNameLength) && (c == L' ')) + while ((FileNameLength != 0) && (c == L' ')) { /* Keep going, ignoring the spaces */ FileNameLength -= sizeof(WCHAR); - if (FileNameLength) c = FileNameBuffer[FileNameLength / sizeof(WCHAR) - 1]; + if (FileNameLength != 0) c = FileNameBuffer[FileNameLength / sizeof(WCHAR) - 1]; } /* Check if anything is left */ - if (!FileNameLength) return 0; + if (FileNameLength == 0) return 0; + + /* + * Check whether we'll need to skip trailing path separators in the + * computed full path name. If the original file name already contained + * trailing separators, then we keep them in the full path name. On the + * other hand, if the original name didn't contain any trailing separators + * then we'll skip it in the full path name. + */ + SkipTrailingPathSeparators = !IS_PATH_SEPARATOR(FileNameBuffer[FileNameChars - 1]); /* Check if this is a DOS name */ DosLength = RtlIsDosDeviceName_Ustr(FileName); DPRINT("DOS length for filename: %lx %wZ\n", DosLength, FileName); - if (DosLength) + if (DosLength != 0) { /* Zero out the short name */ if (ShortName) *ShortName = NULL; /* See comment for RtlIsDosDeviceName_Ustr if this is confusing... */ - DosLengthOffset = DosLength >> 16; - DosLength = DosLength & 0xFFFF; + DosLengthOffset = HIWORD(DosLength); + DosLength = LOWORD(DosLength); /* Do we have a DOS length, and does the caller want validity? */ - if ((InvalidName) && (DosLengthOffset)) + if (InvalidName && (DosLengthOffset != 0)) { /* Do the check */ Status = RtlpCheckDeviceName(FileName, DosLengthOffset, InvalidName); @@ -370,13 +511,226 @@ RtlGetFullPathName_Ustr( return FullLength + sizeof(UNICODE_NULL); } - /* This should work well enough for our current needs */ - *PathType = RtlDetermineDosPathNameType_U(FileNameBuffer); - DPRINT("Path type: %lx\n", *PathType); + /* Zero out the destination buffer. FileName must be different from Buffer */ + RtlZeroMemory(Buffer, Size); - /* This is disgusting... but avoids re-writing everything */ - DPRINT("Calling old API with '%S' and %lu and %S\n", FileNameBuffer, Size, Buffer); - return RtlGetFullPathName_U(FileNameBuffer, Size, Buffer, (PWSTR*)ShortName); + /* Get the path type */ + *PathType = RtlDetermineDosPathNameType_U(FileNameBuffer); + + + + /********************************************** + ** CODE REWRITTEN IS HAPPENING THERE ** + **********************************************/ + Source = FileNameBuffer; + SourceLength = FileNameLength; + EnvVarValue.Buffer = NULL; + + /* Lock the PEB to get the current directory */ + RtlAcquirePebLock(); + CurDirName = &NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath; + + switch (*PathType) + { + case RtlPathTypeUncAbsolute: /* \\foo */ + PrefixCut = RtlpSkipUNCPrefix(FileNameBuffer); + break; + + case RtlPathTypeLocalDevice: /* \\.\foo */ + PrefixCut = 4; + break; + + case RtlPathTypeDriveAbsolute: /* c:\foo */ + ASSERT(FileNameBuffer[1] == L':'); + ASSERT(IS_PATH_SEPARATOR(FileNameBuffer[2])); + + Prefix = FileNameBuffer; + PrefixLength = 3 * sizeof(WCHAR); + Source += 3; + SourceLength -= 3 * sizeof(WCHAR); + + PrefixCut = 3; + break; + + case RtlPathTypeDriveRelative: /* c:foo */ + Source += 2; + SourceLength -= 2 * sizeof(WCHAR); + if (RtlUpcaseUnicodeChar(FileNameBuffer[0]) != RtlUpcaseUnicodeChar(CurDirName->Buffer[0]) || + CurDirName->Buffer[1] != L':') + { + EnvVarNameBuffer[0] = L'='; + EnvVarNameBuffer[1] = FileNameBuffer[0]; + EnvVarNameBuffer[2] = L':'; + EnvVarNameBuffer[3] = UNICODE_NULL; + + EnvVarName.Length = 3 * sizeof(WCHAR); + EnvVarName.MaximumLength = EnvVarName.Length + sizeof(WCHAR); + EnvVarName.Buffer = EnvVarNameBuffer; + + // FIXME: Is it possible to use the user-given buffer ? + // RtlInitEmptyUnicodeString(&EnvVarValue, NULL, Size); + EnvVarValue.Length = 0; + EnvVarValue.MaximumLength = (USHORT)Size; + EnvVarValue.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); + if (EnvVarValue.Buffer == NULL) + { + Prefix = NULL; + PrefixLength = 0; + goto Quit; + } + + Status = RtlQueryEnvironmentVariable_U(NULL, &EnvVarName, &EnvVarValue); + switch (Status) + { + case STATUS_SUCCESS: + /* + * (From Wine) + * FIXME: Win2k seems to check that the environment + * variable actually points to an existing directory. + * If not, root of the drive is used (this seems also + * to be the only spot in RtlGetFullPathName that the + * existence of a part of a path is checked). + */ + EnvVarValue.Buffer[EnvVarValue.Length / sizeof(WCHAR)] = L'\\'; + Prefix = EnvVarValue.Buffer; + PrefixLength = EnvVarValue.Length + sizeof(WCHAR); /* Append trailing '\\' */ + break; + + case STATUS_BUFFER_TOO_SMALL: + reqsize = EnvVarValue.Length + SourceLength + sizeof(UNICODE_NULL); + goto Quit; + + default: + DPRINT1("RtlQueryEnvironmentVariable_U returned 0x%08lx\n", Status); + + EnvVarNameBuffer[0] = FileNameBuffer[0]; + EnvVarNameBuffer[1] = L':'; + EnvVarNameBuffer[2] = L'\\'; + EnvVarNameBuffer[3] = UNICODE_NULL; + Prefix = EnvVarNameBuffer; + PrefixLength = 3 * sizeof(WCHAR); + + RtlFreeHeap(RtlGetProcessHeap(), 0, EnvVarValue.Buffer); + EnvVarValue.Buffer = NULL; + break; + } + PrefixCut = 3; + break; + } + /* Fall through */ + DPRINT1("RtlPathTypeDriveRelative - Using fall-through to RtlPathTypeRelative\n"); + + case RtlPathTypeRelative: /* foo */ + Prefix = CurDirName->Buffer; + PrefixLength = CurDirName->Length; + if (CurDirName->Buffer[1] != L':') + { + PrefixCut = RtlpSkipUNCPrefix(CurDirName->Buffer); + } + else + { + PrefixCut = 3; + } + break; + + case RtlPathTypeRooted: /* \xxx */ + if (CurDirName->Buffer[1] == L':') + { + // The path starts with "C:\" + ASSERT(CurDirName->Buffer[1] == L':'); + ASSERT(IS_PATH_SEPARATOR(CurDirName->Buffer[2])); + + Prefix = CurDirName->Buffer; + PrefixLength = 3 * sizeof(WCHAR); // Skip "C:\" + + PrefixCut = 3; // Source index location incremented of + 3 + } + else + { + PrefixCut = RtlpSkipUNCPrefix(CurDirName->Buffer); + PrefixLength = PrefixCut * sizeof(WCHAR); + Prefix = CurDirName->Buffer; + } + break; + + case RtlPathTypeRootLocalDevice: /* \\. */ + Prefix = DeviceRootString.Buffer; + PrefixLength = DeviceRootString.Length; + Source += 3; + SourceLength -= 3 * sizeof(WCHAR); + + PrefixCut = 4; + break; + + case RtlPathTypeUnknown: + goto Quit; + } + + /* Do we have enough space for storing the full path? */ + reqsize = PrefixLength; + if (reqsize + SourceLength + sizeof(WCHAR) > Size) + { + /* Not enough space, return needed size (including terminating '\0') */ + reqsize += SourceLength + sizeof(WCHAR); + goto Quit; + } + + /* + * Build the full path + */ + // if (ShortName) DPRINT1("buffer(1) = %S\n", Buffer); + /* Copy the path's prefix */ + if (PrefixLength) RtlMoveMemory(Buffer, Prefix, PrefixLength); + // if (ShortName) DPRINT1("buffer(2) = %S\n", Buffer); + /* Copy the remaining part of the path */ + RtlMoveMemory(Buffer + PrefixLength / sizeof(WCHAR), Source, SourceLength + sizeof(WCHAR)); + // if (ShortName) DPRINT1("buffer(3) = %S\n", Buffer); + + /* Some cleanup */ + Prefix = NULL; + if (EnvVarValue.Buffer) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, EnvVarValue.Buffer); + EnvVarValue.Buffer = NULL; + } + + /* + * Finally, put the path in canonical form, + * i.e. simplify redundant . and .., etc... + */ + // if (*PathType == RtlPathTypeUncAbsolute) DPRINT1("RtlpCollapsePath('%S', %lu)\n", Buffer, PrefixCut); + RtlpCollapsePath(Buffer, PrefixCut, SkipTrailingPathSeparators); + // if (ShortName) DPRINT1("buffer(4) = %S\n", Buffer); + + /* Get the length of the full path name, without its terminating null character */ + reqsize = wcslen(Buffer) * sizeof(WCHAR); + + /* Find the file part, which is present after the last path separator */ + if (ShortName) + { + ptr = wcsrchr(Buffer, L'\\'); + if (ptr) ++ptr; // Skip it + + /* + * For UNC paths, the file part is after the \\share\dir part of the path. + */ + PrefixCut = (*PathType == RtlPathTypeUncAbsolute ? PrefixCut : 3); + + if (ptr && *ptr && (ptr >= Buffer + PrefixCut)) + { + *ShortName = ptr; + } + else + { + /* Zero-out the short name */ + *ShortName = NULL; + } + } + +Quit: + /* Release PEB lock */ + RtlReleasePebLock(); + return (ULONG)reqsize; } NTSTATUS @@ -992,8 +1346,6 @@ RtlGetCurrentDirectory_U( return Length * sizeof(WCHAR); } - - /* * @implemented */ @@ -1198,284 +1550,6 @@ Leave: } -/****************************************************************** - * collapse_path - * - * Helper for RtlGetFullPathName_U. - * Get rid of . and .. components in the path. - */ -void FORCEINLINE collapse_path( WCHAR *path, UINT mark ) -{ - WCHAR *p, *next; - - /* convert every / into a \ */ - for (p = path; *p; p++) if (*p == '/') *p = '\\'; - - /* collapse duplicate backslashes */ - next = path + max( 1, mark ); - for (p = next; *p; p++) if (*p != '\\' || next[-1] != '\\') *next++ = *p; - *next = 0; - - p = path + mark; - while (*p) - { - if (*p == '.') - { - switch(p[1]) - { - case '\\': /* .\ component */ - next = p + 2; - memmove( p, next, (wcslen(next) + 1) * sizeof(WCHAR) ); - continue; - case 0: /* final . */ - if (p > path + mark) p--; - *p = 0; - continue; - case '.': - if (p[2] == '\\') /* ..\ component */ - { - next = p + 3; - if (p > path + mark) - { - p--; - while (p > path + mark && p[-1] != '\\') p--; - } - memmove( p, next, (wcslen(next) + 1) * sizeof(WCHAR) ); - continue; - } - else if (!p[2]) /* final .. */ - { - if (p > path + mark) - { - p--; - while (p > path + mark && p[-1] != '\\') p--; - if (p > path + mark) p--; - } - *p = 0; - continue; - } - break; - } - } - /* skip to the next component */ - while (*p && *p != '\\') p++; - if (*p == '\\') - { - /* remove last dot in previous dir name */ - if (p > path + mark && p[-1] == '.') memmove( p-1, p, (wcslen(p) + 1) * sizeof(WCHAR) ); - else p++; - } - } - - /* remove trailing spaces and dots (yes, Windows really does that, don't ask) */ - while (p > path + mark && (p[-1] == ' ' || p[-1] == '.')) p--; - *p = 0; -} - - - -/****************************************************************** - * skip_unc_prefix - * - * Skip the \\share\dir\ part of a file name. Helper for RtlGetFullPathName_U. - */ -static const WCHAR *skip_unc_prefix( const WCHAR *ptr ) -{ - ptr += 2; - while (*ptr && !IS_PATH_SEPARATOR(*ptr)) ptr++; /* share name */ - while (IS_PATH_SEPARATOR(*ptr)) ptr++; - while (*ptr && !IS_PATH_SEPARATOR(*ptr)) ptr++; /* dir name */ - while (IS_PATH_SEPARATOR(*ptr)) ptr++; - return ptr; -} - - -/****************************************************************** - * get_full_path_helper - * - * Helper for RtlGetFullPathName_U - * Note: name and buffer are allowed to point to the same memory spot - */ -static ULONG get_full_path_helper( - LPCWSTR name, - LPWSTR buffer, - ULONG size) -{ - SIZE_T reqsize = 0, mark = 0, dep = 0, deplen; - LPWSTR ins_str = NULL; - LPCWSTR ptr; - const UNICODE_STRING* cd; - WCHAR tmp[4]; - - /* return error if name only consists of spaces */ - for (ptr = name; *ptr; ptr++) if (*ptr != ' ') break; - if (!*ptr) return 0; - - RtlAcquirePebLock(); - - //cd = &((PCURDIR)&NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->CurrentDirectory.DosPath)->DosPath; - cd = &NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->CurrentDirectory.DosPath; - - switch (RtlDetermineDosPathNameType_U(name)) - { - case RtlPathTypeUncAbsolute: /* \\foo */ - ptr = skip_unc_prefix( name ); - mark = (ptr - name); - break; - - case RtlPathTypeLocalDevice: /* \\.\foo */ - mark = 4; - break; - - case RtlPathTypeDriveAbsolute: /* c:\foo */ - reqsize = sizeof(WCHAR); - tmp[0] = towupper(name[0]); - ins_str = tmp; - dep = 1; - mark = 3; - break; - - case RtlPathTypeDriveRelative: /* c:foo */ - dep = 2; - if (towupper(name[0]) != towupper(cd->Buffer[0]) || cd->Buffer[1] != ':') - { - UNICODE_STRING var, val; - - tmp[0] = '='; - tmp[1] = name[0]; - tmp[2] = ':'; - tmp[3] = '\0'; - var.Length = 3 * sizeof(WCHAR); - var.MaximumLength = 4 * sizeof(WCHAR); - var.Buffer = tmp; - val.Length = 0; - val.MaximumLength = (USHORT)size; - val.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, size); - if (val.Buffer == NULL) - { - reqsize = 0; - goto done; - } - - switch (RtlQueryEnvironmentVariable_U(NULL, &var, &val)) - { - case STATUS_SUCCESS: - /* FIXME: Win2k seems to check that the environment variable actually points - * to an existing directory. If not, root of the drive is used - * (this seems also to be the only spot in RtlGetFullPathName that the - * existence of a part of a path is checked) - */ - /* fall thru */ - case STATUS_BUFFER_TOO_SMALL: - reqsize = val.Length + sizeof(WCHAR); /* append trailing '\\' */ - val.Buffer[val.Length / sizeof(WCHAR)] = '\\'; - ins_str = val.Buffer; - break; - case STATUS_VARIABLE_NOT_FOUND: - reqsize = 3 * sizeof(WCHAR); - tmp[0] = name[0]; - tmp[1] = ':'; - tmp[2] = '\\'; - ins_str = tmp; - RtlFreeHeap(RtlGetProcessHeap(), 0, val.Buffer); - break; - default: - DPRINT1("Unsupported status code\n"); - RtlFreeHeap(RtlGetProcessHeap(), 0, val.Buffer); - break; - } - mark = 3; - break; - } - /* fall through */ - - case RtlPathTypeRelative: /* foo */ - reqsize = cd->Length; - ins_str = cd->Buffer; - if (cd->Buffer[1] != ':') - { - ptr = skip_unc_prefix( cd->Buffer ); - mark = ptr - cd->Buffer; - } - else mark = 3; - break; - - case RtlPathTypeRooted: /* \xxx */ -#ifdef __WINE__ - if (name[0] == '/') /* may be a Unix path */ - { - const WCHAR *ptr = name; - int drive = find_drive_root( &ptr ); - if (drive != -1) - { - reqsize = 3 * sizeof(WCHAR); - tmp[0] = 'A' + drive; - tmp[1] = ':'; - tmp[2] = '\\'; - ins_str = tmp; - mark = 3; - dep = ptr - name; - break; - } - } -#endif - if (cd->Buffer[1] == ':') - { - reqsize = 2 * sizeof(WCHAR); - tmp[0] = cd->Buffer[0]; - tmp[1] = ':'; - ins_str = tmp; - mark = 3; - } - else - { - ptr = skip_unc_prefix( cd->Buffer ); - reqsize = (ptr - cd->Buffer) * sizeof(WCHAR); - mark = reqsize / sizeof(WCHAR); - ins_str = cd->Buffer; - } - break; - - case RtlPathTypeRootLocalDevice: /* \\. */ - reqsize = 4 * sizeof(WCHAR); - dep = 3; - tmp[0] = '\\'; - tmp[1] = '\\'; - tmp[2] = '.'; - tmp[3] = '\\'; - ins_str = tmp; - mark = 4; - break; - - case RtlPathTypeUnknown: - goto done; - } - - /* enough space ? */ - deplen = wcslen(name + dep) * sizeof(WCHAR); - if (reqsize + deplen + sizeof(WCHAR) > size) - { - /* not enough space, return need size (including terminating '\0') */ - reqsize += deplen + sizeof(WCHAR); - goto done; - } - - memmove(buffer + reqsize / sizeof(WCHAR), name + dep, deplen + sizeof(WCHAR)); - if (reqsize) memcpy(buffer, ins_str, reqsize); - reqsize += deplen; - - if (ins_str && ins_str != tmp && ins_str != cd->Buffer) - RtlFreeHeap(RtlGetProcessHeap(), 0, ins_str); - - collapse_path( buffer, (ULONG)mark ); - reqsize = wcslen(buffer) * sizeof(WCHAR); - -done: - RtlReleasePebLock(); - return (ULONG)reqsize; -} - - /****************************************************************** * RtlGetFullPathName_U (NTDLL.@) * @@ -1488,60 +1562,33 @@ done: * * @implemented */ -ULONG NTAPI RtlGetFullPathName_U( - const WCHAR* name, - ULONG size, - WCHAR* buffer, - WCHAR** file_part) + +/* + * @implemented + */ +ULONG +NTAPI +RtlGetFullPathName_U( + _In_ PCWSTR FileName, + _In_ ULONG Size, + _Out_z_bytecap_(Size) PWSTR Buffer, + _Out_opt_ PWSTR *ShortName) { - WCHAR* ptr; - ULONG dosdev; - ULONG reqsize; + NTSTATUS Status; + UNICODE_STRING FileNameString; + RTL_PATH_TYPE PathType; - DPRINT("RtlGetFullPathName_U(%S %lu %p %p)\n", name, size, buffer, file_part); + /* Build the string */ + Status = RtlInitUnicodeStringEx(&FileNameString, FileName); + if (!NT_SUCCESS(Status)) return 0; - if (!name || !*name) return 0; - - /* Zero out the destination buffer (implies that "name" should be different from "buffer" to get this function well-behaving) */ - RtlZeroMemory(buffer, size); - - if (file_part) *file_part = NULL; - - /* check for DOS device name */ - dosdev = RtlIsDosDeviceName_U((WCHAR*)name); - if (dosdev) - { - DWORD offset = HIWORD(dosdev) / sizeof(WCHAR); /* get it in WCHARs, not bytes */ - DWORD sz = LOWORD(dosdev); /* in bytes */ - - if (8 + sz + 2 > size) return sz + 10; - wcscpy(buffer, DeviceRootW); - memmove(buffer + 4, name + offset, sz); - buffer[4 + sz / sizeof(WCHAR)] = '\0'; - /* file_part isn't set in this case */ - return sz + 8; - } - - reqsize = get_full_path_helper(name, buffer, size); - if (!reqsize) return 0; - if (reqsize > size) - { - LPWSTR tmp = RtlAllocateHeap(RtlGetProcessHeap(), 0, reqsize); - if (tmp == NULL) return 0; - reqsize = get_full_path_helper(name, tmp, reqsize); - if (reqsize + sizeof(WCHAR) > size) /* it may have worked the second time */ - { - RtlFreeHeap(RtlGetProcessHeap(), 0, tmp); - return reqsize + sizeof(WCHAR); - } - memcpy( buffer, tmp, reqsize + sizeof(WCHAR) ); - RtlFreeHeap(RtlGetProcessHeap(), 0, tmp); - } - - /* find file part */ - if (file_part && (ptr = wcsrchr(buffer, '\\')) != NULL && ptr >= buffer + 2 && *++ptr) - *file_part = ptr; - return reqsize; + /* Call the extended function */ + return RtlGetFullPathName_Ustr(&FileNameString, + Size, + Buffer, + (PCWSTR*)ShortName, + NULL, + &PathType); } /* @@ -1646,9 +1693,6 @@ RtlDosSearchPath_U(IN PCWSTR Path, PWCHAR NewBuffer, BufferStart; PCWSTR p; - /* Validate the input */ - if (!(Path) || !(FileName)) return 0; - /* Check if this is an absolute path */ if (RtlDetermineDosPathNameType_U(FileName) != RtlPathTypeRelative) { @@ -1668,7 +1712,7 @@ RtlDosSearchPath_U(IN PCWSTR Path, while (*p) { /* Looking for an extension */ - if (*p == '.') + if (*p == L'.') { /* No extension string needed -- it's part of the filename */ Extension = NULL; @@ -1726,7 +1770,7 @@ RtlDosSearchPath_U(IN PCWSTR Path, if (*Path) { /* Loop as long as there's no semicolon */ - while (*Path != ';') + while (*Path != L';') { /* Copy the next character */ *BufferStart++ = *Path++; @@ -1734,7 +1778,7 @@ RtlDosSearchPath_U(IN PCWSTR Path, } /* We found a semi-colon, to stop path processing on this loop */ - if (*Path == ';') ++Path; + if (*Path == L';') ++Path; } /* Add a terminating slash if needed */ @@ -2054,7 +2098,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, sizeof(StaticCandidateBuffer)); /* Initialize optional arguments */ - if (FullNameOut) *FullNameOut = NULL; + if (FullNameOut ) *FullNameOut = NULL; if (FilePartSize) *FilePartSize = 0; if (LengthNeeded) *LengthNeeded = 0; if (DynamicString) @@ -2449,7 +2493,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, &StaticCandidateString, Status); } - DPRINT("STatus: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer); + DPRINT("Status: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer); } else { @@ -2472,7 +2516,7 @@ RtlDosSearchPath_Ustr(IN ULONG Flags, FileNameString, Status); } - DPRINT("STatus: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer); + DPRINT("Status: %lx BUFFER: %S\n", Status, CallerBuffer->Buffer); } } diff --git a/lib/sdk/CMakeLists.txt b/lib/sdk/CMakeLists.txt index 2f85da70108..c89a7365e72 100644 --- a/lib/sdk/CMakeLists.txt +++ b/lib/sdk/CMakeLists.txt @@ -1,5 +1,8 @@ add_subdirectory(comsupp) +if(MSVC) + add_subdirectory(cpprt) +endif() add_subdirectory(crt) add_subdirectory(delayimp) add_subdirectory(dxguid) diff --git a/lib/sdk/comsupp/CMakeLists.txt b/lib/sdk/comsupp/CMakeLists.txt index 051498293ea..0232dfb4682 100644 --- a/lib/sdk/comsupp/CMakeLists.txt +++ b/lib/sdk/comsupp/CMakeLists.txt @@ -1,5 +1,5 @@ -set_cpp() +set_cpp(WITH_EXCEPTIONS WITH_STL) add_library(comsupp comsupp.cpp) add_dependencies(comsupp psdk) diff --git a/lib/sdk/cpprt/CMakeLists.txt b/lib/sdk/cpprt/CMakeLists.txt new file mode 100644 index 00000000000..fad1e39d393 --- /dev/null +++ b/lib/sdk/cpprt/CMakeLists.txt @@ -0,0 +1,9 @@ + +set_cpp(WITH_EXCEPTIONS) + +list(APPEND SOURCE + ehvec.cpp + typeinfo.cpp) + +add_asm_files(cpprt_asm i386/cpprt.s) +add_library(cpprt ${SOURCE} ${cpprt_asm}) diff --git a/lib/sdk/cpprt/ehvec.cpp b/lib/sdk/cpprt/ehvec.cpp new file mode 100644 index 00000000000..a667860f6c7 --- /dev/null +++ b/lib/sdk/cpprt/ehvec.cpp @@ -0,0 +1,48 @@ +/* + * PROJECT: ReactOS c++ runtime library + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Exception-handling vector ctor/dtor iterator implementation + * PROGRAMMER: Thomas Faber (thomas.faber@reactos.org) + */ + +#include + +void __stdcall MSVCRTEX_eh_vector_constructor_iterator(void *pMem, size_t sizeOfItem, int nItems, void (__thiscall *ctor)(void *), void (__thiscall *dtor)(void *)) +{ + char *pEnd = static_cast(pMem) + nItems * sizeOfItem; + for (char *pItem = static_cast(pMem); + pItem < pEnd; + pItem += sizeOfItem) + { + try + { + ctor(pItem); + } + catch (...) + { + for (pItem -= sizeOfItem; pItem >= pMem; pItem -= sizeOfItem) + dtor(pItem); + throw; + } + } +} + +void __stdcall MSVCRTEX_eh_vector_destructor_iterator(void *pMem, size_t sizeOfItem, int nItems, void (__thiscall *dtor)(void *)) +{ + char *pEnd = static_cast(pMem) + nItems * sizeOfItem; + for (char *pItem = pEnd - sizeOfItem; + pItem >= pMem; + pItem -= sizeOfItem) + { + try + { + dtor(pItem); + } + catch (...) + { + for (pItem -= sizeOfItem; pItem >= pMem; pItem -= sizeOfItem) + dtor(pItem); + throw; + } + } +} diff --git a/lib/sdk/cpprt/i386/cpprt.s b/lib/sdk/cpprt/i386/cpprt.s new file mode 100644 index 00000000000..49d0309ccfc --- /dev/null +++ b/lib/sdk/cpprt/i386/cpprt.s @@ -0,0 +1,16 @@ +#include + +.code + +MACRO(DEFINE_ALIAS, alias, orig, type) +EXTERN &orig:&type +ALIAS <&alias> = <&orig> +ENDM + +; void __stdcall `eh vector constructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *),void (__thiscall*)(void *)) +DEFINE_ALIAS ??_L@YGXPAXIHP6EX0@Z1@Z, ?MSVCRTEX_eh_vector_constructor_iterator@@YGXPAXIHP6EX0@Z1@Z + +; void __stdcall `eh vector destructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *)) +DEFINE_ALIAS ??_M@YGXPAXIHP6EX0@Z@Z, ?MSVCRTEX_eh_vector_destructor_iterator@@YGXPAXIHP6EX0@Z@Z + +END diff --git a/lib/sdk/cpprt/typeinfo.cpp b/lib/sdk/cpprt/typeinfo.cpp new file mode 100644 index 00000000000..ac03b2d747c --- /dev/null +++ b/lib/sdk/cpprt/typeinfo.cpp @@ -0,0 +1,27 @@ +/* + * PROJECT: ReactOS c++ runtime library + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Type info stub implementation + * PROGRAMMER: Thomas Faber (thomas.faber@reactos.org) + */ + +/* TODO: #include instead */ +class type_info { +public: + __declspec(dllimport) virtual ~type_info(); +private: + type_info(const type_info &); + type_info &operator=(const type_info &); +}; + +/* These stubs don't need to do anything (those private functions are never + * called). They need to be in cpprt, though, in order to have the vtable + * and generated destructor thunks available to programs */ +type_info::type_info(const type_info &) +{ +} + +type_info &type_info::operator=(const type_info &) +{ + return *this; +} diff --git a/lib/sdk/crt/misc/environ.c b/lib/sdk/crt/misc/environ.c index 24481939017..975ab521f43 100644 --- a/lib/sdk/crt/misc/environ.c +++ b/lib/sdk/crt/misc/environ.c @@ -214,6 +214,8 @@ int SetEnv(const wchar_t *option) wchar_t *woption; char *mboption; int remove, index, count, size, result = 0, found = 0; + wchar_t **wnewenv; + char **mbnewenv; if (option == NULL || (epos = wcschr(option, L'=')) == NULL) return -1; @@ -261,14 +263,18 @@ int SetEnv(const wchar_t *option) free(*wenvptr); for (count = index; *wenvptr != NULL; wenvptr++, count++) *wenvptr = *(wenvptr + 1); - _wenviron = realloc(_wenviron, count * sizeof(wchar_t*)); + wnewenv = realloc(_wenviron, count * sizeof(wchar_t*)); + if (wnewenv != NULL) + _wenviron = wnewenv; /* Remove the option from multibyte environment. We assume * the environments are in sync and the option is at the * same position. */ free(_environ[index]); memmove(&_environ[index], &_environ[index+1], (count - index) * sizeof(char*)); - _environ = realloc(_environ, count * sizeof(char*)); + mbnewenv = realloc(_environ, count * sizeof(char*)); + if (mbnewenv != NULL) + _environ = mbnewenv; result = SetEnvironmentVariableW(name, NULL) ? 0 : -1; } @@ -303,9 +309,6 @@ int SetEnv(const wchar_t *option) } else { - wchar_t **wnewenv; - char **mbnewenv; - /* Get the size of the original environment. */ for (count = index; *wenvptr != NULL; wenvptr++, count++) ; diff --git a/lib/sdk/crt/string/scanf.h b/lib/sdk/crt/string/scanf.h index f364c8cf4ec..4d904bdfd28 100644 --- a/lib/sdk/crt/string/scanf.h +++ b/lib/sdk/crt/string/scanf.h @@ -279,7 +279,7 @@ _FUNCTION_ { /* handle exponent */ if (width!=0 && (nch == 'e' || nch == 'E')) { int exponent = 0, negexp = 0; - float expcnt; + double expcnt, shift; nch = _GETC_(file); if (width>0) width--; /* possible sign on the exponent */ @@ -296,13 +296,15 @@ _FUNCTION_ { if (width>0) width--; } /* update 'cur' with this exponent. */ - expcnt = negexp ? 0.1f : 10.0f; + expcnt = 10; + shift = 1.0; while (exponent!=0) { if (exponent&1) - cur*=expcnt; + shift *= expcnt; exponent/=2; expcnt=expcnt*expcnt; } + cur = (negexp ? cur / shift : cur * shift); } st = 1; if (!suppress) { diff --git a/lib/sdk/uuid/otherguids.c b/lib/sdk/uuid/otherguids.c index 9653b2a9fe6..c3f3589b7c2 100644 --- a/lib/sdk/uuid/otherguids.c +++ b/lib/sdk/uuid/otherguids.c @@ -29,7 +29,6 @@ DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49, DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7); DEFINE_GUID(CLSID_TF_LangBarMgr, 0xebb08c45,0x6c4a,0x4fdc,0xae,0x53,0x4e,0xb8,0xc4,0xc7,0xdb,0x8e); DEFINE_GUID(CLSID_TF_DisplayAttributeMgr, 0x3ce74de4,0x53d3,0x4d74,0x8b,0x83,0x43,0x1b,0x38,0x28,0xba,0x53); -DEFINE_GUID(CLSID_TaskbarList, 0x56fdf344,0xfd6d,0x11d0,0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90); DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31); DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14); DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43); @@ -51,6 +50,4 @@ DEFINE_GUID(CLSID_DsObjectPicker, 0x17d6ccd8, 0x3b7b, 0x11d2, 0x00b9, 0xe0,0x00, DEFINE_GUID(CLSID_StdPicture, 0x0BE35204, 0x8F91, 0x11CE, 0x9D,0xE3, 0x00,0xAA,0x00,0x4B,0xB8,0x51); DEFINE_GUID(CLSID_StdFont, 0x0BE35203, 0x8F91, 0x11CE, 0x9D,0xE3, 0x00,0xAA,0x00,0x4B,0xB8,0x51); -DEFINE_GUID(CLSID_ShellItem, 0x2fe352ea, 0xfd1f, 0x11d2, 0xb1, 0xf4, 0x00, 0xc0, 0x4f, 0x8e, 0xeb, 0x3e); - DEFINE_GUID(SID_VariantConversion, 0x1f101481,0xbccd,0x11d0,0x93,0x36,0x00,0xa0,0xc9,0xd,0xca,0xa9); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index ad5f4da8829..b115bba207d 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -35,9 +35,10 @@ reactos/dll/directx/dplay # Synced to Wine-1.5.26 reactos/dll/directx/dplayx # Synced to Wine-1.5.26 reactos/dll/directx/dsound # Synced to Wine-1.5.26 reactos/dll/directx/dxdiagn # Synced to Wine-0_9_5 +reactos/dll/directx/dxgi # Synced to Wine-1.5.26 reactos/dll/directx/msdmo # Autosync reactos/dll/directx/qedit # Autosync -reactos/dll/directx/quartz # Autosync +reactos/dll/directx/quartz # Synced to Wine-1.5.26 reactos/dll/win32/activeds # Synced to Wine-1.1.43? reactos/dll/win32/actxprxy # Synced to Wine-1.5.26 reactos/dll/win32/advpack # Synced to Wine-1.5.26 @@ -186,6 +187,7 @@ reactos/dll/win32/usp10 # Synced to Wine-1.5.26 reactos/dll/win32/uxtheme # Forked reactos/dll/win32/vbscript # Synced to Wine-1.5.26 reactos/dll/win32/version # Autosync +reactos/dll/win32/wbemprox # Synced to Wine-1.5.26 reactos/dll/win32/wer # Autosync reactos/dll/win32/windowscodecs # Synced to Wine-1.5.26 reactos/dll/win32/winemp3.acm # Synced to Wine-1.5.19 @@ -228,7 +230,8 @@ In addition the following libs, dlls and source files are mostly based on code p from Winehq CVS. If you are looking to update something in these files check Wine current souces first as it may already be fixed. -reactos/lib/sdk/uuid # Synced to Wine-1.1.42 +reactos/lib/3rdparty/strmbase # Synced to Wine-1.5.26 +reactos/lib/sdk/uuid # Synced to Wine-1.1.42 advapi32 - reactos/dll/win32/advapi32/crypt/*.c # Unknown diff --git a/media/inf/CMakeLists.txt b/media/inf/CMakeLists.txt index 85f5b3619c2..491c88ee715 100644 --- a/media/inf/CMakeLists.txt +++ b/media/inf/CMakeLists.txt @@ -27,6 +27,7 @@ list(APPEND INF_FILES NET_NIC.inf netamd.inf netisa.inf + netrtl.inf netrtpnt.inf nettcpip.inf ports.inf diff --git a/media/inf/netrtl.inf b/media/inf/netrtl.inf new file mode 100644 index 00000000000..92f32edfb0b Binary files /dev/null and b/media/inf/netrtl.inf differ diff --git a/media/inf/shortcuts.inf b/media/inf/shortcuts.inf index d37ec6c979a..bc36fc03873 100644 Binary files a/media/inf/shortcuts.inf and b/media/inf/shortcuts.inf differ diff --git a/media/inf/syssetup.inf b/media/inf/syssetup.inf index 0c5a04aeef8..8f7c8c52a52 100644 --- a/media/inf/syssetup.inf +++ b/media/inf/syssetup.inf @@ -98,6 +98,7 @@ AddReg=Classes 11,,wininet.dll,2 11,,wintrust.dll,1 11,,wuapi.dll,1 +11,wbem,wbemprox.dll,1 [TypeLibraries] stdole2.tlb diff --git a/ntoskrnl/fsrtl/largemcb.c b/ntoskrnl/fsrtl/largemcb.c index 0246b682a02..a29bd6d2a7a 100644 --- a/ntoskrnl/fsrtl/largemcb.c +++ b/ntoskrnl/fsrtl/largemcb.c @@ -1,36 +1,37 @@ /* * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory + * LICENSE: GPL v2 - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/largemcb.c * PURPOSE: Large Mapped Control Block (MCB) support for File System Drivers - * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) - * Pierre Schweitzer (heis_spiter@hotmail.com) - * Art Yerkes (art.yerkes@gmail.com) + * PROGRAMMERS: Aleksey Bragin + * Jan Kratochvil */ /* INCLUDES ******************************************************************/ #include -//#define NDEBUG +#define NDEBUG #include +#define MIN(x,y) (((x)<(y))?(x):(y)) +#define MAX(x,y) (((x)>(y))?(x):(y)) + /* GLOBALS *******************************************************************/ PAGED_LOOKASIDE_LIST FsRtlFirstMappingLookasideList; NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList; -typedef struct _LARGE_MCB_MAPPING_ENTRY +/* We use only real 'mapping' runs; we do not store 'holes' to our GTree. */ +typedef struct _LARGE_MCB_MAPPING_ENTRY // run { LARGE_INTEGER RunStartVbn; - LARGE_INTEGER SectorCount; - LARGE_INTEGER StartingLbn; - LIST_ENTRY Sequence; + LARGE_INTEGER RunEndVbn; /* RunStartVbn+SectorCount; that means +1 after the last sector */ + LARGE_INTEGER StartingLbn; /* Lbn of 'RunStartVbn' */ } LARGE_MCB_MAPPING_ENTRY, *PLARGE_MCB_MAPPING_ENTRY; -typedef struct _LARGE_MCB_MAPPING +typedef struct _LARGE_MCB_MAPPING // mcb_priv { RTL_GENERIC_TABLE Table; - LIST_ENTRY SequenceList; } LARGE_MCB_MAPPING, *PLARGE_MCB_MAPPING; typedef struct _BASE_MCB_INTERNAL { @@ -41,6 +42,18 @@ typedef struct _BASE_MCB_INTERNAL { PLARGE_MCB_MAPPING Mapping; } BASE_MCB_INTERNAL, *PBASE_MCB_INTERNAL; +static LARGE_MCB_MAPPING_ENTRY StaticRunBelow0 = { + {{-1}}, /* ignored */ + {{0}}, + {{-1}}, /* ignored */ +}; + +static PLARGE_MCB_MAPPING_ENTRY run_compare_func_last_a_run; +static PLARGE_MCB_MAPPING_ENTRY run_compare_func_last_b_run; +static PLARGE_MCB_MAPPING_ENTRY run_compare_func_minus_a_run; /* last run where we returned -1 */ +static PLARGE_MCB_MAPPING_ENTRY run_compare_func_minus_b_run; +static PLARGE_MCB_MAPPING_ENTRY run_compare_func_plus_a_run; /* last run where we returned +1 */ +static PLARGE_MCB_MAPPING_ENTRY run_compare_func_plus_b_run; static PVOID NTAPI McbMappingAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes) { @@ -57,20 +70,102 @@ static VOID NTAPI McbMappingFree(PRTL_GENERIC_TABLE Table, PVOID Buffer) ExFreePoolWithTag(Buffer, 'LMCB'); } -static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingCompare -(RTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB) +static +RTL_GENERIC_COMPARE_RESULTS +NTAPI +McbMappingCompare(PRTL_GENERIC_TABLE Table, + PVOID PtrA, + PVOID PtrB) { PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB; + INT r; + RTL_GENERIC_COMPARE_RESULTS Res; - return + /*return (A->RunStartVbn.QuadPart + A->SectorCount.QuadPart < B->RunStartVbn.QuadPart) ? GenericLessThan : - (A->RunStartVbn.QuadPart > B->RunStartVbn.QuadPart + B->SectorCount.QuadPart) ? GenericGreaterThan : GenericEqual; + (A->RunStartVbn.QuadPart > B->RunStartVbn.QuadPart + B->SectorCount.QuadPart) ? GenericGreaterThan : GenericEqual;*/ + + /*return + (A->RunEndVbn.QuadPart < B->RunStartVbn.QuadPart) ? GenericLessThan : + (A->RunStartVbn.QuadPart > B->RunEndVbn.QuadPart) ? GenericGreaterThan : GenericEqual;*/ + + run_compare_func_last_a_run = A; + run_compare_func_last_b_run = B; + + if (1 + && !(r = (A->RunStartVbn.QuadPart > B->RunStartVbn.QuadPart) - (A->RunStartVbn.QuadPart < B->RunStartVbn.QuadPart)) + && !(r = (A->RunEndVbn.QuadPart > B->RunEndVbn.QuadPart ) - (A->RunEndVbn.QuadPart < B->RunEndVbn.QuadPart ))) + { + r = 0; + } + + //DPRINT("A(%d-%d,%d) %p, B(%d-%d,%d) %p, Res %d\n", A->RunStartVbn.LowPart, A->RunEndVbn.LowPart, A->StartingLbn.LowPart, A, B->RunStartVbn.LowPart, B->RunEndVbn.LowPart, B->StartingLbn.LowPart, B, r); + + /* + negative value if a < b; + zero if a = b; + positive value if a > b. + */ + if (r < 0) + Res = GenericLessThan; + else if (r > 0) + Res = GenericGreaterThan; + else + Res = GenericEqual; + + if (Res == GenericLessThan) + { + run_compare_func_minus_a_run = A; + run_compare_func_minus_b_run = B; + } + else if (Res == GenericGreaterThan) + { + run_compare_func_plus_a_run = A; + run_compare_func_plus_b_run = B; + } + + return Res; } +static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingIntersectCompare(PRTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB) +{ + PLARGE_MCB_MAPPING_ENTRY HaystackRun = PtrA, NeedleRun = PtrB; + LARGE_MCB_MAPPING_ENTRY CommonRun; + RTL_GENERIC_COMPARE_RESULTS Res; + + if (!HaystackRun) return GenericEqual; + if (HaystackRun->RunEndVbn.QuadPart <= HaystackRun->RunStartVbn.QuadPart) return GenericEqual; + + if (!NeedleRun) return GenericEqual; + if (NeedleRun->RunEndVbn.QuadPart <= NeedleRun->RunStartVbn.QuadPart) return GenericEqual; + + CommonRun.RunStartVbn.QuadPart = MAX(HaystackRun->RunStartVbn.QuadPart, NeedleRun->RunStartVbn.QuadPart); + CommonRun.RunEndVbn.QuadPart = MIN(HaystackRun->RunEndVbn.QuadPart , NeedleRun->RunEndVbn.QuadPart ); + + if (CommonRun.RunEndVbn.QuadPart > CommonRun.RunStartVbn.QuadPart) + return GenericEqual; + + Res = McbMappingCompare(Table, NeedleRun, HaystackRun); + ASSERT(Res != GenericEqual); /* otherwise we would hit it by 'common_run' */ + return Res; +} + + /* PUBLIC FUNCTIONS **********************************************************/ /* * @implemented + * @Mcb: #PLARGE_MCB initialized by FsRtlInitializeLargeMcb(). + * %NULL value is forbidden. + * @Vbn: Starting virtual block number of the wished range. + * @Lbn: Starting logical block number of the wished range. + * @SectorCount: Length of the wished range. + * Value less or equal to %0 is forbidden; FIXME: Is the reject of %0 W32 compliant? + * + * Adds the specified range @Vbn ... @Vbn+@SectorCount-1 to @Mcb. + * Any mappings previously in this range are deleted first. + * + * Returns: %TRUE if successful. */ BOOLEAN NTAPI @@ -80,64 +175,111 @@ FsRtlAddBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG SectorCount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - LARGE_MCB_MAPPING_ENTRY Node; - PLARGE_MCB_MAPPING_ENTRY Existing = NULL; - BOOLEAN NewElement = FALSE; + LARGE_MCB_MAPPING_ENTRY Node, NeedleRun; + PLARGE_MCB_MAPPING_ENTRY LowerRun, HigherRun, Existing = NULL; + BOOLEAN NewElement; + if (Vbn < 0) return FALSE; + if (SectorCount <= 0) return FALSE; + + //DPRINT("Mcb=%p,Vbn=%lld,Lbn=%lld,SectorCount=%lld\n", Mcb, Vbn, Lbn, SectorCount); + + /* clean any possible previous entries in our range */ + FsRtlRemoveBaseMcbEntry(OpaqueMcb, Vbn, SectorCount); + + // We need to map [Vbn, Vbn+SectorCount) to [Lbn, Lbn+SectorCount), + // taking in account the fact that we need to merge these runs if + // they are adjacent or overlap, but fail if new run fully fits into another run + + /* initially we think we will be inserted as a separate run */ Node.RunStartVbn.QuadPart = Vbn; + Node.RunEndVbn.QuadPart = Vbn + SectorCount; Node.StartingLbn.QuadPart = Lbn; - Node.SectorCount.QuadPart = SectorCount; - while (!NewElement) + /* optionally merge with lower run */ + NeedleRun.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart - 1; + NeedleRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart + 1; + //if ((LowerRun = g_tree_search(Mcb_priv->gtree,(GCompareFunc)run_intersect_compare_func, &NeedleRun))) + Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare; + if ((LowerRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun))) { - DPRINT("Inserting %x:%x\n", Node.RunStartVbn.LowPart, Node.SectorCount.LowPart); - Existing = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement); - DPRINT("Existing %x\n", Existing); - if (!Existing) break; - - DPRINT("NewElement %d\n", NewElement); - if (!NewElement) - { - // We merge the existing runs - LARGE_INTEGER StartVbn, FinalVbn; - DPRINT("Existing: %x:%x\n", Existing->RunStartVbn.LowPart, Node.SectorCount.LowPart); - if (Existing->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) - { - StartVbn = Existing->RunStartVbn; - Node.StartingLbn = Existing->StartingLbn; - } - else - { - StartVbn = Node.RunStartVbn; - } - DPRINT("StartVbn %x\n", StartVbn.LowPart); - if (Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart > - Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart) - { - FinalVbn.QuadPart = Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart; - } - else - { - FinalVbn.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; - } - DPRINT("FinalVbn %x\n", FinalVbn.LowPart); - Node.RunStartVbn.QuadPart = StartVbn.QuadPart; - Node.SectorCount.QuadPart = FinalVbn.QuadPart - StartVbn.QuadPart; - RemoveHeadList(&Existing->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); - Mcb->PairCount--; - } - else - { - DPRINT("Mapping added %x\n", Existing); - Mcb->MaximumPairCount++; - Mcb->PairCount++; - InsertHeadList(&Mcb->Mapping->SequenceList, &Existing->Sequence); - } + ASSERT(LowerRun->RunEndVbn.QuadPart == Node.RunStartVbn.QuadPart); + Node.RunStartVbn.QuadPart = LowerRun->RunStartVbn.QuadPart; + Mcb->Mapping->Table.CompareRoutine = McbMappingCompare; + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, LowerRun); + DPRINT("Intersecting lower run found (%I64d,%I64d) Lbn: %I64d\n", LowerRun->RunStartVbn.QuadPart, LowerRun->RunEndVbn.QuadPart, LowerRun->StartingLbn.QuadPart); } - DPRINT("!!Existing %d\n", !!Existing); - return !!Existing; + /* optionally merge with higher run */ + NeedleRun.RunStartVbn.QuadPart = Node.RunEndVbn.QuadPart; + NeedleRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart + 1; + //if ((HigherRun = g_tree_search(Mcb_priv->gtree,(GCompareFunc)run_intersect_compare_func, &NeedleRun))) + Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare; + if ((HigherRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun))) + { + ASSERT(HigherRun->RunStartVbn.QuadPart == Node.RunEndVbn.QuadPart); + Node.RunEndVbn.QuadPart = HigherRun->RunEndVbn.QuadPart; + Mcb->Mapping->Table.CompareRoutine = McbMappingCompare; + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, HigherRun); + DPRINT("Intersecting higher run found (%I64d,%I64d) Lbn: %I64d\n", HigherRun->RunStartVbn.QuadPart, HigherRun->RunEndVbn.QuadPart, HigherRun->StartingLbn.QuadPart); + } + Mcb->Mapping->Table.CompareRoutine = McbMappingCompare; + + /* finally insert the resulting run */ + Existing = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement); + DPRINT("Existing %x, NewElement %d\n", Existing, NewElement); + ASSERT(NewElement); + + // NB: Two consecutive runs can only be merged, if actual LBNs also match! + + /* 1. + Existing->RunStartVbn + | + |///////| + |/////////////| + | + Node->RunStartVbn + + 2. + Existing->RunStartVbn + | + |///////| + |//////| + | + Node->RunStartVbn + + 3. + Existing->RunStartVbn + | + |///////| + |///| + | + Node->RunStartVbn + + 4. + Existing->RunStartVbn + | + |///////| + |///////////////| + | + Node->RunStartVbn + + + Situation with holes: + 1. Holes at both ends + 2. Hole at the right, new run merged with the previous run + 3. Hole at the right, new run is not merged with the previous run + 4. Hole at the left, new run merged with the next run + 5. Hole at the left, new run is not merged with the next run + 6. No holes, exact fit to merge with both previous and next runs + 7. No holes, merges only with the next run + 8. No holes, merges only with the previous run + 9. No holes, does not merge with next or prev runs + + + Overwriting existing mapping is not possible and results in FALSE being returned + */ + return TRUE; } /* @@ -152,7 +294,7 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("Mcb %x Vbn %x Lbn %x SectorCount %x\n", Mcb, Vbn, Lbn, SectorCount); + DPRINT("Mcb %x Vbn %lld Lbn %lld SectorCount %lld\n", Mcb, Vbn, Lbn, SectorCount); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlAddBaseMcbEntry(&(Mcb->BaseMcb), @@ -167,7 +309,25 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, } /* - * @unimplemented + * @implemented + * @Mcb: #PLARGE_MCB initialized by FsRtlInitializeLargeMcb(). + * %NULL value is forbidden. + * @RunIndex: Requested range index to retrieve. + * @Vbn: Returns the starting virtual block number of the wished range. + * %NULL pointer is forbidden. + * @Lbn: Returns the starting logical block number of the wished range (or -1 if it is a hole). + * %NULL pointer is forbidden. + * @SectorCount: Returns the length of the wished range. + * %NULL pointer is forbidden. + * Value less or equal to %0 is forbidden; FIXME: Is the reject of %0 W32 compliant? + * + * Retrieves the parameters of the specified run with index @RunIndex. + * + * Mapping %0 always starts at virtual block %0, either as 'hole' or as 'real' mapping. + * libcaptive does not store 'hole' information to its #GTree. + * Last run is always a 'real' run. 'hole' runs appear as mapping to constant @Lbn value %-1. + * + * Returns: %TRUE if successful. */ BOOLEAN NTAPI @@ -178,26 +338,93 @@ FsRtlGetNextBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PLONGLONG SectorCount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - ULONG i = 0; - BOOLEAN Result = FALSE; - PLARGE_MCB_MAPPING_ENTRY Entry; + ULONG RunIndexRemaining; + PLARGE_MCB_MAPPING_ENTRY Run, RunFound = NULL, RunFoundLower = NULL, RunFoundHigher = NULL; + BOOLEAN First = TRUE; - for (Entry = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); - Entry && (i < RunIndex); - Entry = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE), i++); + RunIndexRemaining = RunIndex; - if (Entry) + /* Traverse the tree */ + for (Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); + Run; + Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)) { - Result = TRUE; - if (Vbn) - *Vbn = Entry->RunStartVbn.QuadPart; - if (Lbn) - *Lbn = Entry->StartingLbn.QuadPart; - if (SectorCount) - *SectorCount = Entry->SectorCount.QuadPart; + if (First) + { + /* Take care when we must emulate missing 'hole' run at start of our run list. */ + if (Run->RunStartVbn.QuadPart > 0) + { + if (RunIndexRemaining == 0) + { + RunFoundLower = &StaticRunBelow0; + RunFoundHigher = Run; + + /* stop the traversal */ + break; + } + /* If someone wants RunIndex #1 we are already on it. */ + RunIndexRemaining--; + } + First = FALSE; + } + + if (RunIndexRemaining > 0) + { + /* FIXME: performance: non-linear direct seek to the requested RunIndex */ + RunIndexRemaining--; + if (RunIndexRemaining == 0) + RunFoundLower = Run; + else + RunIndexRemaining--; + + /* continue the traversal */ + continue; + } + + if (RunFoundLower) + RunFoundHigher = Run; + else + RunFound = Run; + + /* stop the traversal */ + break; } - return Result; + if (RunFound) DPRINT("RunFound(%d %d %d)\n", RunFound->RunStartVbn.LowPart, RunFound->RunEndVbn.LowPart, RunFound->StartingLbn.LowPart); + if (RunFoundLower) DPRINT("RunFoundLower(%d %d %d)\n", RunFoundLower->RunStartVbn.LowPart, RunFoundLower->RunEndVbn.LowPart, RunFoundLower->StartingLbn.LowPart); + if (RunFoundHigher) DPRINT("RunFoundHigher(%d %d %d)\n", RunFoundHigher->RunStartVbn.LowPart, RunFoundHigher->RunEndVbn.LowPart, RunFoundHigher->StartingLbn.LowPart); + + if (RunFound) + { + ASSERT(RunFoundLower == NULL); + ASSERT(RunFoundHigher == NULL); + + if (Vbn) + *Vbn = RunFound->RunStartVbn.QuadPart; + if (Lbn) + *Lbn = RunFound->StartingLbn.QuadPart; + if (SectorCount) + *SectorCount = RunFound->RunEndVbn.QuadPart - RunFound->RunStartVbn.QuadPart; + + return TRUE; + } + + if (RunFoundLower && RunFoundHigher) + { + //ASSERT(RunFoundHigher != NULL); + + if (Vbn) + *Vbn = RunFoundLower->RunEndVbn.QuadPart; + if (Lbn) + *Lbn = -1; + if (SectorCount) + *SectorCount = RunFoundHigher->RunStartVbn.QuadPart - RunFoundLower->RunEndVbn.QuadPart; + + return TRUE; + } + + ASSERT(RunFoundHigher == NULL); + return FALSE; } /* @@ -213,7 +440,7 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("FsRtlGetNextLargeMcbEntry Mcb %x RunIndex %x\n", Mcb, RunIndex); + DPRINT("FsRtlGetNextLargeMcbEntry Mcb %p RunIndex %d\n", Mcb, RunIndex); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlGetNextBaseMcbEntry(&(Mcb->BaseMcb), @@ -237,7 +464,6 @@ FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb, IN POOL_TYPE PoolType) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - Mcb->PairCount = 0; if (PoolType == PagedPool) { @@ -251,13 +477,13 @@ FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb, } Mcb->PoolType = PoolType; + Mcb->PairCount = 0; Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT; RtlInitializeGenericTable(&Mcb->Mapping->Table, - (PRTL_GENERIC_COMPARE_ROUTINE)McbMappingCompare, + McbMappingCompare, McbMappingAllocate, McbMappingFree, Mcb); - InitializeListHead(&Mcb->Mapping->SequenceList); } /* @@ -325,44 +551,98 @@ FsRtlLookupBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PULONG Index OPTIONAL) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - BOOLEAN Result = FALSE; - LARGE_MCB_MAPPING_ENTRY ToLookup; - PLARGE_MCB_MAPPING_ENTRY Entry; - ToLookup.RunStartVbn.QuadPart = Vbn; - ToLookup.SectorCount.QuadPart = 1; - Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); - DPRINT("Entry %p\n", Entry); - if (!Entry) + ULONG RunIndex = 0; + PLARGE_MCB_MAPPING_ENTRY Run, RunFound = NULL, RunFoundLower = NULL, RunFoundHigher = NULL; + BOOLEAN First = TRUE; + + /* Traverse the tree */ + for (Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); + Run; + Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)) { - // Find out if we have a following entry. The spec says we should return - // found with Lbn == -1 when we're beneath the largest map. - ToLookup.SectorCount.QuadPart = (1ull<<62) - ToLookup.RunStartVbn.QuadPart; - Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); - DPRINT("Entry %p\n", Entry); - if (Entry) + if (First) { - Result = TRUE; - if (Lbn) *Lbn = ~0ull; + /* Take care when we must emulate missing 'hole' run at start of our run list. */ + if (Run->RunStartVbn.QuadPart > 0) + { + RunIndex++; + RunFoundLower = &StaticRunBelow0; + } + First = FALSE; } - else + + if (Run->RunStartVbn.QuadPart <= Vbn && Vbn < Run->RunEndVbn.QuadPart) { - Result = FALSE; + RunFound = Run; + RunFoundLower = NULL; + /* stop the traversal; hit */ + break; } + + if (Run->RunEndVbn.QuadPart <= Vbn) + { + RunFoundLower = Run; + RunIndex += 2; + /* continue the traversal; not yet crossed by the run */ + continue; + } + + if (Vbn < Run->RunStartVbn.QuadPart) + { + RunFoundHigher = Run; + RunIndex++; + /* stop the traversal; the run skipped us */ + break; + } + + ASSERT(FALSE); + /* stop the traversal */ + break; } - else + + if (RunFound) { - LARGE_INTEGER Offset; - Offset.QuadPart = Vbn - Entry->RunStartVbn.QuadPart; - Result = TRUE; - if (Lbn) *Lbn = Entry->StartingLbn.QuadPart + Offset.QuadPart; - if (SectorCountFromLbn) *SectorCountFromLbn = Entry->SectorCount.QuadPart - Offset.QuadPart; - if (StartingLbn) *StartingLbn = Entry->StartingLbn.QuadPart; - if (SectorCountFromStartingLbn) *SectorCountFromStartingLbn = Entry->SectorCount.QuadPart; + ASSERT(RunFoundLower == NULL); + ASSERT(RunFoundHigher == NULL); + + if (Lbn) + *Lbn = RunFound->StartingLbn.QuadPart + (Vbn - RunFound->RunStartVbn.QuadPart); + + if (SectorCountFromLbn) /* FIXME: 'after' means including current 'Lbn' or without it? */ + *SectorCountFromLbn = RunFound->RunEndVbn.QuadPart - Vbn; + if (StartingLbn) + *StartingLbn = RunFound->StartingLbn.QuadPart; + if (SectorCountFromStartingLbn) + *SectorCountFromStartingLbn = RunFound->RunEndVbn.QuadPart - RunFound->RunStartVbn.QuadPart; + if (Index) + *Index = RunIndex; + + return TRUE; } - DPRINT("Done\n"); - return Result; + + if (RunFoundHigher) + { + /* search for hole */ + ASSERT(RunFoundLower != NULL); + + if (Lbn) + *Lbn = ~0ull; + if (SectorCountFromLbn) /* FIXME: 'after' means including current 'Lbn' or without it? */ + *SectorCountFromLbn = RunFoundHigher->RunStartVbn.QuadPart - Vbn; + if (StartingLbn) + *StartingLbn = ~0ull; + if (SectorCountFromStartingLbn) + *SectorCountFromStartingLbn = RunFoundHigher->RunStartVbn.QuadPart - RunFoundLower->RunEndVbn.QuadPart; + if (Index) + *Index = RunIndex; + + return TRUE; + } + + /* We may have some 'RunFoundLower'. */ + return FALSE; } /* @@ -397,8 +677,57 @@ FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, return Result; } +static BOOLEAN +NTAPI +FsRtlLookupLastLargeMcbEntryAndIndex_internal(IN PBASE_MCB_INTERNAL Mcb, + OUT PLONGLONG Vbn, + OUT PLONGLONG Lbn, + OUT PULONG Index OPTIONAL) +{ + LARGE_MCB_MAPPING_ENTRY NeedleRunTop; + PLARGE_MCB_MAPPING_ENTRY FoundRun; + ULONG Runs; + + NeedleRunTop.RunStartVbn.QuadPart = MAXLONGLONG - 1; + NeedleRunTop.RunEndVbn.QuadPart = MAXLONGLONG; + NeedleRunTop.StartingLbn.QuadPart = ~0ull; /* ignored*/ + + run_compare_func_last_a_run = NULL; + run_compare_func_last_b_run = NULL; + + FoundRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRunTop); + ASSERT(FoundRun == NULL); + + if (run_compare_func_last_a_run == NULL) + { + ASSERT(run_compare_func_last_b_run == NULL); + + *Vbn = -1; + *Lbn = -1; + if (Index) *Index = 0; + return FALSE; + } + ASSERT(run_compare_func_last_a_run != &NeedleRunTop); + ASSERT(run_compare_func_last_b_run == &NeedleRunTop); + + *Vbn = run_compare_func_last_a_run->RunEndVbn.QuadPart - 1; + *Lbn = run_compare_func_last_a_run->StartingLbn.QuadPart + ((run_compare_func_last_a_run->RunEndVbn.QuadPart - 1) - run_compare_func_last_a_run->RunStartVbn.QuadPart); + + if (Index) + { + Runs = FsRtlNumberOfRunsInBaseMcb((PBASE_MCB)Mcb); + + /* There must be some runs if we found _something_. */ + ASSERT(Runs > 0); + *Index = Runs - 1; + } + + return TRUE; +} + + /* - * @unimplemented + * @implemented */ BOOLEAN NTAPI @@ -408,28 +737,8 @@ FsRtlLookupLastBaseMcbEntryAndIndex(IN PBASE_MCB OpaqueMcb, IN OUT PULONG Index) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - ULONG i = 0; - BOOLEAN Result = FALSE; - PLIST_ENTRY ListEntry; - PLARGE_MCB_MAPPING_ENTRY Entry; - PLARGE_MCB_MAPPING_ENTRY CountEntry; - ListEntry = &Mcb->Mapping->SequenceList; - if (!IsListEmpty(ListEntry)) - { - Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); - Result = TRUE; - *LargeVbn = Entry->RunStartVbn.QuadPart; - *LargeLbn = Entry->StartingLbn.QuadPart; - - for (i = 0, CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); - CountEntry != Entry; - CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)); - DPRINT1("Most probably we are returning shit now\n"); - *Index = i; - } - - return Result; + return FsRtlLookupLastLargeMcbEntryAndIndex_internal(Mcb, LargeVbn, LargeLbn, Index); } /* @@ -468,20 +777,8 @@ FsRtlLookupLastBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PLONGLONG Lbn) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - BOOLEAN Result = FALSE; - PLIST_ENTRY ListEntry; - PLARGE_MCB_MAPPING_ENTRY Entry; - ListEntry = &Mcb->Mapping->SequenceList; - if (!IsListEmpty(ListEntry)) - { - Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); - Result = TRUE; - *Vbn = Entry->RunStartVbn.QuadPart; - *Lbn = Entry->StartingLbn.QuadPart; - } - - return Result; + return FsRtlLookupLastLargeMcbEntryAndIndex_internal(Mcb, Vbn, Lbn, NULL); /* Index */ } /* @@ -513,10 +810,26 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, */ ULONG NTAPI -FsRtlNumberOfRunsInBaseMcb(IN PBASE_MCB Mcb) +FsRtlNumberOfRunsInBaseMcb(IN PBASE_MCB OpaqueMcb) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; + LONGLONG LbnAtVbn0 = -1; + ULONG Nodes = RtlNumberGenericTableElements(&Mcb->Mapping->Table); + + if (Nodes == 0) return 0; + + FsRtlLookupBaseMcbEntry(OpaqueMcb, + 0, /* Vbn */ + &LbnAtVbn0, /* Lbn */ + NULL, NULL, NULL, NULL); /* 4 output arguments - not interested in them */ + + /* Return the count */ - return Mcb->PairCount; + //return Mcb->PairCount; + /* Return the number of 'real' and 'hole' runs. + * If we do not have sector 0 as 'real' emulate a 'hole' there. + */ + return Nodes * 2 - (LbnAtVbn0 != -1 ? 1 : 0); /* include holes as runs */ } /* @@ -532,7 +845,7 @@ FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) /* Read the number of runs while holding the MCB lock */ KeAcquireGuardedMutex(Mcb->GuardedMutex); - NumberOfRuns = Mcb->BaseMcb.PairCount; + NumberOfRuns = FsRtlNumberOfRunsInBaseMcb(&(Mcb->BaseMcb)); KeReleaseGuardedMutex(Mcb->GuardedMutex); DPRINT("Done %d\n", NumberOfRuns); @@ -542,7 +855,15 @@ FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) } /* - * @unimplemented + * @implemented + * @Mcb: #PLARGE_MCB initialized by FsRtlInitializeLargeMcb(). + * %NULL value is forbidden. + * @Vbn: Starting virtual block number to specify the range to delete. + * @SectorCount: Length of the range to delete. + * Value less or equal to %0 is forbidden; FIXME: Is the reject of %0 W32 compliant? + * + * Deletes any possible @Mcb mappings in the given range @Vbn ... @Vbn+@SectorCount-1. + * This call has no problems if no mappings exist there yet. */ BOOLEAN NTAPI @@ -551,79 +872,41 @@ FsRtlRemoveBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG SectorCount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - LARGE_MCB_MAPPING_ENTRY Node; - LARGE_MCB_MAPPING_ENTRY NewElement; - PLARGE_MCB_MAPPING_ENTRY Element; - PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted; - LARGE_INTEGER StartHole, EndHole, EndRun; + LARGE_MCB_MAPPING_ENTRY NeedleRun; + PLARGE_MCB_MAPPING_ENTRY HaystackRun; - Node.RunStartVbn.QuadPart = Vbn; - Node.SectorCount.QuadPart = SectorCount; + if (Vbn < 0 || SectorCount <= 0) return FALSE; + /* FIXME: We are unable to delete the absolutely last sector G_MAXINT64 by this implementation! */ + if (Vbn + SectorCount <= Vbn) return FALSE; - while ((Element = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node))) + NeedleRun.RunStartVbn.QuadPart = Vbn; + NeedleRun.RunEndVbn.QuadPart = Vbn + SectorCount; + + /* adjust/destroy all intersecting ranges */ + Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare; + //while ((HaystackRun = g_tree_search(Mcb_priv->gtree,(GCompareFunc)run_intersect_compare_func,&needle_run))) + while ((HaystackRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun))) { - DPRINT1("Node.RunStartVbn %I64d, Node.SectorCount %I64d\n", Node.RunStartVbn.QuadPart, Node.SectorCount.QuadPart); - DPRINT1("Element %p, .RunStartVbn %I64d, .SectorCount %I64d\n", Element, Element->RunStartVbn.QuadPart, Element->SectorCount.QuadPart); - // Must split - if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart && - Element->SectorCount.QuadPart > Node.SectorCount.QuadPart) + if (HaystackRun->RunStartVbn.QuadPart < NeedleRun.RunStartVbn.QuadPart) { - LARGE_MCB_MAPPING_ENTRY Upper, Reinsert; - StartHole = Node.RunStartVbn; - EndHole.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; - - Upper.RunStartVbn.QuadPart = EndHole.QuadPart; - Upper.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + EndHole.QuadPart - Element->RunStartVbn.QuadPart; - Upper.SectorCount.QuadPart = Element->SectorCount.QuadPart - (EndHole.QuadPart - Element->RunStartVbn.QuadPart); - Reinsert = *Element; - Reinsert.SectorCount.QuadPart = Element->RunStartVbn.QuadPart - StartHole.QuadPart; - RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - Mcb->PairCount--; - - Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Reinsert, sizeof(Reinsert), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); - Mcb->PairCount++; - - Inserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Upper, sizeof(Upper), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Inserted->Sequence); - Mcb->PairCount++; + ASSERT(HaystackRun->RunEndVbn.QuadPart > NeedleRun.RunStartVbn.QuadPart); + HaystackRun->RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart; } - else if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) + else if (HaystackRun->RunEndVbn.QuadPart > NeedleRun.RunEndVbn.QuadPart) { - StartHole = Node.RunStartVbn; - NewElement.RunStartVbn = Element->RunStartVbn; - NewElement.StartingLbn = Element->StartingLbn; - NewElement.SectorCount.QuadPart = StartHole.QuadPart - Element->StartingLbn.QuadPart; - - RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - Mcb->PairCount--; - - Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); - Mcb->PairCount++; + ASSERT(HaystackRun->RunStartVbn.QuadPart < NeedleRun.RunEndVbn.QuadPart); + HaystackRun->RunStartVbn.QuadPart = NeedleRun.RunEndVbn.QuadPart; } else { - EndHole = Element->RunStartVbn; - EndRun.QuadPart = Element->RunStartVbn.QuadPart + Element->SectorCount.QuadPart; - NewElement.RunStartVbn = EndHole; - NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + (EndHole.QuadPart - Element->RunStartVbn.QuadPart); - NewElement.SectorCount.QuadPart = EndRun.QuadPart - EndHole.QuadPart; - - RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - Mcb->PairCount--; - - Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); - Mcb->PairCount++; - - DPRINT1("Reinserted %p, .RunStartVbn %I64d, .SectorCount %I64d\n", Reinserted, Reinserted->RunStartVbn.QuadPart, Reinserted->SectorCount.QuadPart); - DPRINT1("NewElement .RunStartVbn %I64d, .SectorCount %I64d\n", NewElement.RunStartVbn.QuadPart, NewElement.SectorCount.QuadPart); + ASSERT(NeedleRun.RunStartVbn.QuadPart >= HaystackRun->RunStartVbn.QuadPart); + ASSERT(NeedleRun.RunEndVbn.QuadPart <= HaystackRun->RunEndVbn.QuadPart); + Mcb->Mapping->Table.CompareRoutine = McbMappingCompare; + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, HaystackRun); + Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare; } } + Mcb->Mapping->Table.CompareRoutine = McbMappingCompare; return TRUE; } @@ -637,7 +920,7 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount) { - DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %I64d, SectorCount %I64d\n", Mcb, (ULONG)Vbn, (ULONG)SectorCount); + DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %I64d, SectorCount %I64d\n", Mcb, Vbn, SectorCount); KeAcquireGuardedMutex(Mcb->GuardedMutex); FsRtlRemoveBaseMcbEntry(&(Mcb->BaseMcb), Vbn, SectorCount); @@ -683,43 +966,6 @@ FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, KeReleaseGuardedMutex(Mcb->GuardedMutex); } -#define MCB_BUMP_NO_MORE 0 -#define MCB_BUMP_AGAIN 1 - -static ULONG NTAPI McbBump(PBASE_MCB_INTERNAL Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart) -{ - LARGE_MCB_MAPPING_ENTRY Reimagined; - PLARGE_MCB_MAPPING_ENTRY Found = NULL; - - DPRINT("McbBump %x (%x:%x)\n", Mcb, FixedPart->RunStartVbn.LowPart, FixedPart->SectorCount.LowPart); - - Reimagined = *FixedPart; - while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Reimagined))) - { - Reimagined = *Found; - Reimagined.RunStartVbn.QuadPart = - FixedPart->RunStartVbn.QuadPart + FixedPart->SectorCount.QuadPart; - DPRINT("Reimagined %x\n", Reimagined.RunStartVbn.LowPart); - } - - DPRINT("Found %x\n", Found); - if (!Found) return MCB_BUMP_NO_MORE; - - DPRINT1 - ("Moving %x-%x to %x because %x-%x overlaps\n", - Found->RunStartVbn.LowPart, - Found->RunStartVbn.LowPart + Found->SectorCount.QuadPart, - Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart, - Reimagined.RunStartVbn.LowPart, - Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart); - - Found->RunStartVbn.QuadPart = Reimagined.RunStartVbn.QuadPart + Reimagined.SectorCount.QuadPart; - Found->StartingLbn.QuadPart = Reimagined.StartingLbn.QuadPart + Reimagined.SectorCount.QuadPart; - - DPRINT("Again\n"); - return MCB_BUMP_AGAIN; -} - /* * @unimplemented */ @@ -730,72 +976,50 @@ FsRtlSplitBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Amount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - ULONG Result; - LARGE_MCB_MAPPING_ENTRY Node; - PLARGE_MCB_MAPPING_ENTRY Existing = NULL; + PLARGE_MCB_MAPPING_ENTRY Run, InsertLowerRun = NULL, ExistingRun = NULL; + LARGE_MCB_MAPPING_ENTRY LowerRun; + BOOLEAN NewElement; - Node.RunStartVbn.QuadPart = Vbn; - Node.SectorCount.QuadPart = 0; - - Existing = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node); - - if (Existing) + /* Traverse the tree */ + for (Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); + Run; + Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)) { - // We're in the middle of a run - LARGE_MCB_MAPPING_ENTRY UpperPart; - LARGE_MCB_MAPPING_ENTRY LowerPart; - PLARGE_MCB_MAPPING_ENTRY InsertedUpper; + /* unaffected run? */ + /* FIXME: performance: effective skip of all 'lower' runs without traversing them */ + if (Vbn >= Run->RunStartVbn.QuadPart) continue; - UpperPart.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart + Amount; - UpperPart.SectorCount.QuadPart = Existing->RunStartVbn.QuadPart + - (Existing->SectorCount.QuadPart - Node.RunStartVbn.QuadPart); - UpperPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart + - (Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart); - LowerPart.RunStartVbn.QuadPart = Existing->RunStartVbn.QuadPart; - LowerPart.SectorCount.QuadPart = Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart; - LowerPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart; - - Node = UpperPart; - - DPRINT("Loop: %x\n", Node.RunStartVbn.LowPart); - while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN) + /* crossing run to be split? + * 'lower_run' is created on the original place; just shortened. + * current 'run' is shifted up later + */ + if (Vbn < Run->RunEndVbn.QuadPart) { - DPRINT("Node: %x\n", Node.RunStartVbn.LowPart); - } - DPRINT("Done\n"); + LowerRun = *Run; + LowerRun.RunEndVbn.QuadPart = Vbn; + /* FIXME: shift 'run->Lbn_start' ? */ + Run->RunStartVbn.QuadPart = Vbn; - if (Result == MCB_BUMP_NO_MORE) - { - Node = *Existing; - RemoveHeadList(&Existing->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); - Mcb->PairCount--; - - // Adjust the element we found. - Existing->SectorCount = LowerPart.SectorCount; - - InsertedUpper = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &UpperPart, sizeof(UpperPart), NULL); - if (!InsertedUpper) - { - // Just make it like it was - Existing->SectorCount = Node.SectorCount; - return FALSE; - } - InsertHeadList(&Mcb->Mapping->SequenceList, &InsertedUpper->Sequence); - Mcb->PairCount++; - } - else - { - Node.RunStartVbn.QuadPart = Vbn; - Node.SectorCount.QuadPart = Amount; - while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN); - return Result == MCB_BUMP_NO_MORE; + InsertLowerRun = &LowerRun; } + + /* Shift the current 'run'. + * Ordering is not changed in Generic Tree so I hope I do not need to reinsert it. + */ + Run->RunStartVbn.QuadPart += Amount; + ASSERT(Run->RunEndVbn.QuadPart + Amount > Run->RunEndVbn.QuadPart); /* overflow? */ + Run->RunEndVbn.QuadPart += Amount; + /* FIXME: shift 'run->Lbn_start' ? */ + + /* continue the traversal */ } - DPRINT("Done\n"); + if (InsertLowerRun) + ExistingRun = RtlInsertElementGenericTable(&Mcb->Mapping->Table, InsertLowerRun, sizeof(*InsertLowerRun), &NewElement); - return TRUE; + ASSERT(ExistingRun == NULL); + + return (InsertLowerRun != NULL); /* the hole was successfuly created? */ } /* @@ -830,24 +1054,8 @@ NTAPI FsRtlTruncateBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn) { - PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - if (!Vbn) - { - FsRtlResetBaseMcb(OpaqueMcb); - } - else - { - LARGE_MCB_MAPPING_ENTRY Truncate; - PLARGE_MCB_MAPPING_ENTRY Found; - Truncate.RunStartVbn.QuadPart = Vbn; - Truncate.SectorCount.QuadPart = (1ull<<62) - Truncate.RunStartVbn.QuadPart; - while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Truncate))) - { - RemoveEntryList(&Found->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Found); - Mcb->PairCount--; - } - } + DPRINT("Mcb=%p, Vbn=%I64d\n", OpaqueMcb, Vbn); + FsRtlRemoveBaseMcbEntry(OpaqueMcb, Vbn, MAXLONGLONG - Vbn + 1); } /* @@ -874,7 +1082,7 @@ FsRtlUninitializeBaseMcb(IN PBASE_MCB Mcb) { FsRtlResetBaseMcb(Mcb); - if ((Mcb->PoolType == PagedPool) && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT)) + if ((Mcb->PoolType == PagedPool)/* && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT)*/) { ExFreeToPagedLookasideList(&FsRtlFirstMappingLookasideList, Mcb->Mapping); diff --git a/ntoskrnl/fstub/fstubex.c b/ntoskrnl/fstub/fstubex.c index 26c610609c9..fabda98cab8 100644 --- a/ntoskrnl/fstub/fstubex.c +++ b/ntoskrnl/fstub/fstubex.c @@ -84,7 +84,7 @@ typedef struct _MASTER_BOOT_RECORD #define EFI_HEADER_SIGNATURE 0x5452415020494645ULL /* Defines version 1.0 */ #define EFI_HEADER_REVISION_1 0x00010000 -/* Defines system type for MBR showing that a GPT is following */ +/* Defines system type for MBR showing that a GPT is following */ #define EFI_PMBR_OSTYPE_EFI 0xEE #define IS_VALID_DISK_INFO(Disk) \ @@ -1057,7 +1057,7 @@ FstubReadPartitionTableEFI(IN PDISK_INFORMATION Disk, } DriveLayoutEx->PartitionCount = PartitionCount; - /* If we updated partition table using backup table, rewrite partition table */ + /* If we updated partition table using backup table, rewrite partition table */ if (UpdatedPartitionTable) { IoWritePartitionTableEx(Disk->DeviceObject, @@ -1777,6 +1777,7 @@ IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation, } /* Prepare for getting disk geometry */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY, DeviceObject, NULL, @@ -1793,7 +1794,6 @@ IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation, } /* Then, call the drive, and wait for it if needed */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { @@ -1886,6 +1886,7 @@ IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation, } /* And call the drive to get information about partition */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX, DeviceObject, NULL, @@ -1903,7 +1904,6 @@ IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation, } /* Call & wait if needed */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { @@ -1957,6 +1957,7 @@ IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation, } /* And call the drive to get information about partition */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX, DeviceObject, NULL, @@ -1974,7 +1975,6 @@ IoGetBootDiskInformation(IN OUT PBOOTDISK_INFORMATION BootDiskInformation, } /* Call & wait if needed */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c index 7a20cab4e0f..eec1d48b34b 100644 --- a/ntoskrnl/se/token.c +++ b/ntoskrnl/se/token.c @@ -657,7 +657,7 @@ SepCreateToken(OUT PHANDLE TokenHandle, */ uLength = sizeof(SID_AND_ATTRIBUTES) * AccessToken->UserAndGroupCount; - uLength += RtlLengthSid(User); + uLength += RtlLengthSid(User->Sid); for (i = 0; i < GroupCount; i++) uLength += RtlLengthSid(Groups[i].Sid); diff --git a/win32ss/CMakeLists.txt b/win32ss/CMakeLists.txt index 30110ddc31c..e0a83217026 100644 --- a/win32ss/CMakeLists.txt +++ b/win32ss/CMakeLists.txt @@ -17,7 +17,6 @@ endif() add_subdirectory(gdi/gdi32) add_subdirectory(reactx) -add_subdirectory(user/consrv) add_subdirectory(user/user32) add_subdirectory(user/winsrv) diff --git a/win32ss/gdi/ntgdi/icm.c b/win32ss/gdi/ntgdi/icm.c index 54aa505382b..d06dfc2b5d1 100644 --- a/win32ss/gdi/ntgdi/icm.c +++ b/win32ss/gdi/ntgdi/icm.c @@ -23,6 +23,8 @@ IntGdiCreateColorSpace( HCOLORSPACE hCS; pCS = COLORSPACEOBJ_AllocCSWithHandle(); + if (pCS == NULL) return NULL; + hCS = pCS->BaseObject.hHmgr; pCS->lcsColorSpace = pLogColorSpace->lcsColorSpace; diff --git a/win32ss/gdi/ntgdi/stockobj.c b/win32ss/gdi/ntgdi/stockobj.c index 8145956e46c..9f286b3fa00 100644 --- a/win32ss/gdi/ntgdi/stockobj.c +++ b/win32ss/gdi/ntgdi/stockobj.c @@ -107,7 +107,10 @@ IntCreateStockPen(DWORD dwPenStyle, ULONG ulColor) { HPEN hPen; - PBRUSH pbrushPen = PEN_AllocPenWithHandle(); + PBRUSH pbrushPen; + + pbrushPen = PEN_AllocPenWithHandle(); + if (pbrushPen == NULL) return NULL; if ((dwPenStyle & PS_STYLE_MASK) == PS_NULL) dwWidth = 1; diff --git a/win32ss/user/consrv/CMakeLists.txt b/win32ss/user/consrv/CMakeLists.txt deleted file mode 100644 index ca5fae6d87b..00000000000 --- a/win32ss/user/consrv/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ - -remove_definitions(-D_WIN32_WINNT=0x502) -add_definitions(-D_WIN32_WINNT=0x600) - -include_directories( - ${REACTOS_SOURCE_DIR}/include/reactos/subsys - ${REACTOS_SOURCE_DIR}/win32ss/include) - -spec2def(consrv.dll consrv.spec) - -list(APPEND SOURCE - alias.c - coninput.c - conoutput.c - graphics.c - text.c - console.c - handle.c - init.c - lineinput.c - settings.c - frontends/gui/guiterm.c - frontends/gui/guisettings.c - frontends/gui/graphics.c - frontends/gui/text.c - frontends/tui/tuiterm.c - ${CMAKE_CURRENT_BINARY_DIR}/consrv.def) - -add_library(consrv SHARED - ${SOURCE} - consrv.rc) - -# -# Explicitely enable MS extensions to be able to use unnamed (anonymous) nested structs. -# -# FIXME: http://www.cmake.org/Bug/view.php?id=12998 -if(MSVC) - ## NOTE: No need to specify it as we use MSVC :) - ##add_target_compile_flags(consrv "/Ze") - #set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/Ze") -else() - #add_target_compile_flags(consrv "-fms-extensions") - set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fms-extensions") -endif() - -target_link_libraries(consrv win32ksys ${PSEH_LIB} uuid) # win32ksys because of NtUser...() - -set_module_type(consrv win32dll UNICODE) - -add_importlibs(consrv psapi msvcrt kernel32 ntdll csrsrv) -add_delay_importlibs(consrv user32 gdi32 advapi32 ole32) - -add_dependencies(consrv bugcodes) -add_cd_file(TARGET consrv DESTINATION reactos/system32 FOR all) diff --git a/win32ss/user/consrv/coninput.c b/win32ss/user/consrv/coninput.c deleted file mode 100644 index fbf552314e1..00000000000 --- a/win32ss/user/consrv/coninput.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/coninput.c - * PURPOSE: Console Input functions - * PROGRAMMERS: Jeffrey Morlan - * Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -/* INCLUDES *******************************************************************/ - -#include "consrv.h" -#include "include/conio.h" -#include "conio.h" -#include "handle.h" -#include "lineinput.h" - -#define NDEBUG -#include - - -/* GLOBALS ********************************************************************/ - -#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ - ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \ - (Access), (LockConsole), INPUT_BUFFER) -#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \ - ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \ - (Access), (LockConsole), INPUT_BUFFER) -#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \ - ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked)) - - -#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ - WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) - -#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ - MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) - -typedef struct ConsoleInput_t -{ - LIST_ENTRY ListEntry; - INPUT_RECORD InputEvent; -} ConsoleInput; - -typedef struct _GET_INPUT_INFO -{ - PCSR_THREAD CallingThread; // The thread which called the input API. - PVOID HandleEntry; // The handle data associated with the wait thread. - PCONSOLE_INPUT_BUFFER InputBuffer; // The input buffer corresponding to the handle. -} GET_INPUT_INFO, *PGET_INPUT_INFO; - - -/* PRIVATE FUNCTIONS **********************************************************/ - -static VOID FASTCALL -ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent) -{ - if (InputEvent->EventType == KEY_EVENT) - { - WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; - InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; - ConsoleInputUnicodeCharToAnsiChar(Console, - &InputEvent->Event.KeyEvent.uChar.AsciiChar, - &UnicodeChar); - } -} - -NTSTATUS FASTCALL -ConioProcessInputEvent(PCONSOLE Console, - PINPUT_RECORD InputEvent) -{ - ConsoleInput *ConInRec; - - /* Check for pause or unpause */ - if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) - { - WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode; - if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) - { - DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState; - if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT && - (vk == VK_PAUSE || (vk == 'S' && - (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && - !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) - { - ConioPause(Console, PAUSED_FROM_KEYBOARD); - return STATUS_SUCCESS; - } - } - else - { - if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && - vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) - { - ConioUnpause(Console, PAUSED_FROM_KEYBOARD); - return STATUS_SUCCESS; - } - } - } - - /* Add event to the queue */ - ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput)); - if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES; - - ConInRec->InputEvent = *InputEvent; - InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry); - - SetEvent(Console->InputBuffer.ActiveEvent); - CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue, - WaitAny, - NULL, - NULL); - if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue)) - { - CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue); - } - - return STATUS_SUCCESS; -} - -VOID FASTCALL -PurgeInputBuffer(PCONSOLE Console) -{ - PLIST_ENTRY CurrentEntry; - ConsoleInput* Event; - - while (!IsListEmpty(&Console->InputBuffer.InputEvents)) - { - CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents); - Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - ConsoleFreeHeap(Event); - } - - CloseHandle(Console->InputBuffer.ActiveEvent); -} - -static DWORD FASTCALL -ConioGetShiftState(PBYTE KeyState, LPARAM lParam) -{ - DWORD ssOut = 0; - - if (KeyState[VK_CAPITAL] & 0x01) - ssOut |= CAPSLOCK_ON; - - if (KeyState[VK_NUMLOCK] & 0x01) - ssOut |= NUMLOCK_ON; - - if (KeyState[VK_SCROLL] & 0x01) - ssOut |= SCROLLLOCK_ON; - - if (KeyState[VK_SHIFT] & 0x80) - ssOut |= SHIFT_PRESSED; - - if (KeyState[VK_LCONTROL] & 0x80) - ssOut |= LEFT_CTRL_PRESSED; - if (KeyState[VK_RCONTROL] & 0x80) - ssOut |= RIGHT_CTRL_PRESSED; - - if (KeyState[VK_LMENU] & 0x80) - ssOut |= LEFT_ALT_PRESSED; - if (KeyState[VK_RMENU] & 0x80) - ssOut |= RIGHT_ALT_PRESSED; - - /* See WM_CHAR MSDN documentation for instance */ - if (lParam & 0x01000000) - ssOut |= ENHANCED_KEY; - - return ssOut; -} - -VOID WINAPI -ConioProcessKey(PCONSOLE Console, MSG* msg) -{ - static BYTE KeyState[256] = { 0 }; - /* MSDN mentions that you should use the last virtual key code received - * when putting a virtual key identity to a WM_CHAR message since multiple - * or translated keys may be involved. */ - static UINT LastVirtualKey = 0; - DWORD ShiftState; - WCHAR UnicodeChar; - UINT VirtualKeyCode; - UINT VirtualScanCode; - BOOL Down = FALSE; - INPUT_RECORD er; - BOOLEAN Fake; // synthesized, not a real event - BOOLEAN NotChar; // message should not be used to return a character - - if (NULL == Console) - { - DPRINT1("No Active Console!\n"); - return; - } - - VirtualScanCode = HIWORD(msg->lParam) & 0xFF; - Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || - msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; - - GetKeyboardState(KeyState); - ShiftState = ConioGetShiftState(KeyState, msg->lParam); - - if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) - { - VirtualKeyCode = LastVirtualKey; - UnicodeChar = msg->wParam; - } - else - { - WCHAR Chars[2]; - INT RetChars = 0; - - VirtualKeyCode = msg->wParam; - RetChars = ToUnicodeEx(VirtualKeyCode, - VirtualScanCode, - KeyState, - Chars, - 2, - 0, - NULL); - UnicodeChar = (1 == RetChars ? Chars[0] : 0); - } - - er.EventType = KEY_EVENT; - er.Event.KeyEvent.bKeyDown = Down; - er.Event.KeyEvent.wRepeatCount = 1; - er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; - er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; - er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; - er.Event.KeyEvent.dwControlKeyState = ShiftState; - - if (ConioProcessKeyCallback(Console, - msg, - KeyState[VK_MENU], - ShiftState, - VirtualKeyCode, - Down)) - { - return; - } - - Fake = UnicodeChar && - (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && - msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); - NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); - if (NotChar) LastVirtualKey = msg->wParam; - - DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n", - Down ? "down" : "up ", - (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? - "char" : "key ", - Fake ? "fake" : "real", - NotChar ? "notc" : "char", - VirtualScanCode, - VirtualKeyCode, - (UnicodeChar >= L' ') ? UnicodeChar : L'.', - ShiftState); - - if (Fake) return; - - /* process Ctrl-C and Ctrl-Break */ - if (Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && - er.Event.KeyEvent.bKeyDown && - ((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) || - (er.Event.KeyEvent.wVirtualKeyCode == 'C')) && - (er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80)) - { - DPRINT1("Console_Api Ctrl-C\n"); - ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT); - - if (Console->LineBuffer && !Console->LineComplete) - { - /* Line input is in progress; end it */ - Console->LinePos = Console->LineSize = 0; - Console->LineComplete = TRUE; - } - return; - } - - if (0 != (er.Event.KeyEvent.dwControlKeyState - & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) - && (VK_UP == er.Event.KeyEvent.wVirtualKeyCode - || VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode)) - { - if (er.Event.KeyEvent.bKeyDown) - { - /* scroll up or down */ - if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode) - { - /* only scroll up if there is room to scroll up into */ - if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + - Console->ActiveBuffer->ScreenBufferSize.Y - 1) % - Console->ActiveBuffer->ScreenBufferSize.Y; - Console->ActiveBuffer->CursorPosition.Y++; - } - } - else - { - /* only scroll down if there is room to scroll down into */ - if (Console->ActiveBuffer->CursorPosition.Y != 0) - { - Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % - Console->ActiveBuffer->ScreenBufferSize.Y; - Console->ActiveBuffer->CursorPosition.Y--; - } - } - ConioDrawConsole(Console); - } - return; - } - ConioProcessInputEvent(Console, &er); -} - -static NTSTATUS -WaitBeforeReading(IN PGET_INPUT_INFO InputInfo, - IN PCSR_API_MESSAGE ApiMessage, - IN CSR_WAIT_FUNCTION WaitFunction OPTIONAL, - IN BOOL CreateWaitBlock OPTIONAL) -{ - if (CreateWaitBlock) - { - PGET_INPUT_INFO CapturedInputInfo; - - CapturedInputInfo = ConsoleAllocHeap(0, sizeof(GET_INPUT_INFO)); - if (!CapturedInputInfo) return STATUS_NO_MEMORY; - - RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO)); - - if (!CsrCreateWait(&InputInfo->InputBuffer->ReadWaitQueue, - WaitFunction, - InputInfo->CallingThread, - ApiMessage, - CapturedInputInfo, - NULL)) - { - ConsoleFreeHeap(CapturedInputInfo); - return STATUS_NO_MEMORY; - } - } - - /* Wait for input */ - return STATUS_PENDING; -} - -static NTSTATUS -ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, - IN BOOL Wait, - IN PCSR_API_MESSAGE ApiMessage, - IN BOOL CreateWaitBlock OPTIONAL); - -// Wait function CSR_WAIT_FUNCTION -static BOOLEAN -ReadInputBufferThread(IN PLIST_ENTRY WaitList, - IN PCSR_THREAD WaitThread, - IN PCSR_API_MESSAGE WaitApiMessage, - IN PVOID WaitContext, - IN PVOID WaitArgument1, - IN PVOID WaitArgument2, - IN ULONG WaitFlags) -{ - NTSTATUS Status; - PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)WaitApiMessage)->Data.GetInputRequest; - PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext; - - PVOID InputHandle = WaitArgument2; - - DPRINT("ReadInputBufferThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); - - /* - * If we are notified of the process termination via a call - * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or - * CsrDestroyThread, just return. - */ - if (WaitFlags & CsrProcessTerminating) - { - Status = STATUS_THREAD_IS_TERMINATING; - goto Quit; - } - - /* - * Somebody is closing a handle to this input buffer, - * by calling ConSrvCloseHandleEntry. - * See whether we are linked to that handle (ie. we - * are a waiter for this handle), and if so, return. - * Otherwise, ignore the call and continue waiting. - */ - if (InputHandle != NULL) - { - Status = (InputHandle == InputInfo->HandleEntry ? STATUS_ALERTED - : STATUS_PENDING); - goto Quit; - } - - /* - * If we go there, that means we are notified for some new input. - * The console is therefore already locked. - */ - Status = ReadInputBuffer(InputInfo, - GetInputRequest->bRead, - WaitApiMessage, - FALSE); - -Quit: - if (Status != STATUS_PENDING) - { - WaitApiMessage->Status = Status; - ConsoleFreeHeap(InputInfo); - } - - return (Status == STATUS_PENDING ? FALSE : TRUE); -} - -static NTSTATUS -ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, - IN BOOL Wait, // TRUE --> Read ; FALSE --> Peek - IN PCSR_API_MESSAGE ApiMessage, - IN BOOL CreateWaitBlock OPTIONAL) -{ - PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; - - if (IsListEmpty(&InputBuffer->InputEvents)) - { - if (Wait) - { - return WaitBeforeReading(InputInfo, - ApiMessage, - ReadInputBufferThread, - CreateWaitBlock); - } - else - { - /* No input available and we don't wait, so we return success */ - return STATUS_SUCCESS; - } - } - else - { - PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; - PLIST_ENTRY CurrentInput; - ConsoleInput* Input; - ULONG Length = GetInputRequest->Length; - PINPUT_RECORD InputRecord = GetInputRequest->InputRecord; - - /* Only get input if there is any */ - CurrentInput = InputBuffer->InputEvents.Flink; - - while ( CurrentInput != &InputBuffer->InputEvents && - GetInputRequest->InputsRead < Length ) - { - Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry); - - GetInputRequest->InputsRead++; - *InputRecord = Input->InputEvent; - - if (GetInputRequest->Unicode == FALSE) - { - ConioInputEventToAnsi(InputBuffer->Header.Console, InputRecord); - } - - InputRecord++; - CurrentInput = CurrentInput->Flink; - - if (Wait) // TRUE --> Read, we remove inputs from the buffer ; FALSE --> Peek, we keep inputs. - { - RemoveEntryList(&Input->ListEntry); - ConsoleFreeHeap(Input); - } - } - - if (IsListEmpty(&InputBuffer->InputEvents)) - { - ResetEvent(InputBuffer->ActiveEvent); - } - - /* We read all the inputs available, we return success */ - return STATUS_SUCCESS; - } -} - -static NTSTATUS -ReadChars(IN PGET_INPUT_INFO InputInfo, - IN PCSR_API_MESSAGE ApiMessage, - IN BOOL CreateWaitBlock OPTIONAL); - -// Wait function CSR_WAIT_FUNCTION -static BOOLEAN -ReadCharsThread(IN PLIST_ENTRY WaitList, - IN PCSR_THREAD WaitThread, - IN PCSR_API_MESSAGE WaitApiMessage, - IN PVOID WaitContext, - IN PVOID WaitArgument1, - IN PVOID WaitArgument2, - IN ULONG WaitFlags) -{ - NTSTATUS Status; - PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext; - - PVOID InputHandle = WaitArgument2; - - DPRINT("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); - - /* - * If we are notified of the process termination via a call - * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or - * CsrDestroyThread, just return. - */ - if (WaitFlags & CsrProcessTerminating) - { - Status = STATUS_THREAD_IS_TERMINATING; - goto Quit; - } - - /* - * Somebody is closing a handle to this input buffer, - * by calling ConSrvCloseHandleEntry. - * See whether we are linked to that handle (ie. we - * are a waiter for this handle), and if so, return. - * Otherwise, ignore the call and continue waiting. - */ - if (InputHandle != NULL) - { - Status = (InputHandle == InputInfo->HandleEntry ? STATUS_ALERTED - : STATUS_PENDING); - goto Quit; - } - - /* - * If we go there, that means we are notified for some new input. - * The console is therefore already locked. - */ - Status = ReadChars(InputInfo, - WaitApiMessage, - FALSE); - -Quit: - if (Status != STATUS_PENDING) - { - WaitApiMessage->Status = Status; - ConsoleFreeHeap(InputInfo); - } - - return (Status == STATUS_PENDING ? FALSE : TRUE); -} - -static NTSTATUS -ReadChars(IN PGET_INPUT_INFO InputInfo, - IN PCSR_API_MESSAGE ApiMessage, - IN BOOL CreateWaitBlock OPTIONAL) -{ - BOOL WaitForMoreToRead = TRUE; // TRUE : Wait if more to read ; FALSE : Don't wait. - - PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; - PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; - PCONSOLE Console = InputBuffer->Header.Console; - PLIST_ENTRY CurrentEntry; - ConsoleInput *Input; - PCHAR Buffer = (PCHAR)ReadConsoleRequest->Buffer; - PWCHAR UnicodeBuffer = (PWCHAR)Buffer; - ULONG nNumberOfCharsToRead = ReadConsoleRequest->NrCharactersToRead; - - /* We haven't read anything (yet) */ - - if (InputBuffer->Mode & ENABLE_LINE_INPUT) - { - if (Console->LineBuffer == NULL) - { - /* Starting a new line */ - Console->LineMaxSize = (WORD)max(256, nNumberOfCharsToRead); - Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR)); - if (Console->LineBuffer == NULL) - { - return STATUS_NO_MEMORY; - } - Console->LineComplete = FALSE; - Console->LineUpPressed = FALSE; - Console->LineInsertToggle = 0; - Console->LineWakeupMask = ReadConsoleRequest->CtrlWakeupMask; - Console->LineSize = ReadConsoleRequest->NrCharactersRead; - Console->LinePos = Console->LineSize; - - /* - * Pre-filling the buffer is only allowed in the Unicode API, - * so we don't need to worry about ANSI <-> Unicode conversion. - */ - memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR)); - if (Console->LineSize == Console->LineMaxSize) - { - Console->LineComplete = TRUE; - Console->LinePos = 0; - } - } - - /* If we don't have a complete line yet, process the pending input */ - while ( !Console->LineComplete && - !IsListEmpty(&InputBuffer->InputEvents) ) - { - /* Remove input event from queue */ - CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); - if (IsListEmpty(&InputBuffer->InputEvents)) - { - ResetEvent(InputBuffer->ActiveEvent); - } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - - /* Only pay attention to key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown) - { - LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); - ReadConsoleRequest->ControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState; - } - ConsoleFreeHeap(Input); - } - - /* Check if we have a complete line to read from */ - if (Console->LineComplete) - { - while ( ReadConsoleRequest->NrCharactersRead < nNumberOfCharsToRead && - Console->LinePos != Console->LineSize ) - { - WCHAR Char = Console->LineBuffer[Console->LinePos++]; - - if (ReadConsoleRequest->Unicode) - { - UnicodeBuffer[ReadConsoleRequest->NrCharactersRead] = Char; - } - else - { - ConsoleInputUnicodeCharToAnsiChar(Console, - &Buffer[ReadConsoleRequest->NrCharactersRead], - &Char); - } - - ReadConsoleRequest->NrCharactersRead++; - } - - if (Console->LinePos == Console->LineSize) - { - /* Entire line has been read */ - ConsoleFreeHeap(Console->LineBuffer); - Console->LineBuffer = NULL; - } - - WaitForMoreToRead = FALSE; - } - } - else - { - /* Character input */ - while ( ReadConsoleRequest->NrCharactersRead < nNumberOfCharsToRead && - !IsListEmpty(&InputBuffer->InputEvents) ) - { - /* Remove input event from queue */ - CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); - if (IsListEmpty(&InputBuffer->InputEvents)) - { - ResetEvent(InputBuffer->ActiveEvent); - } - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - - /* Only pay attention to valid ascii chars, on key down */ - if (KEY_EVENT == Input->InputEvent.EventType - && Input->InputEvent.Event.KeyEvent.bKeyDown - && Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') - { - WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; - - if (ReadConsoleRequest->Unicode) - { - UnicodeBuffer[ReadConsoleRequest->NrCharactersRead] = Char; - } - else - { - ConsoleInputUnicodeCharToAnsiChar(Console, - &Buffer[ReadConsoleRequest->NrCharactersRead], - &Char); - } - - ReadConsoleRequest->NrCharactersRead++; - - /* Did read something */ - WaitForMoreToRead = FALSE; - } - ConsoleFreeHeap(Input); - } - } - - /* We haven't completed a read, so start a wait */ - if (WaitForMoreToRead == TRUE) - { - return WaitBeforeReading(InputInfo, - ApiMessage, - ReadCharsThread, - CreateWaitBlock); - } - else /* We read all what we wanted, we return success */ - { - return STATUS_SUCCESS; - } -} - - -/* PUBLIC SERVER APIS *********************************************************/ - -CSR_API(SrvReadConsole) -{ - NTSTATUS Status; - PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PVOID HandleEntry; - PCONSOLE_INPUT_BUFFER InputBuffer; - GET_INPUT_INFO InputInfo; - - DPRINT("SrvReadConsole\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&ReadConsoleRequest->Buffer, - ReadConsoleRequest->BufferSize, - sizeof(BYTE))) - { - return STATUS_INVALID_PARAMETER; - } - - if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, ReadConsoleRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - ReadConsoleRequest->NrCharactersRead = 0; - - InputInfo.CallingThread = CsrGetClientThread(); - InputInfo.HandleEntry = HandleEntry; - InputInfo.InputBuffer = InputBuffer; - - Status = ReadChars(&InputInfo, - ApiMessage, - TRUE); - - ConSrvReleaseInputBuffer(InputBuffer, TRUE); - - if (Status == STATUS_PENDING) - *ReplyCode = CsrReplyPending; - - return Status; -} - -CSR_API(SrvGetConsoleInput) -{ - NTSTATUS Status; - PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PVOID HandleEntry; - PCONSOLE_INPUT_BUFFER InputBuffer; - GET_INPUT_INFO InputInfo; - - DPRINT("SrvGetConsoleInput\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&GetInputRequest->InputRecord, - GetInputRequest->Length, - sizeof(INPUT_RECORD))) - { - return STATUS_INVALID_PARAMETER; - } - - GetInputRequest->InputsRead = 0; - - Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - InputInfo.CallingThread = CsrGetClientThread(); - InputInfo.HandleEntry = HandleEntry; - InputInfo.InputBuffer = InputBuffer; - - Status = ReadInputBuffer(&InputInfo, - GetInputRequest->bRead, - ApiMessage, - TRUE); - - ConSrvReleaseInputBuffer(InputBuffer, TRUE); - - if (Status == STATUS_PENDING) - *ReplyCode = CsrReplyPending; - - return Status; -} - -CSR_API(SrvWriteConsoleInput) -{ - NTSTATUS Status; - PCONSOLE_WRITEINPUT WriteInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteInputRequest; - PINPUT_RECORD InputRecord; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PCONSOLE_INPUT_BUFFER InputBuffer; - PCONSOLE Console; - DWORD Length; - DWORD i; - - DPRINT("SrvWriteConsoleInput\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&WriteInputRequest->InputRecord, - WriteInputRequest->Length, - sizeof(INPUT_RECORD))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetInputBuffer(ProcessData, WriteInputRequest->InputHandle, &InputBuffer, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = InputBuffer->Header.Console; - InputRecord = WriteInputRequest->InputRecord; - Length = WriteInputRequest->Length; - - for (i = 0; i < Length && NT_SUCCESS(Status); i++) - { - if (!WriteInputRequest->Unicode && - InputRecord->EventType == KEY_EVENT) - { - CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; - ConsoleInputAnsiCharToUnicodeChar(Console, - &InputRecord->Event.KeyEvent.uChar.UnicodeChar, - &AsciiChar); - } - - Status = ConioProcessInputEvent(Console, InputRecord++); - } - - ConSrvReleaseInputBuffer(InputBuffer, TRUE); - - WriteInputRequest->Length = i; - - return Status; -} - -CSR_API(SrvFlushConsoleInputBuffer) -{ - NTSTATUS Status; - PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest; - PLIST_ENTRY CurrentEntry; - PCONSOLE_INPUT_BUFFER InputBuffer; - ConsoleInput* Event; - - DPRINT("SrvFlushConsoleInputBuffer\n"); - - Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - FlushInputBufferRequest->InputHandle, - &InputBuffer, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - /* Discard all entries in the input event queue */ - while (!IsListEmpty(&InputBuffer->InputEvents)) - { - CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); - Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - ConsoleFreeHeap(Event); - } - ResetEvent(InputBuffer->ActiveEvent); - - ConSrvReleaseInputBuffer(InputBuffer, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvGetConsoleNumberOfInputEvents) -{ - NTSTATUS Status; - PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumInputEventsRequest; - PCONSOLE_INPUT_BUFFER InputBuffer; - PLIST_ENTRY CurrentInput; - DWORD NumEvents; - - DPRINT("SrvGetConsoleNumberOfInputEvents\n"); - - Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), GetNumInputEventsRequest->InputHandle, &InputBuffer, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - CurrentInput = InputBuffer->InputEvents.Flink; - /* GetNumInputEventsRequest->NumInputEvents = */ NumEvents = 0; - - /* If there are any events ... */ - while (CurrentInput != &InputBuffer->InputEvents) - { - CurrentInput = CurrentInput->Flink; - NumEvents++; - } - - ConSrvReleaseInputBuffer(InputBuffer, TRUE); - - GetNumInputEventsRequest->NumInputEvents = NumEvents; - - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/win32ss/user/consrv/coninput.h b/win32ss/user/consrv/coninput.h deleted file mode 100644 index 4f3efbac369..00000000000 --- a/win32ss/user/consrv/coninput.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/coninput.h - * PURPOSE: Console Input functions - * PROGRAMMERS: Jeffrey Morlan - * Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -#pragma once - -VOID FASTCALL PurgeInputBuffer(PCONSOLE Console); - -/* EOF */ diff --git a/win32ss/user/consrv/conio.h b/win32ss/user/consrv/conio.h deleted file mode 100644 index da698a1c3ed..00000000000 --- a/win32ss/user/consrv/conio.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/conio.h - * PURPOSE: Internal Console I/O Interface - * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -#pragma once - -/* Macros used to call functions in the FRONTEND_VTBL virtual table */ - -#define ConioCleanupConsole(Console) \ - (Console)->TermIFace.Vtbl->CleanupConsole(Console) -#define ConioDrawRegion(Console, Region) \ - (Console)->TermIFace.Vtbl->DrawRegion((Console), (Region)) -#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \ - (Console)->TermIFace.Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \ - (ScrolledLines), (Buffer), (Length)) -#define ConioSetCursorInfo(Console, Buff) \ - (Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff)) -#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \ - (Console)->TermIFace.Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY)) -#define ConioResizeTerminal(Console) \ - (Console)->TermIFace.Vtbl->ResizeTerminal(Console) -#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \ - (Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down)) -#define ConioRefreshInternalInfo(Console) \ - (Console)->TermIFace.Vtbl->RefreshInternalInfo(Console) - -#define ConioChangeTitle(Console) \ - (Console)->TermIFace.Vtbl->ChangeTitle(Console) -#define ConioChangeIcon(Console, hWindowIcon) \ - (Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon)) -#define ConioGetConsoleWindowHandle(Console) \ - (Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console) -#define ConioGetLargestConsoleWindowSize(Console, pSize) \ - (Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize)) -#define ConioGetDisplayMode(Console) \ - (Console)->TermIFace.Vtbl->GetDisplayMode(Console) -#define ConioSetDisplayMode(Console, NewMode) \ - (Console)->TermIFace.Vtbl->SetDisplayMode((Console), (NewMode)) -#define ConioShowMouseCursor(Console, Show) \ - (Console)->TermIFace.Vtbl->ShowMouseCursor((Console), (Show)) -#define ConioSetMouseCursor(Console, hCursor) \ - (Console)->TermIFace.Vtbl->SetMouseCursor((Console), (hCursor)) -#define ConioMenuControl(Console, CmdIdLow, CmdIdHigh) \ - (Console)->TermIFace.Vtbl->MenuControl((Console), (CmdIdLow), (CmdIdHigh)) -#define ConioSetMenuClose(Console, Enable) \ - (Console)->TermIFace.Vtbl->SetMenuClose((Console), (Enable)) - -/* EOF */ diff --git a/win32ss/user/consrv/conoutput.c b/win32ss/user/consrv/conoutput.c deleted file mode 100644 index d74f76dee06..00000000000 --- a/win32ss/user/consrv/conoutput.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/conoutput.c - * PURPOSE: General Console Output Functions - * PROGRAMMERS: Jeffrey Morlan - * Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -/* INCLUDES *******************************************************************/ - -#include "consrv.h" -#include "console.h" -#include "include/conio.h" -#include "conio.h" -#include "conoutput.h" -#include "handle.h" - -#define NDEBUG -#include - - -/* PRIVATE FUNCTIONS **********************************************************/ - -NTSTATUS -TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, - IN OUT PCONSOLE Console, - IN PTEXTMODE_BUFFER_INFO TextModeInfo); -NTSTATUS -GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, - IN OUT PCONSOLE Console, - IN PGRAPHICS_BUFFER_INFO GraphicsInfo); - -VOID -TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer); -VOID -GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer); - - -NTSTATUS -CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, - IN OUT PCONSOLE Console, - IN SIZE_T Size) -{ - if (Buffer == NULL || Console == NULL) - return STATUS_INVALID_PARAMETER; - - *Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, max(sizeof(CONSOLE_SCREEN_BUFFER), Size)); - if (*Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES; - - /* Initialize the header with the default type */ - ConSrvInitObject(&(*Buffer)->Header, SCREEN_BUFFER, Console); - (*Buffer)->Vtbl = NULL; - return STATUS_SUCCESS; -} - -VOID -CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer) -{ - if (Buffer->Header.Type == TEXTMODE_BUFFER) - TEXTMODE_BUFFER_Destroy(Buffer); - else if (Buffer->Header.Type == GRAPHICS_BUFFER) - GRAPHICS_BUFFER_Destroy(Buffer); - else if (Buffer->Header.Type == SCREEN_BUFFER) - ConsoleFreeHeap(Buffer); - // else - // do_nothing; -} - -NTSTATUS FASTCALL -ConSrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer, - IN OUT PCONSOLE Console, - IN ULONG BufferType, - IN PVOID ScreenBufferInfo) -{ - NTSTATUS Status = STATUS_SUCCESS; - - if ( Console == NULL || Buffer == NULL || - (BufferType != CONSOLE_TEXTMODE_BUFFER && BufferType != CONSOLE_GRAPHICS_BUFFER) ) - { - return STATUS_INVALID_PARAMETER; - } - - if (BufferType == CONSOLE_TEXTMODE_BUFFER) - { - Status = TEXTMODE_BUFFER_Initialize(Buffer, - Console, - (PTEXTMODE_BUFFER_INFO)ScreenBufferInfo); - } - else if (BufferType == CONSOLE_GRAPHICS_BUFFER) - { - Status = GRAPHICS_BUFFER_Initialize(Buffer, - Console, - (PGRAPHICS_BUFFER_INFO)ScreenBufferInfo); - } - else - { - /* Never ever go there!! */ - ASSERT(FALSE); - } - - /* Insert the newly created screen buffer into the list, if succeeded */ - if (NT_SUCCESS(Status)) InsertHeadList(&Console->BufferList, &(*Buffer)->ListEntry); - - return Status; -} - -VOID WINAPI -ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer) -{ - PCONSOLE Console = Buffer->Header.Console; - PCONSOLE_SCREEN_BUFFER NewBuffer; - - RemoveEntryList(&Buffer->ListEntry); - if (Buffer == Console->ActiveBuffer) - { - /* Delete active buffer; switch to most recently created */ - Console->ActiveBuffer = NULL; - if (!IsListEmpty(&Console->BufferList)) - { - NewBuffer = CONTAINING_RECORD(Console->BufferList.Flink, - CONSOLE_SCREEN_BUFFER, - ListEntry); - ConioSetActiveScreenBuffer(NewBuffer); - } - } - - CONSOLE_SCREEN_BUFFER_Destroy(Buffer); -} - -VOID FASTCALL -ConioDrawConsole(PCONSOLE Console) -{ - SMALL_RECT Region; - PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; - - if (ActiveBuffer) - { - ConioInitRect(&Region, 0, 0, ActiveBuffer->ViewSize.Y - 1, ActiveBuffer->ViewSize.X - 1); - ConioDrawRegion(Console, &Region); - } -} - -VOID FASTCALL -ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer) -{ - PCONSOLE Console = Buffer->Header.Console; - Console->ActiveBuffer = Buffer; - ConioResizeTerminal(Console); - // ConioDrawConsole(Console); -} - - -/* PUBLIC SERVER APIS *********************************************************/ - -CSR_API(SrvInvalidateBitMapRect) -{ - NTSTATUS Status; - PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.InvalidateDIBitsRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - DPRINT("SrvInvalidateBitMapRect\n"); - - Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), InvalidateDIBitsRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - /* If the output buffer is the current one, redraw the correct portion of the screen */ - if (Buff == Console->ActiveBuffer) - ConioDrawRegion(Console, &InvalidateDIBitsRequest->Region); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvGetConsoleCursorInfo) -{ - NTSTATUS Status; - PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest; - PCONSOLE_SCREEN_BUFFER Buff; - - DPRINT("SrvGetConsoleCursorInfo\n"); - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), CursorInfoRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - CursorInfoRequest->Info.bVisible = Buff->CursorInfo.bVisible; - CursorInfoRequest->Info.dwSize = Buff->CursorInfo.dwSize; - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleCursorInfo) -{ - NTSTATUS Status; - PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - DWORD Size; - BOOL Visible, Success = TRUE; - - DPRINT("SrvSetConsoleCursorInfo\n"); - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), CursorInfoRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - Size = CursorInfoRequest->Info.dwSize; - Visible = CursorInfoRequest->Info.bVisible; - if (Size < 1) Size = 1; - if (100 < Size) Size = 100; - - if ( (Size != Buff->CursorInfo.dwSize) || - (Visible && !Buff->CursorInfo.bVisible) || - (!Visible && Buff->CursorInfo.bVisible) ) - { - Buff->CursorInfo.dwSize = Size; - Buff->CursorInfo.bVisible = Visible; - - Success = ConioSetCursorInfo(Console, Buff); - } - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); -} - -CSR_API(SrvSetConsoleCursorPosition) -{ - NTSTATUS Status = STATUS_SUCCESS; - PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorPositionRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - SHORT OldCursorX, OldCursorY; - SHORT NewCursorX, NewCursorY; - - DPRINT("SrvSetConsoleCursorPosition\n"); - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetCursorPositionRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - NewCursorX = SetCursorPositionRequest->Position.X; - NewCursorY = SetCursorPositionRequest->Position.Y; - if ( NewCursorX < 0 || NewCursorX >= Buff->ScreenBufferSize.X || - NewCursorY < 0 || NewCursorY >= Buff->ScreenBufferSize.Y ) - { - Status = STATUS_INVALID_PARAMETER; - goto Quit; - } - OldCursorX = Buff->CursorPosition.X; - OldCursorY = Buff->CursorPosition.Y; - Buff->CursorPosition.X = NewCursorX; - Buff->CursorPosition.Y = NewCursorY; - if (Buff == Console->ActiveBuffer) - { - if (!ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY)) - { - Status = STATUS_UNSUCCESSFUL; - goto Quit; - } - } - -Quit: - ConSrvReleaseScreenBuffer(Buff, TRUE); - return Status; -} - -CSR_API(SrvCreateConsoleScreenBuffer) -{ - NTSTATUS Status = STATUS_INVALID_PARAMETER; - PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CreateScreenBufferRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - PVOID ScreenBufferInfo = NULL; - TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25}, - DEFAULT_SCREEN_ATTRIB, - DEFAULT_POPUP_ATTRIB , - TRUE, - CSR_DEFAULT_CURSOR_SIZE}; - GRAPHICS_BUFFER_INFO GraphicsInfo; - GraphicsInfo.Info = CreateScreenBufferRequest->GraphicsBufferInfo; // HACK for MSVC - - DPRINT("SrvCreateConsoleScreenBuffer\n"); - - Status = ConSrvGetConsole(ProcessData, &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_TEXTMODE_BUFFER) - { - ScreenBufferInfo = &TextModeInfo; - - /* - if (Console->ActiveBuffer) - { - TextModeInfo.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize; - if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 80; - if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 25; - - TextModeInfo.ScreenAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.ScreenDefaultAttrib; - TextModeInfo.PopupAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.PopupDefaultAttrib; - - TextModeInfo.IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible; - TextModeInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; - } - */ - - /* - * This is Windows' behaviour - */ - - /* Use the current console size. Regularize it if needed. */ - TextModeInfo.ScreenBufferSize = Console->ConsoleSize; - if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1; - if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1; - - /* If we have an active screen buffer, use its attributes as the new ones */ - if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) - { - PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer; - - TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib; - TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib; - - TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible; - TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize; - } - } - else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER) - { - /* Get infos from the graphics buffer information structure */ - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo, - 1, - CreateScreenBufferRequest->GraphicsBufferInfo.dwBitMapInfoLength)) - { - Status = STATUS_INVALID_PARAMETER; - goto Quit; - } - - ScreenBufferInfo = &GraphicsInfo; - - /* Initialize shared variables */ - CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = GraphicsInfo.Info.hMutex = INVALID_HANDLE_VALUE; - CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = GraphicsInfo.Info.lpBitMap = NULL; - - /* A graphics screen buffer is never inheritable */ - CreateScreenBufferRequest->Inheritable = FALSE; - } - - Status = ConSrvCreateScreenBuffer(&Buff, - Console, - CreateScreenBufferRequest->ScreenBufferType, - ScreenBufferInfo); - if (!NT_SUCCESS(Status)) goto Quit; - - /* Insert the new handle inside the process handles table */ - RtlEnterCriticalSection(&ProcessData->HandleTableLock); - - Status = ConSrvInsertObject(ProcessData, - &CreateScreenBufferRequest->OutputHandle, - &Buff->Header, - CreateScreenBufferRequest->Access, - CreateScreenBufferRequest->Inheritable, - CreateScreenBufferRequest->ShareMode); - - RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - - if (!NT_SUCCESS(Status)) goto Quit; - - if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER) - { - PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)Buff; - /* - * Initialize the graphics buffer information structure - * and give it back to the client. - */ - CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = Buffer->ClientMutex; - CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = Buffer->ClientBitMap; - } - -Quit: - ConSrvReleaseConsole(Console, TRUE); - return Status; -} - -CSR_API(SrvSetConsoleActiveScreenBuffer) -{ - NTSTATUS Status; - PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - DPRINT("SrvSetConsoleActiveScreenBuffer\n"); - - Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetScreenBufferRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - if (Buff == Console->ActiveBuffer) goto Quit; - - /* If old buffer has no handles, it's now unreferenced */ - if (Console->ActiveBuffer->Header.HandleCount == 0) - { - ConioDeleteScreenBuffer(Console->ActiveBuffer); - } - - /* Tie console to new buffer */ - ConioSetActiveScreenBuffer(Buff); - -Quit: - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -/* EOF */ diff --git a/win32ss/user/consrv/console.c b/win32ss/user/consrv/console.c deleted file mode 100644 index deed524978a..00000000000 --- a/win32ss/user/consrv/console.c +++ /dev/null @@ -1,1692 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/console.c - * PURPOSE: Console Management Functions - * PROGRAMMERS: G van Geldorp - * Jeffrey Morlan - * Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -/* INCLUDES *******************************************************************/ - -#define COBJMACROS -#define NONAMELESSUNION - -#include "consrv.h" -#include "include/conio.h" -#include "conio.h" -#include "handle.h" -#include "procinit.h" -#include "alias.h" -#include "coninput.h" -#include "conoutput.h" -#include "lineinput.h" -#include "include/settings.h" - -#include "frontends/gui/guiterm.h" -#include "frontends/tui/tuiterm.h" - -#include "include/console.h" -#include "console.h" -#include "resource.h" - -#include -#include - -#define NDEBUG -#include - -/* GLOBALS ********************************************************************/ - -static LIST_ENTRY ConsoleList; /* The list of all the allocated consoles */ -static RTL_RESOURCE ListLock; - -#define ConSrvLockConsoleListExclusive() \ - RtlAcquireResourceExclusive(&ListLock, TRUE) - -#define ConSrvLockConsoleListShared() \ - RtlAcquireResourceShared(&ListLock, TRUE) - -#define ConSrvUnlockConsoleList() \ - RtlReleaseResource(&ListLock) - -// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180 -BOOLEAN -ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest, - IN PCWSTR Source) -{ - SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR); - if (Size > MAXUSHORT) return FALSE; - - UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size); - if (UniDest->Buffer == NULL) return FALSE; - - RtlCopyMemory(UniDest->Buffer, Source, Size); - UniDest->MaximumLength = (USHORT)Size; - UniDest->Length = (USHORT)Size - sizeof(WCHAR); - - return TRUE; -} - -// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431 -VOID -ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString) -{ - if (UnicodeString->Buffer) - { - ConsoleFreeHeap(UnicodeString->Buffer); - RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING)); - } -} - - -/* PRIVATE FUNCTIONS **********************************************************/ - -static BOOL -DtbgIsDesktopVisible(VOID) -{ - return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE)); -} - -static ULONG -ConSrvConsoleCtrlEventTimeout(DWORD Event, - PCONSOLE_PROCESS_DATA ProcessData, - DWORD Timeout) -{ - ULONG Status = ERROR_SUCCESS; - - DPRINT("ConSrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess); - - if (ProcessData->CtrlDispatcher) - { - _SEH2_TRY - { - HANDLE Thread = NULL; - - _SEH2_TRY - { - Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0, - ProcessData->CtrlDispatcher, - UlongToPtr(Event), 0, NULL); - if (NULL == Thread) - { - Status = GetLastError(); - DPRINT1("Failed thread creation (Error: 0x%x)\n", Status); - } - else - { - DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process); - WaitForSingleObject(Thread, Timeout); - } - } - _SEH2_FINALLY - { - CloseHandle(Thread); - } - _SEH2_END; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = RtlNtStatusToDosError(_SEH2_GetExceptionCode()); - DPRINT1("ConSrvConsoleCtrlEventTimeout - Caught an exception, Status = %08X\n", Status); - } - _SEH2_END; - } - - return Status; -} - -static ULONG -ConSrvConsoleCtrlEvent(DWORD Event, - PCONSOLE_PROCESS_DATA ProcessData) -{ - return ConSrvConsoleCtrlEventTimeout(Event, ProcessData, 0); -} - -ULONG FASTCALL -ConSrvConsoleProcessCtrlEvent(PCONSOLE Console, - ULONG ProcessGroupId, - DWORD Event) -{ - ULONG Status = ERROR_SUCCESS; - PLIST_ENTRY current_entry; - PCONSOLE_PROCESS_DATA current; - - /* If the console is already being destroyed, just return */ - if (!ConSrvValidateConsole(Console, CONSOLE_RUNNING, FALSE)) - return STATUS_UNSUCCESSFUL; - - /* - * Loop through the process list, from the most recent process - * (the active one) to the oldest one (the first created, i.e. - * the console leader process), and for each, send an event - * (new processes are inserted at the head of the console process list). - */ - current_entry = Console->ProcessList.Flink; - while (current_entry != &Console->ProcessList) - { - current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink); - current_entry = current_entry->Flink; - - /* - * Only processes belonging to the same process group are signaled. - * If the process group ID is zero, then all the processes are signaled. - */ - if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId) - { - Status = ConSrvConsoleCtrlEvent(Event, current); - } - } - - return Status; -} - -VOID FASTCALL -ConioPause(PCONSOLE Console, UINT Flags) -{ - Console->PauseFlags |= Flags; - if (!Console->UnpauseEvent) - Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); -} - -VOID FASTCALL -ConioUnpause(PCONSOLE Console, UINT Flags) -{ - Console->PauseFlags &= ~Flags; - - // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0) - if (Console->PauseFlags == 0 && Console->UnpauseEvent) - { - SetEvent(Console->UnpauseEvent); - CloseHandle(Console->UnpauseEvent); - Console->UnpauseEvent = NULL; - - CsrNotifyWait(&Console->WriteWaitQueue, - WaitAll, - NULL, - NULL); - if (!IsListEmpty(&Console->WriteWaitQueue)) - { - CsrDereferenceWait(&Console->WriteWaitQueue); - } - } -} - -BOOL FASTCALL -ConSrvValidateConsolePointer(PCONSOLE Console) -{ - PLIST_ENTRY ConsoleEntry; - PCONSOLE CurrentConsole = NULL; - - if (!Console) return FALSE; - - /* The console list must be locked */ - // ASSERT(Console_list_locked); - - ConsoleEntry = ConsoleList.Flink; - while (ConsoleEntry != &ConsoleList) - { - CurrentConsole = CONTAINING_RECORD(ConsoleEntry, CONSOLE, Entry); - ConsoleEntry = ConsoleEntry->Flink; - if (CurrentConsole == Console) return TRUE; - } - - return FALSE; -} - -BOOL FASTCALL -ConSrvValidateConsoleState(PCONSOLE Console, - CONSOLE_STATE ExpectedState) -{ - // if (!Console) return FALSE; - - /* The console must be locked */ - // ASSERT(Console_locked); - - return (Console->State == ExpectedState); -} - -BOOL FASTCALL -ConSrvValidateConsoleUnsafe(PCONSOLE Console, - CONSOLE_STATE ExpectedState, - BOOL LockConsole) -{ - if (!Console) return FALSE; - - /* - * Lock the console to forbid possible console's state changes - * (which must be done when the console is already locked). - * If we don't want to lock it, it's because the lock is already - * held. So there must be no problems. - */ - if (LockConsole) EnterCriticalSection(&Console->Lock); - - // ASSERT(Console_locked); - - /* Check whether the console's state is what we expect */ - if (!ConSrvValidateConsoleState(Console, ExpectedState)) - { - if (LockConsole) LeaveCriticalSection(&Console->Lock); - return FALSE; - } - - return TRUE; -} - -BOOL FASTCALL -ConSrvValidateConsole(PCONSOLE Console, - CONSOLE_STATE ExpectedState, - BOOL LockConsole) -{ - BOOL RetVal = FALSE; - - if (!Console) return FALSE; - - /* - * Forbid creation or deletion of consoles when - * checking for the existence of a console. - */ - ConSrvLockConsoleListShared(); - - if (ConSrvValidateConsolePointer(Console)) - { - RetVal = ConSrvValidateConsoleUnsafe(Console, - ExpectedState, - LockConsole); - } - - /* Unlock the console list and return */ - ConSrvUnlockConsoleList(); - return RetVal; -} - -NTSTATUS -FASTCALL -ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData, - PCONSOLE* Console, - BOOL LockConsole) -{ - NTSTATUS Status = STATUS_SUCCESS; - PCONSOLE ProcessConsole; - - // RtlEnterCriticalSection(&ProcessData->HandleTableLock); - ProcessConsole = ProcessData->Console; - - if (ConSrvValidateConsole(ProcessConsole, CONSOLE_RUNNING, LockConsole)) - { - InterlockedIncrement(&ProcessConsole->ReferenceCount); - *Console = ProcessConsole; - } - else - { - *Console = NULL; - Status = STATUS_INVALID_HANDLE; - } - - // RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - return Status; -} - -VOID FASTCALL -ConSrvReleaseConsole(PCONSOLE Console, - BOOL WasConsoleLocked) -{ - LONG RefCount = 0; - - if (!Console) return; - // if (Console->ReferenceCount == 0) return; // This shouldn't happen - ASSERT(Console->ReferenceCount > 0); - - /* The console must be locked */ - // ASSERT(Console_locked); - - /* - * Decrement the reference count. Save the new value too, - * because Console->ReferenceCount might be modified after - * the console gets unlocked but before we check whether we - * can destroy it. - */ - RefCount = _InterlockedDecrement(&Console->ReferenceCount); - - /* Unlock the console if needed */ - if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock); - - /* Delete the console if needed */ - if (RefCount <= 0) ConSrvDeleteConsole(Console); -} - -VOID WINAPI -ConSrvInitConsoleSupport(VOID) -{ - DPRINT("CONSRV: ConSrvInitConsoleSupport()\n"); - - /* Initialize the console list and its lock */ - InitializeListHead(&ConsoleList); - RtlInitializeResource(&ListLock); - - /* Should call LoadKeyboardLayout */ -} - -static BOOL -LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo, - IN OUT PCONSOLE_INFO ConsoleInfo, - OUT LPWSTR IconPath, - IN SIZE_T IconPathLength, - OUT PINT piIcon) -{ -#define PATH_SEPARATOR L'\\' - - BOOL RetVal = FALSE; - HRESULT hRes = S_OK; - LPWSTR LinkName = NULL; - SIZE_T Length = 0; - - if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) - return FALSE; - - if (IconPath == NULL || piIcon == NULL) - return FALSE; - - IconPath[0] = L'\0'; - *piIcon = 0; - - /* 1- Find the last path separator if any */ - LinkName = wcsrchr(ConsoleStartInfo->ConsoleTitle, PATH_SEPARATOR); - if (LinkName == NULL) - { - LinkName = ConsoleStartInfo->ConsoleTitle; - } - else - { - /* Skip the path separator */ - ++LinkName; - } - - /* 2- Check for the link extension. The name ".lnk" is considered invalid. */ - Length = wcslen(LinkName); - if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) ) - return FALSE; - - /* 3- It may be a link. Try to retrieve some properties */ - hRes = CoInitialize(NULL); - if (SUCCEEDED(hRes)) - { - /* Get a pointer to the IShellLink interface */ - IShellLinkW* pshl = NULL; - hRes = CoCreateInstance(&CLSID_ShellLink, - NULL, - CLSCTX_INPROC_SERVER, - &IID_IShellLinkW, - (LPVOID*)&pshl); - if (SUCCEEDED(hRes)) - { - /* Get a pointer to the IPersistFile interface */ - IPersistFile* ppf = NULL; - hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf); - if (SUCCEEDED(hRes)) - { - /* Load the shortcut */ - hRes = IPersistFile_Load(ppf, ConsoleStartInfo->ConsoleTitle, STGM_READ); - if (SUCCEEDED(hRes)) - { - /* - * Finally we can get the properties ! - * Update the old ones if needed. - */ - INT ShowCmd = 0; - // WORD HotKey = 0; - - /* Reset the name of the console with the name of the shortcut */ - Length = min(/*Length*/ Length - 4, // 4 == len(".lnk") - sizeof(ConsoleInfo->ConsoleTitle) / sizeof(ConsoleInfo->ConsoleTitle[0]) - 1); - wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length); - ConsoleInfo->ConsoleTitle[Length] = L'\0'; - - /* Get the window showing command */ - hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd); - if (SUCCEEDED(hRes)) ConsoleStartInfo->ShowWindow = (WORD)ShowCmd; - - /* Get the hotkey */ - // hRes = pshl->GetHotkey(&ShowCmd); - // if (SUCCEEDED(hRes)) ConsoleStartInfo->HotKey = HotKey; - - /* Get the icon location, if any */ - hRes = IShellLinkW_GetIconLocation(pshl, IconPath, IconPathLength, piIcon); - if (!SUCCEEDED(hRes)) - { - IconPath[0] = L'\0'; - } - - // FIXME: Since we still don't load console properties from the shortcut, - // return false. When this will be done, we will return true instead. - RetVal = FALSE; - } - IPersistFile_Release(ppf); - } - IShellLinkW_Release(pshl); - } - } - CoUninitialize(); - - return RetVal; -} - -NTSTATUS WINAPI -ConSrvInitConsole(OUT PCONSOLE* NewConsole, - IN OUT PCONSOLE_START_INFO ConsoleStartInfo, - IN PCSR_PROCESS ConsoleLeaderProcess) -{ - NTSTATUS Status; - SECURITY_ATTRIBUTES SecurityAttributes; - SIZE_T Length = 0; - DWORD ProcessId = HandleToUlong(ConsoleLeaderProcess->ClientId.UniqueProcess); - CONSOLE_INFO ConsoleInfo; - TEXTMODE_BUFFER_INFO ScreenBufferInfo; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER NewBuffer; - BOOL GuiMode; - WCHAR DefaultTitle[128]; - WCHAR IconPath[MAX_PATH + 1] = L""; - INT iIcon = 0; - - if (NewConsole == NULL) return STATUS_INVALID_PARAMETER; - *NewConsole = NULL; - - /* - * Allocate a console structure - */ - Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(CONSOLE)); - if (NULL == Console) - { - DPRINT1("Not enough memory for console creation.\n"); - return STATUS_NO_MEMORY; - } - - /* - * Load the console settings - */ - - /* 1. Load the default settings */ - ConSrvGetDefaultSettings(&ConsoleInfo, ProcessId); - - /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */ - Length = min(wcslen(ConsoleStartInfo->ConsoleTitle), - sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1); - wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length); - ConsoleInfo.ConsoleTitle[Length] = L'\0'; - - /* - * 3. Check whether the process creating the console was launched - * via a shell-link. ConsoleInfo.ConsoleTitle may be updated by - * the name of the shortcut. - */ - if (ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) - { - if (!LoadShellLinkConsoleInfo(ConsoleStartInfo, - &ConsoleInfo, - IconPath, - MAX_PATH, - &iIcon)) - { - ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME; - } - } - - /* - * 4. Load the remaining console settings via the registry. - */ - if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) - { - /* - * Either we weren't created by an app launched via a shell-link, - * or we failed to load shell-link console properties. - * Therefore, load the console infos for the application from the registry. - */ - ConSrvReadUserSettings(&ConsoleInfo, ProcessId); - - /* - * Now, update them with the properties the user might gave to us - * via the STARTUPINFO structure before calling CreateProcess - * (and which was transmitted via the ConsoleStartInfo structure). - * We therefore overwrite the values read in the registry. - */ - if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE) - { - ConsoleInfo.ScreenAttrib = (USHORT)ConsoleStartInfo->FillAttribute; - } - if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS) - { - ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize; - } - if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE) - { - // ConsoleInfo->ConsoleSize = ConsoleStartInfo->ConsoleWindowSize; - ConsoleInfo.ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx; - ConsoleInfo.ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy; - } - } - - /* - * Fix the screen buffer size if needed. The rule is: - * ScreenBufferSize >= ConsoleSize - */ - if (ConsoleInfo.ScreenBufferSize.X < ConsoleInfo.ConsoleSize.X) - ConsoleInfo.ScreenBufferSize.X = ConsoleInfo.ConsoleSize.X; - if (ConsoleInfo.ScreenBufferSize.Y < ConsoleInfo.ConsoleSize.Y) - ConsoleInfo.ScreenBufferSize.Y = ConsoleInfo.ConsoleSize.Y; - - /* - * Initialize the console - */ - Console->State = CONSOLE_INITIALIZING; - Console->ReferenceCount = 0; - InitializeCriticalSection(&Console->Lock); - InitializeListHead(&Console->ProcessList); - RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace)); - - memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors)); - Console->ConsoleSize = ConsoleInfo.ConsoleSize; - Console->FixedSize = FALSE; // Value by default; is reseted by the front-ends if needed. - - /* - * Initialize the input buffer - */ - ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console); - - SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - SecurityAttributes.lpSecurityDescriptor = NULL; - SecurityAttributes.bInheritHandle = TRUE; - Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); - if (NULL == Console->InputBuffer.ActiveEvent) - { - DeleteCriticalSection(&Console->Lock); - ConsoleFreeHeap(Console); - return STATUS_UNSUCCESSFUL; - } - - Console->InputBuffer.InputBufferSize = 0; // FIXME! - InitializeListHead(&Console->InputBuffer.InputEvents); - InitializeListHead(&Console->InputBuffer.ReadWaitQueue); - Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | - ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT; - - Console->QuickEdit = ConsoleInfo.QuickEdit; - Console->InsertMode = ConsoleInfo.InsertMode; - Console->LineBuffer = NULL; - Console->LineMaxSize = Console->LineSize = Console->LinePos = 0; - Console->LineComplete = Console->LineUpPressed = Console->LineInsertToggle = FALSE; - // LineWakeupMask - RtlZeroMemory(&Console->Selection, sizeof(CONSOLE_SELECTION_INFO)); - Console->Selection.dwFlags = CONSOLE_NO_SELECTION; - // dwSelectionCursor - - Console->CodePage = GetOEMCP(); - Console->OutputCodePage = GetOEMCP(); - - /* Initialize a new text-mode screen buffer with default settings */ - ScreenBufferInfo.ScreenBufferSize = ConsoleInfo.ScreenBufferSize; - ScreenBufferInfo.ScreenAttrib = ConsoleInfo.ScreenAttrib; - ScreenBufferInfo.PopupAttrib = ConsoleInfo.PopupAttrib; - ScreenBufferInfo.IsCursorVisible = TRUE; - ScreenBufferInfo.CursorSize = ConsoleInfo.CursorSize; - - InitializeListHead(&Console->BufferList); - Status = ConSrvCreateScreenBuffer(&NewBuffer, - Console, - CONSOLE_TEXTMODE_BUFFER, - &ScreenBufferInfo); - if (!NT_SUCCESS(Status)) - { - DPRINT1("ConSrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status); - CloseHandle(Console->InputBuffer.ActiveEvent); - DeleteCriticalSection(&Console->Lock); - ConsoleFreeHeap(Console); - return Status; - } - /* Make the new screen buffer active */ - Console->ActiveBuffer = NewBuffer; - InitializeListHead(&Console->WriteWaitQueue); - Console->PauseFlags = 0; - Console->UnpauseEvent = NULL; - - /* - * Initialize the alias and history buffers - */ - Console->Aliases = NULL; - InitializeListHead(&Console->HistoryBuffers); - Console->HistoryBufferSize = ConsoleInfo.HistoryBufferSize; - Console->NumberOfHistoryBuffers = ConsoleInfo.NumberOfHistoryBuffers; - Console->HistoryNoDup = ConsoleInfo.HistoryNoDup; - - /* Initialize the console title */ - ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo.ConsoleTitle); - if (ConsoleInfo.ConsoleTitle[0] == L'\0') - { - if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0]))) - { - ConsoleCreateUnicodeString(&Console->Title, DefaultTitle); - } - else - { - ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console"); - } - } - else - { - ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle); - } - - /* Lock the console until its initialization is finished */ - // EnterCriticalSection(&Console->Lock); - - /* - * If we are not in GUI-mode, start the text-mode terminal emulator. - * If we fail, try to start the GUI-mode terminal emulator. - */ - GuiMode = DtbgIsDesktopVisible(); - - if (!GuiMode) - { - DPRINT("CONSRV: Opening text-mode terminal emulator\n"); - Status = TuiInitConsole(Console, - ConsoleStartInfo, - &ConsoleInfo, - ProcessId); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to open text-mode terminal emulator, switching to gui-mode, Status = 0x%08lx\n", Status); - GuiMode = TRUE; - } - } - - /* - * Try to open the GUI-mode terminal emulator. Two cases are possible: - * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case - * failed and we start GUI-mode terminal emulator. - * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case - * succeeded BUT we failed at starting text-mode terminal emulator. - * Then GuiMode was switched to TRUE in order to try to open the GUI-mode - * terminal emulator (Win32k will automatically switch to graphical mode, - * therefore no additional code is needed). - */ - if (GuiMode) - { - DPRINT("CONSRV: Opening GUI-mode terminal emulator\n"); - Status = GuiInitConsole(Console, - ConsoleStartInfo, - &ConsoleInfo, - ProcessId, - IconPath, - iIcon); - if (!NT_SUCCESS(Status)) - { - DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status); - ConsoleFreeUnicodeString(&Console->OriginalTitle); - ConsoleFreeUnicodeString(&Console->Title); - ConioDeleteScreenBuffer(NewBuffer); - CloseHandle(Console->InputBuffer.ActiveEvent); - // LeaveCriticalSection(&Console->Lock); - DeleteCriticalSection(&Console->Lock); - ConsoleFreeHeap(Console); - return Status; - } - } - - DPRINT("Terminal initialized\n"); - - /* All went right, so add the console to the list */ - ConSrvLockConsoleListExclusive(); - DPRINT("Insert in the list\n"); - InsertTailList(&ConsoleList, &Console->Entry); - - /* The initialization is finished */ - DPRINT("Change state\n"); - Console->State = CONSOLE_RUNNING; - - /* Unlock the console */ - // LeaveCriticalSection(&Console->Lock); - - /* Unlock the console list */ - ConSrvUnlockConsoleList(); - - /* Copy buffer contents to screen */ - ConioDrawConsole(Console); - DPRINT("Console drawn\n"); - - /* Return the newly created console to the caller and a success code too */ - *NewConsole = Console; - return STATUS_SUCCESS; -} - -VOID WINAPI -ConSrvDeleteConsole(PCONSOLE Console) -{ - DPRINT("ConSrvDeleteConsole\n"); - - /* - * Forbid validation of any console by other threads - * during the deletion of this console. - */ - ConSrvLockConsoleListExclusive(); - - /* Check the existence of the console, and if it's ok, continue */ - if (!ConSrvValidateConsolePointer(Console)) - { - /* Unlock the console list and return */ - ConSrvUnlockConsoleList(); - return; - } - - /* - * If the console is already being destroyed - * (thus not running), just return. - */ - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) - { - /* Unlock the console list and return */ - ConSrvUnlockConsoleList(); - return; - } - - /* - * We are about to be destroyed. Signal it to other people - * so that they can terminate what they are doing, and that - * they cannot longer validate the console. - */ - Console->State = CONSOLE_TERMINATING; - - /* - * Allow other threads to finish their job: basically, unlock - * all other calls to EnterCriticalSection(&Console->Lock); by - * ConSrvValidateConsole(Unsafe) functions so that they just see - * that we are not in CONSOLE_RUNNING state anymore, or unlock - * other concurrent calls to ConSrvDeleteConsole so that they - * can see that we are in fact already deleting the console. - */ - LeaveCriticalSection(&Console->Lock); - ConSrvUnlockConsoleList(); - - /* FIXME: Send a terminate message to all the processes owning this console */ - - /* Cleanup the UI-oriented part */ - ConioCleanupConsole(Console); - - /*** - * Check that the console is in terminating state before continuing - * (the cleanup code must not change the state of the console... - * ...unless to cancel console deletion ?). - ***/ - - ConSrvLockConsoleListExclusive(); - - /* Re-check the existence of the console, and if it's ok, continue */ - if (!ConSrvValidateConsolePointer(Console)) - { - /* Unlock the console list and return */ - ConSrvUnlockConsoleList(); - return; - } - - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE)) - { - ConSrvUnlockConsoleList(); - return; - } - - /* We are in destruction */ - Console->State = CONSOLE_IN_DESTRUCTION; - - /* Remove the console from the list */ - RemoveEntryList(&Console->Entry); - - /* Reset the count to be sure */ - Console->ReferenceCount = 0; - - /* Discard all entries in the input event queue */ - PurgeInputBuffer(Console); - - if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer); - - IntDeleteAllAliases(Console); - HistoryDeleteBuffers(Console); - - ConioDeleteScreenBuffer(Console->ActiveBuffer); - if (!IsListEmpty(&Console->BufferList)) - { - DPRINT1("BUG: screen buffer list not empty\n"); - } - - // CloseHandle(Console->InputBuffer.ActiveEvent); - if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); - - ConsoleFreeUnicodeString(&Console->OriginalTitle); - ConsoleFreeUnicodeString(&Console->Title); - - DPRINT("ConSrvDeleteConsole - Unlocking\n"); - LeaveCriticalSection(&Console->Lock); - DPRINT("ConSrvDeleteConsole - Destroying lock\n"); - DeleteCriticalSection(&Console->Lock); - DPRINT("ConSrvDeleteConsole - Lock destroyed ; freeing console\n"); - - ConsoleFreeHeap(Console); - DPRINT("ConSrvDeleteConsole - Console freed\n"); - - /* Unlock the console list and return */ - ConSrvUnlockConsoleList(); -} - - -/* PUBLIC SERVER APIS *********************************************************/ - -CSR_API(SrvAllocConsole) -{ - NTSTATUS Status = STATUS_SUCCESS; - PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest; - PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess); - - if (ProcessData->Console != NULL) - { - DPRINT1("Process already has a console\n"); - return STATUS_ACCESS_DENIED; - } - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&AllocConsoleRequest->ConsoleStartInfo, - 1, - sizeof(CONSOLE_START_INFO))) - { - return STATUS_INVALID_PARAMETER; - } - - /* Initialize a new Console owned by the Console Leader Process */ - Status = ConSrvAllocateConsole(ProcessData, - &AllocConsoleRequest->InputHandle, - &AllocConsoleRequest->OutputHandle, - &AllocConsoleRequest->ErrorHandle, - AllocConsoleRequest->ConsoleStartInfo); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Console allocation failed\n"); - return Status; - } - - /* Return it to the caller */ - AllocConsoleRequest->Console = ProcessData->Console; - - /* Input Wait Handle */ - AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent; - - /* Set the Property Dialog Handler */ - ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher; - - /* Set the Ctrl Dispatcher */ - ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher; - - return STATUS_SUCCESS; -} - -CSR_API(SrvAttachConsole) -{ - NTSTATUS Status = STATUS_SUCCESS; - PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AttachConsoleRequest; - PCSR_PROCESS SourceProcess = NULL; // The parent process. - PCSR_PROCESS TargetProcess = CsrGetClientThread()->Process; // Ourselves. - HANDLE ProcessId = ULongToHandle(AttachConsoleRequest->ProcessId); - PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData; - - TargetProcessData = ConsoleGetPerProcessData(TargetProcess); - - if (TargetProcessData->Console != NULL) - { - DPRINT1("Process already has a console\n"); - return STATUS_ACCESS_DENIED; - } - - /* Check whether we try to attach to the parent's console */ - if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS)) - { - PROCESS_BASIC_INFORMATION ProcessInfo; - ULONG Length = sizeof(ProcessInfo); - - /* Get the real parent's ID */ - - Status = NtQueryInformationProcess(TargetProcess->ProcessHandle, - ProcessBasicInformation, - &ProcessInfo, - Length, &Length); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = %lu\n", Status); - return Status; - } - - ProcessId = ULongToHandle(ProcessInfo.InheritedFromUniqueProcessId); - } - - /* Lock the source process via its PID */ - Status = CsrLockProcessByClientId(ProcessId, &SourceProcess); - if (!NT_SUCCESS(Status)) return Status; - - SourceProcessData = ConsoleGetPerProcessData(SourceProcess); - - if (SourceProcessData->Console == NULL) - { - Status = STATUS_INVALID_HANDLE; - goto Quit; - } - - /* - * Inherit the console from the parent, - * if any, otherwise return an error. - */ - Status = ConSrvInheritConsole(TargetProcessData, - SourceProcessData->Console, - TRUE, - &AttachConsoleRequest->InputHandle, - &AttachConsoleRequest->OutputHandle, - &AttachConsoleRequest->ErrorHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Console inheritance failed\n"); - goto Quit; - } - - /* Return it to the caller */ - AttachConsoleRequest->Console = TargetProcessData->Console; - - /* Input Wait Handle */ - AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent; - - /* Set the Property Dialog Handler */ - TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher; - - /* Set the Ctrl Dispatcher */ - TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher; - - Status = STATUS_SUCCESS; - -Quit: - /* Unlock the "source" process and exit */ - CsrUnlockProcess(SourceProcess); - return Status; -} - -CSR_API(SrvFreeConsole) -{ - ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process)); - return STATUS_SUCCESS; -} - -CSR_API(SrvGetConsoleMode) -{ - NTSTATUS Status; - PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest; - PCONSOLE_IO_OBJECT Object = NULL; - - Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - ConsoleModeRequest->ConsoleHandle, - &Object, NULL, GENERIC_READ, TRUE, 0); - if (!NT_SUCCESS(Status)) return Status; - - Status = STATUS_SUCCESS; - - if (INPUT_BUFFER == Object->Type) - { - PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; - PCONSOLE Console = InputBuffer->Header.Console; - DWORD ConsoleMode = InputBuffer->Mode; - - if (Console->QuickEdit || Console->InsertMode) - { - // Windows does this, even if it's not documented on MSDN - ConsoleMode |= ENABLE_EXTENDED_FLAGS; - - if (Console->QuickEdit ) ConsoleMode |= ENABLE_QUICK_EDIT_MODE; - if (Console->InsertMode) ConsoleMode |= ENABLE_INSERT_MODE; - } - - ConsoleModeRequest->ConsoleMode = ConsoleMode; - } - else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type) - { - PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; - ConsoleModeRequest->ConsoleMode = Buffer->Mode; - } - else - { - Status = STATUS_INVALID_HANDLE; - } - - ConSrvReleaseObject(Object, TRUE); - return Status; -} - -CSR_API(SrvSetConsoleMode) -{ -#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE ) -#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \ - ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \ - ENABLE_MOUSE_INPUT ) -#define CONSOLE_VALID_OUTPUT_MODES ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT ) - - NTSTATUS Status; - PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest; - DWORD ConsoleMode = ConsoleModeRequest->ConsoleMode; - PCONSOLE_IO_OBJECT Object = NULL; - - Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - ConsoleModeRequest->ConsoleHandle, - &Object, NULL, GENERIC_WRITE, TRUE, 0); - if (!NT_SUCCESS(Status)) return Status; - - Status = STATUS_SUCCESS; - - if (INPUT_BUFFER == Object->Type) - { - PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; - PCONSOLE Console = InputBuffer->Header.Console; - - DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode); - - /* - * 1. Only the presence of valid mode flags is allowed. - */ - if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES | CONSOLE_VALID_CONTROL_MODES)) - { - Status = STATUS_INVALID_PARAMETER; - goto Quit; - } - - /* - * 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS, - * then consider the flags invalid. - * - if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) && - (ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 ) - { - Status = STATUS_INVALID_PARAMETER; - goto Quit; - } - */ - - /* - * 3. Now we can continue. - */ - if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) - { - Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE); - Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE); - } - InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES); - } - else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type) - { - PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; - - DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode); - - if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES) - { - Status = STATUS_INVALID_PARAMETER; - } - else - { - Buffer->Mode = (ConsoleMode & CONSOLE_VALID_OUTPUT_MODES); - } - } - else - { - Status = STATUS_INVALID_HANDLE; - } - -Quit: - ConSrvReleaseObject(Object, TRUE); - return Status; -} - -CSR_API(SrvGetConsoleTitle) -{ - NTSTATUS Status; - PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest; - // PCSR_PROCESS Process = CsrGetClientThread()->Process; - PCONSOLE Console; - DWORD Length; - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID)&TitleRequest->Title, - TitleRequest->Length, - sizeof(BYTE))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Can't get console\n"); - return Status; - } - - /* Copy title of the console to the user title buffer */ - if (TitleRequest->Length >= sizeof(WCHAR)) - { - Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length); - memcpy(TitleRequest->Title, Console->Title.Buffer, Length); - TitleRequest->Title[Length / sizeof(WCHAR)] = L'\0'; - } - - TitleRequest->Length = Console->Title.Length; - - ConSrvReleaseConsole(Console, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleTitle) -{ - NTSTATUS Status; - PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest; - // PCSR_PROCESS Process = CsrGetClientThread()->Process; - PCONSOLE Console; - PWCHAR Buffer; - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID)&TitleRequest->Title, - TitleRequest->Length, - sizeof(BYTE))) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Can't get console\n"); - return Status; - } - - /* Allocate a new buffer to hold the new title (NULL-terminated) */ - Buffer = ConsoleAllocHeap(0, TitleRequest->Length + sizeof(WCHAR)); - if (Buffer) - { - /* Free the old title */ - ConsoleFreeUnicodeString(&Console->Title); - - /* Copy title to console */ - Console->Title.Buffer = Buffer; - Console->Title.Length = TitleRequest->Length; - Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR); - RtlCopyMemory(Console->Title.Buffer, - TitleRequest->Title, - Console->Title.Length); - Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; - - ConioChangeTitle(Console); - Status = STATUS_SUCCESS; - } - else - { - Status = STATUS_NO_MEMORY; - } - - ConSrvReleaseConsole(Console, TRUE); - return Status; -} - -/********************************************************************** - * HardwareStateProperty - * - * DESCRIPTION - * Set/Get the value of the HardwareState and switch - * between direct video buffer ouput and GDI windowed - * output. - * ARGUMENTS - * Client hands us a CONSOLE_GETSETHWSTATE object. - * We use the same object to Request. - * NOTE - * ConsoleHwState has the correct size to be compatible - * with NT's, but values are not. - */ -#if 0 -static NTSTATUS FASTCALL -SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState) -{ - DPRINT1("Console Hardware State: %d\n", ConsoleHwState); - - if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) - ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) - { - if (Console->HardwareState != ConsoleHwState) - { - /* TODO: implement switching from full screen to windowed mode */ - /* TODO: or back; now simply store the hardware state */ - Console->HardwareState = ConsoleHwState; - } - - return STATUS_SUCCESS; - } - - return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ -} -#endif - -CSR_API(SrvGetConsoleHardwareState) -{ -#if 0 - NTSTATUS Status; - PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest; - PCONSOLE_SCREEN_BUFFER Buff; - PCONSOLE Console; - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - HardwareStateRequest->OutputHandle, - &Buff, - GENERIC_READ, - TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n"); - return Status; - } - - Console = Buff->Header.Console; - HardwareStateRequest->State = Console->HardwareState; - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return Status; -#else - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -#endif -} - -CSR_API(SrvSetConsoleHardwareState) -{ -#if 0 - NTSTATUS Status; - PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest; - PCONSOLE_SCREEN_BUFFER Buff; - PCONSOLE Console; - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - HardwareStateRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n"); - return Status; - } - - DPRINT("Setting console hardware state.\n"); - Console = Buff->Header.Console; - Status = SetConsoleHardwareState(Console, HardwareStateRequest->State); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return Status; -#else - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -#endif -} - -CSR_API(SrvGetConsoleDisplayMode) -{ - NTSTATUS Status; - PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetDisplayModeRequest; - PCONSOLE Console; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - GetDisplayModeRequest->DisplayMode = ConioGetDisplayMode(Console); - - ConSrvReleaseConsole(Console, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleDisplayMode) -{ - NTSTATUS Status; - PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - SetDisplayModeRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - if (ConioSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode)) - { - SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize; - Status = STATUS_SUCCESS; - } - else - { - Status = STATUS_INVALID_PARAMETER; - } - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return Status; -} - -CSR_API(SrvGetLargestConsoleWindowSize) -{ - NTSTATUS Status; - PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetLargestWindowSizeRequest; - PCONSOLE_SCREEN_BUFFER Buff; - PCONSOLE Console; - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - GetLargestWindowSizeRequest->OutputHandle, - &Buff, - GENERIC_READ, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - ConioGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvShowConsoleCursor) -{ - NTSTATUS Status; - PCONSOLE_SHOWCURSOR ShowCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ShowCursorRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - ShowCursorRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - ShowCursorRequest->RefCount = ConioShowMouseCursor(Console, ShowCursorRequest->Show); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleCursor) -{ - NTSTATUS Status; - BOOL Success; - PCONSOLE_SETCURSOR SetCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - // FIXME: Tests show that this function is used only for graphics screen buffers - // and otherwise it returns false + set last error to invalid handle. - // NOTE: I find that behaviour is ridiculous but ok, let's accept that at the moment... - Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - SetCursorRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - Success = ConioSetMouseCursor(Console, SetCursorRequest->hCursor); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); -} - -CSR_API(SrvConsoleMenuControl) -{ - NTSTATUS Status; - PCONSOLE_MENUCONTROL MenuControlRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.MenuControlRequest; - PCONSOLE Console; - PCONSOLE_SCREEN_BUFFER Buff; - - Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - MenuControlRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - MenuControlRequest->hMenu = ConioMenuControl(Console, - MenuControlRequest->dwCmdIdLow, - MenuControlRequest->dwCmdIdHigh); - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleMenuClose) -{ - NTSTATUS Status; - BOOL Success; - PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetMenuCloseRequest; - PCONSOLE Console; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Success = ConioSetMenuClose(Console, SetMenuCloseRequest->Enable); - - ConSrvReleaseConsole(Console, TRUE); - return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); -} - -CSR_API(SrvSetConsoleWindowInfo) -{ - NTSTATUS Status; - PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest; - PCONSOLE_SCREEN_BUFFER Buff; - SMALL_RECT WindowRect = SetWindowInfoRequest->WindowRect; - - DPRINT("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n", - SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute, - WindowRect.Left, WindowRect.Top, WindowRect.Right, WindowRect.Bottom); - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - SetWindowInfoRequest->OutputHandle, - &Buff, - GENERIC_READ, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - if (SetWindowInfoRequest->Absolute == FALSE) - { - /* Relative positions given. Transform them to absolute ones */ - WindowRect.Left += Buff->ViewOrigin.X; - WindowRect.Top += Buff->ViewOrigin.Y; - WindowRect.Right += Buff->ViewOrigin.X + Buff->ViewSize.X - 1; - WindowRect.Bottom += Buff->ViewOrigin.Y + Buff->ViewSize.Y - 1; - } - - /* See MSDN documentation on SetConsoleWindowInfo about the performed checks */ - if ( (WindowRect.Left < 0) || (WindowRect.Top < 0) || - (WindowRect.Right >= Buff->ScreenBufferSize.X) || - (WindowRect.Bottom >= Buff->ScreenBufferSize.Y) || - (WindowRect.Right <= WindowRect.Left) || - (WindowRect.Bottom <= WindowRect.Top) ) - { - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_INVALID_PARAMETER; - } - - Buff->ViewOrigin.X = WindowRect.Left; - Buff->ViewOrigin.Y = WindowRect.Top; - - Buff->ViewSize.X = WindowRect.Right - WindowRect.Left + 1; - Buff->ViewSize.Y = WindowRect.Bottom - WindowRect.Top + 1; - - ConSrvReleaseScreenBuffer(Buff, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvGetConsoleWindow) -{ - NTSTATUS Status; - PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest; - PCONSOLE Console; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - GetWindowRequest->WindowHandle = ConioGetConsoleWindowHandle(Console); - - ConSrvReleaseConsole(Console, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleIcon) -{ - NTSTATUS Status; - PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest; - PCONSOLE Console; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Status = (ConioChangeIcon(Console, SetIconRequest->WindowIcon) - ? STATUS_SUCCESS - : STATUS_UNSUCCESSFUL); - - ConSrvReleaseConsole(Console, TRUE); - return Status; -} - -CSR_API(SrvGetConsoleCP) -{ - NTSTATUS Status; - PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest; - PCONSOLE Console; - - DPRINT("SrvGetConsoleCP, getting %s Code Page\n", - ConsoleCPRequest->InputCP ? "Input" : "Output"); - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - ConsoleCPRequest->CodePage = (ConsoleCPRequest->InputCP ? Console->CodePage - : Console->OutputCodePage); - ConSrvReleaseConsole(Console, TRUE); - return STATUS_SUCCESS; -} - -CSR_API(SrvSetConsoleCP) -{ - NTSTATUS Status; - PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest; - PCONSOLE Console; - - DPRINT("SrvSetConsoleCP, setting %s Code Page\n", - ConsoleCPRequest->InputCP ? "Input" : "Output"); - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - if (IsValidCodePage(ConsoleCPRequest->CodePage)) - { - if (ConsoleCPRequest->InputCP) - Console->CodePage = ConsoleCPRequest->CodePage; - else - Console->OutputCodePage = ConsoleCPRequest->CodePage; - - ConSrvReleaseConsole(Console, TRUE); - return STATUS_SUCCESS; - } - - ConSrvReleaseConsole(Console, TRUE); - return STATUS_INVALID_PARAMETER; -} - -CSR_API(SrvGetConsoleProcessList) -{ - NTSTATUS Status; - PCONSOLE_GETPROCESSLIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest; - PDWORD Buffer; - // PCSR_PROCESS Process = CsrGetClientThread()->Process; - PCONSOLE Console; - PCONSOLE_PROCESS_DATA current; - PLIST_ENTRY current_entry; - ULONG nItems = 0; - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID)&GetProcessListRequest->pProcessIds, - GetProcessListRequest->nMaxIds, - sizeof(DWORD))) - { - return STATUS_INVALID_PARAMETER; - } - - Buffer = GetProcessListRequest->pProcessIds; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - for (current_entry = Console->ProcessList.Flink; - current_entry != &Console->ProcessList; - current_entry = current_entry->Flink) - { - current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink); - if (++nItems <= GetProcessListRequest->nMaxIds) - { - *Buffer++ = HandleToUlong(current->Process->ClientId.UniqueProcess); - } - } - - ConSrvReleaseConsole(Console, TRUE); - - GetProcessListRequest->nProcessIdsTotal = nItems; - return STATUS_SUCCESS; -} - -CSR_API(SrvGenerateConsoleCtrlEvent) -{ - NTSTATUS Status; - PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEventRequest; - PCONSOLE Console; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Status = ConSrvConsoleProcessCtrlEvent(Console, - GenerateCtrlEventRequest->ProcessGroup, - GenerateCtrlEventRequest->Event); - - ConSrvReleaseConsole(Console, TRUE); - return Status; -} - -CSR_API(SrvGetConsoleSelectionInfo) -{ - NTSTATUS Status; - PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest; - PCONSOLE Console; - - Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); - if (NT_SUCCESS(Status)) - { - memset(&GetSelectionInfoRequest->Info, 0, sizeof(CONSOLE_SELECTION_INFO)); - if (Console->Selection.dwFlags != 0) - GetSelectionInfoRequest->Info = Console->Selection; - ConSrvReleaseConsole(Console, TRUE); - } - - return Status; -} - -/* EOF */ diff --git a/win32ss/user/consrv/consrv.rc b/win32ss/user/consrv/consrv.rc deleted file mode 100644 index 6a089772b29..00000000000 --- a/win32ss/user/consrv/consrv.rc +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include "resource.h" - -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL - -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Console Server & Terminal Emulator DLL" -#define REACTOS_STR_INTERNAL_NAME "consrv" -#define REACTOS_STR_ORIGINAL_FILENAME "consrv.dll" -#include - -#include "rsrc.rc" - -#include "frontends/frontends.rc" diff --git a/win32ss/user/consrv/consrv.spec b/win32ss/user/consrv/consrv.spec deleted file mode 100644 index c8831657bfe..00000000000 --- a/win32ss/user/consrv/consrv.spec +++ /dev/null @@ -1 +0,0 @@ -@ stdcall ConServerDllInitialization(ptr) diff --git a/win32ss/user/consrv/include/console.h b/win32ss/user/consrv/include/console.h deleted file mode 100644 index 09e4b338168..00000000000 --- a/win32ss/user/consrv/include/console.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/include/console.h - * PURPOSE: Public Console Management Interface - * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) - */ - -#pragma once - -BOOL FASTCALL ConSrvValidateConsolePointer(PCONSOLE Console); -BOOL FASTCALL ConSrvValidateConsoleState(PCONSOLE Console, - CONSOLE_STATE ExpectedState); -BOOL FASTCALL ConSrvValidateConsoleUnsafe(PCONSOLE Console, - CONSOLE_STATE ExpectedState, - BOOL LockConsole); -BOOL FASTCALL ConSrvValidateConsole(PCONSOLE Console, - CONSOLE_STATE ExpectedState, - BOOL LockConsole); - -/* EOF */ diff --git a/win32ss/user/ntuser/hotkey.c b/win32ss/user/ntuser/hotkey.c index 5335658df58..0fbd6648d40 100644 --- a/win32ss/user/ntuser/hotkey.c +++ b/win32ss/user/ntuser/hotkey.c @@ -18,11 +18,23 @@ DBG_DEFAULT_CHANNEL(UserHotkey); /* GLOBALS *******************************************************************/ -/* Hardcoded hotkeys. See http://ivanlef0u.fr/repo/windoz/VI20051005.html */ +/* + * Hardcoded hotkeys. See http://ivanlef0u.fr/repo/windoz/VI20051005.html + * or http://repo.meh.or.id/Windows/VI20051005.html . + * + * NOTE: The (Shift-)F12 keys are used only for the "UserDebuggerHotKey" setting + * which enables setting a key shortcut which, when pressed, establishes a + * breakpoint in the code being debugged: + * see http://technet.microsoft.com/en-us/library/cc786263(v=ws.10).aspx + * and http://flylib.com/books/en/4.441.1.33/1/ for more details. + * By default the key is VK-F12 on a 101-key keyboard, and is VK_SUBTRACT + * (hyphen / substract sign) on a 82-key keyboard. + */ /* thread hwnd modifiers vk id next */ -HOT_KEY hkF12 = {NULL, NULL, 0, VK_F12, IDHK_F12, NULL}; -HOT_KEY hkShiftF12 = {NULL, NULL, MOD_SHIFT, VK_F12, IDHK_SHIFTF12, &hkF12}; -HOT_KEY hkWinKey = {NULL, NULL, MOD_WIN, 0, IDHK_WINKEY, &hkShiftF12}; +// HOT_KEY hkF12 = {NULL, NULL, 0, VK_F12, IDHK_F12, NULL}; +// HOT_KEY hkShiftF12 = {NULL, NULL, MOD_SHIFT, VK_F12, IDHK_SHIFTF12, &hkF12}; +// HOT_KEY hkWinKey = {NULL, NULL, MOD_WIN, 0, IDHK_WINKEY, &hkShiftF12}; +HOT_KEY hkWinKey = {NULL, NULL, MOD_WIN, 0, IDHK_WINKEY, NULL}; PHOT_KEY gphkFirst = &hkWinKey; BOOL bWinHotkeyActive = FALSE; @@ -171,7 +183,7 @@ co_UserProcessHotKeys(WORD wVk, BOOL bIsDown) { TRACE("Hot key pressed (hWnd %p, id %d)\n", pHotKey->hWnd, pHotKey->id); - /* WIN and F12 keys are hardcoded here. See: http://ivanlef0u.fr/repo/windoz/VI20051005.html */ + /* WIN and F12 keys are hardcoded here. See comments on top of this file. */ if (pHotKey == &hkWinKey) { if(bWinHotkeyActive == TRUE) @@ -180,10 +192,12 @@ co_UserProcessHotKeys(WORD wVk, BOOL bIsDown) bWinHotkeyActive = FALSE; } } +#if 0 /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */ else if (pHotKey == &hkF12 || pHotKey == &hkShiftF12) { //co_ActivateDebugger(); // FIXME } +#endif else if (pHotKey->id == IDHK_REACTOS && !pHotKey->pThread) // FIXME: Those hotkeys doesn't depend on RegisterHotKey { UserPostMessage(pHotKey->hWnd, WM_SYSCOMMAND, SC_HOTKEY, (LPARAM)pHotKey->hWnd); diff --git a/win32ss/user/winsrv/CMakeLists.txt b/win32ss/user/winsrv/CMakeLists.txt index e5d865991f6..39f5deb3100 100644 --- a/win32ss/user/winsrv/CMakeLists.txt +++ b/win32ss/user/winsrv/CMakeLists.txt @@ -5,16 +5,19 @@ include_directories( spec2def(winsrv.dll winsrv.spec) +# The components +include(consrv.cmake) +include(usersrv.cmake) + list(APPEND SOURCE - harderror.c init.c - register.c - shutdown.c winsrv.rc ${CMAKE_CURRENT_BINARY_DIR}/winsrv.def) add_library(winsrv SHARED ${SOURCE}) +# Add the components +target_link_libraries(winsrv consrv usersrv) target_link_libraries(winsrv win32ksys ${PSEH_LIB}) # win32ksys because of NtUser...() set_module_type(winsrv win32dll UNICODE) diff --git a/win32ss/user/winsrv/consrv.cmake b/win32ss/user/winsrv/consrv.cmake new file mode 100644 index 00000000000..faa44c6422d --- /dev/null +++ b/win32ss/user/winsrv/consrv.cmake @@ -0,0 +1,52 @@ + +remove_definitions(-D_WIN32_WINNT=0x502) +add_definitions(-D_WIN32_WINNT=0x600) + +include_directories(consrv) + +list(APPEND CONSRV_SOURCE + consrv/alias.c + consrv/coninput.c + consrv/conoutput.c + consrv/console.c + consrv/frontendctl.c + consrv/handle.c + consrv/init.c + consrv/lineinput.c + consrv/settings.c + consrv/condrv/coninput.c + consrv/condrv/conoutput.c + consrv/condrv/console.c + consrv/condrv/dummyfrontend.c + consrv/condrv/graphics.c + consrv/condrv/text.c + consrv/frontends/input.c + consrv/frontends/gui/guiterm.c + consrv/frontends/gui/guisettings.c + consrv/frontends/gui/graphics.c + consrv/frontends/gui/text.c + consrv/frontends/tui/tuiterm.c + # consrv/consrv.rc + ) + +# +# Explicitely enable MS extensions to be able to use unnamed (anonymous) nested structs. +# +# FIXME: http://www.cmake.org/Bug/view.php?id=12998 +if(MSVC) + ## NOTE: No need to specify it as we use MSVC :) + ##add_target_compile_flags(consrv "/Ze") + #set_source_files_properties(${CONSRV_SOURCE} PROPERTIES COMPILE_FLAGS "/Ze") +else() + #add_target_compile_flags(consrv "-fms-extensions") + set_source_files_properties(${CONSRV_SOURCE} PROPERTIES COMPILE_FLAGS "-fms-extensions") +endif() + +add_library(consrv ${CONSRV_SOURCE}) +#add_object_library(consrv ${CONSRV_SOURCE}) + +add_importlibs(consrv psapi) # And the default ones from winsrv +add_delay_importlibs(consrv ole32) # And the default ones from winsrv +target_link_libraries(consrv uuid) # And the default ones from winsrv + +set_module_type(consrv module UNICODE) diff --git a/win32ss/user/consrv/alias.c b/win32ss/user/winsrv/consrv/alias.c similarity index 99% rename from win32ss/user/consrv/alias.c rename to win32ss/user/winsrv/consrv/alias.c index 1ab7b075f04..d96ab0a872b 100644 --- a/win32ss/user/consrv/alias.c +++ b/win32ss/user/winsrv/consrv/alias.c @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/alias.c + * FILE: win32ss/user/winsrv/consrv/alias.c * PURPOSE: Alias support functions * PROGRAMMERS: Christoph Wittich * Johannes Anderwald diff --git a/win32ss/user/consrv/alias.h b/win32ss/user/winsrv/consrv/alias.h similarity index 84% rename from win32ss/user/consrv/alias.h rename to win32ss/user/winsrv/consrv/alias.h index cc501d977b6..19e3b98a871 100644 --- a/win32ss/user/consrv/alias.h +++ b/win32ss/user/winsrv/consrv/alias.h @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/alias.h + * FILE: win32ss/user/winsrv/consrv/alias.h * PURPOSE: Alias support functions * PROGRAMMERS: Christoph Wittich * Johannes Anderwald diff --git a/win32ss/user/consrv/api.h b/win32ss/user/winsrv/consrv/api.h similarity index 97% rename from win32ss/user/consrv/api.h rename to win32ss/user/winsrv/consrv/api.h index d2f6db562ff..a7f340bc742 100644 --- a/win32ss/user/consrv/api.h +++ b/win32ss/user/winsrv/consrv/api.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/api.h + * FILE: win32ss/user/winsrv/consrv/api.h * PURPOSE: Public server APIs definitions * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ diff --git a/win32ss/user/winsrv/consrv/condrv/coninput.c b/win32ss/user/winsrv/consrv/condrv/coninput.c new file mode 100644 index 00000000000..38031304921 --- /dev/null +++ b/win32ss/user/winsrv/consrv/condrv/coninput.c @@ -0,0 +1,514 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver DLL + * FILE: win32ss/user/winsrv/consrv/condrv/coninput.c + * PURPOSE: Console Input functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "handle.h" +#include "lineinput.h" + +#define NDEBUG +#include + + +/* GLOBALS ********************************************************************/ + +#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ + ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \ + (Access), (LockConsole), INPUT_BUFFER) +#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \ + ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \ + (Access), (LockConsole), INPUT_BUFFER) +#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \ + ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked)) + + +#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \ + WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL) + +#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \ + MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1) + +typedef struct ConsoleInput_t +{ + LIST_ENTRY ListEntry; + INPUT_RECORD InputEvent; +} ConsoleInput; + + +/* PRIVATE FUNCTIONS **********************************************************/ + +static VOID FASTCALL +ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent) +{ + if (InputEvent->EventType == KEY_EVENT) + { + WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar; + InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0; + ConsoleInputUnicodeCharToAnsiChar(Console, + &InputEvent->Event.KeyEvent.uChar.AsciiChar, + &UnicodeChar); + } +} + +NTSTATUS FASTCALL +ConioProcessInputEvent(PCONSOLE Console, + PINPUT_RECORD InputEvent) +{ + ConsoleInput *ConInRec; + + /* Check for pause or unpause */ + if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown) + { + WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode; + if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD)) + { + DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState; + if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT && + (vk == VK_PAUSE || (vk == 'S' && + (cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) && + !(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))))) + { + ConioPause(Console, PAUSED_FROM_KEYBOARD); + return STATUS_SUCCESS; + } + } + else + { + if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN && + vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL) + { + ConioUnpause(Console, PAUSED_FROM_KEYBOARD); + return STATUS_SUCCESS; + } + } + } + + /* Add event to the queue */ + ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput)); + if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES; + + ConInRec->InputEvent = *InputEvent; + InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry); + + SetEvent(Console->InputBuffer.ActiveEvent); + CsrNotifyWait(&Console->InputBuffer.ReadWaitQueue, + WaitAny, + NULL, + NULL); + if (!IsListEmpty(&Console->InputBuffer.ReadWaitQueue)) + { + CsrDereferenceWait(&Console->InputBuffer.ReadWaitQueue); + } + + return STATUS_SUCCESS; +} + +VOID FASTCALL +PurgeInputBuffer(PCONSOLE Console) +{ + PLIST_ENTRY CurrentEntry; + ConsoleInput* Event; + + while (!IsListEmpty(&Console->InputBuffer.InputEvents)) + { + CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents); + Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + ConsoleFreeHeap(Event); + } + + CloseHandle(Console->InputBuffer.ActiveEvent); +} + +VOID NTAPI +ConDrvProcessKey(IN PCONSOLE Console, + IN BOOLEAN Down, + IN UINT VirtualKeyCode, + IN UINT VirtualScanCode, + IN WCHAR UnicodeChar, + IN ULONG ShiftState, + IN BYTE KeyStateCtrl) +{ + INPUT_RECORD er; + + /* process Ctrl-C and Ctrl-Break */ + if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && + Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') && + (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyStateCtrl & 0x80) ) + { + DPRINT1("Console_Api Ctrl-C\n"); + ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_C_EVENT); + + if (Console->LineBuffer && !Console->LineComplete) + { + /* Line input is in progress; end it */ + Console->LinePos = Console->LineSize = 0; + Console->LineComplete = TRUE; + } + return; + } + + if ( (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) != 0 && + (VK_UP == VirtualKeyCode || VK_DOWN == VirtualKeyCode) ) + { + if (!Down) return; + + /* scroll up or down */ + if (VK_UP == VirtualKeyCode) + { + /* only scroll up if there is room to scroll up into */ + if (Console->ActiveBuffer->CursorPosition.Y != Console->ActiveBuffer->ScreenBufferSize.Y - 1) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + + Console->ActiveBuffer->ScreenBufferSize.Y - 1) % + Console->ActiveBuffer->ScreenBufferSize.Y; + Console->ActiveBuffer->CursorPosition.Y++; + } + } + else + { + /* only scroll down if there is room to scroll down into */ + if (Console->ActiveBuffer->CursorPosition.Y != 0) + { + Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) % + Console->ActiveBuffer->ScreenBufferSize.Y; + Console->ActiveBuffer->CursorPosition.Y--; + } + } + + ConioDrawConsole(Console); + return; + } + + er.EventType = KEY_EVENT; + er.Event.KeyEvent.bKeyDown = Down; + er.Event.KeyEvent.wRepeatCount = 1; + er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; + er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; + er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar; + er.Event.KeyEvent.dwControlKeyState = ShiftState; + + ConioProcessInputEvent(Console, &er); +} + + +/* PUBLIC DRIVER APIS *********************************************************/ + +NTSTATUS NTAPI +ConDrvReadConsole(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN Unicode, + OUT PVOID Buffer, + IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, + IN ULONG NumCharsToRead, + OUT PULONG NumCharsRead OPTIONAL) +{ + // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait. + NTSTATUS Status = STATUS_PENDING; + PLIST_ENTRY CurrentEntry; + ConsoleInput *Input; + ULONG i = ReadControl->nInitialChars; + + if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */ + ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity checks */ + ASSERT(Console == InputBuffer->Header.Console); + ASSERT( (Buffer != NULL && NumCharsToRead >= 0) || + (Buffer == NULL && NumCharsToRead == 0) ); + + /* We haven't read anything (yet) */ + + if (InputBuffer->Mode & ENABLE_LINE_INPUT) + { + if (Console->LineBuffer == NULL) + { + /* Starting a new line */ + Console->LineMaxSize = (WORD)max(256, NumCharsToRead); + + Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR)); + if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY; + + Console->LineComplete = FALSE; + Console->LineUpPressed = FALSE; + Console->LineInsertToggle = 0; + Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask; + Console->LineSize = ReadControl->nInitialChars; + Console->LinePos = Console->LineSize; + + /* + * Pre-filling the buffer is only allowed in the Unicode API, + * so we don't need to worry about ANSI <-> Unicode conversion. + */ + memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR)); + if (Console->LineSize == Console->LineMaxSize) + { + Console->LineComplete = TRUE; + Console->LinePos = 0; + } + } + + /* If we don't have a complete line yet, process the pending input */ + while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents)) + { + /* Remove input event from queue */ + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); + if (IsListEmpty(&InputBuffer->InputEvents)) + { + ResetEvent(InputBuffer->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* Only pay attention to key down */ + if (Input->InputEvent.EventType == KEY_EVENT && + Input->InputEvent.Event.KeyEvent.bKeyDown) + { + LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent); + ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState; + } + ConsoleFreeHeap(Input); + } + + /* Check if we have a complete line to read from */ + if (Console->LineComplete) + { + while (i < NumCharsToRead && Console->LinePos != Console->LineSize) + { + WCHAR Char = Console->LineBuffer[Console->LinePos++]; + + if (Unicode) + { + ((PWCHAR)Buffer)[i] = Char; + } + else + { + ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char); + } + ++i; + } + + if (Console->LinePos == Console->LineSize) + { + /* Entire line has been read */ + ConsoleFreeHeap(Console->LineBuffer); + Console->LineBuffer = NULL; + } + + Status = STATUS_SUCCESS; + } + } + else + { + /* Character input */ + while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents)) + { + /* Remove input event from queue */ + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); + if (IsListEmpty(&InputBuffer->InputEvents)) + { + ResetEvent(InputBuffer->ActiveEvent); + } + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + + /* Only pay attention to valid ASCII chars, on key down */ + if (Input->InputEvent.EventType == KEY_EVENT && + Input->InputEvent.Event.KeyEvent.bKeyDown && + Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0') + { + WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar; + + if (Unicode) + { + ((PWCHAR)Buffer)[i] = Char; + } + else + { + ConsoleInputUnicodeCharToAnsiChar(Console, &((PCHAR)Buffer)[i], &Char); + } + ++i; + + /* Did read something */ + Status = STATUS_SUCCESS; + } + ConsoleFreeHeap(Input); + } + } + + if (NumCharsRead) *NumCharsRead = i; + + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleInput(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN WaitForMoreEvents, + IN BOOLEAN Unicode, + OUT PINPUT_RECORD InputRecord, + IN ULONG NumEventsToRead, + OUT PULONG NumEventsRead OPTIONAL) +{ + PLIST_ENTRY CurrentInput; + ConsoleInput* Input; + ULONG i = 0; + + if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */) + return STATUS_INVALID_PARAMETER; + + /* Validity checks */ + ASSERT(Console == InputBuffer->Header.Console); + ASSERT( (InputRecord != NULL && NumEventsToRead >= 0) || + (InputRecord == NULL && NumEventsToRead == 0) ); + + // Do NOT do that !! Use the existing number of events already read, if any... + // if (NumEventsRead) *NumEventsRead = 0; + + if (IsListEmpty(&InputBuffer->InputEvents)) + { + /* + * No input is available. Wait for more input if requested, + * otherwise, we don't wait, so we return success. + */ + return (WaitForMoreEvents ? STATUS_PENDING : STATUS_SUCCESS); + } + + /* Only get input if there is any */ + CurrentInput = InputBuffer->InputEvents.Flink; + if (NumEventsRead) i = *NumEventsRead; // We will read the remaining events... + + while ((CurrentInput != &InputBuffer->InputEvents) && (i < NumEventsToRead)) + { + Input = CONTAINING_RECORD(CurrentInput, ConsoleInput, ListEntry); + + *InputRecord = Input->InputEvent; + + if (!Unicode) + { + ConioInputEventToAnsi(InputBuffer->Header.Console, InputRecord); + } + + ++InputRecord; + ++i; + CurrentInput = CurrentInput->Flink; + + if (WaitForMoreEvents) // TRUE --> Read, we remove inputs from the buffer ; FALSE --> Peek, we keep inputs. + { + RemoveEntryList(&Input->ListEntry); + ConsoleFreeHeap(Input); + } + } + + if (NumEventsRead) *NumEventsRead = i; + + if (IsListEmpty(&InputBuffer->InputEvents)) + { + ResetEvent(InputBuffer->ActiveEvent); + } + + /* We read all the inputs available, we return success */ + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvWriteConsoleInput(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN Unicode, + IN PINPUT_RECORD InputRecord, + IN ULONG NumEventsToWrite, + OUT PULONG NumEventsWritten OPTIONAL) +{ + NTSTATUS Status = STATUS_SUCCESS; + ULONG i; + + if (Console == NULL || InputBuffer == NULL /* || InputRecord == NULL */) + return STATUS_INVALID_PARAMETER; + + /* Validity checks */ + ASSERT(Console == InputBuffer->Header.Console); + ASSERT( (InputRecord != NULL && NumEventsToWrite >= 0) || + (InputRecord == NULL && NumEventsToWrite == 0) ); + + // Do NOT do that !! Use the existing number of events already written, if any... + // if (NumEventsWritten) *NumEventsWritten = 0; + + for (i = (NumEventsWritten ? *NumEventsWritten : 0); i < NumEventsToWrite && NT_SUCCESS(Status); ++i) + { + if (InputRecord->EventType == KEY_EVENT && !Unicode) + { + CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar; + ConsoleInputAnsiCharToUnicodeChar(Console, + &InputRecord->Event.KeyEvent.uChar.UnicodeChar, + &AsciiChar); + } + + Status = ConioProcessInputEvent(Console, InputRecord++); + } + + if (NumEventsWritten) *NumEventsWritten = i; + + return Status; +} + +NTSTATUS NTAPI +ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer) +{ + PLIST_ENTRY CurrentEntry; + ConsoleInput* Event; + + if (Console == NULL || InputBuffer == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == InputBuffer->Header.Console); + + /* Discard all entries in the input event queue */ + while (!IsListEmpty(&InputBuffer->InputEvents)) + { + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); + Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + ConsoleFreeHeap(Event); + } + ResetEvent(InputBuffer->ActiveEvent); + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + OUT PULONG NumEvents) +{ + PLIST_ENTRY CurrentInput; + + if (Console == NULL || InputBuffer == NULL || NumEvents == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == InputBuffer->Header.Console); + + *NumEvents = 0; + + /* If there are any events ... */ + CurrentInput = InputBuffer->InputEvents.Flink; + while (CurrentInput != &InputBuffer->InputEvents) + { + CurrentInput = CurrentInput->Flink; + (*NumEvents)++; + } + + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/condrv/conoutput.c b/win32ss/user/winsrv/consrv/condrv/conoutput.c new file mode 100644 index 00000000000..03d5745f754 --- /dev/null +++ b/win32ss/user/winsrv/consrv/condrv/conoutput.c @@ -0,0 +1,287 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver DLL + * FILE: win32ss/user/winsrv/consrv/condrv/conoutput.c + * PURPOSE: General Console Output Functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "console.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "conoutput.h" +#include "handle.h" + +#define NDEBUG +#include + + +/* PRIVATE FUNCTIONS **********************************************************/ + +NTSTATUS +TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, + IN OUT PCONSOLE Console, + IN PTEXTMODE_BUFFER_INFO TextModeInfo); +NTSTATUS +GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, + IN OUT PCONSOLE Console, + IN PGRAPHICS_BUFFER_INFO GraphicsInfo); + +VOID +TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer); +VOID +GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer); + + +NTSTATUS +CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, + IN OUT PCONSOLE Console, + IN SIZE_T Size) +{ + if (Buffer == NULL || Console == NULL) + return STATUS_INVALID_PARAMETER; + + *Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, max(sizeof(CONSOLE_SCREEN_BUFFER), Size)); + if (*Buffer == NULL) return STATUS_INSUFFICIENT_RESOURCES; + + /* Initialize the header with the default type */ + ConSrvInitObject(&(*Buffer)->Header, SCREEN_BUFFER, Console); + (*Buffer)->Vtbl = NULL; + return STATUS_SUCCESS; +} + +VOID +CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer) +{ + if (Buffer->Header.Type == TEXTMODE_BUFFER) + TEXTMODE_BUFFER_Destroy(Buffer); + else if (Buffer->Header.Type == GRAPHICS_BUFFER) + GRAPHICS_BUFFER_Destroy(Buffer); + else if (Buffer->Header.Type == SCREEN_BUFFER) + ConsoleFreeHeap(Buffer); + // else + // do_nothing; +} + +// ConDrvCreateConsoleScreenBuffer +NTSTATUS FASTCALL +ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer, + IN OUT PCONSOLE Console, + IN ULONG BufferType, + IN PVOID ScreenBufferInfo) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if ( Console == NULL || Buffer == NULL || + (BufferType != CONSOLE_TEXTMODE_BUFFER && BufferType != CONSOLE_GRAPHICS_BUFFER) ) + { + return STATUS_INVALID_PARAMETER; + } + + if (BufferType == CONSOLE_TEXTMODE_BUFFER) + { + Status = TEXTMODE_BUFFER_Initialize(Buffer, + Console, + (PTEXTMODE_BUFFER_INFO)ScreenBufferInfo); + } + else if (BufferType == CONSOLE_GRAPHICS_BUFFER) + { + Status = GRAPHICS_BUFFER_Initialize(Buffer, + Console, + (PGRAPHICS_BUFFER_INFO)ScreenBufferInfo); + } + else + { + /* Never ever go there!! */ + ASSERT(FALSE); + } + + /* Insert the newly created screen buffer into the list, if succeeded */ + if (NT_SUCCESS(Status)) InsertHeadList(&Console->BufferList, &(*Buffer)->ListEntry); + + return Status; +} + +static VOID +ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); + +VOID WINAPI +ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer) +{ + PCONSOLE Console = Buffer->Header.Console; + PCONSOLE_SCREEN_BUFFER NewBuffer; + + RemoveEntryList(&Buffer->ListEntry); + if (Buffer == Console->ActiveBuffer) + { + /* Delete active buffer; switch to most recently created */ + Console->ActiveBuffer = NULL; + if (!IsListEmpty(&Console->BufferList)) + { + NewBuffer = CONTAINING_RECORD(Console->BufferList.Flink, + CONSOLE_SCREEN_BUFFER, + ListEntry); + ConioSetActiveScreenBuffer(NewBuffer); + } + } + + CONSOLE_SCREEN_BUFFER_Destroy(Buffer); +} + +VOID FASTCALL +ConioDrawConsole(PCONSOLE Console) +{ + SMALL_RECT Region; + PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; + + if (ActiveBuffer) + { + ConioInitRect(&Region, 0, 0, ActiveBuffer->ViewSize.Y - 1, ActiveBuffer->ViewSize.X - 1); + ConioDrawRegion(Console, &Region); + } +} + +static VOID +ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer) +{ + PCONSOLE Console = Buffer->Header.Console; + Console->ActiveBuffer = Buffer; + ConioResizeTerminal(Console); + // ConioDrawConsole(Console); +} + +NTSTATUS NTAPI +ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console, + IN PCONSOLE_SCREEN_BUFFER Buffer) +{ + if (Console == NULL || Buffer == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + if (Buffer == Console->ActiveBuffer) return STATUS_SUCCESS; + + /* If old buffer has no handles, it's now unreferenced */ + if (Console->ActiveBuffer->Header.HandleCount == 0) + { + ConioDeleteScreenBuffer(Console->ActiveBuffer); + } + + /* Tie console to new buffer */ + ConioSetActiveScreenBuffer(Buffer); + + return STATUS_SUCCESS; +} + +PCONSOLE_SCREEN_BUFFER +ConDrvGetActiveScreenBuffer(IN PCONSOLE Console) +{ + return (Console ? Console->ActiveBuffer : NULL); +} + +/* PUBLIC DRIVER APIS *********************************************************/ + +NTSTATUS NTAPI +ConDrvInvalidateBitMapRect(IN PCONSOLE Console, + IN PCONSOLE_SCREEN_BUFFER Buffer, + IN PSMALL_RECT Region) +{ + if (Console == NULL || Buffer == NULL || Region == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + /* If the output buffer is the current one, redraw the correct portion of the screen */ + if (Buffer == Console->ActiveBuffer) ConioDrawRegion(Console, Region); + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvGetConsoleCursorInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PCONSOLE_CURSOR_INFO CursorInfo) +{ + if (Console == NULL || Buffer == NULL || CursorInfo == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + *CursorInfo = Buffer->CursorInfo; + // CursorInfo->bVisible = Buffer->CursorInfo.bVisible; + // CursorInfo->dwSize = Buffer->CursorInfo.dwSize; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvSetConsoleCursorInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCONSOLE_CURSOR_INFO CursorInfo) +{ + ULONG Size; + BOOLEAN Visible, Success = TRUE; + + if (Console == NULL || Buffer == NULL || CursorInfo == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + Size = min(max(CursorInfo->dwSize, 1), 100); + Visible = CursorInfo->bVisible; + + if ( (Size != Buffer->CursorInfo.dwSize) || + (Visible && !Buffer->CursorInfo.bVisible) || + (!Visible && Buffer->CursorInfo.bVisible) ) + { + Buffer->CursorInfo.dwSize = Size; + Buffer->CursorInfo.bVisible = Visible; + + Success = ConioSetCursorInfo(Console, (PCONSOLE_SCREEN_BUFFER)Buffer); + } + + return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); +} + +NTSTATUS NTAPI +ConDrvSetConsoleCursorPosition(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCOORD Position) +{ + SHORT OldCursorX, OldCursorY; + + if (Console == NULL || Buffer == NULL || Position == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + if ( Position->X < 0 || Position->X >= Buffer->ScreenBufferSize.X || + Position->Y < 0 || Position->Y >= Buffer->ScreenBufferSize.Y ) + { + return STATUS_INVALID_PARAMETER; + } + + OldCursorX = Buffer->CursorPosition.X; + OldCursorY = Buffer->CursorPosition.Y; + Buffer->CursorPosition = *Position; + // Buffer->CursorPosition.X = Position->X; + // Buffer->CursorPosition.Y = Position->Y; + if ( ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) && + (!ConioSetScreenInfo(Console, (PCONSOLE_SCREEN_BUFFER)Buffer, OldCursorX, OldCursorY)) ) + { + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/condrv/console.c b/win32ss/user/winsrv/consrv/condrv/console.c new file mode 100644 index 00000000000..861c4721f74 --- /dev/null +++ b/win32ss/user/winsrv/consrv/condrv/console.c @@ -0,0 +1,1106 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver DLL + * FILE: win32ss/user/winsrv/consrv/condrv/console.c + * PURPOSE: Console Management Functions + * PROGRAMMERS: G van Geldorp + * Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "handle.h" +#include "procinit.h" +#include "alias.h" +#include "coninput.h" +#include "conoutput.h" +#include "lineinput.h" +#include "include/settings.h" + +#include "include/console.h" +#include "console.h" +#include "resource.h" + +#define NDEBUG +#include + +// FIXME: Add this prototype to winternl.h / rtlfuncs.h / ... +NTSTATUS NTAPI RtlGetLastNtStatus(VOID); + + +/* GLOBALS ********************************************************************/ + +static ULONG ConsoleListSize; +static PCONSOLE* ConsoleList; /* The list of all the allocated consoles */ +static RTL_RESOURCE ListLock; + +#define ConDrvLockConsoleListExclusive() \ + RtlAcquireResourceExclusive(&ListLock, TRUE) + +#define ConDrvLockConsoleListShared() \ + RtlAcquireResourceShared(&ListLock, TRUE) + +#define ConDrvUnlockConsoleList() \ + RtlReleaseResource(&ListLock) + +// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180 +static BOOLEAN +ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest, + IN PCWSTR Source) +{ + SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR); + if (Size > MAXUSHORT) return FALSE; + + UniDest->Buffer = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size); + if (UniDest->Buffer == NULL) return FALSE; + + RtlCopyMemory(UniDest->Buffer, Source, Size); + UniDest->MaximumLength = (USHORT)Size; + UniDest->Length = (USHORT)Size - sizeof(WCHAR); + + return TRUE; +} + +// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431 +static VOID +ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString) +{ + if (UnicodeString->Buffer) + { + ConsoleFreeHeap(UnicodeString->Buffer); + RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING)); + } +} + + +static NTSTATUS +InsertConsole(OUT PHANDLE Handle, + IN PCONSOLE Console) +{ +#define CONSOLE_HANDLES_INCREMENT 2 * 3 + + NTSTATUS Status = STATUS_SUCCESS; + ULONG i = 0; + PCONSOLE* Block; + + ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) || + (ConsoleList != NULL && ConsoleListSize != 0) ); + + /* All went right, so add the console to the list */ + ConDrvLockConsoleListExclusive(); + DPRINT1("Insert in the list\n"); + + if (ConsoleList) + { + for (i = 0; i < ConsoleListSize; i++) + { + if (ConsoleList[i] == NULL) break; + } + } + + if (i >= ConsoleListSize) + { + DPRINT1("Creation of a new handles table\n"); + /* Allocate a new handles table */ + Block = ConsoleAllocHeap(HEAP_ZERO_MEMORY, + (ConsoleListSize + + CONSOLE_HANDLES_INCREMENT) * sizeof(PCONSOLE)); + if (Block == NULL) + { + Status = STATUS_UNSUCCESSFUL; + goto Quit; + } + + /* If we previously had a handles table, free it and use the new one */ + if (ConsoleList) + { + /* Copy the handles from the old table to the new one */ + RtlCopyMemory(Block, + ConsoleList, + ConsoleListSize * sizeof(PCONSOLE)); + ConsoleFreeHeap(ConsoleList); + } + ConsoleList = Block; + ConsoleListSize += CONSOLE_HANDLES_INCREMENT; + } + + ConsoleList[i] = Console; + *Handle = ULongToHandle((i << 2) | 0x3); + +Quit: + /* Unlock the console list and return status */ + ConDrvUnlockConsoleList(); + return Status; +} + +/* Unused */ +#if 0 +static NTSTATUS +RemoveConsoleByHandle(IN HANDLE Handle) +{ + NTSTATUS Status = STATUS_SUCCESS; + ULONG Index = HandleToULong(Handle) >> 2; + PCONSOLE Console; + + ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) || + (ConsoleList != NULL && ConsoleListSize != 0) ); + + /* Remove the console from the list */ + ConDrvLockConsoleListExclusive(); + + if (Index >= ConsoleListSize || + (Console = ConsoleList[Index]) == NULL) + { + Status = STATUS_INVALID_HANDLE; + goto Quit; + } + + ConsoleList[Index] = NULL; + +Quit: + /* Unlock the console list and return status */ + ConDrvUnlockConsoleList(); + return Status; +} +#endif + +static NTSTATUS +RemoveConsoleByPointer(IN PCONSOLE Console) +{ + ULONG i = 0; + + if (!Console) return STATUS_INVALID_PARAMETER; + + ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) || + (ConsoleList != NULL && ConsoleListSize != 0) ); + + /* Remove the console from the list */ + ConDrvLockConsoleListExclusive(); + + if (ConsoleList) + { + for (i = 0; i < ConsoleListSize; i++) + { + if (ConsoleList[i] == Console) ConsoleList[i] = NULL; + } + } + + /* Unlock the console list */ + ConDrvUnlockConsoleList(); + + return STATUS_SUCCESS; +} + + +/* For resetting the frontend - defined in dummyfrontend.c */ +VOID ResetFrontEnd(IN PCONSOLE Console); + + +/* PRIVATE FUNCTIONS **********************************************************/ + +static NTSTATUS +ConDrvConsoleCtrlEventTimeout(IN ULONG Event, + IN PCONSOLE_PROCESS_DATA ProcessData, + IN ULONG Timeout) +{ + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("ConDrvConsoleCtrlEventTimeout Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess); + + if (ProcessData->CtrlDispatcher) + { + _SEH2_TRY + { + HANDLE Thread = NULL; + + _SEH2_TRY + { + Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0, + ProcessData->CtrlDispatcher, + UlongToPtr(Event), 0, NULL); + if (NULL == Thread) + { + Status = RtlGetLastNtStatus(); + DPRINT1("Failed thread creation, Status = 0x%08lx\n", Status); + } + else + { + DPRINT("ProcessData->CtrlDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process); + WaitForSingleObject(Thread, Timeout); + } + } + _SEH2_FINALLY + { + CloseHandle(Thread); + } + _SEH2_END; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + DPRINT1("ConDrvConsoleCtrlEventTimeout - Caught an exception, Status = 0x%08lx\n", Status); + } + _SEH2_END; + } + + return Status; +} + +static NTSTATUS +ConDrvConsoleCtrlEvent(IN ULONG Event, + IN PCONSOLE_PROCESS_DATA ProcessData) +{ + return ConDrvConsoleCtrlEventTimeout(Event, ProcessData, 0); +} + +VOID FASTCALL +ConioPause(PCONSOLE Console, UINT Flags) +{ + Console->PauseFlags |= Flags; + if (!Console->UnpauseEvent) + Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +VOID FASTCALL +ConioUnpause(PCONSOLE Console, UINT Flags) +{ + Console->PauseFlags &= ~Flags; + + // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0) + if (Console->PauseFlags == 0 && Console->UnpauseEvent) + { + SetEvent(Console->UnpauseEvent); + CloseHandle(Console->UnpauseEvent); + Console->UnpauseEvent = NULL; + + CsrNotifyWait(&Console->WriteWaitQueue, + WaitAll, + NULL, + NULL); + if (!IsListEmpty(&Console->WriteWaitQueue)) + { + CsrDereferenceWait(&Console->WriteWaitQueue); + } + } +} + + +/* + * Console accessibility check helpers + */ + +BOOLEAN NTAPI +ConDrvValidateConsoleState(IN PCONSOLE Console, + IN CONSOLE_STATE ExpectedState) +{ + // if (!Console) return FALSE; + + /* The console must be locked */ + // ASSERT(Console_locked); + + return (Console->State == ExpectedState); +} + +BOOLEAN NTAPI +ConDrvValidateConsoleUnsafe(IN PCONSOLE Console, + IN CONSOLE_STATE ExpectedState, + IN BOOLEAN LockConsole) +{ + if (!Console) return FALSE; + + /* + * Lock the console to forbid possible console's state changes + * (which must be done when the console is already locked). + * If we don't want to lock it, it's because the lock is already + * held. So there must be no problems. + */ + if (LockConsole) EnterCriticalSection(&Console->Lock); + + // ASSERT(Console_locked); + + /* Check whether the console's state is what we expect */ + if (!ConDrvValidateConsoleState(Console, ExpectedState)) + { + if (LockConsole) LeaveCriticalSection(&Console->Lock); + return FALSE; + } + + return TRUE; +} + +BOOLEAN NTAPI +ConDrvValidateConsole(OUT PCONSOLE* Console, + IN HANDLE ConsoleHandle, + IN CONSOLE_STATE ExpectedState, + IN BOOLEAN LockConsole) +{ + BOOLEAN RetVal = FALSE; + + ULONG Index = HandleToULong(ConsoleHandle) >> 2; + PCONSOLE ValidatedConsole; + + if (!Console) return FALSE; + *Console = NULL; + + /* + * Forbid creation or deletion of consoles when + * checking for the existence of a console. + */ + ConDrvLockConsoleListShared(); + + if (Index >= ConsoleListSize || + (ValidatedConsole = ConsoleList[Index]) == NULL) + { + /* Unlock the console list */ + ConDrvUnlockConsoleList(); + + return FALSE; + } + + ValidatedConsole = ConsoleList[Index]; + + /* Unlock the console list and return */ + ConDrvUnlockConsoleList(); + + RetVal = ConDrvValidateConsoleUnsafe(ValidatedConsole, + ExpectedState, + LockConsole); + if (RetVal) *Console = ValidatedConsole; + + return RetVal; +} + +NTSTATUS NTAPI +ConDrvGetConsole(OUT PCONSOLE* Console, + IN HANDLE ConsoleHandle, + IN BOOLEAN LockConsole) +{ + NTSTATUS Status = STATUS_INVALID_HANDLE; + PCONSOLE GrabConsole; + + if (Console == NULL) return STATUS_INVALID_PARAMETER; + *Console = NULL; + + if (ConDrvValidateConsole(&GrabConsole, + ConsoleHandle, + CONSOLE_RUNNING, + LockConsole)) + { + InterlockedIncrement(&GrabConsole->ReferenceCount); + *Console = GrabConsole; + Status = STATUS_SUCCESS; + } + + return Status; +} + +VOID NTAPI +ConDrvReleaseConsole(IN PCONSOLE Console, + IN BOOLEAN WasConsoleLocked) +{ + LONG RefCount = 0; + + if (!Console) return; + // if (Console->ReferenceCount == 0) return; // This shouldn't happen + ASSERT(Console->ReferenceCount > 0); + + /* The console must be locked */ + // ASSERT(Console_locked); + + /* + * Decrement the reference count. Save the new value too, + * because Console->ReferenceCount might be modified after + * the console gets unlocked but before we check whether we + * can destroy it. + */ + RefCount = _InterlockedDecrement(&Console->ReferenceCount); + + /* Unlock the console if needed */ + if (WasConsoleLocked) LeaveCriticalSection(&Console->Lock); + + /* Delete the console if needed */ + if (RefCount <= 0) ConDrvDeleteConsole(Console); +} + + +/* CONSOLE INITIALIZATION FUNCTIONS *******************************************/ + +VOID NTAPI +ConDrvInitConsoleSupport(VOID) +{ + DPRINT("CONSRV: ConDrvInitConsoleSupport()\n"); + + /* Initialize the console list and its lock */ + ConsoleListSize = 0; + ConsoleList = NULL; + RtlInitializeResource(&ListLock); + + /* Should call LoadKeyboardLayout */ +} + +NTSTATUS NTAPI +ConDrvInitConsole(OUT PHANDLE NewConsoleHandle, + OUT PCONSOLE* NewConsole, + IN PCONSOLE_INFO ConsoleInfo, + IN ULONG ConsoleLeaderProcessId) +{ + NTSTATUS Status; + SECURITY_ATTRIBUTES SecurityAttributes; + // CONSOLE_INFO CapturedConsoleInfo; + TEXTMODE_BUFFER_INFO ScreenBufferInfo; + HANDLE ConsoleHandle; + PCONSOLE Console; + PCONSOLE_SCREEN_BUFFER NewBuffer; + // WCHAR DefaultTitle[128]; + + if (NewConsoleHandle == NULL || NewConsole == NULL || ConsoleInfo == NULL) + return STATUS_INVALID_PARAMETER; + + *NewConsoleHandle = NULL; + *NewConsole = NULL; + + /* + * Allocate a console structure + */ + Console = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(CONSOLE)); + if (NULL == Console) + { + DPRINT1("Not enough memory for console creation.\n"); + return STATUS_NO_MEMORY; + } + + /* + * Load the console settings + */ + + /* 1. Load the default settings */ + // ConSrvGetDefaultSettings(ConsoleInfo, ProcessId); + + // /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */ + // Length = min(wcslen(ConsoleStartInfo->ConsoleTitle), + // sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1); + // wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length); + // ConsoleInfo.ConsoleTitle[Length] = L'\0'; + + /* + * 4. Load the remaining console settings via the registry. + */ +#if 0 + if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) + { + /* + * Either we weren't created by an app launched via a shell-link, + * or we failed to load shell-link console properties. + * Therefore, load the console infos for the application from the registry. + */ + ConSrvReadUserSettings(ConsoleInfo, ProcessId); + + /* + * Now, update them with the properties the user might gave to us + * via the STARTUPINFO structure before calling CreateProcess + * (and which was transmitted via the ConsoleStartInfo structure). + * We therefore overwrite the values read in the registry. + */ + if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE) + { + ConsoleInfo->ScreenAttrib = (USHORT)ConsoleStartInfo->FillAttribute; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS) + { + ConsoleInfo->ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE) + { + // ConsoleInfo->ConsoleSize = ConsoleStartInfo->ConsoleWindowSize; + ConsoleInfo->ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx; + ConsoleInfo->ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy; + } + } +#endif + + /* + * Fix the screen buffer size if needed. The rule is: + * ScreenBufferSize >= ConsoleSize + */ + if (ConsoleInfo->ScreenBufferSize.X < ConsoleInfo->ConsoleSize.X) + ConsoleInfo->ScreenBufferSize.X = ConsoleInfo->ConsoleSize.X; + if (ConsoleInfo->ScreenBufferSize.Y < ConsoleInfo->ConsoleSize.Y) + ConsoleInfo->ScreenBufferSize.Y = ConsoleInfo->ConsoleSize.Y; + + /* + * Initialize the console + */ + Console->State = CONSOLE_INITIALIZING; + Console->ReferenceCount = 0; + InitializeCriticalSection(&Console->Lock); + InitializeListHead(&Console->ProcessList); + + /* Initialize the frontend interface */ + ResetFrontEnd(Console); + + memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(ConsoleInfo->Colors)); + Console->ConsoleSize = ConsoleInfo->ConsoleSize; + Console->FixedSize = FALSE; // Value by default; is reseted by the front-ends if needed. + + /* + * Initialize the input buffer + */ + ConSrvInitObject(&Console->InputBuffer.Header, INPUT_BUFFER, Console); + + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.lpSecurityDescriptor = NULL; + SecurityAttributes.bInheritHandle = TRUE; + Console->InputBuffer.ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL); + if (NULL == Console->InputBuffer.ActiveEvent) + { + DeleteCriticalSection(&Console->Lock); + ConsoleFreeHeap(Console); + return STATUS_UNSUCCESSFUL; + } + + Console->InputBuffer.InputBufferSize = 0; // FIXME! + InitializeListHead(&Console->InputBuffer.InputEvents); + InitializeListHead(&Console->InputBuffer.ReadWaitQueue); + Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | + ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT; + + Console->QuickEdit = ConsoleInfo->QuickEdit; + Console->InsertMode = ConsoleInfo->InsertMode; + Console->LineBuffer = NULL; + Console->LineMaxSize = Console->LineSize = Console->LinePos = 0; + Console->LineComplete = Console->LineUpPressed = Console->LineInsertToggle = FALSE; + // LineWakeupMask + + // FIXME: This is terminal-specific !! VV + RtlZeroMemory(&Console->Selection, sizeof(CONSOLE_SELECTION_INFO)); + Console->Selection.dwFlags = CONSOLE_NO_SELECTION; + // dwSelectionCursor + + /* Set-up the code page */ + Console->CodePage = Console->OutputCodePage = ConsoleInfo->CodePage; + + /* Initialize a new text-mode screen buffer with default settings */ + ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize; + ScreenBufferInfo.ScreenAttrib = ConsoleInfo->ScreenAttrib; + ScreenBufferInfo.PopupAttrib = ConsoleInfo->PopupAttrib; + ScreenBufferInfo.IsCursorVisible = TRUE; + ScreenBufferInfo.CursorSize = ConsoleInfo->CursorSize; + + InitializeListHead(&Console->BufferList); + Status = ConDrvCreateScreenBuffer(&NewBuffer, + Console, + CONSOLE_TEXTMODE_BUFFER, + &ScreenBufferInfo); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ConDrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status); + CloseHandle(Console->InputBuffer.ActiveEvent); + DeleteCriticalSection(&Console->Lock); + ConsoleFreeHeap(Console); + return Status; + } + /* Make the new screen buffer active */ + Console->ActiveBuffer = NewBuffer; + InitializeListHead(&Console->WriteWaitQueue); + Console->PauseFlags = 0; + Console->UnpauseEvent = NULL; + + /* + * Initialize the alias and history buffers + */ + Console->Aliases = NULL; + InitializeListHead(&Console->HistoryBuffers); + Console->HistoryBufferSize = ConsoleInfo->HistoryBufferSize; + Console->NumberOfHistoryBuffers = ConsoleInfo->NumberOfHistoryBuffers; + Console->HistoryNoDup = ConsoleInfo->HistoryNoDup; + + /* Initialize the console title */ + ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo->ConsoleTitle); + // if (ConsoleInfo.ConsoleTitle[0] == L'\0') + // { + // if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, DefaultTitle, sizeof(DefaultTitle) / sizeof(DefaultTitle[0]))) + // { + // ConsoleCreateUnicodeString(&Console->Title, DefaultTitle); + // } + // else + // { + // ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console"); + // } + // } + // else + // { + ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo->ConsoleTitle); + // } + + /* Lock the console until its initialization is finished */ + // EnterCriticalSection(&Console->Lock); + + DPRINT("Console initialized\n"); + + /* All went right, so add the console to the list */ + Status = InsertConsole(&ConsoleHandle, Console); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + ConDrvDeleteConsole(Console); + return Status; + } + + /* The initialization is finished */ + DPRINT("Change state\n"); + Console->State = CONSOLE_RUNNING; + + /* Unlock the console */ + // LeaveCriticalSection(&Console->Lock); + + /* Return the newly created console to the caller and a success code too */ + *NewConsoleHandle = ConsoleHandle; + *NewConsole = Console; + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvRegisterFrontEnd(IN PCONSOLE Console, + IN PFRONTEND FrontEnd) +{ + NTSTATUS Status; + + if (Console == NULL || FrontEnd == NULL) + return STATUS_INVALID_PARAMETER; + + /* FIXME: Lock the console before ?? */ + + /* + * Attach the frontend to the console. Use now the TermIFace of the console, + * and not the user-defined temporary FrontEnd pointer. + */ + Console->TermIFace = *FrontEnd; + Console->TermIFace.Console = Console; + + /* Initialize the frontend AFTER having attached it to the console */ + DPRINT("Finish initialization of frontend\n"); + Status = Console->TermIFace.Vtbl->InitFrontEnd(&Console->TermIFace, Console); + if (!NT_SUCCESS(Status)) + { + DPRINT1("FrontEnd initialization failed, Status = 0x%08lx\n", Status); + + /* We failed, detach the frontend from the console */ + FrontEnd->Console = NULL; // For the caller + ResetFrontEnd(Console); + + return Status; + } + + /* Copy buffer contents to screen */ + // FrontEnd.Draw(); + // ConioDrawConsole(Console); + DPRINT("Console drawn\n"); + + DPRINT("Terminal FrontEnd initialization done\n"); + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvDeregisterFrontEnd(IN PCONSOLE Console) +{ + if (Console == NULL) return STATUS_INVALID_PARAMETER; + + /* FIXME: Lock the console before ?? */ + + /* Deinitialize the frontend BEFORE detaching it from the console */ + Console->TermIFace.Vtbl->DeinitFrontEnd(&Console->TermIFace/*, Console*/); + + /* + * Detach the frontend from the console: + * reinitialize the frontend interface. + */ + ResetFrontEnd(Console); + + DPRINT("Terminal FrontEnd unregistered\n"); + return STATUS_SUCCESS; +} + +VOID NTAPI +ConDrvDeleteConsole(IN PCONSOLE Console) +{ + DPRINT("ConDrvDeleteConsole(0x%p)\n", Console); + + /* + * Forbid validation of any console by other threads + * during the deletion of this console. + */ + ConDrvLockConsoleListExclusive(); + + /* + * If the console is already being destroyed, i.e. not running + * or finishing to be initialized, just return. + */ + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE) && + !ConDrvValidateConsoleUnsafe(Console, CONSOLE_INITIALIZING, TRUE)) + { + /* Unlock the console list and return */ + ConDrvUnlockConsoleList(); + return; + } + + /* + * We are about to be destroyed. Signal it to other people + * so that they can terminate what they are doing, and that + * they cannot longer validate the console. + */ + Console->State = CONSOLE_TERMINATING; + + /* + * Allow other threads to finish their job: basically, unlock + * all other calls to EnterCriticalSection(&Console->Lock); by + * ConDrvValidateConsole(Unsafe) functions so that they just see + * that we are not in CONSOLE_RUNNING state anymore, or unlock + * other concurrent calls to ConDrvDeleteConsole so that they + * can see that we are in fact already deleting the console. + */ + LeaveCriticalSection(&Console->Lock); + ConDrvUnlockConsoleList(); + + /* FIXME: Send a terminate message to all the processes owning this console */ + + /* Cleanup the UI-oriented part */ + DPRINT("Deregister console\n"); + ConDrvDeregisterFrontEnd(Console); + DPRINT("Console deregistered\n"); + + /*** + * Check that the console is in terminating state before continuing + * (the cleanup code must not change the state of the console... + * ...unless to cancel console deletion ?). + ***/ + + ConDrvLockConsoleListExclusive(); + + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_TERMINATING, TRUE)) + { + ConDrvUnlockConsoleList(); + return; + } + + /* We are now in destruction */ + Console->State = CONSOLE_IN_DESTRUCTION; + + /* We really delete the console. Reset the count to be sure. */ + Console->ReferenceCount = 0; + + /* Remove the console from the list */ + RemoveConsoleByPointer(Console); + + /* Discard all entries in the input event queue */ + PurgeInputBuffer(Console); + + if (Console->LineBuffer) ConsoleFreeHeap(Console->LineBuffer); + + IntDeleteAllAliases(Console); + HistoryDeleteBuffers(Console); + + ConioDeleteScreenBuffer(Console->ActiveBuffer); + Console->ActiveBuffer = NULL; + if (!IsListEmpty(&Console->BufferList)) + { + DPRINT1("BUG: screen buffer list not empty\n"); + ASSERT(FALSE); + } + + /**/ CloseHandle(Console->InputBuffer.ActiveEvent); /**/ + if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); + + ConsoleFreeUnicodeString(&Console->OriginalTitle); + ConsoleFreeUnicodeString(&Console->Title); + + DPRINT("ConDrvDeleteConsole - Unlocking\n"); + LeaveCriticalSection(&Console->Lock); + DPRINT("ConDrvDeleteConsole - Destroying lock\n"); + DeleteCriticalSection(&Console->Lock); + DPRINT("ConDrvDeleteConsole - Lock destroyed ; freeing console\n"); + + ConsoleFreeHeap(Console); + DPRINT("ConDrvDeleteConsole - Console destroyed\n"); + + /* Unlock the console list and return */ + ConDrvUnlockConsoleList(); +} + + +/* PUBLIC DRIVER APIS *********************************************************/ + +NTSTATUS NTAPI +ConDrvGetConsoleMode(IN PCONSOLE Console, + IN PCONSOLE_IO_OBJECT Object, + OUT PULONG ConsoleMode) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (Console == NULL || Object == NULL || ConsoleMode == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Object->Console); + + /*** FIXME: */ *ConsoleMode = 0; /***/ + + if (INPUT_BUFFER == Object->Type) + { + PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; + + *ConsoleMode = InputBuffer->Mode; + + if (Console->QuickEdit || Console->InsertMode) + { + // Windows does this, even if it's not documented on MSDN + *ConsoleMode |= ENABLE_EXTENDED_FLAGS; + + if (Console->QuickEdit ) *ConsoleMode |= ENABLE_QUICK_EDIT_MODE; + if (Console->InsertMode) *ConsoleMode |= ENABLE_INSERT_MODE; + } + } + else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type) + { + PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; + *ConsoleMode = Buffer->Mode; + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleMode(IN PCONSOLE Console, + IN PCONSOLE_IO_OBJECT Object, + IN ULONG ConsoleMode) +{ +#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE ) +#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \ + ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \ + ENABLE_MOUSE_INPUT ) +#define CONSOLE_VALID_OUTPUT_MODES ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT ) + + NTSTATUS Status = STATUS_SUCCESS; + + if (Console == NULL || Object == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Object->Console); + + if (INPUT_BUFFER == Object->Type) + { + PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; + + DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode); + + /* + * 1. Only the presence of valid mode flags is allowed. + */ + if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES | CONSOLE_VALID_CONTROL_MODES)) + { + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + + /* + * 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS, + * then consider the flags invalid. + * + if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) && + (ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 ) + { + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + */ + + /* + * 3. Now we can continue. + */ + if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) + { + Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE); + Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE); + } + InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES); + } + else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type) + { + PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; + + DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode); + + if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + Buffer->Mode = (ConsoleMode & CONSOLE_VALID_OUTPUT_MODES); + } + } + else + { + Status = STATUS_INVALID_HANDLE; + } + +Quit: + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleTitle(IN PCONSOLE Console, + IN OUT PWCHAR Title, + IN OUT PULONG BufLength) +{ + ULONG Length; + + if (Console == NULL || Title == NULL || BufLength == NULL) + return STATUS_INVALID_PARAMETER; + + /* Copy title of the console to the user title buffer */ + if (*BufLength >= sizeof(WCHAR)) + { + Length = min(*BufLength - sizeof(WCHAR), Console->Title.Length); + RtlCopyMemory(Title, Console->Title.Buffer, Length); + Title[Length / sizeof(WCHAR)] = L'\0'; + } + + *BufLength = Console->Title.Length; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvSetConsoleTitle(IN PCONSOLE Console, + IN PWCHAR Title, + IN ULONG BufLength) +{ + PWCHAR Buffer; + + if (Console == NULL || Title == NULL) + return STATUS_INVALID_PARAMETER; + + /* Allocate a new buffer to hold the new title (NULL-terminated) */ + Buffer = ConsoleAllocHeap(0, BufLength + sizeof(WCHAR)); + if (!Buffer) return STATUS_NO_MEMORY; + + /* Free the old title */ + ConsoleFreeUnicodeString(&Console->Title); + + /* Copy title to console */ + Console->Title.Buffer = Buffer; + Console->Title.Length = BufLength; + Console->Title.MaximumLength = Console->Title.Length + sizeof(WCHAR); + RtlCopyMemory(Console->Title.Buffer, Title, Console->Title.Length); + Console->Title.Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; + + // ConioChangeTitle(Console); + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvGetConsoleCP(IN PCONSOLE Console, + OUT PUINT CodePage, + IN BOOLEAN InputCP) +{ + if (Console == NULL || CodePage == NULL) + return STATUS_INVALID_PARAMETER; + + *CodePage = (InputCP ? Console->CodePage : Console->OutputCodePage); + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvSetConsoleCP(IN PCONSOLE Console, + IN UINT CodePage, + IN BOOLEAN InputCP) +{ + if (Console == NULL || !IsValidCodePage(CodePage)) + return STATUS_INVALID_PARAMETER; + + if (InputCP) + Console->CodePage = CodePage; + else + Console->OutputCodePage = CodePage; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvGetConsoleProcessList(IN PCONSOLE Console, + IN OUT PULONG ProcessIdsList, + IN ULONG MaxIdListItems, + OUT PULONG ProcessIdsTotal) +{ + PCONSOLE_PROCESS_DATA current; + PLIST_ENTRY current_entry; + + if (Console == NULL || ProcessIdsList == NULL || ProcessIdsTotal == NULL) + return STATUS_INVALID_PARAMETER; + + *ProcessIdsTotal = 0; + + for (current_entry = Console->ProcessList.Flink; + current_entry != &Console->ProcessList; + current_entry = current_entry->Flink) + { + current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink); + if (++(*ProcessIdsTotal) <= MaxIdListItems) + { + *ProcessIdsList++ = HandleToUlong(current->Process->ClientId.UniqueProcess); + } + } + + return STATUS_SUCCESS; +} + +// ConDrvGenerateConsoleCtrlEvent +NTSTATUS NTAPI +ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console, + IN ULONG ProcessGroupId, + IN ULONG Event) +{ + NTSTATUS Status = STATUS_SUCCESS; + PLIST_ENTRY current_entry; + PCONSOLE_PROCESS_DATA current; + + /* If the console is already being destroyed, just return */ + if (!ConDrvValidateConsoleState(Console, CONSOLE_RUNNING)) + return STATUS_UNSUCCESSFUL; + + /* + * Loop through the process list, from the most recent process + * (the active one) to the oldest one (the first created, i.e. + * the console leader process), and for each, send an event + * (new processes are inserted at the head of the console process list). + */ + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) + { + current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink); + current_entry = current_entry->Flink; + + /* + * Only processes belonging to the same process group are signaled. + * If the process group ID is zero, then all the processes are signaled. + */ + if (ProcessGroupId == 0 || current->Process->ProcessGroupId == ProcessGroupId) + { + Status = ConDrvConsoleCtrlEvent(Event, current); + } + } + + return Status; +} + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/condrv/dummyfrontend.c b/win32ss/user/winsrv/consrv/condrv/dummyfrontend.c new file mode 100644 index 00000000000..fe8c43fc36c --- /dev/null +++ b/win32ss/user/winsrv/consrv/condrv/dummyfrontend.c @@ -0,0 +1,185 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/condrv/dummyfrontend.c + * PURPOSE: Dummy Terminal Front-End used when no frontend + * is attached to the specified console. + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" + + +/* DUMMY FRONTEND INTERFACE ***************************************************/ + +static NTSTATUS NTAPI +DummyInitFrontEnd(IN OUT PFRONTEND This, + IN PCONSOLE Console) +{ + /* Load some settings ?? */ + return STATUS_SUCCESS; +} + +static VOID NTAPI +DummyDeinitFrontEnd(IN OUT PFRONTEND This) +{ + /* Free some settings ?? */ +} + +static VOID NTAPI +DummyDrawRegion(IN OUT PFRONTEND This, + SMALL_RECT* Region) +{ +} + +static VOID NTAPI +DummyWriteStream(IN OUT PFRONTEND This, + SMALL_RECT* Region, + SHORT CursorStartX, + SHORT CursorStartY, + UINT ScrolledLines, + PWCHAR Buffer, + UINT Length) +{ +} + +static BOOL NTAPI +DummySetCursorInfo(IN OUT PFRONTEND This, + PCONSOLE_SCREEN_BUFFER Buff) +{ + return TRUE; +} + +static BOOL NTAPI +DummySetScreenInfo(IN OUT PFRONTEND This, + PCONSOLE_SCREEN_BUFFER Buff, + SHORT OldCursorX, + SHORT OldCursorY) +{ + return TRUE; +} + +static VOID NTAPI +DummyResizeTerminal(IN OUT PFRONTEND This) +{ +} + +static BOOL NTAPI +DummyProcessKeyCallback(IN OUT PFRONTEND This, + MSG* msg, + BYTE KeyStateMenu, + DWORD ShiftState, + UINT VirtualKeyCode, + BOOL Down) +{ + return FALSE; +} + +static VOID NTAPI +DummyRefreshInternalInfo(IN OUT PFRONTEND This) +{ +} + +static VOID NTAPI +DummyChangeTitle(IN OUT PFRONTEND This) +{ +} + +static BOOL NTAPI +DummyChangeIcon(IN OUT PFRONTEND This, + HICON hWindowIcon) +{ + return TRUE; +} + +static HWND NTAPI +DummyGetConsoleWindowHandle(IN OUT PFRONTEND This) +{ + return NULL; +} + +static VOID NTAPI +DummyGetLargestConsoleWindowSize(IN OUT PFRONTEND This, + PCOORD pSize) +{ +} + +static ULONG NTAPI +DummyGetDisplayMode(IN OUT PFRONTEND This) +{ + return 0; +} + +static BOOL NTAPI +DummySetDisplayMode(IN OUT PFRONTEND This, + ULONG NewMode) +{ + return TRUE; +} + +static INT NTAPI +DummyShowMouseCursor(IN OUT PFRONTEND This, + BOOL Show) +{ + return 0; +} + +static BOOL NTAPI +DummySetMouseCursor(IN OUT PFRONTEND This, + HCURSOR hCursor) +{ + return TRUE; +} + +static HMENU NTAPI +DummyMenuControl(IN OUT PFRONTEND This, + UINT cmdIdLow, + UINT cmdIdHigh) +{ + return NULL; +} + +static BOOL NTAPI +DummySetMenuClose(IN OUT PFRONTEND This, + BOOL Enable) +{ + return TRUE; +} + +static FRONTEND_VTBL DummyVtbl = +{ + DummyInitFrontEnd, + DummyDeinitFrontEnd, + DummyDrawRegion, + DummyWriteStream, + DummySetCursorInfo, + DummySetScreenInfo, + DummyResizeTerminal, + DummyProcessKeyCallback, + DummyRefreshInternalInfo, + DummyChangeTitle, + DummyChangeIcon, + DummyGetConsoleWindowHandle, + DummyGetLargestConsoleWindowSize, + DummyGetDisplayMode, + DummySetDisplayMode, + DummyShowMouseCursor, + DummySetMouseCursor, + DummyMenuControl, + DummySetMenuClose, +}; + +VOID +ResetFrontEnd(IN PCONSOLE Console) +{ + if (!Console) return; + + /* Reinitialize the frontend interface */ + RtlZeroMemory(&Console->TermIFace, sizeof(Console->TermIFace)); + Console->TermIFace.Vtbl = &DummyVtbl; +} + +/* EOF */ diff --git a/win32ss/user/consrv/graphics.c b/win32ss/user/winsrv/consrv/condrv/graphics.c similarity index 98% rename from win32ss/user/consrv/graphics.c rename to win32ss/user/winsrv/consrv/condrv/graphics.c index 51b6e79b599..7c1f070c734 100644 --- a/win32ss/user/consrv/graphics.c +++ b/win32ss/user/winsrv/consrv/condrv/graphics.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/graphics.c + * PROJECT: ReactOS Console Driver DLL + * FILE: win32ss/user/winsrv/consrv/condrv/graphics.c * PURPOSE: Console Output Functions for graphics-mode screen-buffers * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) * @@ -13,7 +13,7 @@ #include "consrv.h" #include "include/conio.h" -#include "conio.h" +#include "include/conio2.h" #include "conoutput.h" #include "handle.h" diff --git a/win32ss/user/consrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c similarity index 53% rename from win32ss/user/consrv/text.c rename to win32ss/user/winsrv/consrv/condrv/text.c index 314965c6643..f6b3b507b4a 100644 --- a/win32ss/user/consrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/text.c + * PROJECT: ReactOS Console Driver DLL + * FILE: win32ss/user/winsrv/consrv/condrv/text.c * PURPOSE: Console Output Functions for text-mode screen-buffers * PROGRAMMERS: Jeffrey Morlan * Hermes Belusca-Maito (hermes.belusca@sfr.fr) @@ -11,19 +11,13 @@ #include "consrv.h" #include "include/conio.h" -#include "conio.h" +#include "include/conio2.h" #include "conoutput.h" #include "handle.h" #define NDEBUG #include -/* -// Define wmemset(...) -#include -#define HAVE_WMEMSET -*/ - /* GLOBALS ********************************************************************/ @@ -152,10 +146,10 @@ ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff) } } -static __inline BOOLEAN ConioGetIntersection( - SMALL_RECT* Intersection, - SMALL_RECT* Rect1, - SMALL_RECT* Rect2) +static __inline BOOLEAN +ConioGetIntersection(OUT PSMALL_RECT Intersection, + IN PSMALL_RECT Rect1, + IN PSMALL_RECT Rect2) { if ( ConioIsRectEmpty(Rect1) || ConioIsRectEmpty(Rect2) || @@ -170,18 +164,18 @@ static __inline BOOLEAN ConioGetIntersection( } ConioInitRect(Intersection, - max(Rect1->Top, Rect2->Top), - max(Rect1->Left, Rect2->Left), + max(Rect1->Top , Rect2->Top ), + max(Rect1->Left , Rect2->Left ), min(Rect1->Bottom, Rect2->Bottom), - min(Rect1->Right, Rect2->Right)); + min(Rect1->Right , Rect2->Right )); return TRUE; } -static __inline BOOLEAN ConioGetUnion( - SMALL_RECT* Union, - SMALL_RECT* Rect1, - SMALL_RECT* Rect2) +static __inline BOOLEAN +ConioGetUnion(OUT PSMALL_RECT Union, + IN PSMALL_RECT Rect1, + IN PSMALL_RECT Rect2) { if (ConioIsRectEmpty(Rect1)) { @@ -202,17 +196,20 @@ static __inline BOOLEAN ConioGetUnion( else { ConioInitRect(Union, - min(Rect1->Top, Rect2->Top), - min(Rect1->Left, Rect2->Left), + min(Rect1->Top , Rect2->Top ), + min(Rect1->Left , Rect2->Left ), max(Rect1->Bottom, Rect2->Bottom), - max(Rect1->Right, Rect2->Right)); + max(Rect1->Right , Rect2->Right )); } return TRUE; } static VOID FASTCALL -ConioComputeUpdateRect(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCOORD Start, UINT Length) +ConioComputeUpdateRect(IN PTEXTMODE_SCREEN_BUFFER Buff, + IN OUT PSMALL_RECT UpdateRect, + IN PCOORD Start, + IN UINT Length) { if (Buff->ScreenBufferSize.X <= Start->X + Length) { @@ -244,9 +241,9 @@ ConioComputeUpdateRect(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, PCO */ static VOID FASTCALL ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer, - SMALL_RECT* SrcRegion, - SMALL_RECT* DstRegion, - SMALL_RECT* ClipRegion, + PSMALL_RECT SrcRegion, + PSMALL_RECT DstRegion, + PSMALL_RECT ClipRegion, CHAR_INFO FillChar) { int Width = ConioRectWidth(SrcRegion); @@ -320,13 +317,10 @@ ConioResizeBuffer(PCONSOLE Console, PCHAR_INFO Buffer; DWORD Offset = 0; PCHAR_INFO ptr; + WORD CurrentAttribute; USHORT CurrentY; PCHAR_INFO OldBuffer; -#ifdef HAVE_WMEMSET - USHORT value = MAKEWORD(' ', ScreenBuffer->ScreenDefaultAttrib); -#else DWORD i; -#endif DWORD diff; /* Buffer size is not allowed to be smaller than the view size */ @@ -371,28 +365,29 @@ ConioResizeBuffer(PCONSOLE Console, RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO)); Offset += ScreenBuffer->ScreenBufferSize.X; + /* The attribute to be used is the one of the last cell of the current line */ + CurrentAttribute = ConioCoordToPointer(ScreenBuffer, + ScreenBuffer->ScreenBufferSize.X - 1, + CurrentY)->Attributes; + diff = Size.X - ScreenBuffer->ScreenBufferSize.X; - /* Zero new part of it */ -#ifdef HAVE_WMEMSET - wmemset((PWCHAR)&Buffer[Offset], value, diff); -#else + + /* Zero-out the new part of the buffer */ for (i = 0; i < diff; i++) { ptr = Buffer + Offset; ptr->Char.UnicodeChar = L' '; - ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; + ptr->Attributes = CurrentAttribute; ++Offset; } -#endif } } if (Size.Y > ScreenBuffer->ScreenBufferSize.Y) { diff = Size.X * (Size.Y - ScreenBuffer->ScreenBufferSize.Y); -#ifdef HAVE_WMEMSET - wmemset((PWCHAR)&Buffer[Offset], value, diff); -#else + + /* Zero-out the new part of the buffer */ for (i = 0; i < diff; i++) { ptr = Buffer + Offset; @@ -400,7 +395,6 @@ ConioResizeBuffer(PCONSOLE Console, ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; ++Offset; } -#endif } (void)InterlockedExchangePointer((PVOID volatile*)&ScreenBuffer->Buffer, Buffer); @@ -435,7 +429,7 @@ ConioResizeBuffer(PCONSOLE Console, } static VOID FASTCALL -ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* UpdateRect, UINT *ScrolledLines) +ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines) { /* If we hit bottom, slide the viewable screen */ if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y) @@ -597,208 +591,66 @@ ConioWriteConsole(PCONSOLE Console, return STATUS_SUCCESS; } -static NTSTATUS -DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, - IN PCSR_THREAD ClientThread, - IN BOOL CreateWaitBlock OPTIONAL); -// Wait function CSR_WAIT_FUNCTION -static BOOLEAN -WriteConsoleThread(IN PLIST_ENTRY WaitList, - IN PCSR_THREAD WaitThread, - IN PCSR_API_MESSAGE WaitApiMessage, - IN PVOID WaitContext, - IN PVOID WaitArgument1, - IN PVOID WaitArgument2, - IN ULONG WaitFlags) +/* PUBLIC DRIVER APIS *********************************************************/ + +NTSTATUS NTAPI +ConDrvReadConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + OUT PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT ReadRegion) { - NTSTATUS Status; - - DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); - - /* - * If we are notified of the process termination via a call - * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or - * CsrDestroyThread, just return. - */ - if (WaitFlags & CsrProcessTerminating) - { - Status = STATUS_THREAD_IS_TERMINATING; - goto Quit; - } - - Status = DoWriteConsole(WaitApiMessage, - WaitThread, - FALSE); - -Quit: - if (Status != STATUS_PENDING) - { - WaitApiMessage->Status = Status; - } - - return (Status == STATUS_PENDING ? FALSE : TRUE); -} - -static NTSTATUS -DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, - IN PCSR_THREAD ClientThread, - IN BOOL CreateWaitBlock OPTIONAL) -{ - NTSTATUS Status = STATUS_SUCCESS; - PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - PVOID Buffer; - DWORD Written = 0; - ULONG Length; - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process), WriteConsoleRequest->OutputHandle, &Buff, GENERIC_WRITE, FALSE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) - if (Console->PauseFlags && Console->UnpauseEvent != NULL) - { - if (CreateWaitBlock) - { - if (!CsrCreateWait(&Console->WriteWaitQueue, - WriteConsoleThread, - ClientThread, - ApiMessage, - NULL, - NULL)) - { - /* Fail */ - ConSrvReleaseScreenBuffer(Buff, FALSE); - return STATUS_NO_MEMORY; - } - } - - /* Wait until we un-pause the console */ - Status = STATUS_PENDING; - } - else - { - if (WriteConsoleRequest->Unicode) - { - Buffer = WriteConsoleRequest->Buffer; - } - else - { - Length = MultiByteToWideChar(Console->OutputCodePage, 0, - (PCHAR)WriteConsoleRequest->Buffer, - WriteConsoleRequest->NrCharactersToWrite, - NULL, 0); - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); - if (Buffer) - { - MultiByteToWideChar(Console->OutputCodePage, 0, - (PCHAR)WriteConsoleRequest->Buffer, - WriteConsoleRequest->NrCharactersToWrite, - (PWCHAR)Buffer, Length); - } - else - { - Status = STATUS_NO_MEMORY; - } - } - - if (Buffer) - { - if (NT_SUCCESS(Status)) - { - Status = ConioWriteConsole(Console, - Buff, - Buffer, - WriteConsoleRequest->NrCharactersToWrite, - TRUE); - if (NT_SUCCESS(Status)) - { - Written = WriteConsoleRequest->NrCharactersToWrite; - } - } - - if (!WriteConsoleRequest->Unicode) - RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); - } - - WriteConsoleRequest->NrCharactersWritten = Written; - } - - ConSrvReleaseScreenBuffer(Buff, FALSE); - return Status; -} - - -/* PUBLIC SERVER APIS *********************************************************/ - -CSR_API(SrvReadConsoleOutput) -{ - PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); - PCHAR_INFO CharInfo; PCHAR_INFO CurCharInfo; - PTEXTMODE_SCREEN_BUFFER Buff; SHORT SizeX, SizeY; - NTSTATUS Status; - COORD BufferSize; - COORD BufferCoord; - SMALL_RECT ReadRegion; + SMALL_RECT CapturedReadRegion; SMALL_RECT ScreenRect; DWORD i; PCHAR_INFO Ptr; LONG X, Y; UINT CodePage; - DPRINT("SrvReadConsoleOutput\n"); - - CharInfo = ReadOutputRequest->CharInfo; - ReadRegion = ReadOutputRequest->ReadRegion; - BufferSize = ReadOutputRequest->BufferSize; - BufferCoord = ReadOutputRequest->BufferCoord; - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&ReadOutputRequest->CharInfo, - BufferSize.X * BufferSize.Y, - sizeof(CHAR_INFO))) + if (Console == NULL || Buffer == NULL || CharInfo == NULL || + BufferSize == NULL || BufferCoord == NULL || ReadRegion == NULL) { return STATUS_INVALID_PARAMETER; } - Status = ConSrvGetTextModeBuffer(ProcessData, ReadOutputRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + CapturedReadRegion = *ReadRegion; /* FIXME: Is this correct? */ - CodePage = ProcessData->Console->OutputCodePage; + CodePage = Console->OutputCodePage; - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&ReadRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&ReadRegion)); - ReadRegion.Bottom = ReadRegion.Top + SizeY; - ReadRegion.Right = ReadRegion.Left + SizeX; + SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedReadRegion)); + SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedReadRegion)); + CapturedReadRegion.Right = CapturedReadRegion.Left + SizeX; + CapturedReadRegion.Bottom = CapturedReadRegion.Top + SizeY; - ConioInitRect(&ScreenRect, 0, 0, Buff->ScreenBufferSize.Y, Buff->ScreenBufferSize.X); - if (!ConioGetIntersection(&ReadRegion, &ScreenRect, &ReadRegion)) + ConioInitRect(&ScreenRect, 0, 0, Buffer->ScreenBufferSize.Y, Buffer->ScreenBufferSize.X); + if (!ConioGetIntersection(&CapturedReadRegion, &ScreenRect, &CapturedReadRegion)) { - ConSrvReleaseScreenBuffer(Buff, TRUE); return STATUS_SUCCESS; } - for (i = 0, Y = ReadRegion.Top; Y < ReadRegion.Bottom; ++i, ++Y) + for (i = 0, Y = CapturedReadRegion.Top; Y < CapturedReadRegion.Bottom; ++i, ++Y) { - CurCharInfo = CharInfo + (i * BufferSize.X); + CurCharInfo = CharInfo + (i * BufferSize->X); - Ptr = ConioCoordToPointer(Buff, ReadRegion.Left, Y); - for (X = ReadRegion.Left; X < ReadRegion.Right; ++X) + Ptr = ConioCoordToPointer(Buffer, CapturedReadRegion.Left, Y); + for (X = CapturedReadRegion.Left; X < CapturedReadRegion.Right; ++X) { - if (ReadOutputRequest->Unicode) + if (Unicode) { CurCharInfo->Char.UnicodeChar = Ptr->Char.UnicodeChar; } else { - // ConsoleUnicodeCharToAnsiChar(ProcessData->Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar); + // ConsoleUnicodeCharToAnsiChar(Console, &CurCharInfo->Char.AsciiChar, &Ptr->Char.UnicodeChar); WideCharToMultiByte(CodePage, 0, &Ptr->Char.UnicodeChar, 1, &CurCharInfo->Char.AsciiChar, 1, NULL, NULL); } @@ -808,81 +660,64 @@ CSR_API(SrvReadConsoleOutput) } } - ConSrvReleaseScreenBuffer(Buff, TRUE); - - ReadOutputRequest->ReadRegion.Right = ReadRegion.Left + SizeX - 1; - ReadOutputRequest->ReadRegion.Bottom = ReadRegion.Top + SizeY - 1; - ReadOutputRequest->ReadRegion.Left = ReadRegion.Left; - ReadOutputRequest->ReadRegion.Top = ReadRegion.Top; + ReadRegion->Left = CapturedReadRegion.Left; + ReadRegion->Top = CapturedReadRegion.Top ; + ReadRegion->Right = CapturedReadRegion.Left + SizeX - 1; + ReadRegion->Bottom = CapturedReadRegion.Top + SizeY - 1; return STATUS_SUCCESS; } -CSR_API(SrvWriteConsoleOutput) +NTSTATUS NTAPI +ConDrvWriteConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + IN PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT WriteRegion) { - PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest; - PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); SHORT i, X, Y, SizeX, SizeY; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; SMALL_RECT ScreenBuffer; PCHAR_INFO CurCharInfo; - SMALL_RECT WriteRegion; - PCHAR_INFO CharInfo; - COORD BufferCoord; - COORD BufferSize; - NTSTATUS Status; + SMALL_RECT CapturedWriteRegion; PCHAR_INFO Ptr; - DPRINT("SrvWriteConsoleOutput\n"); - - BufferSize = WriteOutputRequest->BufferSize; - BufferCoord = WriteOutputRequest->BufferCoord; - CharInfo = WriteOutputRequest->CharInfo; - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&WriteOutputRequest->CharInfo, - BufferSize.X * BufferSize.Y, - sizeof(CHAR_INFO))) + if (Console == NULL || Buffer == NULL || CharInfo == NULL || + BufferSize == NULL || BufferCoord == NULL || WriteRegion == NULL) { return STATUS_INVALID_PARAMETER; } - Status = ConSrvGetTextModeBuffer(ProcessData, - WriteOutputRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); - Console = Buff->Header.Console; + CapturedWriteRegion = *WriteRegion; - WriteRegion = WriteOutputRequest->WriteRegion; - - SizeY = min(BufferSize.Y - BufferCoord.Y, ConioRectHeight(&WriteRegion)); - SizeX = min(BufferSize.X - BufferCoord.X, ConioRectWidth(&WriteRegion)); - WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; - WriteRegion.Right = WriteRegion.Left + SizeX - 1; + SizeX = min(BufferSize->X - BufferCoord->X, ConioRectWidth(&CapturedWriteRegion)); + SizeY = min(BufferSize->Y - BufferCoord->Y, ConioRectHeight(&CapturedWriteRegion)); + CapturedWriteRegion.Right = CapturedWriteRegion.Left + SizeX - 1; + CapturedWriteRegion.Bottom = CapturedWriteRegion.Top + SizeY - 1; /* Make sure WriteRegion is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1); - if (!ConioGetIntersection(&WriteRegion, &ScreenBuffer, &WriteRegion)) + ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); + if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion)) { - ConSrvReleaseScreenBuffer(Buff, TRUE); - - /* It is okay to have a WriteRegion completely outside the screen buffer. - No data is written then. */ + /* + * It is okay to have a WriteRegion completely outside + * the screen buffer. No data is written then. + */ return STATUS_SUCCESS; } - for (i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++) + for (i = 0, Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; i++, Y++) { - CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; + CurCharInfo = CharInfo + (i + BufferCoord->Y) * BufferSize->X + BufferCoord->X; - Ptr = ConioCoordToPointer(Buff, WriteRegion.Left, Y); - for (X = WriteRegion.Left; X <= WriteRegion.Right; X++) + Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y); + for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; X++) { - if (WriteOutputRequest->Unicode) + if (Unicode) { Ptr->Char.UnicodeChar = CurCharInfo->Char.UnicodeChar; } @@ -896,59 +731,117 @@ CSR_API(SrvWriteConsoleOutput) } } - ConioDrawRegion(Console, &WriteRegion); + ConioDrawRegion(Console, &CapturedWriteRegion); - ConSrvReleaseScreenBuffer(Buff, TRUE); - - WriteOutputRequest->WriteRegion.Right = WriteRegion.Left + SizeX - 1; - WriteOutputRequest->WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; - WriteOutputRequest->WriteRegion.Left = WriteRegion.Left; - WriteOutputRequest->WriteRegion.Top = WriteRegion.Top; + WriteRegion->Left = CapturedWriteRegion.Left; + WriteRegion->Top = CapturedWriteRegion.Top ; + WriteRegion->Right = CapturedWriteRegion.Left + SizeX - 1; + WriteRegion->Bottom = CapturedWriteRegion.Top + SizeY - 1; return STATUS_SUCCESS; } -CSR_API(SrvWriteConsole) +NTSTATUS NTAPI +ConDrvWriteConsole(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, + IN BOOLEAN Unicode, + IN PVOID StringBuffer, + IN ULONG NumCharsToWrite, + OUT PULONG NumCharsWritten OPTIONAL) { - NTSTATUS Status; - PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; + NTSTATUS Status = STATUS_SUCCESS; + PWCHAR Buffer = NULL; + ULONG Written = 0; + ULONG Length; - DPRINT("SrvWriteConsole\n"); - - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID)&WriteConsoleRequest->Buffer, - WriteConsoleRequest->BufferSize, - sizeof(BYTE))) - { + if (Console == NULL || ScreenBuffer == NULL /* || StringBuffer == NULL */) return STATUS_INVALID_PARAMETER; + + /* Validity checks */ + ASSERT(Console == ScreenBuffer->Header.Console); + ASSERT( (StringBuffer != NULL && NumCharsToWrite >= 0) || + (StringBuffer == NULL && NumCharsToWrite == 0) ); + + // if (Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) + if (Console->PauseFlags && Console->UnpauseEvent != NULL) + { + return STATUS_PENDING; } - Status = DoWriteConsole(ApiMessage, - CsrGetClientThread(), - TRUE); + if (Unicode) + { + Buffer = StringBuffer; + } + else + { + Length = MultiByteToWideChar(Console->OutputCodePage, 0, + (PCHAR)StringBuffer, + NumCharsToWrite, + NULL, 0); + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); + if (Buffer) + { + MultiByteToWideChar(Console->OutputCodePage, 0, + (PCHAR)StringBuffer, + NumCharsToWrite, + (PWCHAR)Buffer, Length); + } + else + { + Status = STATUS_NO_MEMORY; + } + } - if (Status == STATUS_PENDING) - *ReplyCode = CsrReplyPending; + if (Buffer) + { + if (NT_SUCCESS(Status)) + { + Status = ConioWriteConsole(Console, + ScreenBuffer, + Buffer, + NumCharsToWrite, + TRUE); + if (NT_SUCCESS(Status)) + { + Written = NumCharsToWrite; + } + } + + if (!Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + } + + if (NumCharsWritten) *NumCharsWritten = Written; return Status; } -CSR_API(SrvReadConsoleOutputString) +NTSTATUS NTAPI +ConDrvReadConsoleOutputString(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PCOORD EndCoord, + OUT PULONG CodesRead) { - NTSTATUS Status; - PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - USHORT CodeType; SHORT Xpos, Ypos; PVOID ReadBuffer; - DWORD i; + ULONG i; ULONG CodeSize; PCHAR_INFO Ptr; - DPRINT("SrvReadConsoleOutputString\n"); + if (Console == NULL || Buffer == NULL || + ReadCoord == NULL || EndCoord == NULL || CodesRead == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity checks */ + ASSERT(Console == Buffer->Header.Console); + ASSERT( (StringBuffer != NULL && NumCodesToRead >= 0) || + (StringBuffer == NULL && NumCodesToRead == 0) ); - CodeType = ReadOutputCodeRequest->CodeType; switch (CodeType) { case CODE_ASCII: @@ -967,26 +860,9 @@ CSR_API(SrvReadConsoleOutputString) return STATUS_INVALID_PARAMETER; } - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&ReadOutputCodeRequest->pCode.pCode, - ReadOutputCodeRequest->NumCodesToRead, - CodeSize)) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - ReadOutputCodeRequest->OutputHandle, - &Buff, - GENERIC_READ, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - ReadBuffer = ReadOutputCodeRequest->pCode.pCode; - Xpos = ReadOutputCodeRequest->ReadCoord.X; - Ypos = (ReadOutputCodeRequest->ReadCoord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; + ReadBuffer = StringBuffer; + Xpos = ReadCoord->X; + Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; /* * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) : @@ -1001,11 +877,11 @@ CSR_API(SrvReadConsoleOutputString) * TODO: Do NOT loop up to NumCodesToRead, but stop before * if we are going to overflow... */ - // Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work - for (i = 0; i < min(ReadOutputCodeRequest->NumCodesToRead, Buff->ScreenBufferSize.X * Buff->ScreenBufferSize.Y); ++i) + // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work + for (i = 0; i < min(NumCodesToRead, Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); ++i) { - // Ptr = ConioCoordToPointer(Buff, Xpos, Ypos); // Doesn't work either - Ptr = &Buff->Buffer[Xpos + Ypos * Buff->ScreenBufferSize.X]; + // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work either + Ptr = &Buffer->Buffer[Xpos + Ypos * Buffer->ScreenBufferSize.X]; switch (CodeType) { @@ -1026,12 +902,12 @@ CSR_API(SrvReadConsoleOutputString) Xpos++; - if (Xpos == Buff->ScreenBufferSize.X) + if (Xpos == Buffer->ScreenBufferSize.X) { Xpos = 0; Ypos++; - if (Ypos == Buff->ScreenBufferSize.Y) + if (Ypos == Buffer->ScreenBufferSize.Y) { Ypos = 0; } @@ -1053,34 +929,44 @@ CSR_API(SrvReadConsoleOutputString) // break; // } - ReadOutputCodeRequest->EndCoord.X = Xpos; - ReadOutputCodeRequest->EndCoord.Y = (Ypos - Buff->VirtualY + Buff->ScreenBufferSize.Y) % Buff->ScreenBufferSize.Y; + EndCoord->X = Xpos; + EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y; - ConSrvReleaseScreenBuffer(Buff, TRUE); - - ReadOutputCodeRequest->CodesRead = (DWORD)((ULONG_PTR)ReadBuffer - (ULONG_PTR)ReadOutputCodeRequest->pCode.pCode) / CodeSize; - // <= ReadOutputCodeRequest->NumCodesToRead + *CodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize; + // <= NumCodesToRead return STATUS_SUCCESS; } -CSR_API(SrvWriteConsoleOutputString) +NTSTATUS NTAPI +ConDrvWriteConsoleOutputString(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + IN PVOID StringBuffer, + IN ULONG NumCodesToWrite, + IN PCOORD WriteCoord /*, + OUT PCOORD EndCoord, + OUT PULONG CodesWritten */) { - NTSTATUS Status; - PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - USHORT CodeType; - PVOID ReadBuffer = NULL; + NTSTATUS Status = STATUS_SUCCESS; + PVOID WriteBuffer = NULL; PWCHAR tmpString = NULL; DWORD X, Y, Length; // , Written = 0; ULONG CodeSize; SMALL_RECT UpdateRect; PCHAR_INFO Ptr; - DPRINT("SrvWriteConsoleOutputString\n"); + if (Console == NULL || Buffer == NULL || + WriteCoord == NULL /* || EndCoord == NULL || CodesWritten == NULL */) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity checks */ + ASSERT(Console == Buffer->Header.Console); + ASSERT( (StringBuffer != NULL && NumCodesToWrite >= 0) || + (StringBuffer == NULL && NumCodesToWrite == 0) ); - CodeType = WriteOutputCodeRequest->CodeType; switch (CodeType) { case CODE_ASCII: @@ -1099,37 +985,20 @@ CSR_API(SrvWriteConsoleOutputString) return STATUS_INVALID_PARAMETER; } - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&WriteOutputCodeRequest->pCode.pCode, - WriteOutputCodeRequest->Length, - CodeSize)) - { - return STATUS_INVALID_PARAMETER; - } - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - WriteOutputCodeRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - if (CodeType == CODE_ASCII) { /* Convert the ASCII string into Unicode before writing it to the console */ Length = MultiByteToWideChar(Console->OutputCodePage, 0, - WriteOutputCodeRequest->pCode.AsciiChar, - WriteOutputCodeRequest->Length, + (PCHAR)StringBuffer, + NumCodesToWrite, NULL, 0); - tmpString = ReadBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); - if (ReadBuffer) + tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); + if (WriteBuffer) { MultiByteToWideChar(Console->OutputCodePage, 0, - WriteOutputCodeRequest->pCode.AsciiChar, - WriteOutputCodeRequest->Length, - (PWCHAR)ReadBuffer, Length); + (PCHAR)StringBuffer, + NumCodesToWrite, + (PWCHAR)WriteBuffer, Length); } else { @@ -1139,124 +1008,120 @@ CSR_API(SrvWriteConsoleOutputString) else { /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */ - ReadBuffer = WriteOutputCodeRequest->pCode.pCode; + WriteBuffer = StringBuffer; } - if (ReadBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup; + if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup; - X = WriteOutputCodeRequest->Coord.X; - Y = (WriteOutputCodeRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; - Length = WriteOutputCodeRequest->Length; - // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work - // Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work + X = WriteCoord->X; + Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; + Length = NumCodesToWrite; + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work + // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work while (Length--) { - // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either - Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either + Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; switch (CodeType) { case CODE_ASCII: case CODE_UNICODE: - Ptr->Char.UnicodeChar = *(PWCHAR)ReadBuffer; + Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer; break; case CODE_ATTRIBUTE: - Ptr->Attributes = *(PWORD)ReadBuffer; + Ptr->Attributes = *(PWORD)WriteBuffer; break; } - ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize); + WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize); // ++Ptr; // Written++; - if (++X == Buff->ScreenBufferSize.X) + if (++X == Buffer->ScreenBufferSize.X) { X = 0; - if (++Y == Buff->ScreenBufferSize.Y) + if (++Y == Buffer->ScreenBufferSize.Y) { Y = 0; } } } - if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) + if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { - ConioComputeUpdateRect(Buff, &UpdateRect, &WriteOutputCodeRequest->Coord, - WriteOutputCodeRequest->Length); + ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); ConioDrawRegion(Console, &UpdateRect); } - // WriteOutputCodeRequest->EndCoord.X = X; - // WriteOutputCodeRequest->EndCoord.Y = (Y + Buff->ScreenBufferSize.Y - Buff->VirtualY) % Buff->ScreenBufferSize.Y; + // EndCoord->X = X; + // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Cleanup: - if (tmpString) - RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString); + if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString); - ConSrvReleaseScreenBuffer(Buff, TRUE); - - // WriteOutputCodeRequest->NrCharactersWritten = Written; + // CodesWritten = Written; return Status; } -CSR_API(SrvFillConsoleOutput) +NTSTATUS NTAPI +ConDrvFillConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + IN PVOID Code, + IN ULONG NumCodesToWrite, + IN PCOORD WriteCoord /*, + OUT PULONG CodesWritten */) { - NTSTATUS Status; - PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; DWORD X, Y, Length; // , Written = 0; - USHORT CodeType; - PVOID Code = NULL; PCHAR_INFO Ptr; SMALL_RECT UpdateRect; - DPRINT("SrvFillConsoleOutput\n"); - - CodeType = FillOutputRequest->CodeType; - if ( (CodeType != CODE_ASCII ) && - (CodeType != CODE_UNICODE ) && - (CodeType != CODE_ATTRIBUTE) ) + if (Console == NULL || Buffer == NULL || Code == NULL || + WriteCoord == NULL /* || CodesWritten == NULL */) { return STATUS_INVALID_PARAMETER; } - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - FillOutputRequest->OutputHandle, - &Buff, - GENERIC_WRITE, - TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); +#if 0 switch (CodeType) { case CODE_ASCII: /* On-place conversion from the ASCII char to the UNICODE char */ - ConsoleAnsiCharToUnicodeChar(Console, &FillOutputRequest->Code.UnicodeChar, &FillOutputRequest->Code.AsciiChar); + ConsoleAnsiCharToUnicodeChar(Console, &Code->UnicodeChar, &Code->AsciiChar); /* Fall through */ case CODE_UNICODE: - Code = &FillOutputRequest->Code.UnicodeChar; + Code = &Code->UnicodeChar; break; case CODE_ATTRIBUTE: - Code = &FillOutputRequest->Code.Attribute; + Code = &Code->Attribute; break; } +#else + if (CodeType == CODE_ASCII) + { + /* On-place conversion from the ASCII char to the UNICODE char */ + // FIXME: What if Code points to an invalid memory zone ?? + ConsoleAnsiCharToUnicodeChar(Console, (PWCHAR)Code, (PCHAR)Code); + } +#endif - X = FillOutputRequest->Coord.X; - Y = (FillOutputRequest->Coord.Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y; - Length = FillOutputRequest->Length; - // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work - // Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; // May work + X = WriteCoord->X; + Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; + Length = NumCodesToWrite; + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work + // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work while (Length--) { - // Ptr = ConioCoordToPointer(Buff, X, Y); // Doesn't work either - Ptr = &Buff->Buffer[X + Y * Buff->ScreenBufferSize.X]; + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either + Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; switch (CodeType) { @@ -1272,181 +1137,209 @@ CSR_API(SrvFillConsoleOutput) // ++Ptr; // Written++; - if (++X == Buff->ScreenBufferSize.X) + if (++X == Buffer->ScreenBufferSize.X) { X = 0; - if (++Y == Buff->ScreenBufferSize.Y) + if (++Y == Buffer->ScreenBufferSize.Y) { Y = 0; } } } - if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) + if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { - ConioComputeUpdateRect(Buff, &UpdateRect, &FillOutputRequest->Coord, - FillOutputRequest->Length); + ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); ConioDrawRegion(Console, &UpdateRect); } - ConSrvReleaseScreenBuffer(Buff, TRUE); -/* - Length = FillOutputRequest->Length; - FillOutputRequest->NrCharactersWritten = Length; -*/ + // CodesWritten = Written; // NumCodesToWrite; return STATUS_SUCCESS; } -CSR_API(SrvGetConsoleScreenBufferInfo) +NTSTATUS NTAPI +ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PCONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo) { - NTSTATUS Status; - PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest; - // PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - PCONSOLE_SCREEN_BUFFER_INFO pInfo = &ScreenBufferInfoRequest->Info; + if (Console == NULL || Buffer == NULL || ScreenBufferInfo == NULL) + return STATUS_INVALID_PARAMETER; - DPRINT("SrvGetConsoleScreenBufferInfo\n"); + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), ScreenBufferInfoRequest->OutputHandle, &Buff, GENERIC_READ, TRUE); - if (!NT_SUCCESS(Status)) return Status; + ScreenBufferInfo->dwSize = Buffer->ScreenBufferSize; + ScreenBufferInfo->dwCursorPosition = Buffer->CursorPosition; + ScreenBufferInfo->wAttributes = Buffer->ScreenDefaultAttrib; + ScreenBufferInfo->srWindow.Left = Buffer->ViewOrigin.X; + ScreenBufferInfo->srWindow.Top = Buffer->ViewOrigin.Y; + ScreenBufferInfo->srWindow.Right = Buffer->ViewOrigin.X + Buffer->ViewSize.X - 1; + ScreenBufferInfo->srWindow.Bottom = Buffer->ViewOrigin.Y + Buffer->ViewSize.Y - 1; - // Console = Buff->Header.Console; + // FIXME: Refine the computation + ScreenBufferInfo->dwMaximumWindowSize = Buffer->ScreenBufferSize; - pInfo->dwSize = Buff->ScreenBufferSize; - pInfo->dwCursorPosition = Buff->CursorPosition; - pInfo->wAttributes = Buff->ScreenDefaultAttrib; - pInfo->srWindow.Left = Buff->ViewOrigin.X; - pInfo->srWindow.Top = Buff->ViewOrigin.Y; - pInfo->srWindow.Right = Buff->ViewOrigin.X + Buff->ViewSize.X - 1; - pInfo->srWindow.Bottom = Buff->ViewOrigin.Y + Buff->ViewSize.Y - 1; - pInfo->dwMaximumWindowSize = Buff->ScreenBufferSize; // TODO: Refine the computation - - ConSrvReleaseScreenBuffer(Buff, TRUE); return STATUS_SUCCESS; } -CSR_API(SrvSetConsoleTextAttribute) +NTSTATUS NTAPI +ConDrvSetConsoleTextAttribute(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN WORD Attribute) { - NTSTATUS Status; - PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTextAttribRequest; - PTEXTMODE_SCREEN_BUFFER Buff; + if (Console == NULL || Buffer == NULL) + return STATUS_INVALID_PARAMETER; - DPRINT("SrvSetConsoleTextAttribute\n"); + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetTextAttribRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Buff->ScreenDefaultAttrib = SetTextAttribRequest->Attrib; - - ConSrvReleaseScreenBuffer(Buff, TRUE); + Buffer->ScreenDefaultAttrib = Attribute; return STATUS_SUCCESS; } -CSR_API(SrvSetConsoleScreenBufferSize) +NTSTATUS NTAPI +ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCOORD Size) { NTSTATUS Status; - PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferSizeRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), SetScreenBufferSizeRequest->OutputHandle, &Buff, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; + if (Console == NULL || Buffer == NULL || Size == NULL) + return STATUS_INVALID_PARAMETER; - Console = Buff->Header.Console; + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); - Status = ConioResizeBuffer(Console, Buff, SetScreenBufferSizeRequest->Size); + Status = ConioResizeBuffer(Console, Buffer, *Size); if (NT_SUCCESS(Status)) ConioResizeTerminal(Console); - ConSrvReleaseScreenBuffer(Buff, TRUE); return Status; } -CSR_API(SrvScrollConsoleScreenBuffer) +NTSTATUS NTAPI +ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + IN PSMALL_RECT ScrollRectangle, + IN BOOLEAN UseClipRectangle, + IN PSMALL_RECT ClipRectangle OPTIONAL, + IN PCOORD DestinationOrigin, + IN CHAR_INFO FillChar) { - PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest; - PCONSOLE Console; - PTEXTMODE_SCREEN_BUFFER Buff; + COORD CapturedDestinationOrigin; SMALL_RECT ScreenBuffer; SMALL_RECT SrcRegion; SMALL_RECT DstRegion; SMALL_RECT UpdateRegion; - SMALL_RECT ScrollRectangle; - SMALL_RECT ClipRectangle; - NTSTATUS Status; - HANDLE OutputHandle; - BOOLEAN UseClipRectangle; - COORD DestinationOrigin; - CHAR_INFO FillChar; + SMALL_RECT CapturedClipRectangle; - DPRINT("SrvScrollConsoleScreenBuffer\n"); - - OutputHandle = ScrollScreenBufferRequest->OutputHandle; - UseClipRectangle = ScrollScreenBufferRequest->UseClipRectangle; - DestinationOrigin = ScrollScreenBufferRequest->DestinationOrigin; - FillChar = ScrollScreenBufferRequest->Fill; - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), OutputHandle, &Buff, GENERIC_WRITE, TRUE); - if (!NT_SUCCESS(Status)) return Status; - - Console = Buff->Header.Console; - - ScrollRectangle = ScrollScreenBufferRequest->ScrollRectangle; - - /* Make sure source rectangle is inside the screen buffer */ - ConioInitRect(&ScreenBuffer, 0, 0, Buff->ScreenBufferSize.Y - 1, Buff->ScreenBufferSize.X - 1); - if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, &ScrollRectangle)) + if (Console == NULL || Buffer == NULL || ScrollRectangle == NULL || + (UseClipRectangle ? ClipRectangle == NULL : FALSE) || DestinationOrigin == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + CapturedDestinationOrigin = *DestinationOrigin; + + /* Make sure the source rectangle is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); + if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, ScrollRectangle)) { - ConSrvReleaseScreenBuffer(Buff, TRUE); return STATUS_SUCCESS; } /* If the source was clipped on the left or top, adjust the destination accordingly */ - if (ScrollRectangle.Left < 0) + if (ScrollRectangle->Left < 0) { - DestinationOrigin.X -= ScrollRectangle.Left; + CapturedDestinationOrigin.X -= ScrollRectangle->Left; } - if (ScrollRectangle.Top < 0) + if (ScrollRectangle->Top < 0) { - DestinationOrigin.Y -= ScrollRectangle.Top; + CapturedDestinationOrigin.Y -= ScrollRectangle->Top; } if (UseClipRectangle) { - ClipRectangle = ScrollScreenBufferRequest->ClipRectangle; - if (!ConioGetIntersection(&ClipRectangle, &ClipRectangle, &ScreenBuffer)) + CapturedClipRectangle = *ClipRectangle; + if (!ConioGetIntersection(&CapturedClipRectangle, &CapturedClipRectangle, &ScreenBuffer)) { - ConSrvReleaseScreenBuffer(Buff, TRUE); return STATUS_SUCCESS; } } else { - ClipRectangle = ScreenBuffer; + CapturedClipRectangle = ScreenBuffer; } ConioInitRect(&DstRegion, - DestinationOrigin.Y, - DestinationOrigin.X, - DestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, - DestinationOrigin.X + ConioRectWidth(&SrcRegion) - 1); + CapturedDestinationOrigin.Y, + CapturedDestinationOrigin.X, + CapturedDestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, + CapturedDestinationOrigin.X + ConioRectWidth(&SrcRegion ) - 1); - if (!ScrollScreenBufferRequest->Unicode) + if (!Unicode) ConsoleAnsiCharToUnicodeChar(Console, &FillChar.Char.UnicodeChar, &FillChar.Char.AsciiChar); - ConioMoveRegion(Buff, &SrcRegion, &DstRegion, &ClipRectangle, FillChar); + ConioMoveRegion(Buffer, &SrcRegion, &DstRegion, &CapturedClipRectangle, FillChar); - if ((PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) + if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); - if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &ClipRectangle)) + if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &CapturedClipRectangle)) { /* Draw update region */ ConioDrawRegion(Console, &UpdateRegion); } } - ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Absolute, + IN PSMALL_RECT WindowRect) +{ + SMALL_RECT CapturedWindowRect; + + if (Console == NULL || Buffer == NULL || WindowRect == NULL) + return STATUS_INVALID_PARAMETER; + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + CapturedWindowRect = *WindowRect; + + if (Absolute == FALSE) + { + /* Relative positions given. Transform them to absolute ones */ + CapturedWindowRect.Left += Buffer->ViewOrigin.X; + CapturedWindowRect.Top += Buffer->ViewOrigin.Y; + CapturedWindowRect.Right += Buffer->ViewOrigin.X + Buffer->ViewSize.X - 1; + CapturedWindowRect.Bottom += Buffer->ViewOrigin.Y + Buffer->ViewSize.Y - 1; + } + + /* See MSDN documentation on SetConsoleWindowInfo about the performed checks */ + if ( (CapturedWindowRect.Left < 0) || (CapturedWindowRect.Top < 0) || + (CapturedWindowRect.Right >= Buffer->ScreenBufferSize.X) || + (CapturedWindowRect.Bottom >= Buffer->ScreenBufferSize.Y) || + (CapturedWindowRect.Right <= CapturedWindowRect.Left) || + (CapturedWindowRect.Bottom <= CapturedWindowRect.Top) ) + { + return STATUS_INVALID_PARAMETER; + } + + Buffer->ViewOrigin.X = CapturedWindowRect.Left; + Buffer->ViewOrigin.Y = CapturedWindowRect.Top; + + Buffer->ViewSize.X = CapturedWindowRect.Right - CapturedWindowRect.Left + 1; + Buffer->ViewSize.Y = CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1; + return STATUS_SUCCESS; } diff --git a/win32ss/user/winsrv/consrv/coninput.c b/win32ss/user/winsrv/consrv/coninput.c new file mode 100644 index 00000000000..7143a322c5f --- /dev/null +++ b/win32ss/user/winsrv/consrv/coninput.c @@ -0,0 +1,479 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/coninput.c + * PURPOSE: Console Input functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "handle.h" +#include "lineinput.h" + +#define NDEBUG +#include + + +/* GLOBALS ********************************************************************/ + +#define ConSrvGetInputBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \ + ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \ + (Access), (LockConsole), INPUT_BUFFER) +#define ConSrvGetInputBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \ + ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \ + (Access), (LockConsole), INPUT_BUFFER) +#define ConSrvReleaseInputBuffer(Buff, IsConsoleLocked) \ + ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked)) + + +typedef struct _GET_INPUT_INFO +{ + PCSR_THREAD CallingThread; // The thread which called the input API. + PVOID HandleEntry; // The handle data associated with the wait thread. + PCONSOLE_INPUT_BUFFER InputBuffer; // The input buffer corresponding to the handle. +} GET_INPUT_INFO, *PGET_INPUT_INFO; + + +/* PRIVATE FUNCTIONS **********************************************************/ + +static NTSTATUS +WaitBeforeReading(IN PGET_INPUT_INFO InputInfo, + IN PCSR_API_MESSAGE ApiMessage, + IN CSR_WAIT_FUNCTION WaitFunction OPTIONAL, + IN BOOL CreateWaitBlock OPTIONAL) +{ + if (CreateWaitBlock) + { + PGET_INPUT_INFO CapturedInputInfo; + + CapturedInputInfo = ConsoleAllocHeap(0, sizeof(GET_INPUT_INFO)); + if (!CapturedInputInfo) return STATUS_NO_MEMORY; + + RtlMoveMemory(CapturedInputInfo, InputInfo, sizeof(GET_INPUT_INFO)); + + if (!CsrCreateWait(&InputInfo->InputBuffer->ReadWaitQueue, + WaitFunction, + InputInfo->CallingThread, + ApiMessage, + CapturedInputInfo, + NULL)) + { + ConsoleFreeHeap(CapturedInputInfo); + return STATUS_NO_MEMORY; + } + } + + /* Wait for input */ + return STATUS_PENDING; +} + +static NTSTATUS +ReadChars(IN PGET_INPUT_INFO InputInfo, + IN PCSR_API_MESSAGE ApiMessage, + IN BOOL CreateWaitBlock OPTIONAL); + +// Wait function CSR_WAIT_FUNCTION +static BOOLEAN +ReadCharsThread(IN PLIST_ENTRY WaitList, + IN PCSR_THREAD WaitThread, + IN PCSR_API_MESSAGE WaitApiMessage, + IN PVOID WaitContext, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2, + IN ULONG WaitFlags) +{ + NTSTATUS Status; + PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext; + + PVOID InputHandle = WaitArgument2; + + DPRINT("ReadCharsThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); + + /* + * If we are notified of the process termination via a call + * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or + * CsrDestroyThread, just return. + */ + if (WaitFlags & CsrProcessTerminating) + { + Status = STATUS_THREAD_IS_TERMINATING; + goto Quit; + } + + /* + * Somebody is closing a handle to this input buffer, + * by calling ConSrvCloseHandleEntry. + * See whether we are linked to that handle (ie. we + * are a waiter for this handle), and if so, return. + * Otherwise, ignore the call and continue waiting. + */ + if (InputHandle != NULL) + { + Status = (InputHandle == InputInfo->HandleEntry ? STATUS_ALERTED + : STATUS_PENDING); + goto Quit; + } + + /* + * If we go there, that means we are notified for some new input. + * The console is therefore already locked. + */ + Status = ReadChars(InputInfo, + WaitApiMessage, + FALSE); + +Quit: + if (Status != STATUS_PENDING) + { + WaitApiMessage->Status = Status; + ConsoleFreeHeap(InputInfo); + } + + return (Status == STATUS_PENDING ? FALSE : TRUE); +} + +NTSTATUS NTAPI +ConDrvReadConsole(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN Unicode, + OUT PVOID Buffer, + IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, + IN ULONG NumCharsToRead, + OUT PULONG NumCharsRead OPTIONAL); +static NTSTATUS +ReadChars(IN PGET_INPUT_INFO InputInfo, + IN PCSR_API_MESSAGE ApiMessage, + IN BOOL CreateWaitBlock OPTIONAL) +{ + NTSTATUS Status; + PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; + PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; + CONSOLE_READCONSOLE_CONTROL ReadControl; + + ReadControl.nLength = sizeof(CONSOLE_READCONSOLE_CONTROL); + ReadControl.nInitialChars = ReadConsoleRequest->NrCharactersRead; + ReadControl.dwCtrlWakeupMask = ReadConsoleRequest->CtrlWakeupMask; + ReadControl.dwControlKeyState = ReadConsoleRequest->ControlKeyState; + + Status = ConDrvReadConsole(InputBuffer->Header.Console, + InputBuffer, + ReadConsoleRequest->Unicode, + ReadConsoleRequest->Buffer, + &ReadControl, + ReadConsoleRequest->NrCharactersToRead, + &ReadConsoleRequest->NrCharactersRead); + + ReadConsoleRequest->ControlKeyState = ReadControl.dwControlKeyState; + + if (Status == STATUS_PENDING) + { + /* We haven't completed a read, so start a wait */ + return WaitBeforeReading(InputInfo, + ApiMessage, + ReadCharsThread, + CreateWaitBlock); + } + else + { + /* We read all what we wanted, we return the error code we were given */ + return Status; + // return STATUS_SUCCESS; + } +} + +static NTSTATUS +ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, + IN BOOL Wait, + IN PCSR_API_MESSAGE ApiMessage, + IN BOOL CreateWaitBlock OPTIONAL); + +// Wait function CSR_WAIT_FUNCTION +static BOOLEAN +ReadInputBufferThread(IN PLIST_ENTRY WaitList, + IN PCSR_THREAD WaitThread, + IN PCSR_API_MESSAGE WaitApiMessage, + IN PVOID WaitContext, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2, + IN ULONG WaitFlags) +{ + NTSTATUS Status; + PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)WaitApiMessage)->Data.GetInputRequest; + PGET_INPUT_INFO InputInfo = (PGET_INPUT_INFO)WaitContext; + + PVOID InputHandle = WaitArgument2; + + DPRINT("ReadInputBufferThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); + + /* + * If we are notified of the process termination via a call + * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or + * CsrDestroyThread, just return. + */ + if (WaitFlags & CsrProcessTerminating) + { + Status = STATUS_THREAD_IS_TERMINATING; + goto Quit; + } + + /* + * Somebody is closing a handle to this input buffer, + * by calling ConSrvCloseHandleEntry. + * See whether we are linked to that handle (ie. we + * are a waiter for this handle), and if so, return. + * Otherwise, ignore the call and continue waiting. + */ + if (InputHandle != NULL) + { + Status = (InputHandle == InputInfo->HandleEntry ? STATUS_ALERTED + : STATUS_PENDING); + goto Quit; + } + + /* + * If we go there, that means we are notified for some new input. + * The console is therefore already locked. + */ + Status = ReadInputBuffer(InputInfo, + GetInputRequest->bRead, + WaitApiMessage, + FALSE); + +Quit: + if (Status != STATUS_PENDING) + { + WaitApiMessage->Status = Status; + ConsoleFreeHeap(InputInfo); + } + + return (Status == STATUS_PENDING ? FALSE : TRUE); +} + +NTSTATUS NTAPI +ConDrvGetConsoleInput(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN WaitForMoreEvents, + IN BOOLEAN Unicode, + OUT PINPUT_RECORD InputRecord, + IN ULONG NumEventsToRead, + OUT PULONG NumEventsRead); +static NTSTATUS +ReadInputBuffer(IN PGET_INPUT_INFO InputInfo, + IN BOOL Wait, // TRUE --> Read ; FALSE --> Peek + IN PCSR_API_MESSAGE ApiMessage, + IN BOOL CreateWaitBlock OPTIONAL) +{ + NTSTATUS Status; + PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; + PCONSOLE_INPUT_BUFFER InputBuffer = InputInfo->InputBuffer; + + // GetInputRequest->InputsRead = 0; + + Status = ConDrvGetConsoleInput(InputBuffer->Header.Console, + InputBuffer, + Wait, + GetInputRequest->Unicode, + GetInputRequest->InputRecord, + GetInputRequest->Length, + &GetInputRequest->InputsRead); + + if (Status == STATUS_PENDING) + { + /* We haven't completed a read, so start a wait */ + return WaitBeforeReading(InputInfo, + ApiMessage, + ReadInputBufferThread, + CreateWaitBlock); + } + else + { + /* We read all what we wanted, we return the error code we were given */ + return Status; + // return STATUS_SUCCESS; + } +} + + +/* PUBLIC SERVER APIS *********************************************************/ + +CSR_API(SrvReadConsole) +{ + NTSTATUS Status; + PCONSOLE_READCONSOLE ReadConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadConsoleRequest; + PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); + PVOID HandleEntry; + PCONSOLE_INPUT_BUFFER InputBuffer; + GET_INPUT_INFO InputInfo; + + DPRINT("SrvReadConsole\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&ReadConsoleRequest->Buffer, + ReadConsoleRequest->BufferSize, + sizeof(BYTE))) + { + return STATUS_INVALID_PARAMETER; + } + + if (ReadConsoleRequest->NrCharactersRead > ReadConsoleRequest->NrCharactersToRead) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, ReadConsoleRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + // This member is set by the caller (IntReadConsole in kernel32) + // ReadConsoleRequest->NrCharactersRead = 0; + + InputInfo.CallingThread = CsrGetClientThread(); + InputInfo.HandleEntry = HandleEntry; + InputInfo.InputBuffer = InputBuffer; + + Status = ReadChars(&InputInfo, + ApiMessage, + TRUE); + + ConSrvReleaseInputBuffer(InputBuffer, TRUE); + + if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending; + + return Status; +} + +CSR_API(SrvGetConsoleInput) +{ + NTSTATUS Status; + PCONSOLE_GETINPUT GetInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetInputRequest; + PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); + PVOID HandleEntry; + PCONSOLE_INPUT_BUFFER InputBuffer; + GET_INPUT_INFO InputInfo; + + DPRINT("SrvGetConsoleInput\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&GetInputRequest->InputRecord, + GetInputRequest->Length, + sizeof(INPUT_RECORD))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetInputBufferAndHandleEntry(ProcessData, GetInputRequest->InputHandle, &InputBuffer, &HandleEntry, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + GetInputRequest->InputsRead = 0; + + InputInfo.CallingThread = CsrGetClientThread(); + InputInfo.HandleEntry = HandleEntry; + InputInfo.InputBuffer = InputBuffer; + + Status = ReadInputBuffer(&InputInfo, + GetInputRequest->bRead, + ApiMessage, + TRUE); + + ConSrvReleaseInputBuffer(InputBuffer, TRUE); + + if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending; + + return Status; +} + +NTSTATUS NTAPI +ConDrvWriteConsoleInput(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + IN BOOLEAN Unicode, + IN PINPUT_RECORD InputRecord, + IN ULONG NumEventsToWrite, + OUT PULONG NumEventsWritten OPTIONAL); +CSR_API(SrvWriteConsoleInput) +{ + NTSTATUS Status; + PCONSOLE_WRITEINPUT WriteInputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteInputRequest; + PCONSOLE_INPUT_BUFFER InputBuffer; + ULONG NumEventsWritten; + + DPRINT("SrvWriteConsoleInput\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteInputRequest->InputRecord, + WriteInputRequest->Length, + sizeof(INPUT_RECORD))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + WriteInputRequest->InputHandle, + &InputBuffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + NumEventsWritten = 0; + Status = ConDrvWriteConsoleInput(InputBuffer->Header.Console, + InputBuffer, + WriteInputRequest->Unicode, + WriteInputRequest->InputRecord, + WriteInputRequest->Length, + &NumEventsWritten); + WriteInputRequest->Length = NumEventsWritten; + + ConSrvReleaseInputBuffer(InputBuffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer); +CSR_API(SrvFlushConsoleInputBuffer) +{ + NTSTATUS Status; + PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FlushInputBufferRequest; + PCONSOLE_INPUT_BUFFER InputBuffer; + + DPRINT("SrvFlushConsoleInputBuffer\n"); + + Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + FlushInputBufferRequest->InputHandle, + &InputBuffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvFlushConsoleInputBuffer(InputBuffer->Header.Console, + InputBuffer); + + ConSrvReleaseInputBuffer(InputBuffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console, + IN PCONSOLE_INPUT_BUFFER InputBuffer, + OUT PULONG NumEvents); +CSR_API(SrvGetConsoleNumberOfInputEvents) +{ + NTSTATUS Status; + PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetNumInputEventsRequest; + PCONSOLE_INPUT_BUFFER InputBuffer; + + DPRINT("SrvGetConsoleNumberOfInputEvents\n"); + + Status = ConSrvGetInputBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + GetNumInputEventsRequest->InputHandle, + &InputBuffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvGetConsoleNumberOfInputEvents(InputBuffer->Header.Console, + InputBuffer, + &GetNumInputEventsRequest->NumInputEvents); + + ConSrvReleaseInputBuffer(InputBuffer, TRUE); + return Status; +} + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/coninput.h b/win32ss/user/winsrv/consrv/coninput.h new file mode 100644 index 00000000000..43e4f54e2b8 --- /dev/null +++ b/win32ss/user/winsrv/consrv/coninput.h @@ -0,0 +1,23 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/coninput.h + * PURPOSE: Console Input functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#pragma once + +VOID FASTCALL PurgeInputBuffer(PCONSOLE Console); + +VOID NTAPI +ConDrvProcessKey(IN PCONSOLE Console, + IN BOOLEAN Down, + IN UINT VirtualKeyCode, + IN UINT VirtualScanCode, + IN WCHAR UnicodeChar, + IN ULONG ShiftState, + IN BYTE KeyStateCtrl); + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/conoutput.c b/win32ss/user/winsrv/consrv/conoutput.c new file mode 100644 index 00000000000..223f6caf781 --- /dev/null +++ b/win32ss/user/winsrv/consrv/conoutput.c @@ -0,0 +1,793 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/conoutput.c + * PURPOSE: General Console Output Functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "console.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "conoutput.h" +#include "handle.h" + +#define NDEBUG +#include + + +/* PRIVATE FUNCTIONS **********************************************************/ + + +/* PUBLIC SERVER APIS *********************************************************/ + +NTSTATUS NTAPI +ConDrvInvalidateBitMapRect(IN PCONSOLE Console, + IN PCONSOLE_SCREEN_BUFFER Buffer, + IN PSMALL_RECT Region); +CSR_API(SrvInvalidateBitMapRect) +{ + NTSTATUS Status; + PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.InvalidateDIBitsRequest; + PCONSOLE_SCREEN_BUFFER Buffer; + + DPRINT("SrvInvalidateBitMapRect\n"); + + Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + InvalidateDIBitsRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvInvalidateBitMapRect(Buffer->Header.Console, + Buffer, + &InvalidateDIBitsRequest->Region); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleCursorInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PCONSOLE_CURSOR_INFO CursorInfo); +CSR_API(SrvGetConsoleCursorInfo) +{ + NTSTATUS Status; + PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvGetConsoleCursorInfo\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + CursorInfoRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvGetConsoleCursorInfo(Buffer->Header.Console, + Buffer, + &CursorInfoRequest->Info); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleCursorInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCONSOLE_CURSOR_INFO CursorInfo); +CSR_API(SrvSetConsoleCursorInfo) +{ + NTSTATUS Status; + PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CursorInfoRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvSetConsoleCursorInfo\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + CursorInfoRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleCursorInfo(Buffer->Header.Console, + Buffer, + &CursorInfoRequest->Info); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleCursorPosition(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCOORD Position); +CSR_API(SrvSetConsoleCursorPosition) +{ + NTSTATUS Status; + PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorPositionRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvSetConsoleCursorPosition\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetCursorPositionRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleCursorPosition(Buffer->Header.Console, + Buffer, + &SetCursorPositionRequest->Position); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +CSR_API(SrvCreateConsoleScreenBuffer) +{ + NTSTATUS Status = STATUS_INVALID_PARAMETER; + PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.CreateScreenBufferRequest; + PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process); + PCONSOLE Console; + PCONSOLE_SCREEN_BUFFER Buff; + + PVOID ScreenBufferInfo = NULL; + TEXTMODE_BUFFER_INFO TextModeInfo = {{80, 25}, + DEFAULT_SCREEN_ATTRIB, + DEFAULT_POPUP_ATTRIB , + TRUE, + CSR_DEFAULT_CURSOR_SIZE}; + GRAPHICS_BUFFER_INFO GraphicsInfo; + GraphicsInfo.Info = CreateScreenBufferRequest->GraphicsBufferInfo; // HACK for MSVC + + DPRINT("SrvCreateConsoleScreenBuffer\n"); + + Status = ConSrvGetConsole(ProcessData, &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_TEXTMODE_BUFFER) + { + ScreenBufferInfo = &TextModeInfo; + + /* + if (Console->ActiveBuffer) + { + TextModeInfo.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize; + if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 80; + if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 25; + + TextModeInfo.ScreenAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.ScreenDefaultAttrib; + TextModeInfo.PopupAttrib = Console->ActiveBuffer->ScreenBuffer.TextBuffer.PopupDefaultAttrib; + + TextModeInfo.IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible; + TextModeInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; + } + */ + + /* + * This is Windows' behaviour + */ + + /* Use the current console size. Regularize it if needed. */ + TextModeInfo.ScreenBufferSize = Console->ConsoleSize; + if (TextModeInfo.ScreenBufferSize.X == 0) TextModeInfo.ScreenBufferSize.X = 1; + if (TextModeInfo.ScreenBufferSize.Y == 0) TextModeInfo.ScreenBufferSize.Y = 1; + + /* If we have an active screen buffer, use its attributes as the new ones */ + if (Console->ActiveBuffer && GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) + { + PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer; + + TextModeInfo.ScreenAttrib = Buffer->ScreenDefaultAttrib; + TextModeInfo.PopupAttrib = Buffer->PopupDefaultAttrib; + + TextModeInfo.IsCursorVisible = Buffer->CursorInfo.bVisible; + TextModeInfo.CursorSize = Buffer->CursorInfo.dwSize; + } + } + else if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER) + { + /* Get infos from the graphics buffer information structure */ + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo, + 1, + CreateScreenBufferRequest->GraphicsBufferInfo.dwBitMapInfoLength)) + { + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + + ScreenBufferInfo = &GraphicsInfo; + + /* Initialize shared variables */ + CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = GraphicsInfo.Info.hMutex = INVALID_HANDLE_VALUE; + CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = GraphicsInfo.Info.lpBitMap = NULL; + + /* A graphics screen buffer is never inheritable */ + CreateScreenBufferRequest->Inheritable = FALSE; + } + + Status = ConDrvCreateScreenBuffer(&Buff, + Console, + CreateScreenBufferRequest->ScreenBufferType, + ScreenBufferInfo); + if (!NT_SUCCESS(Status)) goto Quit; + + /* Insert the new handle inside the process handles table */ + RtlEnterCriticalSection(&ProcessData->HandleTableLock); + + Status = ConSrvInsertObject(ProcessData, + &CreateScreenBufferRequest->OutputHandle, + &Buff->Header, + CreateScreenBufferRequest->Access, + CreateScreenBufferRequest->Inheritable, + CreateScreenBufferRequest->ShareMode); + + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + + if (!NT_SUCCESS(Status)) goto Quit; + + if (CreateScreenBufferRequest->ScreenBufferType == CONSOLE_GRAPHICS_BUFFER) + { + PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)Buff; + /* + * Initialize the graphics buffer information structure + * and give it back to the client. + */ + CreateScreenBufferRequest->GraphicsBufferInfo.hMutex = Buffer->ClientMutex; + CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap = Buffer->ClientBitMap; + } + +Quit: + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console, + IN PCONSOLE_SCREEN_BUFFER Buffer); +CSR_API(SrvSetConsoleActiveScreenBuffer) +{ + NTSTATUS Status; + PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferRequest; + PCONSOLE_SCREEN_BUFFER Buffer; + + DPRINT("SrvSetConsoleActiveScreenBuffer\n"); + + Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetScreenBufferRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleActiveScreenBuffer(Buffer->Header.Console, + Buffer); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + + +/* CSR THREADS FOR WriteConsole ***********************************************/ + +static NTSTATUS +DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, + IN PCSR_THREAD ClientThread, + IN BOOL CreateWaitBlock OPTIONAL); + +// Wait function CSR_WAIT_FUNCTION +static BOOLEAN +WriteConsoleThread(IN PLIST_ENTRY WaitList, + IN PCSR_THREAD WaitThread, + IN PCSR_API_MESSAGE WaitApiMessage, + IN PVOID WaitContext, + IN PVOID WaitArgument1, + IN PVOID WaitArgument2, + IN ULONG WaitFlags) +{ + NTSTATUS Status; + + DPRINT("WriteConsoleThread - WaitContext = 0x%p, WaitArgument1 = 0x%p, WaitArgument2 = 0x%p, WaitFlags = %lu\n", WaitContext, WaitArgument1, WaitArgument2, WaitFlags); + + /* + * If we are notified of the process termination via a call + * to CsrNotifyWaitBlock triggered by CsrDestroyProcess or + * CsrDestroyThread, just return. + */ + if (WaitFlags & CsrProcessTerminating) + { + Status = STATUS_THREAD_IS_TERMINATING; + goto Quit; + } + + Status = DoWriteConsole(WaitApiMessage, + WaitThread, + FALSE); + +Quit: + if (Status != STATUS_PENDING) + { + WaitApiMessage->Status = Status; + } + + return (Status == STATUS_PENDING ? FALSE : TRUE); +} + +NTSTATUS NTAPI +ConDrvWriteConsole(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, + IN BOOLEAN Unicode, + IN PVOID StringBuffer, + IN ULONG NumCharsToWrite, + OUT PULONG NumCharsWritten OPTIONAL); +static NTSTATUS +DoWriteConsole(IN PCSR_API_MESSAGE ApiMessage, + IN PCSR_THREAD ClientThread, + IN BOOL CreateWaitBlock OPTIONAL) +{ + NTSTATUS Status; + PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; + PTEXTMODE_SCREEN_BUFFER ScreenBuffer; + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(ClientThread->Process), + WriteConsoleRequest->OutputHandle, + &ScreenBuffer, GENERIC_WRITE, FALSE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvWriteConsole(ScreenBuffer->Header.Console, + ScreenBuffer, + WriteConsoleRequest->Unicode, + WriteConsoleRequest->Buffer, + WriteConsoleRequest->NrCharactersToWrite, + &WriteConsoleRequest->NrCharactersWritten); + + if (Status == STATUS_PENDING) + { + if (CreateWaitBlock) + { + if (!CsrCreateWait(&ScreenBuffer->Header.Console->WriteWaitQueue, + WriteConsoleThread, + ClientThread, + ApiMessage, + NULL, + NULL)) + { + /* Fail */ + Status = STATUS_NO_MEMORY; + goto Quit; + } + } + + /* Wait until we un-pause the console */ + // Status = STATUS_PENDING; + } + +Quit: + ConSrvReleaseScreenBuffer(ScreenBuffer, FALSE); + return Status; +} + + +/* TEXT OUTPUT APIS ***********************************************************/ + +NTSTATUS NTAPI +ConDrvReadConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + OUT PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT ReadRegion); +CSR_API(SrvReadConsoleOutput) +{ + NTSTATUS Status; + PCONSOLE_READOUTPUT ReadOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvReadConsoleOutput\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&ReadOutputRequest->CharInfo, + ReadOutputRequest->BufferSize.X * ReadOutputRequest->BufferSize.Y, + sizeof(CHAR_INFO))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ReadOutputRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvReadConsoleOutput(Buffer->Header.Console, + Buffer, + ReadOutputRequest->Unicode, + ReadOutputRequest->CharInfo, + &ReadOutputRequest->BufferSize, + &ReadOutputRequest->BufferCoord, + &ReadOutputRequest->ReadRegion); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvWriteConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + IN PCHAR_INFO CharInfo/*Buffer*/, + IN PCOORD BufferSize, + IN PCOORD BufferCoord, + IN OUT PSMALL_RECT WriteRegion); +CSR_API(SrvWriteConsoleOutput) +{ + NTSTATUS Status; + PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvWriteConsoleOutput\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteOutputRequest->CharInfo, + WriteOutputRequest->BufferSize.X * WriteOutputRequest->BufferSize.Y, + sizeof(CHAR_INFO))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + WriteOutputRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvWriteConsoleOutput(Buffer->Header.Console, + Buffer, + WriteOutputRequest->Unicode, + WriteOutputRequest->CharInfo, + &WriteOutputRequest->BufferSize, + &WriteOutputRequest->BufferCoord, + &WriteOutputRequest->WriteRegion); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +CSR_API(SrvWriteConsole) +{ + NTSTATUS Status; + PCONSOLE_WRITECONSOLE WriteConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteConsoleRequest; + + DPRINT("SrvWriteConsole\n"); + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID)&WriteConsoleRequest->Buffer, + WriteConsoleRequest->BufferSize, + sizeof(BYTE))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = DoWriteConsole(ApiMessage, + CsrGetClientThread(), + TRUE); + + if (Status == STATUS_PENDING) *ReplyCode = CsrReplyPending; + + return Status; +} + +NTSTATUS NTAPI +ConDrvReadConsoleOutputString(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PCOORD EndCoord, + OUT PULONG CodesRead); +CSR_API(SrvReadConsoleOutputString) +{ + NTSTATUS Status; + PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ReadOutputCodeRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + ULONG CodeSize; + + DPRINT("SrvReadConsoleOutputString\n"); + + switch (ReadOutputCodeRequest->CodeType) + { + case CODE_ASCII: + CodeSize = sizeof(CHAR); + break; + + case CODE_UNICODE: + CodeSize = sizeof(WCHAR); + break; + + case CODE_ATTRIBUTE: + CodeSize = sizeof(WORD); + break; + + default: + return STATUS_INVALID_PARAMETER; + } + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&ReadOutputCodeRequest->pCode.pCode, + ReadOutputCodeRequest->NumCodesToRead, + CodeSize)) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ReadOutputCodeRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvReadConsoleOutputString(Buffer->Header.Console, + Buffer, + ReadOutputCodeRequest->CodeType, + ReadOutputCodeRequest->pCode.pCode, + ReadOutputCodeRequest->NumCodesToRead, + &ReadOutputCodeRequest->ReadCoord, + &ReadOutputCodeRequest->EndCoord, + &ReadOutputCodeRequest->CodesRead); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvWriteConsoleOutputString(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + IN PVOID StringBuffer, + IN ULONG NumCodesToWrite, + IN PCOORD WriteCoord /*, + OUT PCOORD EndCoord, + OUT PULONG CodesWritten */); +CSR_API(SrvWriteConsoleOutputString) +{ + NTSTATUS Status; + PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputCodeRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + ULONG CodeSize; + + DPRINT("SrvWriteConsoleOutputString\n"); + + switch (WriteOutputCodeRequest->CodeType) + { + case CODE_ASCII: + CodeSize = sizeof(CHAR); + break; + + case CODE_UNICODE: + CodeSize = sizeof(WCHAR); + break; + + case CODE_ATTRIBUTE: + CodeSize = sizeof(WORD); + break; + + default: + return STATUS_INVALID_PARAMETER; + } + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteOutputCodeRequest->pCode.pCode, + WriteOutputCodeRequest->Length, + CodeSize)) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + WriteOutputCodeRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvWriteConsoleOutputString(Buffer->Header.Console, + Buffer, + WriteOutputCodeRequest->CodeType, + WriteOutputCodeRequest->pCode.pCode, + WriteOutputCodeRequest->Length, // NumCodesToWrite, + &WriteOutputCodeRequest->Coord /*, // WriteCoord, + &WriteOutputCodeRequest->EndCoord, + &WriteOutputCodeRequest->NrCharactersWritten */); + + // WriteOutputCodeRequest->NrCharactersWritten = Written; + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvFillConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + IN PVOID Code, + IN ULONG NumCodesToWrite, + IN PCOORD WriteCoord /*, + OUT PULONG CodesWritten */); +CSR_API(SrvFillConsoleOutput) +{ + NTSTATUS Status; + PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.FillOutputRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + USHORT CodeType = FillOutputRequest->CodeType; + + DPRINT("SrvFillConsoleOutput\n"); + + if ( (CodeType != CODE_ASCII ) && + (CodeType != CODE_UNICODE ) && + (CodeType != CODE_ATTRIBUTE) ) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + FillOutputRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CodeType, + &FillOutputRequest->Code, + FillOutputRequest->Length, // NumCodesToWrite, + &FillOutputRequest->Coord /*, // WriteCoord, + &FillOutputRequest->NrCharactersWritten */); + + // FillOutputRequest->NrCharactersWritten = Written; + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleScreenBufferInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PCONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo); +CSR_API(SrvGetConsoleScreenBufferInfo) +{ + NTSTATUS Status; + PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScreenBufferInfoRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvGetConsoleScreenBufferInfo\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ScreenBufferInfoRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvGetConsoleScreenBufferInfo(Buffer->Header.Console, + Buffer, + &ScreenBufferInfoRequest->Info); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleTextAttribute(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN WORD Attribute); +CSR_API(SrvSetConsoleTextAttribute) +{ + NTSTATUS Status; + PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetTextAttribRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvSetConsoleTextAttribute\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetTextAttribRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleTextAttribute(Buffer->Header.Console, + Buffer, + SetTextAttribRequest->Attrib); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCOORD Size); +CSR_API(SrvSetConsoleScreenBufferSize) +{ + NTSTATUS Status; + PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetScreenBufferSizeRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvSetConsoleScreenBufferSize\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetScreenBufferSizeRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleScreenBufferSize(Buffer->Header.Console, + Buffer, + &SetScreenBufferSizeRequest->Size); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + IN PSMALL_RECT ScrollRectangle, + IN BOOLEAN UseClipRectangle, + IN PSMALL_RECT ClipRectangle OPTIONAL, + IN PCOORD DestinationOrigin, + IN CHAR_INFO FillChar); +CSR_API(SrvScrollConsoleScreenBuffer) +{ + NTSTATUS Status; + PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ScrollScreenBufferRequest; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT("SrvScrollConsoleScreenBuffer\n"); + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ScrollScreenBufferRequest->OutputHandle, + &Buffer, GENERIC_WRITE, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvScrollConsoleScreenBuffer(Buffer->Header.Console, + Buffer, + ScrollScreenBufferRequest->Unicode, + &ScrollScreenBufferRequest->ScrollRectangle, + ScrollScreenBufferRequest->UseClipRectangle, + &ScrollScreenBufferRequest->ClipRectangle, + &ScrollScreenBufferRequest->DestinationOrigin, + ScrollScreenBufferRequest->Fill); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Absolute, + IN PSMALL_RECT WindowRect); +CSR_API(SrvSetConsoleWindowInfo) +{ + NTSTATUS Status; + PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest; + // PCONSOLE_SCREEN_BUFFER Buffer; + PTEXTMODE_SCREEN_BUFFER Buffer; + + DPRINT1("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n", + SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute, + SetWindowInfoRequest->WindowRect.Left , + SetWindowInfoRequest->WindowRect.Top , + SetWindowInfoRequest->WindowRect.Right, + SetWindowInfoRequest->WindowRect.Bottom); + + // ConSrvGetScreenBuffer + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetWindowInfoRequest->OutputHandle, + &Buffer, GENERIC_READ, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleWindowInfo(Buffer->Header.Console, + Buffer, + SetWindowInfoRequest->Absolute, + &SetWindowInfoRequest->WindowRect); + + ConSrvReleaseScreenBuffer(Buffer, TRUE); + return Status; +} + +/* EOF */ diff --git a/win32ss/user/consrv/conoutput.h b/win32ss/user/winsrv/consrv/conoutput.h similarity index 88% rename from win32ss/user/consrv/conoutput.h rename to win32ss/user/winsrv/consrv/conoutput.h index f10320b53db..966a6abcca6 100644 --- a/win32ss/user/consrv/conoutput.h +++ b/win32ss/user/winsrv/consrv/conoutput.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/conoutput.h + * FILE: win32ss/user/winsrv/consrv/conoutput.h * PURPOSE: Console Output functions * PROGRAMMERS: Jeffrey Morlan * Hermes Belusca-Maito (hermes.belusca@sfr.fr) @@ -33,11 +33,14 @@ #define ConSrvReleaseScreenBuffer(Buff, IsConsoleLocked) \ ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked)) -NTSTATUS FASTCALL ConSrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer, +NTSTATUS FASTCALL ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer, IN OUT PCONSOLE Console, IN ULONG BufferType, IN PVOID ScreenBufferInfo); VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); -VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); +// VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); + +PCONSOLE_SCREEN_BUFFER +ConDrvGetActiveScreenBuffer(IN PCONSOLE Console); /* EOF */ diff --git a/win32ss/user/winsrv/consrv/console.c b/win32ss/user/winsrv/consrv/console.c new file mode 100644 index 00000000000..9403daa081f --- /dev/null +++ b/win32ss/user/winsrv/consrv/console.c @@ -0,0 +1,652 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/console.c + * PURPOSE: Console Management Functions + * PROGRAMMERS: G van Geldorp + * Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "handle.h" +#include "procinit.h" +#include "alias.h" +#include "coninput.h" +#include "conoutput.h" +#include "lineinput.h" +#include "include/settings.h" + +#include "frontends/gui/guiterm.h" +#ifdef TUITERM_COMPILE +#include "frontends/tui/tuiterm.h" +#endif + +#include "include/console.h" +#include "console.h" +#include "resource.h" + +#define NDEBUG +#include + + +/* GLOBALS ********************************************************************/ + +/***************/ +#ifdef TUITERM_COMPILE +NTSTATUS NTAPI +TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, + IN OUT PCONSOLE_INFO ConsoleInfo, + IN OUT PVOID ExtraConsoleInfo, + IN ULONG ProcessId); +NTSTATUS NTAPI +TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd); +#endif + +NTSTATUS NTAPI +GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, + IN OUT PCONSOLE_INFO ConsoleInfo, + IN OUT PVOID ExtraConsoleInfo, + IN ULONG ProcessId); +NTSTATUS NTAPI +GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd); +/***************/ + +typedef +NTSTATUS (NTAPI *FRONTEND_LOAD)(IN OUT PFRONTEND FrontEnd, + IN OUT PCONSOLE_INFO ConsoleInfo, + IN OUT PVOID ExtraConsoleInfo, + IN ULONG ProcessId); + +typedef +NTSTATUS (NTAPI *FRONTEND_UNLOAD)(IN OUT PFRONTEND FrontEnd); + +/* + * If we are not in GUI-mode, start the text-mode terminal emulator. + * If we fail, try to start the GUI-mode terminal emulator. + * + * Try to open the GUI-mode terminal emulator. Two cases are possible: + * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case + * failed and we start GUI-mode terminal emulator. + * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case + * succeeded BUT we failed at starting text-mode terminal emulator. + * Then GuiMode was switched to TRUE in order to try to open the GUI-mode + * terminal emulator (Win32k will automatically switch to graphical mode, + * therefore no additional code is needed). + */ + +/* + * NOTE: Each entry of the table should be retrieved when loading a front-end + * (examples of the CSR servers which register some data for CSRSS). + */ +struct +{ + CHAR FrontEndName[80]; + FRONTEND_LOAD FrontEndLoad; + FRONTEND_UNLOAD FrontEndUnload; +} FrontEndLoadingMethods[] = +{ +#ifdef TUITERM_COMPILE + {"TUI", TuiLoadFrontEnd, TuiUnloadFrontEnd}, +#endif + {"GUI", GuiLoadFrontEnd, GuiUnloadFrontEnd}, + +// {"Not found", 0, NULL} +}; + + +/* PRIVATE FUNCTIONS **********************************************************/ + +#if 0000 +VOID FASTCALL +ConioPause(PCONSOLE Console, UINT Flags) +{ + Console->PauseFlags |= Flags; + if (!Console->UnpauseEvent) + Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +VOID FASTCALL +ConioUnpause(PCONSOLE Console, UINT Flags) +{ + Console->PauseFlags &= ~Flags; + + // if ((Console->PauseFlags & (PAUSED_FROM_KEYBOARD | PAUSED_FROM_SCROLLBAR | PAUSED_FROM_SELECTION)) == 0) + if (Console->PauseFlags == 0 && Console->UnpauseEvent) + { + SetEvent(Console->UnpauseEvent); + CloseHandle(Console->UnpauseEvent); + Console->UnpauseEvent = NULL; + + CsrNotifyWait(&Console->WriteWaitQueue, + WaitAll, + NULL, + NULL); + if (!IsListEmpty(&Console->WriteWaitQueue)) + { + CsrDereferenceWait(&Console->WriteWaitQueue); + } + } +} +#endif + + +NTSTATUS FASTCALL +ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData, + PCONSOLE* Console, + BOOL LockConsole) +{ + NTSTATUS Status = STATUS_SUCCESS; + PCONSOLE ProcessConsole; + + ASSERT(Console); + *Console = NULL; + + // RtlEnterCriticalSection(&ProcessData->HandleTableLock); + + Status = ConDrvGetConsole(&ProcessConsole, ProcessData->ConsoleHandle, LockConsole); + if (NT_SUCCESS(Status)) *Console = ProcessConsole; + + // RtlLeaveCriticalSection(&ProcessData->HandleTableLock); + return Status; +} + +VOID FASTCALL +ConSrvReleaseConsole(PCONSOLE Console, + BOOL WasConsoleLocked) +{ + /* Just call the driver*/ + ConDrvReleaseConsole(Console, WasConsoleLocked); +} + + +NTSTATUS WINAPI +ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, + OUT PCONSOLE* NewConsole, + IN OUT PCONSOLE_START_INFO ConsoleStartInfo, + IN ULONG ConsoleLeaderProcessId) +{ + NTSTATUS Status; + HANDLE ConsoleHandle; + PCONSOLE Console; + CONSOLE_INFO ConsoleInfo; + SIZE_T Length = 0; + ULONG i = 0; + FRONTEND FrontEnd; + + if (NewConsole == NULL || ConsoleStartInfo == NULL) + return STATUS_INVALID_PARAMETER; + + *NewConsole = NULL; + + /* + * Load the console settings + */ + + /* 1. Load the default settings */ + ConSrvGetDefaultSettings(&ConsoleInfo, ConsoleLeaderProcessId); + + /* 2. Get the title of the console (initialize ConsoleInfo.ConsoleTitle) */ + Length = min(wcslen(ConsoleStartInfo->ConsoleTitle), + sizeof(ConsoleInfo.ConsoleTitle) / sizeof(ConsoleInfo.ConsoleTitle[0]) - 1); + wcsncpy(ConsoleInfo.ConsoleTitle, ConsoleStartInfo->ConsoleTitle, Length); + ConsoleInfo.ConsoleTitle[Length] = L'\0'; + + + /* + * Choose an adequate terminal front-end to load, and load it + */ + Status = STATUS_SUCCESS; + for (i = 0; i < sizeof(FrontEndLoadingMethods) / sizeof(FrontEndLoadingMethods[0]); ++i) + { + DPRINT("CONSRV: Trying to load %s terminal emulator...\n", FrontEndLoadingMethods[i].FrontEndName); + Status = FrontEndLoadingMethods[i].FrontEndLoad(&FrontEnd, + &ConsoleInfo, + ConsoleStartInfo, + ConsoleLeaderProcessId); + if (NT_SUCCESS(Status)) + { + DPRINT("CONSRV: %s terminal emulator loaded successfully\n", FrontEndLoadingMethods[i].FrontEndName); + break; + } + else + { + DPRINT1("CONSRV: Loading %s terminal emulator failed, Status = 0x%08lx , continuing...\n", FrontEndLoadingMethods[i].FrontEndName, Status); + } + } + + if (!NT_SUCCESS(Status)) + { + DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status); + return Status; + } + + DPRINT("CONSRV: Frontend initialized\n"); + + +/******************************************************************************/ + /* + * 4. Load the remaining console settings via the registry. + */ + if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) + { + /* + * Either we weren't created by an app launched via a shell-link, + * or we failed to load shell-link console properties. + * Therefore, load the console infos for the application from the registry. + */ + ConSrvReadUserSettings(&ConsoleInfo, ConsoleLeaderProcessId); + + /* + * Now, update them with the properties the user might gave to us + * via the STARTUPINFO structure before calling CreateProcess + * (and which was transmitted via the ConsoleStartInfo structure). + * We therefore overwrite the values read in the registry. + */ + if (ConsoleStartInfo->dwStartupFlags & STARTF_USEFILLATTRIBUTE) + { + ConsoleInfo.ScreenAttrib = (USHORT)ConsoleStartInfo->FillAttribute; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USECOUNTCHARS) + { + ConsoleInfo.ScreenBufferSize = ConsoleStartInfo->ScreenBufferSize; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USESIZE) + { + // ConsoleInfo.ConsoleSize = ConsoleStartInfo->ConsoleWindowSize; + ConsoleInfo.ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx; + ConsoleInfo.ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy; + } + } + + /* Set-up the code page */ + ConsoleInfo.CodePage = GetOEMCP(); +/******************************************************************************/ + + Status = ConDrvInitConsole(&ConsoleHandle, + &Console, + &ConsoleInfo, + ConsoleLeaderProcessId); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Creating a new console failed, Status = 0x%08lx\n", Status); + FrontEndLoadingMethods[i].FrontEndUnload(&FrontEnd); + return Status; + } + + ASSERT(Console); + DPRINT("Console initialized\n"); + + Status = ConDrvRegisterFrontEnd(Console, &FrontEnd); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to register frontend to the given console, Status = 0x%08lx\n", Status); + ConDrvDeleteConsole(Console); + FrontEndLoadingMethods[i].FrontEndUnload(&FrontEnd); + return Status; + } + DPRINT("FrontEnd registered\n"); + + /* Return the newly created console to the caller and a success code too */ + *NewConsoleHandle = ConsoleHandle; + *NewConsole = Console; + return STATUS_SUCCESS; +} + +VOID WINAPI +ConSrvDeleteConsole(PCONSOLE Console) +{ + DPRINT("ConSrvDeleteConsole\n"); + + /* Just call the driver. ConSrvDeregisterFrontEnd is called on-demand. */ + ConDrvDeleteConsole(Console); +} + + +/* PUBLIC SERVER APIS *********************************************************/ + +CSR_API(SrvAllocConsole) +{ + NTSTATUS Status = STATUS_SUCCESS; + PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest; + PCSR_PROCESS CsrProcess = CsrGetClientThread()->Process; + PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrProcess); + + if (ProcessData->ConsoleHandle != NULL) + { + DPRINT1("Process already has a console\n"); + return STATUS_ACCESS_DENIED; + } + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&AllocConsoleRequest->ConsoleStartInfo, + 1, + sizeof(CONSOLE_START_INFO))) + { + return STATUS_INVALID_PARAMETER; + } + + /* Initialize a new Console owned by the Console Leader Process */ + Status = ConSrvAllocateConsole(ProcessData, + &AllocConsoleRequest->InputHandle, + &AllocConsoleRequest->OutputHandle, + &AllocConsoleRequest->ErrorHandle, + AllocConsoleRequest->ConsoleStartInfo); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Console allocation failed\n"); + return Status; + } + + /* Return the console handle and the input wait handle to the caller */ + AllocConsoleRequest->ConsoleHandle = ProcessData->ConsoleHandle; + AllocConsoleRequest->InputWaitHandle = ProcessData->ConsoleEvent; + + /* Set the Property-Dialog and Control-Dispatcher handlers */ + ProcessData->PropDispatcher = AllocConsoleRequest->PropDispatcher; + ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher; + + return STATUS_SUCCESS; +} + +CSR_API(SrvAttachConsole) +{ + NTSTATUS Status = STATUS_SUCCESS; + PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AttachConsoleRequest; + PCSR_PROCESS SourceProcess = NULL; // The parent process. + PCSR_PROCESS TargetProcess = CsrGetClientThread()->Process; // Ourselves. + HANDLE ProcessId = ULongToHandle(AttachConsoleRequest->ProcessId); + PCONSOLE_PROCESS_DATA SourceProcessData, TargetProcessData; + + TargetProcessData = ConsoleGetPerProcessData(TargetProcess); + + if (TargetProcessData->ConsoleHandle != NULL) + { + DPRINT1("Process already has a console\n"); + return STATUS_ACCESS_DENIED; + } + + /* Check whether we try to attach to the parent's console */ + if (ProcessId == ULongToHandle(ATTACH_PARENT_PROCESS)) + { + PROCESS_BASIC_INFORMATION ProcessInfo; + ULONG Length = sizeof(ProcessInfo); + + /* Get the real parent's ID */ + + Status = NtQueryInformationProcess(TargetProcess->ProcessHandle, + ProcessBasicInformation, + &ProcessInfo, + Length, &Length); + if (!NT_SUCCESS(Status)) + { + DPRINT1("SrvAttachConsole - Cannot retrieve basic process info, Status = %lu\n", Status); + return Status; + } + + ProcessId = ULongToHandle(ProcessInfo.InheritedFromUniqueProcessId); + } + + /* Lock the source process via its PID */ + Status = CsrLockProcessByClientId(ProcessId, &SourceProcess); + if (!NT_SUCCESS(Status)) return Status; + + SourceProcessData = ConsoleGetPerProcessData(SourceProcess); + + if (SourceProcessData->ConsoleHandle == NULL) + { + Status = STATUS_INVALID_HANDLE; + goto Quit; + } + + /* + * Inherit the console from the parent, + * if any, otherwise return an error. + */ + Status = ConSrvInheritConsole(TargetProcessData, + SourceProcessData->ConsoleHandle, + TRUE, + &AttachConsoleRequest->InputHandle, + &AttachConsoleRequest->OutputHandle, + &AttachConsoleRequest->ErrorHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Console inheritance failed\n"); + goto Quit; + } + + /* Return the console handle and the input wait handle to the caller */ + AttachConsoleRequest->ConsoleHandle = TargetProcessData->ConsoleHandle; + AttachConsoleRequest->InputWaitHandle = TargetProcessData->ConsoleEvent; + + /* Set the Property-Dialog and Control-Dispatcher handlers */ + TargetProcessData->PropDispatcher = AttachConsoleRequest->PropDispatcher; + TargetProcessData->CtrlDispatcher = AttachConsoleRequest->CtrlDispatcher; + + Status = STATUS_SUCCESS; + +Quit: + /* Unlock the "source" process and exit */ + CsrUnlockProcess(SourceProcess); + return Status; +} + +CSR_API(SrvFreeConsole) +{ + ConSrvRemoveConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process)); + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI +ConDrvGetConsoleMode(IN PCONSOLE Console, + IN PCONSOLE_IO_OBJECT Object, + OUT PULONG ConsoleMode); +CSR_API(SrvGetConsoleMode) +{ + NTSTATUS Status; + PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest; + PCONSOLE_IO_OBJECT Object; + + Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ConsoleModeRequest->ConsoleHandle, + &Object, NULL, GENERIC_READ, TRUE, 0); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvGetConsoleMode(Object->Console, Object, + &ConsoleModeRequest->ConsoleMode); + + ConSrvReleaseObject(Object, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleMode(IN PCONSOLE Console, + IN PCONSOLE_IO_OBJECT Object, + IN ULONG ConsoleMode); +CSR_API(SrvSetConsoleMode) +{ + NTSTATUS Status; + PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest; + PCONSOLE_IO_OBJECT Object; + + Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ConsoleModeRequest->ConsoleHandle, + &Object, NULL, GENERIC_WRITE, TRUE, 0); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleMode(Object->Console, Object, + ConsoleModeRequest->ConsoleMode); + + ConSrvReleaseObject(Object, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleTitle(IN PCONSOLE Console, + IN OUT PWCHAR Title, + IN OUT PULONG BufLength); +CSR_API(SrvGetConsoleTitle) +{ + NTSTATUS Status; + PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest; + PCONSOLE Console; + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID)&TitleRequest->Title, + TitleRequest->Length, + sizeof(BYTE))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Can't get console\n"); + return Status; + } + + Status = ConDrvGetConsoleTitle(Console, + TitleRequest->Title, + &TitleRequest->Length); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleTitle(IN PCONSOLE Console, + IN PWCHAR Title, + IN ULONG BufLength); +CSR_API(SrvSetConsoleTitle) +{ + NTSTATUS Status; + PCONSOLE_GETSETCONSOLETITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest; + PCONSOLE Console; + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID)&TitleRequest->Title, + TitleRequest->Length, + sizeof(BYTE))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Can't get console\n"); + return Status; + } + + Status = ConDrvSetConsoleTitle(Console, + TitleRequest->Title, + TitleRequest->Length); + + if (NT_SUCCESS(Status)) ConioChangeTitle(Console); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleCP(IN PCONSOLE Console, + OUT PUINT CodePage, + IN BOOLEAN InputCP); +CSR_API(SrvGetConsoleCP) +{ + NTSTATUS Status; + PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest; + PCONSOLE Console; + + DPRINT("SrvGetConsoleCP, getting %s Code Page\n", + ConsoleCPRequest->InputCP ? "Input" : "Output"); + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvGetConsoleCP(Console, + &ConsoleCPRequest->CodePage, + ConsoleCPRequest->InputCP); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvSetConsoleCP(IN PCONSOLE Console, + IN UINT CodePage, + IN BOOLEAN InputCP); +CSR_API(SrvSetConsoleCP) +{ + NTSTATUS Status = STATUS_INVALID_PARAMETER; + PCONSOLE_GETSETINPUTOUTPUTCP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest; + PCONSOLE Console; + + DPRINT("SrvSetConsoleCP, setting %s Code Page\n", + ConsoleCPRequest->InputCP ? "Input" : "Output"); + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvSetConsoleCP(Console, + ConsoleCPRequest->CodePage, + ConsoleCPRequest->InputCP); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +NTSTATUS NTAPI +ConDrvGetConsoleProcessList(IN PCONSOLE Console, + IN OUT PULONG ProcessIdsList, + IN ULONG MaxIdListItems, + OUT PULONG ProcessIdsTotal); +CSR_API(SrvGetConsoleProcessList) +{ + NTSTATUS Status; + PCONSOLE_GETPROCESSLIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest; + PCONSOLE Console; + + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID)&GetProcessListRequest->pProcessIds, + GetProcessListRequest->nMaxIds, + sizeof(DWORD))) + { + return STATUS_INVALID_PARAMETER; + } + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvGetConsoleProcessList(Console, + GetProcessListRequest->pProcessIds, + GetProcessListRequest->nMaxIds, + &GetProcessListRequest->nProcessIdsTotal); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +CSR_API(SrvGenerateConsoleCtrlEvent) +{ + NTSTATUS Status; + PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEventRequest; + PCONSOLE Console; + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = ConDrvConsoleProcessCtrlEvent(Console, + GenerateCtrlEventRequest->ProcessGroup, + GenerateCtrlEventRequest->Event); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +/* EOF */ diff --git a/win32ss/user/consrv/console.h b/win32ss/user/winsrv/consrv/console.h similarity index 65% rename from win32ss/user/consrv/console.h rename to win32ss/user/winsrv/consrv/console.h index 3a802671581..b617da888c7 100644 --- a/win32ss/user/consrv/console.h +++ b/win32ss/user/winsrv/consrv/console.h @@ -1,19 +1,23 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/console.h + * FILE: win32ss/user/winsrv/consrv/console.h * PURPOSE: Console Initialization Functions * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ #pragma once -VOID WINAPI ConSrvInitConsoleSupport(VOID); +// FIXME: Fix compilation +struct _CONSOLE; -NTSTATUS WINAPI ConSrvInitConsole(OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole, - IN OUT PCONSOLE_START_INFO ConsoleStartInfo, - IN PCSR_PROCESS ConsoleLeaderProcess); +NTSTATUS WINAPI +ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, + OUT struct _CONSOLE** /* PCONSOLE* */ NewConsole, + IN OUT PCONSOLE_START_INFO ConsoleStartInfo, + IN ULONG ConsoleLeaderProcessId); VOID WINAPI ConSrvDeleteConsole(struct _CONSOLE* /* PCONSOLE */ Console); + NTSTATUS FASTCALL ConSrvGetConsole(PCONSOLE_PROCESS_DATA ProcessData, struct _CONSOLE** /* PCONSOLE* */ Console, BOOL LockConsole); diff --git a/win32ss/user/consrv/consrv.h b/win32ss/user/winsrv/consrv/consrv.h similarity index 92% rename from win32ss/user/consrv/consrv.h rename to win32ss/user/winsrv/consrv/consrv.h index 335bdc510fc..7a07e3bafb8 100644 --- a/win32ss/user/consrv/consrv.h +++ b/win32ss/user/winsrv/consrv/consrv.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/consrv.h + * FILE: win32ss/user/winsrv/consrv/consrv.h * PURPOSE: Main header - Definitions * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ @@ -60,8 +60,9 @@ typedef struct _CONSOLE_PROCESS_DATA LIST_ENTRY ConsoleLink; PCSR_PROCESS Process; // Process owning this structure. HANDLE ConsoleEvent; - struct _CONSOLE* /* PCONSOLE */ Console; - struct _CONSOLE* /* PCONSOLE */ ParentConsole; + + HANDLE ConsoleHandle; + HANDLE ParentConsoleHandle; BOOL ConsoleApp; // TRUE if it is a CUI app, FALSE otherwise. diff --git a/win32ss/user/winsrv/consrv/consrv.rc b/win32ss/user/winsrv/consrv/consrv.rc new file mode 100644 index 00000000000..3e6479868de --- /dev/null +++ b/win32ss/user/winsrv/consrv/consrv.rc @@ -0,0 +1,6 @@ +#include +#include +#include "resource.h" + +#include "rsrc.rc" +#include "frontends/frontends.rc" diff --git a/win32ss/user/winsrv/consrv/frontendctl.c b/win32ss/user/winsrv/consrv/frontendctl.c new file mode 100644 index 00000000000..92c147a5a36 --- /dev/null +++ b/win32ss/user/winsrv/consrv/frontendctl.c @@ -0,0 +1,331 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/frontendctl.c + * PURPOSE: Terminal Front-Ends Control + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "conoutput.h" +#include "console.h" +#include "handle.h" + +#define NDEBUG +#include + + +/* PRIVATE FUNCTIONS **********************************************************/ + + +/* PUBLIC SERVER APIS *********************************************************/ + +/********************************************************************** + * HardwareStateProperty + * + * DESCRIPTION + * Set/Get the value of the HardwareState and switch + * between direct video buffer ouput and GDI windowed + * output. + * ARGUMENTS + * Client hands us a CONSOLE_GETSETHWSTATE object. + * We use the same object to Request. + * NOTE + * ConsoleHwState has the correct size to be compatible + * with NT's, but values are not. + */ +#if 0 +static NTSTATUS FASTCALL +SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState) +{ + DPRINT1("Console Hardware State: %d\n", ConsoleHwState); + + if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) + ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) + { + if (Console->HardwareState != ConsoleHwState) + { + /* TODO: implement switching from full screen to windowed mode */ + /* TODO: or back; now simply store the hardware state */ + Console->HardwareState = ConsoleHwState; + } + + return STATUS_SUCCESS; + } + + return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */ +} +#endif + +CSR_API(SrvGetConsoleHardwareState) +{ +#if 0 + NTSTATUS Status; + PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest; + PCONSOLE_SCREEN_BUFFER Buff; + PCONSOLE Console; + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + HardwareStateRequest->OutputHandle, + &Buff, + GENERIC_READ, + TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n"); + return Status; + } + + Console = Buff->Header.Console; + HardwareStateRequest->State = Console->HardwareState; + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return Status; +#else + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +#endif +} + +CSR_API(SrvSetConsoleHardwareState) +{ +#if 0 + NTSTATUS Status; + PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest; + PCONSOLE_SCREEN_BUFFER Buff; + PCONSOLE Console; + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + HardwareStateRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n"); + return Status; + } + + DPRINT("Setting console hardware state.\n"); + Console = Buff->Header.Console; + Status = SetConsoleHardwareState(Console, HardwareStateRequest->State); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return Status; +#else + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +#endif +} + +CSR_API(SrvGetConsoleDisplayMode) +{ + NTSTATUS Status; + PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetDisplayModeRequest; + PCONSOLE Console; + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + GetDisplayModeRequest->DisplayMode = ConioGetDisplayMode(Console); + + ConSrvReleaseConsole(Console, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvSetConsoleDisplayMode) +{ + NTSTATUS Status; + PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest; + PCONSOLE Console; + PCONSOLE_SCREEN_BUFFER Buff; + + Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetDisplayModeRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Console = Buff->Header.Console; + + if (ConioSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode)) + { + SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize; + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return Status; +} + +CSR_API(SrvGetLargestConsoleWindowSize) +{ + NTSTATUS Status; + PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetLargestWindowSizeRequest; + PCONSOLE_SCREEN_BUFFER Buff; + PCONSOLE Console; + + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + GetLargestWindowSizeRequest->OutputHandle, + &Buff, + GENERIC_READ, + TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Console = Buff->Header.Console; + ConioGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvShowConsoleCursor) +{ + NTSTATUS Status; + PCONSOLE_SHOWCURSOR ShowCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ShowCursorRequest; + PCONSOLE Console; + PCONSOLE_SCREEN_BUFFER Buff; + + Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + ShowCursorRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Console = Buff->Header.Console; + + ShowCursorRequest->RefCount = ConioShowMouseCursor(Console, ShowCursorRequest->Show); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvSetConsoleCursor) +{ + NTSTATUS Status; + BOOL Success; + PCONSOLE_SETCURSOR SetCursorRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetCursorRequest; + PCONSOLE Console; + PCONSOLE_SCREEN_BUFFER Buff; + + // FIXME: Tests show that this function is used only for graphics screen buffers + // and otherwise it returns false + set last error to invalid handle. + // NOTE: I find that behaviour is ridiculous but ok, let's accept that at the moment... + Status = ConSrvGetGraphicsBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetCursorRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Console = Buff->Header.Console; + + Success = ConioSetMouseCursor(Console, SetCursorRequest->hCursor); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); +} + +CSR_API(SrvConsoleMenuControl) +{ + NTSTATUS Status; + PCONSOLE_MENUCONTROL MenuControlRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.MenuControlRequest; + PCONSOLE Console; + PCONSOLE_SCREEN_BUFFER Buff; + + Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + MenuControlRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Console = Buff->Header.Console; + + MenuControlRequest->hMenu = ConioMenuControl(Console, + MenuControlRequest->dwCmdIdLow, + MenuControlRequest->dwCmdIdHigh); + + ConSrvReleaseScreenBuffer(Buff, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvSetConsoleMenuClose) +{ + NTSTATUS Status; + BOOL Success; + PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetMenuCloseRequest; + PCONSOLE Console; + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Success = ConioSetMenuClose(Console, SetMenuCloseRequest->Enable); + + ConSrvReleaseConsole(Console, TRUE); + return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); +} + +CSR_API(SrvGetConsoleWindow) +{ + NTSTATUS Status; + PCONSOLE_GETWINDOW GetWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetWindowRequest; + PCONSOLE Console; + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + GetWindowRequest->WindowHandle = ConioGetConsoleWindowHandle(Console); + + ConSrvReleaseConsole(Console, TRUE); + return STATUS_SUCCESS; +} + +CSR_API(SrvSetConsoleIcon) +{ + NTSTATUS Status; + PCONSOLE_SETICON SetIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetIconRequest; + PCONSOLE Console; + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (!NT_SUCCESS(Status)) return Status; + + Status = (ConioChangeIcon(Console, SetIconRequest->WindowIcon) + ? STATUS_SUCCESS + : STATUS_UNSUCCESSFUL); + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +CSR_API(SrvGetConsoleSelectionInfo) +{ + NTSTATUS Status; + PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetSelectionInfoRequest; + PCONSOLE Console; + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE); + if (NT_SUCCESS(Status)) + { + memset(&GetSelectionInfoRequest->Info, 0, sizeof(CONSOLE_SELECTION_INFO)); + if (Console->Selection.dwFlags != 0) + GetSelectionInfoRequest->Info = Console->Selection; + ConSrvReleaseConsole(Console, TRUE); + } + + return Status; +} + +/* EOF */ diff --git a/win32ss/user/consrv/frontends/frontends.rc b/win32ss/user/winsrv/consrv/frontends/frontends.rc similarity index 100% rename from win32ss/user/consrv/frontends/frontends.rc rename to win32ss/user/winsrv/consrv/frontends/frontends.rc diff --git a/win32ss/user/consrv/frontends/gui/consolecpl.h b/win32ss/user/winsrv/consrv/frontends/gui/consolecpl.h similarity index 84% rename from win32ss/user/consrv/frontends/gui/consolecpl.h rename to win32ss/user/winsrv/consrv/frontends/gui/consolecpl.h index d5aeebcf73e..b33b7174217 100644 --- a/win32ss/user/consrv/frontends/gui/consolecpl.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/consolecpl.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/consolecpl.h + * FILE: win32ss/user/winsrv/consrv/consolecpl.h * PURPOSE: GUI front-end settings management - Header for console.dll * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ diff --git a/win32ss/user/consrv/frontends/gui/graphics.c b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c similarity index 97% rename from win32ss/user/consrv/frontends/gui/graphics.c rename to win32ss/user/winsrv/consrv/frontends/gui/graphics.c index 43df51cffa1..58267a7c15a 100644 --- a/win32ss/user/consrv/frontends/gui/graphics.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/gui/graphics.c + * FILE: win32ss/user/winsrv/consrv/frontends/gui/graphics.c * PURPOSE: GUI Terminal Front-End - Support for graphics-mode screen-buffers * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ diff --git a/win32ss/user/consrv/frontends/gui/guisettings.c b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c similarity index 99% rename from win32ss/user/consrv/frontends/gui/guisettings.c rename to win32ss/user/winsrv/consrv/frontends/gui/guisettings.c index 7b9a72b17a1..dc22dfc9cd5 100644 --- a/win32ss/user/consrv/frontends/gui/guisettings.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/gui/guisettings.c + * FILE: win32ss/user/winsrv/consrv/frontends/gui/guisettings.c * PURPOSE: GUI Terminal Front-End Settings Management * PROGRAMMERS: Johannes Anderwald * Hermes Belusca-Maito (hermes.belusca@sfr.fr) diff --git a/win32ss/user/consrv/frontends/gui/guisettings.h b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h similarity index 98% rename from win32ss/user/consrv/frontends/gui/guisettings.h rename to win32ss/user/winsrv/consrv/frontends/gui/guisettings.h index 607129d749a..0b0201178be 100644 --- a/win32ss/user/consrv/frontends/gui/guisettings.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/guisettings.h + * FILE: win32ss/user/winsrv/consrv/guisettings.h * PURPOSE: GUI front-end settings management * PROGRAMMERS: Johannes Anderwald * Hermes Belusca-Maito (hermes.belusca@sfr.fr) diff --git a/win32ss/user/consrv/frontends/gui/guiterm.c b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c similarity index 84% rename from win32ss/user/consrv/frontends/gui/guiterm.c rename to win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index 53485d49d4a..a974e9b47b0 100644 --- a/win32ss/user/consrv/frontends/gui/guiterm.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/gui/guiterm.c + * FILE: win32ss/user/winsrv/consrv/frontends/gui/guiterm.c * PURPOSE: GUI Terminal Front-End * PROGRAMMERS: G van Geldorp * Johannes Anderwald @@ -11,16 +11,23 @@ /* INCLUDES *******************************************************************/ +#define COBJMACROS +#define NONAMELESSUNION + #include "consrv.h" #include "include/conio.h" #include "include/console.h" #include "include/settings.h" +#include "conoutput.h" #include "guiterm.h" #include "guisettings.h" #include "resource.h" #include +#include +#include + #define NDEBUG #include @@ -38,17 +45,19 @@ /* Not defined in any header file */ -// extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); -// From win32ss/user/win32csr/dllmain.c -VOID -WINAPI -PrivateCsrssManualGuiCheck(LONG Check) -{ - NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK); -} +extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); +// See winsrv/usersrv/init.c line 234 + /* GLOBALS ********************************************************************/ +typedef struct _GUI_INIT_INFO +{ + PCONSOLE_INFO ConsoleInfo; + PCONSOLE_START_INFO ConsoleStartInfo; + ULONG ProcessId; +} GUI_INIT_INFO, *PGUI_INIT_INFO; + /**************************************************************\ \** Define the Console Leader Process for the console window **/ #define GWLP_CONSOLEWND_ALLOC (2 * sizeof(LONG_PTR)) @@ -129,6 +138,32 @@ const COLORREF s_Colors[16] = /* FUNCTIONS ******************************************************************/ +static VOID +GetScreenBufferSizeUnits(IN PCONSOLE_SCREEN_BUFFER Buffer, + IN PGUI_CONSOLE_DATA GuiData, + OUT PUINT WidthUnit, + OUT PUINT HeightUnit) +{ + if (Buffer == NULL || GuiData == NULL || + WidthUnit == NULL || HeightUnit == NULL) + { + return; + } + + if (GetType(Buffer) == TEXTMODE_BUFFER) + { + *WidthUnit = GuiData->CharWidth ; + *HeightUnit = GuiData->CharHeight; + } + else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */ + { + *WidthUnit = 1; + *HeightUnit = 1; + } +} + + + static VOID GuiConsoleAppendMenuItems(HMENU hMenu, const GUICONSOLE_MENUITEM *Items) @@ -212,7 +247,7 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData); static VOID GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord); static VOID WINAPI -GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region); +GuiDrawRegion(IN OUT PFRONTEND This, SMALL_RECT* Region); static VOID GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData); @@ -224,12 +259,12 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM PCONSOLE Console = GuiData->Console; PCONSOLE_SCREEN_BUFFER ActiveBuffer; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { Ret = FALSE; goto Quit; } - ActiveBuffer = Console->ActiveBuffer; + ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); /* * In case the selected menu item belongs to the user-reserved menu id range, @@ -354,22 +389,13 @@ static VOID GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PCONSOLE_SCREEN_BUFFER Buff = ConDrvGetActiveScreenBuffer(Console); SCROLLINFO sInfo; DWORD Width, Height; UINT WidthUnit, HeightUnit; - if (GetType(Buff) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Buff) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); Width = Buff->ViewSize.X * WidthUnit + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); @@ -421,7 +447,7 @@ GuiConsoleSwitchFullScreen(PGUI_CONSOLE_DATA GuiData) PCONSOLE Console = GuiData->Console; // DEVMODE dmScreenSettings; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; /* Switch to full-screen or to windowed mode */ GuiData->GuiInfo.FullScreen = !GuiData->GuiInfo.FullScreen; @@ -559,19 +585,10 @@ static VOID SmallRectToRect(PGUI_CONSOLE_DATA GuiData, PRECT Rect, PSMALL_RECT SmallRect) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console); UINT WidthUnit, HeightUnit; - if (GetType(Buffer) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(Buffer, GuiData, &WidthUnit, &HeightUnit); Rect->left = (SmallRect->Left - Buffer->ViewOrigin.X) * WidthUnit ; Rect->top = (SmallRect->Top - Buffer->ViewOrigin.Y) * HeightUnit; @@ -661,12 +678,12 @@ GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData) HDC hDC; PAINTSTRUCT ps; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { Success = FALSE; goto Quit; } - ActiveBuffer = Console->ActiveBuffer; + ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); hDC = BeginPaint(GuiData->hWindow, &ps); if (hDC != NULL && @@ -745,9 +762,9 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l PCONSOLE Console = GuiData->Console; PCONSOLE_SCREEN_BUFFER ActiveBuffer; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - ActiveBuffer = Console->ActiveBuffer; + ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) { @@ -903,10 +920,10 @@ Quit: } static VOID -GuiInvalidateCell(PCONSOLE Console, SHORT x, SHORT y) +GuiInvalidateCell(IN OUT PFRONTEND This, SHORT x, SHORT y) { SMALL_RECT CellRect = { x, y, x, y }; - GuiDrawRegion(Console, &CellRect); + GuiDrawRegion(This, &CellRect); } static VOID @@ -917,13 +934,13 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - Buff = Console->ActiveBuffer; + Buff = ConDrvGetActiveScreenBuffer(Console); if (GetType(Buff) == TEXTMODE_BUFFER) { - GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y); + GuiInvalidateCell(&Console->TermIFace, Buff->CursorPosition.X, Buff->CursorPosition.Y); Buff->CursorBlinkOn = !Buff->CursorBlinkOn; if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y)) @@ -1006,35 +1023,36 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) LeaveCriticalSection(&Console->Lock); } -static VOID +static BOOL GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData) { PCONSOLE Console = GuiData->Console; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; + + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + return TRUE; + + // TODO: Prompt for termination ? (Warn the user about possible apps running in this console) /* * FIXME: Windows will wait up to 5 seconds for the thread to exit. * We shouldn't wait here, though, since the console lock is entered. * A copy of the thread list probably needs to be made. */ - ConSrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT); + ConDrvConsoleProcessCtrlEvent(Console, 0, CTRL_CLOSE_EVENT); LeaveCriticalSection(&Console->Lock); + return FALSE; } static LRESULT GuiConsoleHandleNcDestroy(HWND hWnd) { - // PGUI_CONSOLE_DATA GuiData; - KillTimer(hWnd, CONGUI_UPDATE_TIMER); GetSystemMenu(hWnd, TRUE); /* Free the GuiData registration */ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)NULL); - // GuiData->hWindow = NULL; - // return 0; return DefWindowProcW(hWnd, WM_NCDESTROY, 0, 0); } @@ -1042,20 +1060,11 @@ static COORD PointToCoord(PGUI_CONSOLE_DATA GuiData, LPARAM lParam) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console); COORD Coord; UINT WidthUnit, HeightUnit; - if (GetType(Buffer) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(Buffer, GuiData, &WidthUnit, &HeightUnit); Coord.X = Buffer->ViewOrigin.X + ((SHORT)LOWORD(lParam) / (int)WidthUnit ); Coord.Y = Buffer->ViewOrigin.Y + ((SHORT)HIWORD(lParam) / (int)HeightUnit); @@ -1103,7 +1112,7 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM goto Quit; } - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { Err = TRUE; goto Quit; @@ -1330,7 +1339,7 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData) if (OpenClipboard(GuiData->hWindow) == TRUE) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console); if (GetType(Buffer) == TEXTMODE_BUFFER) { @@ -1358,7 +1367,7 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData) if (OpenClipboard(GuiData->hWindow) == TRUE) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = Console->ActiveBuffer; + PCONSOLE_SCREEN_BUFFER Buffer = ConDrvGetActiveScreenBuffer(Console); if (GetType(Buffer) == TEXTMODE_BUFFER) { @@ -1381,20 +1390,11 @@ GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo) DWORD windx, windy; UINT WidthUnit, HeightUnit; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - ActiveBuffer = Console->ActiveBuffer; + ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); - if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit); windx = CONGUI_MIN_WIDTH * WidthUnit + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); windy = CONGUI_MIN_HEIGHT * HeightUnit + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); @@ -1419,25 +1419,16 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam) { PCONSOLE Console = GuiData->Console; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) { - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PCONSOLE_SCREEN_BUFFER Buff = ConDrvGetActiveScreenBuffer(Console); DWORD windx, windy, charx, chary; UINT WidthUnit, HeightUnit; - if (GetType(Buff) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Buff) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); GuiData->WindowSizeLock = TRUE; @@ -1525,9 +1516,9 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam) int old_pos, Maximum; PSHORT pShowXY; - if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0; + if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0; - Buff = Console->ActiveBuffer; + Buff = ConDrvGetActiveScreenBuffer(Console); if (uMsg == WM_HSCROLL) { @@ -1600,16 +1591,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam) *pShowXY = sInfo.nPos; - if (GetType(Buff) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Buff) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); ScrollWindowEx(GuiData->hWindow, (OldX - Buff->ViewOrigin.X) * WidthUnit , @@ -1659,7 +1641,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) * If there is no data, just go away. */ GuiData = GuiGetGuiData(hWnd); - if (GuiData == NULL) return 0; + if (GuiData == NULL) return DefWindowProcW(hWnd, msg, wParam, lParam); /* * Just retrieve a pointer to the console in case somebody needs it. @@ -1678,7 +1660,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } case WM_CLOSE: - GuiConsoleHandleClose(GuiData); + if (GuiConsoleHandleClose(GuiData)) goto Default; break; case WM_PAINT: @@ -1846,7 +1828,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED)); } - if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { GuiSendMenuEvent(Console, WM_INITMENU); LeaveCriticalSection(&Console->Lock); @@ -1858,7 +1840,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (HIWORD(wParam) == 0xFFFF) // Allow all the menu flags { - if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { GuiSendMenuEvent(Console, WM_MENUSELECT); LeaveCriticalSection(&Console->Lock); @@ -1877,7 +1859,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_SETFOCUS: case WM_KILLFOCUS: { - if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { INPUT_RECORD er; er.EventType = FOCUS_EVENT; @@ -1913,7 +1895,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case PM_APPLY_CONSOLE_INFO: { - if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { GuiApplyUserSettings(GuiData, (HANDLE)wParam, (BOOL)lParam); LeaveCriticalSection(&Console->Lock); @@ -2219,9 +2201,190 @@ GuiInit(VOID) ******************************************************************************/ static VOID WINAPI -GuiCleanupConsole(PCONSOLE Console) +GuiDeinitFrontEnd(IN OUT PFRONTEND This); + +NTSTATUS NTAPI +GuiInitFrontEnd(IN OUT PFRONTEND This, + IN PCONSOLE Console) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_INIT_INFO GuiInitInfo; + PCONSOLE_INFO ConsoleInfo; + PCONSOLE_START_INFO ConsoleStartInfo; + + PGUI_CONSOLE_DATA GuiData; + GUI_CONSOLE_INFO TermInfo; + + SIZE_T Length = 0; + LPWSTR IconPath = NULL; + INT IconIndex = 0; + + if (This == NULL || Console == NULL || This->OldData == NULL) + return STATUS_INVALID_PARAMETER; + + ASSERT(This->Console == Console); + + GuiInitInfo = This->OldData; + + if (GuiInitInfo->ConsoleInfo == NULL || GuiInitInfo->ConsoleStartInfo == NULL) + return STATUS_INVALID_PARAMETER; + + ConsoleInfo = GuiInitInfo->ConsoleInfo; + ConsoleStartInfo = GuiInitInfo->ConsoleStartInfo; + + IconPath = ConsoleStartInfo->IconPath; + IconIndex = ConsoleStartInfo->IconIndex; + + + /* Terminal data allocation */ + GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA)); + if (!GuiData) + { + DPRINT1("CONSRV: Failed to create GUI_CONSOLE_DATA\n"); + return STATUS_UNSUCCESSFUL; + } + /* HACK */ Console->TermIFace.Data = (PVOID)GuiData; /* HACK */ + GuiData->Console = Console; + GuiData->hWindow = NULL; + + /* The console can be resized */ + Console->FixedSize = FALSE; + + InitializeCriticalSection(&GuiData->Lock); + + + /* + * Load terminal settings + */ + + /* 1. Load the default settings */ + GuiConsoleGetDefaultSettings(&TermInfo, GuiInitInfo->ProcessId); + + /* 3. Load the remaining console settings via the registry. */ + if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) + { + /* Load the terminal infos from the registry. */ + GuiConsoleReadUserSettings(&TermInfo, + ConsoleInfo->ConsoleTitle, + GuiInitInfo->ProcessId); + + /* + * Now, update them with the properties the user might gave to us + * via the STARTUPINFO structure before calling CreateProcess + * (and which was transmitted via the ConsoleStartInfo structure). + * We therefore overwrite the values read in the registry. + */ + if (ConsoleStartInfo->dwStartupFlags & STARTF_USESHOWWINDOW) + { + TermInfo.ShowWindow = ConsoleStartInfo->ShowWindow; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION) + { + TermInfo.AutoPosition = FALSE; + TermInfo.WindowOrigin = ConsoleStartInfo->ConsoleWindowOrigin; + } + if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN) + { + TermInfo.FullScreen = TRUE; + } + } + + + /* + * Set up GUI data + */ + + Length = min(wcslen(TermInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen + wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE); + GuiData->GuiInfo.FaceName[Length] = L'\0'; + GuiData->GuiInfo.FontFamily = TermInfo.FontFamily; + GuiData->GuiInfo.FontSize = TermInfo.FontSize; + GuiData->GuiInfo.FontWeight = TermInfo.FontWeight; + GuiData->GuiInfo.UseRasterFonts = TermInfo.UseRasterFonts; + GuiData->GuiInfo.FullScreen = TermInfo.FullScreen; + GuiData->GuiInfo.ShowWindow = TermInfo.ShowWindow; + GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition; + GuiData->GuiInfo.WindowOrigin = TermInfo.WindowOrigin; + + /* Initialize the icon handles to their default values */ + GuiData->hIcon = ghDefaultIcon; + GuiData->hIconSm = ghDefaultIconSm; + + /* Get the associated icon, if any */ + if (IconPath == NULL || IconPath[0] == L'\0') + { + IconPath = ConsoleStartInfo->AppPath; + IconIndex = 0; + } + DPRINT("IconPath = %S ; IconIndex = %lu\n", (IconPath ? IconPath : L"n/a"), IconIndex); + if (IconPath && IconPath[0] != L'\0') + { + HICON hIcon = NULL, hIconSm = NULL; + PrivateExtractIconExW(IconPath, + IconIndex, + &hIcon, + &hIconSm, + 1); + DPRINT("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm); + if (hIcon != NULL) + { + DPRINT("Effectively set the icons\n"); + GuiData->hIcon = hIcon; + GuiData->hIconSm = hIconSm; + } + } + + /* Mouse is shown by default with its default cursor shape */ + GuiData->hCursor = ghDefaultCursor; + GuiData->MouseCursorRefCount = 0; + + /* A priori don't ignore mouse signals */ + GuiData->IgnoreNextMouseSignal = FALSE; + + /* Close button and the corresponding system menu item are enabled by default */ + GuiData->IsCloseButtonEnabled = TRUE; + + /* There is no user-reserved menu id range by default */ + GuiData->cmdIdLow = GuiData->cmdIdHigh = 0; + + /* + * We need to wait until the GUI has been fully initialized + * to retrieve custom settings i.e. WindowSize etc... + * Ideally we could use SendNotifyMessage for this but its not + * yet implemented. + */ + GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + + DPRINT("GUI - Checkpoint\n"); + + /* Create the terminal window */ + PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, GuiData->GuiInfo.ShowWindow, (LPARAM)GuiData); + + /* Wait until initialization has finished */ + WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); + DPRINT("OK we created the console window\n"); + CloseHandle(GuiData->hGuiInitEvent); + GuiData->hGuiInitEvent = NULL; + + /* Check whether we really succeeded in initializing the terminal window */ + if (GuiData->hWindow == NULL) + { + DPRINT("GuiInitConsole - We failed at creating a new terminal window\n"); + GuiDeinitFrontEnd(This); + return STATUS_UNSUCCESSFUL; + } + + /* Finally, finish to initialize the frontend structure */ + This->Data = GuiData; + if (This->OldData) ConsoleFreeHeap(This->OldData); + This->OldData = NULL; + + return STATUS_SUCCESS; +} + +static VOID WINAPI +GuiDeinitFrontEnd(IN OUT PFRONTEND This) +{ + PGUI_CONSOLE_DATA GuiData = This->Data; SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM)GuiData); @@ -2238,17 +2401,18 @@ GuiCleanupConsole(PCONSOLE Console) DestroyIcon(GuiData->hIconSm); } - Console->TermIFace.Data = NULL; + This->Data = NULL; DeleteCriticalSection(&GuiData->Lock); ConsoleFreeHeap(GuiData); - DPRINT("Quit GuiCleanupConsole\n"); + DPRINT("Quit GuiDeinitFrontEnd\n"); } static VOID WINAPI -GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region) +GuiDrawRegion(IN OUT PFRONTEND This, + SMALL_RECT* Region) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; RECT RegionRect; SmallRectToRect(GuiData, &RegionRect, Region); @@ -2257,15 +2421,22 @@ GuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region) } static VOID WINAPI -GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY, - UINT ScrolledLines, PWCHAR Buffer, UINT Length) +GuiWriteStream(IN OUT PFRONTEND This, + SMALL_RECT* Region, + SHORT CursorStartX, + SHORT CursorStartY, + UINT ScrolledLines, + PWCHAR Buffer, + UINT Length) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; - PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; + PGUI_CONSOLE_DATA GuiData = This->Data; + PCONSOLE_SCREEN_BUFFER Buff; SHORT CursorEndX, CursorEndY; RECT ScrollRect; if (NULL == GuiData || NULL == GuiData->hWindow) return; + + Buff = ConDrvGetActiveScreenBuffer(GuiData->Console); if (GetType(Buff) != TEXTMODE_BUFFER) return; if (0 != ScrolledLines) @@ -2285,12 +2456,12 @@ GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT C SW_INVALIDATE); } - GuiDrawRegion(Console, Region); + GuiDrawRegion(This, Region); if (CursorStartX < Region->Left || Region->Right < CursorStartX || CursorStartY < Region->Top || Region->Bottom < CursorStartY) { - GuiInvalidateCell(Console, CursorStartX, CursorStartY); + GuiInvalidateCell(This, CursorStartX, CursorStartY); } CursorEndX = Buff->CursorPosition.X; @@ -2299,7 +2470,7 @@ GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT C || CursorEndY < Region->Top || Region->Bottom < CursorEndY) && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) { - GuiInvalidateCell(Console, CursorEndX, CursorEndY); + GuiInvalidateCell(This, CursorEndX, CursorEndY); } // Set up the update timer (very short interval) - this is a "hack" for getting the OS to @@ -2309,34 +2480,42 @@ GuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT C } static BOOL WINAPI -GuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) +GuiSetCursorInfo(IN OUT PFRONTEND This, + PCONSOLE_SCREEN_BUFFER Buff) { - if (Console->ActiveBuffer == Buff) + PGUI_CONSOLE_DATA GuiData = This->Data; + + if (ConDrvGetActiveScreenBuffer(GuiData->Console) == Buff) { - GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y); + GuiInvalidateCell(This, Buff->CursorPosition.X, Buff->CursorPosition.Y); } return TRUE; } static BOOL WINAPI -GuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX, SHORT OldCursorY) +GuiSetScreenInfo(IN OUT PFRONTEND This, + PCONSOLE_SCREEN_BUFFER Buff, + SHORT OldCursorX, + SHORT OldCursorY) { - if (Console->ActiveBuffer == Buff) + PGUI_CONSOLE_DATA GuiData = This->Data; + + if (ConDrvGetActiveScreenBuffer(GuiData->Console) == Buff) { /* Redraw char at old position (remove cursor) */ - GuiInvalidateCell(Console, OldCursorX, OldCursorY); + GuiInvalidateCell(This, OldCursorX, OldCursorY); /* Redraw char at new position (show cursor) */ - GuiInvalidateCell(Console, Buff->CursorPosition.X, Buff->CursorPosition.Y); + GuiInvalidateCell(This, Buff->CursorPosition.X, Buff->CursorPosition.Y); } return TRUE; } static VOID WINAPI -GuiResizeTerminal(PCONSOLE Console) +GuiResizeTerminal(IN OUT PFRONTEND This) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; /* Resize the window to the user's values */ // GuiData->WindowSizeLock = TRUE; @@ -2348,7 +2527,12 @@ GuiResizeTerminal(PCONSOLE Console) } static BOOL WINAPI -GuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down) +GuiProcessKeyCallback(IN OUT PFRONTEND This, + MSG* msg, + BYTE KeyStateMenu, + DWORD ShiftState, + UINT VirtualKeyCode, + BOOL Down) { if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyStateMenu & 0x80) && (VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE)) @@ -2361,12 +2545,13 @@ GuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD Shift } static BOOL WINAPI -GuiSetMouseCursor(PCONSOLE Console, HCURSOR hCursor); +GuiSetMouseCursor(IN OUT PFRONTEND This, + HCURSOR hCursor); static VOID WINAPI -GuiRefreshInternalInfo(PCONSOLE Console) +GuiRefreshInternalInfo(IN OUT PFRONTEND This) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; /* Update the console leader information held by the window */ SetConsoleWndConsoleLeaderCID(GuiData); @@ -2382,21 +2567,22 @@ GuiRefreshInternalInfo(PCONSOLE Console) /* Mouse is shown by default with its default cursor shape */ GuiData->MouseCursorRefCount = 0; // Reinitialize the reference counter - GuiSetMouseCursor(Console, NULL); + GuiSetMouseCursor(This, NULL); } static VOID WINAPI -GuiChangeTitle(PCONSOLE Console) +GuiChangeTitle(IN OUT PFRONTEND This) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; // PostMessageW(GuiData->hWindow, PM_CONSOLE_SET_TITLE, 0, 0); - SetWindowText(GuiData->hWindow, Console->Title.Buffer); + SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer); } static BOOL WINAPI -GuiChangeIcon(PCONSOLE Console, HICON hWindowIcon) +GuiChangeIcon(IN OUT PFRONTEND This, + HICON hWindowIcon) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; HICON hIcon, hIconSm; if (hWindowIcon == NULL) @@ -2438,16 +2624,18 @@ GuiChangeIcon(PCONSOLE Console, HICON hWindowIcon) } static HWND WINAPI -GuiGetConsoleWindowHandle(PCONSOLE Console) +GuiGetConsoleWindowHandle(IN OUT PFRONTEND This) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; return GuiData->hWindow; } static VOID WINAPI -GuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize) +GuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This, + PCOORD pSize) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; + PCONSOLE_SCREEN_BUFFER ActiveBuffer; RECT WorkArea; LONG width, height; UINT WidthUnit, HeightUnit; @@ -2460,18 +2648,10 @@ GuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize) return; } - if (Console->ActiveBuffer) + ActiveBuffer = ConDrvGetActiveScreenBuffer(GuiData->Console); + if (ActiveBuffer) { - if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) - { - WidthUnit = GuiData->CharWidth ; - HeightUnit = GuiData->CharHeight; - } - else /* if (GetType(Console->ActiveBuffer) == GRAPHICS_BUFFER) */ - { - WidthUnit = 1; - HeightUnit = 1; - } + GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit); } else { @@ -2494,9 +2674,9 @@ GuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize) } static ULONG WINAPI -GuiGetDisplayMode(PCONSOLE Console) +GuiGetDisplayMode(IN OUT PFRONTEND This) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; ULONG DisplayMode = 0; if (GuiData->GuiInfo.FullScreen) @@ -2508,9 +2688,10 @@ GuiGetDisplayMode(PCONSOLE Console) } static BOOL WINAPI -GuiSetDisplayMode(PCONSOLE Console, ULONG NewMode) +GuiSetDisplayMode(IN OUT PFRONTEND This, + ULONG NewMode) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE)) return FALSE; @@ -2521,9 +2702,10 @@ GuiSetDisplayMode(PCONSOLE Console, ULONG NewMode) } static INT WINAPI -GuiShowMouseCursor(PCONSOLE Console, BOOL Show) +GuiShowMouseCursor(IN OUT PFRONTEND This, + BOOL Show) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; /* Set the reference count */ if (Show) ++GuiData->MouseCursorRefCount; @@ -2536,9 +2718,10 @@ GuiShowMouseCursor(PCONSOLE Console, BOOL Show) } static BOOL WINAPI -GuiSetMouseCursor(PCONSOLE Console, HCURSOR hCursor) +GuiSetMouseCursor(IN OUT PFRONTEND This, + HCURSOR hCursor) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; /* * Set the cursor's handle. If the given handle is NULL, @@ -2553,9 +2736,11 @@ GuiSetMouseCursor(PCONSOLE Console, HCURSOR hCursor) } static HMENU WINAPI -GuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh) +GuiMenuControl(IN OUT PFRONTEND This, + UINT cmdIdLow, + UINT cmdIdHigh) { - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; GuiData->cmdIdLow = cmdIdLow ; GuiData->cmdIdHigh = cmdIdHigh; @@ -2564,7 +2749,8 @@ GuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh) } static BOOL WINAPI -GuiSetMenuClose(PCONSOLE Console, BOOL Enable) +GuiSetMenuClose(IN OUT PFRONTEND This, + BOOL Enable) { /* * NOTE: See http://www.mail-archive.com/harbour@harbour-project.org/msg27509.html @@ -2572,7 +2758,7 @@ GuiSetMenuClose(PCONSOLE Console, BOOL Enable) * for more information. */ - PGUI_CONSOLE_DATA GuiData = Console->TermIFace.Data; + PGUI_CONSOLE_DATA GuiData = This->Data; HMENU hSysMenu = GetSystemMenu(GuiData->hWindow, FALSE); if (hSysMenu == NULL) return FALSE; @@ -2585,7 +2771,8 @@ GuiSetMenuClose(PCONSOLE Console, BOOL Enable) static FRONTEND_VTBL GuiVtbl = { - GuiCleanupConsole, + GuiInitFrontEnd, + GuiDeinitFrontEnd, GuiDrawRegion, GuiWriteStream, GuiSetCursorInfo, @@ -2605,164 +2792,167 @@ static FRONTEND_VTBL GuiVtbl = GuiSetMenuClose, }; -NTSTATUS FASTCALL -GuiInitConsole(PCONSOLE Console, - /*IN*/ PCONSOLE_START_INFO ConsoleStartInfo, - PCONSOLE_INFO ConsoleInfo, - DWORD ProcessId, - LPCWSTR IconPath, - INT IconIndex) -{ - PGUI_CONSOLE_DATA GuiData; - GUI_CONSOLE_INFO TermInfo; - SIZE_T Length = 0; - if (Console == NULL || ConsoleInfo == NULL) +static BOOL +LoadShellLinkConsoleInfo(IN OUT PCONSOLE_START_INFO ConsoleStartInfo, + IN OUT PCONSOLE_INFO ConsoleInfo) +{ +#define PATH_SEPARATOR L'\\' + + BOOL RetVal = FALSE; + HRESULT hRes = S_OK; + LPWSTR LinkName = NULL; + SIZE_T Length = 0; + + if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) + return FALSE; + + ConsoleStartInfo->IconPath[0] = L'\0'; + ConsoleStartInfo->IconIndex = 0; + + /* 1- Find the last path separator if any */ + LinkName = wcsrchr(ConsoleStartInfo->ConsoleTitle, PATH_SEPARATOR); + if (LinkName == NULL) + { + LinkName = ConsoleStartInfo->ConsoleTitle; + } + else + { + /* Skip the path separator */ + ++LinkName; + } + + /* 2- Check for the link extension. The name ".lnk" is considered invalid. */ + Length = wcslen(LinkName); + if ( (Length <= 4) || (wcsicmp(LinkName + (Length - 4), L".lnk") != 0) ) + return FALSE; + + /* 3- It may be a link. Try to retrieve some properties */ + hRes = CoInitialize(NULL); + if (SUCCEEDED(hRes)) + { + /* Get a pointer to the IShellLink interface */ + IShellLinkW* pshl = NULL; + hRes = CoCreateInstance(&CLSID_ShellLink, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, + (LPVOID*)&pshl); + if (SUCCEEDED(hRes)) + { + /* Get a pointer to the IPersistFile interface */ + IPersistFile* ppf = NULL; + hRes = IPersistFile_QueryInterface(pshl, &IID_IPersistFile, (LPVOID*)&ppf); + if (SUCCEEDED(hRes)) + { + /* Load the shortcut */ + hRes = IPersistFile_Load(ppf, ConsoleStartInfo->ConsoleTitle, STGM_READ); + if (SUCCEEDED(hRes)) + { + /* + * Finally we can get the properties ! + * Update the old ones if needed. + */ + INT ShowCmd = 0; + // WORD HotKey = 0; + + /* Reset the name of the console with the name of the shortcut */ + Length = min(/*Length*/ Length - 4, // 4 == len(".lnk") + sizeof(ConsoleInfo->ConsoleTitle) / sizeof(ConsoleInfo->ConsoleTitle[0]) - 1); + wcsncpy(ConsoleInfo->ConsoleTitle, LinkName, Length); + ConsoleInfo->ConsoleTitle[Length] = L'\0'; + + /* Get the window showing command */ + hRes = IShellLinkW_GetShowCmd(pshl, &ShowCmd); + if (SUCCEEDED(hRes)) ConsoleStartInfo->ShowWindow = (WORD)ShowCmd; + + /* Get the hotkey */ + // hRes = pshl->GetHotkey(&ShowCmd); + // if (SUCCEEDED(hRes)) ConsoleStartInfo->HotKey = HotKey; + + /* Get the icon location, if any */ + + hRes = IShellLinkW_GetIconLocation(pshl, + ConsoleStartInfo->IconPath, + sizeof(ConsoleStartInfo->IconPath)/sizeof(ConsoleStartInfo->IconPath[0]) - 1, // == MAX_PATH + &ConsoleStartInfo->IconIndex); + if (!SUCCEEDED(hRes)) + { + ConsoleStartInfo->IconPath[0] = L'\0'; + ConsoleStartInfo->IconIndex = 0; + } + + // FIXME: Since we still don't load console properties from the shortcut, + // return false. When this will be done, we will return true instead. + RetVal = FALSE; + } + IPersistFile_Release(ppf); + } + IShellLinkW_Release(pshl); + } + } + CoUninitialize(); + + return RetVal; +} + +NTSTATUS NTAPI +GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, + IN OUT PCONSOLE_INFO ConsoleInfo, + IN OUT PVOID ExtraConsoleInfo, + IN ULONG ProcessId) +{ + PCONSOLE_START_INFO ConsoleStartInfo = ExtraConsoleInfo; + PGUI_INIT_INFO GuiInitInfo; + + if (FrontEnd == NULL || ConsoleInfo == NULL || ConsoleStartInfo == NULL) return STATUS_INVALID_PARAMETER; - /* Initialize the GUI terminal emulator */ + /* Initialize GUI terminal emulator common functionalities */ if (!GuiInit()) return STATUS_UNSUCCESSFUL; - /* Initialize the console */ - Console->TermIFace.Vtbl = &GuiVtbl; - - GuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_CONSOLE_DATA)); - if (!GuiData) + /* + * Load per-application terminal settings. + * + * Check whether the process creating the console was launched via + * a shell-link. ConsoleInfo->ConsoleTitle may be updated with the + * name of the shortcut, and ConsoleStartInfo->Icon[Path|Index] too. + */ + if (ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) { - DPRINT1("CONSRV: Failed to create GUI_CONSOLE_DATA\n"); - return STATUS_UNSUCCESSFUL; + if (!LoadShellLinkConsoleInfo(ConsoleStartInfo, ConsoleInfo)) + { + ConsoleStartInfo->dwStartupFlags &= ~STARTF_TITLEISLINKNAME; + } } - Console->TermIFace.Data = (PVOID)GuiData; - GuiData->Console = Console; - GuiData->hWindow = NULL; - - /* The console can be resized */ - Console->FixedSize = FALSE; - - InitializeCriticalSection(&GuiData->Lock); - /* - * Load the terminal settings + * Initialize a private initialization info structure for later use. + * It must be freed by a call to GuiUnloadFrontEnd or GuiInitFrontEnd. */ + GuiInitInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(GUI_INIT_INFO)); + if (GuiInitInfo == NULL) return STATUS_NO_MEMORY; - /*********************************************** - * Adapted from ConSrvInitConsole in console.c * - ***********************************************/ + // HACK: We suppose that the pointers will be valid in GuiInitFrontEnd... + GuiInitInfo->ConsoleInfo = ConsoleInfo; + GuiInitInfo->ConsoleStartInfo = ConsoleStartInfo; + GuiInitInfo->ProcessId = ProcessId; - /* 1. Load the default settings */ - GuiConsoleGetDefaultSettings(&TermInfo, ProcessId); + /* Finally, initialize the frontend structure */ + FrontEnd->Vtbl = &GuiVtbl; + FrontEnd->Data = NULL; + FrontEnd->OldData = GuiInitInfo; - /* 2. Load the remaining console settings via the registry. */ - if ((ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) - { - /* Load the terminal infos from the registry. */ - GuiConsoleReadUserSettings(&TermInfo, ConsoleInfo->ConsoleTitle, ProcessId); + return STATUS_SUCCESS; +} - /* - * Now, update them with the properties the user might gave to us - * via the STARTUPINFO structure before calling CreateProcess - * (and which was transmitted via the ConsoleStartInfo structure). - * We therefore overwrite the values read in the registry. - */ - if (ConsoleStartInfo->dwStartupFlags & STARTF_USESHOWWINDOW) - { - TermInfo.ShowWindow = ConsoleStartInfo->ShowWindow; - } - if (ConsoleStartInfo->dwStartupFlags & STARTF_USEPOSITION) - { - TermInfo.AutoPosition = FALSE; - TermInfo.WindowOrigin = ConsoleStartInfo->ConsoleWindowOrigin; - } - if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN) - { - TermInfo.FullScreen = TRUE; - } - } +NTSTATUS NTAPI +GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd) +{ + if (FrontEnd == NULL) return STATUS_INVALID_PARAMETER; - - /* - * Set up the GUI data - */ - - Length = min(wcslen(TermInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen - wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE); - GuiData->GuiInfo.FaceName[Length] = L'\0'; - GuiData->GuiInfo.FontFamily = TermInfo.FontFamily; - GuiData->GuiInfo.FontSize = TermInfo.FontSize; - GuiData->GuiInfo.FontWeight = TermInfo.FontWeight; - GuiData->GuiInfo.UseRasterFonts = TermInfo.UseRasterFonts; - GuiData->GuiInfo.FullScreen = TermInfo.FullScreen; - GuiData->GuiInfo.ShowWindow = TermInfo.ShowWindow; - GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition; - GuiData->GuiInfo.WindowOrigin = TermInfo.WindowOrigin; - - /* Initialize the icon handles to their default values */ - GuiData->hIcon = ghDefaultIcon; - GuiData->hIconSm = ghDefaultIconSm; - - /* Get the associated icon, if any */ - if (IconPath == NULL || *IconPath == L'\0') - { - IconPath = ConsoleStartInfo->AppPath; - IconIndex = 0; - } - DPRINT("IconPath = %S ; IconIndex = %lu\n", (IconPath ? IconPath : L"n/a"), IconIndex); - if (IconPath) - { - HICON hIcon = NULL, hIconSm = NULL; - PrivateExtractIconExW(IconPath, - IconIndex, - &hIcon, - &hIconSm, - 1); - DPRINT("hIcon = 0x%p ; hIconSm = 0x%p\n", hIcon, hIconSm); - if (hIcon != NULL) - { - DPRINT("Effectively set the icons\n"); - GuiData->hIcon = hIcon; - GuiData->hIconSm = hIconSm; - } - } - - /* Mouse is shown by default with its default cursor shape */ - GuiData->hCursor = ghDefaultCursor; - GuiData->MouseCursorRefCount = 0; - - /* A priori don't ignore mouse signals */ - GuiData->IgnoreNextMouseSignal = FALSE; - - /* Close button and the corresponding system menu item are enabled by default */ - GuiData->IsCloseButtonEnabled = TRUE; - - /* There is no user-reserved menu id range by default */ - GuiData->cmdIdLow = GuiData->cmdIdHigh = 0; - - /* - * We need to wait until the GUI has been fully initialized - * to retrieve custom settings i.e. WindowSize etc... - * Ideally we could use SendNotifyMessage for this but its not - * yet implemented. - */ - GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - - /* Create the terminal window */ - PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, GuiData->GuiInfo.ShowWindow, (LPARAM)GuiData); - - /* Wait until initialization has finished */ - WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); - DPRINT("OK we created the console window\n"); - CloseHandle(GuiData->hGuiInitEvent); - GuiData->hGuiInitEvent = NULL; - - /* Check whether we really succeeded in initializing the terminal window */ - if (GuiData->hWindow == NULL) - { - DPRINT("GuiInitConsole - We failed at creating a new terminal window\n"); - // ConioCleanupConsole(Console); - GuiCleanupConsole(Console); - return STATUS_UNSUCCESSFUL; - } + if (FrontEnd->Data) GuiDeinitFrontEnd(FrontEnd); + if (FrontEnd->OldData) ConsoleFreeHeap(FrontEnd->OldData); return STATUS_SUCCESS; } diff --git a/win32ss/user/consrv/frontends/gui/guiterm.h b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h similarity index 92% rename from win32ss/user/consrv/frontends/gui/guiterm.h rename to win32ss/user/winsrv/consrv/frontends/gui/guiterm.h index 585f241797a..c91915b033e 100644 --- a/win32ss/user/consrv/frontends/gui/guiterm.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/gui/guiterm.h + * FILE: win32ss/user/winsrv/consrv/frontends/gui/guiterm.h * PURPOSE: GUI Terminal Front-End * PROGRAMMERS: G van Geldorp * Johannes Anderwald diff --git a/win32ss/user/consrv/frontends/gui/guiterm.rc b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/guiterm.rc rename to win32ss/user/winsrv/consrv/frontends/gui/guiterm.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/bg-BG.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/bg-BG.rc similarity index 94% rename from win32ss/user/consrv/frontends/gui/lang/bg-BG.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/bg-BG.rc index 7e8440e4355..cb6a87b6f5e 100644 --- a/win32ss/user/consrv/frontends/gui/lang/bg-BG.rc +++ b/win32ss/user/winsrv/consrv/frontends/gui/lang/bg-BG.rc @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS CSRSS subsystem - * FILE: win32ss/user/consrv/lang/bg-BG.rc + * FILE: win32ss/user/winsrv/consrv/lang/bg-BG.rc * PURPOSE: Bulgarian resource file */ diff --git a/win32ss/user/consrv/frontends/gui/lang/cs-CZ.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/cs-CZ.rc similarity index 93% rename from win32ss/user/consrv/frontends/gui/lang/cs-CZ.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/cs-CZ.rc index bd38c87488a..a558b892aaa 100644 --- a/win32ss/user/consrv/frontends/gui/lang/cs-CZ.rc +++ b/win32ss/user/winsrv/consrv/frontends/gui/lang/cs-CZ.rc @@ -1,5 +1,5 @@ /* - * FILE: win32ss/user/consrv/lang/cs-CZ.rc + * FILE: win32ss/user/winsrv/consrv/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) * UPDATED: 2011-04-09 */ diff --git a/win32ss/user/consrv/frontends/gui/lang/de-DE.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/de-DE.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/de-DE.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/de-DE.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/el-GR.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/el-GR.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/el-GR.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/el-GR.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/en-US.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/en-US.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/en-US.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/en-US.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/es-ES.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/es-ES.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/es-ES.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/es-ES.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/fr-FR.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/fr-FR.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/fr-FR.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/fr-FR.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/he-IL.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/he-IL.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/he-IL.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/he-IL.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/id-ID.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/id-ID.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/id-ID.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/id-ID.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/it-IT.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/it-IT.rc similarity index 94% rename from win32ss/user/consrv/frontends/gui/lang/it-IT.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/it-IT.rc index ce09f5cca02..4d0bd524cc7 100644 --- a/win32ss/user/consrv/frontends/gui/lang/it-IT.rc +++ b/win32ss/user/winsrv/consrv/frontends/gui/lang/it-IT.rc @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS Client/Server Runtime subsystem * LICENSE: GPL - See COPYING in the top level directory -* FILE: win32ss/user/consrv/lang/it-IT.rc +* FILE: win32ss/user/winsrv/consrv/lang/it-IT.rc * PURPOSE: Italian Translation * PROGRAMMERS: * Copyright (C) 2007 Daniele Forsi (dforsi at gmail.com) Italian Translation diff --git a/win32ss/user/consrv/frontends/gui/lang/ja-JP.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/ja-JP.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/ja-JP.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/ja-JP.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/no-NO.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/no-NO.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/no-NO.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/no-NO.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/pl-PL.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/pl-PL.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/pl-PL.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/pl-PL.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/pt-BR.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/pt-BR.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/pt-BR.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/pt-BR.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/ro-RO.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/ro-RO.rc similarity index 93% rename from win32ss/user/consrv/frontends/gui/lang/ro-RO.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/ro-RO.rc index 9eec57c8b66..1796eb85bbb 100644 --- a/win32ss/user/consrv/frontends/gui/lang/ro-RO.rc +++ b/win32ss/user/winsrv/consrv/frontends/gui/lang/ro-RO.rc @@ -1,5 +1,5 @@ /* - * FILE: win32ss/user/consrv/lang/ro-RO.rc + * FILE: win32ss/user/winsrv/consrv/lang/ro-RO.rc * ReactOS Project (http://www.reactos.org) * TRANSLATOR: Fulea Ștefan (PM on ReactOS Forum at fulea.stefan) * CHANGE LOG: 2011-10-16 initial translation diff --git a/win32ss/user/consrv/frontends/gui/lang/ru-RU.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/ru-RU.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/ru-RU.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/ru-RU.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/sk-SK.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/sk-SK.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/sk-SK.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/sk-SK.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/sv-SE.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/sv-SE.rc similarity index 93% rename from win32ss/user/consrv/frontends/gui/lang/sv-SE.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/sv-SE.rc index f72c472023d..0a478b8b5b5 100644 --- a/win32ss/user/consrv/frontends/gui/lang/sv-SE.rc +++ b/win32ss/user/winsrv/consrv/frontends/gui/lang/sv-SE.rc @@ -1,6 +1,6 @@ /* * PROJECT: ReactOS CSRSS subsystem - * FILE: win32ss/user/consrv/lang/sv-SE.rc + * FILE: win32ss/user/winsrv/consrv/lang/sv-SE.rc * PURPOSE: Swedish resource file * Translation: Jaix Bly */ diff --git a/win32ss/user/consrv/frontends/gui/lang/tr-TR.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/tr-TR.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/tr-TR.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/tr-TR.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/uk-UA.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/uk-UA.rc similarity index 95% rename from win32ss/user/consrv/frontends/gui/lang/uk-UA.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/uk-UA.rc index d610288cbc1..de4715037d7 100644 --- a/win32ss/user/consrv/frontends/gui/lang/uk-UA.rc +++ b/win32ss/user/winsrv/consrv/frontends/gui/lang/uk-UA.rc @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS CSRSS subsystem * LICENSE: GPL - See COPYING in the top level directory - * FILE: win32ss/user/consrv/lang/uk-UA.rc + * FILE: win32ss/user/winsrv/consrv/lang/uk-UA.rc * PURPOSE: Ukraianian resource file * TRANSLATOR: Artem Reznikov */ diff --git a/win32ss/user/consrv/frontends/gui/lang/zh-CN.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/zh-CN.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/zh-CN.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/zh-CN.rc diff --git a/win32ss/user/consrv/frontends/gui/lang/zh-TW.rc b/win32ss/user/winsrv/consrv/frontends/gui/lang/zh-TW.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/lang/zh-TW.rc rename to win32ss/user/winsrv/consrv/frontends/gui/lang/zh-TW.rc diff --git a/win32ss/user/consrv/frontends/gui/res/terminal.ico b/win32ss/user/winsrv/consrv/frontends/gui/res/terminal.ico similarity index 100% rename from win32ss/user/consrv/frontends/gui/res/terminal.ico rename to win32ss/user/winsrv/consrv/frontends/gui/res/terminal.ico diff --git a/win32ss/user/consrv/frontends/gui/resource.h b/win32ss/user/winsrv/consrv/frontends/gui/resource.h similarity index 95% rename from win32ss/user/consrv/frontends/gui/resource.h rename to win32ss/user/winsrv/consrv/frontends/gui/resource.h index 51dd0a2006a..dbc9e1f9a30 100644 --- a/win32ss/user/consrv/frontends/gui/resource.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/resource.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/resource.h + * FILE: win32ss/user/winsrv/consrv/resource.h * PURPOSE: Resource #defines */ diff --git a/win32ss/user/consrv/frontends/gui/rsrc.rc b/win32ss/user/winsrv/consrv/frontends/gui/rsrc.rc similarity index 100% rename from win32ss/user/consrv/frontends/gui/rsrc.rc rename to win32ss/user/winsrv/consrv/frontends/gui/rsrc.rc diff --git a/win32ss/user/consrv/frontends/gui/text.c b/win32ss/user/winsrv/consrv/frontends/gui/text.c similarity index 93% rename from win32ss/user/consrv/frontends/gui/text.c rename to win32ss/user/winsrv/consrv/frontends/gui/text.c index e5454fef28d..38bc4413063 100644 --- a/win32ss/user/consrv/frontends/gui/text.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/gui/text.c + * FILE: win32ss/user/winsrv/consrv/frontends/gui/text.c * PURPOSE: GUI Terminal Front-End - Support for text-mode screen-buffers * PROGRAMMERS: G van Geldorp * Johannes Anderwald @@ -83,7 +83,15 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer) /* Copy only the characters, leave attributes alone */ for (xPos = 0; xPos < selWidth; xPos++) { - dstPos[xPos] = ptr[xPos].Char.UnicodeChar; + /* + * Sometimes, applications can put NULL chars into the screen-buffer + * (this behaviour is allowed). Detect this and replace by a space. + * FIXME - HACK: Improve the way we're doing that (i.e., put spaces + * instead of NULLs (or even, nothing) only if it exists a non-null + * char *after* those NULLs, before the end-of-line of the selection. + * Do the same concerning spaces -- i.e. trailing spaces --). + */ + dstPos[xPos] = (ptr[xPos].Char.UnicodeChar ? ptr[xPos].Char.UnicodeChar : L' '); } dstPos += selWidth; diff --git a/win32ss/user/winsrv/consrv/frontends/input.c b/win32ss/user/winsrv/consrv/frontends/input.c new file mode 100644 index 00000000000..b0779463cb6 --- /dev/null +++ b/win32ss/user/winsrv/consrv/frontends/input.c @@ -0,0 +1,146 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/frontends/input.c + * PURPOSE: Common Front-Ends Input functions + * PROGRAMMERS: Jeffrey Morlan + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "include/conio.h" +#include "include/conio2.h" +#include "coninput.h" + +#define NDEBUG +#include + + +/* PRIVATE FUNCTIONS **********************************************************/ + +static DWORD FASTCALL +ConioGetShiftState(PBYTE KeyState, LPARAM lParam) +{ + DWORD ssOut = 0; + + if (KeyState[VK_CAPITAL] & 0x01) + ssOut |= CAPSLOCK_ON; + + if (KeyState[VK_NUMLOCK] & 0x01) + ssOut |= NUMLOCK_ON; + + if (KeyState[VK_SCROLL] & 0x01) + ssOut |= SCROLLLOCK_ON; + + if (KeyState[VK_SHIFT] & 0x80) + ssOut |= SHIFT_PRESSED; + + if (KeyState[VK_LCONTROL] & 0x80) + ssOut |= LEFT_CTRL_PRESSED; + if (KeyState[VK_RCONTROL] & 0x80) + ssOut |= RIGHT_CTRL_PRESSED; + + if (KeyState[VK_LMENU] & 0x80) + ssOut |= LEFT_ALT_PRESSED; + if (KeyState[VK_RMENU] & 0x80) + ssOut |= RIGHT_ALT_PRESSED; + + /* See WM_CHAR MSDN documentation for instance */ + if (lParam & 0x01000000) + ssOut |= ENHANCED_KEY; + + return ssOut; +} + +VOID WINAPI +ConioProcessKey(PCONSOLE Console, MSG* msg) +{ + static BYTE KeyState[256] = { 0 }; + /* MSDN mentions that you should use the last virtual key code received + * when putting a virtual key identity to a WM_CHAR message since multiple + * or translated keys may be involved. */ + static UINT LastVirtualKey = 0; + DWORD ShiftState; + WCHAR UnicodeChar; + UINT VirtualKeyCode; + UINT VirtualScanCode; + BOOL Down = FALSE; + BOOLEAN Fake; // synthesized, not a real event + BOOLEAN NotChar; // message should not be used to return a character + + if (NULL == Console) + { + DPRINT1("No Active Console!\n"); + return; + } + + VirtualScanCode = HIWORD(msg->lParam) & 0xFF; + Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR || + msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR; + + GetKeyboardState(KeyState); + ShiftState = ConioGetShiftState(KeyState, msg->lParam); + + if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) + { + VirtualKeyCode = LastVirtualKey; + UnicodeChar = msg->wParam; + } + else + { + WCHAR Chars[2]; + INT RetChars = 0; + + VirtualKeyCode = msg->wParam; + RetChars = ToUnicodeEx(VirtualKeyCode, + VirtualScanCode, + KeyState, + Chars, + 2, + 0, + NULL); + UnicodeChar = (1 == RetChars ? Chars[0] : 0); + } + + if (ConioProcessKeyCallback(Console, + msg, + KeyState[VK_MENU], + ShiftState, + VirtualKeyCode, + Down)) + { + return; + } + + Fake = UnicodeChar && + (msg->message != WM_CHAR && msg->message != WM_SYSCHAR && + msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP); + NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR); + if (NotChar) LastVirtualKey = msg->wParam; + + DPRINT("CONSRV: %s %s %s %s %02x %02x '%lc' %04x\n", + Down ? "down" : "up ", + (msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ? + "char" : "key ", + Fake ? "fake" : "real", + NotChar ? "notc" : "char", + VirtualScanCode, + VirtualKeyCode, + (UnicodeChar >= L' ') ? UnicodeChar : L'.', + ShiftState); + + if (Fake) return; + + /* Send the key press to the console driver */ + ConDrvProcessKey(Console, + Down, + VirtualKeyCode, + VirtualScanCode, + UnicodeChar, + ShiftState, + KeyState[VK_CONTROL]); +} + +/* EOF */ diff --git a/win32ss/user/consrv/frontends/tui/tuiterm.c b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c similarity index 83% rename from win32ss/user/consrv/frontends/tui/tuiterm.c rename to win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c index 022c8442b3d..84ae5c42358 100644 --- a/win32ss/user/consrv/frontends/tui/tuiterm.c +++ b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/tui/tuiterm.c + * FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.c * PURPOSE: TUI Terminal Front-End - Virtual Consoles... * PROGRAMMERS: David Welch * G van Geldorp @@ -9,6 +9,8 @@ * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ +#ifdef TUITERM_COMPILE + #include "consrv.h" #include "include/conio.h" #include "include/console.h" @@ -274,7 +276,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_KEYUP: case WM_SYSKEYUP: { - if (ConSrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) { MSG Message; Message.hwnd = hWnd; @@ -290,7 +292,7 @@ TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: { - if (ConSrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsoleUnsafe(ActiveConsole->Console, CONSOLE_RUNNING, TRUE)) { if (LOWORD(wParam) != WA_INACTIVE) { @@ -440,9 +442,90 @@ Quit: ******************************************************************************/ static VOID WINAPI -TuiCleanupConsole(PCONSOLE Console) +TuiDeinitFrontEnd(IN OUT PFRONTEND This /*, + IN PCONSOLE Console */); + +NTSTATUS NTAPI +TuiInitFrontEnd(IN OUT PFRONTEND This, + IN PCONSOLE Console) { - PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data; + PTUI_CONSOLE_DATA TuiData; + HANDLE ThreadHandle; + + if (This == NULL || Console == NULL) + return STATUS_INVALID_PARAMETER; + + // if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) + // return STATUS_INVALID_PARAMETER; + + // /* Initialize the console */ + // Console->TermIFace.Vtbl = &TuiVtbl; + + TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA)); + if (!TuiData) + { + DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n"); + return STATUS_UNSUCCESSFUL; + } + // Console->TermIFace.Data = (PVOID)TuiData; + TuiData->Console = Console; + TuiData->hWindow = NULL; + + InitializeCriticalSection(&TuiData->Lock); + + /* + * HACK: Resize the console since we don't support for now changing + * the console size when we display it with the hardware. + */ + // Console->ConsoleSize = PhysicalConsoleSize; + // ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize); + + // /* The console cannot be resized anymore */ + // Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !! + // // ConioResizeTerminal(Console); + + /* + * Contrary to what we do in the GUI front-end, here we create + * an input thread for each console. It will dispatch all the + * input messages to the proper console (on the GUI it is done + * via the default GUI dispatch thread). + */ + ThreadHandle = CreateThread(NULL, + 0, + TuiConsoleThread, + (PVOID)TuiData, + 0, + NULL); + if (NULL == ThreadHandle) + { + DPRINT1("CONSRV: Unable to create console thread\n"); + // TuiDeinitFrontEnd(Console); + TuiDeinitFrontEnd(This); + return STATUS_UNSUCCESSFUL; + } + CloseHandle(ThreadHandle); + + /* + * Insert the newly created console in the list of virtual consoles + * and activate it (give it the focus). + */ + EnterCriticalSection(&ActiveVirtConsLock); + InsertTailList(&VirtConsList, &TuiData->Entry); + ActiveConsole = TuiData; + LeaveCriticalSection(&ActiveVirtConsLock); + + /* Finally, initialize the frontend structure */ + This->Data = TuiData; + This->OldData = NULL; + + return STATUS_SUCCESS; +} + +static VOID WINAPI +TuiDeinitFrontEnd(IN OUT PFRONTEND This) +{ + // PCONSOLE Console = This->Console; + PTUI_CONSOLE_DATA TuiData = This->Data; // Console->TermIFace.Data; /* Close the notification window */ DestroyWindow(TuiData->hWindow); @@ -473,13 +556,15 @@ TuiCleanupConsole(PCONSOLE Console) /* Switch to the next console */ if (NULL != ActiveConsole) ConioDrawConsole(ActiveConsole->Console); - Console->TermIFace.Data = NULL; + // Console->TermIFace.Data = NULL; + This->Data = NULL; DeleteCriticalSection(&TuiData->Lock); ConsoleFreeHeap(TuiData); } static VOID WINAPI -TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region) +TuiDrawRegion(IN OUT PFRONTEND This, + SMALL_RECT* Region) { DWORD BytesReturned; PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; @@ -517,8 +602,13 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region) } static VOID WINAPI -TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY, - UINT ScrolledLines, PWCHAR Buffer, UINT Length) +TuiWriteStream(IN OUT PFRONTEND This, + SMALL_RECT* Region, + SHORT CursorStartX, + SHORT CursorStartY, + UINT ScrolledLines, + PWCHAR Buffer, + UINT Length) { PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer; PCHAR NewBuffer; @@ -546,7 +636,8 @@ TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT C } static BOOL WINAPI -TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) +TuiSetCursorInfo(IN OUT PFRONTEND This, + PCONSOLE_SCREEN_BUFFER Buff) { CONSOLE_CURSOR_INFO Info; DWORD BytesReturned; @@ -567,7 +658,10 @@ TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff) } static BOOL WINAPI -TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX, SHORT OldCursorY) +TuiSetScreenInfo(IN OUT PFRONTEND This, + PCONSOLE_SCREEN_BUFFER Buff, + SHORT OldCursorX, + SHORT OldCursorY) { CONSOLE_SCREEN_BUFFER_INFO Info; DWORD BytesReturned; @@ -590,12 +684,17 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX } static VOID WINAPI -TuiResizeTerminal(PCONSOLE Console) +TuiResizeTerminal(IN OUT PFRONTEND This) { } static BOOL WINAPI -TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down) +TuiProcessKeyCallback(IN OUT PFRONTEND This, + MSG* msg, + BYTE KeyStateMenu, + DWORD ShiftState, + UINT VirtualKeyCode, + BOOL Down) { if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) && VK_TAB == VirtualKeyCode) @@ -616,43 +715,46 @@ TuiProcessKeyCallback(PCONSOLE Console, MSG* msg, BYTE KeyStateMenu, DWORD Shift } static VOID WINAPI -TuiRefreshInternalInfo(PCONSOLE Console) +TuiRefreshInternalInfo(IN OUT PFRONTEND This) { } static VOID WINAPI -TuiChangeTitle(PCONSOLE Console) +TuiChangeTitle(IN OUT PFRONTEND This) { } static BOOL WINAPI -TuiChangeIcon(PCONSOLE Console, HICON hWindowIcon) +TuiChangeIcon(IN OUT PFRONTEND This, + HICON hWindowIcon) { return TRUE; } static HWND WINAPI -TuiGetConsoleWindowHandle(PCONSOLE Console) +TuiGetConsoleWindowHandle(IN OUT PFRONTEND This) { - PTUI_CONSOLE_DATA TuiData = Console->TermIFace.Data; + PTUI_CONSOLE_DATA TuiData = This->Data; return TuiData->hWindow; } static VOID WINAPI -TuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize) +TuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This, + PCOORD pSize) { if (!pSize) return; *pSize = PhysicalConsoleSize; } static ULONG WINAPI -TuiGetDisplayMode(PCONSOLE Console) +TuiGetDisplayMode(IN OUT PFRONTEND This) { return CONSOLE_FULLSCREEN_HARDWARE; // CONSOLE_FULLSCREEN; } static BOOL WINAPI -TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode) +TuiSetDisplayMode(IN OUT PFRONTEND This, + ULONG NewMode) { // if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE)) // return FALSE; @@ -660,32 +762,38 @@ TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode) } static INT WINAPI -TuiShowMouseCursor(PCONSOLE Console, BOOL Show) +TuiShowMouseCursor(IN OUT PFRONTEND This, + BOOL Show) { return 0; } static BOOL WINAPI -TuiSetMouseCursor(PCONSOLE Console, HCURSOR hCursor) +TuiSetMouseCursor(IN OUT PFRONTEND This, + HCURSOR hCursor) { return TRUE; } static HMENU WINAPI -TuiMenuControl(PCONSOLE Console, UINT cmdIdLow, UINT cmdIdHigh) +TuiMenuControl(IN OUT PFRONTEND This, + UINT cmdIdLow, + UINT cmdIdHigh) { return NULL; } static BOOL WINAPI -TuiSetMenuClose(PCONSOLE Console, BOOL Enable) +TuiSetMenuClose(IN OUT PFRONTEND This, + BOOL Enable) { return TRUE; } static FRONTEND_VTBL TuiVtbl = { - TuiCleanupConsole, + TuiInitFrontEnd, + TuiDeinitFrontEnd, TuiDrawRegion, TuiWriteStream, TuiSetCursorInfo, @@ -705,80 +813,49 @@ static FRONTEND_VTBL TuiVtbl = TuiSetMenuClose, }; -NTSTATUS FASTCALL -TuiInitConsole(PCONSOLE Console, - /*IN*/ PCONSOLE_START_INFO ConsoleStartInfo, - PCONSOLE_INFO ConsoleInfo, - DWORD ProcessId) +// static BOOL +// DtbgIsDesktopVisible(VOID) +// { + // return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE)); +// } +static BOOLEAN +IsConsoleMode(VOID) { - PTUI_CONSOLE_DATA TuiData; - HANDLE ThreadHandle; + return (BOOLEAN)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE); +} - if (Console == NULL || ConsoleInfo == NULL) +NTSTATUS NTAPI +TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, + IN OUT PCONSOLE_INFO ConsoleInfo, + IN OUT PVOID ExtraConsoleInfo, + IN ULONG ProcessId) +{ + if (FrontEnd == NULL || ConsoleInfo == NULL) return STATUS_INVALID_PARAMETER; - if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) - return STATUS_INVALID_PARAMETER; + /* We must be in console mode already */ + if (!IsConsoleMode()) return STATUS_UNSUCCESSFUL; /* Initialize the TUI terminal emulator */ - if (!TuiInit(Console->CodePage)) return STATUS_UNSUCCESSFUL; + if (!TuiInit(ConsoleInfo->CodePage)) return STATUS_UNSUCCESSFUL; - /* Initialize the console */ - Console->TermIFace.Vtbl = &TuiVtbl; - - TuiData = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(TUI_CONSOLE_DATA)); - if (!TuiData) - { - DPRINT1("CONSRV: Failed to create TUI_CONSOLE_DATA\n"); - return STATUS_UNSUCCESSFUL; - } - Console->TermIFace.Data = (PVOID)TuiData; - TuiData->Console = Console; - TuiData->hWindow = NULL; - - InitializeCriticalSection(&TuiData->Lock); - - /* - * HACK: Resize the console since we don't support for now changing - * the console size when we display it with the hardware. - */ - Console->ConsoleSize = PhysicalConsoleSize; - ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize); - - /* The console cannot be resized anymore */ - Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !! - // ConioResizeTerminal(Console); - - /* - * Contrary to what we do in the GUI front-end, here we create - * an input thread for each console. It will dispatch all the - * input messages to the proper console (on the GUI it is done - * via the default GUI dispatch thread). - */ - ThreadHandle = CreateThread(NULL, - 0, - TuiConsoleThread, - (PVOID)TuiData, - 0, - NULL); - if (NULL == ThreadHandle) - { - DPRINT1("CONSRV: Unable to create console thread\n"); - TuiCleanupConsole(Console); - return STATUS_UNSUCCESSFUL; - } - CloseHandle(ThreadHandle); - - /* - * Insert the newly created console in the list of virtual consoles - * and activate it (give it the focus). - */ - EnterCriticalSection(&ActiveVirtConsLock); - InsertTailList(&VirtConsList, &TuiData->Entry); - ActiveConsole = TuiData; - LeaveCriticalSection(&ActiveVirtConsLock); + /* Finally, initialize the frontend structure */ + FrontEnd->Vtbl = &TuiVtbl; + FrontEnd->Data = NULL; + FrontEnd->OldData = NULL; return STATUS_SUCCESS; } +NTSTATUS NTAPI +TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd) +{ + if (FrontEnd == NULL) return STATUS_INVALID_PARAMETER; + if (FrontEnd->Data) TuiDeinitFrontEnd(FrontEnd); + + return STATUS_SUCCESS; +} + +#endif + /* EOF */ diff --git a/win32ss/user/consrv/frontends/tui/tuiterm.h b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.h similarity index 89% rename from win32ss/user/consrv/frontends/tui/tuiterm.h rename to win32ss/user/winsrv/consrv/frontends/tui/tuiterm.h index 4e349e20bfc..8abbcb9810b 100644 --- a/win32ss/user/consrv/frontends/tui/tuiterm.h +++ b/win32ss/user/winsrv/consrv/frontends/tui/tuiterm.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/frontends/tui/tuiterm.h + * FILE: win32ss/user/winsrv/consrv/frontends/tui/tuiterm.h * PURPOSE: TUI Terminal Front-End * PROGRAMMERS: David Welch * G van Geldorp diff --git a/win32ss/user/consrv/handle.c b/win32ss/user/winsrv/consrv/handle.c similarity index 88% rename from win32ss/user/consrv/handle.c rename to win32ss/user/winsrv/consrv/handle.c index 37c68685554..f5ef3e755f3 100644 --- a/win32ss/user/consrv/handle.c +++ b/win32ss/user/winsrv/consrv/handle.c @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/handle.c + * FILE: win32ss/user/winsrv/consrv/handle.c * PURPOSE: Console I/O Handles functions * PROGRAMMERS: David Welch * Jeffrey Morlan @@ -12,7 +12,7 @@ #include "consrv.h" #include "include/conio.h" -#include "conio.h" +#include "include/conio2.h" #include "handle.h" #include "include/console.h" #include "console.h" @@ -135,6 +135,7 @@ static VOID ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData); static NTSTATUS ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, + IN PCONSOLE Console, OUT PHANDLE pInputHandle, OUT PHANDLE pOutputHandle, OUT PHANDLE pErrorHandle) @@ -157,7 +158,7 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, /* Insert the Input handle */ Status = ConSrvInsertObject(ProcessData, &InputHandle, - &ProcessData->Console->InputBuffer.Header, + &Console->InputBuffer.Header, GENERIC_READ | GENERIC_WRITE, TRUE, FILE_SHARE_READ | FILE_SHARE_WRITE); @@ -172,7 +173,7 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, /* Insert the Output handle */ Status = ConSrvInsertObject(ProcessData, &OutputHandle, - &ProcessData->Console->ActiveBuffer->Header, + &Console->ActiveBuffer->Header, GENERIC_READ | GENERIC_WRITE, TRUE, FILE_SHARE_READ | FILE_SHARE_WRITE); @@ -187,7 +188,7 @@ ConSrvInitHandlesTable(IN OUT PCONSOLE_PROCESS_DATA ProcessData, /* Insert the Error handle */ Status = ConSrvInsertObject(ProcessData, &ErrorHandle, - &ProcessData->Console->ActiveBuffer->Header, + &Console->ActiveBuffer->Header, GENERIC_READ | GENERIC_WRITE, TRUE, FILE_SHARE_READ | FILE_SHARE_WRITE); @@ -270,12 +271,12 @@ ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData) ULONG i; /* - * ProcessData->Console is NULL (and the assertion fails) when + * ProcessData->ConsoleHandle is NULL (and the assertion fails) when * ConSrvFreeHandlesTable is called in ConSrvConnect during the * allocation of a new console. */ - // ASSERT(ProcessData->Console); - if (ProcessData->Console != NULL) + // ASSERT(ProcessData->ConsoleHandle); + if (ProcessData->ConsoleHandle != NULL) { /* Close all the console handles */ for (i = 0; i < ProcessData->HandleTableSize; i++) @@ -380,22 +381,22 @@ FASTCALL ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData, HANDLE Handle) { - ULONG_PTR h = (ULONG_PTR)Handle >> 2; + ULONG Index = HandleToULong(Handle) >> 2; PCONSOLE_IO_OBJECT Object; RtlEnterCriticalSection(&ProcessData->HandleTableLock); ASSERT(ProcessData->HandleTable); - if (h >= ProcessData->HandleTableSize || - (Object = ProcessData->HandleTable[h].Object) == NULL) + if (Index >= ProcessData->HandleTableSize || + (Object = ProcessData->HandleTable[Index].Object) == NULL) { RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_HANDLE; } - ASSERT(ProcessData->Console); - ConSrvCloseHandleEntry(&ProcessData->HandleTable[h]); + ASSERT(ProcessData->ConsoleHandle); + ConSrvCloseHandleEntry(&ProcessData->HandleTable[Index]); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_SUCCESS; @@ -411,22 +412,23 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData, BOOL LockConsole, CONSOLE_IO_OBJECT_TYPE Type) { - ULONG_PTR h = (ULONG_PTR)Handle >> 2; + // NTSTATUS Status; + ULONG Index = HandleToULong(Handle) >> 2; PCONSOLE_IO_HANDLE HandleEntry = NULL; PCONSOLE_IO_OBJECT ObjectEntry = NULL; + // PCONSOLE ObjectConsole; ASSERT(Object); if (Entry) *Entry = NULL; - // DPRINT("ConSrvGetObject, Object: %x, %x, %x\n", - // Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); + DPRINT("ConSrvGetObject -- Object: 0x%x, Handle: 0x%x\n", Object, Handle); RtlEnterCriticalSection(&ProcessData->HandleTableLock); if ( IsConsoleHandle(Handle) && - h < ProcessData->HandleTableSize ) + Index < ProcessData->HandleTableSize ) { - HandleEntry = &ProcessData->HandleTable[h]; + HandleEntry = &ProcessData->HandleTable[Index]; ObjectEntry = HandleEntry->Object; } @@ -436,14 +438,18 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData, /*(Type != 0 && ObjectEntry->Type != Type)*/ (Type != 0 && (ObjectEntry->Type & Type) == 0) ) { - DPRINT1("ConSrvGetObject returning invalid handle (%x) of type %lu with access %lu ; wanted type %lu with access %lu\n", Handle, ObjectEntry->Type, HandleEntry->Access, Type, Access); + DPRINT1("ConSrvGetObject -- Invalid handle 0x%x of type %lu with access %lu ; retrieved object 0x%x (handle 0x%x) of type %lu with access %lu\n", + Handle, Type, Access, ObjectEntry, HandleEntry, (ObjectEntry ? ObjectEntry->Type : 0), (HandleEntry ? HandleEntry->Access : 0)); + RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_INVALID_HANDLE; } RtlLeaveCriticalSection(&ProcessData->HandleTableLock); - if (ConSrvValidateConsole(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole)) + // Status = ConDrvGetConsole(&ObjectConsole, ProcessData->ConsoleHandle, LockConsole); + // if (NT_SUCCESS(Status)) + if (ConDrvValidateConsoleUnsafe(ObjectEntry->Console, CONSOLE_RUNNING, LockConsole)) { _InterlockedIncrement(&ObjectEntry->Console->ReferenceCount); @@ -478,6 +484,8 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PCONSOLE_START_INFO ConsoleStartInfo) { NTSTATUS Status = STATUS_SUCCESS; + HANDLE ConsoleHandle; + PCONSOLE Console; /* * We are about to create a new console. However when ConSrvNewProcess @@ -492,29 +500,36 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, ConSrvFreeHandlesTable(ProcessData); /* Initialize a new Console owned by this process */ - Status = ConSrvInitConsole(&ProcessData->Console, ConsoleStartInfo, ProcessData->Process); + Status = ConSrvInitConsole(&ConsoleHandle, + &Console, + ConsoleStartInfo, + HandleToUlong(ProcessData->Process->ClientId.UniqueProcess)); if (!NT_SUCCESS(Status)) { DPRINT1("Console initialization failed\n"); return Status; } + /* Assign the new console handle */ + ProcessData->ConsoleHandle = ConsoleHandle; + /* Initialize the handles table */ Status = ConSrvInitHandlesTable(ProcessData, + Console, pInputHandle, pOutputHandle, pErrorHandle); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to initialize the handles table\n"); - ConSrvDeleteConsole(ProcessData->Console); - ProcessData->Console = NULL; + ConSrvDeleteConsole(Console); + ProcessData->ConsoleHandle = NULL; return Status; } /* Duplicate the Input Event */ Status = NtDuplicateObject(NtCurrentProcess(), - ProcessData->Console->InputBuffer.ActiveEvent, + Console->InputBuffer.ActiveEvent, ProcessData->Process->ProcessHandle, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, 0, 0); @@ -522,19 +537,19 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, { DPRINT1("NtDuplicateObject() failed: %lu\n", Status); ConSrvFreeHandlesTable(ProcessData); - ConSrvDeleteConsole(ProcessData->Console); - ProcessData->Console = NULL; + ConSrvDeleteConsole(Console); + ProcessData->ConsoleHandle = NULL; return Status; } /* Insert the process into the processes list of the console */ - InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink); + InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink); /* Add a reference count because the process is tied to the console */ - _InterlockedIncrement(&ProcessData->Console->ReferenceCount); + _InterlockedIncrement(&Console->ReferenceCount); /* Update the internal info of the terminal */ - ConioRefreshInternalInfo(ProcessData->Console); + ConioRefreshInternalInfo(Console); return STATUS_SUCCESS; } @@ -542,23 +557,26 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, - PCONSOLE Console, + HANDLE ConsoleHandle, BOOL CreateNewHandlesTable, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle) { NTSTATUS Status = STATUS_SUCCESS; + PCONSOLE Console; /* Validate and lock the console */ - if (!ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE)) + if (!ConDrvValidateConsole(&Console, + ConsoleHandle, + CONSOLE_RUNNING, TRUE)) { // FIXME: Find another status code return STATUS_UNSUCCESSFUL; } /* Inherit the console */ - ProcessData->Console = Console; + ProcessData->ConsoleHandle = ConsoleHandle; if (CreateNewHandlesTable) { @@ -576,20 +594,21 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, /* Initialize the handles table */ Status = ConSrvInitHandlesTable(ProcessData, + Console, pInputHandle, pOutputHandle, pErrorHandle); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to initialize the handles table\n"); - ProcessData->Console = NULL; + ProcessData->ConsoleHandle = NULL; goto Quit; } } /* Duplicate the Input Event */ Status = NtDuplicateObject(NtCurrentProcess(), - ProcessData->Console->InputBuffer.ActiveEvent, + Console->InputBuffer.ActiveEvent, ProcessData->Process->ProcessHandle, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, 0, 0); @@ -597,18 +616,18 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, { DPRINT1("NtDuplicateObject() failed: %lu\n", Status); ConSrvFreeHandlesTable(ProcessData); // NOTE: Always free the handles table. - ProcessData->Console = NULL; + ProcessData->ConsoleHandle = NULL; goto Quit; } /* Insert the process into the processes list of the console */ - InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink); + InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink); /* Add a reference count because the process is tied to the console */ - _InterlockedIncrement(&ProcessData->Console->ReferenceCount); + _InterlockedIncrement(&Console->ReferenceCount); /* Update the internal info of the terminal */ - ConioRefreshInternalInfo(ProcessData->Console); + ConioRefreshInternalInfo(Console); Status = STATUS_SUCCESS; @@ -622,14 +641,16 @@ VOID FASTCALL ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData) { - PCONSOLE Console = ProcessData->Console; + PCONSOLE Console; DPRINT("ConSrvRemoveConsole\n"); // RtlEnterCriticalSection(&ProcessData->HandleTableLock); /* Validate and lock the console */ - if (ConSrvValidateConsole(Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsole(&Console, + ProcessData->ConsoleHandle, + CONSOLE_RUNNING, TRUE)) { DPRINT("ConSrvRemoveConsole - Locking OK\n"); @@ -637,7 +658,7 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData) ConSrvFreeHandlesTable(ProcessData); /* Detach the process from the console */ - ProcessData->Console = NULL; + ProcessData->ConsoleHandle = NULL; /* Remove ourselves from the console's list of processes */ RemoveEntryList(&ProcessData->ConsoleLink); @@ -647,7 +668,7 @@ ConSrvRemoveConsole(PCONSOLE_PROCESS_DATA ProcessData) /* Release the console */ DPRINT("ConSrvRemoveConsole - Decrement Console->ReferenceCount = %lu\n", Console->ReferenceCount); - ConSrvReleaseConsole(Console, TRUE); + ConDrvReleaseConsole(Console, TRUE); //CloseHandle(ProcessData->ConsoleEvent); //ProcessData->ConsoleEvent = NULL; } @@ -749,7 +770,7 @@ CSR_API(SrvVerifyConsoleIoHandle) PCONSOLE Console; HANDLE ConsoleHandle = VerifyHandleRequest->ConsoleHandle; - ULONG_PTR Index = (ULONG_PTR)ConsoleHandle >> 2; + ULONG Index = HandleToULong(ConsoleHandle) >> 2; Status = ConSrvGetConsole(ProcessData, &Console, TRUE); if (!NT_SUCCESS(Status)) @@ -782,7 +803,7 @@ CSR_API(SrvDuplicateHandle) PCONSOLE Console; HANDLE ConsoleHandle = DuplicateHandleRequest->ConsoleHandle; - ULONG_PTR Index = (ULONG_PTR)ConsoleHandle >> 2; + ULONG Index = HandleToULong(ConsoleHandle) >> 2; PCONSOLE_IO_HANDLE Entry; DWORD DesiredAccess; diff --git a/win32ss/user/consrv/handle.h b/win32ss/user/winsrv/consrv/handle.h similarity index 96% rename from win32ss/user/consrv/handle.h rename to win32ss/user/winsrv/consrv/handle.h index c3ee1f22b88..dcd7b590e1c 100644 --- a/win32ss/user/consrv/handle.h +++ b/win32ss/user/winsrv/consrv/handle.h @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/handle.h + * FILE: win32ss/user/winsrv/consrv/handle.h * PURPOSE: Console I/O Handles functions * PROGRAMMERS: David Welch * Jeffrey Morlan diff --git a/win32ss/user/consrv/heap.h b/win32ss/user/winsrv/consrv/heap.h similarity index 89% rename from win32ss/user/consrv/heap.h rename to win32ss/user/winsrv/consrv/heap.h index dd874e86741..4d21c657f76 100644 --- a/win32ss/user/consrv/heap.h +++ b/win32ss/user/winsrv/consrv/heap.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/heap.h + * FILE: win32ss/user/winsrv/consrv/heap.h * PURPOSE: Heap Helpers * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ diff --git a/win32ss/user/consrv/include/conio.h b/win32ss/user/winsrv/consrv/include/conio.h similarity index 87% rename from win32ss/user/consrv/include/conio.h rename to win32ss/user/winsrv/consrv/include/conio.h index bcada388584..3ef623fb592 100644 --- a/win32ss/user/consrv/include/conio.h +++ b/win32ss/user/winsrv/consrv/include/conio.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/include/conio.h + * FILE: win32ss/user/winsrv/consrv/include/conio.h * PURPOSE: Public Console I/O Interface * PROGRAMMERS: G van Geldorp * Jeffrey Morlan @@ -70,7 +70,7 @@ struct _CONSOLE_SCREEN_BUFFER COORD OldScreenBufferSize; /* Old size of this screen buffer */ COORD OldViewSize; /* Old associated view size */ - COORD ViewOrigin; /* Beginning offset for the actual display area */ + COORD ViewOrigin; /* Beginning offset for the actual display area */ /***** Put that VV in TEXTMODE_SCREEN_BUFFER ?? *****/ USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */ @@ -173,79 +173,85 @@ typedef struct _CONSOLE_INPUT_BUFFER USHORT Mode; /* Input buffer modes */ } CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER; + +typedef struct _FRONTEND FRONTEND, *PFRONTEND; +/* HACK: */ typedef struct _CONSOLE_INFO *PCONSOLE_INFO; typedef struct _FRONTEND_VTBL { /* * Internal interface (functions called by the console server only) */ - // BOOL (WINAPI *Init)(); - VOID (WINAPI *CleanupConsole)(struct _CONSOLE* Console); + NTSTATUS (WINAPI *InitFrontEnd)(IN OUT PFRONTEND This, + IN struct _CONSOLE* Console); + VOID (WINAPI *DeinitFrontEnd)(IN OUT PFRONTEND This); + /* Interface used for both text-mode and graphics screen buffers */ - VOID (WINAPI *DrawRegion)(struct _CONSOLE* Console, + VOID (WINAPI *DrawRegion)(IN OUT PFRONTEND This, SMALL_RECT* Region); /* Interface used only for text-mode screen buffers */ - VOID (WINAPI *WriteStream)(struct _CONSOLE* Console, + VOID (WINAPI *WriteStream)(IN OUT PFRONTEND This, SMALL_RECT* Block, SHORT CursorStartX, SHORT CursorStartY, UINT ScrolledLines, PWCHAR Buffer, UINT Length); - BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console, + BOOL (WINAPI *SetCursorInfo)(IN OUT PFRONTEND This, PCONSOLE_SCREEN_BUFFER ScreenBuffer); - BOOL (WINAPI *SetScreenInfo)(struct _CONSOLE* Console, + BOOL (WINAPI *SetScreenInfo)(IN OUT PFRONTEND This, PCONSOLE_SCREEN_BUFFER ScreenBuffer, SHORT OldCursorX, SHORT OldCursorY); - VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console); - BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console, + VOID (WINAPI *ResizeTerminal)(IN OUT PFRONTEND This); + BOOL (WINAPI *ProcessKeyCallback)(IN OUT PFRONTEND This, MSG* msg, BYTE KeyStateMenu, DWORD ShiftState, UINT VirtualKeyCode, BOOL Down); - VOID (WINAPI *RefreshInternalInfo)(struct _CONSOLE* Console); + VOID (WINAPI *RefreshInternalInfo)(IN OUT PFRONTEND This); /* * External interface (functions corresponding to the Console API) */ - VOID (WINAPI *ChangeTitle)(struct _CONSOLE* Console); - BOOL (WINAPI *ChangeIcon)(struct _CONSOLE* Console, + VOID (WINAPI *ChangeTitle)(IN OUT PFRONTEND This); + BOOL (WINAPI *ChangeIcon)(IN OUT PFRONTEND This, HICON hWindowIcon); - HWND (WINAPI *GetConsoleWindowHandle)(struct _CONSOLE* Console); - VOID (WINAPI *GetLargestConsoleWindowSize)(struct _CONSOLE* Console, + HWND (WINAPI *GetConsoleWindowHandle)(IN OUT PFRONTEND This); + VOID (WINAPI *GetLargestConsoleWindowSize)(IN OUT PFRONTEND This, PCOORD pSize); - ULONG (WINAPI *GetDisplayMode)(struct _CONSOLE* Console); - BOOL (WINAPI *SetDisplayMode)(struct _CONSOLE* Console, + ULONG (WINAPI *GetDisplayMode)(IN OUT PFRONTEND This); + BOOL (WINAPI *SetDisplayMode)(IN OUT PFRONTEND This, ULONG NewMode); - INT (WINAPI *ShowMouseCursor)(struct _CONSOLE* Console, + INT (WINAPI *ShowMouseCursor)(IN OUT PFRONTEND This, BOOL Show); - BOOL (WINAPI *SetMouseCursor)(struct _CONSOLE* Console, + BOOL (WINAPI *SetMouseCursor)(IN OUT PFRONTEND This, HCURSOR hCursor); - HMENU (WINAPI *MenuControl)(struct _CONSOLE* Console, + HMENU (WINAPI *MenuControl)(IN OUT PFRONTEND This, UINT cmdIdLow, UINT cmdIdHigh); - BOOL (WINAPI *SetMenuClose)(struct _CONSOLE* Console, + BOOL (WINAPI *SetMenuClose)(IN OUT PFRONTEND This, BOOL Enable); #if 0 // Possible future front-end interface - BOOL (WINAPI *GetFrontEndProperty)(struct _CONSOLE* Console, + BOOL (WINAPI *GetFrontEndProperty)(IN OUT PFRONTEND This, ULONG Flag, PVOID Info, ULONG Size); - BOOL (WINAPI *SetFrontEndProperty)(struct _CONSOLE* Console, + BOOL (WINAPI *SetFrontEndProperty)(IN OUT PFRONTEND This, ULONG Flag, PVOID Info /*, ULONG Size */); #endif } FRONTEND_VTBL, *PFRONTEND_VTBL; -typedef struct _FRONTEND_IFACE +struct _FRONTEND { - PFRONTEND_VTBL Vtbl; /* Virtual table */ - PVOID Data; /* Private data */ - PVOID OldData; /* Reserved */ -} FRONTEND_IFACE, *PFRONTEND_IFACE; + PFRONTEND_VTBL Vtbl; /* Virtual table */ + struct _CONSOLE* Console; /* Console to which the frontend is attached to */ + PVOID Data; /* Private data */ + PVOID OldData; /* Reserved */ +}; /* * WARNING: Change the state of the console ONLY when the console is locked ! @@ -264,13 +270,12 @@ typedef struct _CONSOLE CRITICAL_SECTION Lock; CONSOLE_STATE State; /* State of the console */ - LIST_ENTRY Entry; /* Entry in the list of consoles */ LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */ - FRONTEND_IFACE TermIFace; /* Frontend-specific interface */ + FRONTEND TermIFace; /* Frontend-specific interface */ /**************************** Input buffer and data ***************************/ - CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */ + CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */ /** Put those things in TEXTMODE_SCREEN_BUFFER ?? **/ PWCHAR LineBuffer; /* Current line being input, in line buffered mode */ @@ -324,9 +329,11 @@ typedef struct _CONSOLE /* console.c */ VOID FASTCALL ConioPause(PCONSOLE Console, UINT Flags); VOID FASTCALL ConioUnpause(PCONSOLE Console, UINT Flags); -ULONG FASTCALL ConSrvConsoleProcessCtrlEvent(PCONSOLE Console, - ULONG ProcessGroupId, - DWORD Event); + +NTSTATUS NTAPI +ConDrvConsoleProcessCtrlEvent(IN PCONSOLE Console, + IN ULONG ProcessGroupId, + IN ULONG Event); /* coninput.c */ VOID WINAPI ConioProcessKey(PCONSOLE Console, MSG* msg); diff --git a/win32ss/user/winsrv/consrv/include/conio2.h b/win32ss/user/winsrv/consrv/include/conio2.h new file mode 100644 index 00000000000..ce8efd006f9 --- /dev/null +++ b/win32ss/user/winsrv/consrv/include/conio2.h @@ -0,0 +1,50 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/conio.h + * PURPOSE: Internal Console I/O Interface + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#pragma once + +/* Macros used to call functions in the FRONTEND_VTBL virtual table */ + +#define ConioDrawRegion(Console, Region) \ + (Console)->TermIFace.Vtbl->DrawRegion(&(Console)->TermIFace, (Region)) +#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \ + (Console)->TermIFace.Vtbl->WriteStream(&(Console)->TermIFace, (Block), (CurStartX), (CurStartY), \ + (ScrolledLines), (Buffer), (Length)) +#define ConioSetCursorInfo(Console, Buff) \ + (Console)->TermIFace.Vtbl->SetCursorInfo(&(Console)->TermIFace, (Buff)) +#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \ + (Console)->TermIFace.Vtbl->SetScreenInfo(&(Console)->TermIFace, (Buff), (OldCursorX), (OldCursorY)) +#define ConioResizeTerminal(Console) \ + (Console)->TermIFace.Vtbl->ResizeTerminal(&(Console)->TermIFace) +#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \ + (Console)->TermIFace.Vtbl->ProcessKeyCallback(&(Console)->TermIFace, (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down)) +#define ConioRefreshInternalInfo(Console) \ + (Console)->TermIFace.Vtbl->RefreshInternalInfo(&(Console)->TermIFace) + +#define ConioChangeTitle(Console) \ + (Console)->TermIFace.Vtbl->ChangeTitle(&(Console)->TermIFace) +#define ConioChangeIcon(Console, hWindowIcon) \ + (Console)->TermIFace.Vtbl->ChangeIcon(&(Console)->TermIFace, (hWindowIcon)) +#define ConioGetConsoleWindowHandle(Console) \ + (Console)->TermIFace.Vtbl->GetConsoleWindowHandle(&(Console)->TermIFace) +#define ConioGetLargestConsoleWindowSize(Console, pSize) \ + (Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize(&(Console)->TermIFace, (pSize)) +#define ConioGetDisplayMode(Console) \ + (Console)->TermIFace.Vtbl->GetDisplayMode(&(Console)->TermIFace) +#define ConioSetDisplayMode(Console, NewMode) \ + (Console)->TermIFace.Vtbl->SetDisplayMode(&(Console)->TermIFace, (NewMode)) +#define ConioShowMouseCursor(Console, Show) \ + (Console)->TermIFace.Vtbl->ShowMouseCursor(&(Console)->TermIFace, (Show)) +#define ConioSetMouseCursor(Console, hCursor) \ + (Console)->TermIFace.Vtbl->SetMouseCursor(&(Console)->TermIFace, (hCursor)) +#define ConioMenuControl(Console, CmdIdLow, CmdIdHigh) \ + (Console)->TermIFace.Vtbl->MenuControl(&(Console)->TermIFace, (CmdIdLow), (CmdIdHigh)) +#define ConioSetMenuClose(Console, Enable) \ + (Console)->TermIFace.Vtbl->SetMenuClose(&(Console)->TermIFace, (Enable)) + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/include/console.h b/win32ss/user/winsrv/consrv/include/console.h new file mode 100644 index 00000000000..4214e071e18 --- /dev/null +++ b/win32ss/user/winsrv/consrv/include/console.h @@ -0,0 +1,54 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/include/console.h + * PURPOSE: Public Console Management Interface + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#pragma once + +VOID NTAPI +ConDrvInitConsoleSupport(VOID); + +NTSTATUS NTAPI +ConDrvInitConsole(OUT PHANDLE NewConsoleHandle, + OUT PCONSOLE* NewConsole, + IN PCONSOLE_INFO ConsoleInfo, + IN ULONG ConsoleLeaderProcessId); +NTSTATUS NTAPI +ConDrvRegisterFrontEnd(IN PCONSOLE Console, + IN PFRONTEND FrontEnd); +NTSTATUS NTAPI +ConDrvDeregisterFrontEnd(IN PCONSOLE Console); +VOID NTAPI +ConDrvDeleteConsole(IN PCONSOLE Console); + + + +BOOLEAN NTAPI +ConDrvValidateConsoleState(IN PCONSOLE Console, + IN CONSOLE_STATE ExpectedState); + +BOOLEAN NTAPI +ConDrvValidateConsoleUnsafe(IN PCONSOLE Console, + IN CONSOLE_STATE ExpectedState, + IN BOOLEAN LockConsole); + +BOOLEAN NTAPI +ConDrvValidateConsole(OUT PCONSOLE* Console, + IN HANDLE ConsoleHandle, + IN CONSOLE_STATE ExpectedState, + IN BOOLEAN LockConsole); + + + +NTSTATUS NTAPI +ConDrvGetConsole(OUT PCONSOLE* Console, + IN HANDLE ConsoleHandle, + IN BOOLEAN LockConsole); +VOID NTAPI +ConDrvReleaseConsole(IN PCONSOLE Console, + IN BOOLEAN WasConsoleLocked); + +/* EOF */ diff --git a/win32ss/user/consrv/include/settings.h b/win32ss/user/winsrv/consrv/include/settings.h similarity index 97% rename from win32ss/user/consrv/include/settings.h rename to win32ss/user/winsrv/consrv/include/settings.h index 551ccdca64f..f538460685b 100644 --- a/win32ss/user/consrv/include/settings.h +++ b/win32ss/user/winsrv/consrv/include/settings.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/include/settings.h + * FILE: win32ss/user/winsrv/consrv/include/settings.h * PURPOSE: Public Console Settings Management Interface * PROGRAMMERS: Johannes Anderwald * Hermes Belusca-Maito (hermes.belusca@sfr.fr) diff --git a/win32ss/user/consrv/init.c b/win32ss/user/winsrv/consrv/init.c similarity index 94% rename from win32ss/user/consrv/init.c rename to win32ss/user/winsrv/consrv/init.c index fd598501053..1cc32b6acd9 100644 --- a/win32ss/user/consrv/init.c +++ b/win32ss/user/winsrv/consrv/init.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/init.c + * FILE: win32ss/user/winsrv/consrv/init.c * PURPOSE: Initialization * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ @@ -326,7 +326,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess, **************************************************************************/ NTSTATUS Status = STATUS_SUCCESS; - PCONSOLE_PROCESS_DATA /* SourceProcessData, */ TargetProcessData; + PCONSOLE_PROCESS_DATA TargetProcessData; /* An empty target process is invalid */ if (!TargetProcess) return STATUS_INVALID_PARAMETER; @@ -337,7 +337,7 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess, RtlZeroMemory(TargetProcessData, sizeof(*TargetProcessData)); TargetProcessData->Process = TargetProcess; TargetProcessData->ConsoleEvent = NULL; - TargetProcessData->Console = TargetProcessData->ParentConsole = NULL; + TargetProcessData->ConsoleHandle = TargetProcessData->ParentConsoleHandle = NULL; TargetProcessData->ConsoleApp = ((TargetProcess->Flags & CsrProcessIsConsoleApp) ? TRUE : FALSE); /* @@ -363,20 +363,23 @@ ConSrvNewProcess(PCSR_PROCESS SourceProcess, if (TargetProcessData->ConsoleApp /* && SourceProcessData->ConsoleApp */) { PCONSOLE_PROCESS_DATA SourceProcessData = ConsoleGetPerProcessData(SourceProcess); + PCONSOLE SourceConsole; /* Validate and lock the parent's console */ - if (ConSrvValidateConsole(SourceProcessData->Console, CONSOLE_RUNNING, TRUE)) + if (ConDrvValidateConsole(&SourceConsole, + SourceProcessData->ConsoleHandle, + CONSOLE_RUNNING, TRUE)) { /* Inherit the parent's handles table */ Status = ConSrvInheritHandlesTable(SourceProcessData, TargetProcessData); if (NT_SUCCESS(Status)) { /* Temporary save the parent's console too */ - TargetProcessData->ParentConsole = SourceProcessData->Console; + TargetProcessData->ParentConsoleHandle = SourceProcessData->ConsoleHandle; } /* Unlock the parent's console */ - LeaveCriticalSection(&SourceProcessData->Console->Lock); + LeaveCriticalSection(&SourceConsole->Lock); } } @@ -412,8 +415,8 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess, } /* If we don't have a console, then create a new one... */ - if (!ConnectInfo->Console || - ConnectInfo->Console != ProcessData->ParentConsole) + if (!ConnectInfo->ConsoleHandle || + ConnectInfo->ConsoleHandle != ProcessData->ParentConsoleHandle) { DPRINT("ConSrvConnect - Allocate a new console\n"); @@ -446,7 +449,7 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess, /* Reuse our current console */ Status = ConSrvInheritConsole(ProcessData, - ConnectInfo->Console, + ConnectInfo->ConsoleHandle, FALSE, NULL, // &ConnectInfo->InputHandle, NULL, // &ConnectInfo->OutputHandle, @@ -458,16 +461,12 @@ ConSrvConnect(IN PCSR_PROCESS CsrProcess, } } - /* Return it to the caller */ - ConnectInfo->Console = ProcessData->Console; - - /* Input Wait Handle */ + /* Return the console handle and the input wait handle to the caller */ + ConnectInfo->ConsoleHandle = ProcessData->ConsoleHandle; ConnectInfo->InputWaitHandle = ProcessData->ConsoleEvent; - /* Set the Property Dialog Handler */ + /* Set the Property-Dialog and Control-Dispatcher handlers */ ProcessData->PropDispatcher = ConnectInfo->PropDispatcher; - - /* Set the Ctrl Dispatcher */ ProcessData->CtrlDispatcher = ConnectInfo->CtrlDispatcher; return STATUS_SUCCESS; @@ -483,8 +482,8 @@ ConSrvDisconnect(PCSR_PROCESS Process) * This function is called whenever a new process (GUI or CUI) is destroyed. **************************************************************************/ - if ( ProcessData->Console != NULL || - ProcessData->HandleTable != NULL ) + if ( ProcessData->ConsoleHandle != NULL || + ProcessData->HandleTable != NULL ) { DPRINT("ConSrvDisconnect - calling ConSrvRemoveConsole\n"); ConSrvRemoveConsole(ProcessData); @@ -508,7 +507,7 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization) if (!ConSrvHeap) return STATUS_NO_MEMORY; */ - ConSrvInitConsoleSupport(); + ConDrvInitConsoleSupport(); /* Setup the DLL Object */ LoadedServerDll->ApiBase = CONSRV_FIRST_API_NUMBER; @@ -529,16 +528,4 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization) return STATUS_SUCCESS; } -BOOL -WINAPI -DllMain(IN HINSTANCE hInstanceDll, - IN DWORD dwReason, - IN LPVOID lpReserved) -{ - UNREFERENCED_PARAMETER(hInstanceDll); - UNREFERENCED_PARAMETER(dwReason); - UNREFERENCED_PARAMETER(lpReserved); - return TRUE; -} - /* EOF */ diff --git a/win32ss/user/consrv/lang/bg-BG.rc b/win32ss/user/winsrv/consrv/lang/bg-BG.rc similarity index 100% rename from win32ss/user/consrv/lang/bg-BG.rc rename to win32ss/user/winsrv/consrv/lang/bg-BG.rc diff --git a/win32ss/user/consrv/lang/cs-CZ.rc b/win32ss/user/winsrv/consrv/lang/cs-CZ.rc similarity index 100% rename from win32ss/user/consrv/lang/cs-CZ.rc rename to win32ss/user/winsrv/consrv/lang/cs-CZ.rc diff --git a/win32ss/user/consrv/lang/de-DE.rc b/win32ss/user/winsrv/consrv/lang/de-DE.rc similarity index 100% rename from win32ss/user/consrv/lang/de-DE.rc rename to win32ss/user/winsrv/consrv/lang/de-DE.rc diff --git a/win32ss/user/consrv/lang/el-GR.rc b/win32ss/user/winsrv/consrv/lang/el-GR.rc similarity index 100% rename from win32ss/user/consrv/lang/el-GR.rc rename to win32ss/user/winsrv/consrv/lang/el-GR.rc diff --git a/win32ss/user/consrv/lang/en-US.rc b/win32ss/user/winsrv/consrv/lang/en-US.rc similarity index 100% rename from win32ss/user/consrv/lang/en-US.rc rename to win32ss/user/winsrv/consrv/lang/en-US.rc diff --git a/win32ss/user/consrv/lang/es-ES.rc b/win32ss/user/winsrv/consrv/lang/es-ES.rc similarity index 100% rename from win32ss/user/consrv/lang/es-ES.rc rename to win32ss/user/winsrv/consrv/lang/es-ES.rc diff --git a/win32ss/user/consrv/lang/fr-FR.rc b/win32ss/user/winsrv/consrv/lang/fr-FR.rc similarity index 100% rename from win32ss/user/consrv/lang/fr-FR.rc rename to win32ss/user/winsrv/consrv/lang/fr-FR.rc diff --git a/win32ss/user/consrv/lang/he-IL.rc b/win32ss/user/winsrv/consrv/lang/he-IL.rc similarity index 100% rename from win32ss/user/consrv/lang/he-IL.rc rename to win32ss/user/winsrv/consrv/lang/he-IL.rc diff --git a/win32ss/user/consrv/lang/id-ID.rc b/win32ss/user/winsrv/consrv/lang/id-ID.rc similarity index 100% rename from win32ss/user/consrv/lang/id-ID.rc rename to win32ss/user/winsrv/consrv/lang/id-ID.rc diff --git a/win32ss/user/consrv/lang/it-IT.rc b/win32ss/user/winsrv/consrv/lang/it-IT.rc similarity index 100% rename from win32ss/user/consrv/lang/it-IT.rc rename to win32ss/user/winsrv/consrv/lang/it-IT.rc diff --git a/win32ss/user/consrv/lang/ja-JP.rc b/win32ss/user/winsrv/consrv/lang/ja-JP.rc similarity index 100% rename from win32ss/user/consrv/lang/ja-JP.rc rename to win32ss/user/winsrv/consrv/lang/ja-JP.rc diff --git a/win32ss/user/consrv/lang/no-NO.rc b/win32ss/user/winsrv/consrv/lang/no-NO.rc similarity index 100% rename from win32ss/user/consrv/lang/no-NO.rc rename to win32ss/user/winsrv/consrv/lang/no-NO.rc diff --git a/win32ss/user/consrv/lang/pl-PL.rc b/win32ss/user/winsrv/consrv/lang/pl-PL.rc similarity index 100% rename from win32ss/user/consrv/lang/pl-PL.rc rename to win32ss/user/winsrv/consrv/lang/pl-PL.rc diff --git a/win32ss/user/consrv/lang/pt-BR.rc b/win32ss/user/winsrv/consrv/lang/pt-BR.rc similarity index 100% rename from win32ss/user/consrv/lang/pt-BR.rc rename to win32ss/user/winsrv/consrv/lang/pt-BR.rc diff --git a/win32ss/user/consrv/lang/ro-RO.rc b/win32ss/user/winsrv/consrv/lang/ro-RO.rc similarity index 100% rename from win32ss/user/consrv/lang/ro-RO.rc rename to win32ss/user/winsrv/consrv/lang/ro-RO.rc diff --git a/win32ss/user/consrv/lang/ru-RU.rc b/win32ss/user/winsrv/consrv/lang/ru-RU.rc similarity index 100% rename from win32ss/user/consrv/lang/ru-RU.rc rename to win32ss/user/winsrv/consrv/lang/ru-RU.rc diff --git a/win32ss/user/consrv/lang/sk-SK.rc b/win32ss/user/winsrv/consrv/lang/sk-SK.rc similarity index 100% rename from win32ss/user/consrv/lang/sk-SK.rc rename to win32ss/user/winsrv/consrv/lang/sk-SK.rc diff --git a/win32ss/user/consrv/lang/sv-SE.rc b/win32ss/user/winsrv/consrv/lang/sv-SE.rc similarity index 100% rename from win32ss/user/consrv/lang/sv-SE.rc rename to win32ss/user/winsrv/consrv/lang/sv-SE.rc diff --git a/win32ss/user/consrv/lang/tr-TR.rc b/win32ss/user/winsrv/consrv/lang/tr-TR.rc similarity index 100% rename from win32ss/user/consrv/lang/tr-TR.rc rename to win32ss/user/winsrv/consrv/lang/tr-TR.rc diff --git a/win32ss/user/consrv/lang/uk-UA.rc b/win32ss/user/winsrv/consrv/lang/uk-UA.rc similarity index 100% rename from win32ss/user/consrv/lang/uk-UA.rc rename to win32ss/user/winsrv/consrv/lang/uk-UA.rc diff --git a/win32ss/user/consrv/lang/zh-CN.rc b/win32ss/user/winsrv/consrv/lang/zh-CN.rc similarity index 100% rename from win32ss/user/consrv/lang/zh-CN.rc rename to win32ss/user/winsrv/consrv/lang/zh-CN.rc diff --git a/win32ss/user/consrv/lang/zh-TW.rc b/win32ss/user/winsrv/consrv/lang/zh-TW.rc similarity index 100% rename from win32ss/user/consrv/lang/zh-TW.rc rename to win32ss/user/winsrv/consrv/lang/zh-TW.rc diff --git a/win32ss/user/consrv/lineinput.c b/win32ss/user/winsrv/consrv/lineinput.c similarity index 99% rename from win32ss/user/consrv/lineinput.c rename to win32ss/user/winsrv/consrv/lineinput.c index d780543431d..2f54f0e64be 100644 --- a/win32ss/user/consrv/lineinput.c +++ b/win32ss/user/winsrv/consrv/lineinput.c @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/lineinput.c + * FILE: win32ss/user/winsrv/consrv/lineinput.c * PURPOSE: Console line input functions * PROGRAMMERS: Jeffrey Morlan */ @@ -11,7 +11,7 @@ #include "consrv.h" #include "console.h" #include "include/conio.h" -#include "conio.h" +#include "include/conio2.h" #define NDEBUG #include diff --git a/win32ss/user/consrv/lineinput.h b/win32ss/user/winsrv/consrv/lineinput.h similarity index 85% rename from win32ss/user/consrv/lineinput.h rename to win32ss/user/winsrv/consrv/lineinput.h index 555b08ef4f5..77dae2edbb0 100644 --- a/win32ss/user/consrv/lineinput.h +++ b/win32ss/user/winsrv/consrv/lineinput.h @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/lineinput.c + * FILE: win32ss/user/winsrv/consrv/lineinput.c * PURPOSE: Console line input functions * PROGRAMMERS: Jeffrey Morlan */ diff --git a/win32ss/user/consrv/procinit.h b/win32ss/user/winsrv/consrv/procinit.h similarity index 88% rename from win32ss/user/consrv/procinit.h rename to win32ss/user/winsrv/consrv/procinit.h index a8568ab8876..93f046d99a5 100644 --- a/win32ss/user/consrv/procinit.h +++ b/win32ss/user/winsrv/consrv/procinit.h @@ -1,7 +1,7 @@ /* * LICENSE: GPL - See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/procinit.h + * FILE: win32ss/user/winsrv/consrv/procinit.h * PURPOSE: Functions for console processes initialization * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ @@ -14,7 +14,7 @@ NTSTATUS FASTCALL ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PHANDLE pErrorHandle, PCONSOLE_START_INFO ConsoleStartInfo); NTSTATUS FASTCALL ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, - struct _CONSOLE* /* PCONSOLE */ Console, + HANDLE ConsoleHandle, BOOL CreateNewHandlesTable, PHANDLE pInputHandle, PHANDLE pOutputHandle, diff --git a/win32ss/user/consrv/resource.h b/win32ss/user/winsrv/consrv/resource.h similarity index 78% rename from win32ss/user/consrv/resource.h rename to win32ss/user/winsrv/consrv/resource.h index 126e700acb0..dc6f4a9898f 100644 --- a/win32ss/user/consrv/resource.h +++ b/win32ss/user/winsrv/consrv/resource.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/resource.h + * FILE: win32ss/user/winsrv/consrv/resource.h * PURPOSE: Resource #defines */ diff --git a/win32ss/user/consrv/rsrc.rc b/win32ss/user/winsrv/consrv/rsrc.rc similarity index 100% rename from win32ss/user/consrv/rsrc.rc rename to win32ss/user/winsrv/consrv/rsrc.rc diff --git a/win32ss/user/consrv/settings.c b/win32ss/user/winsrv/consrv/settings.c similarity index 99% rename from win32ss/user/consrv/settings.c rename to win32ss/user/winsrv/consrv/settings.c index 468eebe1da2..738d5bfce3c 100644 --- a/win32ss/user/consrv/settings.c +++ b/win32ss/user/winsrv/consrv/settings.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Console Server DLL - * FILE: win32ss/user/consrv/settings.c + * FILE: win32ss/user/winsrv/consrv/settings.c * PURPOSE: Console settings management * PROGRAMMERS: Johannes Anderwald * Hermes Belusca-Maito (hermes.belusca@sfr.fr) @@ -11,7 +11,7 @@ #include "consrv.h" #include "include/conio.h" -#include "conio.h" +#include "include/conio2.h" #include "include/settings.h" #include // for swprintf diff --git a/win32ss/user/winsrv/init.c b/win32ss/user/winsrv/init.c index c9585cd93ba..877cdc3f8d2 100644 --- a/win32ss/user/winsrv/init.c +++ b/win32ss/user/winsrv/init.c @@ -9,231 +9,19 @@ /* INCLUDES *******************************************************************/ -#include "winsrv.h" -#include "api.h" +/* PSDK Headers */ +#include +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H +#include +#include #define NDEBUG #include -/* GLOBALS ********************************************************************/ -HINSTANCE UserServerDllInstance = NULL; - -/* Memory */ -HANDLE UserServerHeap = NULL; // Our own heap. - -// Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3 -PCSR_API_ROUTINE UserServerApiDispatchTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = -{ - SrvExitWindowsEx, - // SrvEndTask, - // SrvLogon, - SrvRegisterServicesProcess, // Not present in Win7 - // SrvActivateDebugger, - // SrvGetThreadConsoleDesktop, // Not present in Win7 - // SrvDeviceEvent, - SrvRegisterLogonProcess, // Not present in Win7 - // SrvCreateSystemThreads, - // SrvRecordShutdownReason, - // SrvCancelShutdown, // Added in Vista - // SrvConsoleHandleOperation, // Added in Win7 - // SrvGetSetShutdownBlockReason, // Added in Vista -}; - -BOOLEAN UserServerApiServerValidTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = -{ - FALSE, // SrvExitWindowsEx - // FALSE, // SrvEndTask - // FALSE, // SrvLogon - FALSE, // SrvRegisterServicesProcess - // FALSE, // SrvActivateDebugger - // TRUE, // SrvGetThreadConsoleDesktop - // FALSE, // SrvDeviceEvent - FALSE, // SrvRegisterLogonProcess - // FALSE, // SrvCreateSystemThreads - // FALSE, // SrvRecordShutdownReason - // FALSE, // SrvCancelShutdown - // FALSE, // SrvConsoleHandleOperation - // FALSE, // SrvGetSetShutdownBlockReason -}; - -PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = -{ - "SrvExitWindowsEx", - // "SrvEndTask", - // "SrvLogon", - "SrvRegisterServicesProcess", - // "SrvActivateDebugger", - // "SrvGetThreadConsoleDesktop", - // "SrvDeviceEvent", - "SrvRegisterLogonProcess", - // "SrvCreateSystemThreads", - // "SrvRecordShutdownReason", - // "SrvCancelShutdown", - // "SrvConsoleHandleOperation", - // "SrvGetSetShutdownBlockReason", -}; - - -/* FUNCTIONS ******************************************************************/ - -// PUSER_SOUND_SENTRY. Used in basesrv.dll -BOOL WINAPI _UserSoundSentry(VOID) -{ - // TODO: Do something. - return TRUE; -} - -ULONG -InitializeVideoAddressSpace(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); - NTSTATUS Status; - HANDLE PhysMemHandle; - PVOID BaseAddress; - LARGE_INTEGER Offset; - SIZE_T ViewSize; - CHAR IVTAndBda[1024+256]; - - /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */ - BaseAddress = 0; - ViewSize = 1024 * 1024; - Status = ZwFreeVirtualMemory(NtCurrentProcess(), - &BaseAddress, - &ViewSize, - MEM_RELEASE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Couldn't unmap reserved memory (%x)\n", Status); - return 0; - } - - /* Open the physical memory section */ - InitializeObjectAttributes(&ObjectAttributes, - &PhysMemName, - 0, - NULL, - NULL); - Status = ZwOpenSection(&PhysMemHandle, - SECTION_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Couldn't open \\Device\\PhysicalMemory\n"); - return 0; - } - - /* Map the BIOS and device registers into the address space */ - Offset.QuadPart = 0xa0000; - ViewSize = 0x100000 - 0xa0000; - BaseAddress = (PVOID)0xa0000; - Status = ZwMapViewOfSection(PhysMemHandle, - NtCurrentProcess(), - &BaseAddress, - 0, - ViewSize, - &Offset, - &ViewSize, - ViewUnmap, - 0, - PAGE_EXECUTE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Couldn't map physical memory (%x)\n", Status); - ZwClose(PhysMemHandle); - return 0; - } - - /* Close physical memory section handle */ - ZwClose(PhysMemHandle); - - if (BaseAddress != (PVOID)0xa0000) - { - DPRINT1("Couldn't map physical memory at the right address (was %x)\n", - BaseAddress); - return 0; - } - - /* Allocate some low memory to use for the non-BIOS - * parts of the v86 mode address space - */ - BaseAddress = (PVOID)0x1; - ViewSize = 0xa0000 - 0x1000; - Status = ZwAllocateVirtualMemory(NtCurrentProcess(), - &BaseAddress, - 0, - &ViewSize, - MEM_RESERVE | MEM_COMMIT, - PAGE_EXECUTE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status); - return 0; - } - if (BaseAddress != (PVOID)0x0) - { - DPRINT1("Failed to allocate virtual memory at right address (was %x)\n", - BaseAddress); - return 0; - } - - /* Get the real mode IVT and BDA from the kernel */ - Status = NtVdmControl(VdmInitialize, IVTAndBda); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtVdmControl failed (status %x)\n", Status); - return 0; - } - - /* Return success */ - return 1; -} - -/********************************************************************** - * UserpInitVideo - * - * TODO: we need a virtual device for sessions other than - * TODO: the console one - */ -NTSTATUS -UserpInitVideo(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1"); - IO_STATUS_BLOCK Iosb; - HANDLE VideoHandle = (HANDLE) 0; - NTSTATUS Status = STATUS_SUCCESS; - - DPRINT("CSR: %s called\n", __FUNCTION__); - - InitializeVideoAddressSpace(); - - InitializeObjectAttributes(&ObjectAttributes, - &DeviceName, - 0, - NULL, - NULL); - Status = NtOpenFile(&VideoHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &Iosb, - 0, - 0); - if (NT_SUCCESS(Status)) - { - NtClose(VideoHandle); - } - - return Status; -} - -VOID -WINAPI -PrivateCsrssManualGuiCheck(LONG Check) -{ - NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK); -} +/* ENTRY-POINT ****************************************************************/ /*** HACK from win32csr... ***/ static HHOOK hhk = NULL; @@ -248,65 +36,6 @@ KeyboardHookProc(int nCode, } /*** END - HACK from win32csr... ***/ -DWORD -WINAPI -CreateSystemThreads(PVOID pParam) -{ - NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS); - DPRINT1("This thread should not terminate!\n"); - return 0; -} - -CSR_SERVER_DLL_INIT(UserServerDllInitialization) -{ -/*** From win32csr... ***/ - HANDLE ServerThread; - CLIENT_ID ClientId; - NTSTATUS Status; - UINT i; -/*** END - From win32csr... ***/ - - /* Initialize the memory */ - UserServerHeap = RtlGetProcessHeap(); - - /* Initialize the video */ - UserpInitVideo(); - NtUserInitialize(0, NULL, NULL); - PrivateCsrssManualGuiCheck(0); - - /* Setup the DLL Object */ - LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER; - LoadedServerDll->HighestApiSupported = UserpMaxApiNumber; - LoadedServerDll->DispatchTable = UserServerApiDispatchTable; - LoadedServerDll->ValidTable = UserServerApiServerValidTable; - LoadedServerDll->NameTable = UserServerApiNameTable; - LoadedServerDll->SizeOfProcessData = 0; - LoadedServerDll->ConnectCallback = NULL; - LoadedServerDll->DisconnectCallback = NULL; - LoadedServerDll->HardErrorCallback = UserServerHardError; - LoadedServerDll->ShutdownProcessCallback = NULL; - - UserServerDllInstance = LoadedServerDll->ServerHandle; - -/*** From win32csr... See r54125 ***/ - /* Start the Raw Input Thread and the Desktop Thread */ - for (i = 0; i < 2; ++i) - { - Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId); - if (NT_SUCCESS(Status)) - { - NtResumeThread(ServerThread, NULL); - NtClose(ServerThread); - } - else - DPRINT1("Cannot start Raw Input Thread!\n"); - } -/*** END - From win32csr... ***/ - - /* All done */ - return STATUS_SUCCESS; -} - BOOL WINAPI DllMain(IN HINSTANCE hInstanceDll, diff --git a/win32ss/user/winsrv/usersrv.cmake b/win32ss/user/winsrv/usersrv.cmake new file mode 100644 index 00000000000..1cf6e9a36f2 --- /dev/null +++ b/win32ss/user/winsrv/usersrv.cmake @@ -0,0 +1,15 @@ + +include_directories(usersrv) + +list(APPEND USERSRV_SOURCE + usersrv/harderror.c + usersrv/init.c + usersrv/register.c + usersrv/shutdown.c + # usersrv/usersrv.rc + ) + +add_library(usersrv ${USERSRV_SOURCE}) +#add_object_library(usersrv ${USERSRV_SOURCE}) + +set_module_type(usersrv module UNICODE) diff --git a/win32ss/user/winsrv/api.h b/win32ss/user/winsrv/usersrv/api.h similarity index 91% rename from win32ss/user/winsrv/api.h rename to win32ss/user/winsrv/usersrv/api.h index b3a826d8bda..478adf09f6e 100644 --- a/win32ss/user/winsrv/api.h +++ b/win32ss/user/winsrv/usersrv/api.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User API Server DLL - * FILE: win32ss/user/winsrv/api.h + * FILE: win32ss/user/winsrv/usersrv/api.h * PURPOSE: Public server APIs definitions * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ diff --git a/win32ss/user/winsrv/harderror.c b/win32ss/user/winsrv/usersrv/harderror.c similarity index 99% rename from win32ss/user/winsrv/harderror.c rename to win32ss/user/winsrv/usersrv/harderror.c index 708321e097b..31281c6d6f1 100644 --- a/win32ss/user/winsrv/harderror.c +++ b/win32ss/user/winsrv/usersrv/harderror.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User API Server DLL - * FILE: win32ss/user/winsrv/harderror.c + * FILE: win32ss/user/winsrv/usersrv/harderror.c * PURPOSE: Hard errors * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru) * Timo Kreuzer (timo.kreuzer@reactos.org) @@ -9,7 +9,7 @@ /* INCLUDES *******************************************************************/ -#include "winsrv.h" +#include "usersrv.h" #define NDEBUG #include diff --git a/win32ss/user/winsrv/usersrv/init.c b/win32ss/user/winsrv/usersrv/init.c new file mode 100644 index 00000000000..0cf52887b08 --- /dev/null +++ b/win32ss/user/winsrv/usersrv/init.c @@ -0,0 +1,298 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS User API Server DLL + * FILE: win32ss/user/winsrv/usersrv/init.c + * PURPOSE: Initialization + * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru) + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "usersrv.h" +#include "api.h" + +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +HINSTANCE UserServerDllInstance = NULL; + +/* Memory */ +HANDLE UserServerHeap = NULL; // Our own heap. + +// Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3 +PCSR_API_ROUTINE UserServerApiDispatchTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = +{ + SrvExitWindowsEx, + // SrvEndTask, + // SrvLogon, + SrvRegisterServicesProcess, // Not present in Win7 + // SrvActivateDebugger, + // SrvGetThreadConsoleDesktop, // Not present in Win7 + // SrvDeviceEvent, + SrvRegisterLogonProcess, // Not present in Win7 + // SrvCreateSystemThreads, + // SrvRecordShutdownReason, + // SrvCancelShutdown, // Added in Vista + // SrvConsoleHandleOperation, // Added in Win7 + // SrvGetSetShutdownBlockReason, // Added in Vista +}; + +BOOLEAN UserServerApiServerValidTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = +{ + FALSE, // SrvExitWindowsEx + // FALSE, // SrvEndTask + // FALSE, // SrvLogon + FALSE, // SrvRegisterServicesProcess + // FALSE, // SrvActivateDebugger + // TRUE, // SrvGetThreadConsoleDesktop + // FALSE, // SrvDeviceEvent + FALSE, // SrvRegisterLogonProcess + // FALSE, // SrvCreateSystemThreads + // FALSE, // SrvRecordShutdownReason + // FALSE, // SrvCancelShutdown + // FALSE, // SrvConsoleHandleOperation + // FALSE, // SrvGetSetShutdownBlockReason +}; + +PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] = +{ + "SrvExitWindowsEx", + // "SrvEndTask", + // "SrvLogon", + "SrvRegisterServicesProcess", + // "SrvActivateDebugger", + // "SrvGetThreadConsoleDesktop", + // "SrvDeviceEvent", + "SrvRegisterLogonProcess", + // "SrvCreateSystemThreads", + // "SrvRecordShutdownReason", + // "SrvCancelShutdown", + // "SrvConsoleHandleOperation", + // "SrvGetSetShutdownBlockReason", +}; + + +/* FUNCTIONS ******************************************************************/ + +// PUSER_SOUND_SENTRY. Used in basesrv.dll +BOOL WINAPI _UserSoundSentry(VOID) +{ + // TODO: Do something. + return TRUE; +} + +ULONG +InitializeVideoAddressSpace(VOID) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); + NTSTATUS Status; + HANDLE PhysMemHandle; + PVOID BaseAddress; + LARGE_INTEGER Offset; + SIZE_T ViewSize; + CHAR IVTAndBda[1024+256]; + + /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */ + BaseAddress = 0; + ViewSize = 1024 * 1024; + Status = ZwFreeVirtualMemory(NtCurrentProcess(), + &BaseAddress, + &ViewSize, + MEM_RELEASE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't unmap reserved memory (%x)\n", Status); + return 0; + } + + /* Open the physical memory section */ + InitializeObjectAttributes(&ObjectAttributes, + &PhysMemName, + 0, + NULL, + NULL); + Status = ZwOpenSection(&PhysMemHandle, + SECTION_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't open \\Device\\PhysicalMemory\n"); + return 0; + } + + /* Map the BIOS and device registers into the address space */ + Offset.QuadPart = 0xa0000; + ViewSize = 0x100000 - 0xa0000; + BaseAddress = (PVOID)0xa0000; + Status = ZwMapViewOfSection(PhysMemHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + ViewSize, + &Offset, + &ViewSize, + ViewUnmap, + 0, + PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Couldn't map physical memory (%x)\n", Status); + ZwClose(PhysMemHandle); + return 0; + } + + /* Close physical memory section handle */ + ZwClose(PhysMemHandle); + + if (BaseAddress != (PVOID)0xa0000) + { + DPRINT1("Couldn't map physical memory at the right address (was %x)\n", + BaseAddress); + return 0; + } + + /* Allocate some low memory to use for the non-BIOS + * parts of the v86 mode address space + */ + BaseAddress = (PVOID)0x1; + ViewSize = 0xa0000 - 0x1000; + Status = ZwAllocateVirtualMemory(NtCurrentProcess(), + &BaseAddress, + 0, + &ViewSize, + MEM_RESERVE | MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status); + return 0; + } + if (BaseAddress != (PVOID)0x0) + { + DPRINT1("Failed to allocate virtual memory at right address (was %x)\n", + BaseAddress); + return 0; + } + + /* Get the real mode IVT and BDA from the kernel */ + Status = NtVdmControl(VdmInitialize, IVTAndBda); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtVdmControl failed (status %x)\n", Status); + return 0; + } + + /* Return success */ + return 1; +} + +/********************************************************************** + * UserpInitVideo + * + * TODO: we need a virtual device for sessions other than + * TODO: the console one + */ +NTSTATUS +UserpInitVideo(VOID) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1"); + IO_STATUS_BLOCK Iosb; + HANDLE VideoHandle = (HANDLE) 0; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("CSR: %s called\n", __FUNCTION__); + + InitializeVideoAddressSpace(); + + InitializeObjectAttributes(&ObjectAttributes, + &DeviceName, + 0, + NULL, + NULL); + Status = NtOpenFile(&VideoHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &Iosb, + 0, + 0); + if (NT_SUCCESS(Status)) + { + NtClose(VideoHandle); + } + + return Status; +} + +// From win32ss/user/win32csr/dllmain.c +VOID +WINAPI +PrivateCsrssManualGuiCheck(LONG Check) +{ + NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK); +} + +DWORD +WINAPI +CreateSystemThreads(PVOID pParam) +{ + NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS); + DPRINT1("This thread should not terminate!\n"); + return 0; +} + +CSR_SERVER_DLL_INIT(UserServerDllInitialization) +{ +/*** From win32csr... ***/ + HANDLE ServerThread; + CLIENT_ID ClientId; + NTSTATUS Status; + UINT i; +/*** END - From win32csr... ***/ + + /* Initialize the memory */ + UserServerHeap = RtlGetProcessHeap(); + + /* Initialize the video */ + UserpInitVideo(); + NtUserInitialize(0, NULL, NULL); + PrivateCsrssManualGuiCheck(0); + + /* Setup the DLL Object */ + LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER; + LoadedServerDll->HighestApiSupported = UserpMaxApiNumber; + LoadedServerDll->DispatchTable = UserServerApiDispatchTable; + LoadedServerDll->ValidTable = UserServerApiServerValidTable; + LoadedServerDll->NameTable = UserServerApiNameTable; + LoadedServerDll->SizeOfProcessData = 0; + LoadedServerDll->ConnectCallback = NULL; + LoadedServerDll->DisconnectCallback = NULL; + LoadedServerDll->HardErrorCallback = UserServerHardError; + LoadedServerDll->ShutdownProcessCallback = NULL; + + UserServerDllInstance = LoadedServerDll->ServerHandle; + +/*** From win32csr... See r54125 ***/ + /* Start the Raw Input Thread and the Desktop Thread */ + for (i = 0; i < 2; ++i) + { + Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId); + if (NT_SUCCESS(Status)) + { + NtResumeThread(ServerThread, NULL); + NtClose(ServerThread); + } + else + DPRINT1("Cannot start Raw Input Thread!\n"); + } +/*** END - From win32csr... ***/ + + /* All done */ + return STATUS_SUCCESS; +} + +/* EOF */ diff --git a/win32ss/user/winsrv/lang/bg-BG.rc b/win32ss/user/winsrv/usersrv/lang/bg-BG.rc similarity index 100% rename from win32ss/user/winsrv/lang/bg-BG.rc rename to win32ss/user/winsrv/usersrv/lang/bg-BG.rc diff --git a/win32ss/user/winsrv/lang/cs-CZ.rc b/win32ss/user/winsrv/usersrv/lang/cs-CZ.rc similarity index 100% rename from win32ss/user/winsrv/lang/cs-CZ.rc rename to win32ss/user/winsrv/usersrv/lang/cs-CZ.rc diff --git a/win32ss/user/winsrv/lang/de-DE.rc b/win32ss/user/winsrv/usersrv/lang/de-DE.rc similarity index 100% rename from win32ss/user/winsrv/lang/de-DE.rc rename to win32ss/user/winsrv/usersrv/lang/de-DE.rc diff --git a/win32ss/user/winsrv/lang/el-GR.rc b/win32ss/user/winsrv/usersrv/lang/el-GR.rc similarity index 100% rename from win32ss/user/winsrv/lang/el-GR.rc rename to win32ss/user/winsrv/usersrv/lang/el-GR.rc diff --git a/win32ss/user/winsrv/lang/en-US.rc b/win32ss/user/winsrv/usersrv/lang/en-US.rc similarity index 100% rename from win32ss/user/winsrv/lang/en-US.rc rename to win32ss/user/winsrv/usersrv/lang/en-US.rc diff --git a/win32ss/user/winsrv/lang/es-ES.rc b/win32ss/user/winsrv/usersrv/lang/es-ES.rc similarity index 100% rename from win32ss/user/winsrv/lang/es-ES.rc rename to win32ss/user/winsrv/usersrv/lang/es-ES.rc diff --git a/win32ss/user/winsrv/lang/fr-FR.rc b/win32ss/user/winsrv/usersrv/lang/fr-FR.rc similarity index 100% rename from win32ss/user/winsrv/lang/fr-FR.rc rename to win32ss/user/winsrv/usersrv/lang/fr-FR.rc diff --git a/win32ss/user/winsrv/lang/he-IL.rc b/win32ss/user/winsrv/usersrv/lang/he-IL.rc similarity index 100% rename from win32ss/user/winsrv/lang/he-IL.rc rename to win32ss/user/winsrv/usersrv/lang/he-IL.rc diff --git a/win32ss/user/winsrv/lang/id-ID.rc b/win32ss/user/winsrv/usersrv/lang/id-ID.rc similarity index 100% rename from win32ss/user/winsrv/lang/id-ID.rc rename to win32ss/user/winsrv/usersrv/lang/id-ID.rc diff --git a/win32ss/user/winsrv/lang/it-IT.rc b/win32ss/user/winsrv/usersrv/lang/it-IT.rc similarity index 100% rename from win32ss/user/winsrv/lang/it-IT.rc rename to win32ss/user/winsrv/usersrv/lang/it-IT.rc diff --git a/win32ss/user/winsrv/lang/ja-JP.rc b/win32ss/user/winsrv/usersrv/lang/ja-JP.rc similarity index 100% rename from win32ss/user/winsrv/lang/ja-JP.rc rename to win32ss/user/winsrv/usersrv/lang/ja-JP.rc diff --git a/win32ss/user/winsrv/lang/no-NO.rc b/win32ss/user/winsrv/usersrv/lang/no-NO.rc similarity index 100% rename from win32ss/user/winsrv/lang/no-NO.rc rename to win32ss/user/winsrv/usersrv/lang/no-NO.rc diff --git a/win32ss/user/winsrv/lang/pl-PL.rc b/win32ss/user/winsrv/usersrv/lang/pl-PL.rc similarity index 100% rename from win32ss/user/winsrv/lang/pl-PL.rc rename to win32ss/user/winsrv/usersrv/lang/pl-PL.rc diff --git a/win32ss/user/winsrv/lang/pt-BR.rc b/win32ss/user/winsrv/usersrv/lang/pt-BR.rc similarity index 100% rename from win32ss/user/winsrv/lang/pt-BR.rc rename to win32ss/user/winsrv/usersrv/lang/pt-BR.rc diff --git a/win32ss/user/winsrv/lang/ro-RO.rc b/win32ss/user/winsrv/usersrv/lang/ro-RO.rc similarity index 100% rename from win32ss/user/winsrv/lang/ro-RO.rc rename to win32ss/user/winsrv/usersrv/lang/ro-RO.rc diff --git a/win32ss/user/winsrv/lang/ru-RU.rc b/win32ss/user/winsrv/usersrv/lang/ru-RU.rc similarity index 100% rename from win32ss/user/winsrv/lang/ru-RU.rc rename to win32ss/user/winsrv/usersrv/lang/ru-RU.rc diff --git a/win32ss/user/winsrv/lang/sk-SK.rc b/win32ss/user/winsrv/usersrv/lang/sk-SK.rc similarity index 100% rename from win32ss/user/winsrv/lang/sk-SK.rc rename to win32ss/user/winsrv/usersrv/lang/sk-SK.rc diff --git a/win32ss/user/winsrv/lang/sv-SE.rc b/win32ss/user/winsrv/usersrv/lang/sv-SE.rc similarity index 100% rename from win32ss/user/winsrv/lang/sv-SE.rc rename to win32ss/user/winsrv/usersrv/lang/sv-SE.rc diff --git a/win32ss/user/winsrv/lang/tr-TR.rc b/win32ss/user/winsrv/usersrv/lang/tr-TR.rc similarity index 100% rename from win32ss/user/winsrv/lang/tr-TR.rc rename to win32ss/user/winsrv/usersrv/lang/tr-TR.rc diff --git a/win32ss/user/winsrv/lang/uk-UA.rc b/win32ss/user/winsrv/usersrv/lang/uk-UA.rc similarity index 100% rename from win32ss/user/winsrv/lang/uk-UA.rc rename to win32ss/user/winsrv/usersrv/lang/uk-UA.rc diff --git a/win32ss/user/winsrv/lang/zh-CN.rc b/win32ss/user/winsrv/usersrv/lang/zh-CN.rc similarity index 100% rename from win32ss/user/winsrv/lang/zh-CN.rc rename to win32ss/user/winsrv/usersrv/lang/zh-CN.rc diff --git a/win32ss/user/winsrv/lang/zh-TW.rc b/win32ss/user/winsrv/usersrv/lang/zh-TW.rc similarity index 100% rename from win32ss/user/winsrv/lang/zh-TW.rc rename to win32ss/user/winsrv/usersrv/lang/zh-TW.rc diff --git a/win32ss/user/winsrv/register.c b/win32ss/user/winsrv/usersrv/register.c similarity index 96% rename from win32ss/user/winsrv/register.c rename to win32ss/user/winsrv/usersrv/register.c index f571d3823ca..5322075c276 100644 --- a/win32ss/user/winsrv/register.c +++ b/win32ss/user/winsrv/usersrv/register.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User API Server DLL - * FILE: win32ss/user/winsrv/register.c + * FILE: win32ss/user/winsrv/usersrv/register.c * PURPOSE: Register logon window and services process * PROGRAMMERS: Eric Kohl * Hermes Belusca-Maito (hermes.belusca@sfr.fr) @@ -9,7 +9,7 @@ /* INCLUDES *******************************************************************/ -#include "winsrv.h" +#include "usersrv.h" #define NDEBUG #include diff --git a/win32ss/user/winsrv/resource.h b/win32ss/user/winsrv/usersrv/resource.h similarity index 86% rename from win32ss/user/winsrv/resource.h rename to win32ss/user/winsrv/usersrv/resource.h index 2bfeae7a18c..2f0d6ead7a7 100644 --- a/win32ss/user/winsrv/resource.h +++ b/win32ss/user/winsrv/usersrv/resource.h @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User API Server DLL - * FILE: win32ss/user/winsrv/resource.h + * FILE: win32ss/user/winsrv/usersrv/resource.h * PURPOSE: Resource #defines */ diff --git a/win32ss/user/winsrv/rsrc.rc b/win32ss/user/winsrv/usersrv/rsrc.rc similarity index 100% rename from win32ss/user/winsrv/rsrc.rc rename to win32ss/user/winsrv/usersrv/rsrc.rc diff --git a/win32ss/user/winsrv/shutdown.c b/win32ss/user/winsrv/usersrv/shutdown.c similarity index 99% rename from win32ss/user/winsrv/shutdown.c rename to win32ss/user/winsrv/usersrv/shutdown.c index 24bf556bbfa..12f3a123624 100644 --- a/win32ss/user/winsrv/shutdown.c +++ b/win32ss/user/winsrv/usersrv/shutdown.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User API Server DLL - * FILE: win32ss/user/winsrv/shutdown.c + * FILE: win32ss/user/winsrv/usersrv/shutdown.c * PURPOSE: Logout/shutdown * PROGRAMMERS: * @@ -10,7 +10,7 @@ /* INCLUDES *******************************************************************/ -#include "winsrv.h" +#include "usersrv.h" #include #define NDEBUG @@ -430,7 +430,6 @@ NotifyTopLevelWindows(PNOTIFY_CONTEXT Context) return TRUE; } -/*** Taken from win32ss/user/consrv/console.c ***/ static BOOL DtbgIsDesktopVisible(VOID) { diff --git a/win32ss/user/winsrv/winsrv.h b/win32ss/user/winsrv/usersrv/usersrv.h similarity index 89% rename from win32ss/user/winsrv/winsrv.h rename to win32ss/user/winsrv/usersrv/usersrv.h index a3f642c1100..3ac83be9d7e 100644 --- a/win32ss/user/winsrv/winsrv.h +++ b/win32ss/user/winsrv/usersrv/usersrv.h @@ -1,13 +1,13 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User API Server DLL - * FILE: win32ss/user/winsrv/winsrv.h + * FILE: win32ss/user/winsrv/usersrv/usersrv.h * PURPOSE: Main header - Definitions * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) */ -#ifndef __WINSRV_H__ -#define __WINSRV_H__ +#ifndef __USERSRV_H__ +#define __USERSRV_H__ #pragma once @@ -56,6 +56,6 @@ extern HINSTANCE UserServerDllInstance; extern HANDLE UserServerHeap; extern ULONG_PTR LogonProcessId; -#endif // __WINSRV_H__ +#endif // __USERSRV_H__ /* EOF */ diff --git a/win32ss/user/winsrv/usersrv/usersrv.rc b/win32ss/user/winsrv/usersrv/usersrv.rc new file mode 100644 index 00000000000..1cd56b5feaa --- /dev/null +++ b/win32ss/user/winsrv/usersrv/usersrv.rc @@ -0,0 +1,5 @@ +#include +#include +#include "resource.h" + +#include "rsrc.rc" diff --git a/win32ss/user/winsrv/winsrv.rc b/win32ss/user/winsrv/winsrv.rc index 044ecca39ce..062bd69924b 100644 --- a/win32ss/user/winsrv/winsrv.rc +++ b/win32ss/user/winsrv/winsrv.rc @@ -1,13 +1,13 @@ #include #include -#include "resource.h" LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS User API Server DLL" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS User API & Console Server & Terminal Emulator DLL" #define REACTOS_STR_INTERNAL_NAME "winsrv" #define REACTOS_STR_ORIGINAL_FILENAME "winsrv.dll" #include -#include "rsrc.rc" +#include "consrv/consrv.rc" +#include "usersrv/usersrv.rc" diff --git a/win32ss/user/winsrv/winsrv.spec b/win32ss/user/winsrv/winsrv.spec index 79e7e251fb6..afc55aa3566 100644 --- a/win32ss/user/winsrv/winsrv.spec +++ b/win32ss/user/winsrv/winsrv.spec @@ -1,2 +1,3 @@ +@ stdcall ConServerDllInitialization(ptr) @ stdcall UserServerDllInitialization(ptr) @ stdcall _UserSoundSentry()