PIXNET Logo登入

Green Wind

跳到主文

部落格全站分類:不設分類

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 6月 23 週五 200607:55
  • Google搜索技巧2005版


注意:文中[]符號是為了突出關鍵詞,在實際搜索中是不包含的;本文採用的是意譯;本譯文已經征得作者許可;本譯文可任意轉載,請保留本文的頭訊息
1. 雙引號可以用減號代替,比如搜索["like this"]與搜索[like-this]是一個效果
2. Google不會處理一些特殊的字符,比如[#](幾年前還不行,現下可以了,比如搜索[c#]已經可以搜到相應的結果),但是還有一些字符它不認識,比如搜索[t.]、[t-]與[t^]的結果是一樣的
3. Google充許一次搜索最多32個關鍵詞
4. 在單字前加~符號可以搜索同義詞,比如你想搜索[house],同時也想找[home],你就可以搜索[~house]
5. 如果想得到Google索引頁面的總數,可以搜索[* *]
6. Google可以指定數字範圍搜索。搜索[2001..2005]相當於搜索含有2001、2002直到2005的任意一個數的網頁
7. 搜索[define:css]相當於搜索css的定義,這招對想學習知識的人很有效;也可以用[what is css]搜索;對中文來說,也可以用[什麼是css]之類的
8. Google有一定的人工智慧,可以識別一些簡單的片語如[whenwas Einstein born?]或[einstein birthday]
9. 透過[link:]語法,可以尋找含有某個鏈接的網頁,比如[link:blog.outer-court.com]將找到包括指向 blog.outer-court.com超級鏈接的網頁(最新的Google Blog Search也支援這個語法),但是Google並不會給出所有的包含此鏈接的網頁,因為它要保證pagerank算法不被反向工程(呵呵,可以參見那兩個Google創始人關於pagerank的論文,可下載)
10. 如果在搜索的關鍵詞的最後輸入[why?],就會在結果中出現鏈接到Google Answers的鏈接http://answers.google.com ,在裡面可以進行有償提問
11. 現下出現了一種興趣活動,叫做Google Hacking,其內容是使用Google搜索一些特定的關鍵詞,以便找到有漏洞的、易被黑客攻擊的站點。這個網站列出了這些關鍵詞:Google Hacking Database( http://johnny.ihackstuff.com/index....ule=prodreviews )
12. 在Google 中輸入一組關鍵詞時,預設是“與”搜索,就是搜索包含有所有關鍵詞的網頁。如果要“或”搜索,可以使用大寫的[OR]或 [|],使用時要與關鍵詞之間留有空格。比如搜索關鍵詞[Hamlet (pizza | coke)],是讓Google搜索頁面中或頁面鏈接描述中含有Hamlet,並含有pizza與coke兩個關鍵詞中任意一個的網頁。
13. 並非所有的Google服務都支援相同的語法,比如在Google Group中支援 [insubject:test]之類的主題搜索。可以透過進階搜索來摸索這些關鍵詞的用法:進入進階搜索之後設定搜索選項,然後觀察關鍵字輸入視窗中的關鍵字的變化
14. 有時候Google懂得一些自然語言,比如搜索關鍵詞[goog], [weather new york, ny], [new york ny]或[war of the worlds],此時Google會在搜索結果前顯示出一個被業內稱為“onebox”的結果,試試看吧!
15. 並非所有的Google都是相同的,它因國家版本(或是說語言版本)而異。在US版下,搜索[site:stormfront.org]會有成千上萬的結果,而在德語版下,搜索[site:stormfront.org]的結果,嗯,自己看吧。Google的確與各國政府有內容審查協議,比如德國版,法蘭西版(網頁搜索),中國版Google新聞
16. 有時候Google會提示你搜索結果很爛,比如你搜索關鍵詞[jew]試試,Google會告訴你它給出的搜索結果很爛,然後給你一個解釋:http://www.google.com/explanation.html
17. 以前,搜索某些關鍵詞如[work at Google] 時會看到Google給自己打的廣告。可以去http://www.google.com/jobs/了解Google的工作
18. 對於一些“Googlebombed”(大概意思是指Google搜索的結果出問題了)的關鍵詞,會有一個廣告鏈接到:http: //googleblog.blogspot.com/2005/09/googlebombing-failure.html (中國大陸需要代理才能訪問)。比如搜索[failure],第一條是美國布希總統介紹
19. 雖然現下Google還沒有支援自然語言,但這裡有一段錄像顯示了支援自然語言的搜索引擎的使用效果:http://blog.outer-court.com/videos/googlebrain.wmv
20. 有人說在Google中搜索[president of the internet],其結第一條表明了president of the internet是誰,我也是這么認為的,而且你還可以使用這個logo支援本文作者:http://blog.outer- court.com/files/president.gif
21. Google現下不再有“stop words”(被強製忽略的關鍵詞),比如搜索 [to be or not to be], Google返回的結果中間還列有相關的完整片語搜索結果
22. 在Google 電算機(http://www.google.com/help/features.html#calculator )中有個彩蛋:輸入[what is the answer to life, the universe and everything?]時,會返回42。(關鍵詞翻譯過來的意思是指“生命、宇宙和一切的答案”,這是一個著名科幻小說中的情節,詳情參見http: //en.wikipedia.org/wiki/The_Answer_to_Life,_the_Universe, _and_Everything)。試試吧,哈哈
23. 你可以在搜索時使用萬用字元[*],這在搜索詩詞時特別有效。比如你可以搜一下["love you twice as much * oh love * *"] 試試
24. 同樣,你的關鍵詞可以全部都是萬用字元,比如搜索["* * * * * * *"]
25. www.googl.com是在輸錯網址後的結果,也是個搜索網站,但搜索結果與Google完全不同。而且此網站也賺Google的錢,因為它使用Google AdSense
26. 如果你想把搜索結果限制在大學的網站之中,可以使用[site:.edu]關鍵詞,比如[c-tutorial site:.edu],這樣可以只搜索以edu結尾的網站。你也可以使用Google Scholar來達到這個目的。也可以使用[site:.de]或[site:.it]來搜索某個特定國家的網站12. 在Google 中輸入一組關鍵詞時,預設是“與”搜索,就是搜索包含有所有關鍵詞的網頁。如果要“或”搜索,可以使用大寫的[OR]或 [|],使用時要與關鍵詞之間留有空格。比如搜索關鍵詞[Hamlet (pizza | coke)],是讓Google搜索頁面中或頁面鏈接描述中含有Hamlet,並含有pizza與coke兩個關鍵詞中任意一個的網頁。
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(101)

  • 個人分類:轉錄文件
▲top
  • 9月 24 週六 200504:19
  • 簡要的Windows API函數大全

網路找到的好東西
當作索引用
這樣要寫程式就比較方便一點
要詳細的內容就找MSDN吧
==========================================================
正文
1. API之網路函數
WNetAddConnection 創建同一個網路資源的永久性連接
WNetAddConnection2 創建同一個網路資源的連接
WNetAddConnection3 創建同一個網路資源的連接
WNetCancelConnection 結束一個網路連接
WNetCancelConnection2 結束一個網路連接
WNetCloseEnum 結束一次枚舉操作
WNetConnectionDialog 啟動一個標準對話框,以便建立同網路資源的連接
WNetDisconnectDialog 啟動一個標準對話框,以便斷開同網路資源的連接
WNetEnumResource 枚舉網路資源
WNetGetConnection 獲取本地或已連接的一個資源的網路名稱
WNetGetLastError 獲取網路錯誤的擴展錯誤訊息
WNetGetUniversalName 獲取網路中一個文件的遠程名稱以及/或者UNC(統一命名規範)名稱
WNetGetUser 獲取一個網路資源用以連接的名字
WNetOpenEnum 啟動對網路資源進行枚舉的過程
2. API之消息函數
BroadcastSystemMessage 將一條系統消息廣播給系統中所有的頂級窗口
GetMessagePos 取得消息隊列中上一條消息處理完畢時的鼠標指針螢幕位置
GetMessageTime 取得消息隊列中上一條消息處理完畢時的時間
PostMessage 將一條消息投遞到指定窗口的消息隊列
PostThreadMessage 將一條消息投遞給應用程式
RegisterWindowMessage 獲取分發給一個字串標識符的消息編號
ReplyMessage 答覆一個消息
SendMessage 調用一個窗口的窗口函數,將一條消息發給那個窗口
SendMessageCallback 將一條消息發給窗口
SendMessageTimeout 向窗口發送一條消息
SendNotifyMessage 向窗口發送一條消息
3. API之文件處理函數
CloseHandle 關閉一個內核對象。其中包括文件、文件映射、進程、線程、安全和同步對象等
CompareFileTime 對比兩個文件的時間
CopyFile 複製文件
CreateDirectory 創建一個新目錄
CreateFile 打開和創建文件、管道、郵槽、通信服務、設備以及控制台
CreateFileMapping 創建一個新的文件映射對象
DeleteFile 刪除指定文件
DeviceIoControl 對設備執行指定的操作
DosDateTimeToFileTime 將DOS日期和時間值轉換成一個 win32 FILETIME 值
FileTimeToDosDateTime 將一個 win32 FILETIME 值轉換成DOS日期和時間值
FileTimeToLocalFileTime 將一個FILETIME架構轉換成本地時間
FileTimeToSystemTime 根據一個FILETIME架構的內容,裝載一個SYSTEMTIME架構
FindClose 關閉由FindFirstFile函數創建的一個搜索句柄
FindFirstFile 根據文件名查找文件
FindNextFile 根據調用FindFirstFile函數時指定的一個文件名查找下一個文件
FlushFileBuffers 針對指定的文件句柄,刷新內部文件緩沖區
FlushViewOfFile 將寫入文件映射緩沖區的所有數據都刷新到磁片
GetBinaryType 判斷文件是否可以執行
GetCompressedFileSize 判斷一個壓縮文件在磁片上實際佔據的位元組數
GetCurrentDirectory 在一個緩沖區中裝載當前目錄
GetDiskFreeSpace 獲取與一個磁片的組織有關的訊息,以及了解剩餘空間的容量
GetDiskFreeSpaceEx 獲取與一個磁片的組織以及剩餘空間容量有關的訊息
GetDriveType 判斷一個磁碟機的類型
GetExpandedName 取得一個壓縮文件的全名
GetFileAttributes 判斷指定文件的屬性
GetFileInformationByHandle 這個函數提供了獲取文件訊息的一種機製
GetFileSize 判斷文件長度
GetFileTime 取得指定文件的時間訊息
GetFileType 在給出文件句柄的前提下,判斷文件類型
GetFileVersionInfo 從支持版本標記的一個模塊裡獲取文件版本訊息
GetFileVersionInfoSize 針對包含了版本資源的一個文件,判斷容納文件版本訊息需要一個多大的緩沖區
GetFullPathName 獲取指定文件的完整路徑名
GetLogicalDrives 判斷系統中存在哪些邏輯驅動器字母
GetLogicalDriveStrings 獲取一個字串,其中包含了當前所有邏輯驅動器的根驅動器路徑
GetOverlappedResult 判斷一個重疊操作當前的狀態
GetPrivateProfileInt 為初始化文件(.ini文件)中指定的條目獲取一個整數值
GetPrivateProfileSection 獲取指定小節(在.ini文件中)所有項名和值的一個列表
GetPrivateProfileString 為初始化文件中指定的條目取得字串
GetProfileInt 取得win.ini初始化文件中指定條目的一個整數值
GetProfileSection 獲取指定小節(在win.ini文件中)所有項名和值的一個列表
GetProfileString 為win.ini初始化文件中指定的條目取得字串
GetShortPathName 獲取指定文件的短路徑名
GetSystemDirectory 取得Windows系統目錄(即System目錄)的完整路徑名
GetTempFileName 這個函數包含了一個臨時文件的名字,它可由應用程式使用
GetTempPath 獲取為臨時文件指定的路徑
GetVolumeInformation 獲取與一個磁片卷有關的訊息
GetWindowsDirectory 獲取Windows目錄的完整路徑名
hread 參考lread
hwrite 參考lwrite函數
lclose 關閉指定的文件
lcreat 創建一個文件
llseek 設置文件中進行讀寫的當前位置
LockFile 鎖定文件的某一部分,使其不與其他應用程式共享
LockFileEx 與LockFile相似,只是它提供了更多的功能
lopen 以二進製模式打開指定的文件
lread 將文件中的數據讀入內存緩沖區
lwrite 將數據從內存緩沖區寫入一個文件
LZClose 關閉由LZOpenFile 或 LZInit函數打開的一個文件
LZCopy 複製一個文件
LZInit 這個函數用于初始化內部緩沖區
LZOpenFile 該函數能執行大量不同的文件處理,而且兼容于壓縮文件
LZRead 將數據從文件讀入內存緩沖區
LZSeek 設置一個文件中進行讀寫的當前位置
MapViewOfFile 將一個文件映射對象映射到當前應用程式的位址空間
MoveFile 移動文件
OpenFile 這個函數能執行大量不同的文件操作
OpenFileMapping 打開一個現成的文件映射對象
QueryDosDevice 在Windows NT中,DOS設備名會映射成NT系統設備名。該函數可判斷當前的設備映射情況
ReadFile 從文件中讀出數據
ReadFileEx 與ReadFile相似,只是它只能用于異步讀操作,並包含了一個完整的回調
RegCloseKey 關閉系統註冊表中的一個項(或鍵)
RegConnectRegistry 訪問遠程系統的部分註冊表
RegCreateKey 在指定的項下創建或打開一個項
RegCreateKeyEx 在指定項下創建新項的更複雜的模式。在Win32環境中建議使用這個函數
RegDeleteKey 刪除現有項下方一個指定的子項
RegDeleteValue 刪除指定項下方的一個值
RegEnumKey 枚舉指定項的子項。在Win32環境中應使用RegEnumKeyEx
RegEnumKeyEx 枚舉指定項下方的子項
RegEnumValue 枚舉指定項的值
RegFlushKey 將對項和它的子項作出的改動實際寫入磁片
RegGetKeySecurity 獲取與一個註冊表項有關的安全訊息
RegLoadKey 從以前用RegSaveKey函數創建的一個文件裡裝載註冊表訊息
RegNotifyChangeKeyValue 註冊表項或它的任何一個子項發生變化時,用這個函數提供一種通知機製
RegOpenKey 打開一個現有的註冊表項
RegOpenKeyEx 打開一個現有的項。在win32下推薦使用這個函數
RegQueryInfoKey 獲取與一個項有關的訊息
RegQueryValue 取得指定項或子項的默認(未命名)值
RegQueryValueEx 獲取一個項的設置值
RegReplaceKey 用一個磁片文件保存的訊息替換註冊表訊息;並創建一個備份,在其中包含當前註冊表訊息
RegRestoreKey 從一個磁片文件恢復註冊表訊息
RegSaveKey 將一個項以及它的所有子項都保存到一個磁片文件
RegSetKeySecurity 設置指定項的安全特性
RegSetValue 設置指定項或子項的默認值
RegSetValueEx 設置指定項的值
RegUnLoadKey 卸載指定的項以及它的所有子項
RemoveDirectory 刪除指定目錄
SearchPath 查找指定文件
SetCurrentDirectory 設置當前目錄
SetEndOfFile 針對一個打開的文件,將當前文件位置設為文件末尾
SetFileAttributes 設置文件屬性
SetFilePointer 在一個文件中設置當前的讀寫位置
SetFileTime 設置文件的創建、訪問及上次修改時間
SetHandleCount 這個函數不必在win32下使用;即使使用,也不會有任何效果
SetVolumeLabel 設置一個磁片的卷標(Label)
SystemTimeToFileTime 根據一個FILETIME架構的內容,載入一個SYSTEMTIME架構
UnlockFile 解除對一個文件的鎖定
UnlockFileEx 解除對一個文件的鎖定
UnmapViewOfFile 在當前應用程式的內存位址空間解除對一個文件映射對象的映射
VerFindFile 用這個函數決定一個文件應安裝到那裡
VerInstallFile 用這個函數安裝一個文件
VerLanguageName 這個函數能根據16位語言代碼獲取一種語言的名稱
VerQueryValue 這個函數用于從版本資源中獲取訊息
WriteFile 將數據寫入一個文件
WriteFileEx 與WriteFile類似,只是它只能用于異步寫操作,並包括了一個完整的回調
WritePrivateProfileSection 為一個初始化文件(.ini)中指定的小節設置所有項名和值
WritePrivateProfileString 在初始化文件指定小節內設置一個字串
WriteProfileSection 為Win.ini初始化文件中一個指定的小節設置所有項名和值
WriteProfileString 在Win.ini初始化文件指定小節內設置一個字串
4. API之打印函數
AbortDoc 取消一份文檔的打印
AbortPrinter 刪除與一台印表機關聯在一起的緩沖文件
AddForm 為印表機的表單列表添加一個新表單
AddJob 用于獲取一個有效的路徑名,以便用它為作業創建一個后台打印文件。它也會為作業分發一個作業編號
AddMonitor 為系統添加一個印表機監視器
AddPort 啟動"添加端口"對話框,允許用戶在系統可用端口列表中加入一個新端口
AddPrinter 在系統中添加一台新印表機
AddPrinterConnection 連接指定的印表機
AddPrinterDriver 為指定的系統添加一個打印驅動程式
AddPrintProcessor 為指定的系統添加一個打印處理器
AddPrintProvidor 為系統添加一個打印供應商
AdvancedDocumentProperties 啟動印表機文檔設置對話框
ClosePrinter 關閉一個打開的印表機對象
ConfigurePort 針對指定的端口,啟動一個端口配置對話框
ConnectToPrinterDlg 啟動連接印表機對話框,用它同訪問網路的印表機連接
DeleteForm 從印表機可用表單列表中刪除一個表單
DeleteMonitor 刪除指定的打印監視器
DeletePort 啟動"刪除端口"對話框,允許用戶從當前系統刪除一個端口
DeletePrinter 將指定的印表機標誌為從系統中刪除
DeletePrinterConnection 刪除與指定印表機的連接
DeletePrinterDriver 從系統刪除一個印表機驅動程式
DeletePrintProcessor 從指定系統刪除一個打印處理器
DeletePrintProvidor 從系統中刪除一個打印供應商
DeviceCapabilities 利用這個函數可獲得與一個設備的能力有關的訊息
DocumentProperties 印表機配置控制函數
EndDocAPI 結束一個成功的打印作業
EndDocPrinter 在后台打印程式的級別指定一個文檔的結束
EndPage 用這個函數完成一個頁面的打印,並準備設備場景,以便打印下一個頁
EndPagePrinter 指定一個頁在打印作業中的結尾
EnumForms 枚舉一台印表機可用的表單
EnumJobs 枚舉打印隊列中的作業
EnumMonitors 枚舉可用的打印監視器
EnumPorts 枚舉一個系統可用的端口
EnumPrinterDrivers 枚舉指定系統中已安裝的印表機驅動程式
EnumPrinters 枚舉系統中安裝的印表機
EnumPrintProcessorDatatypes 枚舉由一個打印處理器支持的數據類型
EnumPrintProcessors 枚舉系統中可用的打印處理器
Escape 設備控制函數
FindClosePrinterChangeNotification 關閉用FindFirstPrinterChangeNotification函數獲取的一個印表機通告對象
FindFirstPrinterChangeNotification 創建一個新的改變通告對象,以便我們注意印表機狀態的各種變化
FindNextPrinterChangeNotification 用這個函數判斷觸發一次印表機改變通告信號的原因
FreePrinterNotifyInfo 釋放由FindNextPrinterChangeNotification函數分發的一個緩沖區
GetForm 取得與指定表單有關的訊息
GetJob 獲取與指定作業有關的訊息
GetPrinter 取得與指定印表機有關的訊息
GetPrinterData 為印表機設置註冊表配置訊息
GetPrinterDriver 針對指定的印表機,獲取與印表機驅動程式有關的訊息
GetPrinterDriverDirectory 判斷指定系統中包含了印表機驅動程式的目錄是什麼
GetPrintProcessorDirectory 判斷指定系統中包含了印表機處理器驅動程式及文件的目錄
OpenPrinter 打開指定的印表機,並獲取印表機的句柄
PrinterMessageBox 在擁有指定打印作業的系統上顯示一個印表機出錯消息框
PrinterProperties 啟動印表機屬性對話框,以便對印表機進行配置
ReadPrinter 從印表機讀入數據
ResetDC 重設一個設備場景
ResetPrinter 改變指定印表機的默認數據類型及文檔設置
ScheduleJob 提交一個要打印的作業
SetAbortProc 為Windows指定取消函數的位址
SetForm 為指定的表單設置訊息
SetJob 對一個打印作業的狀態進行控制
SetPrinter 對一台印表機的狀態進行控制
SetPrinterData 設置印表機的註冊表配置訊息
StartDoc 開始一個打印作業
StartDocPrinter 在后台打印的級別啟動一個新文檔
StartPage 打印一個新頁前要先調用這個函數
StartPagePrinter 在打印作業中指定一個新頁的開始
WritePrinter 將發送目錄中的數據寫入印表機
5. API之文本和字體函數
AddFontResource 在Windows系統中添加一種字體資源
CreateFont 用指定的屬性創建一種邏輯字體
CreateFontIndirect 用指定的屬性創建一種邏輯字體
CreateScalableFontResource 為一種TureType字體創建一個資源文件,以便能用API函數AddFontResource將其加入Windows系統
DrawText 將文本描繪到指定的矩形中
DrawTextEx 與DrawText相似,只是加入了更多的功能
EnumFontFamilies 列舉指定設備可用的字體
EnumFontFamiliesEx 列舉指定設備可用的字體
EnumFonts 列舉指定設備可用的字體
ExtTextOut 經過擴展的文本描繪函數。也請參考SetTextAlign函數
GetAspectRatioFilterEx 用SetMapperFlags要求Windows只選擇與設備當前縱橫比相符的光閘極字體時,本函數可判斷縱橫比大小
GetCharABCWidths 判斷TureType字體中一個或多個字符的A-B-C大小
GetCharABCWidthsFloat 查詢一種字體中一個或多個字符的A-B-C尺寸
GetCharacterPlacement 該函數用于了解如何用一個給定的字符顯示一個字串
GetCharWidth 調查字體中一個或多個字符的寬度
GetFontData 接收一種可縮放字體文件的數據
GetFontLanguageInfo 返回目前選入指定設備場景中的字體的訊息
GetGlyphOutline 取得TureType字體中構成一個字符的曲線訊息
GetKerningPairs 取得指定字體的字距訊息
GetOutlineTextMetrics 接收與TureType字體內部特徵有關的詳細訊息
GetRasterizerCaps 了解系統是否有能力支持可縮放的字體
GetTabbedTextExtent 判斷一個字串佔據的範圍,同時考慮製表站擴充的原素
GetTextAlign 接收一個設備場景當前的文本對齊標誌
GetTextCharacterExtra 判斷額外字符間距的當前值
GetTextCharset 接收當前選入指定設備場景的字體的字符集標識符
GetTextCharsetInfo 獲取與當前選定字體的字符集有關的詳細訊息
GetTextColor 判斷當前字體顏色。通常也稱為"前景色"
GetTextExtentExPoint 判斷要填入指定區域的字符數量。也用一個數組裝載每個字符的範圍訊息
GetTextExtentPoint 判斷一個字串的大小(範圍)
GetTextFace 獲取一種字體的字樣名
GetTextMetrics 獲取與選入一種設備場景的物理字體有關的訊息
GrayString 描繪一個以灰色顯示的字串。通常由Windows用于標識禁止狀態
PolyTextOut 描繪一系列字串
RemoveFontResource 從Windows系統中刪除一種字體資源
SetMapperFlags Windows對字體進行映射時,可用該函數選擇與目標設備的縱橫比相符的光閘極字體
SetTextAlign 設置文本對齊模式,並指定在文本輸出過程中使用設備場景的當前位置
SetTextCharacterExtra 描繪文本的時候,指定要在字符間插入的額外間距
SetTextColor 設置當前文本顏色。這種顏色也稱為"前景色"
SetTextJustification 透過指定一個文本行應佔據的額外空間,可用這個函數對文本進行兩端對齊處理
TabbedTextOut 支持製表站的一個文本描繪函數
TextOut 文本繪圖函數
6. API之菜單函數
AppendMenu 在指定的菜單裡添加一個菜單項
CheckMenuItem 複選或撤銷複選指定的菜單條目
CheckMenuRadioItem 指定一個菜單條目被複選成"單選"項目
CreateMenu 創建新菜單
CreatePopupMenu 創建一個空的彈出式菜單
DeleteMenu 刪除指定的菜單條目
DestroyMenu 刪除指定的菜單
DrawMenuBar 為指定的窗口重畫菜單
EnableMenuItem 允許或禁止指定的菜單條目
GetMenu 取得窗口中一個菜單的句柄
GetMenuCheckMarkDimensions 返回一個菜單複選符的大小
GetMenuContextHelpId 取得一個菜單的幫助場景ID
GetMenuDefaultItem 判斷菜單中的哪個條目是默認條目
GetMenuItemCount 返回菜單中條目(菜單項)的數量
GetMenuItemID 返回位于菜單中指定位置處的條目的菜單ID
GetMenuItemInfo 取得(接收)與一個菜單條目有關的特定訊息
GetMenuItemRect 在一個矩形中裝載指定菜單條目的螢幕坐標訊息
GetMenuState 取得與指定菜單條目狀態有關的訊息
GetMenuString 取得指定菜單條目的字串
GetSubMenu 取得一個彈出式菜單的句柄,它位于菜單中指定的位置
GetSystemMenu 取得指定窗口的系統菜單的句柄
HiliteMenuItem 控制頂級菜單條目的加亮顯示狀態
InsertMenu 在菜單的指定位置處插入一個菜單條目,並根據需要將其他條目向下移動
InsertMenuItem 插入一個新菜單條目
IsMenu 判斷指定的句柄是否為一個菜單的句柄
LoadMenu 從指定的模塊或應用程式實例中載入一個菜單
LoadMenuIndirect 載入一個菜單
MenuItemFromPoint 判斷哪個菜單條目包含了螢幕上一個指定的點
ModifyMenu 改變菜單條目
RemoveMenu 刪除指定的菜單條目
SetMenu 設置窗口菜單
SetMenuContextHelpId 設置一個菜單的幫助場景ID
SetMenuDefaultItem 將一個菜單條目設為默認條目
SetMenuItemBitmaps 設置一幅特定位圖,令其在指定的菜單條目中使用,代替標準的複選符號(√)
SetMenuItemInfo 為一個菜單條目設置指定的訊息
TrackPopupMenu 在螢幕的任意地方顯示一個彈出式菜單
TrackPopupMenuEx 與TrackPopupMenu相似,只是它提供了額外的功能
7. API之位圖、圖標和光閘極運算函數
BitBlt 將一幅位圖從一個設備場景複製到另一個
CopyIcon 製作指定圖標或鼠標指針的一個副本。這個副本從屬于發出調用的應用程式
CopyImage 複製位圖、圖標或指針,同時在複製過程中進行一些轉換工作
CreateBitmap 按照規定的格式創建一幅與設備有關位圖
CreateBitmapIndirect 創建一幅與設備有關位圖
CreateCompatibleBitmap 創建一幅與設備有關位圖,它與指定的設備場景兼容
CreateCursor 創建一個鼠標指針
CreateDIBitmap 根據一幅與設備無關的位圖創建一幅與設備有關的位圖
CreateDIBSection 創建一個DIBSection
CreateIcon 創建一個圖標
CreateIconIndirect 創建一個圖標
DestroyCursor 清除指定的鼠標指針,並釋放它佔用的所有系統資源
DestroyIcon 清除圖標
DrawIcon 在指定的位置畫一個圖標
DrawIconEx 描繪一個圖標或鼠標指針。與DrawIcon相比,這個函數提供了更多的功能
ExtractAssociatedIcon 判斷一個可執行程式或DLL中是否存在圖標,或是否有圖標與系統註冊表中指定的文件存在關聯並提取之
ExtractIcon 判斷一個可執行文件或DLL中是否有圖標存在,並將其提取出來
GetBitmapBits 將來自位圖的二進製位複製到一個緩沖區
GetBitmapDimensionEx 取得一幅位圖的寬度和高度
GetDIBColorTable 從選入設備場景的DIBSection中取得顏色表訊息
GetDIBits 將來自一幅位圖的二進製位複製到一幅與設備無關的位圖裡
GetIconInfo 取得與圖標有關的訊息
GetStretchBltMode 判斷StretchBlt 和 StretchDIBits函數採用的伸縮模式
LoadBitmap 從指定的模塊或應用程式實例中載入一幅位圖
LoadCursor 從指定的模塊或應用程式實例中載入一個鼠標指針
LoadCursorFromFile 在一個指針文件或一個動畫指針文件的基礎上創建一個指針
LoadIcon 從指定的模塊或應用程式實例中載入一個圖標
LoadImage 載入一個位圖、圖標或指針
MaskBlt 執行複雜的圖象傳輸,同時進行掩模(MASK)處理
PatBlt 在當前選定的刷子的基礎上,用一個圖案填充指定的設備場景
PlgBlt 複製一幅位圖,同時將其轉換成一個平行四邊形。利用它可對位圖進行旋轉處理
SetBitmapBits 將來自緩沖區的二進製位複製到一幅位圖
SetBitmapDimensionEx 設置一幅位圖的寬度。以一毫米的十分之一為單位
SetDIBColorTable 設置選入設備場景的一個DIBSection的顏色表訊息
SetDIBits 將來自與設備無關位圖的二進製位複製到一幅與設備有關的位圖裡
SetDIBitsToDevice 將一幅與設備無關位圖的全部或部分數據直接複製到一個設備
SetStretchBltMode 指定StretchBlt 和 StretchDIBits函數的伸縮模式
StretchBlt 將一幅位圖從一個設備場景複製到另一個
StretchDIBits 將一幅與設備無關位圖的全部或部分數據直接複製到指定的設備場景
8. API之繪圖函數
AbortPath 拋棄選入指定設備場景中的所有路徑。也取消目前正在進行的任何路徑的創建工作
AngleArc 用一個連接弧畫一條線
Arc 畫一個圓弧
BeginPath 啟動一個路徑分支
CancelDC 取消另一個線程裡的長時間繪圖操作
Chord 畫一個弦
CloseEnhMetaFile 關閉指定的增強型圖元文件設備場景,並將新建的圖元文件返回一個句柄
CloseFigure 描繪到一個路徑時,關閉當前打開的圖形
CloseMetaFile 關閉指定的圖元文件設備場景,並向新建的圖元文件返回一個句柄
CopyEnhMetaFile 製作指定增強型圖元文件的一個副本(拷貝)
CopyMetaFile 製作指定(標準)圖元文件的一個副本
CreateBrushIndirect 在一個LOGBRUSH數據架構的基礎上創建一個刷子
CreateDIBPatternBrush 用一幅與設備無關的位圖創建一個刷子,以便指定刷子樣式(圖案)
CreateEnhMetaFile 創建一個增強型的圖元文件設備場景
CreateHatchBrush 創建帶有陰影圖案的一個刷子
CreateMetaFile 創建一個圖元文件設備場景
CreatePatternBrush 用指定了刷子圖案的一幅位圖創建一個刷子
CreatePen 用指定的樣式、寬度和顏色創建一個畫筆
CreatePenIndirect 根據指定的LOGPEN架構創建一個畫筆
CreateSolidBrush 用純色創建一個刷子
DeleteEnhMetaFile 刪除指定的增強型圖元文件
DeleteMetaFile 刪除指定的圖元文件
DeleteObject 刪除GDI對象,對象使用的所有系統資源都會被釋放
DrawEdge 用指定的樣式描繪一個矩形的邊框
DrawEscape 換碼(Escape)函數將數據直接發至顯示設備驅動程式
DrawFocusRect 畫一個焦點矩形
DrawFrameControl 描繪一個標準控件
DrawState 為一幅圖象或繪圖操作應用各式各樣的效果
Ellipse 描繪一個橢圓,由指定的矩形圍繞
EndPath 停止定義一個路徑
EnumEnhMetaFile 針對一個增強型圖元文件,列舉其中單獨的圖元文件記錄
EnumMetaFile 為一個標準的windows圖元文件枚舉單獨的圖元文件記錄
EnumObjects 枚舉可隨同指定設備場景使用的畫筆和刷子
ExtCreatePen 創建一個擴展畫筆(裝飾或幾何)
ExtFloodFill 在指定的設備場景裡,用當前選擇的刷子填充一個區域
FillPath 關閉路徑中任何打開的圖形,並用當前刷子填充
FillRect 用指定的刷子填充一個矩形
FlattenPath 將一個路徑中的所有曲線都轉換成線段
FloodFill 用當前選定的刷子在指定的設備場景中填充一個區域
FrameRect 用指定的刷子圍繞一個矩形畫一個邊框
GdiComment 為指定的增強型圖元文件設備場景添加一條註釋訊息
GdiFlush 執行任何未決的繪圖操作
GdiGetBatchLimit 判斷有多少個GDI繪圖命令位于隊列中
GdiSetBatchLimit 指定有多少個GDI繪圖命令能夠進入隊列
GetArcDirection 畫圓弧的時候,判斷當前採用的繪圖方向
GetBkColor 取得指定設備場景當前的背景顏色
GetBkMode 針對指定的設備場景,取得當前的背景填充模式
GetBrushOrgEx 判斷指定設備場景中當前選定刷子起點
GetCurrentObject 獲得指定類型的當前選定對象
GetCurrentPositionEx 在指定的設備場景中取得當前的畫筆位置
GetEnhMetaFile 取得磁片文件中包含的一個增強型圖元文件的圖元文件句柄
GetEnhMetaFileBits 將指定的增強型圖元文件複製到一個內存緩沖區裡
GetEnhMetaFileDescription 返回對一個增強型圖元文件的說明
GetEnhMetaFileHeader 取得增強型圖元文件的圖元文件頭
GetEnhMetaFilePaletteEntries 取得增強型圖元文件的全部或部分調色板
GetMetaFile 取得包含在一個磁片文件中的圖元文件的圖元文件句柄
GetMetaFileBitsEx 將指定的圖元文件複製到一個內存緩沖區
GetMiterLimit 取得設備場景的斜率限制(Miter)設置
GetNearestColor 根據設備的顯示能力,取得與指定顏色最接近的一種純色
GetObjectAPI 取得對指定對象進行說明的一個架構
GetObjectType 判斷由指定句柄引用的GDI對象的類型
GetPath 取得對當前路徑進行定義的一系列數據
GetPixel 在指定的設備場景中取得一個像素的RGB值
GetPolyFillMode 針對指定的設備場景,獲得多邊形填充模式
GetROP2 針對指定的設備場景,取得當前的繪圖模式
GetStockObject 取得一個固有對象(Stock)
GetSysColorBrush 為任何一種標準系統顏色取得一個刷子
GetWinMetaFileBits 透過在一個緩沖區中填充用于標準圖元文件的數據,將一個增強型圖元文件轉換成標準windows圖元文件
InvertRect 透過反轉每個像素的值,從而反轉一個設備場景中指定的矩形
LineDDA 枚舉指定線段中的所有點
LineTo 用當前畫筆畫一條線,從當前位置連到一個指定的點
MoveToEx 為指定的設備場景指定一個新的當前畫筆位置
PaintDesk 在指定的設備場景中描繪桌面牆紙圖案
PathToRegion 將當前選定的路徑轉換到一個區域裡
Pie 畫一個餅圖
PlayEnhMetaFile 在指定的設備場景中畫一個增強型圖元文件
PlayEnhMetaFileRecord 回放單獨一條增強型圖元文件記錄
PlayMetaFile 在指定的設備場景中回放一個圖元文件
PlayMetaFileRecord 回放來自圖元文件的單條記錄
PolyBezier 描繪一條或多條貝塞爾(Bezier)曲線
PolyDraw 描繪一條複雜的曲線,由線段及貝塞爾曲線組成
Polygon 描繪一個多邊形
Polyline 用當前畫筆描繪一系列線段
PolyPolygon 用當前選定畫筆描繪兩個或多個多邊形
PolyPolyline 用當前選定畫筆描繪兩個或多個多邊形
Rectangle 用當前選定的畫筆描繪矩形,並用當前選定的刷子填充
RoundRect 用當前選定的畫筆畫一個圓角矩形,並用當前選定的刷子在其中填充
SelectClipPath 將設備場景當前的路徑合併到剪切區域裡
SelectObject 為當前設備場景選擇圖形對象
SetArcDirection 設置圓弧的描繪方向
SetBkColor 為指定的設備場景設置背景顏色
SetBkMode 指定陰影刷子、虛線畫筆以及字符中的空隙的填充模式
SetBrushOrgEx 為指定的設備場景設置當前選定刷子的起點
SetEnhMetaFileBits 用指定內存緩沖區內包含的數據創建一個增強型圖元文件
SetMetaFileBitsEx 用包含在指定內存緩沖區內的數據架構創建一個圖元文件
SetMiterLimit 設置設備場景當前的斜率限制
SetPixel 在指定的設備場景中設置一個像素的RGB值
SetPixelV 在指定的設備場景中設置一個像素的RGB值
SetPolyFillMode 設置多邊形的填充模式
SetROP2 設置指定設備場景的繪圖模式。與vb的DrawMode屬性完全一致
SetWinMetaFileBits 將一個標準Windows圖元文件轉換成增強型圖元文件
StrokeAndFillPath 針對指定的設備場景,關閉路徑上打開的所有區域
StrokePath 用當前畫筆描繪一個路徑的輪廓。打開的圖形不會被這個函數關閉
UnrealizeObject 將一個刷子對象選入設備場景之前,如刷子的起點準備用SetBrushOrgEx修改,則必須先調用本函數
WidenPath 根據選定畫筆的寬度,重新定義當前選定的路徑
9. API之設備場景函數
CombineRgn 將兩個區域組合為一個新區域
CombineTransform 驅動世界轉換。它相當于依順序進行兩次轉換
CreateCompatibleDC 創建一個與特定設備場景一致的內存設備場景
CreateDC 為專門設備創建設備場景
CreateEllipticRgn 創建一個橢圓
CreateEllipticRgnIndirect 創建一個內切于特定矩形的橢圓區域
CreateIC 為專用設備創建一個訊息場景
CreatePolygonRgn 創建一個由一系列點圍成的區域
CreatePolyPolygonRgn 創建由多個多邊形構成的區域。每個多邊形都應是封閉的
CreateRectRgn 創建一個矩形區域
CreateRectRgnIndirect 創建一個矩形區域
CreateRoundRectRgn 創建一個圓角矩形
DeleteDC 刪除專用設備場景或訊息場景,釋放所有相關窗口資源
DPtoLP 將點陣從設備坐標轉換到專用設備場景邏輯坐標
EqualRgn 確定兩個區域是否相等
ExcludeClipRect 從專用設備場景的剪裁區中去掉一個矩形區。矩形內不能進行繪圖
ExcludeUpdateRgn 從專用設備場景剪裁區去掉指定窗口的刷新區域
ExtCreateRegion 根據世界轉換修改區域
ExtSelectClipRgn 將指定區域組合到設備場景的當前剪裁區
FillRgn 用指定刷子填充指定區域
FrameRgn 用指定刷子圍繞指定區域畫一個外框
GetBoundsRect 獲取指定設備場景的邊界矩形
GetClipBox 獲取完全包含指定設備場景剪裁區的最小矩形
GetClipRgn 獲取設備場景當前剪裁區
GetDC 獲取指定窗口的設備場景
GetDCEx 為指定窗口獲取設備場景。相比GetDC,本函數提供了更多的選項
GetDCOrgEx 獲取指定設備場景起點位置(以螢幕坐標表示)
GetDeviceCaps 根據指定設備場景代表的設備的功能返回訊息
GetGraphicsMode 確定是否允許增強圖形模式(世界轉換)
GetMapMode 為特定設備場景調入映像模式
GetRegionData 裝入描述一個區域訊息的RgnData架構或緩沖區
GetRgnBox 獲取完全包含指定區域的最小矩形
GetUpdateRgn 確定指定窗口的刷新區域。該區域當前無效,需要刷新
GetViewportExtEx 獲取設備場景視口(viewport)範圍
GetViewportOrgEx 獲取設備場景視口起點
GetWindowDC 獲取整個窗口(包括邊框、滾動條、標題欄、菜單等)的設備場景
GetWindowExtEx 獲取指定設備場景的窗口範圍
GetWindowOrgEx 獲取指定設備場景的邏輯窗口的起點
GetWindowRgn 獲取窗口區域
GetWorldTransform 如果有世界轉換,為設備場景獲取當前世界轉換
IntersectClipRect 為指定設備定義一個新的剪裁區
InvalidateRgn 使窗口指定區域不活動,並將它加入窗口刷新區,使之可隨后被重畫
InvertRgn 透過顛倒每個像素值反轉設備場景指定區域
LPtoDP 將點陣從指定設備場景邏輯坐標轉換為設備坐標
ModifyWorldTransform 根據指定的模式修改世界轉換
OffsetClipRgn 按指定量平移設備場景剪裁區
OffsetRgn 按指定偏移量平移指定區域
OffsetViewportOrgEx 平移設備場景視口區域
OffsetWindowOrgEx 平移指定設備場景窗口起點
PaintRgn 用當前刷子背景色填充指定區域
PtInRegion 確定點是否在指定區域內
PtVisible 確定指定點是否可見(即,點是否在設備場景剪裁區內)
RectInRegion 確定矩形是否有部分在指定區域內
RectVisible 確定指定矩形是否有部分可見(是否在設備場景剪裁區內)
ReleaseDC 釋放由調用GetDC或GetWindowDC函數獲取的指定設備場景
RestoreDC 從設備場景堆棧恢復一個原先保存的設備場景
SaveDC 將指定設備場景狀態保存到Windows設備場景堆棧
ScaleViewportExtEx 縮放設備場景視口的範圍
ScaleWindowExtEx 縮放指定設備場景窗口範圍
ScrollDC 在窗口(由設備場景代表)中水準和(或)垂直滾動矩形
SelectClipRgn 為指定設備場景選擇新的剪裁區
SetBoundsRect 設置指定設備場景的邊界矩形
SetGraphicsMode 允許或禁止增強圖形模式,以提供某些支持(包括世界轉換)
SetMapMode 設置指定設備場景的映射模式
SetRectRgn 設置區域為指定的矩形
SetViewportExtEx 設置設備場景視口範圍
SetViewportOrgEx 設置設備場景視口起點
SetWindowExtEx 設置指定設備場景窗口範圍
SetWindowOrgEx 設置指定設備場景窗口起點
SetWindowRgn 設置窗口區域
SetWorldTransform 設置世界轉換
ValidateRgn 激活窗口中指定區域,把它從刷新區移走
WindowFromDC 取回與某一設備場景相關的窗口的句柄
10. API之硬體與系統函數
ActivateKeyboardLayout 激活一個新的鍵盤佈局。鍵盤佈局定義了按鍵在一種物理性鍵盤上的位置與含義
Beep 用于生成簡單的聲音
CharToOem 將一個字串從ANSI字符集轉換到OEM字符集
ClipCursor 將指針限制到指定區域
ConvertDefaultLocale 將一個特殊的地方標識符轉換成真實的地方ID
CreateCaret 根據指定的訊息創建一個插入符(游標),並將它選定為指定窗口的默認插入符
DestroyCaret 清除(破壞)一個插入符
EnumCalendarInfo 枚舉在指定"地方"環境中可用的日曆訊息
EnumDateFormats 列舉指定的"當地"設置中可用的長、短日期格式
EnumSystemCodePages 枚舉系統中已安裝或支持的代碼頁
EnumSystemLocales 枚舉系統已經安裝或提供支持的"地方"設置
EnumTimeFormats 枚舉一個指定的地方適用的時間格式
ExitWindowsEx 退出windows,並用特定的選項重新啟動
ExpandEnvironmentStrings 擴充環境字串
FreeEnvironmentStrings 翻譯指定的環境字串塊
GetACP 判斷目前正在生效的ANSI代碼頁
GetAsyncKeyState 判斷函數調用時指定虛擬鍵的狀態
GetCaretBlinkTime 判斷插入符游標的閃爍頻率
GetCaretPos 判斷插入符的當前位置
GetClipCursor 取得一個矩形,用于描述目前為鼠標指針規定的剪切區域
GetCommandLine 獲得指向當前命令行緩沖區的一個指針
GetComputerName 取得這台計算機的名稱
GetCPInfo 取得與指定代碼頁有關的訊息
GetCurrencyFormat 針對指定的"地方"設置,根據貨幣格式格式化一個數字
GetCursor 獲取目前選擇的鼠標指針的句柄
GetCursorPos 獲取鼠標指針的當前位置
GetDateFormat 針對指定的"當地"格式,對一個系統日期進行格式化
GetDoubleClickTime 判斷連續兩次鼠標單擊之間會被處理成雙擊事件的間隔時間
GetEnvironmentStrings 為包含了當前環境字串設置的一個內存塊分發和返回一個句柄
GetEnvironmentVariable 取得一個環境變量的值
GetInputState 判斷是否存在任何待決(等待處理)的鼠標或鍵盤事件
GetKBCodePage 由GetOEMCP取代,兩者功能完全相同
GetKeyboardLayout 取得一個句柄,描述指定應用程式的鍵盤佈局
GetKeyboardLayoutList 獲得系統適用的所有鍵盤佈局的一個列表
GetKeyboardLayoutName 取得當前活動鍵盤佈局的名稱
GetKeyboardState 取得鍵盤上每個虛擬鍵當前的狀態
GetKeyboardType 了解與正在使用的鍵盤有關的訊息
GetKeyNameText 在給出掃描碼的前提下,判斷鍵名
GetKeyState 針對已處理過的按鍵,在最近一次輸入訊息時,判斷指定虛擬鍵的狀態
GetLastError 針對之前調用的api函數,用這個函數取得擴展錯誤訊息
GetLocaleInfo 取得與指定"地方"有關的訊息
GetLocalTime 取得本地日期和時間
GetNumberFormat 針對指定的"地方",按特定的格式格式化一個數字
GetOEMCP 判斷在OEM和ANSI字符集間轉換的windows代碼頁
GetQueueStatus 判斷應用程式消息隊列中待決(等待處理)的消息類型
GetSysColor 判斷指定windows顯示對象的顏色
GetSystemDefaultLangID 取得系統的默認語言ID
GetSystemDefaultLCID 取得當前的默認系統"地方"
GetSystemInfo 取得與底層硬體平台有關的訊息
GetSystemMetrics 返回與windows環境有關的訊息
GetSystemPowerStatus 獲得與當前系統電源狀態有關的訊息
GetSystemTime 取得當前系統時間,這個時間採用的是"協同世界時間"(即UTC,也叫做GMT)格式
GetSystemTimeAdjustment 使內部系統時鐘與一個外部的時鐘信號源同步
GetThreadLocale 取得當前線程的地方ID
GetTickCount 用于獲取自windows啟動以來經歷的時間長度(毫秒)
GetTimeFormat 針對當前指定的"地方",按特定的格式格式化一個系統時間
GetTimeZoneInformation 取得與系統時區設置有關的訊息
GetUserDefaultLangID 為當前用戶取得默認語言ID
GetUserDefaultLCID 取得當前用戶的默認"地方"設置
GetUserName 取得當前用戶的名字
GetVersion 判斷當前營運的Windows和DOS版本
GetVersionEx 取得與平台和作業系統有關的版本訊息
HideCaret 在指定的窗口隱藏插入符(游標)
IsValidCodePage 判斷一個代碼頁是否有效
IsValidLocale 判斷地方標識符是否有效
keybd_event 這個函數類比了鍵盤行動
LoadKeyboardLayout 載入一個鍵盤佈局
MapVirtualKey 根據指定的映射類型,執行不同的掃描碼和字符轉換
MapVirtualKeyEx 根據指定的映射類型,執行不同的掃描碼和字符轉換
MessageBeep 播放一個系統聲音。系統聲音的分發方案是在控制面板裡決定的
mouse_event 類比一次鼠標事件
OemKeyScan 判斷OEM字符集中的一個ASCII字符的掃描碼和Shift鍵狀態
OemToChar 將OEM字符集的一個字串轉換到ANSI字符集
SetCaretBlinkTime 指定插入符(游標)的閃爍頻率
SetCaretPos 指定插入符的位置
SetComputerName 設置新的計算機名
SetCursor 將指定的鼠標指針設為當前指針
SetCursorPos 設置指針的位置
SetDoubleClickTime 設置連續兩次鼠標單擊之間能使系統認為是雙擊事件的間隔時間
SetEnvironmentVariable 將一個環境變量設為指定的值
SetKeyboardState 設置每個虛擬鍵當前在鍵盤上的狀態
SetLocaleInfo 改變用戶"地方"設置訊息
SetLocalTime 設置當前地方時間
SetSysColors 設置指定窗口顯示對象的顏色
SetSystemCursor 改變任何一個標準系統指針
SetSystemTime 設置當前系統時間
SetSystemTimeAdjustment 定時添加一個校準值使內部系統時鐘與一個外部的時鐘信號源同步
SetThreadLocale 為當前線程設置地方
SetTimeZoneInformation 設置系統時區訊息
ShowCaret 在指定的窗口裡顯示插入符(游標)
ShowCursor 控制鼠標指針的可視性
SwapMouseButton 決定是否互換鼠標左右鍵的功能
SystemParametersInfo 獲取和設置數量眾多的windows系統參數
SystemTimeToTzSpecificLocalTime 將系統時間轉換成地方時間
ToAscii 根據當前的掃描碼和鍵盤訊息,將一個虛擬鍵轉換成ASCII字符
ToUnicode 根據當前的掃描碼和鍵盤訊息,將一個虛擬鍵轉換成Unicode字符
UnloadKeyboardLayout 卸載指定的鍵盤佈局
VkKeyScan 針對Windows字符集中一個ASCII字符,判斷虛擬鍵碼和Shift鍵的狀態
11. API之進程和線程函數
CancelWaitableTimer 這個函數用于取消一個可以等待下去的計時器操作
CallNamedPipe 這個函數由一個希望透過管道通信的一個客戶進程調用
ConnectNamedPipe 指示一台伺服器等待下去,直至客戶機同一個命名管道連接
CreateEvent 創建一個事件對象
CreateMailslot 創建一個郵路。返回的句柄由郵路伺服器使用(收件人)
CreateMutex 創建一個互斥體(MUTEX)
CreateNamedPipe 創建一個命名管道。返回的句柄由管道的伺服器端使用
CreatePipe 創建一個匿名管道
CreateProcess 創建一個新進程(比如執行一個程式)
CreateSemaphore 創建一個新的信號機
CreateWaitableTimer 創建一個可等待的計時器對象
DisconnectNamedPipe 斷開一個客戶與一個命名管道的連接
DuplicateHandle 在指出一個現有系統對象當前句柄的情況下,為那個對象創建一個新句柄
ExitProcess 中止一個進程
FindCloseChangeNotification 關閉一個改動通知對象
FindExecutable 查找與一個指定文件關聯在一起的程式的文件名
FindFirstChangeNotification 創建一個文件通知對象。該對象用于監視文件系統發生的變化
FindNextChangeNotification 重設一個文件改變通知對象,令其繼續監視下一次變化
FreeLibrary 釋放指定的動態鏈接庫
GetCurrentProcess 獲取當前進程的一個偽句柄
GetCurrentProcessId 獲取當前進程一個唯一的標識符
GetCurrentThread 獲取當前線程的一個偽句柄
GetCurrentThreadId 獲取當前線程一個唯一的線程標識符
GetExitCodeProces 獲取一個已中斷進程的退出代碼
GetExitCodeThread 獲取一個已中止線程的退出代碼
GetHandleInformation 獲取與一個系統對象句柄有關的訊息
GetMailslotInfo 獲取與一個郵路有關的訊息
GetModuleFileName 獲取一個已裝載模板的完整路徑名稱
GetModuleHandle 獲取一個應用程式或動態鏈接庫的模塊句柄
GetPriorityClass 獲取特定進程的優先級別
GetProcessShutdownParameters 調查系統關閉時一個指定的進程相對于其它進程的關閉早遲情況
GetProcessTimes 獲取與一個進程的經過時間有關的訊息
GetProcessWorkingSetSize 了解一個應用程式在營運過程中實際向它交付了多大容量的內存
GetSartupInfo 獲取一個進程的啟動訊息
GetThreadPriority 獲取特定線程的優先級別
GetTheardTimes 獲取與一個線程的經過時間有關的訊息
GetWindowThreadProcessId 獲取與指定窗口關聯在一起的一個進程和線程標識符
LoadLibrary 載入指定的動態鏈接庫,並將它映射到當前進程使用的位址空間
LoadLibraryEx 裝載指定的動態鏈接庫,並為當前進程把它映射到位址空間
LoadModule 載入一個Windows應用程式,並在指定的環境中營運
MsgWaitForMultipleObjects 等侯單個對象或一系列對象發出信號。如返回條件已經滿足,則立即返回
SetPriorityClass 設置一個進程的優先級別
SetProcessShutdownParameters 在系統關閉期間,為指定進程設置他相對于其它程式的關閉順序
SetProcessWorkingSetSize 設置作業系統實際劃分給進程使用的內存容量
SetThreadPriority 設定線程的優先級別
ShellExecute 查找與指定文件關聯在一起的程式的文件名
TerminateProcess 結束一個進程
WinExec 營運指定的程式
12. API之控件與消息函數
AdjustWindowRect 給定一種窗口樣式,計算獲得目標客戶區矩形所需的窗口大小
AnyPopup 判斷螢幕上是否存在任何彈出式窗口
ArrangeIconicWindows 排列一個父窗口的最小化子窗口
AttachThreadInput 連接線程輸入函數
BeginDeferWindowPos 啟動構建一系列新窗口位置的過程
BringWindowToTop 將指定的窗口帶至窗口列表頂部
CascadeWindows 以層疊模式排列窗口
ChildWindowFromPoint 返回父窗口中包含了指定點的第一個子窗口的句柄
ClientToScreen 判斷窗口內以客戶區坐標表示的一個點的螢幕坐標
CloseWindow 最小化指定的窗口
CopyRect 矩形內容複製
DeferWindowPos 該函數為特定的窗口指定一個新窗口位置
DestroyWindow 清除指定的窗口以及它的所有子窗口
DrawAnimatedRects 描繪一系列動態矩形
EnableWindow 指定的窗口裡允許或禁止所有鼠標及鍵盤輸入
EndDeferWindowPos 同時更新DeferWindowPos調用時指定的所有窗口的位置及狀態
EnumChildWindows 為指定的父窗口枚舉子窗口
EnumThreadWindows 枚舉與指定任務相關的窗口
EnumWindows 枚舉窗口列表中的所有父窗口
EqualRect 判斷兩個矩形架構是否相同
FindWindow 尋找窗口列表中第一個符合指定條件的頂級窗口
FindWindowEx 在窗口列表中尋找與指定條件相符的第一個子窗口
FlashWindow 閃爍顯示指定窗口
GetActiveWindow 獲得活動窗口的句柄
GetCapture 獲得一個窗口的句柄,這個窗口位于當前輸入線程,且擁有鼠標捕獲(鼠標活動由它接收)
GetClassInfo 取得WNDCLASS架構(或WNDCLASSEX架構)的一個副本,架構中包含了與指定類有關的訊息
GetClassLong 取得窗口類的一個Long變量條目
GetClassName 為指定的窗口取得類名
GetClassWord 為窗口類取得一個整數變量
GetClientRect 返回指定窗口客戶區矩形的大小
GetDesktopWindow 獲得代表整個螢幕的一個窗口(桌面窗口)句柄
GetFocus 獲得擁有輸入焦點的窗口的句柄
GetForegroundWindow 獲得前台窗口的句柄
GetLastActivePopup 獲得在一個給定父窗口中最近激活過的彈出式窗口的句柄
GetParent 判斷指定窗口的父窗口
GetTopWindow 搜索內部窗口列表,尋找隸屬于指定窗口的頭一個窗口的句柄
GetUpdateRect 獲得一個矩形,它描敘了指定窗口中需要更新的那一部分
GetWindow 獲得一個窗口的句柄,該窗口與某源窗口有特定的關係
GetWindowContextHelpId 取得與窗口關聯在一起的幫助場景ID
GetWindowLong 從指定窗口的架構中取得訊息
GetWindowPlacement 獲得指定窗口的狀態及位置訊息
GetWindowRect 獲得整個窗口的範圍矩形,窗口的邊框、標題欄、滾動條及菜單等都在這個矩形內
GetWindowText 取得一個窗體的標題(caption)文字,或者一個控件的內容
GetWindowTextLength 調查窗口標題文字或控件內容的長短
GetWindowWord 獲得指定窗口架構的訊息
InflateRect 增大或減小一個矩形的大小
IntersectRect 這個函數在lpDestRect裡載入一個矩形,它是lpSrc1Rect與lpSrc2Rect兩個矩形的交集
InvalidateRect 屏蔽一個窗口客戶區的全部或部分區域
IsChild 判斷一個窗口是否為另一窗口的子或隸屬窗口
IsIconic 判斷窗口是否已最小化
IsRectEmpty 判斷一個矩形是否為空
IsWindow 判斷一個窗口句柄是否有效
IsWindowEnabled 判斷窗口是否處于活動狀態
IsWindowUnicode 判斷一個窗口是否為Unicode窗口。這意味著窗口為所有基于文本的消息都接收Unicode文字
IsWindowVisible 判斷窗口是否可見
IsZoomed 判斷窗口是否最大化
LockWindowUpdate 鎖定指定窗口,禁止它更新
MapWindowPoints 將一個窗口客戶區坐標的點轉換到另一窗口的客戶區坐標系統
MoveWindow 改變指定窗口的位置和大小
OffsetRect 透過應用一個指定的偏移,從而讓矩形移動起來
OpenIcon 恢復一個最小化的程式,並將其激活
PtInRect 判斷指定的點是否位于矩形內部
RedrawWindow 重畫全部或部分窗口
ReleaseCapture 為當前的應用程式釋放鼠標捕獲
ScreenToClient 判斷螢幕上一個指定點的客戶區坐標
ScrollWindow 滾動窗口客戶區的全部或一部分
ScrollWindowEx 根據附加的選項,滾動窗口客戶區的全部或部分
SetActiveWindow 激活指定的窗口
SetCapture 將鼠標捕獲設置到指定的窗口
SetClassLong 為窗口類設置一個Long變量條目
SetClassWord 為窗口類設置一個條目
SetFocusAPI 將輸入焦點設到指定的窗口。如有必要,會激活窗口
SetForegroundWindow 將窗口設為系統的前台窗口
SetParent 指定一個窗口的新父
SetRect 設置指定矩形的內容
SetRectEmpty 將矩形設為一個空矩形
SetWindowContextHelpId 為指定的窗口設置幫助場景(上下文)ID
SetWindowLong 在窗口架構中為指定的窗口設置訊息
SetWindowPlacement 設置窗口狀態和位置訊息
SetWindowPos 為窗口指定一個新位置和狀態
SetWindowText 設置窗口的標題文字或控件的內容
SetWindowWord 在窗口架構中為指定的窗口設置訊息
ShowOwnedPopups 顯示或隱藏由指定窗口所有的全部彈出式窗口
ShowWindow 控制窗口的可見性
ShowWindowAsync 與ShowWindow相似
SubtractRect 裝載矩形lprcDst,它是在矩形lprcSrc1中減去lprcSrc2得到的結果
TileWindows 以平鋪順序排列窗口
UnionRect 裝載一個lpDestRect目標矩形,它是lpSrc1Rect和lpSrc2Rect聯合起來的結果
UpdateWindow 強製立即更新窗口
ValidateRect 校驗窗口的全部或部分客戶區
WindowFromPoint 返回包含了指定點的窗口的句柄。忽略屏蔽、隱藏以及透明窗口
正文完
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(843)

  • 個人分類:轉錄文件
▲top
  • 5月 24 週二 200512:42
  • [轉錄] Short Message Serives (SMS) Library


BitLevelSMS - Short Message Serives (SMS) Library - Send/Receive SMS (via serial port) for GSM phones (Siemens,Nokia,others)
BitLevelSMS software library provides a PC-based user application with access to a mobile phone's Short Message Service (SMS) functionality over serial port, according to ETSI standards: GSM 07.05 (ETS 300 585) "Use of Data Terminal Equipment - Data Circuit terminating; Equipment (DTE - DCE) interface for Short Message Service (SMS) and Cell Broadcast Service (CBS)" and GSM 03.40. "Technical Realization of Short Message Service - Point-to-Point".
BitLevelSMS allows the user to: send and receive SMS messages in PDU mode on many GSM mobile phones, including Siemens C35, S25, ME45, Nokia 6610 and others. Interfaces to serial ports COM1-COM8. Supports SEND - RECEIVE - DELETE functions. Decodes sender number and service centre timestamp.
Free demo available: http://www.bitleveltechnology.com/blsms.htm
Operating Systems
PC 32-bit Windows
Compilers
Visual C++
Added : 2003-05-13 Amended: 2003-05-13 Licensing : Demo
Product web site
Contact us about this product.
Submitted by:fromtrumph@bitleveltechnology.com
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(25)

  • 個人分類:轉錄文件
▲top
  • 4月 05 週二 200506:47
  • bbs看到的 有關穿衣研究

利害,這樣還可以跟論文研究扯上關係
=============
: 別學來學去了
: 雜誌上的人和路人甲又不是你
: 她們怎有可能真的讓你學到什麼東西適合你?
: 就算是有一項搭配不錯
: 那你又從和得知還有哪些方式適合你?
: 每個人適合的顏色、風格、款式都不同
: 找對方向比漫無目的看雜誌實在多了
: : 這個我也試過~~而且挺好玩的
不
要學
所有學問都是從模仿開始
比如說碩士論文
一定先上網亂看,什麼題目自己覺得可以做
然後收集相關論文
再來讀透別人的論文
模仿,學習,之後去想為他的缺點在哪
如何改進
最後研發自己的學問
穿衣服也是
要模仿,揣摩,再去發現自我,然後改他人的,去適合自己
再去研發,創新
就是因為不知道什麼適合自己
所以要先漫無目的去copy去發掘
最後改進
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(28)

  • 個人分類:轉錄文件
▲top
  • 3月 18 週五 200506:48
  • [轉錄]ADPCM

[轉錄]
一、話說從頭
ADPCM是Adaptive Differential Pulse Code Modulation的簡寫
一般我們在聽的CD,以及常見的wav檔,都是用PCM的方式來把聲音數位化
那麼,PCM跟ADPCM有什麼差別呢?
其實說穿了也沒什麼,都是當初的先烈(!)前輩們所想出來,減少資料大小的辦法
二、何謂DPCM
要講ADPCM之前,我們先來看看DPCM是什麼
D=Differential,Differential這個字在這邊是"差",相差多少的意思
因此,顧名思義…
假設某段聲音的PCM編碼是 250,268,269,241,這樣子會花掉12個數字的儲存空間
那麼這段聲音改用DPCM會是250,+18,+19,-9,這樣子就只花8個數字的儲存空間
所以,DPCM是PCM的紀錄方式的改良,用較少的bit數記錄一樣的東西
而250,+18,+19,-10經由反推可以得到和PCM一樣的數字,所以DPCM是無失真的壓縮
三、從DPCM看ADPCM
但是這樣子能壓縮掉的東西很有限,所以我們需要ADPCM
A=Adaptive,Adaptive這個字是適應性的意思(英文教學時間@_@)
承接上面的例子,當PCM是250,268,269,241、DPCM是250,+18,+19,-9時
250,+18,+19,-10可以進一步簡化成250,(+9,+9,-5)*2←這個就是ADPCM的編碼
那麼可以發現,250,(+9,+9,-4)*2只要花6個數字的儲存空間,比DPCM更少
而250,(+9,+9,-4)*2反推回去後,得到250,+18,+18,-8,跟原來的不一樣了
所以ADPCM是失真性的壓縮
實際上,編碼器執行壓縮的工作時,會考慮前後波形的變化,選擇簡化所使用的數字,
比如上面的那個*2可能改為*5,這就是"Adaptive 適應性"的意義所在
再看看上面的例子,250,268,269,241->250,(+9,+9,-4)*2
想像一個有所變化的聲波,我們只記錄某個時間點,之後的波與那個時間點的差值
假如差值大過我們能省略的,那麼就再重新設立一個開始點
如此一來,我們就不需要用很多很長的數字來描述一段聲音的波形
因此,音樂CD需要用16個bits(-32768~+32767的數字範圍),才能記錄的聲音波形變化
經過ADPCM的簡化,就只需要4個bits(-8~+7的數字範圍)就可以記錄(*)
所以,ADPCM的壓縮比一般當作1:4,比MP3常用的1:10~1:12壓縮比要高一些
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(1) 人氣(7,353)

  • 個人分類:轉錄文件
▲top
  • 2月 25 週五 200505:49
  • [轉錄]MFC架構下的DirectX 8.0


作者Blog︰http://blog.csdn.net/EA/
=======================================
1、MFC框架
  (DX8MFC)
  這裡的MFC框架指的是一個符合遊戲開發應用的框架,當然你也可以寫一個符合你要求的MFC框架。如果你對MF
C比較熟悉的話可以直接從第二章開始閱讀。本框架是以後幾個例子的基礎,如果你對MFC不是很了解的話,就要認
真閱讀本章,以求對這個MFC框架有一個深入的了解。
  框架中包括兩個類︰
  CDX8MFCApp類和CFrameWin類,CDX8MFCApp類是應用程式類,CFrameWin類是框架的主類,以後我們的大部分代
碼都是從這裡擴展的。首先來看一看CDX8MFCApp類,它包括CDX8MFCApp()、ExitInstance()、InitInstance()、On
Idle(LONG lCount)等成員函數和一個Game對象。
  InitInstance()成員函數在程式初始化時就被調用,在這裡我建立了一個窗口︰
  ExitInstance()成員函數在程式終止時被調用,在這裡我們釋放一些對象和指針︰
  OnIdle(LONG lCount)成員函數會在沒有Windows消息要處理的時候被調用,也就是說OnIdle()成員函數會不斷
的被調用,這正好被我們用作遊戲循環。
  BOOL CDX8MFCApp::InitInstance()
  {
   // The one and only window has been initialized, so show and update it.
   m_pMainWnd = new CFrameWin();
   m_pMainWnd->ShowWindow(m_nCmdShow);
   m_pMainWnd->UpdateWindow();
   Game = (CFrameWin*) m_pMainWnd;
   Game->Init();
   return TRUE;
  }
  ExitInstance()成員函數在程式終止時被調用,在這裡我們釋放一些對象和指針︰
  int CDX8MFCApp::ExitInstance()
  {
   // TODO: Add your specialized code here and/or call the base class
   Game->End();
   delete Game;
   return CWinApp::ExitInstance();
  }
  OnIdle(LONG lCount)成員函數會在沒有Windows消息要處理的時候被調用,也就是說OnIdle()成員函數會不斷
的被調用,這正好被我們用作遊戲循環。
  BOOL CDX8MFCApp::OnIdle(LONG lCount)
  {
   // TODO: Add your specialized code here and/or call the base class
   if(Game->window_active==TRUE)
    {
     Game->Active();
     Game->window_active=FALSE;
    }
   Game->Go();
   return TRUE;
  }
  Game對象是一個CFrameWin類指針,我們在InitInstance()成員函數中創建了一個CFrameWin對象並把CFrameWi
n對象的指針值賦給Game。下面我們來看一看CFrameWin類, 它包括Active()、End()、Go()、Init()、Update()等
成員函數。
  Init()成員函數,你可以在這裡做一些自己的初始化。回顧CDX8MFCApp類的InitInstance()成員函數可知,在
完成窗口初始化后InitInstance()成員函數裡就調用了Game->Init(),也就是說Init()在窗口初始化后被調用。
  void CFrameWin::Init()
  {
   AfxMessageBox("Init");
  }
  Go()成員函數會不斷的被循環調用,它又調用了Update()和DestroyWindow()。Update()用于更新窗口,調用D
estroyWindow()則會結束應用程式。如果你把DestroyWindow()語句刪除掉,程式會不斷的循環。
  void CFrameWin::Go() // Game循環
  {
   AfxMessageBox("Go");
   Update();
   DestroyWindow();
  }
  Active()成員函數會在應用程式被擊活的時候被調用。
  void CFrameWin::Active() //窗口被激活
  {
   TRACE("Active");
   AfxMessageBox("Active");
  }
  這個程式並不做任何事,只是一個MFC框架。
2、初始化DirectX
  (DX8MFC1)
  本例將以第一章的MFC框架為基礎對CFrameWin類進行擴展。主要加入了DrawScene()、InitDirect3D(HWND hwn
d)和ShutdownDirect3D()三個函數。
  InitDirect3D(HWND hwnd)函數對Direct3D進行初始化︰
  HRESULT CFrameWin::InitDirect3D(HWND hwnd)
  {
   pID3D = Direct3DCreate8(D3D_SDK_VERSION);
   HRESULT hr;
   do
    {
     // we need the display mode so we can get
     // the properties of our back buffer
     D3DDISPLAYMODE d3ddm;
     hr = pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
     if(FAILED(hr))
      break;
     D3DPRESENT_PARAMETERS present;
     ZeroMemory(&present, sizeof(present));
     present.SwapEffect = D3DSWAPEFFECT_COPY;
     present.Windowed = TRUE;
     present.BackBufferFormat = d3ddm.Format;
     hr = pID3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
                  D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice);
     if(FAILED(hr))
      break;
     // we do our own coloring, so disable lighting
     hr = pID3DDevice->SetRenderState(D3DRS_LIGHTING , FALSE);
     }
   while(0);
   return hr;
  }
  IDirect3D是我們首先要用到的界面,你可以這樣寫︰
  IDirect3D8 * pID3D = Direct3Dcreate8(D3D_SDK_VERSION);
  在你使用pID3D以前,請檢查pID3D是否為非空。你下一步通常是創建D3D設備,但在創建D3D設備之前你要調用
GetAdapterDisplayMode方法取得必須的訊息︰
  D3DDISPLAYMODE d3ddm; pID3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
  接下來是取得當前顯示模式參數。下面的參數是Surface格式。你可以用這些參數來創建一個D3DPRESENT_PARA
METERS架構︰
  D3DPRESENT_PARAMETERS present;
  ZeroMemory(&present, sizeof(present));
  present.SwapEffect = D3DSWAPEFFECT_COPY;
  present.Windowed = TRUE;
  present.BackBufferFormat = d3ddm.Format;
  D3DPRESENT_PARAMETERS描述了顯示器Surface的訊息,交換機製的類型,應用程式是窗口的還是全屏模式等信
息。在本例中, Surface是以拷貝方法代替頁面翻轉的,因為它是一個窗口模式的應用程式。把后台表面設置成與
當前顯示模式相匹配的格式,一個準備顯示的Surface可以Draw在后台表面上。
  現下你可以創建一個IDirect3DDevice8界面了︰
  pID3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
            D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice);
  這個函數有六個參數,幸運的是沒有一個是很複雜的。D3DADAPTER_DEFAULT告訴Direct3D使用主顯示器,只有
當你使用多顯示器時才是必須的。你可以使用一個數值來指定另外一個顯示器。調用IDirect3D的GetAdapterCount
將返回系統的適配器數目。
  第二個參數,D3DDEVTYPE_HAL,告訴Direct3D使用硬體加速。其它選項包括D3DDEVTYPE_REF和D3DDEVTYPE_SW,
通常你都會希望使用硬體加速的,但有時侯你可能會使用軟體加速進行測試。指定窗口取得焦點。如果是全屏應用
程式,你需要一個最頂層窗口。 D3DCREATE_SOFTWARE_VERTEXPROCESSING指定頂點處理類型。你也可以使用硬體加
速或是聯合類型,我不使用硬體加速為的是廣泛的兼容性。如果你想支持T&L, 則你必須使用硬體加速。最後兩個
參數很簡單,一個是你以前建立的,而pID3Ddevice是你現下要創建的IDirect3DDevice8界面。如果方法返回D3DER
R_NOTAVAILABLE,則你寫的參數是正確的,但你的設備不支持你指定的參數。
  最完美的是這個方法自動為你創建后台緩沖(back buffers)和深度緩沖(depth buffers) 。剪裁(Clippi
ng)作為后台表面(backface culling)被自動激活。燈光也被自動激活了,直到你定義頂點顏色之前,你可以禁
止使用燈光︰
  pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
  // DrawScene() 函數
  HRESULT CFrameWin::DrawScene()
  {
   HRESULT hr;
   do
    {
     // clear back buffer
     hr = pID3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0,63,0,0), 0, 0);
     if(FAILED(hr))
      break;
     // start drawing
     hr = pID3DDevice->BeginScene();
     if(FAILED(hr))
      break;
     // Put all drawing code here
     hr = pID3DDevice->EndScene();
     if(FAILED(hr))
      break;
     // flip back buffer to front
     hr = pID3DDevice->Present(NULL, NULL, NULL, NULL);
    }
   while(0);
   return hr;
   }
  Clear會填充你指定的緩沖區。你可以填充Z緩沖區、后台緩沖區或摸板緩沖區(stencil buffer)。在這個例
