O Windowsie bez Windowsa
06.03.2018 | aktual.: 07.03.2018 00:59
Nie da się ukryć, że Windows jest dzisiaj najpopularniejszym systemem na biurkach. Jest nim od lat dziewięćdziesiątych i póki co nie zapowiada się na szybką zmianę w tej sprawie. Mimo wszystko Windows nie jest jedynym istniejącym systemem – mamy przecież całą masę innych systemów, mniej, lub bardziej znanych. Mimo wszystko system Microsoftu jest liderem na biurkach, stąd też posiada najwięcej oprogramowania – jest to system, który wspiera się przede wszystkim z ewentualnymi portami na inne systemy. Praktycznie odkąd Windows uzyskał swoją potęgę pojawiały się pomysły i głosy by umożliwić skorzystanie z jego bazy aplikacji także poza nim. Tylko w jaki sposób tego dokonać?
API Windowsa
Jak każdy system operacyjny, Windows posiada swoje API. Zbiorczo jest ono nazywane Windows API, w skrócie WinAPI. Z tego API korzysta (bezpośrednio lub pośrednio za sprawą różnych toolkitów) każda aplikacja działająca na tym systemie. API (Application Programming Interfejs – Interfejs programowania aplikacji) to zbiór funkcji, protokołów i narzędzi pozwalających zbudować aplikacje. To dzięki WinAPI aplikacje mogą rozmawiać z jądrem Windowsa w celu wykonania swoich zadań. API Windowsa skupia się głównie na języku C, mamy do dyspozycji jednak sporo bibliotek graficznych (w tym i od samego Microsoftu), które pozwalają pisać aplikacje na Windowsa w nowocześniejszych językach i nie babrać się w niskopoziomowym API systemowym. WinAPI nie jest używane tylko przez aplikacje, gdyż także spora część Windowsa jest w nim napisana.
Biorąc pod uwagę oficjalne implementacje WinAPI, używane w Windowsie, możemy wyróżnić 5 implementacji:
Win16 – Było to API dla 16 bitowych edycji Windowsa. Początkowo było znane jako Windows API, nazwa Win16 powstała by odróżnić je od 32 bitowej implementacji zwanej Win32. Funkcje tego API było zapewniane głównie przez te pliki: kernel.exe/krnl286.exe/krnl386.exe, user.exe i gdi.exe. Warto zaznaczyć, że pomimo rozszerzenia „exe”, były to biblioteki, nie pliki wykonywalne.
Win32 – Jak sama nazwa wskazuje, jest to 32 bitowa implementacja API Windowsa. Wprowadził ją Windows NT (który był pierwszym w pełni 32 bitowym Windowsem), zostało wprowadzone także do bazującego na DOS Windows 95. Tam początkowo nosiło nazwę Win32c (c – compatibility, czyli kompatybilność), jednak z czasem zmieniło nazwę na po prostu Win32. API to zapewniały biblioteki kernel32.dll, user32.dll i gdi32.dll.
Win32s – jest to rozszerzenie dla Windows 3.1x które implementowało pewien podzbiór Win32 umożliwiając uruchamianie niektórych, 32 bitowych aplikacji Windowsa na tych systemach. Litera „s” (ang. subset) oznacza właśnie „podzbiór”.
Win64 – nietrudno się domyślić, że to 64 bitowa implementacja WinAPI. Używana jest oczywiście w 64 bitowych odmianach Windowsa (zarówno x86‑64 jak i IA‑64). Kompatybilność została zachowana, więc zarówno 32 bitowe jak i 64 bitowe aplikacje mogą być skompilowane z jednego kodu źródłowego, lecz nie zawsze z pozytywnym skutkiem, gdyż niektóre funkcje zostały porzucone a nawet usunięte. Poza tym wskaźniki również są 64 bitowe, co w niektórych przypadkach może rodzić pewne problemy.
WinCE – odmiana WinAPI dla systemu Windows CE.
Jak widać, mamy do czynienia z kilkoma implementacjami API Windowsa. Jedne to naturalny postęp (jak przejście z Win16 na Win32), inne powstały w celach kompatybilności (np. Win32s). Tylko jak skorzystać z tego bogactwa na innych systemach? Oczywiście implementując tam WinAPI (a także ABI, czyli binarny interfejs, by móc korzystać z binarnych aplikacji bez konieczności rekompilacji). Pomimo tego, że to Wine jest chyba najsłynniejszą próbą implementacji API Windowsa na innych systemach, to nie jest jednak jedyną. Pomimo nieco innych podejść takich rozwiązań, wszystkie je łączy jedno – starały się umożliwić uruchamianie aplikacji Windowsa na systemie nie będącym Windowsem.
Wabi - próba Sun Microsystems
Wabi jest jednym z najstarszych projektów tego typu. Jego początki sięgają 1990 roku. Projekt został zapoczątkowany przez firmę Praxsys Technologies, jesienią 1992 roku projekt przejął Sun. Nazwa „Wabi” została wybrana z tego powodu, że w języku japońskim oznacza harmonię lub balans co odzwierciedlało cel projektu, który miał umożliwić pokojową egzystencje Windowsa i Uniksów. Poza tym nazwę rozszerzano jako „Windows Application Binary Interface”, chociaż Sun zarzekał się, że nazwa nie jest akronimem. Sun przejął projekt z myślą o swoim Solarisie, wersja 2.2B licencjonowana przez Caldera pojawiła się też na Linuksie.
Projekt nie implementował innych bibliotek Windowsa (skupiał się na emulacji bibliotek user.dll, kernel.dll i gdi.dll) tak więc do działania wymagał instalacji Windowsa 3.1 (gdyż projekt skupiał się na Win16), a co za tym idzie też licencji na Windowsa. Ponieważ reszta Windowsa bazowała na tych 3 bibliotekach, ich emulacja pozwoliła na uruchamianie się poprawnie aplikacji pisanych z myślą o Windowsie. Emulacja tylko kluczowych bibliotek była uważana przez inżynierów za jedyną racjonalną metodę zabierania się do uruchamiania aplikacji Windowsa. Uważano, że pełna implementacja bibliotek systemu Microsoftu (bez korzystania z już zainstalowanego systemu) byłaby zbyt trudna biorąc pod uwagę wielkość i jego skomplikowanie. Warto wspomnieć, że Wabi był dostępny zarówno dla architektury x86 jak i SPARC. Na tej drugiej aplikacje x86 były w stanie pracować dzięki dynamicznej translacji wywołań x86 na SPARC.
Poza samą warstwą kompatybilności, starano się też ustandaryzować API Windowsa (o tym w następnym punkcie), co jednak zakończyło się fiaskiem, przez co Wabi umarł w 1997 roku.
Public Windows Initiative - próba standaryzacji
Poza Wabi, Sun w 1993 roku zapowiedział też Public Windows Interface. Była to próba standaryzacji podzbioru popularnego 16 bitowego API Windowsa. Windows 3.0 sprzedawał się bardzo dobrze i był jednym z najpopularniejszych systemów. Podejście to miało zapewnić przenośność aplikacji i ich kompatybilność pomiędzy różnymi środowiskami. PWI zostało zaproponowane różnym organizacjom takim jak X/Open, IEEE czy Unix International. W lutym 1994 roku PWI Specification Comitee wysłała szkic specyfikacji do X/Open, który jednak został odrzucony, gdyż organizacja obawiała się zagrożenia ze strony Microsoft, którego WinAPI było własnością intelektualną. We wrześniu tego roku ECMA zapowiedziała zrobienie z tego standardu ISO, które zmusiłoby Microsoft do standaryzacji, który ryzykowałby utratą klientów pod postacią rządów europejskich czy azjatyckich. W 1995 roku firma Willow Software, Inc., która pracowała nad przeniesieniem technologii z Windows na Uniksy od 1993 roku, dołączyła do ECMA. Firma obiecała stworzenie pełnej specyfikacji do końca roku. W październiku zarys specyfikacji był gotowy pod nazwą Application Programming Interface for Windows i został w grudniu zaakceptowany jako ECMA-234 i przygotowywano się do zrobienia z niego standardu ISO.
Microsoft jednak ponownie upomniał się o swoją intelektualną własność, co zatrzymało proces. Opóźnienie trwało do listopada 1997 roku, a ISO po braku odpowiedzi od Microsoftu ogłosiło kontynuacje, projekt jednak zamilkł i ostatecznie nie stał się standardem ISO.
Microsoft ogłosił własny program znany jako Windows Interface Source Environment. Program ten pozwalał deweloperom rekompilować i uruchamiać aplikacje Windowsa na Uniksach i Macintoshach. WISE SDK bazowało na emulacji Windows API. SoftPC stworzony przez firmę Insygnia Solutions robił użytek z WISE. SoftPC jako emulator platformy x86 początkowo celował w uruchamianie aplikacji MS‑DOS na stacjach roboczych z Uniksem, później dzięki dołączaniu Windowsa stało się także możliwe uruchamianie aplikacji Windows. W przeciwieństwie do wielu innych podobnych emulatorów, SoftPC używał specjalnie zmodyfikowanych wersji Windowsa, które zapewniały większą wydajność, czasem sięgającą nieraz natywnej. Kiedy Microsoft wydał Windows NT wraz z podsystemem WoW (Windows on Windows, później znany jako NTVDM) pozwalającym uruchamiać aplikacje Win16 na 32 bitowym systemie, który dodatkowo trafił też na inne platformy, SoftPC stał się niepotrzebny, zwłaszcza, że platformy inne niż x86 nie cieszyły się aż takim zainteresowaniem.
Innym przykładem podobnego softu jest Merge (wcześniej celujący w zgodność z DOS), który dzięki WISE zyskał możliwość uruchamiania aplikacji Windows.
OS/2 - brat Windowsa
Innym przykładem kompatybilnego z Windowsem systemu jest OS/2. O OS/2 pisałem już wpis (można go znaleźć tutaj), warto jednak o nim wspomnieć, gdyż pasuje do tematyki wpisu. OS/2 początkowo był rozwijany wspólnie z Microsoftem, ten jednak porzucił IBM by zająć się swoim systemem. Jądro OS/2 jednak posiadało obsługę aplikacji Win16 (podobnie jak jądro NT posiadało obsługę aplikacji OS/2). Podobnie jednak jak wspomniany wcześniej Wabi, nie implementował całości Windowsa, więc wymagał jego obecności. Początkowo nieomal cały Windows 3.x był zawarty w OS/2, później system IBM pozwalał też użyć Windowsa zainstalowanego na dysku. Aplikacje Windows mogły pojawiać się bezpośrednio na pulpicie OS/2, a także możliwe było uruchomienie pełnego Windowsa na pełnym ekranie. Proces obsługujący system Microsoftu miał szeroki dostęp do sprzętu, zwłaszcza wideo, przez co przełączanie się pomiędzy OS/2 a pełnoekranowym Windowsem mogło prowadzić do usterek.
Aplikacje tak uruchomione nie posiadały ochrony pamięci, zupełnie jak w oryginale. Można było temu jednak zapobiec uruchamiając kilka sesji Windows obok siebie, gdyż każda miała swoją osobną przestrzeń adresową. Aplikacje tak uruchamiane mogły się komunikować pomiędzy sobą dzięki OLE, a także z natywnymi aplikacjami OS/2 poprzez DDE. Istniał też projekt Odin, który pozwalał skonwertować aplikacje Win32 (OS/2 wspierał tylko Win16) do natywnego formatu OS/2. Zawierał też implementacje Win32 zwaną jako Odin32 bazującą na kodzie Wine.
IBM niestety przegrał wyścig z Microsoftem, więc OS/2 nie zawojował rynku. Poniekąd przyczyniło się do tego wsparcie aplikacji Windows – bo po co pisać aplikacje natywne dla OS/2, jak można pisać aplikacje na Windowsa, które zadziałają na obu systemach? Swoją drogą z tego też powodu bierze się część niechęci do projektu Wine. Również postrzegany jest jako zagrożenie, gdyż jak osiągnie lepszą kompatybilność, to również chętniej będą tworzone aplikacje Windows, które zadziałają także i na Wine. Swoją drogą, kilka portów aplikacji na Linuksa wykorzystuje Wine, np. Picasa.
Wine - próba środowiska FLOSS
Ostatnią przedstawioną tutaj próbą zapewnienia kompatybilności z Windowsem będzie Wine. Jest to chyba największy i najstarszy ciągle rozwijany projekt tego typu. Projekt został zapoczątkowany w 1993 roku przez Boba Amstadt’a i Erica Youndale’a zainspirowany poprzez działania firmy Sun (Wabi i Public Windows Initiative). Projekt początkowo skupiał się na Win16, został jednak przekierowany na Win32 i Win64. Projektem opiekuje się od 1994 roku Alexandre Julliard. W przeciwieństwie do swoich odpowiedników, Wine nie implementuje wyłącznie WinAPI, ale stara się stworzyć wolną implementacje także innych bibliotek i API Windowsa (w tym DirectX). Dzięki takiemu podejściu Wine nie potrzebuje instalacji Windowsa do działania. Jednak wadą takiego podejścia jest utrudniony rozwój projektu. Projekt początkowo miał licencje MIT, w 2002 została jednak zmieniona na LGPL, by uniemożliwić zarabianie na Wine bez zwracania czegoś w zamian. Wine jest implementowany w przestrzeni użytkownika (w odróżnieniu od podobnych rozwiązań), co uniezależnia go od wykorzystywanego systemu. Sercem jest program wineserver, który po uruchomieniu udaje Windowsa i przechwytuje wywołania aplikacji tłumacząc je na odpowiednie wywołania POSIX, X11 i OpenGL. Wine obsługuje też ładowanie natywnych bibliotek Windowsa, co zwiększa funkcjonalność, rodzi jednak pewne problemy licencyjne. Przez swoją naturę Wine naturalnie nie obsługuje sterowników Windowsa. Translacja odbija się też na wydajności – wywołania API Windows muszą być najpierw przetłumaczone na odpowiednie wywołania X11/POSIX/OpenGL zanim zostaną wykonane, co rodzi większe lub mniejsze opóźnienia.
Projekt pomimo wielu trudności (niepełna dokumentacja API Windowsa czy bugi, które trzeba powielać dla zachowania kompatybilności) osiągnął dużo i zawiera całkiem niezłą implementacje WinAPI i DirectX 9, obecnie prace trwają nad DirectX 11 (obecna implementacja pozwala już uruchomić kilka tytułów DX11, jednak zazwyczaj z większymi lub mniejszymi błędami), planowane też jest wsparcie DX12 (tłumacząc go na Vulkan). Wine posiada też wsparcie firm, jedną z nich jest CodeWeavers, który zarabia na sprzedawaniu skonfigurowanych wersji Wine dla wybranych aplikacji i wsparcia do nich i odpłaca się Wine poprzez wkład w jego rozwój. Projekt współpracuje też z ReactOS, o którym również pisałem tutaj.
Zakończenie
Jak widać, Wine to nie jedyna próba implementacji API Windowsa niezależnej od Microsoftu. Mimo wszystko na pewno najbardziej udana, gdyż projekt żyje do dzisiaj, jest w ciągłym rozwoju i skupia się też nad alternatywną instalacją bibliotek systemu Microsoftu, by nie trzeba było korzystać z oficjalnych. Mimo wszystko Wine jako projekt FLOSS ma tą przewagę, że nie strasznie mu upadki. Nawet (co jest mało prawdopodobne biorąc pod uwagę dynamikę projektu) jeżeli Wine zostanie porzucone, to jego kod zostanie i nadal inni będą mogli z niego skorzystać. W sumie można teraz stwierdzić, że po co bawić się w takie projekty, skoro zwyczajnie można zainstalować Windowsa. Niby tak, ale należy wziąć pod uwagę choćby preferencje użytkowników – nie każdy Windowsa czy Microsoft kocha, a niechęć do nich nie oznacza wcale niechęci do aplikacji tego systemu. Do tego otwarta implementacja API Windowsa ma swoją zaletę w zachowaniu kompatybilności – jeżeli kiedyś Windows przestanie istnieć w obecnej formie, lub Microsoft ostatecznie pozbędzie się obsługi klasycznych aplikacji, to dzięki Wine ta cała masa aplikacji, których rozwój już dawno się skończył, nie zostanie skazana na zapomnienie. Owszem, Wine idealne nie jest, ale przyznać wypada, że to co osiągnął do tej pory i liczba działających aplikacji robi wrażenie.