300 likes | 455 Views
THE Windows API. 這們課介紹如何使用 Windows 應用程式介面( Application Programming Interface , API )的書,主要介紹系統核心的部分 。 例如檔案系統、行程( process )與緒程( thread )的管理、行程間相互溝通 ( interprocess communication , IPC )的方式、網路程式設計( Winsock )、以及同步控制( synchronization )等。 至於使用者介面、系 統內部運作、 I/O 設備的驅動程式等,雖然也都是非常重要、有趣的主題,但並不在這本書討論的範圍內。.
E N D
THE Windows API • 這們課介紹如何使用Windows應用程式介面(Application Programming Interface,API)的書,主要介紹系統核心的部分。 • 例如檔案系統、行程(process)與緒程(thread)的管理、行程間相互溝通 (interprocess communication,IPC)的方式、網路程式設計(Winsock)、以及同步控制(synchronization)等。 • 至於使用者介面、系 統內部運作、I/O設備的驅動程式等,雖然也都是非常重要、有趣的主題,但並不在這本書討論的範圍內。
THE Windows API • Win32/Win64 API,或簡稱為Windows API,是微軟的32位元與64位元作業系統家族(包括Windows XP、Windows 2000、Windows Server 2003)所支援的API。 • 較舊的Windows家族成員,包含Windows NT、Me、98、95,則已視為淘汰;不過這些系統仍可執行本書的某些範例。 • 必要時,本課程也會討論從Win32移植到漸露頭角的Win64。Win64 這個由特定版本的Windows 2003及XP所支援的64位元介面,幾乎和Win32一模一樣。
Chapter 1 Getting Started with Win32/64
Chapter 1 OBJECTIVES • 研讀完本章節,您應該能具備下列能力: • 描述甚麼是Windows API • 在Windows 2000, XP, 2003 (“NT5”)中所扮演的角色 • Windows 程式設計的風格與便利性 • 使用Microsoft Visual C++來發展Windows 應用程式 • 編寫與執行簡單的程式碼 • 使用除錯器(Debugger)協助程式除錯 • 使用online help 獲得更多資訊 • 第一章是整個Windows作業系統家族與Windows的概論,透過一個簡單的範例程式,解說Windows程式設計風格的基本要素,並作為其他進階 Windows功能的基礎。
作業系統必備元素 • 我們可以由現代作業系統所必須管理的最重要資源來描述作業系統的功能: • 記憶體 • 檔案系統 • 資源的命名與位置 • 多工 • 通訊與同步控制 • 安全性與保護 • 微軟Windows的Win32/Win64 API 就在多種不同版本的Windows提供了以上所有的功能,甚至還更豐富。 • 我們這們課討論的是如何利用Windows API開發應用程式,Windows API和UNIX(或Linux)所提供的POSIX標準API完全不一樣,Windows 並不遵循X/Open標準,也不符合任何其他標準訂定機構的開放業界標準。
THE WINDOWS NT ARCHITECTURE • 無疑的,Windows API已經成為應用程式開發的重大要素,在桌上型以及伺服端軟體系統的範疇裡,Windows API在許多情況都已經漸漸取代了由UNIX與Linux所支援的POSIX API,成為軟體開發人員偏好或致少等同重視的API。 • 許多有經驗的開發人員都需要快速學習Windows API。 • 我們的第一個目標,是要介紹Windows是甚麼,並告訴大家如何在實務的狀況之下使用Win32 API 。
OS/2Program WindowsProgram POSIXProgram Applications OS/2 Subsystem Windows Subsystem POSIX Subsystem Protected Subsystems NTExecutive Systems Services Process Manager I/O Manager Virtual Memory Manager KERNEL HAL: Hardware Abstraction HARDWARE
GETTING STARTED:Windows 的基本原則 (1 OF 2) • 許多系統資源都以核心物件 “object” 表示,並以所謂的代碼 HANDLE來取用。 • 唯有透過WindowsAPIs才能存取核心物件。 • 核心物件的 HANDLE包括: • Files/檔案pipes/資料通道 • Processes/行程memory mapping/記憶體應對 • Threads/緒程events/事件 • Windows 是既豐富又彈性 • 包含了許多可以執行同一件工作的多種函式,特別是提供了可以叫用一連串函式的簡便函式。 • 每個函式有相當多的參數與旗標來指定函式的各項運作。
GETTING STARTED:Windows 的基本原則 (2 OF 2) • Windows 是以緒程(thread)為基本的執行單元, • 每個行程(process)都可以包含多個緒程。 • 每個行程(process)有他自己的程式碼與資料記憶體位址空間。 • 緒程(Threads)共享行程的程式碼位址空間。 • Threads are “輕量化/lightweight” and more efficient than processes • Used for servers, asynchronous I/O, ...
Windows 命名慣例 • 函式都是以較長而且可以望文生義的方式來命名: • WaitForSingleObjectWaitForMultipleObjects • 預設的資料型別以大寫表示: • BOOL, DWORD, LPDWORD, ... • 預設的資料型別會避免讓您使用*(指標)運算: • LPTSTR (defined as TCHAR *) and • LPCTSTR (defined as const TCHAR *) • 變數名稱使用匈牙利命名法/“Hungarian” notation : • lpFileName — long pointer [to a zero terminated string] • dwAccess —檔案存取權限旗標的雙字組(32bits) ,其中dw就表示以雙字組記錄的旗標。
Windows 程式設計慣例(PROGRAMMING CONVENTIONS) • <windows.h> is always included,這個檔案包含了所有Windows函式的定義與資料型別。 • 所有的Windows核心物件都是以HANDLE型別的變數來識別,並且使用CloseHandle function 來釋放各種物件。 • 許多符號用來代表各式各樣的常數值以及旗標值,其名稱通常很長一串,好處是可以望文生意。 • INVALID_HANDLE_VALUE and GENERIC_READ • ReadFile, WriteFile, and many other Windows functions return Boolean values • System error codes obtained through GetLastError () ,第二章程式2-2會教您如何使用。 • C library always available • But you cannot fully exploit Windows with it
Think About • 問題: • 執行”cpW.exe cpW.obj cpW.100” 指令的過程中應用程式是如何知道來源檔為”cpW.obj” 而目的檔為”cpW.100” • Ans: • 作業系統會先將使用者執行的命令進行字串切割(以空白字元為切割依據) 。 • 切割完計算共分為幾段,以argc變數儲存(argc=3)。 • 切割後的字串分段依序置入argv[ ]陣列中。 • argv[0]=“cpW.exe” • argv[1]=“cpW.obj” • argv[2]=“cpW.100” • 作業系統將argc與argv[ ]當作參數去呼叫cpW.exe的main( )作為程式執行的訊息傳遞方式
EXAMPLE: Windows FILE COPY (1 of 3) • /* Basic cp file copy program */ • /* cp file1 file2: Copy file1 to file2 */ • #include <windows.h> /* 所有Windows程式都須要引入 */ • #include <stdio.h> /* 定義標準輸出入的標頭檔 */ • #define BUF_SIZE 256 /* 加大數字可以加快複製檔案的速度 */ • int main (int argc, LPTSTR argv []) • { • HANDLE hIn, hOut; /* Input and output handles */ • DWORD nIn, nOut; /* Number bytes transferred */ • CHAR Buffer [BUF_SIZE];/* 讀取資料後的暫存區 */ • if (argc != 3) { /* 執行命令的參數項個數不符 */ • printf ("Usage: cp file1 file2\n"); • return 1; • }
EXAMPLE: Windows FILE COPY (2 of 3) • /* Create handles for reading and writing. Many */ • /* default values are used */ • hIn = CreateFile (argv [1], GENERIC_READ, 0, NULL, • OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); • if (hIn == INVALID_HANDLE_VALUE) { /*檔案開啟失敗*/ • printf ("Cannot open input file\n"); • return 2; • } • hOut = CreateFile (argv [2], GENERIC_WRITE, 0, NULL, • CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); • if (hOut == INVALID_HANDLE_VALUE) {/*檔案開啟失敗*/ • printf ("Cannot open output file\n"); • return 3; • }
EXAMPLE: Windows FILE COPY (3 of 3) • /* Input and output file handles are open. */ • /* Copy file. Note end-of-file detection */ • while (ReadFile (hIn, Buffer, BUF_SIZE, • &nIn, NULL) && nIn > 0) • WriteFile (hOut, Buffer, nIn, &nOut, NULL); • /* 釋放 resources, such as open handles */ • CloseHandle (hIn); CloseHandle (hOut); • return 0; • }
Getting Ready for Win64 • Objectives: • Win32 binaries run in 64-bit environment • Source code can be recompiled for 64-bit environment • Cautions: • Do not assume integers and pointers are same length • Win64 introduces 64-bit pointers • New data types include • DWORD32, DWORD64 • POINTER_32, POINTER_64 • LONG32, LONG64
LAB 1–A (1 of 2) • Use the VC++ environment • Build, run, and test the Windows file copy program, cpW • Extend the program so that it prints the value of the error message in case of any failure • Obtained from GetLastError() • Don’t forget to test this error reporting capability • The source code is in Chapter1\cpw.c
LAB 1–A (2 of 2) • The instructor will show you how to: • Create a console application under Microsoft Visual C++ • Execute the application • Use Visual C++ to edit and rebuild the program • Use the Visual C++ debugger • Use the online help • Note: http://world.std.com/~jmhart/wined3.htm contains many explanatory comments, examples, diagrams, and book errata
Chapter 2 BASIC I/O • 我們已經在第一章透過複製檔案的範例程式,循序處理檔案最基本的四個系統函式(API): • CreateFile • ReadFile • WriteFile • CloseHandle • 在這個章節,我們會詳細解說這四個函式,以及相關的系統函式,並且也會介紹提供字元處理以及主控台I/O功能的函式。 • 各種檔案系統及其特色。 • Unicode(萬國碼) 。 • Windows檔案及目錄的管理。
THE FILE SYSTEMS • Windows File Systems • (檔案配置表) File Allocation Table File System (FAT, VFAT) • Windows 9x唯一可用的檔案系統。 • NT File System /NT檔案系統(NTFS) • 支援長檔名、安全性、容錯性、加密、壓縮與延伸屬性。 • 所有Windows NT 以後的版本皆支援。 • CD-ROM File System (CDFS) • Custom file systems • Developed by software vendors
Windows FILE NAMING (1 of 2) • Hierarchical • Full pathname can start with a drive name • A:, C:, … • Or with a “share” name • \\servername\sharename • Pathname separator is a backslash — \ • You can also use / in C
Windows FILE NAMING (2 of 2) • Directory and file names cannot use ASCII 1–31 • Or any of < > : " | • But you can have blanks in file names • Case insensitive but case retaining • File, directory names up to 255 characters long • 250 in Windows 9x • A period . separates a file’s name from its extension • The period is in the name; there can be more than one • . and .. indicate the current directory and its parent
建立以及開啟檔案(1 OF 3) • HANDLE CreateFile (LPCTSTR lpName, • DWORD dwAccess, DWORD dwShareMode, • LPSECURITY_ATTRIBUTES lpsa, DWORD dwCreate, • DWORD dwAttrsAndFlags, HANDLE hTemplateFile) • Return: A HANDLE to an open file object • INVALID_HANDLE_VALUE in case of failure • LPCTSTR will be described in Part II
建立以及開啟檔案(2 OF 3) • 參數(Parameters) :從個別參數的名稱可以看出Windows的程式撰寫慣例。 • [參數格式] • [傳入變數]:[解釋/用意] ==>[接收變數] • argv[1]:來源檔名 ==> lpName • GENERIC_READ:指定要讀取 ==> dwAccess • FILE_SHARE_READ:其他行程(process)可以開啟同一個檔案同時讀取內容 ==> dwSharemode • NULL:檔案開啟時的安全屬性 ==> lpSecurityAttributes • OPEN_EXISTING:如果檔案不存在的話就失敗 ==> dwCreate
建立以及開啟檔案(3 OF 3) • 0:開啟舊檔時,此項傳入值會被忽略 ==> dwAttrsAndFlags • 用在開啟新檔時,建立檔案的屬性與旗標。 • NULL:開啟舊檔時,此項傳入值會被忽略 ==> hTemplateFile • 用在開啟新檔時,將現有檔案的屬性套用到新建立的檔案。
READING FILES (1 OF 2) • BOOL ReadFile ( • HANDLE hFile, • LPVOID lpBuffer, • DWORD nNumberOfBytesToRead, • LPDWORD lpNumberOfBytesRead, • LPOVERLAPPED lpOverlapped) • Return: TRUE if the read succeeds • Even if no bytes were read due to an attempt to read past the end of file • FALSE indicates an invalid handle, a handle without GENERIC_READ access, etc.
READING FILES (2 OF 2) • Parameters • hind:File handle ==> hFile • Buffer:接收讀取資料暫存區起始位址 ==> lpBuffer • BUF_SIZE:要讀取的位元組(Byte)數目 ==> nNumberOfBytesToRead • &nIn:真正讀取到的位元組數目的指標,用來回傳值使用==>lpNumberOfBytesRead • Zero indicates end of file • lpOverlapped • Points to OVERLAPPED structure (NULL for now)
WRITING FILES • BOOL WriteFile ( • HANDLE hFile, CONST VOID *lpBuffer, • DWORD nNumberOfBytesToWrite, • LPDWORD lpNumberOfBytesWritten, • LPOVERLAPPED lpOverlapped) • Return: TRUE if the function succeeds; FALSE otherwise
CLOSING FILES • BOOL CloseHandle (HANDLE hObject) • Return: TRUE if the function succeeds; FALSE otherwise • This function is general purpose and will be used to close handles to many different object types
COPYING FILES • BOOL CopyFile (LPCTSTR lpExistingFile, • LPCTSTR lpNewFile, BOOL fFailIfExists) • If a file with the new name already exists, it will be replaced only if fFailIfExists is FALSE • This is a “convenience function” and also provides performance