子中你將用綠色填充后台緩沖區。所以,我們設定D3DCLEAR_TARGET標誌和綠色。 在本例中BeginScene和EndScene
並沒有做什麼,但在以後的例子中我們會用到它的。這兩個函數是畫圖元時的例行公事代碼,這個函數不斷的翻轉
后台表面。我們可以不斷的在后台表面畫一些東西,然後把后台表面翻轉到前台表面。
  // ShutdownDirect3D() 函數
  void CFrameWin::ShutdownDirect3D()
  {
   HELPER_RELEASE(pTexture);
   HELPER_RELEASE(pIndexBuffer);
   HELPER_RELEASE(pStreamData);
   HELPER_RELEASE(pID3DDevice);
   HELPER_RELEASE(pID3D);
  }
  ShutdownDirect3D釋放所有的界面。將來你可能要加入額外的代碼來關閉Direct3D界面,但現下已經夠了。如
果你營運程式,你將得到一個綠色背景的窗口。你可以按“ESC”鍵來退出應用程式。
3、畫三角形
  (DX8MFC2)
  定義你的頂點格式,Direct3D引入了一種可變形頂點格式(flexible vertex format)(FVF)的概念。在FVF
中,你定義一個架構其中包括所需要的頂點組成部分。這個架構會隨著你的程式而改變,但在這裡你將初步把它定
義成這個樣子︰
  struct MYVERTEX
  {
   FLOAT x, y, z; // The transformed position
   FLOAT rhw; // 1.0 (reciprocal of homogeneous w)
   DWORD color; // The vertex color
  };
  示例的開始定義了一個頂點架構,頂點的名稱,和每一個三角形的頂點。在你的InitDirect3D函數中,你必須
