Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00070 005886 13638233 na godz. na dobę w sumie
Programowanie w systemie Windows. Wydanie IV - książka
Programowanie w systemie Windows. Wydanie IV - książka
Autor: Liczba stron: 752
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-2780-6 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> inne - programowanie
Porównaj ceny (książka, ebook, audiobook).

Wybierając system Windows jako docelową platformę rozwijanych aplikacji, programiści na całym świecie sugerują się najczęściej jego dużą funkcjonalnością i wymogami biznesowymi. System ten jest bowiem zgodny z wieloma kluczowymi standardami. Obsługuje między innymi biblioteki standardowe języków C i C+ oraz uwzględnia wiele otwartych standardów współdziałania. Dlatego gniazda systemu Windows są standardowym interfejsem programowania rozwiązań sieciowych z dostępem do TCP/IP i innych protokołów sieciowych. W dodatku każda nowa wersja tego systemu jest coraz bardziej zintegrowana z dodatkowymi technologiami z obszaru multimediów, sieci bezprzewodowych, usług Web Service, platformy .NET i usługi plug-and-play. Niewątpliwym atutem Windows jest także zawsze uważany za stabilny, a jednak ciągle wzbogacany o ważne dodatki interfejs API.

Jeśli zatem szukasz kompletnego, rzetelnego i aktualnego podręcznika do nauki programowania za pomocą interfejsu Windows API, właśnie go znalazłeś! Książka ta w praktyczny sposób przedstawia wszystkie mechanizmy systemu Windows potrzebne programistom, pokazując, w jaki sposób działają funkcje tego systemu i jak wchodzą w interakcje z aplikacjami. Skoncentrowano się tu na podstawowych usługach systemu, w tym na systemie plików, zarządzaniu procesami i wątkami, komunikacji między procesami, programowaniu sieciowym i synchronizacji. Autor tej książki nie zamierza jednak obciążać Cię zbędną teorią i nieistotnymi szczegółami. Podaje Ci wiedzę opartą na prawdziwych przykładach, dzięki czemu szybko i sprawnie opanujesz poruszane tu zagadnienia. Wiadomości, które tu znajdziesz, pozwolą Ci zrozumieć interfejs Windows API w takim stopniu, byś zdobył solidne podstawy do rozwijania programów na platformę .NET Microsoftu.

W książce znajdziesz omówienie między innymi takich kwestii, jak:

