標籤:windows 核心編程
最近工作比較閑了,一直沒來得及看的核心編程最近開始看了,分享下筆記。
1、核心控制代碼用完不釋放一定會造成記憶體流失嗎?
不一定,核心控制代碼在進程退出時會被系統釋放掉(遍曆核心控制代碼表,只要每個控制代碼指向的核心對象的引用計數為0,核心就會銷毀該對象,適用於所有的核心對象、資源(GDI對象在內)、記憶體塊);
2、核心對象如何關閉?
調用CloseHandle(),核心會尋找該進程的控制代碼表,如果沒找到該控制代碼,返回FALSE(Debug下拋出異常);如果找到,則使該控制代碼指向的核心對象引用計數減一,若引用計數為0,則釋放該對象所使用的記憶體;
3、核心對象建立後一定要檢查返回控制代碼,並不是所有的API調用失敗返回的都是NULL,有些返回的是INVALID_HANDLE_VALUE(如:CreateFile);
4、控制代碼到底是什嗎?
不同的Windows版本內部實現機制有所區別,這裡說到的控制代碼由三部分構成:指向核心對象記憶體塊的指標、存取遮罩、標誌;
5、進程共用核心對象的三種方式:(繼承、為對象命名,複製物件控點)
5.1使用物件控點繼承:前提是進程之間有父--子關係時,父進程在建立核心對象時,可以指定該對象是可以繼承的。建立子進程時,指定bInheritHandles=TRUE,系統會為子進程建立一個新的、空白的進程控制代碼表,然後遍曆父進程的控制代碼表,凡是包含“可繼承的控制代碼”的項都會被複製到子進程的控制代碼表中,複製項的位置與之在父進程控制代碼表中的位置完全一致(這個重要的原因是:在父進程和子進程中,對一個核心對象進行標識的控制代碼值完全一樣),然後核心會遞增該核心對象的引用計數,因為現在兩個進程都在使用該核心對象;
5.1.1如何使複製項的位置和父進程控制代碼表中的位置完全一致:中間空白位置補上停用控制代碼(0x00000000);
5.1.2子進程的控制代碼表是在子進程建立時建立的,同時複製父進程控制代碼表。因此,後續過程中父進程再建立核心對象並制定其可繼承,尚需子進程仍然是不可繼承該核心對象的;
5.1.3共用控制代碼如何在父--子進程間傳遞?
1、建立子進程時,通過參數傳遞控制代碼值%u HANDLE之類的;
2、子進程建立完成後發送訊息,WaitForInputIdle等待子進程完畢,然後發送訊息PostMessage/SendMessage,WPARAM LPARAM都可以直接傳遞HANDLE值;(只針對有訊息迴圈的程式)
3、共用環境變數,略。
5.1.4改變控制代碼的標誌
SetHandleInformation可改變控制代碼為是否可繼承、是否拒絕關閉;還有GetHandleInformation可以查看當前進程對該控制代碼所擁有的屬性。(詳情查看MSDN)
5.2為對象命名
5.2.1某些核心對象的建立是可以命名的,Mutex、Event、Semaphore……,如果該名稱的對象已被建立(所有核心對象共用共用著這些命名,即使類型不同也會失敗),則返回已建立對象的控制代碼,響應的會複製該控制代碼資訊到當前進程的控制代碼表;
5.2.2終端命名空間
命名核心對象時,Global\\首碼,強制指定對象放入全域命名空間;Local\\首碼強制把核心對象放入當前會話的命名空間;
5.2.3複製物件控點
主要使用API DuplicateHandle複製進程控制代碼到另一個進程的控制代碼表中,可以是三個進程、兩個進程、一個進程間進行複製。
大部分都是Windows核心編程第五版中提取出來的,感謝作者。
Windows核心編程筆記(1)