創建一個頂點緩沖區︰
  int num_elems = sizeof(vertices) / sizeof(vertices[0]);
  pID3DDevice->CreateVertexBuffer(sizeof(MYVERTEX) * num_elems,
                  D3DUSAGE_WRITEONLY,
                  D3DFVF_XYZRHW|D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &pStreamData);
  函數的第一個參數是頂點架構的位元組大小。在應用程式還不能讀取頂點之前,傳一個D3DUSAGE_WRITEONLY標記
給它。這裡可以有不同的標記來指定如何處理你的頂點,但現下你可以確信Direct3D已經能正確的工作了。下一步
,指定我們用的是什麼FVF格式。當你還沒有使用坐標系預轉換之前,指定為D3DFVF_XYZRHW標記。以後你使用自己
的矩陣坐標系轉換時,把它改成D3DFVF_XYZ。D3DFVF_DIFFUSE告訴Direct3D,我們將為每一個頂點指定顏色。
  D3DPOOL_DEFAULT指定內存的管理模式。最後一個參數是頂點緩沖區的指針, 在例子1中你已經定義了它,但
並沒有用上。 如果你不向頂點緩沖區填入有用數據的話,頂點緩沖區是沒有用的︰
  MYVERTEX *v;
  pStreamData->Lock(0, 0, (BYTE**)&v, 0);
  for(int ii = 0; ii < num_elems; ii++)
  {
   v[ii].x = vertices[ii].x;
   v[ii].y = vertices[ii].y;
   v[ii].z = vertices[ii].z;
   v[ii].rhw = vertices[ii].rhw;
   v[ii].color = vertices[ii].color;
  }
  pStreamData->Unlock();
  這是不難理解的,Lock返回一個你想寫入頂點數據的指針。下一步你從你的頂點陣列中拷貝數據。然後,反還