Oto kompletny, aktualny przewodnik po programowaniu
przy użyciu interfejsu Windows API!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Programowanie w systemie Windows. Wydanie IV Autor: Johnson M. Hart T³umaczenie: Tomasz Walczak ISBN: 978-83-246-2780-6 Tytu³ orygina³u: Windows System Programming (4th Edition) Format: 168x237, stron: 752 • Wykorzystaj paralelizm i maksymalizuj wydajnoœæ w systemach wielordzeniowych • Zapewnij przenoœnoœæ miêdzy œrodowiskami 64- i 32-bitowymi • Popraw skalowalnoœæ za pomoc¹ w¹tków, pul w¹tków i mechanizmu IOCP Wybieraj¹c system Windows jako docelow¹ platformê rozwijanych aplikacji, programiœci na ca³ym œwiecie sugeruj¹ siê najczêœciej jego du¿¹ funkcjonalnoœci¹ i wymogami biznesowymi. System ten jest bowiem zgodny z wieloma kluczowymi standardami. Obs³uguje miêdzy innymi biblioteki standardowe jêzyków C i C+ oraz uwzglêdnia wiele otwartych standardów wspó³dzia³ania. Dlatego gniazda systemu Windows s¹ standardowym interfejsem programowania rozwi¹zañ sieciowych z dostêpem do TCP/IP i innych protoko³ów sieciowych. W dodatku ka¿da nowa wersja tego systemu jest coraz bardziej zintegrowana z dodatkowymi technologiami z obszaru multimediów, sieci bezprzewodowych, us³ug Web Service, platformy .NET i us³ugi plug-and-play. Niew¹tpliwym atutem Windows jest tak¿e zawsze uwa¿any za stabilny, a jednak ci¹gle wzbogacany o wa¿ne dodatki interfejs API. Jeœli zatem szukasz kompletnego, rzetelnego i aktualnego podrêcznika do nauki programowania za pomoc¹ interfejsu Windows API, w³aœnie go znalaz³eœ! Ksi¹¿ka ta w praktyczny sposób przedstawia wszystkie mechanizmy systemu Windows potrzebne programistom, pokazuj¹c, w jaki sposób dzia³aj¹ funkcje tego systemu i jak wchodz¹ w interakcje z aplikacjami. Skoncentrowano siê tu na podstawowych us³ugach systemu, w tym na systemie plików, zarz¹dzaniu procesami i w¹tkami, komunikacji miêdzy procesami, programowaniu sieciowym i synchronizacji. Autor tej ksi¹¿ki nie zamierza jednak obci¹¿aæ Ciê zbêdn¹ teori¹ i nieistotnymi szczegó³ami. Podaje Ci wiedzê opart¹ na prawdziwych przyk³adach, dziêki czemu szybko i sprawnie opanujesz poruszane tu zagadnienia. Wiadomoœci, które tu znajdziesz, pozwol¹ Ci zrozumieæ interfejs Windows API w takim stopniu, byœ zdoby³ solidne podstawy do rozwijania programów na platformê .NET Microsoftu. Oto kompletny, aktualny przewodnik po programowaniu przy u¿yciu interfejsu Windows API! SPIS TREŚCI Rysunki .................................................................................13 Tabele ...................................................................................15 Listingi ..................................................................................17 Przebiegi programów ...........................................................21 Wstęp ....................................................................................23 O autorze ..............................................................................33 Rozdział 1. Wprowadzenie do systemu Windows ...................................35 Podstawy systemów operacyjnych ......................................................................... 36 Ewolucja systemu Windows ...................................................................................... 37 Wersje systemu Windows .......................................................................................... 37 Pozycja systemu Windows na rynku ...................................................................... 40 System Windows, standardy i systemy o otwartym dostępie do kodu źródłowego ................................................................................................ 41 Podstawy systemu Windows .................................................................................... 43 Przenośność 32- i 64-bitowego kodu źródłowego ............................................ 46 Biblioteka standardowa języka C — kiedy korzystać z niej do przetwarzania plików? ....................................................................................... 47 Co jest potrzebne do korzystania z tej książki? ................................................... 48 Przykład — proste sekwencyjne kopiowanie pliku ........................................... 50 Podsumowanie .............................................................................................................. 58 Ćwiczenia ......................................................................................................................... 61 Rozdział 2. Korzystanie z systemu plików i znakowych operacji wejścia-wyjścia w systemie Windows ...................................63 Systemy plików w systemie Windows ................................................................... 64 Reguły tworzenia nazw plików ................................................................................. 65 Otwieranie, wczytywanie, zapisywanie i zamykanie plików .......................... 66 5 6 S P I S T R E ¥ C I Przerywnik — Unicode i znaki ogólne ................................................................... 74 Strategie związane z kodowaniem Unicode ........................................................ 77 Przykład — przetwarzanie błędów ......................................................................... 78 Urządzenia standardowe ............................................................................................ 81 Przykład — kopiowanie wielu plików do standardowego wyjścia .............. 82 Przykład — proste szyfrowanie pliku ..................................................................... 85 Zarządzanie plikami i katalogami ............................................................................ 88 Operacje wejścia-wyjścia konsoli ............................................................................ 94 Przykład — wyświetlanie danych i instrukcji ....................................................... 96 Przykład — wyświetlanie bieżącego katalogu .................................................... 99 Podsumowanie ............................................................................................................100 Ćwiczenia .......................................................................................................................101 Rozdział 3. Zaawansowane przetwarzanie plików i katalogów oraz rejestr ..........................................................................103 64-bitowy system plików .........................................................................................104 Wskaźniki do plików ...................................................................................................104 Pobieranie rozmiaru plików ....................................................................................109 Przykład — bezpośrednie aktualizowanie rekordów .....................................111 Atrybuty plików i przetwarzanie katalogów ......................................................115 Przykład — wyświetlanie atrybutów plików .....................................................121 Przykład — ustawianie znaczników czasu dla plików ....................................125 Strategie przetwarzania plików ..............................................................................126 Blokowanie dostępu do plików ..............................................................................128 Rejestr .............................................................................................................................134 Zarządzanie rejestrem ...............................................................................................137 Przykład — wyświetlanie kluczy i zawartości rejestru ....................................141 Podsumowanie ............................................................................................................145 Ćwiczenia .......................................................................................................................146 Rozdział 4. Obsługa wyjątków ..............................................................149 Wyjątki i procedury do ich obsługi ........................................................................150 Wyjątki zmiennoprzecinkowe ................................................................................157 Błędy i wyjątki ...............................................................................................................159 Przykład — traktowanie błędów jak wyjątków .................................................161 Procedury obsługi zakończenia .............................................................................163 Przykład — stosowanie procedur obsługi zakończenia do poprawy jakości programów .........................................................................167 Przykład — stosowanie funkcji filtrującej ...........................................................170 Procedury sterujące konsoli ....................................................................................175 Przykład — procedura sterująca konsoli .............................................................176 Wektorowa obsługa wyjątków ...............................................................................178 Podsumowanie ............................................................................................................180 Ćwiczenia .......................................................................................................................181 S P I S T R E ¥ C I 7 Rozdział 5. Zarządzanie pamięcią, pliki odwzorowane w pamięci i biblioteki DLL ....................................................................183 Architektura zarządzania pamięcią w systemie Windows ............................184 Sterty ...............................................................................................................................187 Zarządzanie pamięcią na stercie ............................................................................191 Przykład — sortowanie plików za pomocą binarnego drzewa wyszukiwań ....................................................198 Pliki odwzorowane w pamięci ................................................................................203 Przykład — sekwencyjne przetwarzanie pliku za pomocą plików odwzorowanych .................................................................212 Przykład — sortowanie pliku odwzorowanego w pamięci ..........................215 Przykład — stosowanie wskaźników z bazą ......................................................218 Biblioteki DLL ................................................................................................................224 Przykład — dołączanie w czasie wykonywania programu funkcji do konwersji plików ................................................................................................231 Punkt wejścia do biblioteki DLL .............................................................................232 Zarządzanie wersjami bibliotek DLL .....................................................................234 Podsumowanie ............................................................................................................236 Ćwiczenia .......................................................................................................................237 Rozdział 6. Zarządzanie procesem ........................................................241 Procesy i wątki w systemie Windows ...................................................................241 Tworzenie procesu .....................................................................................................244 Dane identyfikacyjne procesów .............................................................................251 Powielanie uchwytów ...............................................................................................252 Wychodzenie z procesu i kończenie jego działania ........................................254 Oczekiwanie na zakończenie działania procesu ...............................................256 Bloki i łańcuchy znaków środowiska ....................................................................258 Przykład — równoległe wyszukiwanie wzorca .................................................260 Procesy w środowisku wieloprocesorowym ......................................................264 Czas wykonywania procesu .....................................................................................265 Przykład — czas wykonywania procesu ..............................................................265 Generowanie zdarzeń sterujących konsoli .........................................................267 Przykład — proste zarządzanie zadaniem ..........................................................268 Przykład — korzystanie z obiektów zadań .........................................................279 Podsumowanie ............................................................................................................283 Ćwiczenia .......................................................................................................................284 Rozdział 7. Wątki i szeregowanie ..........................................................287 Wprowadzenie do wątków ......................................................................................287 Podstawowe informacje o wątkach ......................................................................290 Zarządzanie wątkami .................................................................................................291 Stosowanie biblioteki języka C w wątkach .........................................................296 Przykład — wielowątkowe wyszukiwanie wzorca ...........................................298 8 S P I S T R E ¥ C I Wpływ na wydajność .................................................................................................301 Wątki główne i robocze oraz inne modele działania wątków ......................303 Przykład — sortowanie przez scalanie z wykorzystaniem wielu procesorów ................................................................304 Wprowadzenie do paralelizmu w programach ................................................311 Pamięć TLS ....................................................................................................................312 Priorytety oraz szeregowanie procesów i wątków ..........................................314 Stany wątków ...............................................................................................................317 Pułapki i często popełniane błędy .........................................................................319 Oczekiwanie z pomiarem czasu .............................................................................321 Włókna ............................................................................................................................322 Podsumowanie ............................................................................................................325 Ćwiczenia .......................................................................................................................326 Rozdział 8. Synchronizowanie wątków .................................................329 Dlaczego trzeba synchronizować wątki? ............................................................330 Obiekty synchronizacji wątków .............................................................................339 Obiekty CRITICAL_SECTION .....................................................................................340 Obiekty CRITICAL_SECTION do zabezpieczania współużytkowanych zmiennych ..................................343 Przykład — prosty system z producentem i konsumentem ........................345 Muteksy ..........................................................................................................................351 Semafory ........................................................................................................................358 Zdarzenia .......................................................................................................................361 Przykład — system z producentem i konsumentem ......................................364 Więcej wskazówek na temat muteksów i obiektów CRITICAL_SECTION ............................................................................369 Inne funkcje Interlocked ...........................................................................................371 Wydajność przy zarządzaniu pamięcią ................................................................373 Podsumowanie ............................................................................................................374 Ćwiczenia .......................................................................................................................375 Rozdział 9. Blokowanie, wydajność i dodatki w systemach NT6 ..........377 Wpływ synchronizacji na wydajność ....................................................................378 Program do badania wydajności ...........................................................................383 Dopracowywanie wydajności systemów wieloprocesorowych za pomocą liczby powtórzeń pętli obiektów CS ...........................................384 Blokady SRW w systemach NT6 ..............................................................................387 Zmniejszanie rywalizacji za pomocą puli wątków ...........................................390 Porty kończenia operacji wejścia-wyjścia ...........................................................393 Pule wątków z systemów NT6 ................................................................................394 Podsumowanie — wydajność blokowania ........................................................403 Paralelizm po raz wtóry .............................................................................................404 Koligacja procesora ....................................................................................................409 S P I S T R E ¥ C I 9 Wskazówki i pułapki z obszaru wydajności ........................................................411 Podsumowanie ............................................................................................................413 Ćwiczenia .......................................................................................................................414 Rozdział 10. Zaawansowana synchronizacja wątków .............................417 Model zmiennej warunkowej i właściwości związane z bezpieczeństwem ...................................................418 Stosowanie funkcji SignalObjectAndWait ..........................................................426 Przykład — obiekt bariery z progiem ...................................................................428 Obiekt kolejki ................................................................................................................432 Przykład — wykorzystanie kolejek w wieloetapowym potoku ...................436 Zmienne warunkowe z systemów Windows NT6 ............................................446 Asynchroniczne wywołania procedur ..................................................................451 Kolejkowanie asynchronicznych wywołań procedur .....................................452 Oczekiwanie z obsługą alertów ..............................................................................454 Bezpieczne anulowanie wątków ...........................................................................456 Wątki Pthreads i przenośność aplikacji ................................................................457 Stosy wątków i liczba wątków ................................................................................457 Wskazówki z obszaru projektowania, diagnozowania i testowania ..........458 Poza interfejs Windows API .....................................................................................461 Podsumowanie ............................................................................................................462 Ćwiczenia .......................................................................................................................463 Rozdział 11. Komunikacja między procesami .........................................467 Potoki anonimowe .....................................................................................................468 Przykład — przekierowywanie wejścia-wyjścia za pomocą potoku anonimowego ....................................................................469 Potoki nazwane ...........................................................................................................472 Funkcje do obsługi transakcji z wykorzystaniem potoku nazwanego .....479 Przykład — system klient-serwer do przetwarzania wiersza poleceń ......483 Komentarze na temat programu klient-serwer do przetwarzania wiersza poleceń ....................................................................489 Szczeliny pocztowe ....................................................................................................491 Tworzenie i nazywanie potoków oraz szczelin pocztowych i nawiązywanie połączeń z nimi .........................................................................496 Przykład — serwer możliwy do znalezienia przez klienty .............................496 Podsumowanie ............................................................................................................499 Ćwiczenia .......................................................................................................................500 Rozdział 12. Programowanie sieciowe z wykorzystaniem gniazd systemu Windows .....................503 Gniazda systemu Windows ......................................................................................504 Funkcje do obsługi gniazd serwera ......................................................................507 10 S P I S T R E ¥ C I Funkcje do obsługi gniazd klienta ........................................................................513 Porównanie potoków nazwanych i gniazd ........................................................515 Przykład — funkcja do odbierania komunikatów w gnieździe ...................516 Przykład — klient oparty na gniazdach ...............................................................517 Przykład — oparty na gniazdach serwer z nowymi mechanizmami .........519 Serwery wewnątrzprocesowe .................................................................................529 Komunikaty oparte na wierszach, punkty wejścia bibliotek DLL i pamięć TLS ...............................................................................................................531 Przykład — bezpieczna ze względu na wątki biblioteka DLL do obsługi komunikatów w gniazdach ............................................................533 Przykład — inna strategia tworzenia bibliotek DLL bezpiecznych ze względu na wątki ...............................................................................................538 Datagramy .....................................................................................................................541 Gniazda Berkeley a gniazda systemu Windows ................................................543 Operacje nakładanego wejścia-wyjścia oparte na gniazdach systemu Windows ..........................................................544 Dodatkowe funkcje gniazd systemu Windows .................................................544 Podsumowanie ............................................................................................................545 Ćwiczenia .......................................................................................................................546 Rozdział 13. Usługi systemu Windows ....................................................549 Tworzenie usług systemu Windows — przegląd .............................................550 Funkcja main() ..............................................................................................................551 Funkcje ServiceMain() ................................................................................................552 Procedura sterująca usługi ......................................................................................557 Rejestrowanie zdarzeń ..............................................................................................558 Przykład — nakładka na usługi ..............................................................................558 Zarządzanie usługami systemu Windows ..........................................................565 Podsumowanie — działanie usług i zarządzanie nimi ...................................569 Przykład — powłoka do sterowania usługą .......................................................569 Współużytkowanie obiektów jądra przy użyciu usługi ..................................574 Uwagi na temat diagnozowania usług ................................................................575 Podsumowanie ............................................................................................................576 Ćwiczenia .......................................................................................................................577 Rozdział 14. Asynchroniczne operacje wejścia-wyjścia i IOCP ................579 Przegląd asynchronicznych operacji wejścia-wyjścia w systemie Windows ..............................................................................................580 Operacje nakładanego wejścia-wyjścia ...............................................................581 Przykład — synchronizacja z wykorzystaniem uchwytu pliku ....................586 Przykład — przekształcanie pliku za pomocą operacji nakładanego wejścia-wyjścia i wielu buforów ..............................................587 Wzbogacone operacje wejścia-wyjścia z procedurami zakończenia ........591 Przykład — przekształcanie plików za pomocą wzbogaconych operacji wejścia-wyjścia ..................................597 S P I S T R E ¥ C I 11 Asynchroniczne operacje wejścia-wyjścia z wykorzystaniem wątków .....600 Zegary oczekujące ......................................................................................................602 Przykład — korzystanie z zegarów oczekujących ............................................605 Mechanizm IOCP .........................................................................................................607 Przykład — serwer oparty na mechanizmie IOCP ............................................612 Podsumowanie ............................................................................................................619 Ćwiczenia .......................................................................................................................620 Rozdział 15. Zabezpieczanie obiektów systemu Windows .....................623 Atrybuty zabezpieczeń .............................................................................................623 Przegląd zabezpieczeń — deskryptor zabezpieczeń ......................................624 Flagi kontrolne deskryptora zabezpieczeń ........................................................628 Identyfikatory zabezpieczeń ...................................................................................628 Zarządzanie listami ACL ............................................................................................630 Przykład — uprawnienia w stylu UNIX-a do plików NTFS .............................632 Przykład — inicjowanie atrybutów zabezpieczeń ...........................................636 Wczytywanie i modyfikowanie deskryptorów zabezpieczeń ......................641 Przykład — odczytywanie uprawnień do pliku ................................................643 Przykład — modyfikowanie uprawnień do plików .........................................645 Zabezpieczanie obiektów jądra i komunikacji ..................................................645 Przykład — zabezpieczanie procesu i jego wątków .......................................648 Przegląd dodatkowych mechanizmów zabezpieczeń ...................................648 Podsumowanie ............................................................................................................650 Ćwiczenia .......................................................................................................................651 Dodatek A Używanie przykładowych programów ...............................655 Układ plików w pakiecie Przykłady .......................................................................656 Dodatek B Przenośność kodu źródłowego — Windows, UNIX i Linux ....................................................659 Strategie tworzenia przenośnego kodu źródłowego .....................................660 Usługi systemu Windows dla systemu UNIX .....................................................660 Przenośność kodu źródłowego z funkcjami systemu Windows .................661 Rozdziały 2. i 3. — zarządzanie plikami i katalogami ......................................667 Rozdział 4. — obsługa wyjątków ...........................................................................672 Rozdział 5. — zarządzanie pamięcią, pliki odwzorowane w pamięci i biblioteki DLL ..........................................................................................................674 Rozdział 6. — zarządzanie procesem ...................................................................675 Rozdział 7. — wątki i szeregowanie ......................................................................677 Rozdziały od 8. do 10. — synchronizowanie wątków .....................................679 Rozdział 11. — komunikacja między procesami ..............................................681 Rozdział 14. — asynchroniczne operacje wejścia-wyjścia ............................684 Rozdział 15. — zabezpieczanie obiektów systemu Windows ......................685 12 S P I S T R E ¥ C I Dodatek C Wyniki pomiarów wydajności .............................................687 Konfiguracje testowe .................................................................................................687 Pomiary wydajności ...................................................................................................690 Przeprowadzanie testów ..........................................................................................703 Bibliografia .........................................................................705 Skorowidz ...........................................................................709 R O Z D Z I A ’ 1 3 USŁUGI SYSTEMU WINDOWS Serwery z rozdziaïów 11. i 12. to aplikacje konsolowe. W zasadzie serwery te mogÈ dziaïaÊ w nieskoñczonoĂÊ i obsïugiwaÊ liczne klienty, a te nawiÈ- zujÈ poïÈczenie, wysyïajÈ ĝÈdania, odbierajÈ odpowiedzi i zrywajÈ poïÈ- czenie. Oznacza to, ĝe serwery te mogÈ ciÈgle oferowaÊ usïugi. Jednak aby serwery byïy w peïni efektywne, potrzebna jest moĝliwoĂÊ zarzÈdza- nia usïugami. Usïugi systemu Windows (ang. Windows Services)1, nazywane niegdyĂ usïugami NT, udostÚpniajÈ mechanizmy do zarzÈdzania potrzebne do prze- ksztaïcenia serwerów na usïugi, które moĝna uruchamiaÊ na ĝÈdanie lub w czasie ïadowania systemu przed zalogowaniem siÚ uĝytkowników. Moĝna teĝ wstrzymywaÊ i wznawiaÊ takie usïugi, jak równieĝ koñczyÊ i ĂledziÊ ich dziaïanie. Informacje o usïugach zawiera rejestr. Ostatecznie wszystkie serwery, na przykïad te zbudowane w rozdzia- ïach 11. i 12., naleĝy przeksztaïciÊ na usïugi, zwïaszcza jeĂli majÈ byÊ powszechnie stosowane przez klientów lub w organizacji. System Windows udostÚpnia wiele usïug. NaleĝÈ do nich Klient DNS, róĝne usïugi SQL Server i Usïugi terminalowe. Peïny zestaw usïug moĝna wyĂwietliÊ za pomocÈ przystawki ZarzÈdzanie komputerem dostÚpnej w Panelu sterowania. Program JobShell (listing 6.3) z rozdziaïu 6. umoĝliwia uproszczone zarzÈdzanie serwerem. Pozwala uruchomiÊ serwer pod kontrolÈ zadania i wysïaÊ sygnaï zakoñczenia pracy. Usïugi systemu Windows sÈ jednak duĝo bardziej kompletne i niezawodne. Podstawowym przykïadem w tym rozdziale jest zmodyfikowana wersja programu JobShell umoĝliwiajÈca kon- trolowanie takich usïug. 1 Ta terminologia bywa mylÈca, poniewaĝ system Windows udostÚpnia wiele usïug, które nie sÈ opisanymi tu usïugami systemu Windows. Znaczenie powinno wynikaÊ z kontekstu (podobnie zrozumienie pojÚcia „system Windows” przy omawianiu interfejsu API nie spra- wiaïo problemu). 549 550 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S W tym rozdziale pokazano teĝ, jak przeksztaïciÊ istniejÈcÈ aplikacjÚ kon- solowÈ w usïugÚ systemu Windows, a takĝe jak instalowaÊ, obserwowaÊ i kontrolowaÊ usïugi. Znajduje siÚ tu takĝe omówienie rejestrowania zdarzeñ (mechanizm ten umoĝliwia usïudze zapis wykonanych operacji w pliku). Tworzenie usług systemu Windows — przegląd Usïugi systemu Windows dziaïajÈ pod kontrolÈ menedĝera SCM (ang. Ser- vice Control Manager). NarzÚdzie to moĝna wykorzystaÊ do sterowania usïugami na trzy sposoby: 1. Przez uĝycie przystawki administracyjnej Usïugi (Panel sterowania/ System i konserwacja/NarzÚdzia administracyjne). 2. Za pomocÈ narzÚdzia sc.exe obsïugiwanego z poziomu wiersza 3. Przez programistyczne kontrolowanie menedĝera SCM, co ilustruje poleceñ. listing 13.3. Przeksztaïcenie aplikacji konsolowej (takiej jak serverNP lub serverSK) na usïugÚ systemu Windows wymaga wykonania trzech podstawowych kroków w celu umieszczenia programu pod kontrolÈ menedĝera SCM. 1. Naleĝy utworzyÊ nowy punkt wejĂcia w postaci funkcji main() i zarejestrowaÊ w nim usïugÚ w menedĝerze SCM przez podanie logicznych punktów wejĂcia i nazwy usïugi. 2. Trzeba przeksztaïciÊ dawny punkt wejĂcia w postaci funkcji main() na funkcjÚ ServiceMain(), która rejestruje procedurÚ sterujÈcÈ usïugi i informuje menedĝer SCM o jej stanie. Pozostaïy kod pro- gramu moĝe pozostaÊ taki sam, choÊ moĝna dodaÊ polecenia do reje- strowania zdarzeñ. Zamiast nazwy ServiceMain() naleĝy podaÊ nazwÚ logicznej usïugi. W procesie moĝe dziaïaÊ jedna lub kilka takich usïug. 3. Naleĝy napisaÊ procedurÚ sterujÈcÈ usïugi reagujÈcÈ na polecenia od menedĝera SCM. W tych trzech punktach wspomniano kilkakrotnie o tworzeniu, uru- chamianiu i kontrolowaniu usïug. W nastÚpnych podrozdziaïach opisano szczegóïy tych operacji, a rysunek 13.1 w dalszej czÚĂci rozdziaïu ilustruje wspóïdziaïanie róĝnych komponentów. F U N K C J A M A I N() 551 Funkcja main() Nowa funkcja main() wywoïywana przez menedĝer SCM ma za zadanie rejestrowaÊ usïugÚ w menedĝerze i uruchamiaÊ program rozdzielajÈcy do sterowania usïugÈ. Wymaga to wywoïania funkcji StartServiceCtrl ´Dispatcher z nazwami i punktami wejĂcia usïug logicznych. BOOL StartServiceCtrlDispatcher ( SERVICE_TABLE_ENTRY *lpServiceStartTable) Jedyny parametr, lpServiceStartTable, to adres tablicy z elemen- tami SERVICE_TABLE_ENTRY. Kaĝdy taki element to nazwa i punkt wej- Ăcia usïugi logicznej. Koñcem tablicy jest para elementów NULL. Funkcja zwraca wartoĂÊ TRUE, jeĂli rejestracja zakoñczyïa siÚ powo- dzeniem. Gïówny wÈtek procesu usïugi wywoïujÈcego funkcjÚ StartService ´CtrlDispatcher nawiÈzuje poïÈczenie z menedĝerem SCM. Menedĝer ten rejestruje usïugÚ (lub usïugi), przy czym wÈtek wywoïujÈcy sïuĝy jako program rozdzielajÈcy do sterowania usïugÈ. Menedĝer SCM nie zwraca sterowania do wÈtku wywoïujÈcego do czasu zakoñczenia pracy przez wszystkie usïugi. Warto zauwaĝyÊ, ĝe usïugi logiczne nie rozpoczynajÈ dziaïania od razu. Uruchomienie usïugi wymaga wywoïania opisanej dalej funkcji StartService. Listing 13.1 przedstawia typowy program gïówny usïugi z jednÈ usïugÈ logicznÈ. Listing 13.1. Funkcja main — główny punkt wejścia usługi #include Everything.h void WINAPI ServiceMain (DWORD argc, LPTSTR argv[]); static LPTSTR serviceName = _T( SocketCommandLineService ); /* Gïówna procedura uruchamiajÈca program rozdzielajÈcy do sterowania usïugÈ. */ VOID _tmain (int argc, LPTSTR argv[]) { SERVICE_TABLE_ENTRY dispatchTable[] = { { serviceName, ServiceMain }, { NULL, NULL } }; 552 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S if (!StartServiceCtrlDispatcher (dispatchTable)) ReportError (_T( Nie mozna uruchomic programu ´rozdzielajacego. ), 1, TRUE); /* Funkcja ServiceMain() zadziaïa po uruchomieniu jej przez menedĝer SCM. */ /* Sterowanie jest zwracane do tego miejsca dopiero po zamkniÚciu wszystkich usïug. */ return; } Funkcje ServiceMain() Tablica przydziaïu okreĂla funkcje, jak pokazano to na listingu 13.1, a kaĝda z nich reprezentuje usïugÚ logicznÈ. Funkcje te to wzbogacone wersje podstawowego programu przeksztaïconego na usïugÚ, a menedĝer SCM wywoïuje kaĝdÈ usïugÚ logicznÈ w osobnym wÈtku. Usïuga logiczna moĝe z kolei uruchomiÊ dodatkowe wÈtki, takie jak wÈtki robocze serwera gene- rowane przez programy serverSK i serverNP. CzÚsto usïuga systemu Win- dows obejmuje tylko jednÈ usïugÚ logicznÈ. Na listingu 13.2 usïuga logiczna to zmodyfikowana wersja gïównego serwera (listing 12.2). W jednej usïudze systemu Windows moĝna uruchomiÊ usïugi logiczne oparte na gniazdach i potokach nazwanych. Wtedy naleĝy udostÚpniÊ dwie funkcje gïówne usïugi. ChoÊ funkcja ServiceMain() jest oparta na funkcji main() oraz ma parametry z liczbÈ i ïañcuchem argumentów, warto zwróciÊ uwagÚ na jednÈ maïÈ róĝnicÚ. FunkcjÚ tÚ naleĝy zadeklarowaÊ jako void WINAPI. Nie powinna ona zwracaÊ wartoĂci typu int, jak robi to zwykïa funkcja main(). Rejestrowanie procedury sterującej usługi Procedura sterujÈca usïugi wywoïywana przez menedĝer SCM musi mieÊ moĝliwoĂÊ kontrolowania powiÈzanej z niÈ usïugi logicznej. Procedura sterujÈca konsoli z programu serverSK ustawia globalnÈ flagÚ zamkniÚcia i ilustruje (choÊ na uproszczonym przykïadzie), jak powinna wyglÈdaÊ taka procedura. Jednak kaĝda usïuga logiczna musi przede wszystkim natych- miast zarejestrowaÊ procedurÚ za pomocÈ funkcji RegisterServiceCtrl ´HandlerEx. FunkcjÚ tÚ naleĝy wywoïaÊ na poczÈtku funkcji Service ´Main() i nie uruchamiaÊ jej w dalszej czÚĂci programu. Menedĝer SCM po otrzymaniu ĝÈdania sterujÈcego od usïugi wywoïuje omawianÈ procedurÚ. F U N K C J E S E R V I C EM A I N() 553 SERVICE_STATUS_HANDLE RegisterServiceCtrlHandlerEx ( LPCTSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext) Parametry Parametr lpServiceName to podana przez uĝytkownika nazwa usïugi umieszczona we wpisie dotyczÈcym danej usïugi logicznej w tablicy usïug. Nazwa ta powinna odpowiadaÊ nazwie funkcji ServiceMain zarejestro- wanej za pomocÈ funkcji StartServiceCtrlDispatcher. Parametr lpHandlerProc to adres rozbudowanej procedury obsïugi opisanej w dalszym podrozdziale. Parametr lpContext to zdefiniowane przez uĝytkownika dane prze- kazane do procedury sterujÈcej. UmoĝliwiajÈ one jednej procedurze ste- rujÈcej rozróĝnianie wielu korzystajÈcych z niej usïug. JeĂli wystÈpiï bïÈd, zwracana wartoĂÊ (obiekt typu SERVICE_STATUS_ ´HANDLE) to 0. Do zbadania bïÚdów naleĝy zastosowaÊ standardowe metody. Ustawianie stanu usługi Po zarejestrowaniu procedury obsïugi nastÚpne zadanie polega na usta- wieniu stanu usïugi na wartoĂÊ SERVICE_START_PENDING. Umoĝliwia to funkcja SetServiceStatus. Posïuĝy ona jeszcze w kilku innych miejscach do ustawiania róĝnych wartoĂci w celu poinformowania menedĝera SCM o obecnym stanie usïugi. W jednym z dalszych podrozdziaïów i w tabeli 13.3 opisano inne obok SERVICE_START_PENDING prawidïowe wartoĂci stanu. Procedura sterujÈca usïugi musi ustawiÊ stan przy kaĝdym wywoïa- niu, nawet jeĂli stan ten siÚ nie zmieniï. Ponadto kaĝdy wÈtek usïugi moĝe w dowolnym momencie wywoïaÊ funkcjÚ SetServiceStatus, aby przekazaÊ informacje o postÚpie w pracy programu, bïÚdach i inne. Usïugi czÚsto korzystajÈ z odrÚbnego wÈtku do okresowego aktualizowania stanu. OdstÚp miÚdzy aktualizacjami jest okre- Ălony w skïadowej w parametrze ze strukturÈ danych. Menedĝer SCM moĝe uznaÊ, ĝe wystÈpiï bïÈd, jeĂli aktualizacja stanu nie nastÈpi w poda- nym czasie. 554 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S BOOL SetServiceStatus ( SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus) Parametry Parametr hServiceStatus to wartoĂÊ typu SERVICE_STATUS_HANDLE zwrócona przez funkcjÚ RegisterServiceCtrlHandlerEx (dlatego naleĝy jÈ wywoïaÊ przed funkcjÈ SetServiceStatus). Parametr lpServiceStatus wskazuje strukturÚ SERVICE_STATUS. Opisuje ona wïaĂciwoĂci, stan i moĝliwoĂci usïugi. Struktura SERVICE_STATUS Oto definicja struktury SERVICE_STATUS: typedef struct _SERVICE_STATUS { DWORD dwServiceType; DWORD dwCurrentState; DWORD dwControlsAccepted; DWORD dwWin32ExitCode; DWORD dwServiceSpecificExitCode; DWORD dwCheckPoint; DWORD dwWaitHint; } SERVICE_STATUS, *LPSERVICE_STATUS; Parametry Parametr dwWin32ExitCode to normalny kod wyjĂcia wÈtku usïugi logi- cznej. Usïuga musi ustawiÊ ten kod na wartoĂÊ NO_ERROR w czasie dzia- ïania i przy standardowym koñczeniu pracy. Mimo nazwy parametru moĝna go uĝywaÊ takĝe w aplikacjach 64-bitowych. Czïon „32” pojawia siÚ teĝ w innych nazwach. Parametr dwServiceSpecificExitCode moĝna wykorzystaÊ do zasy- gnalizowania bïÚdu w czasie uruchamiania lub zatrzymywania usïugi, jednak wartoĂÊ ta zostanie zignorowana, jeĂli parametr dwWin32ExitCode ma wartoĂÊ róĝnÈ od ERROR_SERVICE_SPECIFIC_ERROR. Usïuga powinna okresowo zwiÚkszaÊ wartoĂÊ parametru dwCheckPoint, aby informowaÊ o przechodzeniu przez wszystkie etapy pracy, w tym ini- F U N K C J E S E R V I C EM A I N() 555 cjowanie i zamykanie usïugi. Ta wartoĂÊ jest niewaĝna i powinna wynosiÊ 0, jeĂli usïuga nie ma do wykonania operacji uruchomienia, zatrzymania, wstrzymania lub kontynuowania. Parametr dwWaitHint to czas w milisekundach miÚdzy wywoïaniami funkcji SetServiceStatus w celu zwiÚkszenia wartoĂci parametru dwCheckPoint lub zmiany wartoĂci parametru dwCurrentState. Jak wczeĂniej wspomniano, jeĂli ten czas upïynie bez wywoïania funkcji Set ´ServiceStatus, menedĝer SCM moĝe uznaÊ, ĝe wystÈpiï bïÈd. Pozostaïe skïadowe struktury SERVICE_STATUS opisano w osobnych punktach. Typ usługi (dwServiceType) Parametr dwServiceType musi mieÊ jednÈ z wartoĂci opisanych w ta- beli 13.1. Tabela 13.1. Typy usług Wartość SERVICE_WIN32_OWN_PROCESS Znaczenie Sygnalizuje, ĝe usïuga systemu Windows dziaïa we wïasnym procesie ze swoimi zasobami. WartoĂÊ tÚ wykorzystano na listingu 13.2. SERVICE_WIN32_SHARE_PROCESS OkreĂla usïugÚ systemu Windows wspóïuĝytkujÈcÈ proces z innymi usïugami. Powoduje to poïÈczenie kilku usïug w jednym procesie, co pozwala zmniejszyÊ potrzebnÈ iloĂÊ zasobów. OkreĂla sterownik urzÈdzenia systemu Windows i jest zarezerwowana do uĝytku przez system. OkreĂla sterownik systemu plików systemu Windows i takĝe jest zarezerwowana. SERVICE_FILE_SYSTEM_DRIVER SERVICE_KERNEL_DRIVER SERVICE_INTERACTIVE_PROCESS TÚ flagÚ moĝna poïÈczyÊ tylko z dwoma wartoĂciami SERVICE_WIN32_X. Usïugi interaktywne powodujÈ zagroĝenie w obszarze bezpieczeñstwa i naleĝy ich unikaÊ. W tej ksiÈĝce typ usïugi to prawie zawsze SERVICE_WIN32_OWN_ ´PROCESS, a ustawienie SERVICE_WIN32_SHARE_PROCESS to jedyna inna wartoĂÊ odpowiednia dla usïug w trybie uĝytkownika. Przedstawie- nie pozostaïych wartoĂci pozwala jednak pokazaÊ, ĝe usïugi odgrywajÈ wiele róĝnych ról. 556 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S Stan usługi (dwCurrentState) Parametr dwCurrentState okreĂla obecny stan usïugi. W tabeli 13.2 przedstawiono róĝne moĝliwe wartoĂci. Tabela 13.2. Wartości określające stan usługi Wartość SERVICE_STOPPED SERVICE_START_PENDING SERVICE_STOP_PENDING SERVICE_PAUSE_PENDING SERVICE_PAUSED Znaczenie Usïuga nie jest uruchomiona. Usïuga rozpoczyna dziaïanie, ale nie jest jeszcze gotowa do odpowiadania na ĝÈdania (na przykïad dlatego, ĝe wÈtek roboczy nie zostaï jeszcze uruchomiony). Usïuga zatrzymuje dziaïanie, ale nie zakoñczyïa jeszcze zamykania. Na przykïad globalna flaga zamkniÚcia zostaïa ustawiona, ale wÈtki robocze jeszcze nie odpowiedziaïy. Usïuga dziaïa. ale jeszcze nie dziaïa. Trwa wstrzymywanie usïugi, ale nie przeszïa ona jeszcze bezpiecznie w stan wstrzymania. Usïuga jest wstrzymana. SERVICE_RUNNING SERVICE_CONTINUE_PENDING Usïuga jest w trakcie wznawiania pracy po wstrzymaniu, Akceptowane kody sterowania (dwControlsAccepted) Parametr dwControlsAccepted okreĂla kody sterowania, które usïuga ma akceptowaÊ i przetwarzaÊ za pomocÈ procedury sterujÈcej usïugi (zobacz nastÚpny podrozdziaï). W tabeli 13.3 wymieniono trzy wartoĂci uĝyte w jednym z dalszych przykïadów. Odpowiednie wartoĂci naleĝy poïÈczyÊ bitowym operatorem „or” (|). Trzy dodatkowe wartoĂci zawiera opis struk- tury SERVICE_STATUS w dokumentacji MSDN. Kod specyficzny dla usługi Po zarejestrowaniu procedury obsïugi i ustawieniu stanu na wartoĂÊ SERVICE_START_PENDING usïuga moĝe przeprowadziÊ swojÈ inicjacjÚ oraz ponownie okreĂliÊ stan. W przeksztaïconej wersji programu serverSK po zainicjowaniu gniazd i przygotowaniu serwera do akceptowania poïÈczeñ od klientów status naleĝy ustawiÊ na wartoĂÊ SERVICE_RUNNING. P R O C E D U R A S T E R U J k C A U S ’ U G I 557 Tabela 13.3. Kody sterowania akceptowane przez usługę (niepełna lista) Wartość SERVICE_ACCEPT_STOP Znaczenie Dodaje obsïugÚ ĝÈdania SERVICE_CONTROL_STOP. SERVICE_ACCEPT_PAUSE_CONTINUE Dodaje obsïugÚ ĝÈdañ SERVICE_ACCEPT_SHUTDOWN (funkcja ControlService nie moĝe wysïaÊ tego kodu sterowania) SERVICE_ACCEPT_PARAMCHANGE SERVICE_CONTROL_PAUSE i SERVICE_CONTROL_CONTINUE. Powiadamia usïugÚ o zamykaniu systemu. Umoĝliwia to systemowi przesïanie wartoĂci SERVICE_CONTROL_SHUTDOWN do usïugi. Ten kod jest przeznaczony do wyïÈcznego uĝytku przez system Windows. Umoĝliwia zmianÚ parametrów rozruchowych bez ponownego uruchamiania. Powiadomienie to SERVICE_CONTROL_PARAMCHANGE. Procedura sterująca usługi Procedura sterujÈca usïugi, czyli funkcja zwrotna okreĂlona w funkcji RegisterServiceCtrlHandlerEx, ma nastÚpujÈcÈ postaÊ: DWORD WINAPI HandlerEx ( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) Parametr dwControl okreĂla wysïany przez menedĝer SCM sygnaï ste- rujÈcy, który naleĝy przetworzyÊ. Parametr ten przyjmuje 14 wartoĂci, w tym te wymienione w tabeli 13.3. Oto piÚÊ wartoĂci istotnych w omawianym przykïadzie: SERVICE_CONTROL_STOP SERVICE_CONTROL_PAUSE SERVICE_CONTROL_CONTINUE SERVICE_CONTROL_INTERROGATE SERVICE_CONTROL_SHUTDOWN 558 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S Moĝna teĝ stosowaÊ zdefiniowane przez uĝytkownika wartoĂci z prze- dziaïu od 128 do 255, jednak nie wykorzystano ich w tym miejscu. Parametr dwEventType ma zwykle wartoĂÊ 0, jednak do zarzÈdzania urzÈdzeniami sïuĝÈ wartoĂci niezerowe (omawianie tego zagadnienia wy- kracza poza zakres ksiÈĝki). Parametr lpEventDate udostÚpnia dodat- kowe dane wymagane dla niektórych zdarzeñ. Ostatni parametr, lpContext, zawiera zdefiniowane przez uĝytkow- nika dane przekazane do funkcji RegisterServiceCtrlHandlerEx przy rejestrowaniu okreĂlonej procedury obsïugi. Procedura obsïugi jest wywoïywana przez menedĝer SCM w tym samym wÈtku, co program gïówny, i jest zwykle napisana jako instrukcja switch. IlustrujÈ to przykïady. Rejestrowanie zdarzeń Usïugi dziaïajÈ „bezwejĂciowo” bez interakcji z uĝytkownikiem, dlatego zwykle nie powinny bezpoĂrednio wyĂwietlaÊ komunikatów o stanie. W sys- temach starszych niĝ Vista i NT6 niektóre usïugi tworzyïy konsolÚ, pole komunikatów lub okno do interakcji z uĝytkownikiem. Obecnie techniki te nie sÈ juĝ dostÚpne. RozwiÈzanie tego problemu polega na rejestrowaniu zdarzeñ w pliku dziennika lub wykorzystaniu mechanizmu rejestrowania zdarzeñ z sys- temu Windows. Takie zdarzenia sÈ przechowywane w systemie Windows i moĝna je wyĂwietliÊ za pomocÈ przeglÈdarki zdarzeñ dostÚpnej w NarzÚ- dziach administracyjnych w Panelu sterowania. Dalszy przykïadowy program SimpleService (listing 13.2) rejestruje waĝne zdarzenia i bïÚdy usïugi w pliku dziennika. W Êwiczeniu poproszono o zmo- dyfikowanie tego programu przez zastosowanie zdarzeñ systemu Windows. Przykład — nakładka na usługi Program z listingu 13.2 przeksztaïca dowolnÈ funkcjÚ _tmain na usïugÚ. Aby byïo to moĝliwe, trzeba wykonaÊ opisane dalej operacje. IstniejÈcy kod serwera (czyli dawna funkcja _tmain) jest wywoïywany jako wÈtek lub proces z poziomu funkcji ServiceSpecific. Dlatego przedstawiony tu kod to nakïadka na istniejÈcy serwer. P R Z Y K ’ A D — N A K ’ A D K A N A U S ’ U G I 559 Listing 13.2. Program SimpleService — nakładka na serwery /* Rozdziaï 13. SimpleService.c. Najprostszy przykïad usïugi systemu Windows. Jej jedyne moĝliwoĂci to aktualizowanie punktów kontrolnych i akceptowanie podstawowych poleceñ sterujÈcych. Program moĝna teĝ uruchomiÊ jako niezaleĝnÈ aplikacjÚ. */ #include Everything.h #include time.h #define UPDATE_TIME 1000 /* Sekunda odstÚpu miÚdzy aktualizacjami. */ VOID LogEvent (LPCTSTR, WORD), LogClose(); BOOL LogInit(LPTSTR); void WINAPI ServiceMain (DWORD argc, LPTSTR argv[]); VOID WINAPI ServerCtrlHandler(DWORD); void UpdateStatus (int, int); int ServiceSpecific (int, LPTSTR *); static BOOL shutDown = FALSE, pauseFlag = FALSE; static SERVICE_STATUS hServStatus; static SERVICE_STATUS_HANDLE hSStat; /* Uchwyt do ustawiania stanu. */ static LPTSTR serviceName = _T( SimpleService ); static LPTSTR logFileName = _T( .\\LogFiles\\SimpleServiceLog.txt ); static BOOL consoleApp = FALSE, isService; /* Gïówna procedura uruchamiajÈca program rozdzielajÈcy do sterowania usïugÈ. */ /* Program moĝna teĝ uruchomiÊ jako niezaleĝnÈ aplikacjÚ konsolowÈ. */ /* Stosowanie: simpleService [-c] */ /* Opcja -c powoduje uruchomienie aplikacji konsolowej zamiast usïugi. */ VOID _tmain (int argc, LPTSTR argv[]) { SERVICE_TABLE_ENTRY DispatchTable[] = { { serviceName, ServiceMain}, { NULL, NULL } }; Options (argc, argv, _T( c ), consoleApp, NULL); isService = !consoleApp; /* Inicjowanie pliku dziennika. */ if (!LogInit (logFileName)) return; if (isService) { LogEvent(_T( Uruchamianie programu rozdzielajacego. ), ´EVENTLOG_SUCCESS); StartServiceCtrlDispatcher (DispatchTable); 560 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S } else { LogEvent(_T( Uruchamianie aplikacji. ), EVENTLOG_SUCCESS); ServiceSpecific (argc, argv); } LogClose(); return; } /* Punkt wejĂcia w postaci funkcji ServiceMain wywoïywanej przez program gïówny. */ void WINAPI ServiceMain (DWORD argc, LPTSTR argv[]) { LogEvent (_T( Wchodzenie do funkcji ServiceMain. ), ´EVENTLOG_SUCCESS); hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; hServStatus.dwCurrentState = SERVICE_START_PENDING; hServStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; hServStatus.dwWin32ExitCode = NO_ERROR; hServStatus.dwServiceSpecificExitCode = 0; hServStatus.dwCheckPoint = 0; hServStatus.dwWaitHint = 2 * UPDATE_TIME; hSStat = RegisterServiceCtrlHandler( serviceName, ServerCtrlHandler); if (hSStat == 0) { LogEvent (_T( Nie mozna zarejestrowac procedury obslugi. ), EVENTLOG_ERROR_TYPE); hServStatus.dwCurrentState = SERVICE_STOPPED; hServStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; hServStatus.dwServiceSpecificExitCode = 1; UpdateStatus (SERVICE_STOPPED, -1); return; } LogEvent (_T( Zarejestrowano procedure sterujaca. ), ´EVENTLOG_SUCCESS); SetServiceStatus (hSStat, hServStatus); LogEvent (_T( Stan SERVICE_START_PENDING. ), EVENTLOG_SUCCESS); /* Uruchamianie zadañ specyficznych dla usïugi. Ogólne operacje zostaïy wykonane. */ ServiceSpecific (argc, argv); /* Sterowanie jest zwracane do tego miejsca dopiero po zakoñczeniu dziaïania funkcji ServiceSpecific, co oznacza zamkniÚcie systemu. */ LogEvent (_T( Watki uslugi zakonczyly prace. ), ´EVENTLOG_SUCCESS); LogEvent (_T( Ustawianie stanu na SERVICE_STOPPED. ), ´EVENTLOG_SUCCESS); P R Z Y K ’ A D — N A K ’ A D K A N A U S ’ U G I 561 UpdateStatus (SERVICE_STOPPED, 0); LogEvent (_T( Stan ustawiono na SERVICE_STOPPED. ), ´EVENTLOG_SUCCESS); return; } /* Funkcja specyficzna dla usïugi (gïówna) wywoïywana w funkcji ServiceMain. */ int ServiceSpecific (int argc, LPTSTR argv[]) { UpdateStatus (-1, -1); /* Zmiana stanu i ustawienie nastÚpnego punktu kontrolnego. */ /* Serwer moĝna uruchomiÊ jako wÈtek lub proces. */ /* Zaïóĝmy, ĝe usïuga rozpoczyna pracÚ w dwie sekundy. */ UpdateStatus (SERVICE_RUNNING, -1); LogEvent (_T( Aktualizacja stanu. Usluga dziala. ), ´EVENTLOG_SUCCESS); /* Okresowe aktualizowanie stanu. */ /*** PÚtlÚ do obsïugi aktualizacji moĝna uruchomiÊ w odrÚbnym wÈtku. ***/ /* Naleĝy teĝ sprawdziÊ flagÚ pauseFlag – zobacz Êwiczenie 13-1. */ LogEvent (_T( Uruchamianie glownej petli uslugi. ), ´EVENTLOG_SUCCESS); while (!shutDown) { /* Flaga shutDown jest ustawiana przy poleceniu zamkniÚcia. */ Sleep (UPDATE_TIME); UpdateStatus (-1, -1); /* Zaïóĝmy, ĝe zmiany nie wystÈpiïy. */ LogEvent (_T( Aktualizacja stanu. Brak zmian. ), ´EVENTLOG_SUCCESS); } LogEvent (_T ( Proces serwera zakonczyl prace. ), ´EVENTLOG_SUCCESS); return 0; } /* Procedura sterujÈca. */ VOID WINAPI ServerCtrlHandler( DWORD dwControl) { switch (dwControl) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: shutDown = TRUE; /* Ustawianie flagi globalnej shutDown. */ UpdateStatus (SERVICE_STOP_PENDING, -1); break; case SERVICE_CONTROL_PAUSE: pauseFlag = TRUE; /* Implementacja wstrzymania to temat Êwiczenia 13.1. */ break; case SERVICE_CONTROL_CONTINUE: pauseFlag = FALSE; /* Implementacja kontynuacji to teĝ Êwiczenie. */ break; 562 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S case SERVICE_CONTROL_INTERROGATE: break; default: if (dwControl 127 dwControl 256) /* Zdefiniowane przez uĝytkownika. */ break; } UpdateStatus (-1, -1); return; } void UpdateStatus (int NewStatus, int Check) /* Ustawianie stanu usïugi i punktu kontrolnego (na okreĂlonÈ wartoĂÊ lub przez zwiÚkszenie). */ { if (Check 0 ) hServStatus.dwCheckPoint++; else hServStatus.dwCheckPoint = Check; if (NewStatus = 0) hServStatus.dwCurrentState = NewStatus; if (isService) { if (!SetServiceStatus (hSStat, hServStatus)) { LogEvent (_T( Nie mozna ustawic stanu. ), ´EVENTLOG_ERROR_TYPE); hServStatus.dwCurrentState = SERVICE_STOPPED; hServStatus.dwWin32ExitCode = ´ERROR_SERVICE_SPECIFIC_ERROR; hServStatus.dwServiceSpecificExitCode = 2; UpdateStatus (SERVICE_STOPPED, -1); return; } else { LogEvent (_T( Zaktualizowano stan uslugi. ), ´EVENTLOG_SUCCESS); } } else { LogEvent (_T( Zaktualizowano stan niezaleznego programu. ), ´EVENTLOG_SUCCESS); } return; } /* Proste rejestrowanie zdarzeñ w pliku. */ static FILE * logFp = NULL; /* Bardzo prosta usïuga rejestrujÈca (korzysta z pliku). */ VOID LogEvent (LPCTSTR UserMessage, WORD type) { TCHAR cTimeString[30] = _T( ); time_t currentTime = time(NULL); _tcsncat (cTimeString, _tctime( currentTime), 30); /* Usuwanie znaku nowego wiersza na koñcu ïañcucha z czasem. */ cTimeString[_tcslen(cTimeString)-2] = _T( \0 ); _ftprintf(logFp, _T( s. ), cTimeString); P R Z Y K ’ A D — N A K ’ A D K A N A U S ’ U G I 563 if (type == EVENTLOG_SUCCESS || type == ´EVENTLOG_INFORMATION_TYPE) _ftprintf(logFp, _T( s ), _T( Informacja. )); else if (type == EVENTLOG_ERROR_TYPE) _ftprintf(logFp, _T( s ), _T( Blad. )); else if (type == EVENTLOG_WARNING_TYPE) _ftprintf(logFp, _T( s ), _T( Ostrzezenie. )); else _ftprintf(logFp, _T( s ), _T( Nieznane. )); _ftprintf(logFp, _T( s\n ), UserMessage); fflush(logFp); return; } BOOL LogInit(LPTSTR name) { logFp = _tfopen (name, _T( a+ )); if (logFp != NULL) LogEvent (_T( Zainicjowano rejestrowanie. ), EVENTLOG_SUCCESS); return (logFp != NULL); } VOID LogClose() { LogEvent (_T( Zamykanie dziennika. ), EVENTLOG_SUCCESS); return; } Opcja –c podawana w wierszu poleceñ okreĂla, ĝe kod naleĝy uru- chomiÊ jako niezaleĝny program (na przykïad w celach diagnostycznych). PominiÚcie tej opcji powoduje wywoïanie funkcji StartServiceCtrl ´Dispatcher. Innym dodatkiem jest plik dziennika. Dla uproszczenia jego nazwÚ zapisano na staïe w kodzie. Usïuga rejestruje w tym pliku istotne zdarzenia. Na koñcu znajdujÈ siÚ proste funkcje do inicjowania i zamykania dziennika oraz rejestrowania komunikatów. W komentarzach opisano kilka innych uproszczeñ i ograniczeñ. Uruchamianie prostej usługi Przebieg programu 13.2a pokazuje, jak za pomocÈ uruchamianego w wier- szu poleceñ narzÚdzia sc utworzyÊ, uruchomiÊ, odpytaÊ, zatrzymaÊ i zam- knÈÊ program SimpleService. Tylko administrator moĝe wykonywaÊ te operacje. Przebieg programu 13.2b przedstawia zawartoĂÊ pliku dziennika. 564 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S Przebieg programu 13.2a. Usługa SimpleService kontrolowana za pomocą narzędzia sc Przebieg programu 13.2b. SimpleServiceLog.txt — plik dziennika Z A R Z k D Z A N I E U S ’ U G A M I S Y S T E M U W I N D O W S 565 Zarządzanie usługami systemu Windows Po napisaniu usïugi nastÚpnym krokiem jest umieszczenie jej pod kontrolÈ menedĝera SCM, aby mógï on uruchamiaÊ i zatrzymywaÊ usïugÚ oraz ste- rowaÊ niÈ na inne sposoby. ChoÊ program sc.exe i usïugowe narzÚdzia administracyjne na to pozwalajÈ, usïugami moĝna teĝ zarzÈdzaÊ progra- mistycznie, co opisano w dalszej czÚĂci podrozdziaïu. Trzeba wykonaÊ kilka kroków — otworzyÊ menedĝer SCM, utworzyÊ usïugÚ pod jego kontrolÈ, a nastÚpnie uruchomiÊ tÚ usïugÚ. Te etapy nie sïuĝÈ do bezpoĂredniego kontrolowania usïugi. SÈ to instrukcje dla mene- dĝera SCM, który z kolei steruje okreĂlonÈ usïugÈ. Otwieranie menedżera SCM Do utworzenia usïugi niezbÚdny jest odrÚbny proces uruchomiony jako „administrator”. Podobnie dziaïa program JobShell (rozdziaï 6.) urucha- miajÈcy zadania. Pierwszy krok to otwarcie menedĝera SCM i pobranie uchwytu, który umoĝliwi utworzenie usïugi. SC_HANDLE OpenSCManager ( LPCTSTR lpMachineName, LPCTSTR lpDatabaseName, DWORD dwDesiredAccess) Parametry JeĂli menedĝer SCM dziaïa na komputerze lokalnym, parametr lpMachine ´Name ma wartoĂÊ NULL, natomiast moĝna teĝ uzyskaÊ dostÚp do mene- dĝera uruchomionego na maszynach z danej sieci. Parametr lpDatabaseName ma zwykle wartoĂÊ NULL. Parametr dwDesiredAccess ma standardowo wartoĂÊ SC_MANAGER_ ´ALL_ACCESS, jednak moĝna okreĂliÊ bardziej ograniczone uprawnienia dostÚpu, jak opisano to w dokumentacji dostÚpnej w internecie. Tworzenie i usuwanie usługi Aby zarejestrowaÊ usïugÚ, naleĝy wywoïaÊ funkcjÚ CreateService. 566 R O Z D Z I A ’ 1 3 . U S ’ U G I S Y S T E M U W I N D O W S SC_HANDLE CreateService ( SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPCTSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword); Funkcja CreateService umieszcza nowe usïugi w rejestrze w kluczu: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services Nie naleĝy jednak próbowaÊ pomijaÊ funkcji CreateService przez bez- poĂrednie manipulowanie rejestrem. O tym kluczu wspomniano tylko po to, aby pokazaÊ, w jaki sposób Windows przechowuje informacje o usïugach. Parametry Parametr hSCManager to uchwyt typu SC_HANDLE zwrócony przez funkcjÚ OpenSCManager. Parametr lpServiceName to nazwa uĝywana do póěniejszego wska- zywania usïugi. Jest to jedna z nazw usïug logicznych podanych w tablicy przydziaïu w wywoïaniu funkcji StartServiceCtrlDispatcher. Warto zauwaĝyÊ, ĝe funkcjÚ CreateService trzeba wywoïaÊ dla kaĝdej usïugi logicznej. Parametr lpDisplayName to nazwa usïugi wyĂwietlana uĝytkownikowi w narzÚdziu administracyjnym Usïugi (Panel sterowania/NarzÚdzia admini- stracyjne) i w innych miejscach. Nazwa ta pojawia siÚ natychmiast po uda- nym wywoïaniu funkcji CreateService. Do parametru dwDesiredAccess moĝna przypisaÊ wartoĂÊ SERVICE_ ´ALL_ACCESS lub kombinacjÚ wartoĂci GENERIC_READ, GENERIC_WRITE i GENERIC_EXECUTE. WiÚcej szczegóïów na ten temat moĝna znaleěÊ w dokumentacji MSDN. WartoĂci parametru dwServiceType przedstawiono w tabeli 13.1. Z A R Z k D Z A N I E U S ’ U G A M I S Y S T E M U W I N D O W S 567 Parametr dwStartType okreĂla sposób uruchamiania usïugi. W przy- kïadach uĝyto ustawienia SERVICE_DEMAND_START, natomiast inne warto- Ăci (SERVICE_BOOT_START i SERVICE_SYSTEM_START) umoĝliwiajÈ uruchamianie usïug sterowników urzÈdzeñ w czasie ïadowania lub urucha- miania systemu. Ustawienie SERVICE_AUTO_START informuje, ĝe usïugÚ naleĝy wïÈczyÊ w czasie uruchamiania komputera. Parametr lpBinaryPathName okreĂla peïnÈ ĂcieĝkÚ do pliku wykony- walnego. Koniecznie trzeba podaÊ rozszerzenie .exe. JeĂli Ăcieĝka obej- muje odstÚpy, naleĝy uĝyÊ cudzysïowów. Inne parametry dotyczÈ nazwy konta i hasïa, grup sïuĝÈcych do ïÈczenia usïug, a takĝe zaleĝnoĂci, jeĂli istnieje kilka zaleĝnych od siebie usïug. WartoĂci parametrów konfiguracyjnych istniejÈcej usïugi moĝna zmie- niÊ za pomocÈ funkcji ChangeServiceConfig i ChangeService ´Config2. Ta druga jest prostsza i prawdopodobnie z tego powodu nie nosi nazwy ChangeServiceConfigEx. Do wskazywania usïug sïuĝÈ ich uchwyty, a wspomniane funkcje pozwalajÈ ustawiÊ nowe wartoĂci wiÚkszoĂci parametrów. Moĝna na przykïad podaÊ nowÈ wartoĂÊ para- metrów dwServiceType lub dwStartType, jednak nie moĝna zmieniÊ parametru dwAccess. Istnieje teĝ funkcja OpenService. Sïuĝy ona do pobierania uchwytu nazwanej usïugi. Aby wyrejestrowaÊ usïugÚ z menedĝera SCM, naleĝy uĝyÊ funkcji DeleteService, a do zamykania uchwytów SC_HANDLE przezna- czona jest funkcja CloseServiceHandle. Uruchamianie usługi Usïuga po utworzeniu nie jest uruchomiona. Naleĝy wywoïaÊ funkcjÚ Ser ´viceMain() przez podanie uchwytu uzyskanego za pomocÈ funkcji CreateService. Razem z uchwytem naleĝy podaÊ parametry wiersza poleceñ (argc
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Programowanie w systemie Windows. Wydanie IV
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: