最近在學習Windows底層原理,準備寫個系列文章分享給大家,Michael Li(微軟實習期間的Mentor,為人超好)在知憾訓答過一些關于學習Windows原理的書籍推薦,大家可以拜讀其中一本來入門,我是先從《Windows核心編程》開始了解一些Windows底層管理與硬體互動的原理,然后買了一套冬瓜哥撰寫的《大話計算機》系列叢書,學有余力的童鞋強烈推薦你去看看,這套書對計算機整體的運作原理講解的很系統,涉及了計算機組成原理、網路原理、編譯原理、作業系統、硬體等,可以作為不錯的入門教材,
Windows核心編程(第5版)電子書及配套代碼
學習前需要理解一些系統專業詞匯的概念,比如:系統資源、記憶體管理、句柄、內核態/用戶態、Hook、事件、訊息處理機制等,不然后續對Windows底層原理的理解會有些誤差和盲區,例如很容易將系統資源和CPU資源(CPU使用率)相混淆,


我們將Linux、Unix、Windows對其內核進行對比學習Windows的內核管理機制,參考
Linux:
Linux 優先使用物理記憶體,當物理記憶體還有空閑時,linux是不會釋放記憶體的,即時占用記憶體的程式已經被關閉了(這部分記憶體就用來做快取了),也就是說,即時你 有很大的記憶體,用過一段時間后,也會被占滿,這樣做的好處是,啟動那些剛開啟過的程式、或是讀取剛存取過得資料會比較快,對于服務器很有好處,
Windows:
windows則總是給記憶體留下一定的空閑空間,即時記憶體有空閑也會讓程式使用一些虛擬記憶體,這樣做的好處是,啟動新的程式比較快,直接分給它些空閑記憶體就可以了,而linux下呢?由于記憶體經常處于全部被使用的狀態,則要先清理出一塊記憶體,再分配給新的程式使用,因此,新程式的啟動會慢一些,
Windows是由C語言撰寫的,但是整個系統是面向物件設計的,所以引入了句柄這種資料結構,句柄是一種指向指標的指標,確切點說句柄是一種指向結構體的指標,而指標就是一串記憶體地址,
Windows是基于事件驅動機制的,整個系統都是通過訊息傳遞來實作的,
Issue:
各大系統平臺的程式是用什么機制來接收用戶的事件而做出反應的?
Windows的訊息系統是如何支持帶有圖形用戶界面的應用程式?
點擊滑鼠,觸發一個系統事件(事件本質上是對訊息的封裝)——>Windows把這個事件翻譯為訊息,然后把它放到訊息佇列中,傳遞給應用程式——>應用程式從訊息佇列中接收到這個訊息,把它存放在TMsg記錄中——>應用程式把訊息傳遞給一個適當的視窗的視窗程序(回呼函式)——>視窗程序回應這個訊息并進行處理
Windows作業系統訊息包括:標準Windows訊息(WM_打頭) + 通知訊息(針對標注Windows控制元件) + 自定義訊息(編程)
訊息系統(內核控制中心)組成:訊息佇列 + 訊息回圈 + 視窗程序
在Windows中發生的一切都可以用訊息來表示,訊息用于告訴作業系統發生了什么,所有的Windows應用程式都是訊息驅動的,訊息本身是作為一個記錄傳遞給應用程式的,這個記錄(一般在 C/C++/匯編 中稱為“結構體”)中包含了訊息的型別以及其他資訊,例如,對單擊滑鼠所產生的訊息來說,這個記錄(結構體)中包含了單擊滑鼠的訊息號(WM_LBUTTONDOWN)、單擊滑鼠時的坐標(由X,Y值連接而成的一個32位整數),這個記錄型別叫做TMsg,
在C語言中訊息的定義:
typedef struct Msg
{
HWND hwnd; / /視窗句柄
UINT message; / /訊息常量識別符號
WPARAM wParam; // 32位訊息的特定附加資訊
LPARAM lParam; // 32位訊息的特定附加資訊
DWORD time; / /訊息創建時的時間
TPoint pt; / /訊息創建時的滑鼠位置
} TMsg;
typedef struct TPoint
{
int x;
int y;
}TPoint;
不是每個控制元件都能接收訊息,轉發訊息和繪制自身,只有具有句柄(handle)的控制元件才能做到,有句柄的控制元件本質上都是一個表單(window),它們可以獨立存在,可以作為其它控制元件的容器,而沒有句柄的控制元件,如Label,是不能獨立存在的,只能作為視窗控制元件的子控制元件,它不能繪制自身,只能依靠父表單將它繪制來,
然而,并非所有的句柄都是表單的句柄,Windows系統中還中很多其它型別的句柄,如畫布(hdc)句柄,畫筆句柄,畫刷句柄,應用程式句柄(hInstance)等,這種句柄是不能接收訊息的,但不管是哪種句柄,都是系統中物件的唯一標識,本文只討論表單句柄,
那為什么句柄使視窗具有了如此獨特的特性呢?實際是都是由于訊息的原因,由于有了句柄,表單能夠接收訊息,也就知道了該什么時候繪制自己,繪制子控制元件,知道了滑鼠在什么時候點擊了視窗的哪個部分,從而作出相應的處理,句柄就好像是一個人的身份證,有了它,你就可以從事各種社會活動;否則的話,你要么是一個社會看不到的黑戶,要么跟在別人后面,通過別人來證明你的存在,
Windows保存的訊息佇列是以執行緒(Thread)來分組的,也就是說每個執行緒都有自己的訊息佇列,事件本質上是對訊息的封裝,
有哪些內核物件:
令牌物件 Token
事件物件 Event
檔案物件 File
檔案映射物件 Mapping File
執行緒物件 Thread
時鐘物件 Timer
執行緒池物件 ThreadPool
I/O完成端物件 Completion port
作業物件 Job
郵槽物件 Mailslot
互斥物件 Mutex
管道物件 Pipe
行程物件 Process
信號燈物件 Semaphore
...
內核物件的結構:
公用部分(安全描述符、計數器) + 個性部分
句柄、Windows資料型別:
WORD:16位無符號整型資料
DWORD:32位無符號整型資料(DWORD32)
DWORD64:64位無符號整型資料
INT:32位有符號整型資料型別
INT_PTR:指向INT資料型別的指標型別
INT32:32位符號整型
INT64:64位符號整型
UINT:無符號INT
LONG:32位符號整型(LONG32)
ULONG:無符號LONG
LONGLONG:64位符號整型(LONG64)
SHORT:無符號短整型(16位)
LPARAM:訊息的L引數
WPARAM:訊息的W引數
HANDLE:物件的句柄,最基本的句柄型別
HICON:圖示的句柄
HINSTANCE:程式實體的句柄
HKEY:注冊表鍵的句柄
HMODULE:模塊的句柄
HWND:視窗的句柄
LPSTR:字符指標,也就是字串變數
LPCSTR:字串常量
LPCTSTR:根據環境配置,如果定義了UNICODE宏,則是LPCWSTR型別,否則則為LPCSTR型別
LPCWSTR:UNICODE字串常量
LPDWORD:指向DWORD型別資料的指標
CHAR:8位元位元組
TCHAR:如果定義了UNICODE,則為WCHAR,否則為CHAR
UCHAR:無符號CHAR
WCHAR:16位Unicode字符
BOOL:布爾型變數
BYTE:位元組型別(8位)
CONST:常量
FLOAT:浮點資料型別
SIZE_T:表示記憶體大小,以位元組為單位,其最大值是CPU最大尋址范圍
VOID:無型別,相當于標準C語言中的void
WINAPI:Windows API的函式呼叫方式,常見于SDK頭檔案中對API函式的宣告中,相當于_stdcall(更嚴格地說,這不是資料型別,而是一種函式呼叫約定
BYTE 8位 unsigned char
CHAR 8位 char
BOOL 16位 int
DWORD 32位 unsigned long int
HANDLE 一般句柄
HWND 32位 long int
LONG 32位 long int
LPCSTR 指向字串的 const 指標
LPSTR 指向字串的指標
SHORT 16位短整數
UINT 32位無符號長整數
WORD 16位無符號短整數
BITMAP 獨立于邏輯設備的位圖(DIB)
LOGBRUSH 邏輯刷
LOGFONT 邏輯字體
LOGPEN 邏輯筆
MSG 視窗訊息
POINT 點
RECT 矩形
WNDCLASS 視窗類結構
hBitmap 為保存DIB影像資訊的記憶體域的句柄
hBrush 當畫圖時用于填滿設備范圍的刷子的句柄
hCtl 子視窗控制元件的句柄
hCursor 滑鼠游標句柄
hDc 設備描述表句柄
hDlg 文本字體的句柄
hFont 文本字體的句柄
hIcon 圖示的句柄
hInstance windows應用程式實體句柄
hMem 記憶體塊句柄
hMenu 選單或彈出式選單句柄
hModule 模式的句柄,常用于從一可執行檔案獲取資源資料
hPalette 顏色調色板
hPen 當在設備上畫圖時用于指明線型的筆的句柄
hRgn 在視窗上剪貼一塊區域的句柄
hTask 獨立于已執行的任務的句柄
hWnd 視窗句柄
持續更新中...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/67480.html
標籤:其他
上一篇:pn512
下一篇:為什么創建博客網站?