這個指針。這一對的調用可以告訴Direct3D你的FVF格式, 並設定頂點陣列為當前的活動頂點陣列。(你可以有多
個頂點陣列)。
  pID3DDevice->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
  pID3DDevice->SetStreamSource(0, pStreamData, sizeof(MYVERTEX));
  SetVertexShader告訴Direct3D使用與CreateVertexBuffer同樣的格式。
  SetStreamSource告訴Direct3D使用pStreamData作為當前頂點陣列,並取得所有元素的大小。
  你現下可以加入畫三角形的代碼了。在DrawScene()的BeginScene和EndScene之間加入如下代碼︰
  int num_elems = sizeof(vertices) / sizeof(vertices[0]);
  pID3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, num_elems / 3);
  D3DPT_TRIANGLELIST標記將命令Direct3D畫不連續的三角形。你指定從索引的第0個頂點開始, 指定所要畫的
三角形數目。如果正確的話,你會看到一個三角形畫在先前的綠色背景窗口上。
4、畫索引三角形
  (DX8MFC3)
  上一章的畫三角形模式營運效率是較低的,而實際上我們都會使用DrawIndexedPrimitive()而不是DrawPrimit
ive()。想一想,如果要畫兩個相連的三角形,共有四個頂點。用DrawIndexedPrimitive()畫要畫四個頂點,而用D
rawPrimitive()畫則要畫六個頂點。
  如果你可以頂點建立索引,你就可以用DrawIndexedPrimitive()畫三角形了。我們可以為一個三角形建立這樣
的索引︰
  WORD indices[] = { 0, 1, 2 };
  它表示三角形中,第一個頂點對應于頂點陣列的第0個頂點;三角形中,第二個頂點對應于頂點陣列的第1個頂
點;三角形中,第三個頂點對應于頂點陣列的第2個頂點; 要畫索引三角形,首先要建立索引緩沖︰
  num_elems = sizeof(indices) / sizeof(indices[0]);
  pID3DDevice->CreateIndexBuffer(sizeof(WORD) * num_elems,
                  D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
                  D3DPOOL_DEFAULT, &pIndexBuffer);
  第二步是用頂點填充這個索引緩沖︰
  WORD *pIndex;
  pIndexBuffer->Lock(0, 0, (BYTE **)&pIndex, 0);
  for(ii = 0; ii < num_elems; ii++)
  {
   pIndex[ii] = indices[ii];
  }
  pIndexBuffer->Unlock();
  設定索引緩沖︰
  pID3DDevice->SetIndices(pIndexBuffer, 0);
  把DrawScene()的相應的pID3DDevice->DrawPrimitive(...)換成︰
  pID3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, sizeof(indices) / sizeof(indices[0]),
                    0, sizeof(indices) / sizeof(indices[0]) / 3);
  營運程式的到的還是一個三角形。
5、加入帖圖
  (DX8MFC4)
  首先,在MYVERTEX架構中加入帖圖坐標系tu和tv,並給頂點陣列賦以適當的值。
  下一步,設置你的帖圖︰
  D3DXCreateTextureFromFile(pID3DDevice, "dx5_logo.bmp", &pTexture);
  pID3DDevice->SetTexture(0, pTexture);
  其中的“dx5_logo.bmp”指的是帖圖文件,你可以用其他的文件代替它,營運程式你會看到一個帶帖圖的三角
形。
6、帖圖立方體
  (DX8MFC5)
  現下樣我們來進入三維的世界吧﹗這裡你要啟用Z緩沖(z-buffer), 設置立方體的材質,世界坐標系和投影坐
標系。啟用Z緩沖(z-buffer),你要在D3DPRESENT_PARAMETERS架構中加入︰
  present.EnableAutoDepthStencil = TRUE;
  present.AutoDepthStencilFormat = D3DFMT_D16;
  這裡告訴DirectX8使用16位的Z緩沖,下一步︰
  pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
  到這裡Z緩沖已經設置完成。最後你還要在DrawScene()中調用清除Z緩沖內容的代碼︰
  pID3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
           D3DCOLOR_RGBA(0,63,0,0), 1.0, 0);
  // MYVERTEX架構改成︰
  struct MYVERTEX
  {
   FLOAT x, y, z; // The transformed position
   DWORD color; // The vertex color
   FLOAT tu, tv; // Texture coordinates
  };
  在InitDirect3D()也作了相應改動,具體可見源代碼。Direct3D中有多種矩陣,在這裡只使用其中的三個︰世
界、視圖和投影矩陣。世界矩陣變換會把正方體放在世界坐標系中,視圖矩陣變換把正方體放在可視空間內,投影
矩陣使正方體看起來有深度感。BuildMatrices()函數將建立這三個矩陣︰
  void CFrameWin::BuildMatrices()
  {
   D3DXMATRIX matrix;
   D3DXMatrixRotationY(&matrix, timeGetTime() / 1000.0f);
   pID3DDevice->SetTransform(D3DTS_WORLD, &matrix);
   D3DXMatrixLookAtLH(&matrix,
             &D3DXVECTOR3(0.0f, 3.0f, -5.0f), // 攝像機的空間位置
             &D3DXVECTOR3(0.0f, 0.0f, 0.0f), // 攝象機觀察點
             &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); // 攝象機向上方向矢量
   pID3DDevice->SetTransform(D3DTS_VIEW, &matrix); // 設置我們的平截面為45度角
   D3DXMatrixPerspectiveFovLH(&matrix, D3DX_PI / 4, 4.0f / 3.0f, 1.0f, 100.0f);
   pID3DDevice->SetTransform(D3DTS_PROJECTION, &matrix);
  }
  營運本章的例子你將看到一個旋轉的正方體。
  你可以從gamedev.363.net下載本文所有例子的源程式,或透過E-Mail向本文作者索取。
作者Blog︰http://blog.csdn.net/EA/
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(122)

  • 個人分類:轉錄文件
▲top
  • 2月 25 週五 200505:45
  • [轉錄]高級網路掃描技術

Scan,是一切入侵的基礎,掃描探測一台主機包括是為了確定主機是否活動、主機系統、正在使用哪些端口、提供了哪些服務、相關服務的軟體版本等等,對這些內容的探測就是為了"對症下藥"。對主機的探測工具非常多,比如大名鼎鼎的nmap、netcat、superscan,以及國內的X-Scanner等等。
ICMP協議──PING是最常用的,也是最簡單的探測手段,用來判斷目標是否活動。實際上Ping是向目標發送一個要求回顯(Type = 8)的ICMP數據報,當主機得到請求后,再返回一個回顯(Type = 0)數據報。而且Ping 程式一般是直接實現下系統內核中的,而不是一個用戶進程。Ping是最基本的探測手段,Ping Sweep(Ping掃射)就是對一個網段進行大範圍的Ping,由此確定這個網段的網路運作情況,比如著名的fping工具就是進行Ping掃射的。
不過現下連基本的個人防火牆都對Ping做了限制,這個也太基本了。如果透過防火牆,如何獲得最理想的目標圖,也是很多人整天思考的問題。我們這裡介紹的一些掃描技術就是要儘可能地繞過一些安全防護設備,並且盡量保護自己,同時達到我們需要的目的。
  一、高級ICMP掃描技術
  Ping就是利用ICMP協議走的,高級的ICMP掃描技術主要是利用ICMP協議最基本的用途︰報錯。根據網路協議,如果按照協議出現了錯誤,那么接收端將產生一個ICMP的錯誤報文。這些錯誤報文並不是主動發送的,而是由於錯誤,根據協議自動產生。
  當IP數據報出現checksum和版本的錯誤的時候,目標主機將拋棄這個數據報,如果是checksum出現錯誤,那么路由器就直接丟棄這個數據報了。有些主機比如AIX、HP-UX等,是不會發送ICMP的Unreachable數據報的。
  我們利用下面這些特性︰
  1、向目標主機發送一個只有IP頭的IP數據包,目標將返回Destination Unreachable的ICMP錯誤報文。
  2、向目標主機發送一個壞IP數據報,比如,不正確的IP頭長度,目標主機將返回Parameter Problem的ICMP錯誤報文。
  3、當數據包分片但是,卻沒有給接收端足夠的分片,接收端分片組裝超時會發送分片組裝超時的ICMP數據報。
  向目標主機發送一個IP數據報,但是協議項是錯誤的,比如協議項不可用,那么目標將返回Destination Unreachable的ICMP報文,但是如果是在目標主機前有一個防火牆或者一個其他的過濾裝置,可能過濾掉提出的要求,從而接收不到任何回應。可以使用一個非常大的協議數字來作為IP頭部的協議內容,而且這個協議數字至少在今天還沒有被使用,應該主機一定會返回Unreachable,如果沒有Unreachable的ICMP數據報返回錯誤提示,那么就說明被防火牆或者其他設備過濾了,我們也可以用這個辦法來探測是否有防火牆或者其他過濾設備存在。
  利用IP的協議項來探測主機正在使用哪些協議,我們可以把IP頭的協議項改變,因為是8位的,有256種可能。透過目標返回的ICMP錯誤報文,來作判斷哪些協議在使用。如果返回Destination Unreachable,那么主機是沒有使用這個協議的,相反,如果什麼都沒有返回的話,主機可能使用這個協議,但是也可能是防火牆等過濾掉了。NMAP的IP Protocol scan也就是利用這個原理。
  利用IP分片造成組裝超時ICMP錯誤消息,同樣可以來達到我們的探測目的。當主機接收到丟失分片的數據報,並且在一定時間內沒有接收到丟失的數據報,就會丟棄整個包,並且發送ICMP分片組裝超時錯誤給原發送端。我們可以利用這個特性製造分片的數據包,然後等待ICMP組裝超時錯誤消息。可以對UDP分片,也可以對TCP甚至ICMP數據包進行分片,只要不讓目標主機獲得完整的數據包就行了,當然,對于UDP這種非連接的不可靠協議來說,如果我們沒有接收到超時錯誤的ICMP返回報,也有可能時由於線路或者其他問題在傳輸過程中丟失了。
  我們能夠利用上面這些特性來得到防火牆的ACL(access list),甚至用這些特性來獲得整個網路拓撲架構。如果我們不能從目標得到Unreachable報文或者分片組裝超時錯誤報文,可以作下面的判斷︰
  1、防火牆過濾了我們發送的協議類型
  2、防火牆過濾了我們指定的端口
  3、防火牆阻塞ICMP的Destination Unreachable或者Protocol Unreachable錯誤消息。
  4、防火牆對我們指定的主機進行了ICMP錯誤報文的阻塞。
  二、高級TCP掃描技術
  最基本的利用TCP掃描就是使用connect(),這個很容易實現,如果目標主機能夠connect,就說明一個相應的端口打開。不過,這也是最原始和最先被防護工具拒絕的一種。
  在高級的TCP掃描技術中主要利用TCP連接的三次握手特性和TCP數據頭中的標誌位來進行,也就是所謂的半開掃描。
  先認識一下TCP數據報頭的這六個標誌位。
  URG︰(Urgent Pointer field significant)緊急指針。用到的時候值為1,用來處理避免TCP數據流中斷
  ACK︰(Acknowledgment field significant)置1時表示確認號(Acknowledgment Number)為合法,為0的時候表示數據段不包含確認訊息,確認號被忽略。
  PSH︰(Push Function),PUSH標誌的數據,置1時請求的數據段在接收方得到后就可直接送到應用程式,而不必等到緩沖區滿時才傳送。
  RST︰(Reset the connection)用于複位因某種原因引起出現的錯誤連接,也用來拒絕非法數據和請求。如果接收到RST位時候,通常發生了某些錯誤。
  SYN︰(Synchronize sequence numbers)用來建立連接,在連接請求中,SYN=1,ACK=0,連接附應時, SYN=1,ACK=1。即,SYN和ACK來區分Connection Request和Connection Accepted。
  FIN︰(No more data from sender)用來釋放連接,表明發送方已經沒有數據發送了。
  TCP協議連接的三次握手過程是這樣的︰
  首先客戶端(請求方)在連接請求中,發送SYN=1,ACK=0的TCP數據包給伺服器端(接收請求端),表示要求同伺服器端建立一個連接;然後如果伺服器端附應這個連接,就返回一個SYN=1,ACK=1的數據報給客戶端,表示伺服器端同意這個連接,並要求客戶端確認;最後客戶端就再發送SYN=0,ACK=1的數據包給伺服器端,表示確認建立連接。
  我們就利用這些標誌位和TCP協議連接的三次握手特性來進行掃描探測。
  SYN 掃描
  這種掃描模式也被稱為"半打開" 掃描,因為利用了TCP協議連接的第一步,並且沒有建立一個完整的TCP連接。實現辦法是向遠端主機某端口發送一個只有SYN標誌位的TCP數據報,如果主機回饋一個SYN || ACK數據包,那么,這個主機正在監聽該端口,如果回饋的是RST數據包,說明,主機沒有監聽該端口。在X-Scanner 上就有SYN的選擇項。
  ACK 掃描
  發送一個只有ACK標誌的TCP數據報給主機,如果主機回饋一個TCP RST數據報來,那么這個主機是存在的。也可以透過這種技術來確定對方防火牆是否是簡單的分組過濾,還是一個基于狀態的防火牆。
  FIN
  對某端口發送一個TCP FIN數據報給遠端主機。如果主機沒有任何回饋,那么這個主機是存在的,而且正在監聽這個端口;主機回饋一個TCP RST回來,那么說明該主機是存在的,但是沒有監聽這個端口。
  NULL
  即發送一個沒有任何標誌位的TCP包,根據RFC793,如果目標主機的相應端口是關閉的話,應該發送回一個RST數據包。
  FIN+URG+PUSH
  向目標主機發送一個Fin、URG和PUSH分組,根據RFC793,如果目標主機的相應端口是關閉的,那么應該返回一個RST標誌。
  上面這些辦法可以繞過一些防火牆,從而得到防火牆后面的主機訊息,當然,是在不被欺騙的情況下的。這些方法還有一個好處就是比較難于被記錄,有的辦法即使在用netstat命令上也根本顯示不出來,而且一般的安全防護設備也根本不記錄這些內容,這樣能夠更好地隱藏自己。
三、高級UDP掃描技術
  在UDP實現的掃描中,多是了利用和ICMP進行的組合進行,這在ICMP中以及提及了。還有一些特殊的就是UDP回饋,比如SQL SERVER,對其1434端口發送‘x02'或者‘x03'就能夠探測得到其連接端口。
  下面這段程式就是一個TCP探測的例子,當然,並沒有做得完美,因為沒有接收部分,而在WIN2000下實際就是一個選擇性的SNIFFER,呵呵,大家可以使用其他的SNIFFER來實現同樣的目的。也可以改變下面的程式只發送IP包,利用ICMP特性來實現探測。
#include 〈stdio.h>;
#include 〈winsock2.h>;
#include 〈ws2tcpip.h>;
#define SOURCE_PORT 7234
#define MAX_RECEIVEBYTE 255
typedef struct ip_hdr //定義IP首部
{
unsigned char h_verlen; //4位首部長度,4位IP版本號
unsigned char tos; //8位服務類型TOS
unsigned short total_len; //16位總長度(位元組)
unsigned short ident; //16位標識
unsigned short frag_and_flags; //3位標誌位
unsigned char ttl; //8位生存時間 TTL
unsigned char proto; //8位協議 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校驗和
unsigned int sourceIP; //32位源IP位址
unsigned int destIP; //32位目的IP位址
}IPHEADER;
typedef struct tsd_hdr //定義TCP偽首部
{
unsigned long saddr; //源位址
unsigned long daddr; //到達站址
char mbz;
char ptcl; //協議類型
unsigned short tcpl; //TCP長度
}PSDHEADER;
typedef struct tcp_hdr //定義TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列號
unsigned int th_ack; //32位確認號
unsigned char th_lenres; //4位首部長度/6位保留字
unsigned char th_flag; //6位標誌位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校驗和
USHORT th_urp; //16位緊急數據偏移量
}TCPHEADER;
//CheckSum:計算校驗和的子函數
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >;1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >;>; 16) + (cksum &; 0xffff);
cksum += (cksum >;>;16);
return (USHORT)(~cksum);
}
void usage()
{
printf(";******************************************
";);
printf(";TCPPing
";);
printf("; Written by Refdom
";);
printf("; Email: refdom@263.net
";);
printf(";Useage: TCPPing.exe Target_ip Target_port
";);
printf(";*******************************************
";);
}
int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
IPHEADER ipHeader;
TCPHEADER tcpHeader;
PSDHEADER psdHeader;
char szSendBuf[60]={0};
BOOL flag;
int rect,nTimeOver;
usage();
if (argc!= 3)
{ return false; }
if (WSAStartup(MAKEWORD(2,2), &;WSAData)!=0)
{
printf(";WSAStartup Error!
";);
return false;
}
if ((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf(";Socket Setup Error!
";);
return false;
}
flag=true;
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&;flag,sizeof(flag))==SOCKET_ERROR)
{
printf(";setsockopt IP_HDRINCL error!
";);
return false;
}
nTimeOver=1000;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&;nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)
{
printf(";setsockopt SO_SNDTIMEO error!
";);
return false;
}
addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(atoi(argv[2]));
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);
//
//
//填充IP首部
ipHeader.h_verlen=(4〈〈4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr(";本地位址";);
ipHeader.destIP=inet_addr(argv[1]);
//填充TCP首部
tcpHeader.th_dport=htons(atoi(argv[2]));
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口號
tcpHeader.th_seq=htonl(0x12345678);
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/4〈〈4|0);
tcpHeader.th_flag=2; //修改這裡來實現不同的標誌位探測,2是SYN,1是FIN,16是ACK探測 等等
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;
psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));
//計算校驗和
memcpy(szSendBuf, &;psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &;tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));
memcpy(szSendBuf, &;ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &;tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));
memcpy(szSendBuf, &;ipHeader, sizeof(ipHeader));
rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),
0, (struct sockaddr*)&;addr_in, sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf(";send error!:%d
";,WSAGetLastError());
return false;
}
else
printf(";send ok!
";);
closesocket(sock);
WSACleanup();
return 0;
}
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(237)

  • 個人分類:轉錄文件
▲top
  • 2月 24 週四 200502:15
  • 未來

網路上看到的文章中有好句子
轉錄一下
未來是看得見摸得著的,她隱藏在你前面的濃霧中,經常給你這樣那樣的以外,讓你無法認情自己的方向。
你甚至不知道下一刻你會在什麼地方,雖然這一刻你還坐在電腦前面看著這篇東西。
對于未來不再有把握。雖然我知道我的方向始終沒有變過,但是我卻再沒有那種對于成功的十足的自信和把握。
也許,未來就像一座山,你在很遠的地方,能夠很清晰的看見,而離它越近,卻越難以看清。
直到有一天你忽然發現你已經到了山頂上,才知道人生是如此精彩。沒有意外的人生又怎么會是真實的呢?
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(19)

  • 個人分類:轉錄文件
▲top
  • 9月 27 週一 200406:47
  • JPEG2000簡介

資料來源:中國印刷物資商情
出處 http://www.cgan.com/science/publish/others/JPEG2000.htm
過去十年人們親眼看到了數字圖像 的存儲和傳輸的急劇變化。數字相機和便宜的掃描儀在客戶和商業方面迅速擴大了數字圖像的應用。此外,準備訪問Internet和多媒體啟動的PC(個人計算機)的低成本使數字圖像成為很多人每日生活的組成部分。
這些因素,連同彩色打印機廣泛的可用性,要求適合於印刷複製的圖像分辨率。為滿足這些要求所必需的圖像文件大小對圖像存儲和傳輸提出了重要的挑戰。因此,數字圖像壓縮實際上對成像技術的每個方面均是關鍵的,這取決於客戶、商業或科學應用水平。
目前的JPEG壓縮(因為與JPEG2000不同)基於一項決定,這項決定是JPEG委員會於1988年做出的,目的是採用與霍夫曼編碼結合的DCT(不連續正弦變換)作為其在ISO10918-1中的編碼方式,現在多部分標準的第一部分適用於靜止圖像壓縮。
DCT是一種有損耗的壓縮方式,用戶用它來定義所期望的複製質量並因此得到取決於編碼圖像實際內容的壓縮比。這是通過把轉換應用於圖像位圖獲得的,像素深度的量化在轉換中是一個參數。低質量的圖像具有有限的量化水平,結果是一個使用霍夫曼編碼的很好的壓縮比。
這種與質量有關的編碼主要好處是當同時提供多幅圖像時,它們的特點是無論在屏幕上還是在印刷時,相同水平的質量。
在選擇DCT算法的1988年,由於適用於成像的PC和工作站的能力有限,所以實現起來十分複雜。JPEG有一個困難的開端,這就在標準的不同實現之間,產生了比較隨機的互操作性。
1992年,一家美國公司的總工程師當時在JPEG委員會中,建議借助有限的色空間、算法和其他參數,特別是嚴格的文件格式規範(JFIF),提出了標準的簡化實現。這立即獲得歡迎並在市場中成了唯一的JPEG實現。
JFIF就是指今天的JPEG文件格式。然而,這種有限的工具有點過時且難以滿足高分辨率、真彩色及附加功能性的要求。
自從最初引入JPEG及JFIF以來,引入了基於使用DCT的許多附加的文件格式和壓縮技術。這些包括SPIFF(靜止圖像交換文件格式),稱為JTIP的多分辨率格式(JPEG平舖圖像錐形),及稱為Flashpix的同樣概念的較新的工具。
JPEG200
到了1995年,一般計算機的計算能力提高了,於是就可能擁有和JPEG有效硬件實現一樣快或較之更快的顯示圖像的軟件解碼器。
在1996年,JPEG委員會決定研究圖像數據的更強有力的壓縮的可能性,特別是分形和小波技術提供了新解決方案的可能性。因為這些研究的進步,好像到了2000年新標準準備好了,並選擇了JPEG2000這個名稱。
目的是創造一先進的標準化的圖像編碼系統以服務於進入下一個世紀的應用程序。目的是:
1.確定現行的標準不能產生最好質量或性能的範圍;
2.給現在未使用壓縮的市場提供可能性;
3.給成像應用程序提供開放系統方法。
不同意圖的應用程序提出了不同的要求。例如:
△Internet應用程序(環球網成像)必須在質量和分辨率上有所改進且有快的譯碼能力。
△移動式應用程序產生對錯誤彈性,低功率,及順次譯碼的要求,同時電子商務需要圖像保密性和數字水印。
△數字照相要求低的複雜性和壓縮有效性。
△硬拷貝彩色傳真,印刷及掃描要求去除或平舖處理。
△鍵入數字圖書館/檔案應用程序是元數據和內容管理的需要。
△對於遙感來說,多元件,快速編碼和有價值的編碼區域是十分主要的。
醫療應用程序不只是大部分,需要各種各樣的有損耗的和無損耗的編碼。
一項對技術要求產生了約20種建議,其中大多數基於小波技術。並測試了對於DCT編碼的增強,對於JPEG2000的要求則太多且對DCT編碼似乎不可能令他們滿意。
小波技術最終被選作JPEG2000的新的算法,具有在分辨率和質量兩方面允許可伸縮性的能力。雖然與整數篩選程序比較,小波變換的複雜性取決於篩選程序的大小和浮點的使用,但小波變換一般比現在的基於程序塊的DCT變換計算上更為複雜。作為全畫面變換,小波變換也需要比DCT更多的存儲器。
然而,基於程序行的實現可減少存儲器的需求。要注意雖然小波變換比DCT變換計算上更為複雜,但是在其複雜性由在標準預期完成時計算機的預期的計算能力得以規範化,小波變換並不比在出版最初的JPEG時DCT變換複雜。因此,JPEG委員會覺得計算機能力現在的和預期的進步減小了這些問題的影響且編碼-譯碼要求的複雜性對於小波技術的廣泛實現也不覺得像是一個障礙。
分辨率的可伸縮性意思是圖像代碼是連續的代碼流,各種水平的分辨率從代碼流中得到,作為譯代碼流達到程度的函數。(即,只譯代碼流的部分並得到某種水平的分辨率,連續譯代碼流的代碼以得到分辨率)。
同樣的圖像文件可用於不同的應用程序。注意這點很在趣:一旦壓縮,則壓縮的數據可重新排序,因此,它可以以行方式解壓縮,按大小是順次的或按分辨率是順次的。
質量不但是一個分辨率問題,而且還是一個像素深度值的量化的問題。編圖像代碼的操作人員按分辨率或質量確定可伸縮性水平。可逐步按所要求的質量,譯質量可伸縮的文件代碼,包括如果照此編碼的全部無損耗的結果。
這就可以實現一個有趣的特點:能夠使用圖像的無損耗編碼和允許下流處理以確定應用程序所要求的譯碼程度。這種能力對醫療成像和出版應用而言是相當有趣的。
標準和在哪裡繼續有效
JPEG2000系指ISO15444標準的所有部分,現在的計劃要求下列7個部分:
部分1.JPEG2000圖像編碼系統
部分2.擴充(給部分1的核心定義添加更多的特徵和完善度)
部分3.運動JPEG2000
部分4.一致性
部分5.參考軟件(目前包含Java和C實現)
部分6.復合圖像文件格式(用於文件掃描和傳真應用程序)
部分7.對部分1的最小支持(技術報告)。
到2000年度,部分1預計成為完全被認可的ISO標準。部分1定義核心壓縮技術和「最小文件格式」,部分1使用可伸縮的文件格式體系結構以及預計滿足80%市場要求的最小特徵。
部分2到部分6定義壓縮和文件格式的擴充。基本的文件格式,稱之為JP2,它是標準的任選部分,但文件格式的任何實現必須符合於標準並閱讀所有合法的JP2文件。文件含有擴充,但這些擴充並不妨礙部分1閱讀程序執行部分1的功能。這就保證了客戶的互操作性。部分2中定義的JPX文件要求擴充的閱讀程序,且目標是專門的市場。
JPEG2000代碼流,不管所用的文件格式如何對於所有應用程序而言都是強制性的。JP2文件格式是應用程序使用JPEG2000代碼流的缺省接口。
重要的是要指出壓縮和文件格式是分離的。雖然是交換使用JPEG2000壓縮的數據時大多數應用程序將使用標準文件格式中的一種,但壓縮代碼流卻可以獨立於文件格式使用。
在很多情況下,用來封裝壓縮圖像數據的文件格式是涉及互操作性時的關鍵問題。當前的JP2文件格式來源於與數字成像集團DIG2000發端的聯合行動。在這次發端中,DIG成員公司在創立JPGE委員會要考慮的文件格式建議當中與JPEG委員會合作。這項工作規定了各類普通用戶能夠使用的文件格式。它的目標是將生成使用現有的JPEG2000壓縮標準、在線圖像數據庫的軟硬件開發者及Web開發者。
已考慮到各種格式技術,範圍包括從基於TIFF的方法到基於Apple的QuickTime方法。所有這些方法都把不同水平的複雜性及輕易地使用二進制數據的特性混合在一起。最終的選擇使用部分基於Apple的QuickTime文件格式和MPEG-4文件格式的二進制容器(binarycontainet)。生成此種文件格式使用的技術包括ICC、XML、JPEG2000壓縮,及圖像元數據。
在這些之外,JPEG2000委員會考慮到很多集團希望把JPEG2000位流隱藏於另外的文件格式中。因此,問題是要在位流和JPEG2000文件格式中提供適當水平的圖像數據和元數據以滿足各種使用。
JP2文件格式規定了確定應怎樣解釋顏色的方法。部分2(JPX)將規定另外的方法及兩部分之間的方法基於複雜性的區分。在部分1中,JP2文件格式,與sRGB和灰sRGB(來自於sRGB的中性sRGB)是所有閱讀程序所要求的。此外,所有JP2閱讀程序必須支持採用合法ICC輪廓文件解釋顏色。這些輪廓文件必須符合於Three□ComponentMatrixBasedandMonochromeInputProfiles(三元素矩陣基和單色輸入輪廓文件)。這就提供了低的靈活性但高的互操作性。雖然將列舉適用於JPX文件的其他色空間,但不需要JP2閱讀程序中的支持。此外,部分2規定了專門規定之外的適合於色空間的登記過程。
JP2文件格式把文件定義為一系列的含有圖像數據或元數據(關於圖像數據的數據)的邏輯框。這就使它容易通過邏輯框分析或給文件結構添加新的邏輯框。
JP2文件的標準邏輯框是文件特徵標記,文件類型和兼容性信息,一般標題信息、彩色調色板、色空間規範、元素排序及代碼流。除了特徵標記和文件類型必須是首次及標題信息邏輯框必須在代碼流之前產生之外,不確定邏輯框次序。矢量確定的邏輯框總是在任何地方而未知的邏輯框卻被標準閱讀程序忽略。
要包括的其他特點
元數據:元數據被定義為與圖像一起進位的數據,目的是提高全局文件或含有數據的系統的值。元數據與圖像一起循環,因此與圖像內容密切相關。例如,元數據可含有以字符顯示的描述、作者的名字、創作日期、版權記載、使用條件、創作參數等。
元數據的一個應用程序是IPR(知識產權),用於信譽的作者姓名的指示,與圖像一起記入的有關利用、版權記載的權力所有人。
圖像登記
為原JPEG規定了圖像登記過程,在JPEG部分4中規定了它的操作。現正為JPEG2000考慮同樣的能力。此登記過程給簡單的標識符提供識別圖像的能力,叫做LicensePlate(特許板),它是專門的。
包括其中的是登記權限(RA),記錄請求並傳遞在JPEG中被定義為三邏輯框標識符的標識符。其結構如下:16位用於國家識別,16位用於國家內RA,32位用於40億個單獨的標識符。最近JURA(JPEG實用程序登記權限)提供此功能,它在世界傳遞RA標識符。
水印
防止圖像內容剽竊或不適當使用不是一個簡單的事。水印是一個可能的解決方法,用這種的辦法某種信息隱藏於圖像數據之內,眼睛看不見但可以探測得到,它攜帶著用於鍊接的足夠信息。現在的提案是把64位用於給圖像加水印,64位恰好是由作為LicensePlate的登記權限傳遞的標識符。水印技術仍處在發展階段,但正由JPEG2000鑒定。
使人感興趣的區域(ROI)
有很多種情況,其中圖像的某個部分即使人感興趣的區域比圖像的其他部分需要更詳細地訪問。在JPEG2000中設計了兩種訪問ROI的方法,即有源法和無源法。
在用戶任意決定圖像中高度使人感興趣的部分時使用有源ROI。這裡,整個圖像是以高分辨率存儲的;需要圖像服務器來傳遞使所選部位細節顯示所需要的代碼。
在圖像具有明顯的使人感興趣的區域時,而此區域是創作者根據JPEG2000編碼過程的可伸縮性通過額外分辨率或額外質量,加以強調的使用無源ROI。通過把一種透明區域指示符貼在圖像上顯示可獲得細節的部分,用戶就知道現有的使人感興趣的區域。
DCT,分形和小波壓縮技術
首先沒有一個簡單的解釋。數字圖像是一系列的像素值,我們可以把這一系列像素值看作是一個數值表。壓縮問題包括兩部分:編碼和譯碼。編碼包括表示在某種意義上要求較少存儲空間的數值表。譯碼是恢復接近於來自於編碼信息的數值原始組合。
有兩個方法可以用來減小數值表的大小。其一是取消某些不重要的數值;其二找到某種表示需要很少數據的數值的方法。DTC,分形和小波均是算法逼近,目的是試圖把數據變為其他的更容易允許被安全刪除的數據識別的域(頻率等)。在DCT的情況下,這是高頻率數據;在小波變換的情況下,這是高度詳細數據。分形方法以更為簡明的方法直接表示數據。通過編碼數值的壓縮表示可以進一步壓縮這些模式的輸出。量化可在表中產生很少的數值且每個數值很少的位。熵編碼分析到達有效位表示模式的數值表。頻繁發生的數值通過很少的位表示,不太經常出現的數值被確定為長的位流。
ISO/IEC/JTC1/SC29/WG1
IEC即國際電工技術委員會,它負責電工技術方面的標準,包括電子學、電磁學、磁學、電聲學、電極及電能生產及分配。ISO即國際標準化組織,它負責除電氣和電子工程之外的所有技術領域的標準,後兩個方面由IEC負責。JTC1即聯合技術委員會1號(且迄今為止唯一的聯合委員會),它向ISO和IEC報告並負責信息技術領域。JTC1的小組委員會(SC)29負責聲音、圖像、多媒體和超媒體的編碼。SC29的工作組1(WG)包括聯合照相專家組(JPEG)和聯合雙級圖像小組(JBIG)。JPEG和JBIG二者中的聯合系指兩個小組與國際電信聯盟(ITU)的聯合活動這個事實。事實上,ISO15444-1將作為ITU□T建議T.800發表,具有相同的文本。
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(167)

  • 個人分類:轉錄文件
▲top
  • 7月 25 週日 200412:57
  • linux 驅動程式開發簡介

在網路上看到的教學文章,怪不錯的
就貼上了,
作者一樣不詳
====================================================================
作需要寫了我們公司一塊網卡的Linux驅動程式。經歷一個從無到有的過程,深感技術
交流的重要。Linux作為挑戰微軟壟斷的強有力武器,日益受到大家的喜愛。真希望她能
在中國迅速成長。把程式文檔貼出來,希望和大家探討Linux技術和應用,促進Linux在
中國的普及。
Linux作業系統網路驅動程式編寫
一.Linux系統設備驅動程式概述
1.1 Linux設備驅動程式分類
1.2 編寫驅動程式的一些基本概念
二.Linux系統網路設備驅動程式
2.1 網路驅動程式的架構
2.2 網路驅動程式的基本方法
2.3 網路驅動程式中用到的數據架構
2.4 常用的系統支持
三.編寫Linux網路驅動程式中可能遇到的問題
3.1 中斷共享
3.2 硬體發送忙時的處理
3.3 流量控制(flow control)
3.4 調試
四.進一步的閱讀
五.雜項
一.Linux系統設備驅動程式概述
1.1 Linux設備驅動程式分類
Linux設備驅動程式在Linux的內核源代碼中佔有很大的比例,源代碼的長度日益增加,
主要是驅動程式的增加。在Linux內核的不斷升級過程中,驅動程式的架構還是相對穩定
。在2.0.xx到2.2.xx的變動裡,驅動程式的編寫做了一些改變,但是從2.0.xx的驅動到
2.2.xx的移植只需做少量的工作。
Linux系統的設備分為字符設備(char device),塊設備(block device)和網路設備(net
work device)三種。字符設備是指存取時沒有緩存的設備。塊設備的讀寫都有緩存來支
持,並且塊設備必須能夠隨機存取(random access),字符設備則沒有這個要求。典型的
字符設備包括鼠標,鍵盤,串行口等。塊設備主要包括硬碟軟碟設備,CD-ROM等。一個
文件系統要安裝進入作業系統必須在塊設備上。
網路設備在Linux裡做專門的處理。Linux的網路系統主要是基于BSD unix的socket機製
。在系統和驅動程式之間定義有專門的數據架構(sk_buff)進行數據的傳遞。系統裡支持
對發送數據和接收數據的緩存,提供流量控制機製,提供對多協議的支持。
1.2 編寫驅動程式的一些基本概念
無論是什麼作業系統的驅動程式,都有一些通用的概念。作業系統提供給驅動程式的支
持也大致相同。下面簡單介紹一下網路設備驅動程式的一些基本要求。
1.2.1 發送和接收
這是一個網路設備最基本的功能。一塊網卡所做的無非就是收發工作。所以驅動程式裡
要告訴系統你的發送函數在那裡,系統在有數據要發送時就會調用你的發 送程式。還有
驅動程式由於是直接操縱硬體的,所以網路硬體有數據收到最先能得到這個數據的也就
是驅動程式,它負責把這些原始數據進行必要的處理然后送給系統。這裡,作業系統必
須要提供兩個機製,一個是找到驅動程式的發送函數,一個是驅動程式把收到的數據送
給系統。
1.2.2 中斷
中斷在現代計算機架構中有重要的地位。作業系統必須提供驅動程式附應中斷的能力。
一般是把一個中斷處理程式註冊到系統中去。作業系統在硬體中斷發生后 調用驅動程式
的處理程式。Linux支持中斷的共享,即多個設備共享一個中斷。
1.2.3 時鐘
在實現驅動程式時,很多地方會用到時鐘。如某些協議裡的超時處理,沒有中斷機製的
硬體的輪詢等。作業系統應為驅動程式提供定時機製。一般是在預定的時 間過了以後回
調註冊的時鐘函數。在網路驅動程式中,如果硬體沒有中斷功能,定時器可以提供輪詢
(poll)模式對硬體進行存取。或者是實現某些協議時需要的超時重傳等。
二.Linux系統網路設備驅動程式
2.1 網路驅動程式的架構
所有的Linux網路驅動程式遵循通用的界面。設計時採用的是面向對象的方法。一個設備
就是一個對象(device 架構),它內部有自己的數據和方法。每一個設備的方法被調用時
的第一個參數都是這個設備對象本身。這樣這個方法就可以存取自身的數據(類似面向對
象程式設計時的this引用)。
一個網路設備最基本的方法有初始化、發送和接收。
------------------- ---------------------
|deliver packets | |receive packets queue|
|(dev_queue_xmit()) | |them(netif_rx()) |
------------------- ---------------------
| | /
/ | |
-------------------------------------------------------
| methods and variables(initialize,open,close,hard_xmit,|
| interrupt handler,config,resources,status...) |
-------------------------------------------------------
| | /
/ | |
----------------- ----------------------
|send to hardware | |receivce from hardware|
----------------- ----------------------
| | /
/ | |
-----------------------------------------------------
| hardware media |
-----------------------------------------------------
初始化程式完成硬體的初始化、device中變量的初始化和系統資源的申請。發送程式是
在驅動程式的上層協議層有數據要發送時自動調用的。一般驅動程式中不對發送數據進
行緩存,而是直接使用硬體的發送功能把數據發送出去。接收數據一般是透過硬體中斷
來通知的。在中斷處理程式裡,把硬體幀訊息填入一個skbuff架構中,然后調用netif_
rx()傳遞給上層處理。
2.2 網路驅動程式的基本方法
網路設備做為一個對象,提供一些方法供系統訪問。正是這些有統一界面的方法,掩蔽
了硬體的具體細節,讓系統對各種網路設備的訪問都採用統一的形式,做到硬體無關性
。
下面解釋最基本的方法。
2.2.1 初始化(initialize)
驅動程式必須有一個初始化方法。在把驅動程式載入系統的時候會調用這個初始化程式
。它做以下幾方面的工作。檢測設備。在初始化程式裡你可以根據硬體的特徵檢查硬體
是否存在,然后決定是否啟動這個驅動程式。配置和初始化硬體。在初始化程式裡你可
以完成對硬體資源的配置,比如即插即用的硬體就可以在這個時候進行配置(Linux內核
對PnP功能沒有很好的支持,可以在驅動程式裡完成這個功能)。配置或協商好硬體佔用
的資源以後,就可以向系統申請這些資源。有些資源是可以和別的設備共享的,如中斷
。有些是不能共享的,如IO、DMA。接下來你要初始化device架構中的變量。最後,你可
以讓硬體正式開始工作。
2.2.2 打開(open)
open這個方法在網路設備驅動程式裡是網路設備被激活的時候被調用(即設備狀態由dow
n-->up)。所以實際上很多在initialize中的工作可以放到這裡來做。比如資源的申請,
硬體的激活。如果dev->open返回非0(error),則硬體的狀態還是down。
open方法另一個作用是如果驅動程式做為一個模塊被裝入,則要防止模塊卸載時設備處
于打開狀態。在open方法裡要調用MOD_INC_USE_COUNT宏。
2.2.3 關閉(stop)
close方法做和open相反的工作。可以釋放某些資源以減少系統負擔。close是在設備狀
態由up轉為down時被調用的。另外如果是做為模塊裝入的驅動程式,close裡應該調用M
OD_DEC_USE_COUNT,減少設備被引用的次數,以使驅動程式可以被卸載。
另外close方法必須返回成功(0==success)。
2.2.4 發送(hard_start_xmit)
所有的網路設備驅動程式都必須有這個發送方法。在系統調用驅動程式的xmit時,發送
的數據放在一個sk_buff架構中。一般的驅動程式把數據傳給硬體發出去。也有一些特殊
的設備比如loopback把數據組成一個接收數據再回送給系統,或者dummy設備直接丟棄數
據。
如果發送成功,hard_start_xmit方法裡釋放sk_buff,返回0(發送成功)。如果設備暫時
無法處理,比如硬體忙,則返回1。這時如果dev->tbusy置為非0,則系統認為硬體忙,
要等到dev->tbusy置0以後才會再次發送。tbusy的置0任務一般由中斷完成。硬體在發送
結束后產生中斷,這時可以把tbusy置0,然后用mark_bh()調用通知系統可以再次發送。
在發送不成功的情況下,也可以不置dev->tbusy為非0,這樣系統會不斷嘗試重發。如果
hard_start_xmit發送不成功,則不要釋放sk_buff。傳送下來的sk_buff中的數據已經包
含硬體需要的幀頭。所以在發送方法裡不需要再填充硬體幀頭,數據可以直接提交給硬
件發送。sk_buff是被鎖住的(locked),確保其他程式不會存取它。
2.2.5 接收(reception)
驅動程式並不存在一個接收方法。有數據收到應該是驅動程式來通知系統的。一般設備
收到數據后都會產生一個中斷,在中斷處理程式中驅動程式申請一塊sk_buff(skb),從
硬體讀出數據放置到申請好的緩沖區裡。接下來填充sk_buff中 的一些訊息。skb->dev
= dev,判斷收到幀的協議類型,填入skb->protocol(多協 議的支持)。把指針skb->m
ac.raw指向硬體數據然后丟棄硬體幀頭(skb_pull)。還要設置skb->pkt_type,標明第二
層(鏈路層)數據類型。可以是以下類型︰
PACKET_BROADCAST : 鏈路層廣播
PACKET_MULTICAST : 鏈路層組播
PACKET_SELF : 發給自己的幀
PACKET_OTHERHOST : 發給別人的幀(監聽模式時會有這種幀)
最後調用netif_rx()把數據傳送給協議層。netif_rx()裡數據放入處理隊列然后返回,
真正的處理是在中斷返回以後,這樣可以減少中斷時間。調用netif_rx()以後,
驅動程式就不能再存取數據緩沖區skb。
2.2.6 硬體幀頭(hard_header)
硬體一般都會在上層數據發送之前加上自己的硬體幀頭,比如以太網(Ethernet)就有14
位元組的幀頭。這個幀頭是加在上層ip、ipx等數據包的前面的。驅動程式提供一個hard_
header方法,協議層(ip、ipx、arp等)在發送數據之前會調用這段程式。
硬體幀頭的長度必須填在dev->hard_header_len,這樣協議層回在數據之前保留好硬體
幀頭的空間。這樣hard_header程式只要調用skb_push然后正確填入硬體幀頭就可以了。
在協議層調用hard_header時,傳送的參數包括(2.0.xx)︰數據的sk_buff,device指針
,protocol,到達站址(daddr),源位址(saddr),數據長度(len)。數據長度不要使用s
k_buff中的參數,因為調用hard_header時數據可能還沒完全組織好。saddr是NULL的話
是使用缺省位址(default)。daddr是NULL表明協議層不知道硬體到達站址。如果hard_h
eader完全填好了硬體幀頭,則返回添加的位元組數。如果硬體幀頭中的訊息還不完全(比
如daddr為NULL,但是幀頭中需要目的硬體位址。典型的情況是以太網需要位址解析(ar
p)),則返回負位元組數。hard_header返回負數的情況下,協議層會做進一步的build he
ader的工作。目前Linux系統裡就是做arp (如果hard_header返回正,dev->arp=1,表明
不需要做arp,返回負,dev->arp=0,做arp)。
對hard_header的調用在每個協議層的處理程式裡。如ip_output。
2.2.7 位址解析(xarp)
有些網路有硬體位址(比如Ethernet),並且在發送硬體幀時需要知道目的硬體位址。這
樣就需要上層協議位址(ip、ipx)和硬體位址的對應。這個對應是透過位址解析完成的。
需要做arp的的設備在發送之前會調用驅動程式的rebuild_header方法。調用的主要參數
包括指向硬體幀頭的指針,協議層位址。如果驅動程式能夠解析硬體位址,就返回1,如
果不能,返回0。
對rebuild_header的調用在net/core/dev.c的do_dev_queue_xmit()裡。
2.2.8 參數設置和統計數據
在驅動程式裡還提供一些方法供系統對設備的參數進行設置和讀取訊息。一般只有超級
用戶(root)權限才能對設備參數進行設置。設置方法有︰
dev->set_mac_address()
當用戶調用ioctl類型為SIOCSIFHWADDR時是要設置這個設備的mac位址。一般對mac位址
的設置沒有太大意義的。
dev->set_config()
當用戶調用ioctl時類型為SIOCSIFMAP時,系統會調用驅動程式的set_config方法。用戶
會傳遞一個ifmap架構包含需要的I/O、中斷等參數。
dev->do_ioctl()
如果用戶調用ioctl時類型在SIOCDEVPRIVATE和SIOCDEVPRIVATE+15之間,系統會調用驅
動程式的這個方法。一般是設置設備的專用數據。
讀取訊息也是透過ioctl調用進行。除次之外驅動程式還可以提供一個
dev->get_stats方法,返回一個enet_statistics架構,包含發送接收的統計訊息。ioc
tl的處理在net/core/dev.c的dev_ioctl()和dev_ifsioc()裡。
linuxman@263.net
.3 網路驅動程式中用到的數據架構
最重要的是網路設備的數據架構。定義在include/linux/netdevice.h裡。它的註釋已經
足夠詳盡。
struct device
{
/*
* This is the first field of the "visible" part of this structure
* (i.e. as seen by users in the "Space.c" file). It is the name
* the interface.
*/
char *name;
/* I/O specific fields - FIXME: Merge these and struct ifmap into one */
unsigned long rmem_end; /* shmem "recv" end */
unsigned long rmem_start; /* shmem "recv" start */
unsigned long mem_end; /* shared mem end */
unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */
unsigned char irq; /* device IRQ number */
/* Low-level status flags. */
volatile unsigned char start, /* start an operation */
interrupt; /* interrupt arrived */
/* 在處理中斷時interrupt設為1,處理完清0。 */
unsigned long tbusy; /* transmitter busy must be long for
bitops */
struct device *next;
/* The device initialization function. Called only once. */
/* 指向驅動程式的初始化方法。 */
int (*init)(struct device *dev);
/* Some hardware also needs these fields, but they are not part of the
usual set specified in Space.c. */
/* 一些硬體可以在一塊板上支持多個界面,可能用到if_port。 */
unsigned char if_port; /* Selectable AUI, TP,..*/
unsigned char dma; /* DMA channel */
struct enet_statistics* (*get_stats)(struct device *dev);
/*
* This marks the end of the "visible" part of the structure. All
* fields hereafter are internal to the system, and may change at
* will (read: may be cleaned up at will).
*/
/* These may be needed for future network-power-down code. */
/* trans_start記錄最後一次成功發送的時間。可以用來確定硬體是否工作正常。*/
unsigned long trans_start; /* Time (in jiffies) of last Tx */
unsigned long last_rx; /* Time of last Rx */
/* flags裡面有很多內容,定義在include/linux/if.h裡。*/
unsigned short flags; /* interface flags (a la BSD) */
unsigned short family; /* address family ID (AF_INET) */
unsigned short metric; /* routing metric (not used) */
unsigned short mtu; /* interface MTU value */
/* type標明物理硬體的類型。主要說明硬體是否需要arp。定義在
include/linux/if_arp.h裡。 */
unsigned short type; /* interface hardware type */
/* 上層協議層根據hard_header_len在發送數據緩沖區前面預留硬體幀頭空間。*/
unsigned short hard_header_len; /* hardware hdr length */
/* priv指向驅動程式自己定義的一些參數。*/
void *priv; /* pointer to private data */
/* Interface address info. */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
unsigned char pad; /* make dev_addr aligned to 8
bytes */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char addr_len; /* hardware address length */
unsigned long pa_addr; /* protocol address */
unsigned long pa_brdaddr; /* protocol broadcast addr */
unsigned long pa_dstaddr; /* protocol P-P other side addr */
unsigned long pa_mask; /* protocol netmask */
unsigned short pa_alen; /* protocol address length */
struct dev_mc_list *mc_list; /* Multicast mac addresses */
int mc_count; /* Number of installed mcasts */
struct ip_mc_list *ip_mc_list; /* IP multicast filter chain */
__u32 tx_queue_len; /* Max frames per queue allowed */
/* For load balancing driver pair support */
unsigned long pkt_queue; /* Packets queued */
struct device *slave; /* Slave device */
struct net_alias_info *alias_info; /* main dev alias info */
struct net_alias *my_alias; /* alias devs */
/* Pointer to the interface buffers. */
struct sk_buff_head buffs[DEV_NUMBUFFS];
/* Pointers to interface service routines. */
int (*open)(struct device *dev);
int (*stop)(struct device *dev);
int (*hard_start_xmit) (struct sk_buff *skb,
struct device *dev);
int (*hard_header) (struct sk_buff *skb,
struct device *dev,
unsigned short type,
void *daddr,
void *saddr,
unsigned len);
int (*rebuild_header)(void *eth, struct device *dev,
unsigned long raddr, struct sk_buff *skb);
#define HAVE_MULTICAST
void (*set_multicast_list)(struct device *dev);
#define HAVE_SET_MAC_ADDR
int (*set_mac_address)(struct device *dev, void *addr);
#define HAVE_PRIVATE_IOCTL
int (*do_ioctl)(struct device *dev, struct ifreq *ifr, int cmd);
#define HAVE_SET_CONFIG
int (*set_config)(struct device *dev, struct ifmap *map);
#define HAVE_HEADER_CACHE
void (*header_cache_bind)(struct hh_cache **hhp, struct device
*dev, unsigned short htype, __u32 daddr);
void (*header_cache_update)(struct hh_cache *hh, struct device
*dev, unsigned char * haddr);
#define HAVE_CHANGE_MTU
int (*change_mtu)(struct device *dev, int new_mtu);
struct iw_statistics* (*get_wireless_stats)(struct device *dev);
};
2.4 常用的系統支持
2.4.1 內存申請和釋放
include/linux/kernel.h裡聲明了kmalloc()和kfree()。用于在內核模式下申請和釋放
內存。
void *kmalloc(unsigned int len,int priority);
void kfree(void *__ptr);
與用戶模式下的malloc()不同,kmalloc()申請空間有大小限制。長度是2的整次方。可
以申請的最大長度也有限制。另外kmalloc()有priority參數,通常使用時可以為GFP_K
ERNEL,如果在中斷裡調用用GFP_ATOMIC參數,因為使用GFP_KERNEL 則調用者可能進入
sleep狀態,在處理中斷時是不允許的。
kfree()釋放的內存必須是kmalloc()申請的。如果知道內存的大小,也可以用kfree_s(
)釋放。
2.4.2 request_irq()、free_irq()
這是驅動程式申請中斷和釋放中斷的調用。在include/linux/sched.h裡聲明。
request_irq()調用的定義︰
int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,
void *dev_id);
irq是要申請的硬體中斷號。在Intel平台,範圍0--15。handler是向系統登記的中斷處
理函數。這是一個回調函數,中斷發生時,系統調用這個函數,傳入的參 數包括硬體中
斷號,device id,暫存器值。dev_id就是下面的request_irq時傳遞 給系統的參數dev
_id。irqflags是中斷處理的一些屬性。比較重要的有SA_INTERRUPT,
標明中斷處理程式是快速處理程式(設置SA_INTERRUPT)還是慢速處理程式(不設置SA_IN
TERRUPT)。快速處理程式被調用時屏蔽所有中斷。慢速處理程式不屏蔽。還有 一個SA_
SHIRQ屬性,設置了以後營運多個設備共享中斷。dev_id在中斷共享時會用到。一般設置
為這個設備的device架構本身或者NULL。中斷處理程式可以用dev_id 找到相應的控制這
個中斷的設備,或者用irq2dev_map找到中斷對應的設備。
void free_irq(unsigned int irq,void *dev_id);
2.4.3 時鐘
時鐘的處理類似中斷,也是登記一個時間處理函數,在預定的時間過后,系統會調用這
個函數。在include/linux/timer.h裡聲明。
struct timer_list {
struct timer_list *next;
struct timer_list *prev;
unsigned long expires;
unsigned long data;
void (*function)(unsigned long);
};
void add_timer(struct timer_list * timer);
int del_timer(struct timer_list * timer);
void init_timer(struct timer_list * timer);
使用時鐘,先聲明一個timer_list架構,調用init_timer對它進行初始化。
time_list架構裡expires是標明這個時鐘的週期,單位採用jiffies的單位。
jiffies是Linux一個全局變量,代表時間。它的單位隨硬體平台的不同而不同。
系統裡定義了一個常數HZ,代表每秒種最小時間間隔的數目。這樣jiffies的單位就是1
/HZ。Intel平台jiffies的單位是1/100秒,這就是系統所能分辨的最小時間間隔了。所
以expires/HZ就是以秒為單位的這個時鐘的週期。
function就是時間到了以後的回調函數,它的參數就是timer_list中的data。data這個
參數在初始化時鐘的時候賦值,一般賦給它設備的device架構指針。
在預置時間到系統調用function,同時系統把這個time_list從定時隊列裡清除。所以如
果需要一直使用定時函數,要在function裡再次調用add_timer()把這個timer_list加進
定時隊列。
2.4.4 I/O
I/O端口的存取使用︰
inline unsigned int inb(unsigned short port);
inline unsigned int inb_p(unsigned short port);
inline void outb(char value, unsigned short port);
inline void outb_p(char value, unsigned short port);
在include/adm/io.h裡定義。
inb_p()、outb_p()與inb()、outb_p()的不同在于前者在存取I/O時有等待(pause)一適
應慢速的I/O設備。
為了防止存取I/O時發生衝突,Linux提供對端口使用情況的控制。在使用端口之前,可
以檢查需要的I/O是否正在被使用,如果沒有,則把端口標記為正在使用,使用完后再釋
放。系統提供以下幾個函數做這些工作。
int check_region(unsigned int from, unsigned int extent);
void request_region(unsigned int from, unsigned int extent,const char *name)
;
void release_region(unsigned int from, unsigned int extent);
其中的參數from表示用到的I/O端口的起始位址,extent標明從from開始的端口數目。n
ame為設備名稱。
2.4.5 中斷打開關閉
系統提供給驅動程式開放和關閉附應中斷的能力。是在include/asm/system.h中的兩個
定義。
#define cli() __asm__ __volatile__ ("cli"::)
#define sti() __asm__ __volatile__ ("sti"::)
2.4.6 打印訊息
類似普通程式裡的printf(),驅動程式要輸出訊息使用printk()。在include/linux/ke
rnel.h裡聲明。
int printk(const char* fmt, ...);
其中fmt是格式化字元串。...是參數。都是和printf()格式一樣的。
2.4.7 註冊驅動程式
如果使用模塊(module)模式加載驅動程式,需要在模塊初始化時把設備註冊 到系統設備
表裡去。不再使用時,把設備從系統中卸除。定義在drivers/net/net_init.h裡的兩個
函數完成這個工作。
int register_netdev(struct device *dev);
void unregister_netdev(struct device *dev);
dev就是要註冊進系統的設備架構指針。在register_netdev()時,dev架構一般填寫前面
11項,即到init,后面的暫時可以不用初始化。最重要的是name指針和init方法。name
指針空(NULL)或者內容為或者name[0]為空格(space),則系統把你的設備做為以太網設
備處理。以太網設備有統一的命名格式,ethX。對以太網這么特別對待大概和Linux的歷
史有關。
init方法一定要提供,register_netdev()會調用這個方法讓你對硬體檢測和設置。
register_netdev()返回0表示成功,非0不成功。
2.4.8 sk_buff
Linux網路各層之間的數據傳送都是透過sk_buff。sk_buff提供一套管理緩沖區的方法,
是Linux系統網路高效營運的關鍵。每個sk_buff包括一些控制方法和一塊數據緩沖區。
控制方法按功能分為兩種類型。一種是控制整個buffer鏈的方法,
另一種是控制數據緩沖區的方法。sk_buff組織成雙向鏈表的形式,根據網路應用的特點
,對鏈表的操作主要是刪除鏈表頭的元素和添加到鏈表尾。sk_buff的控制
方法都很短小以盡量減少系統負荷。(translated from article written by Alan Cox
)
常用的方法包括︰
.alloc_skb() 申請一個sk_buff並對它初始化。返回就是申請到的sk_buff。
.dev_alloc_skb()類似alloc_skb,在申請好緩沖區后,保留16位元組的幀頭空間。主要用
在Ethernet驅動程式。
.kfree_skb() 釋放一個sk_buff。
.skb_clone() 複製一個sk_buff,但不複製數據部分。
.skb_copy()完全複製一個sk_buff。
.skb_dequeue() 從一個sk_buff鏈表裡取出第一個元素。返回取出的sk_buff,如果鏈表
空則返回NULL。這是常用的一個操作。
.skb_queue_head() 在一個sk_buff鏈表頭放入一個元素。
.skb_queue_tail() 在一個sk_buff鏈表尾放入一個元素。這也是常用的一個操作。網路
數據的處理主要是對一個先進先出隊列的管理,skb_queue_tail()
和skb_dequeue()完成這個工作。
.skb_insert() 在鏈表的某個元素前插入一個元素。
.skb_append() 在鏈表的某個元素后插入一個元素。一些協議(如TCP)對沒按順序到達的
數據進行重組時用到skb_insert()和skb_append()。
.skb_reserve() 在一個申請好的sk_buff的緩沖區裡保留一塊空間。這個空間一般是用
做下一層協議的頭空間的。
.skb_put() 在一個申請好的sk_buff的緩沖區裡為數據保留一塊空間。在
alloc_skb以後,申請到的sk_buff的緩沖區都是處于空(free)狀態,有一個tail指針指
向free空間,實際上開始時tail就指向緩沖區頭。skb_reserve()
在free空間裡申請協議頭空間,skb_put()申請數據空間。見下面的圖。
.skb_push() 把sk_buff緩沖區裡數據空間往前移。即把Head room中的空間移一部分到
Data area。
.skb_pull() 把sk_buff緩沖區裡Data area中的空間移一部分到Head room中。
--------------------------------------------------
| Tail room(free) |
--------------------------------------------------
After alloc_skb()
--------------------------------------------------
| Head room | Tail room(free) |
--------------------------------------------------
After skb_reserve()
--------------------------------------------------
| Head room | Data area | Tail room(free) |
--------------------------------------------------
After skb_put()
--------------------------------------------------
|Head| skb_ | Data | Tail room(free) |
|room| push | | |
| | Data area | |
--------------------------------------------------
After skb_push()
--------------------------------------------------
| Head | skb_ | Data area | Tail room(free) |
| | pull | | |
| Head room | | |
--------------------------------------------------
After skb_pull()
三.編寫Linux網路驅動程式中需要注意的問題
3.1 中斷共享
Linux系統營運幾個設備共享同一個中斷。需要共享的話,在申請的時候指明共享模式。
系統提供的request_irq()調用的定義︰
int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id, struct pt_regs *regs),
unsigned long irqflags,
const char * devname,
void *dev_id);
如果共享中斷,irqflags設置SA_SHIRQ屬性,這樣就允許別的設備申請同一個中斷。需
要注意所有用到這個中斷的設備在調用request_irq()都必須設置這個屬性。系統在回調
每個中斷處理程式時,可以用dev_id這個參數找到相應的設備。一 般dev_id就設為dev
ice架構本身。系統處理共享中斷是用各自的dev_id參數依次調用每一個中斷處理程式。
3.2 硬體發送忙時的處理
主CPU的處理能力一般比網路發送要快,所以經常會遇到系統有數據要發,但上一包數據
網路設備還沒發送完。因為在Linux裡網路設備驅動程式一般不做數據緩存,不能發送的
數據都是通知系統發送不成功,所以必須要有一個機製在硬體不忙時及時通知系統接著
發送下面的數據。
一般對發送忙的處理在前面設備的發送方法(hard_start_xmit)裡已經描述過,即如果發
送忙,置tbusy為1。處理完發送數據后,在發送結束中斷裡清tbusy,同時用mark_bh()
調用通知系統繼續發送。
但在具體實現我的驅動程式時發現,這樣的處理系統好像並不能及時地知道硬體已經空
閑了,即在mark_bh()以後,系統要等一段時間才會接著發送。造成發送效率很低。2M線
路只有10%不到的使用率。內核版本為2.0.35。
我最後的實現是不把tbusy置1,讓系統始終認為硬體空閒,但是報告發送不成功。系統
會一直嘗試重發。這樣處理就營運正常了。但是遍循內核源碼中的網路驅動程式,似乎
沒有這樣處理的。不知道症結在那裡。
3.3 流量控制(flow control)
網路數據的發送和接收都需要流量控制。這些控制是在系統裡實現的,不需要驅動程式
做工作。每個設備數據架構裡都有一個參數dev->tx_queue_len,這個參數標明發送時最
多緩存的數據包。在Linux系統裡以太網設備(10/100Mbps)tx_queue_len一般設置為100
,串行線路(異步串口)為10。實際上如果看源碼可以知道,設置了dev->tx_queue_len並
不是為緩存這些數據申請了空間。這個參數只是在收到協議層的數據包時判斷發送隊列
裡的數據是不是到了tx_queue_len的限度,以決定這一包數據加不加進發送隊列。發送
時另一個方面的流控是更高層協議的發送窗口(TCP協議裡就有發送窗口)。達到了窗口大
小,高層協議就不會再發送數據。
接收流控也分兩個層次。netif_rx()緩存的數據包有限制。另外高層協議也會有一個最
大的等待處理的數據量。
發送和接收流控處理在net/core/dev.c的do_dev_queue_xmit()和netif_rx()中。
3.4 調試
很多Linux的驅動程式都是編譯進內核的,形成一個大的內核文件。但對調試來說,這是
相當麻煩的。調試驅動程式可以用module模式加載。支持模塊模式的驅動程式必須提供
兩個函數︰int init_module(void)和void cleanup_module(void)。init_module()在加
載此模塊時調用,在這個函數裡可以register_netdev()註冊設備。init_module()返回
0表示成功,返回負表示失敗。cleanup_module()在驅動程式被卸載時調用,清除佔用的
資源,調用unregister_netdev()。
模塊可以動態地加載、卸載。在2.0.xx版本裡,還有kerneld自動加載模塊,但是2.2.x
x中已經取消了kerneld。手工加載使用insmod命令,卸載用rmmod命令,看內核中的模塊
用lsmod命令。
編譯驅動程式用gcc,主要命令行參數-DKERNEL -DMODULE。並且作為模塊加載的驅動程
序,只編譯成obj形式(加-c參數)。編譯好的目標文件放在/lib/modules/2.x.xx/misc下
,在啟動文件裡用insmod加載。
四.進一步的閱讀
Linux程式設計資料可以從網上獲得。這就是開放源代碼的好處。並且沒有什麼“未公開
的祕密”。我編寫驅動程式時參閱的主要資料包括︰
Linux內核源代碼
<> by Michael K. Johnson
<> by Ori Pomerantz
by olly in BBS水木清華站
可以選擇一個模板作為開始,內核源代碼裡有一個網路驅動程式的模板,
drivers/net/skeleton.c。裡麵包含了驅動程式的基本內容。但這個模板是以以太網設
備為對象的,以太網的處理在Linux系統裡有特殊“待遇”,所以如果不是以太網設備,
有些細節上要注意,主要在初始化程式裡。
最後,多參照別人寫的程式,聽聽其他開發者的經驗之談大概是最有效的幫助了。
(繼續閱讀...)
文章標籤

eager 發表在 痞客邦 留言(0) 人氣(4,543)

  • 個人分類:轉錄文件
▲top
12»

自訂側欄

自訂側欄

自訂側欄

近期文章

  • 系統錯誤訊息在/usr/include/asm/error.h
  • 最近突然想到
  • [轉錄] 給年輕朋友的就業建議
  • windows live Write
  • [轉]水的科學與偽科學
  • 五年的變化 真大
  • 第一個目標達成
  • 媽媽沒教過妳不要隨便跟陌生人說話嗎?
  • 似是而非的六大飲食迷思(轉)
  • 日劇寓言...同情與目光

最新迴響

  • [16/04/25] 小G 於文章「[轉錄]ADPCM...」留言:
    Very useful information, thank...
  • [09/12/11] 有趣又好玩8 於文章「日劇寓言...同情與目光...」留言:
    歡迎大家來看看唷3 ...
  • [06/09/24] eager 於文章「捷徑遠途...」留言:
    太貴了 學長沒有折扣歐 最好趕快幫我提升一下心靈 要不然我...
  • [06/09/07] louk 於文章「捷徑遠途...」留言:
    這個時候你需要心靈的導師 乖... 現在入會.參加lo...
  • [06/04/08] eager 於文章「我果然沒有跳舞細胞阿...」留言:
    好阿 我會去看看你的blog的 有空多寫些文章阿~~...
  • [06/04/05] tennyu 於文章「我果然沒有跳舞細胞阿...」留言:
    呵 ~ 你好,我是無名的新鮮人,在網路上看到了你的網誌,所...
  • [06/02/13] eager 於文章「批判性思考的五大步驟...」留言:
    這個嗎 著名出處就是要給你去買書看的阿 >_< .......
  • [06/02/12] Robert 於文章「批判性思考的五大步驟...」留言:
    怎么看啊,具体的内容呢...
  • [06/02/12] Robert 於文章「批判性思考的五大步驟...」留言:
    短短的...
  • [05/12/26] eager 於文章「好像滿好玩的小水滴寵物...」留言:
    最近過的不好 不過...還死不去啦 小水滴 不知怎樣 我...

個人頭像

eager
暱稱:
eager
分類:
不設分類
好友:
累積中
地區:

文章彙整

文章分類

  • 飲食 (2)
  • 心情 (3)
  • 分享 (3)
  • 心情霧雨 (45)
  • 技術言究 (9)
  • 樂澀文章 (4)
  • 轉錄文件 (12)
  • 色影輯景 (5)
  • 閱讀心得 (2)
  • 未分類文章 (1)