3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Windbg内核调试(大杂烩)

發布時間:2023/12/18 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windbg内核调试(大杂烩) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Windbg內核調試之三: 調試驅動


這次我們通過一個實際調試驅動的例子,來逐步體會Windbg在內核調試中的作用.
由于條件所限,大多數情況下,很多人都是用VMware+Windbg調試內核(VMware的確是個好東西).但這樣的調試需要占用大量的系統資源,對于和我一樣急性子的朋友來說這是不可接受的:).利用雙機調試就可以讓你一邊喝咖啡一邊輕松的看結果,而不至于郁悶的等待每次長達數分鐘的系統響應.有關雙機調試的基本設置,請參考:

本次調試驅動所構建的環境如下:

host computer: WinXP+Windbg
Target computer:? Vista SP1
driver object: syscow
connect setting: 1394數據線

說明: 1.1394卡在很多機器上都已經沒有了,Vista也取消了1394的數據連接協議(調試還是可以的),但不可否認的是利用1394數據線連接調試要比COM口和USB速率快很多(為什么好用的東西卻得不到支持!).2.本次調試的driver是公司開發的某個軟件的驅動程序,拿來嘗試在Vista SP1下track.由于涉及到商業機密,本驅動源代碼不便公開.3.Vista SP1就沒什么好說的了,前些天才發布,MS又一個失敗的典型.

OK,Let's go!
該驅動是一個類型sr.sys(MS的System Restore驅動)的Filter Driver,屬于文件系統過濾驅動,加載在文件系統驅動上層,由Filter Manager負責與用戶層和底層通信.連接到目標機后,按下Ctrl+break中斷當前狀態.(注:你也可以進入到explorer之后再中斷,為了了解驅動加載時的進入點,以及系統啟動時內核的裝態,我們中斷到這里)

Microsoft (R) Windows Debugger? Version 6.6.0007.5
Copyright (c) Microsoft Corporation. All rights reserved.

Using 1394 for debugging
Opened //./DBG1394_INSTANCE01
Waiting to reconnect...
Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: D:/symbolslocal; D:/IR/SystemOK/Restore/Driver/objchk_wlh_x86/i386
Executable search path is:
*** ERROR: Symbol file could not be found.? Defaulted to export symbols for ntkrnlmp.exe -
Windows Vista Kernel Version 6000 MP (1 procs) Free x86 compatible
Built by: 6000.16584.x86fre.vista_gdr.071023-1545
Kernel base = 0x81800000 PsLoadedModuleList = 0x81908ad0
System Uptime: not available
WARNING: Whitespace at start of path element
WARNING: Whitespace at start of path element
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
*?? You are seeing this message because you pressed either????????????????????????????????????????????????????????
*?????? CTRL+C (if you run kd.exe) or,???????????????????????????????????????
*?????? CTRL+BREAK (if you run WinDBG),?????????????????????????????????????
*?? on your debugger machine's keyboard.?????????????????????????????????????
*????????????????????????????????????????????????????????????????????????????
*?????????????????? THIS IS NOT A BUG OR A SYSTEM CRASH??????????????????????
*????????????????????????????????????????????????????????????????????????????
* If you did not intend to break into the debugger, press the "g" key, then??
* press the "Enter" key now.? This message might immediately reappear.? If it
* does, press "g" and "Enter" again.?????????????????????????????????????????
*????????????????????????????????????????????????????????????????????????????
*******************************************************************************
nt!RtlpBreakWithStatusInstruction:
818355e8 cc????????????? int???? 3

然后,在Command line里鍵入lm,查看當前系統加載的模塊和驅動(會發現我們的driver列在其中):

kd> lm
start??? end??????? module name
80404000 80412000?? PCIIDEX??? (deferred)????????????
80412000 80419000?? intelide?? (deferred)????????????
80419000 80429000?? mountmgr?? (deferred)????????????
80429000 80438000?? volmgr???? (deferred)????????????
80438000 8045d000?? pci??????? (deferred)????????????
8045d000 80465000?? msisadrv?? (deferred)????????????
80465000 8046e000?? WMILIB???? (deferred)????????????
8046e000 804b1000?? acpi?????? (deferred)????????????
804b1000 804be000?? WDFLDR???? (deferred)????????????
804be000 80539000?? Wdf01000?? (deferred)????????????
80539000 8061a000?? CI???????? (deferred)????????????
8061a000 80655000?? CLFS?????? (deferred)????????????
80655000 8065d000?? BOOTVID??? (pdb symbols)?????????
8065d000 80666000?? PSHED????? (deferred)????????????
80666000 806c6000?? mcupdate_GenuineIntel?? (deferred)????????????
806c6000 806ce000?? kdcom????? (deferred)????????????
81800000 81b95000?? nt???????? (pdb symbols)?????????
81b95000 81bc9000?? hal??????? (pdb symbols)????????
81c06000 81c0e000?? spldr????? (deferred)????????????
81c0e000 81c44000?? volsnap??? (deferred)????????????
81c44000 81cae000?? ksecdd???? (deferred)????????????
81cae000 81db6000?? Ntfs?????? (deferred)????????????
81db6000 81def000?? NETIO????? (deferred)????????????
81def000 81e1a000?? msrpc????? (deferred)????????????
81e1a000 81f1e000?? ndis?????? (deferred)????????????
81f1e000 81f270c0?? PxHelp20?? (deferred)????????????
81f28000 81f4f000?? syscow32v?? (private pdb symbols)?
81f4f000 81f5f000?? fileinfo?? (deferred)????????????
81f5f000 81f90000?? fltmgr???? (deferred)????????????
81f90000 81fae000?? ataport??? (deferred)????????????
81fae000 81fb6000?? atapi????? (deferred)????????????
81fb6000 82000000?? volmgrx??? (deferred)????????????
8234f000 82358000?? crcdisk??? (deferred)????????????
82358000 82368000?? agp440???? (deferred)????????????
82368000 82389000?? CLASSPNP?? (deferred)????????????
82389000 8239a000?? disk?????? (deferred)????????????
8239a000 823bd000?? fvevol???? (deferred)????????????
823bd000 823e2000?? ecache???? (deferred)????????????
823e2000 823f1000?? mup??????? (deferred)????????????
823f1000 82400000?? partmgr??? (deferred)??

注: 若符號文件沒有加載成功,Windbg會提示響應的符號找不到,不過一般Windbg會自己尋找符號文件路徑.實在找不到時,就包含
srv*c:/symbols*http://msdl.microsoft.com/download/symbols, 然后reload一下(!reload).

另外,鍵入lm t n, 我們可以查看更為詳細的模塊及驅動信息.
然后,鍵入!thread和Kp,查看當前的線程詳細信息和堆棧(或者Alt+6也可以看stack).注意當前thread的ID:

kd> !thread
THREAD 84254ae8? Cid 0004.0008? Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
Owning Process??????????? 84254d90?????? Image:???????? System
Wait Start TickCount????? 0????????????? Ticks: 1 (0:00:00:00.015)
Context Switch Count????? 1????????????
UserTime????????????????? 00:00:00.0000
KernelTime??????????????? 00:00:00.0015
Win32 Start Address nt!Phase1Initialization (0x819433ae)
Stack Init 81c06000 Current 81c05db8 Base 81c06000 Limit 81c03000 Call 0
Priority 31 BasePriority 8 PriorityDecrement 0
ChildEBP RetAddr? Args to Child?????????????
81c05af0 818aa92c 00000001 81867999 0002625a nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0])
81c05af8 81867999 0002625a 00000000 00000001 nt!KdCheckForDebugBreak+0x22 (FPO: [0,0,0])
81c05b18 81836cfd 81928100 000000d1 81c05b9c nt!KeUpdateRunTime+0x270
81c05b18 81ba4130 81928100 000000d1 81c05b9c nt!KeUpdateSystemTime+0xed (FPO: [0,2] TrapFrame @ 81c05b28)
81c05b9c 81ba3fd0 81bb28a0 8181dced 81c05bc8 hal!XmGetCodeByte+0x30 (FPO: [Non-Fpo])
81c05bac 81ba40c5 81bb28a0 0000c000 00001da4 hal!XmEmulateStream+0x88 (FPO: [Non-Fpo])
81c05bc8 81ba374d 00000010 81c05c0c 8181dced hal!XmEmulateInterrupt+0x80 (FPO: [Non-Fpo])
81c05bdc 81ba0a1c 00000010 81c05c0c 00000000 hal!x86BiosExecuteInterruptShadowed+0x43 (FPO: [Non-Fpo])
81c05bf8 81ba0a5b 00000010 81c05c0c 00000000 hal!x86BiosCall+0x22 (FPO: [Non-Fpo])
81c05c2c 80656697 80806ae0 8080f438 00000000 hal!HalpBiosDisplayReset+0x25 (FPO: [Non-Fpo])
81c05c58 81b2cd6d 00000001 81b0ab01 80806ae0 BOOTVID!VidInitialize+0x135 (FPO: [Non-Fpo])
81c05c7c 81b3f098 00000001 80806ae0 00000007 nt!InbvDriverInitialize+0x81
81c05d74 819433bb 81c05dc0 819afbad 80806ae0 nt!Phase1InitializationDiscard+0xd0
81c05d7c 819afbad 80806ae0 81c0e680 00000000 nt!Phase1Initialization+0xd
81c05dc0 8189a346 819433ae 80806ae0 00000000 nt!PspSystemThreadStartup+0x9d
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

kd> kp
ChildEBP RetAddr?
81c05af0 818aa92c nt!RtlpBreakWithStatusInstruction
81c05af8 81867999 nt!KdCheckForDebugBreak+0x22
81c05b18 81836cfd nt!KeUpdateRunTime+0x270
81c05b18 81ba4130 nt!KeUpdateSystemTime+0xed
81c05b9c 81ba3fd0 hal!XmGetCodeByte+0x30
81c05bac 81ba40c5 hal!XmEmulateStream+0x88
81c05bc8 81ba374d hal!XmEmulateInterrupt+0x80
81c05bdc 81ba0a1c hal!x86BiosExecuteInterruptShadowed+0x43
81c05bf8 81ba0a5b hal!x86BiosCall+0x22
81c05c2c 80656697 hal!HalpBiosDisplayReset+0x25
81c05c58 81b2cd6d BOOTVID!VidInitialize+0x135
81c05c7c 81b3f098 nt!InbvDriverInitialize+0x81
81c05d74 819433bb nt!Phase1InitializationDiscard+0xd0
81c05d7c 819afbad nt!Phase1Initialization+0xd
81c05dc0 8189a346 nt!PspSystemThreadStartup+0x9d
00000000 00000000 nt!KiThreadStartup+0x16

鍵入!process [PID] 0, 查到當前進程:

kd> !process 0004.0008 0
PROCESS 84254d90? SessionId: none? Cid: 0004??? Peb: 00000000? ParentCid: 0000
??? DirBase: 00122000? ObjectTable: 830001d0? HandleCount:?? 1.
??? Image: System
??? VadRoot 00000000 Vads 0 Clone 0 Private 0. Modified 0. Locked 0.
??? DeviceMap 00000000
??? Token???????????????????????????? 83003830
??? ElapsedTime?????????????????????? 00:00:00.015
??? UserTime????????????????????????? 00:00:00.000
??? KernelTime??????????????????????? 00:00:00.000
??? QuotaPoolUsage[PagedPool]???????? 0
??? QuotaPoolUsage[NonPagedPool]????? 0
??? Working Set Sizes (now,min,max)? (4, 0, 0) (16KB, 0KB, 0KB)
??? PeakWorkingSetSize??????????????? 0
??? VirtualSize?????????????????????? 0 Mb
??? PeakVirtualSize?????????????????? 0 Mb
??? PageFaultCount??????????????????? 0
??? MemoryPriority??????????????????? BACKGROUND
??? BasePriority????????????????????? 8
??? CommitCharge????????????????????? 0

??????? THREAD 84254ae8? Cid 0004.0008? Teb: 00000000 Win32Thread: 00000000 RUNNING on processor 0

在lm命令列出的信息中,start是模塊的起始地址,通過鍵入"u 驅動起始地址",我們可以反匯編出它的代碼:

kd> u 81f28000
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0x0):
81f28000 4d????????????? dec???? ebp
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0x1):
81f28001 5a????????????? pop???? edx
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0x2):
81f28002 90????????????? nop
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0x3):
81f28003 0003??????????? add???? byte ptr [ebx],al
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0x5):
81f28005 0000??????????? add???? byte ptr [eax],al
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0x7):
81f28007 000400????????? add???? byte ptr [eax+eax],al
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0xa):
81f2800a 0000??????????? add???? byte ptr [eax],al
syscow32v!SysCowAllocatePostCopyWorkItem <PERF> (syscow32v+0xc):
81f2800c ff????????????? ???

逐步查找(enter),最終我們可以發現driver的入口點.這個過程其實是非常慢的,因為系統內核在加載驅動實際代碼的過程中進行了N多次調用.如果我們本身有驅動的代碼,也可以直接包含源代碼路徑,通過在實際代碼中設置斷點,讓Windbg自己中斷到相應的代碼位置(在實際調試內核的過程中,這幾乎是不可能的,因為你不會得到Windows內核或某個驅動程序的源代碼.Linux系列的某些driver們又另當別論).這里為了方便,我包含了syscow的源代碼,增加斷點直接走到DriverEntry例程:

kd> u 81f42780
syscow32v!DriverEntry [隱藏了address]:
81f42780 8bff??????????? mov???? edi,edi
81f42782 55????????????? push??? ebp
81f42783 8bec??????????? mov???? ebp,esp
81f42785 51????????????? push??? ecx
81f42786 c745fc010000c0? mov???? dword ptr [ebp-4],0C0000001h
81f4278d a1749cf481????? mov???? eax,dword ptr [syscow32v!SysCowDbgFlags (81f49c74)]
81f42792 83e004????????? and???? eax,4
81f42795 7424??????????? je????? syscow32v!DriverEntry+0x3b (81f427bb)

其中顯示的匯編代碼,是內核調用驅動是進行的操作,其實也和實際代碼相對應.

在driver代碼中,如果要查看當前參數值,用dv命令:

kd> dv
?? DriverObject = 0x84663730
?? RegistryPath = 0x8084b560
???????? status = 8
?????? dontload = 0

另外,用"dt 參數名"可以看某個參數的當前值.

kd> dt DriverObject
Local var @ 0x81c05af8 Type _DRIVER_OBJECT*
0x84663730
?? +0x000 Type???????????? : 4
?? +0x002 Size???????????? : 168
?? +0x004 DeviceObject???? : (null)
?? +0x008 Flags??????????? : 2
?? +0x00c DriverStart????? : 0x81f28000
?? +0x010 DriverSize?????? : 0x27000
?? +0x014 DriverSection??? : 0x84230a68
?? +0x018 DriverExtension? : 0x846637d8 _DRIVER_EXTENSION
?? +0x01c DriverName?????? : _UNICODE_STRING "/FileSystem/SysCow"
?? +0x024 HardwareDatabase : 0x81af6ed8 _UNICODE_STRING "/REGISTRY/MACHINE/HARDWARE/DESCRIPTION/SYSTEM"
?? +0x028 FastIoDispatch?? : (null)
?? +0x02c DriverInit?????? : 0x81f4a005???? syscow32v!GsDriverEntry+0
?? +0x030 DriverStartIo??? : (null)
?? +0x034 DriverUnload???? : (null)
?? +0x038 MajorFunction??? : [28] 0x8189a5c1???? nt!IopInvalidDeviceRequest+0

這樣,我們就可以通過上述的這些命令,逐步分析一個驅動程序在加載和執行過程中的情況。另外,Windbg還有眾多內核調試命令,如!irp可以查看一個對象的數據結構,!devobj可以查看設備對象等,在今后的操作系統內核學習過程中會不斷用到這些命令。

從上面的操作過程我們可以看出,利用Windbg調試驅動程序,或者說進行內核調試,是非常方便的。如果我們對Windows內核有一定的了解,同時擁有一定匯編語言的功底,就可以有Windbg進行簡單的系統排障(比如系統加載是出現藍屏,或是某個系統模塊出現問題)、驅動學習等。同時,這個過程也可以讓我們更深入的理解操作系統原理。另外,Windbg也可以進行系統服務(service)的調試,這就是User mode的調試過程了。


posted @ 2008-03-27 21:16 Da Vinci 閱讀(138) | 評論 (1) |?編輯

2008年3月25日

.NET下午茶之三: 淺析CLR應用程序域


CLR(公共語言運行庫)可以說是整個.NET平臺的核心元素.基本上托管應用程序所有的操作都是需要CLR的監管和處理.這些操作包括進程內應用程序的加載, IL語言轉換為機器語言, 異常管理, 垃圾回收,加載程序集等等.

CLR執行托管代碼前,實際上會創建三個應用程序域, 它們是系統域(System Domain),共享域(Shared Domain)和缺省應用程序域(Default AppDomain).其中系統域和共享域對于托管代碼和CLR的宿主程序(如控制臺程序,ASP.NET等)不可見.域可以通過AppDomain.CreateDomain方法創建(下文會詳細敘述這個過程),在非托管的代碼中,可以使用一個ICORRutimeHost的接口創建(這個接口我也沒用過,一般都是托管的代碼).對于復雜的宿主程序,由網站根據應用程序的數目來建立域。



???????????????????? 圖1.CLR啟動程序創建的域
?????????? (轉載自Inside .NET Framework:CLR runtime object)

注:下文中的AppDomain特指應用程序域,對于系統域和共享域保持原來的指定

要注意的是,這里的域不同于C#類中域的概念.C#類中域指類和對象相關的變量,這里的域其實是一種輕量的進程,你完全可以把它當成進程來理解.有人也許不明白既然有了進程的概念,干嗎又搞出一個域來.其實這是為了實現在服務器中加載多個應用程序才提出的.AppDomain與進程相比優勢在于:
???? 1.所需系統資源更少
???? 2.進程之間的AppDomain可以共享資源
但是千萬別把AppDomain和線程搞混,這二者之間沒有從屬的關系.地球人都知道線程是進程的孩子,但是線程和AppDomain的關系類似于正交關系.同一時間內多個線程可以運行在一個AppDomain中,多個AppDomain也可以跨越一個線程.

下面, 我們先大致看一下系統域和共享域的一些基本概念,再著重探討AppDomain的知識.

系統域(System Domain):系統域初始化共享域和AppDomain。它在共享域中加載了mscorlib.dll()。同時,系統域產生了進程的接口ID(不知道這樣描述對不對),以此來創建AppDomain的接口虛擬表映射的接口。在進程中,系統域監控所有的域,加載(load)和卸載(unload)AppDomain也有它完成。可以認為系統域是CLR中的基礎域。

共享域(Shared Domain):在.NET中,不是所有的代碼都屬于某個域,但這些代碼卻是用戶代碼所必需的。共享域就負責加載這部分代碼。比如大家熟悉的Object,Array,String,delegate等。這些代碼在CLR啟動程序時先被加載到共享域中.共享域中有一個程序集映射表,通過這個表來查找共享的程序集的依賴關系. 可以認為共享域是CLR中的帶有索引的共享文件夾.

注:用戶代碼和控制臺程序也可以加載到共享域.(具體方法?..不急..以后告訴你)

AppDomain

終于說到學習.NET要接觸最多的AppDomain了.其實CLR啟動應用程序時,就會自動創建一個AppDomain的實例,叫默認的AppDomain(Default AppDomain).大部分的應用程序在運行期間只創建一個域.有些應用程序有多個AppDomain,它們之間由.NET Remoting通信。AppDomain之間是彼此獨立的。一個AppDomain無法訪問其他的AppDomain的程序集和對象(并不意味著不能相互通信),并且可以定義自己的程序集訪問策略。
通過System.AppDomain類的實例,可以獲得進程中一個AppDomain的引用:

??? using System;
??? using System.Threading;
??? class MyAppDomain
?? {
??????? static void Main()
?????? {
?????????? Thread.CurrentThread.Name = "MyDomain";
?????????? AppDomainSetup info = new AppDomainSetup();
?????????? AppDomain myAppDomain = AppDomain.CurrentDomain;
?????????? AppDomain newDomain = AppDomain.CreateDomain("MyDomain", null, info);
???
?????????? myAppDomain.ExecuteAssembly("AssemblyName.exe"); // load your assembly name
?????????? AppDomain.unload(myDomain);
??????? }
??? }

上面代碼創建了一個AppDomain的實例,并調用ExecuteAssembly方法加載一個程序集。其中AppDomainSetup為CLR定位信息。unload為AppDomain類的卸載域方法。注意:這段代碼中ExecuteAssembly()方法的線程調用了AssemblyName.exe程序集的線程。這樣一個線程就跨越了兩個AppDomain。這也說明了AppDomain和線程之間沒有包含關系。

到這里,我們已經對CLR中域的概念,各種域的結構有了一個大概的認識。AppDomain是CLR中最基本的概念,在CLR的整個框架中都與它有著千絲萬縷的聯系,掌握它是學習CLR的基礎。有關AppDomain間通信的方法,我們在.NET Remoting篇中再詳細闡述。


posted @ 2008-03-25 22:25 Da Vinci 閱讀(32) | 評論 (2) |?編輯

2008年3月22日

Windbg內核調試之二: 常用命令


運用Windbg進行內核調試, 熟練的運用命令行是必不可少的技能. 但是面對眾多繁瑣的命令, 實在是不可能全部的了解和掌握. 而了解Kernel正是需要這些命令的指引, 不斷深入理解其基本的內容. 下面, 將介紹最常用的一些指令, 使初學Kernel調試的朋友們能有一個大致的了解. 至于如何熟練的運用它們, 還需要實際的操作過程中進行反復的琢磨.

Windbg能夠方便的進行遠程調試和本地進程調試(只限于User模式), 遠程調試又分User mode和Kernel mode兩種. 個人認為用Windbg進行遠程的User mode調試還不如用Visual Studio來的方便, 畢竟要一些相應的配置才行, 而Visual Studio只需要遠程機器的IP地址即可.(當然, 如果你在LiveCD或WinPE下進行User mode的調試, 這時候沒有VS, Windbg就是不二之選了). Windbg的優勢就在于遠程的Kernel模式的調試, 這是VS所做不到的.

1. 首先是設置符號路徑(無論在User mode下還是Kernel mode下都需要), 在Windbg的符號路徑對話框中, 輸入以下符號路徑:

????? srv*c:/symbols*http://msdl.microsoft.com/download/symbols

這個符號路徑是自動在微軟給定的symbols路徑下進行自動搜索, 一些常用的符號都可以利用這個鏈接自動找到. 當然, 如果你的本地已經有相應的符號路徑, 包含本地的也可以.

2. 等Windbg的聯機狀態設置好后, 按下Ctrl+break, 中斷當前的Kernel狀態, 在Windbg的命令行窗口輸入"?", 則會輸出幫助菜單, 在這個Menu中會顯示一些常用的命令:

? (1)斷點指令 ???? B[C|D|E] [<bps>] ???? clear|disable|enable breakpoints ???? BL ???? list breakpoints ???? BP <address> ???? set soft breakpoints ???? BA <access> <size> <addr> ???? break on access ? (2)數據查看指令 ???? D[type][<range>] ???? dump memory ???? DT [-n|y] [[mod!]name] [[-n|y]fields][address] [-l list] [-a[]|c|i|o|r[#]|v] ???? dump using type information ???? DV [<name>]? ???? dump local variables ? (3)數據修改指令 ???? E[type] <address> [<values>] ???? enter memory values ? (4)運行 ???? G[H|N] [=<address> [<address>...]]? ???? go ???? P [=<addr>] [<value>] ???? step over ? (5)堆棧操作 ???? K[b|p|P|v] ? (6)顯示加載的模塊列表 ???? LM ???? list modules ? (7)寄存器操作 ???? R [[<reg> [= <expr>]]] ???? view or set registers ? (8)Search指令 ???? S[<opts>] <range> <values> ???? search memory ? (9)跟蹤指令T,TA,TB,TC,WT,P,PA,PC ? (10)退出 ????? Q

? (11)反匯編
????? U[<range>]

其中最常用的就是反匯編操作和顯示模塊操作. LM命令顯示當前加載的模塊. 當你連接過程中, Windbg提示相應的module找不到時, 就可以運用這個命令進行查看. LM的一個擴展命令是"lm t n", 這個命令顯示當前所有加載的驅動信息(過去的命令是!driver),在調試內核驅動的過程中非常有用,可以找到相應驅動的起始地址。反匯編命令u, 可以在相應的地址中逐步的解析代碼,這在內核調試中是最常用的一種查看代碼的方式。

除上面的一些基本命令之外,還有一些非常有用的指令:
?
? (1)K[KB|KP]
???? 顯示當前的堆棧,當然也可以用alt+6直接調出窗口顯示
?
? (2)!process
???? 顯示當前的進程EXPROCESS狀態,!process 0 0 顯示所有的進程狀態

? (3)!thread
???? 顯示當前的線程狀態,dt nt!_ethread顯示ETHREAD結構

? (4)!drvobj [path]
???? 列出當前的驅動程序在驅動對象中的例程,其中path是驅動的設備路徑,例如: !drvobj /filesystem/fat 2 列出FAT文件系統驅動的例程

? (5)dt nt!_*
???? 查看內核的數據結構
?
? (6)!stack 0
???? 顯示線程當前地址
?
? (7)!ioapic
???? 查看I/O的中斷控制器

? (8)!irql
???? 查看CPU的IRQL,這在CPU中斷調試中非常有用

? (9)!exqueue
???? 可以看系統輔助的線程列表

? (10)!reg viewlist
???? 注冊表的存儲顯示,!reg hivelist顯示注冊表一個存儲的內存使用量

? (11)!vm
???? 顯示系統的內存池信息

? (12)dt _TOKEN
???? 顯示內部訪問令牌

? (13)!object /device
???? 顯示設備對象信息,用winobj工具也可以看到

以上命令是一些常用的內核調試命令, 還有非常多的命令技巧, 不可能全部一一解釋. 在今后的文章, 還會結合具體的調試過程分析進行逐步介紹. 內核的調試無非是處理器, 系統設備, 內存, 進程線程, 注冊表, 驅動這幾大類的信息, 每一類都有很多的命令, 需要我們在實際的調試過程中不斷認識和體會它的用法. 當然, 理解這些命令用法的前提是需要我們對操作系統內部構造有一個清晰的認識. 這需要不斷的學習, 對OS有一個全局的把握, 這樣才能更深入的理解它. 而通過Windbg的內核調試, 我們有一種更好的方式直接與Kernel打交道, 這對我們深入理解和認識操作系統有很大的幫助. 下一節我們將通過一個實際的調試driver的例子, 來進一步認識Windbg在內核調試中的作用.


posted @ 2008-03-22 12:30 Da Vinci 閱讀(102) | 評論 (0) |?編輯

2008年3月20日

Windbg內核調試之一: Vista Boot Config設置


Windbg進行內核調試,需要一些基本的技巧和設置,在這個系列文章中,我將使用Windbg過程中所遇到的一些問題和經驗記錄下來,算是對Kernel調試的一個總結,同時也是學習Windows系統內核的另一種過程。

很多人說Windbg不如SoftIce好用, 但是我使用過程中還是覺得Windbg能更好的反映系統狀態, 而且相比SoftIce, Windbg更穩定(雖然它的部分操作略顯復雜), 下面介紹Windbg的Kernel模式調試第一部分: 雙機連接設置.

Vista和XP不同, 沒有boot.ini文件, 需要用bcdedit進行啟動設置。(關于啟動數據配置編輯器BCD的具體設置, 參見另一篇文章: (From MS)Vista: 啟動配置數據編輯器(BCD))

在administrator權限下, 進入command line模式,? 鍵入bcdedit命令, 會出現以下界面:

?

然后, 設置端口COM1, baudrate為115200 (除COM1外, 也可以用1394或USB. 1394用起來比COM口快多了, 當然前提是你需要有1394卡及其驅動. 很惡心的是Vista不再支持1394的文件傳輸協議, 但是用windbg雙機調試還是可以的)
命令為:
bcdedit?/dbgsettings?{serial?[baudrate:value][debugport:value]?| 1394?[channel:value]?|?usb?}



接著, 我們需要復制一個開機選項, 以進入OS的debug模式
命令為:
bcdedit?/copy?{current}?/d?DebugPoint
DebugPoint為選項名稱, 名字可以自己定義. 然后復制得到的ID號.



接著增加一個新的選項到引導菜單
bcdedit?/displayorder?{current}?{ID}
這里的{ID}的ID值是剛生成的ID值.



激活DEBUG : bcdedit?/debug?{ID}?ON
這里的{ID}?的ID值還是剛才的ID值.



命令執行成功后, 重新啟動機器.

選擇DebugPoint登錄,開啟Windbg

連接成功, 則顯示如下:
Microsoft?(R)?Windows?Debugger??Version?6.6.0007.5
Copyright?(c)?Microsoft?Corporation.?All?rights?reserved.

Opened?//./pipe/com_1
Waiting?to?reconnect...
Connected?to?Windows?Vista?6000?x86?compatible?target,?ptr64?FALSE
Kernel?Debugger?connection?established.
Symbol?search?path?is:?symsrv*symsrv.dll*F:/symbols*http://msdl.microsoft.com/download/symbols
Executable?search?path?is:?
Windows?Vista?Kernel?Version?6000?MP?(1?procs)?Free?x86?compatible
Built?by:?6000.16386.x86fre.vista_rtm.061101-2205
Kernel?base?=?0x81800000?PsLoadedModuleList?=?0x81911db0
System?Uptime:?not?available
Break?instruction?exception?-?code?80000003?(first?chance)
*******************************************************************************
*????????????????????????????????????????????????????????????????????????????
*???You?are?seeing?this?message?because?you?pressed?either???????????????????
*???????CTRL+C?(if?you?run?kd.exe)?or,???????????????????????????????????????
*???????CTRL+BREAK?(if?you?run?WinDBG),??????????????????????????????????????
*???on?your?debugger?machine's?keyboard.?????????????????????????????????????
*????????????????????????????????????????????????????????????????????????????
*???????????????????THIS?IS?NOT?A?BUG?OR?A?SYSTEM?CRASH??????????????????????
*????????????????????????????????????????????????????????????????????????????
*?If?you?did?not?intend?to?break?into?the?debugger,?press?the?"g"?key,?then??
*?press?the?"Enter"?key?now.??This?message?might?immediately?reappear.??If?it
*?does,?press?"g"?and?"Enter"?again.?????????????????????????????????????????
*????????????????????????????????????????????????????????????????????????????
*******************************************************************************
nt!RtlpBreakWithStatusInstruction:
81881760?cc??????????????int?????3

總結: 雖然利用VMware虛擬機能更方便的設置雙機的調試環境, 而且這種模擬環境也是大多數人使用的(方便), 但是如果有雙機條件的話,? 還是希望大家能夠使用兩臺機器, 因為用虛擬機進行Kernel調試, 真不是一般的慢! 基本就等于死機. 即時你的主機內存2G, 分給VMware1G, 還是會相當卡(Kerenl模式與User模式不同).

posted @ 2008-03-20 14:38 Da Vinci 閱讀(71) | 評論 (0) |?編輯

Windows程序設計:文件操作(轉載)


操作文件基本上是每個應用程序都必須做的事情。除了必要的配置信息外,用戶的工作最終都要以文件的形式保存到磁盤上。保存和獲取這些信息可以使用獨立的磁盤文件,也可以使用系統自帶的數據庫——注冊表。

本章首先介紹底層操作文件的API函數和MFC中對應的CFile類;然后介紹一些與操作文件相關的邏輯驅動器和目錄方面的知識,包括驅動器的格式化和卷標設置、目錄的創建和刪除等;接著,本章介紹使用 API函數和ATL庫中的CRegKey類操作注冊表的方法;本章還重點討論了內存映射文件在讀寫磁盤文件和建立共享內存方面的應用;本章最后介紹一個多線程的文件分割系統的開發過程。

8.1? 文件操作

文件的輸入輸出(I/O)服務是操作系統的重要部分。Windows提供了一類API函數來讀、寫和管理磁盤文件。MFC將這些函數轉化為一個面向對象的類——CFile,它允許將文件視為可以由 CFile成員函數操作的對象,如Read和Write等。CFile類實現了程序開發者執行底層文件I/O需要的大部分功能。

并不是在任何時候使用CFile類都是方便的,特別是要與底層設備(如COM口、設備驅動)進行交互的時候,所以本節主要討論管理文件的API函數。事實上,了解這些函數之后,自然就會使用CFile類了。

8.1.1? 創建和讀寫文件

使用API函數讀寫文件時,首先要使用 CreateFile函數創建文件對象(即打開文件),調用成功會返回文件句柄;然后以此句柄為參數調用ReadFile和WriteFile函數,進行實際的讀寫操作;最后調用CloseHandle函數關閉不再使用的文件對象句柄。

1.打開和關閉文件

CreateFile是一個功能相當強大的函數,Windows下的底層設備差不多都是由它打開的。它可以創建或打開文件、目錄、物理磁盤、控制臺緩沖區、郵槽和管道等。調用成功后,函數返回能夠用來訪問此對象的句柄,其原型如下:

HANDLE CreateFile (

? LPCTSTR lpFileName,?? ???????????????????????????????????????????? // 要創建或打開的對象的名稱

? DWORD dwDesiredAccess, ??????????????????????????????? // 文件的存取方式

? DWORD dwShareMode, ?????????????????????????????????????????????? // 共享屬性

? LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全屬性

??DWORD dwCreationDisposition, ??????????????????????????????? // 文件存在或不存在時系統采取的行動

? DWORD dwFlagsAndAttributes,?????????????????????????????????? // 新文件的屬性

? HANDLE hTemplateFile ?????????????????????????????????????????????? // 一個文件模板的句柄

);

各參數含義如下。

(1)lpFileName參數是要創建或打開的對象的名稱。如果打開文件,直接在這里指定文件名稱即可;如果操作對象是第一個串口,則要指定“COM1”為文件名,然后就可以像操作文件一樣操作串口了;如果要打開本地電腦上的一個服務,要以“"""."服務名稱"”為文件名,其中的“.”代表本地機器;也可以使用CreateFile打開網絡中其他主機上的文件,此時的文件名應該是“""主機名"共享目錄名"文件名”。

(2)dwDesiredAcces參數是訪問方式,它指定了要對打開的對象進行何種操作。指定GENERIC_READ標志表示以只讀方式打開;指定GENERIC_WRITE標志表示以只寫方式打開;指定這兩個值的組合,表示要同時對打開的對象進行讀寫操作。

(3)dwShareMode參數指定了文件對象的共享模式,表示文件打開后是否允許其他代碼以某種方式再次打開這個文件,它可以是下列值的一個組合:

l????????? 0???????????????????????????????????????????? 不允許文件再被打開。C語言中的fopen函數就是這樣打開文件的

l????????? FILE_SHARE_DELETE????? 允許以后的程序代碼對文件刪除文件(Win98系列的系統不支持這????? ???????? ???????? ???????? ???????? 個標志)

l????????? FILE_SHARE_READ????????? 允許以后的程序代碼以讀方式打開文件

l????????? FILE_SHARE_WRITE???????? 允許以后的程序代碼以寫方式打開文件

(4)dwCreationDisposition參數指定了當文件已存在或者不存在時系統采取的動作。在這里設置不同的標志就可以決定究竟是要打開文件,還是要創建文件。參數的可能取值如下:

l????????? CREATE_ALWAYS??? 創建新文件。如果文件存在,函數會覆蓋這個文件,清除存在的屬性

l????????? CREATE_NEW??????????????????? 創建新文件。如果文件存在,函數執行失敗

l????????? OPEN_ALWAYS????????????????? 如果文件已經存在,就打開它,不存在則創建新文件

l????????? OPEN_EXISTING?????????????? 打開存在的文件。如果文件不存在,函數執行失敗

l????????? TRUNCATE_EXISTING??? 打開文件并將文件截斷為零,當文件不存在時函數執行失敗

(5)dwFlagsAndAttributes參數用來指定新建文件的屬性和標志。文件屬性可以是下面這些值的組合:

l????????? FILE_ATTRIBUTE_ARCHIVE?? ???????? 標記歸檔屬性

l????????? FILE_ATTRIBUTE_HIDDEN ???????????? 標記隱藏屬性

l????????? FILE_ATTRIBUTE_READONLY ?????? 標記只讀屬性

l????????? FILE_ATTRIBUTE_READONLY ?????? 標記系統屬性

l????????? FILE_ATTRIBUTE_TEMPORARY ?? 臨時文件。操作系統會盡量把所有文件的內容保持在內?????? ???????? ???????? ???????? ???????? ???????? ???????? 存中以加快存取速度。使用完后要盡快將它刪除

此參數還可同時指定對文件的操作方式,下面是一些比較常用的方式:

l????????? FILE_FLAG_DELETE_ON_CLOSE ?? 文件關閉后系統立即自動將它刪除

l????????? FILE_FLAG_OVERLAPPED ????????????? 使用異步讀寫文件的方式

l????????? FILE_FLAG_WRITE_THROUGH ???? 系統不會對文件使用緩存,文件的任何改變都會被系統?????? ???????? ???????? ???????? ???????? ???????? ???????? 立即寫入硬盤

(6)hTemplateFile參數指定了一個文件模板句柄。系統會復制該文件模板的所有屬性到當前創建的文件中。Windows 98系列的操作系統不支持它,必須設為NULL。

打開或創建文件成功時,函數返回文件句柄,失敗時返回INVALID_HANDLE_VALUE(-1)。如果想再詳細了解失敗的原因,可以繼續調用GetLastError函數。

用不同的參數組合調用CreateFile函數可以完成不同的功能,例如,下面的代碼為讀取數據打開了一個存在的文件。

???????? HANDLE hFile;

???????? hFile = ::CreateFile("myfile.txt",??? ???????? // 要打開的文件

?????????????????? GENERIC_READ,???????????????????????? // 要讀這個文件

?????????????????? FILE_SHARE_READ,?????????????????? ???????? // 允許其他程序已只讀形式再次打開它

?????????????????? NULL,?????????????????????????????????? ???????? // 默認安全屬性

?????????????????? OPEN_EXISTING,??????????????????????? // 僅僅打開存在的文件(如果不存不創建)

?????????????????? FILE_ATTRIBUTE_NORMAL,? // 普通文件

?????????????????? NULL);????????????????????????????????? ???????? // 沒有模板

???????? if(hFile == INVALID_HANDLE_VALUE)

???????? { ?????????????? ……// 不能夠打開文件?????? }

僅當當前目錄中存在名稱為myfile.txt的文件時,上面的CreateFile才能執行成功。由于為dwCreationDisposition參數指定了OPEN_EXISTING,所以當要打開的文件不存在時,CreateFile返回INVALID_HANDLE_VALUE,而不會創建這個文件。如果想創建一個文件以便向里面寫入數據,可以使用下面的代碼:

???????? HANDLE hFile;

???????? hFile = CreateFile("myfile.txt",????? ?????????????????? // 要創建的文件

?????????????????? GENERIC_WRITE,?????????????????????? // 要寫這個文件

?????????????????? 0,???????????????????????????????????????????????????? // 不共享

?????????????????? NULL,??????????????????????????????????????????? // 默認安全屬性

?????????????????? CREATE_ALWAYS,????????????????????? // 如果存在就覆蓋

?????????????????? FILE_ATTRIBUTE_NORMAL,? // 普通文件

?????????????????? NULL);?????????????????????????????????????????? // 沒有模板

???????? if(hFile == INVALID_HANDLE_VALUE)

???????? { ?????????????? ……// 不能夠打開文件?????? }

要關閉打開的文件,直接以CreateFile返回的文件句柄調用CloseHandle函數即可。

2.移動文件指針

系統為每個打開的文件維護一個文件指針,指定對文件的下一個讀寫操作從什么位置開始。隨著數據的讀出或寫入,文件指針也隨之移動。當文件剛被打開時,文件指針處于文件的頭部。有時候需要隨機讀取文件內容,這就需要先調整文件指針,SetFilePointer函數提供了這個功能,原型如下:

DWORD SetFilePointer (

? ?????????????? HANDLE hFile,? ???????????????????????? // 文件句柄

? ?????????????? LONG lDistanceToMove, ? ???????? // 要移動的距離

? ?????????????? PLONG lpDistanceToMoveHigh,? ?????? // 移動距離的高32位,一般設置為NULL

? ?????????????? DWORD dwMoveMethod ???????? // 移動的模式

?????????????????? );

dwMoveMethod參數指明了從什么地方開始移動,可以是下面的一個值:

l????????? FILE_BEGIN?????????????? 開始移動位置為0,即從文件頭部開始移動

l????????? FILE_CURRENT??????? 開始移動位置是文件指針的當前值

l????????? FILE_END??????????????????????????? 開始移動位置是文件的結尾,即從文件尾開始移動

函數執行失敗返回-1,否則返回新的文件指針的位置。

文件指針也可以移動到所有數據的后面,比如現在文件的長度是100 KB,但還是可以成功的將文件指針移動到1000 KB的位置。這樣做可以達到擴展文件長度的目的。

SetEndOfFile函數可以截斷或者擴展文件。該函數移動指定文件的結束標志(end-of-file,EOF)到文件指針指向的位置。如果文件擴展,舊的EOF位置和新的EOF位置間的內容是未定義的。SetEndOfFile函數的用法如下:

BOOL SetEndOfFile(HANDLE hFile );

截斷或者擴展文件時,要首先調用SetFilePointer移動文件指針,然后再調用SetFilePointer函數設置新的文件指針位置為EOF。

3.讀寫文件

讀寫文件的函數是ReadFile和WriteFile,這兩個函數既可以同步讀寫文件,又可以異步讀寫文件。而函數ReadFileEx和WriteFileEx只能異步讀寫文件。

從文件讀取數據的函數是ReadFile,向文件寫入數據的函數是WriteFile,操作的開始位置由文件指針指定。這兩個函數的原型如下:

BOOL ReadFile(

? ???? HANDLE hFile,?????????????????????????????????????? // 文件句柄

? ???? LPVOID lpBuffer,?????? ?????????????????????????????????? // 指向一個緩沖區,函數會將讀出的數據返回到這里

? ???? DWORD nNumberOfBytesToRead, ???? // 要求讀入的字節數

? ???? LPDWORD lpNumberOfBytesRead, ?? // 指向一個DWORD類型的變量,

?????????????????????????????????????????????????????????????????????????? // 用于返回實際讀入的字節數

? ???? LPOVERLAPPED lpOverlapped ?????????????????? // 以便設為NULL

);

BOOL WriteFile (hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);

當用WriteFile寫文件時,寫入的數據通常被Windows暫時保存在內部的高速緩存中,等合適的時候再一并寫入磁盤。如果一定要保證所有的數據都已經被傳送,可以強制使用FlushFileBuffers函數來清空數據緩沖區,函數的惟一參數是要操作的文件句柄。

BOOL FlushFileBuffers (HANDLE hFile );

4.鎖定文件

當對文件數據的一致性要求較高時,為了防止程序在寫入的過程中其他進程剛好在讀取寫入區域的內容,可以對已打開文件的某個部分進行加鎖,這就可以防止其他進程對該區域進行讀寫。加鎖和解鎖的函數是LockFile和UnlockFile,它們的原型如下:

BOOL? LockFile(

??? HANDLE hFile, ????????????????????????????????????????????? // 文件句柄

??? DWORD dwFileOffsetLow, ?????????????????????????? // 加鎖的開始位置

??? DWORD dwFileOffsetHigh,

??? DWORD nNumberOfBytesToLockLow, ?????? // 加鎖的區域的大小

??? DWORD nNumberOfBytesToLockHigh

??? );

UnlockFile ( hFile, dwFileOffsetLow, dwFileOffsetHigh,

?????????????????? nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh);

dwFileOffsetLow和 dwFileOffsetHigh參數組合起來指定了加鎖區域的開始位置,nNumberOfBytesToLockLow和 nNumberOfBytesToLockHigh參數組合起來指定了加鎖區域的大小。這兩個參數都指定了一個64位的值,在Win32中,只使用32位就夠了。

如果加鎖文件的進程終止,或者文件關閉時還未解鎖,操作系統會自動解除對文件的鎖定。但是,操作系統解鎖文件花費的時間取決于當前可用的系統資源。因此,進程終止時最好顯式地解鎖所有已鎖定的文件,以免造成這些文件無法訪問。

8.1.2? 獲取文件信息

1.獲取文件類型

Windows下的許多對象都稱之為文件,如果想知道一個文件句柄究竟對應什么對象,可以使用GetFileType函數,原型如下:

DWORD GetFileType(HANDLE hFile);

函數的返回值說明了文件類型,可以是下面的一個值:

l????????? FILE_TYPE_CHAR???????????? 指定文件是字符文件,通常是LPT設備或控制臺

l????????? FILE_TYPE_DISK?????????????? 指定文件是磁盤文件

l????????? FILE_TYPE_PIPE??????????????? 指定文件是套節字,一個命名的或未命名的管道

l????????? FILE_TYPE_UNKNOWN 不能識別指定文件,或者函數調用失敗

2.獲取文件大小

如果確定操作的對象是磁盤文件,還可以使用GetFileSize函數取得這個文件的長度。

DWORD GetFileSize(

? HANDLE hFile,??????????????? // 文件句柄

? LPDWORD lpFileSizeHigh?????? // 用于返回文件長度的高字。可以指定這個參數為NULL

);

函數執行成功將返回文件大小的低雙字,如果lpFileSizeHigh參數不是NULL,函數將文件大小的高雙字放入它指向的DWORD變量中。

如果函數執行失敗,并且 lpFileSizeHigh是NULL,返回值將是INVALID_FILE_SIZE;如果函數執行失敗,但lpFileSizeHigh不是 NULL,返回值是INVALID_FILE_SIZE,進一步調用GetLastError會返回不為NO_ERROR的值。

如果返回值是INVALID_FILE_SIZE,應用程序必須調用GetLastError來確定函數調用是否成功。原因是,當lpFileSizeHigh不為NULL或者文件大小為 0xffffffff時,函數雖然調用成功了,但依然會返回INVALID_FILE_SIZE。這種情況下,GetLastError會返回 NO_ERROR來響應成功。

3.獲取文件屬性

如果要查看文件或者目錄的屬性,可以使用GetFileAttributes函數,它會返回一系列FAT風格的屬性信息。

DWORD GetFileAttributes(LPCTSTR lpFileName);??????? // lpFileName指定了文件或者目錄的名稱

函數執行成功,返回值包含了指定文件或目錄的屬性信息,可以是下列取值的組合:

l????????? ?FILE_ATTRIBUTE_ARCHIVE ??????????????? 文件包含歸檔屬性

l????????? ?FILE_ATTRIBUTE_COMPRESSED ?????? 文件和目錄被壓縮

l????????? ?FILE_ATTRIBUTE_DIRECTORY ?????????? 這是一個目錄

l????????? ?FILE_ATTRIBUTE_HIDDEN ?????????????????????????? 文件包含隱含屬性

l????????? ?FILE_ATTRIBUTE_NORMAL ??????????????? 文件沒有其他屬性

l????????? ?FILE_ATTRIBUTE_READONLY ??????????? 文件包含只讀屬性

l????????? ?FILE_ATTRIBUTE_SYSTEM ????????????????? 文件包含系統屬性

l????????? ?FILE_ATTRIBUTE_TEMPORARY T ???? 文件是一個臨時文件

這些屬性對目錄也同樣適用。INVALID_FILE_ATTRIBUTES(0xFFFFFFFF)是函數執行失敗后的返回值。

下面是快速檢查某個文件或目錄是否存在的自定義函數,可以將它用在自己的工程中。

BOOL FileExists(LPCTSTR lpszFileName, BOOL bIsDirCheck)

{?????? // 試圖取得文件的屬性

?????????????????? DWORD dwAttributes = GetFileAttributes(lpszFileName);

??? ?if(dwAttributes == 0xFFFFFFFF)

??????? return FALSE;

???????? if ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)

???????? {?????? if (bIsDirCheck)

??????????????????????????? return TRUE;

?????????????????? else

??????????????????????????? return FALSE;

???????? }

???????? else

???????? {?????? if (!bIsDirCheck)

??????????????????????????? return TRUE;

?????????????????? else

??????????????????????????? return FALSE;

???????? }

}

第2個參數bIsDirCheck指定要檢查的對象是目錄還是文件。

與GetFileAttributes相對應的函數是SetFileAttributes,這個函數用來設置文件屬性。

BOOL SetFileAttributes(

? LPCTSTR lpFileName,????????????? // 目標文件名稱

? DWORD dwFileAttributes???????????????? // 要設置的屬性值

);

8.1.3? 常用文件操作

1.拷貝文件

拷貝文件的函數是CopyFile和CopyFileEx,其作用都是復制一個存在的文件到一個新文件中。CopyFile函數的用法如下:

BOOL CopyFile(

? LPCTSTR lpExistingFileName, // 指定已存在的文件的名稱

? LPCTSTR lpNewFileName,??????????????? // 指定新文件的名稱

? BOOL bFailIfExists ?????????????????? // 如果指定的新文件存在是否按出錯處理

);

CopyFileEx函數的附加功能是允許指定一個回調函數,在拷貝過程中,函數每拷貝完一部分數據,就會調用回調函數。用戶在回調函數中可以指定是否停止拷貝,還可以顯示進度條來指示拷貝的進度。

2.刪除文件

刪除文件的函數是DeleteFile,僅有的參數是要刪除文件的名稱。

BOOL DeleteFile(LPCTSTR lpFileName);

如果應用程序試圖刪除不存在的文件,DeleteFile將執行失敗。如果目標文件是只讀的,函數也會執行失敗,出錯代碼為ERROR_ACCESS_DENIED。為了刪除只讀文件,先要去掉其只讀屬性。

DeleteFile函數可以標識一個文件為“關閉時刪除”。因此,直到最后一個到此文件的句柄關閉之后,文件才會被刪除。

下面的自定義函數RecursiveDelete示例了如何刪除指定目錄下的所有文件和子目錄。

void RecursiveDelete(CString szPath)

{?????? CFileFind ff;?????? // MFC將查找文件的API封裝到了CFileFind類。讀者可參考下面的框架使用這個類

???????? CString strPath = szPath;

???????? // 說明要查找此目錄下的所有文件

???????? if(strPath.Right(1) != """")

?????????????????? strPath += """";

???????? strPath += "*.*";

???????? BOOL bRet;

???????? if(ff.FindFile(strPath))

???????? {?????? do

?????????????????? {?????? bRet = ff.FindNextFile();

??????????????????????????? if(ff.IsDots())? // 目錄為“.”或者“..”?

???????????????????????????????????? continue;

??????????????????????????? strPath = ff.GetFilePath();

??????????????????????????? if(!ff.IsDirectory())

??????????????????????????? {?????? // 刪除此文件

???????????????????????????????????? ::SetFileAttributes(strPath, FILE_ATTRIBUTE_NORMAL);

???????????????????????????????????? ::DeleteFile(strPath);

??????????????????????????? }

??????????????????????????? else

??????????????????????????? {?????? // 遞歸調用

???????????????????????????????????? RecursiveDelete(strPath);

???????????????????????????????????? // 刪除此目錄(RemoveDirectory只能刪除空目錄)

???????????????????????????????????? ::SetFileAttributes(strPath, FILE_ATTRIBUTE_NORMAL);

???????????????????????????????????? ::RemoveDirectory(strPath);

??????????????????????????? }

?????????????????? }

?????????????????? while(bRet);

???????? }

}

用DeleteFile函數刪除的文件不會被放到回收站,它們將永遠丟失,所以請小心使用RecursiveDelete函數。

3.移動文件

移動文件的函數是MoveFile和MoveFileEx函數。它們的主要功能都是用來移動一個存在的文件或目錄。MoveFile函數用法如下:

BOOL MoveFile(

? LPCTSTR lpExistingFileName, // 存在的文件或目錄

? LPCTSTR lpNewFileName???????????????? // 新的文件或目錄

);

當需要指定如何移動文件時,請使用MoveFileEx函數。

BOOL MoveFileEx(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, DWORD dwFlags);

dwFlags參數可以是下列值的組合:

l????????? MOVEFILE_DELAY_UNTIL_REBOOT ???? 函數并不馬上執行,而是在操作系統下一此重新啟動時才移動文件。在AUTOCHK執行之后,系統立即移動文件,這是在創建任何分頁文件之前進行的。因此,這個值使函數能夠刪除上一次運行時使用的分頁文件。只有擁有管理員權限的用戶才可以使用這個值

l????????? MOVEFILE_REPLACE_EXISTING ??????????? 如果目標文件已存在的話,就將它替換掉

l????????? MOVEFILE_WRITE_THROUGH???????????????? 直到文件實際從磁盤移除之后函數才返回

如果指定了MOVEFILE_DELAY_UNTIL_REBOOT標記,lpNewFileName參數可以指定為NULL,這種情況下,當系統下一次啟動時,操作系統會刪除lpExistingFileName參數指定的文件。

8.1.4 ?檢查PE文件有效性的例子

PE文件格式是任何可執行模塊或者DLL的文件格式,PE文件以64字節的DOS文件頭(IMAGE_DOS_HEADER結構)開始,之后是一小段DOS程序,然后是248字節的NT文件頭(IMAGE_NT_HEADERS結構)。NT文件頭的偏移地址由IMAGE_DOS_HEADER結構的e_lfanew成員給出。

檢查文件是不是有效PE文件的一個方法是檢查IMAGE_DOS_HEADER和IMAGE_NT_HEADERS結構是否有效。IMAGE_DOS_HEADER結構定義如下:

typedef struct _IMAGE_DOS_HEADER {?????

??? WORD?? e_magic;???????????????????? ? // DOS可執行文件標記,為“MZ”。依此識別DOS頭是否有效

???????? ...????????????????????????????????????????????????????????????? // 其他成員,沒什么用途

??? LONG?? e_lfanew;??????????????????? ?? // IMAGE_NT_HEADERS結構的地址

? } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

IMAGE_NT_HEADERS結構定義如下:

typedef struct _IMAGE_NT_HEADERS {?

???????? ???????? ???????? DWORD Signature;? ?????????? // PE文件標識,為“PE"0"0”。依此識別NT文件頭是否有效

???????? ???????? ???????? IMAGE_FILE_HEADER FileHeader;?

???????? ???????? ???????? IMAGE_OPTIONAL_HEADER OptionalHeader;

???????? ???????? } IMAGE_NT_HEADERS,

為了編程方便,Windows為DOS文件標記和PE文件標記都定義了宏標識。

#define IMAGE_DOS_SIGNATURE???????????????? 0x5A4D????? // MZ

#define IMAGE_NT_SIGNATURE????????????????? 0x00004550? ?? // PE00

檢查文件是否為PE文件的步驟如下:

(1)檢驗文件頭部第一個字的值是否等于IMAGE_DOS_SIGNATURE,是則說明DOS MZ頭有效。

(2)一旦證明文件的DOS頭有效后,就可用e_lfanew來定位PE頭了。

(3)比較PE頭的第一個字是否等于IMAGE_NT_SIGNATURE。如果這個值也匹配,那么就認為該文件是一個有效的PE文件。

下面是驗證PE文件有效性的代碼,在配套光盤的08ValidPE工程下。

BOOL CMyApp::InitInstance()

{?????? // 彈出選擇文件對話框

???????? CFileDialog dlg(TRUE);

???????? if(dlg.DoModal() != IDOK)

?????????????????? return FALSE;

???????? // 打開檢查的文件

???????? HANDLE hFile = ::CreateFile(dlg.GetFileName(), GENERIC_READ,

?????????????????? FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

???????? if(hFile == INVALID_HANDLE_VALUE)

???????? ?????????????????? MessageBox(NULL, "無效文件!", "ValidPE", MB_OK);

???????? // 定義PE文件中的DOS頭和NT頭

???????? IMAGE_DOS_HEADER dosHeader;

???????? IMAGE_NT_HEADERS32 ntHeader;

???????? // 驗證過程

???????? BOOL bValid = FALSE;

???????? DWORD dwRead;

???????? // 讀取DOS頭

???????? ::ReadFile(hFile, &dosHeader, sizeof(dosHeader), &dwRead, NULL);

???????? if(dwRead == sizeof(dosHeader))

???????? {?????? if(dosHeader.e_magic == IMAGE_DOS_SIGNATURE) // 是不是有效的DOS頭?

?????????????????? {?????? // 定位NT頭

??????????????????????????? if(::SetFilePointer(hFile, dosHeader.e_lfanew, NULL, FILE_BEGIN) != -1)

??????????????????????????? {?????? // 讀取NT頭

???????????????????????????????????? ::ReadFile(hFile, &ntHeader, sizeof(ntHeader), &dwRead, NULL);

???????????????????????????????????? if(dwRead == sizeof(ntHeader))

???????????????????????????????????? {?????? if(ntHeader.Signature == IMAGE_NT_SIGNATURE)????? // 是不是有效的NT頭

??????????????????????????????????????????????????????? bValid = TRUE;

???????????????????????????????????? }

??????????????????????????? }

?????????????????? }

???????? }

???????? // 顯示結果

???????? if(bValid)

?????????????????? MessageBox(NULL, "是一個PE格式的文件!", "ValidPE", MB_OK);

???????? else

?????????????????? MessageBox(NULL, "不是一個PE格式的文件!", "ValidPE", MB_OK);

???????? ::CloseHandle(hFile);

???????? return FALSE;

}

上述代碼簡單明確,先利用Windows定義的宏 IMAGE_DOS_SIGNATURE判斷DOS頭,比較DOS頭的e_magic字段;再通過DOS頭的e_lfanew字段定位到NT頭;最后檢查 NT頭的Signature字段是不是IMAGE_NT_SIGNATURE(即“PE"0"0”)。

8.1.5? MFC的支持(CFile類)

CFile是一個相當簡單的封裝了一部分文件I/O 處理函數的類。它的成員函數用于打開和關閉文件、讀寫文件數據、刪除和重命名文件、取得文件信息。它的公開成員變量m_hFile保存了與CFile對象關聯的文件的文件句柄。一個受保護的CString類型的成員變量m_strFileName保存了文件的名稱。成員函數GetFilePath、 GetFileName和GetFileTitle能夠用來提取整個或者部分文件名。比如,如果完整的文件名是“C:"MyWork" File.txt”,GetFilePath返回整個字符串,GetFileName返回“File.txt”,GetFileTitle返回 “File”。

但是詳述這些函數就會忽略CFile類的特色,這就是用來寫數據到磁盤和從磁盤讀數據的函數。下面簡單介紹CFile類用法。

1.打開和創建文件

使用CFile類打開文件有兩種方法。

(1)構造一個未初始化的CFile對象,調用CFile::Open函數。下面的部分代碼使用這個技術以讀寫權限打開一個名稱為File.txt的文件。

CFile file;

if(file.Open(_T ("File.txt"), CFile::modeReadWrite))

{?????? // 打開文件成功}

CFile::Open函數的返回值是BOOL類型的變量。如果打開文件出錯,還想進一步了解出錯的原因,可以創建一個CFileException對象,傳遞它的地址到Open函數的第3個參數。

CFile file;

CFileException e;

if (file.Open(_T ("File.txt"), CFile::modeReadWrite, &e))

{?????? // 打開文件成功}

else

{?????? // 打開文件失敗,告訴用戶原因

???????? e.ReportError();

}

如果打開失敗,CFile::Open函數會使用描述失敗原因的信息初始化一個CFileException對象。ReportError成員函數基于這個信息顯示一個出錯對話框。可以通過檢查 CFileException類的公有成員m_cause找到導致這個錯誤的原因。

(2)使用CFile類的構造函數。可以將創建文件對象和打開文件合并成一步,如下面代碼所示。

CFile file(_T ("File.txt"), CFile::modeReadWrite);

如果文件不能被打開,CFile的構造函數會拋出一個CFileException異常。因此,使用CFile::CFile函數打開文件的代碼通常使用try和catch塊來捕獲錯誤。

try

{?????? CFile file(_T ("File.txt"), CFile::modeReadWrite);

}

catch(CFileException* e)

{?????? // 出錯了!

???????? e->ReportError();

???????? e->Delete();

}

刪除MFC拋出的異常是程序寫作者的責任,所以在程序中處理完異常之后要調用異常對象的Delete函數。

為了創建一個文件而不是打開一個存在的文件,要在CFile::Open或者CFile構造函數的第二個參數中包含上CFile::modeCreate標記,如下代碼所示。

CFile file(_T("File.txt"), CFile::modeReadWrite | CFile::modeCreate);

如果以這種方式創建的文件存在,它的長度會被截為0。為了在文件不存在時創建它,存在的時候僅打開而不截去,應再包含上CFile::modeNoTruncate標記,如下面代碼所示。

CFile file(_T("File.txt"), CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate);

默認情況下,由CFile::Open或 CFile::CFile打開的文件使用的是獨占模式,即CreateFile API中的第3個參數dwShareMode被設為了0。如果需要,在打開文件時也可以指定一個共享模式,以明確同意其他訪問此文件的操作。這里是4個可以選擇的共享模式:

l????????? CFile::shareDenyNone ??????? 不獨占這個文件

l????????? CFile::shareDenyRead ???????? 拒絕其他代碼對這個文件進行讀操作

l????????? CFile::shareDenyWrite ??????? 拒絕其他代碼對這個文件進行寫操作

l????????? CFile::shareExclusive ?????????? 拒絕其他代碼對這個文件進行讀和寫操作(默認)

另外,還可以指定下面3個對象訪問類型中的一個:

l????????? CFile::modeReadWrite ??????? 請求讀寫訪問

l????????? CFile::modeRead ???????????????? 僅請求讀訪問

l????????? CFile::modeWrite ??????????????? 僅請求寫訪問

常用的做法是允許其他程序以只讀方式打開文件,但是拒絕它們寫入數據。

CFile file(_T("File.txt"), CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate);

如果在上面的代碼執行之前,文件已經以可寫的方式打開了,這個調用將會失敗,CFile類會拋出CFileException異常,異常對象的m_cause成員等于CFileException::sharingViolation。

CFile類的成員函數Close會調用 CloseHandle API關閉應用程序打開的文件對象句柄。如果句柄沒有關閉,類的析構函數也會調用Close函數關閉它。顯式調用Close函數一般都是為了關閉當前打開的文件,以便使用同樣的CFile對象打開另一個文件。

2.讀寫文件

CFile類中從文件中讀取數據的成員函數是Read。例如,下面的代碼申請了一塊4KB大小的文件I/O緩沖區,每次從文件讀取4KB大小的數據。

BYTE buffer[4096];

CFile file (_T("File.txt"), CFile::modeRead);

DWORD dwBytesRemaining = file.GetLength();

while(dwBytesRemaining)

{?????? UINT nBytesRead = file.Read(buffer, sizeof(buffer));

???????? dwBytesRemaining -= nBytesRead;

}

文件中未讀取的字節數保存在 dwBytesRemaining變量里,此變量由CFile::GetLength返回的文件長度初始化。每次調用Read之后,從文件中讀取的字節數(nBytesRead)會從dwBytesRemaining變量里減去。直到dwBytesRemaining為0整個while循環才結束。

CFile類還提供了Write成員函數向文件寫入數據,Seek成員函數移動文件指針,它們都和相關API一一對應。可以通過跟蹤程序的執行來查看這些函數的實現代碼。

posted @ 2008-03-20 08:44 Da Vinci 閱讀(191) | 評論 (0) |?編輯

.NET下午茶之二: 值類型與引用類型的區別(轉載)

使用值類型還是引用類型?結構體(structs)還是類(class)?什么情況下兩者都可以使用?這并不是C++,你可以為任何類型的對象建立指針來引用他們。這也不是java,任何類型都自動聲明為引用類型。你需要想清楚你將要定義的類型會有怎樣的行為。首次能否選擇對是至關重要的,一旦你決定使用哪種類型,你就要承擔相應的后果,因為如果你后面修改了你之前定義的類型將會給你的代碼帶來潛在的不連貫性。使用struct或class關鍵字來創建你的類型是件簡單的事情,但是在后面更新或修改這些你所定義的類型將需要做更多的工作。

選擇正確的類型而不是你所偏好的類型并不是件簡單的事情。正確的選擇取決于你期望如何使用你所定義的新類型。值類型不支持多態。它更傾向于用在為你的應用程序來存儲數據上。引用類型支持多態而且應該用在定義你程序的行為上。考慮以上你所定義的新類型將會用于哪種用途,然后根據正確的用途來決定你將要創建的類型。結構體(struct)用于存儲數據。類(class)用于定義行為(beahavior)

值類型和引用類型之間的區別被加進.Net和C#中是因為在C++和Java中這些問題很普遍。在C++中,所有的參數和返回類型都是以值類型的方式傳遞的。通過值類型來傳遞具有不錯的效率,但它卻有一個問題:部分拷貝(partial copying)也有人稱作對象的切片(slicing the object)。你期望的是使用一個派生的對象,然而只有基類的部分被拷貝了。也就是你丟失了所有派生類對象中所保存的信息。甚至你對虛函數的調用也是基類的版本。

Java語言的對策是從語言中或多或少的消除值類型。所有用戶定義的類型都是引用類型。在Java語言中所有參數和返回類型都是以引用方式傳遞的。這種策略具有一致性的優點,但是它卻犧牲了效率,因為有些類型根本沒有必要是多態的。因此Java程序員需要在堆上分配空間和最終對每個變量進行垃圾回收。它們同樣需要為每個非引用類型而消耗額外的時間。所有的變量都是引用類型的。在C#中,你通過使用struct和class關鍵字來聲明你的類型是值類型還是引用類型。值類型應是當更小,更輕量的類型。引用類型組成了你的類的層次。這段例子分別使用值類型和引用類型來幫助你理解這兩者之間的區別。

在一開始,這個類型使用一個方法返回的值。

private MyData _myData; public MyData Foo() { return _myData; } ? // call it: MyData v = Foo(); TotalSum += v.Value;

如果MyData是值類型,它給v返回了一份值的拷貝。更多的,v是在棧上的。然而,如果MyData是一個引用類型,你傳遞了引用,也就是你把內部數據輸出給外部變量。這樣會違反封裝的原則。

或者我們來考慮做個變化:

private MyData _myData; public MyData Foo() { return _myData.Clone( ) as MyData; } ? // call it: MyData v = Foo(); TotalSum += v.Value;

現在,v就是_myData原版的一個拷貝。作為一個引用類型,它在堆上創建了兩個對象。這樣你就不會再有暴露內部數據的問題了。作為替代,你在堆上建立了額外的對象。如果v是一個局部變量,那么它很快就會變為垃圾碎片而且克隆(clone)會強制進行運行時檢查。總的來說,這是一種沒有效率可言的做法。

用于從公共方法或屬性來獲得數據的類型應當被定義為值類型。但是這并不等同于任何從公共方法返回的類型就是值類型。前面的代碼段假設MyData存儲了值,那么它的職責就是存儲這些值。

但是,考慮下面的代碼段。

private MyType _myType; public IMyInterface Foo() { return _myType as IMyInterface; } ? // call it: IMyInterface iMe = Foo(); iMe.DoWork( );

_myType變量依然是通過Foo方法獲得的返回值。但是這次不同的是,這次沒有訪問返回值的數據,而是訪問了定義在接口中的方法。你訪問的并不是MyType的數據內容,而是它的行為。它的行為是通過ImyInterface這個接口所體現的,也就是說它可以表現成其他不同的行為。在這個例子中,MyType應當是一個引用類型而不是值類型。MyType的職責包含了它的行為,而不是它的數據成員。

上面的代碼段向你展示了它們之間的區別:值類型存儲數據而引用類型定義行為。現在我們更深入的觀察它們在內存中的存儲方式以及相關存儲模型所帶來性能上的問題。考慮這個類:

public class C { ? private MyType _a = new MyType( ); ? private MyType _b = new MyType( ); ? ? // Remaining implementation removed. } ? C var = new C();

上面的代碼里有多少個對象被創建了?它們分別是多大?它視情況而定,如果MyType是一個值類型,你只需要進行一次分配。這次分配的大小就是 MyType大小的兩倍。然而,如果MyType是一個引用類型,你需要做3次分配:一次是為c對象來分配空間,大小是8字節(假設指針的大小是 32bit),剩下兩次則是為包含在c對象中的MyType對象。結果會有差別是因為值類型是以內聯(inline)方式存儲在對象內的,而引用類型不是。每個引用類型的變量只保留一個對象的引用,而實際的存儲則是需要額外的空間。

為了徹底的闡明以上觀點,現在來考慮一下這種情況的空間分配:

MyType [] var = new MyType[ 100 ];

如果MyType是值類型,一次空間分配將會產生MyType對象大小的一百倍空間。然而,如果MyType是引用類型,則只會發生一次空間分配。這個數組中的每一個元素都是null。在堆上分配大量的引用類型變量會使堆變得凌亂瑣碎而且降低運行速度。如果你只是為了存儲數據的話,那么值類型將會是正確的選擇。

對使用值類型還是引用類型所做的討論是很有意義的,將一個值類型轉換成引用類型將會進入更深層次的研究。考慮下面的情況:

public struct Employee { ? private string? _name; ? private int???? _ID; ? private decimal _salary; ? ? // Properties elided ? ? public void Pay( BankAccount b ) ? { ??? b.Balance += _salary; ? } }

上面的簡單類型包含了一個可以讓你支付自己員工的方法。一段時間過去了,系統運行的相當不錯,但是此后你開始定義不同級別的員工:推銷員得到傭金,而經理得到獎金。你決定把Employee由值類型改為引用類型。

public class Employee { ? private string? _name; ? private int???? _ID; ? private decimal _salary; ? ? // Properties elided ? ? public virtual void Pay( BankAccount b ) ? { ??? b.Balance += _salary; ? } }

這個改變破壞了你的用戶所使用的大部分代碼。返回值變成了返回引用。以前參數傳遞的是值而現在傳遞的是引用。下面這一小段的代碼行為被徹底的改變了:

Employee e1 = Employees.Find( "CEO" ); e1.Salary += Bonus; // Add one time bonus. e1.Pay( CEOBankAccount );

每一次加獎金都將是永久的增加。以前通過值拷貝而如今被引用所替代。編譯器很樂于為你做這些事情。CEO肯定也很高興。但另一方面CFO會匯報這個bug。當面對這樣的實際情況時你就不能產生使用引用類型來代替值類型的想法了:因為它改變了行為。

之所以會產生這樣的問題時因為Employee類型不再遵循使用值類型的原則。你所定義的Employee類型不僅儲存了有關員工的數據信息,而且還定義了它的行為,在這個例子中它具有支付員工的行為。這些職責是屬于類(class)的范疇。類可以使得實現公共職能多態化更加簡單;而結構體就無法做到,它應當被限制為只用于數據存儲。

.Net的支持文檔里推薦根據類型的大小來考慮使用值類型或是引用類型。在實際中,值類型善于用在類型易于構造或用于攜帶數據的情況下。在某些方面值類型更加利于內存的管理:產生更少的堆碎片、更少的垃圾。最重要的是當值類型從方法或屬性返回時使用的是拷貝。這就避免了暴露內部數據結構的風險。但是你也將會為這些特點付出一定的代價。值類型在支持面相對象的技術方面有很大的限制,你無法通過值類型來簡直具有層次的對象,你只能把所有的值類型的對象看成封閉(sealed)的來考慮。你可以用值類型來實現接口,但是那需要采用拆裝箱技術,這將會帶來性能上的損失。考慮值類型只作為存儲數據的容器,而不具有面相對象的意義。

你還是會更加常用到引用類型。如果你能肯定的回答以下的這些問題,那么你就可以放心的使用值類型。比較之前的Employee的例子來考慮下面這些問題:

1. 你所要聲明的類型是否只承擔存儲數據的責任。

2. 你所要聲明的類型的數據訪問接口是否全部定義為了屬性(properties)。

3. 你是否確定它永遠都不會有派生類。

4. 你是否確定它永遠都不會被看作多態對待。

構建低等級的數據存儲類型時使用值類型。構建具有行為的程序時使用引用類型。你從你創建的類的對象中安全獲得數據拷貝。以棧作為基礎并使用內聯的值存儲方式更加有益與內存的利用,你可以利用面相對象的標準技術來建立你引用程序的邏輯。當你疑惑該使用哪種類型時,使用引用類型吧!

參考:http://blog.csdn.net/knight94/archive/2006/07/01/861383.aspx

posted @ 2008-03-20 08:37 Da Vinci 閱讀(19) | 評論 (3) |?編輯

(From MS)Vista: 啟動配置數據編輯器(BCD)

什么是 BCD 存儲?

啟動配置數據 (BCD) 存儲包含啟動配置參數,并控制 Microsoft? Windows?Vista? 操作系統和代號為“Longhorn”的 Microsoft? Windows?Server? 操作系統的啟動方式。這些參數以前位于 Boot.ini 文件(在基于 BIOS 的操作系統中)或穩定 RAM (NVRAM) 條目中(在基于可擴展固件接口的操作系統中)。您可以使用 Bcdedit.exe 命令行工具在 BCD 存儲中添加、刪除、編輯和追加條目,以影響在預操作系統環境中運行的 Windows? 代碼。Bcdedit.exe 位于 Windows?Vista 分區的 "Windows"System32 目錄下。

??注意

雖然本文檔主要介紹 Windows?Vista 相關內容,但此信息同樣適用于 Windows?Server“Longhorn”。

??注意

要在命令提示符下獲得詳細的命令和選項信息,請鍵入 bdedit.exe /?命令。例如,鍵入 bcdedit.exe /?CREATESTORE

為什么從 Boot.ini 改為 BCD?

創建 BCD 的目的是為描述啟動配置數據提供一種改進機制。隨著新固件模型的不斷涌現(例如,可擴展固件接口 (EFI)),人們需要一種可擴展和可互操作的接口來實現基礎固件的抽象化。這一全新設計為 Windows?Vista 中的各種新功能(例如,啟動修復工具和多用戶安裝快捷方式)提供了支持基礎。

BCD 文件位于注冊表中的哪一位置?

  • 基于 BIOS 的操作系統。BCD 注冊表文件位于活動分區的 "Boot"Bcd 目錄下。
  • 基于 EFI 的操作系統。BCD 注冊表文件位于 EFI 系統分區中。

是否任何用戶都可以修改 BCD?

否。您需要提供管理憑據才能修改 BCD。

可以通過哪些方式修改 BCD?

根據您要更改的內容,可以使用下列工具修改 BCD:

  • 啟動和故障恢復。如果您的計算機上安裝了多個操作系統,則通過“啟動和故障恢復”。
  • 系統配置實用程序 (Msconfig.exe)。Msconfig.exe 是一款更高級的工具,其功能包含下列選項:/debug/safeboot/bootlog/noguiboot/basevideo/numproc
  • BCD WMI 提供程序。BCD Windows Management Instrumentation (WMI) 提供程序是一個管理接口,可用于編寫修改 BCD 的實用程序腳本。這是唯一可用于 BCD 的編程接口。有關詳細信息,請參閱 Microsoft 網站上的“啟動配置數據 (BCD)”(http://go.microsoft.com/fwlink/?LinkId=56792)。
  • BCDEdit.exe。BCDEdit.exe 是 Windows?Vista 中取代 Bootcfg.exe 的命令行實用程序。有關詳細信息,請參閱使用 Bcdedit.exe 可執行哪些操作?

為什么在 EFI 啟動管理器中看不到任何 Windows 條目?為什么有兩個啟動管理器?

所有 Windows 條目都存儲在 BCD 存儲中。在基于 EFI 的操作系統中,EFI 固件啟動管理器中只有一個名為“Windows 啟動管理器”的條目。此文件位于 "EFI"Microsoft"Boot"Bootmgfw.efi。如果使用 EFI 啟動管理器啟動 Windows 啟動管理器,則基于 EFI 的操作系統和基于 PC/AT 的操作系統將提供相同的外觀和用戶體驗。例如,高級啟動選項菜單均可供使用。EFI 啟動管理器的默認超時值為 2 秒,以便能夠在 Windows Server?2003 (Service Pack?1) 與 Windows?Vista 之間更輕松地進行啟動切換。

返回頁首

多重引導環境

是否可以在已經包含某個操作系統的計算機上安裝 Windows Vista?

可以。您可以將 Windows?Vista 安裝在另一個分區上。最好在安裝舊版操作系統之后安裝 Windows?Vista。舊版操作系統將繼續使用 Boot.ini 來進行啟動配置。

在 Windows Vista 中,是否可以將過去使用 Boot.ini 的代碼替換為現在使用 BCD?

不可以。您需要將代碼改為針對舊版操作系統使用 Boot.ini,而針對 Windows?Vista 使用 BCD。

在多重引導環境中,在 Windows Vista 之前的操作系統上修改 BCD 是否會修改啟動配置?

不會。您需要修改 BCD 以更改 Windows?Vista 的啟動配置。但要更改舊版操作系統的啟動配置,則還需要修改 Boot.ini(如果是基于 BIOS 的操作系統)或 NVRAM(如果是基于 EFI 的操作系統)。

如果不引導到 Windows Vista,是否可以完全禁用 BCD?

不可以。因為首先會運行 Windows?Vista 的啟動管理器以確定要啟動哪個操作系統。因此,如果希望引導到舊版操作系統,則必須在 BCD 存儲中將默認順序設置為舊版操作系統。有關詳細信息,請參閱如何更改默認操作系統條目

返回頁首

BCDedit.exe

什么是 Bcdedit.exe?

您可以使用 Bcdedit.exe 在 BCD 存儲中添加、刪除、編輯和追加條目,以修改在預操作系統環境中運行的 Windows 代碼。Bcdedit.exe 位于 Windows?Vista 分區的 "Windows"System32 目錄下。

使用 Bcdedit.exe 可以執行哪些操作?

Bcdedit.exe 目前使您能夠執行下列操作:

  • 為稍后安裝 Windows?Server“Longhorn”創建一個 BCD 存儲。
  • 向現有 BCD 存儲中添加條目。
  • 修改 BCD 存儲中的現有條目。
  • 刪除 BCD 存儲中的條目。
  • 將條目導出到 BCD 存儲。
  • 導入來自 BCD 存儲的條目。
  • 列出當前處于活動狀態的設置。
  • 查詢特定類型的條目。
  • (向所有條目)應用全局更改。
  • 更改默認超時值。

當運行 bcdedit /enum 時,為什么會得到一個 Windows 啟動管理器條目、若干 Windows 啟動加載器條目和一個舊條目?

啟動環境分為兩個類別:Windows 啟動管理器和在啟動環境中運行的各種啟動應用程序。Windows 啟動管理器實質上是一個微型操作系統,可控制您的啟動體驗并使您能夠選擇要運行的啟動應用程序。啟動應用程序有很多種(例如 Windows 啟動加載器),并且每種啟動應用程序所執行的任務都有所不同。例如,Windows 啟動加載器應用程序將加載 Windows。

如果指定 /enum 時,您將獲得以下內容:

  • 一個 Windows 啟動管理器條目(因為只有一個啟動管理器)。
  • 適用于計算機上安裝的每個 Windows?Vista 操作系統的 Windows 啟動加載器應用程序。例如,如果您在不同分區上安裝了兩個不同版本的 Windows?Vista,就會看到兩個 Windows 啟動加載器條目。
  • 一 個舊條目。此條目并不是啟動應用程序,但它使用 NTLDR 和 Boot.ini 引導至 Windows?Vista 之前的操作系統。您可以使用此條目引導至 Windows Server?2003、Windows XP 或其他早期操作系統(如果計算機上安裝了該操作系統)。

Bcdedit.exe 是否具有命令行幫助?

有。要在命令提示符下獲得詳細的命令和選項信息,請鍵入 bdedit.exe /?bdedit.exe /?命令。例如,鍵入 bcdedit.exe /?CREATESTORE

返回頁首

執行熟悉任務的新方式

如何更改全局 zf 設置

在命令提示符下鍵入:

bcdedit /dbgsettingsDebugType[debugport:Port] [baudrate:Baud]

[channel:Channel] [targetname:TargetName]

?
選項說明

DebugType

指定調試器的類型。DebugType 可以是 SERIAL、1394 或 USB 之一。其余選項

取決于所選的調試器類型。

Port

用于 SERIAL 調試,指定用作調試端口的串行端口。

Baud

用于 SERIAL 調試,指定調試使用的波特率。

Channel

用于 1394 調試,指定調試使用的 1394 通道。

TargetName

用于通用串行總線 (USB) 調試,指定調試使用的 USB 目標名稱。

示例

以下命令將指定條目設為默認

啟動管理器條目:

bcdedit /default {cbd971bf-b7b8-4885-951a-fa03044f5d71}

以下命令將舊 Windows 加載器 (Ntldr) 設為

默認條目:{466f5a88-0af2-4f76-9038-095b170dc21c} 是 Ntldr 的預定義 GUID。

bcdedit /default {466f5a88-0af2-4f76-9038-095b170dc21c}

如何更改下一次重新啟動的啟動順序

在命令提示符下鍵入:

bcdedit /bootsequence {ID} {ID} {ID} …

?
選項說明

ID

指定構成下一次重新啟動的啟動順序的 GUID。 在此一次性啟動過后,它將還原為默認啟動順序。

示例

以下命令在啟動管理器顯示順序中設置三個操作系統條目:

Bcdedit.exe /displayorder {c84b751a-ff09-11d9-9e6e-0030482375e6} {c74b751a-ff09-11d9-9e6e-0030482375e4} {c34b751a-ff09-11d9-9e6e-0030482375e7}

以下命令在啟動管理器顯示順序中設置兩個操作系統條目和舊 Windows 加載器:

bcdedit /displayorder {802d5e32-0784-11da-bd33-000476eba25f}

以下命令在啟動菜單顯示順序的最后添加由 GUID 表示的條目:

bcdedit.exe /displayorder {c84b751a-ff09-11d9-9e6e-0030482375e6}-addlast

如何刪除啟動項目

在命令提示符下鍵入:

bcdedit /delete ID [/f]

?
選項說明

ID

指定要刪除的啟動項目的 GUID。如果不指定 ID,則刪除當前啟動項目 ID。

如果指定一個已知 GUID,則必須通過指定 /f 強制進行刪除。例如:

bcdedit /delete {default} /f

示例

以下命令將列出所有操作系統加載器啟動項目:

bcdedit /enum osloader

以下命令將列出所有啟動管理器條目:

bcdedit /enum bootmgr

在運行 Windows Vista 的計算機上安裝舊版 Windows 時如何修改 BCD

要在運行 Windows?Vista 的計算機上安裝舊版 Windows 操作系統,請使用以下過程。

在運行 Windows Vista 的計算機上安裝舊版 Windows

  • 安裝舊版 Windows。
  • 登錄到舊版操作系統,并通過運行以下命令還原最新的啟動管理器。Fixntfs.exe 將位于活動分區 fixntfs /lh 的 "boot 目錄下。
  • 通過指定以下內容,為舊版操作系統創建一個 BCD 條目。Bcdedit.exe 位于 Windows?Vista 分區的 "Windows"System32 目錄下。Description 是對舊版操作系統中新條目的描述。

    Bcdedit /create {legacy} /d “Description

    Bcdedit /set {legacy} device boot

    Bcdedit /set {legacy} path "ntldr

    Bcdedit /displayorder {legacy} /addlast

  • 重新啟動計算機以使更改生效。
  • 如何創建一個可從硬盤啟動 WIM 映像的條目

    要創建一個可啟動 Windows 映像格式 (WIM) 映像的條目,您需要創建一個 OSloader 類型的條目,并帶有指向啟動分區的 RAMDISK 選項。為此,請使用以下過程。在此過程中,arcpath multi(0)disk(0)rdisk(0)partition(1) 是指計算機上的 C: 驅動器,Boot.wim 是一個常規 Boot.wim,其中 Winload.exe 位于該 WIM 映像的 System32 文件夾中。

    創建一個可從硬盤啟動 WIM 映像的條目

  • 通過指定以下內容,在您的 BCD 存儲中創建 {ramdisktoptions} 對象。Drive 應是包含該映像的驅動器。

    bcdedit /create {ramdiskoptions} /d "Ramdisk options"

    bcdedit /set {ramdiskoptions} ramdisksdidevice partition=Drive

    bcdedit /set {ramdiskoptions} ramdisksdipath "boot"boot.sdi

  • 通過指定以下內容,創建新的啟動應用程序條目:

    bcdedit /create /d "Boot from WIM" /application OSLOADER

  • 這將為新創建的條目返回一個標識符 (GUID)。此過程的其他部分將使用 {GUID} 指代該新條目。接下來指定以下內容:

    bcdedit /set {GUID} device ramdisk=[c:]"sources"boot.wim,{ramdiskoptions}

    bcdedit /set {GUID} path "windows"system32"winload.exe

    bcdedit /set {GUID} osdevice ramdisk=[c:]"sources"boot.wim,{ramdiskoptions}

    bcdedit /set {GUID} systemroot "windows

  • 如果要引導到 Windows 預安裝環境 (Windows PE),則還需要指定:

    bcdedit /set {GUID} winpe yes

    bcdedit /set {GUID} detecthal yes

  • 繼續指定以下內容,將新條目添加到顯示順序中:

    bcdedit /displayorder {GUID} /addlast

  • 如何更改特定條目的調試器設置

    要覆蓋特定調試器設置的全局條目,請鍵入以下命令之一。

    ??注意

    此命令不會為特定啟動項目啟用或禁用調試器。

    • 要設置串行調試,請鍵入:

      bcdedit /set {GUID} debugtype:serial

      bcdedit /set {GUID} baudrate:Baudrate

      bcdedit /set {GUID} debugport:Port

    • 要設置 USB 調試,請鍵入:

      bcdedit /set {GUID} debugtype:usbbcdedit /set {GUID} targetname:debugging

    • 要設置 1394 調試,請鍵入:

      bcdedit /set {GUID} debugtype:1394bcdedit /set {GUID} targetname:32

    示例

    以下命令將 c74b751a-ff09-11d9-9e6e-0030482375e4 的調試器設置設為以 115,200 的波特率在 com1 上串行調試:

    Bcdedit /set {c74b751a-ff09-11d9-9e6e-0030482375e4} debugtype:serial

    Bcdedit /set {c74b751a-ff09-11d9-9e6e-0030482375e4} baudrate:115200

    Bcdedit /set {c74b751a-ff09-11d9-9e6e-0030482375e4} debugport:1

    posted @ 2008-03-20 08:33 Da Vinci 閱讀(115) | 評論 (0) |?編輯

    Windows: "net use" command introduction

    1)建立空連接:
    net use ""IP"ipc$ "" /user:"" (一定要注意:這一行命令中包含了3個空格)

    2)建立非空連接:
    net use ""IP"ipc$ "密碼" /user:"用戶名" (同樣有3個空格)

    3)映射默認共享:
    net use z: ""IP"c$ "密碼" /user:"用戶名" (即可將對方的c盤映射為自己的z盤,其他盤類推)
    如果已經和目標建立了ipc$,則可以直接用IP+盤符+$訪問,具體命令 net use z: ""IP"c$

    4)刪除一個ipc$連接
    net use ""IP"ipc$ /del

    5)刪除共享映射
    net use c: /del 刪除映射的c盤,其他盤類推
    net use * /del 刪除全部,會有提示要求按y確認

    3 查看遠程主機的共享資源(但看不到默認共享)
    net view ""IP

    4 查看本地主機的共享資源(可以看到本地的默認共享)
    net share

    5 得到遠程主機的用戶名列表
    nbtstat -A IP

    6 得到本地主機的用戶列表
    net user

    7 查看遠程主機的當前時間
    net time ""IP

    8 顯示本地主機當前服務
    net start

    9 啟動/關閉本地服務
    net start 服務名 /y
    net stop 服務名 /y

    10 映射遠程共享:
    net use z: ""IP"baby
    此命令將共享名為baby的共享資源映射到z盤

    11 刪除共享映射
    net use c: /del 刪除映射的c盤,其他盤類推
    net use * /del /y刪除全部

    12 向遠程主機復制文件
    copy "路徑"srv.exe ""IP"共享目錄名,如:
    copy ccbirds.exe ""*.*.*.*"c 即將當前目錄下的文件復制到對方c盤內

    13 遠程添加計劃任務
    at ""ip 時間 程序名,如:
    at ""127.0.0.0 11:00 love.exe
    注意:時間盡量使用24小時制;在系統默認搜索路徑(比如system32/)下不用加路徑,否則必須加全路徑
    14 開啟遠程主機的telnet
    這里要用到一個小程序:opentelnet.exe,各大下載站點都有,而且還需要滿足四個要求:

    1)目標開啟了ipc$共享
    2)你要擁有管理員密碼和帳號
    3)目標開啟RemoteRegistry服務,用戶就該ntlm認證
    4)對WIN2K/XP有效,NT未經測試
    命令格式:OpenTelnet.exe ""server account psw NTLM認證方式 port
    試例如下:c:">OpenTelnet.exe ""*.*.*.* administrator "" 1 90

    15 激活用戶/加入管理員組
    1 net uesr account /active:yes
    2 net localgroup administrators account /add

    16 關閉遠程主機的telnet
    同樣需要一個小程序:ResumeTelnet.exe
    命令格式:ResumeTelnet.exe ""server account psw
    試例如下:c:">ResumeTelnet.exe ""*.*.*.* administrator ""

    17 刪除一個已建立的ipc$連接
    net use ""IP"ipc$ /del

    posted @ 2008-03-20 08:27 Da Vinci 閱讀(27) | 評論 (0) |?編輯

    2008年3月19日

    .NET下午茶之一: CLR/CTS/CLS

    1. CTS Common Type System:公共類型系統。《Practical .NET2.0 and C#2.0》的解釋是:CTS是.NET平臺的一組類型。這組類型獨立于編寫它們的源代碼語言。CTS是一種規范,它描述了每一個能被CLR識別的類型的特征。CTS是定義公共語言運行庫在聲明、使用和管理類型時所遵循的規則的模型。CTS有值類型、引用類型和指針類型組成。
    2. CLS Common Language Specification:公共語言規范。一組可以以編程方式驗證的規則,這組規范控制用不同編程語言編寫的類型的交互操作。.NET程序員利用CLS 來保證可從多種編程語言調用他們的 API。CLS是CLR/CTS的子集,即某些.NET編程語言可以存在滿足CLS定義的部分,也可以包含不滿足CLS定義的部分。例如C#語言的有符號整型包含在CLS中,但無符號整型卻不是CLS的部分。
    3. CLR Common Language Runtime:公共語言運行時。CLR是整個.NET平臺架構的中心元素,是管理所有.NET程序的軟件層。實際上CLR是運行時駐留在內存中的一段代碼,負責IL代碼編譯為機器語言、異常管理、垃圾回收、加載程序集、解析類型等操作。托管就是由它來托管。它類似于Java中的JVM(虛擬機)。

    posted @ 2008-03-19 21:39 Da Vinci 閱讀(13) | 評論 (0) |?編輯

    (轉載)C++字符串完全指引之一 —— Win32 字符編碼

    C++字符串完全指引之一 —— Win32 字符編碼

    原著:Michael Du

    原文出處:CodeProject:The Complete Guide to C++ Strings, Part I

    引言

    毫無疑問,我們都看到過像 TCHAR, std::string, BSTR 等各種各樣的字符串類型,還有那些以 _tcs 開頭的奇怪的宏。你也許正在盯著顯示器發愁。本指引將總結引進各種字符類型的目的,展示一些簡單的用法,并告訴您在必要時,如何實現各種字符串類型之間的轉換。
    在第一部分,我們將介紹3種字符編碼類型。了解各種編碼模式的工作方式是很重要的事情。即使你已經知道一個字符串是一個字符數組,你也應該閱讀本部分。一旦你了解了這些,你將對各種字符串類型之間的關系有一個清楚地了解。
    在第二部分,我們將單獨講述string類,怎樣使用它及實現他們相互之間的轉換。

    字符基礎 -- ASCII, DBCS, Unicode

    所有的 string 類都是以C-style字符串為基礎的。C-style 字符串是字符數組。所以我們先介紹字符類型。這里有3種編碼模式對應3種字符類型。第一種編碼類型是單子節字符集(single-byte character set or SBCS)。在這種編碼模式下,所有的字符都只用一個字節表示。ASCII是SBCS。一個字節表示的0用來標志SBCS字符串的結束。
    第二種編碼模式是多字節字符集(multi-byte character set or MBCS)。一個MBCS編碼包含一些一個字節長的字符,而另一些字符大于一個字節的長度。用在Windows里的MBCS包含兩種字符類型,單字節字符(single-byte characters)和雙字節字符(double-byte characters)。由于Windows里使用的多字節字符絕大部分是兩個字節長,所以MBCS常被用DBCS代替。
    在DBCS編碼模式中,一些特定的值被保留用來表明他們是雙字節字符的一部分。例如,在Shift-JIS編碼中(一個常用的日文編碼模式),0x81-0x9f之間和 0xe0-oxfc之間的值表示"這是一個雙字節字符,下一個子節是這個字符的一部分。"這樣的值被稱作"leading bytes",他們都大于0x7f。跟隨在一個leading byte子節后面的字節被稱作"trail byte"。在DBCS中,trail byte可以是任意非0值。像SBCS一樣,DBCS字符串的結束標志也是一個單字節表示的0。
    第三種編碼模式是Unicode。Unicode是一種所有的字符都使用兩個字節編碼的編碼模式。Unicode字符有時也被稱作寬字符,因為它比單子節字符寬(使用了更多的存儲空間)。注意,Unicode不能被看作MBCS。MBCS的獨特之處在于它的字符使用不同長度的字節編碼。Unicode 字符串使用兩個字節表示的0作為它的結束標志。
    單字節字符包含拉丁文字母表,accented characters及ASCII標準和DOS操作系統定義的圖形字符。雙字節字符被用來表示東亞及中東的語言。Unicode被用在COM及Windows NT操作系統內部。
    你一定已經很熟悉單字節字符。當你使用char時,你處理的是單字節字符。雙字節字符也用char類型來進行操作(這是我們將會看到的關于雙子節字符的很多奇怪的地方之一)。Unicode字符用wchar_t來表示。Unicode字符和字符串常量用前綴L來表示。例如:

    wchar_t wch = L''1''; // 2 bytes, 0x0031
    wchar_t* wsz = L"Hello"; // 12 bytes, 6 wide characters

    字符在內存中是怎樣存儲的

    單字節字符串:每個字符占一個字節按順序依次存儲,最后以單字節表示的0結束。例如。"Bob"的存貯形式如下:

    426F6200
    BobBOS

    Unicode的存儲形式,L"Bob"

    42 00 6F 0062 0000 00
    BobBOS

    使用兩個字節表示的0來做結束標志。

    一眼看上去,DBCS 字符串很像 SBCS 字符串,但是我們一會兒將看到 DBCS 字符串的微妙之處,它使得使用字符串操作函數和永字符指針遍歷一個字符串時會產生預料之外的結果。字符串" " ("nihongo")在內存中的存儲形式如下(LB和TB分別用來表示 leading byte 和 trail byte)

    93 FA96 7B8C EA00
    LB TBLB TBLB TBEOS
    EOS

    值得注意的是,"ni"的值不能被解釋成WORD型值0xfa93,而應該看作兩個值93和fa以這種順序被作為"ni"的編碼。

    使用字符串處理函數

    我們都已經見過C語言中的字符串函數,strcpy(), sprintf(), atoll()等。這些字符串只應該用來處理單字節字符字符串。標準庫也提供了僅適用于Unicode類型字符串的函數,比如wcscpy(), swprintf(), wtol()等。
    微軟還在它的CRT(C runtime library)中增加了操作DBCS字符串的版本。Str***()函數都有對應名字的DBCS版本_mbs***()。如果你料到可能會遇到DBCS 字符串(如果你的軟件會被安裝在使用DBCS編碼的國家,如中國,日本等,你就可能會),你應該使用_mbs***()函數,因為他們也可以處理SBCS 字符串。(一個DBCS字符串也可能含有單字節字符,這就是為什么_mbs***()函數也能處理SBCS字符串的原因)
    讓我們來看一個典型的字符串來闡明為什么需要不同版本的字符串處理函數。我們還是使用前面的Unicode字符串 L"Bob":

    42 00 6F 0062 0000 00
    BobBOS

    因為x86CPU是little-endian,值0x0042在內存中的存儲形式是42 00。你能看出如果這個字符串被傳給strlen()函數會出現什么問題嗎?它將先看到第一個字節42,然后是00,而00是字符串結束的標志,于是 strlen()將會返回1。如果把"Bob"傳給wcslen(),將會得出更壞的結果。wcslen()將會先看到0x6f42,然后是 0x0062,然后一直讀到你的緩沖區的末尾,直到發現00 00結束標志或者引起了GPF。
    到目前為止,我們已經討論了str***()和wcs***()的用法及它們之間的區別。Str***()和_mbs**()之間的有區別區別呢?明白他們之間的區別,對于采用正確的方法來遍歷DBCS字符串是很重要的。下面,我們將先介紹字符串的遍歷,然后回到str***()與_mbs***() 之間的區別這個問題上來。

    正確的遍歷和索引字符串

    因為我們中大多數人都是用著SBCS字符串成長的,所以我們在遍歷字符串時,常常使用指針的++-和-操作。我們也使用數組下標的表示形式來操作字符串中的字符。這兩種方式是用于SBCS和Unicode字符串,因為它們中的字符有著相同的寬度,編譯器能正確的返回我們需要的字符。
    然而,當碰到DBCS字符串時,我們必須拋棄這些習慣。這里有使用指針遍歷DBCS字符串時的兩條規則。違背了這兩條規則,你的程序就會存在DBCS有關的bugs。

  • 1.在前向遍歷時,不要使用++操作,除非你每次都檢查lead byte;
  • 2.永遠不要使用-操作進行后向遍歷。
  • 我們先來闡述規則2,因為找到一個違背它的真實的實例代碼是很容易的。假設你有一個程序在你自己的目錄里保存了一個設置文件,你把安裝目錄保存在注冊表中。在運行時,你從注冊表中讀取安裝目錄,然后合成配置文件名,接著讀取該文件。假設,你的安裝目錄是C:"Program Files"MyCoolApp,那么你合成的文件名應該是C:"Program Files"MyCoolApp"config.bin。當你進行測試時,你發現程序運行正常。
    現在,想象你合成文件名的代碼可能是這樣的:

    bool GetConfigFileName ( char* pszName, size_t nBuffSize )
    {
    char szConfigFilename[MAX_PATH];

    // Read install dir from registry... we''ll assume it succeeds.

    // Add on a backslash if it wasn''t present in the registry value.
    // First, get a pointer to the terminating zero.
    char* pLastChar = strchr ( szConfigFilename, ''"0'' );

    // Now move it back one character.
    pLastChar--;

    if ( *pLastChar != ''""'' )
    strcat ( szConfigFilename, """" );

    // Add on the name of the config file.
    strcat ( szConfigFilename, "config.bin" );

    // If the caller''s buffer is big enough, return the filename.
    if ( strlen ( szConfigFilename ) >= nBuffSize )
    return false;
    else
    {
    strcpy ( pszName, szConfigFilename );
    return true;
    }
    } 這是一段很健壯的代碼,然而在遇到 DBCS 字符時它將會出錯。讓我們來看看為什么。假設一個日本用戶使用了你的程序,把它安裝在 C:"。下面是這個名字在內存中的存儲形式:
    433A5C83 8883 4583 5283 5C00
    LB TB LB TB LB TB LB TB
    C:"EOS

      當使用 GetConfigFileName() 檢查尾部的''""''時,它尋找安裝目錄名中最后的非0字節,看它是等于''""''的,所以沒有重新增加一個''""''。結果是代碼返回了錯誤的文件名。
    哪里出錯了呢?看看上面兩個被用藍色高量顯示的字節。斜杠''""''的值是0x5c。'' ''的值是83 5c。上面的代碼錯誤的讀取了一個 trail byte,把它當作了一個字符。
    正確的后向遍歷方法是使用能夠識別DBCS字符的函數,使指針移動正確的字節數。下面是正確的代碼。(指針移動的地方用紅色標明)

    bool FixedGetConfigFileName ( char* pszName, size_t nBuffSize )
    {
    char szConfigFilename[MAX_PATH];

    // Read install dir from registry... we''ll assume it succeeds.

    // Add on a backslash if it wasn''t present in the registry value.
    // First, get a pointer to the terminating zero.
    char* pLastChar = _mbschr ( szConfigFilename, ''"0'' );

    // Now move it back one double-byte character.
    pLastChar = CharPrev ( szConfigFilename, pLastChar );

    if ( *pLastChar != ''""'' )
    _mbscat ( szConfigFilename, """" );

    // Add on the name of the config file.
    _mbscat ( szConfigFilename, "config.bin" );

    // If the caller''s buffer is big enough, return the filename.
    if ( _mbslen ( szInstallDir ) >= nBuffSize )
    return false;
    else
    {
    _mbscpy ( pszName, szConfigFilename );
    return true;
    }
    }
    上面的函數使用CharPrev() API使pLastChar向后移動一個字符,這個字符可能是兩個字節長。在這個版本里,if條件正常工作,因為lead byte永遠不會等于0x5c。
    讓我們來想象一個違背規則1的場合。例如,你可能要檢測一個用戶輸入的文件名是否多次出現了'':''。如果,你使用++操作來遍歷字符串,而不是使用CharNext(),你可能會發出不正確的錯誤警告如果恰巧有一個trail byte它的值的等于'':''的值。
    與規則2相關的關于字符串索引的規則: 2a. 永遠不要使用減法去得到一個字符串的索引。

    違背這條規則的代碼和違背規則2的代碼很相似。例如,

    char* pLastChar = &szConfigFilename [strlen(szConfigFilename) - 1];

    這和向后移動一個指針是同樣的效果。

    回到關于str***()和_mbs***()的區別

    現在,我們應該很清楚為什么_mbs***()函數是必需的。Str***()函數根本不考慮DBCS字符,而_mbs***()考慮。如果,你調用strrchr("C:"" ", ''""''),返回結果可能是錯誤的,然而_mbsrchr()將會認出最后的雙字節字符,返回一個指向真的''""''的指針。
    關于字符串函數的最后一點:str***()和_mbs***()函數認為字符串的長度都是以char來計算的。所以,如果一個字符串包含3個雙字節字符,_mbslen()將會返回6。Unicode函數返回的長度是按wchar_t來計算的。例如,wcslen(L"Bob")返回3。

    Win32 API中的MBCS和Unicode

    兩組 APIs:
    盡管你也許從來沒有注意過,Win32中的每個與字符串相關的API和message都有兩個版本。一個版本接受MBCS字符串,另一個接受 Unicode字符串。例如,根本沒有SetWindowText()這個API,相反,有SetWindowTextA()和 SetWindowTextW()。后綴A表明這是MBCS函數,后綴W表示這是Unicode版本的函數。
    當你 build 一個 Windows 程序,你可以選擇是用 MBCS 或者 Unicode APIs。如果,你曾經用過VC向導并且沒有改過預處理的設置,那表明你用的是MBCS版本。那么,既然沒有 SetWindowText() API,我們為什么可以使用它呢?winuser.h頭文件包含了一些宏,例如:

    BOOL WINAPI SetWindowTextA ( HWND hWnd, LPCSTR lpString );
    BOOL WINAPI SetWindowTextW ( HWND hWnd, LPCWSTR lpString );

    #ifdef UNICODE
    #define SetWindowText SetWindowTextW
    #else
    #define SetWindowText SetWindowTextA
    #endif 當使用MBCS APIs來build程序時,UNICODE沒有被定義,所以預處理器看到: #define SetWindowText SetWindowTextA

      這個宏定義把所有對SetWindowText的調用都轉換成真正的API函數SetWindowTextA。(當然,你可以直接調用SetWindowTextA() 或者 SetWindowTextW(),雖然你不必那么做。)
    所以,如果你想把默認使用的API函數變成Unicode版的,你可以在預處理器設置中,把_MBCS從預定義的宏列表中刪除,然后添加UNICODE和_UNICODE。(你需要兩個都定義,因為不同的頭文件可能使用不同的宏。) 然而,如果你用char來定義你的字符串,你將會陷入一個尷尬的境地。考慮下面的代碼:

    HWND hwnd = GetSomeWindowHandle();
    char szNewText[] = "we love Bob!";
    SetWindowText ( hwnd, szNewText );

    在預處理器把SetWindowText用SetWindowTextW來替換后,代碼變成:

    HWND hwnd = GetSomeWindowHandle();
    char szNewText[] = "we love Bob!";
    SetWindowTextW ( hwnd, szNewText );

      看到問題了嗎?我們把單字節字符串傳給了一個以Unicode字符串做參數的函數。解決這個問題的第一個方案是使用 #ifdef 來包含字符串變量的定義:

    HWND hwnd = GetSomeWindowHandle();
    #ifdef UNICODE
    wchar_t szNewText[] = L"we love Bob!";
    #else
    char szNewText[] = "we love Bob!";
    #endif
    SetWindowText ( hwnd, szNewText );

    你可能已經感受到了這樣做將會使你多么的頭疼。完美的解決方案是使用TCHAR.

    使用TCHAR

    TCHAR是一種字符串類型,它讓你在以MBCS和UNNICODE來build程序時可以使用同樣的代碼,不需要使用繁瑣的宏定義來包含你的代碼。TCHAR的定義如下:

    #ifdef UNICODE
    typedef wchar_t TCHAR;
    #else
    typedef char TCHAR;
    #endif

    所以用MBCS來build時,TCHAR是char,使用UNICODE時,TCHAR是wchar_t。還有一個宏來處理定義Unicode字符串常量時所需的L前綴。

    #ifdef UNICODE
    #define _T(x) L##x
    #else
    #define _T(x) x
    #endif

    ##是一個預處理操作符,它可以把兩個參數連在一起。如果你的代碼中需要字符串常量,在它前面加上_T宏。如果你使用Unicode來build,它會在字符串常量前加上L前綴。

    TCHAR szNewText[] = _T("we love Bob!");

    像是用宏來隱藏SetWindowTextA/W的細節一樣,還有很多可以供你使用的宏來實現str***()和_mbs***()等字符串函數。例如,你可以使用_tcsrchr宏來替換strrchr()、_mbsrchr()和wcsrchr()。_tcsrchr根據你預定義的宏是_MBCS 還是UNICODE來擴展成正確的函數,就像SetWindowText所作的一樣。
    不僅str***()函數有TCHAR宏。其他的函數如, _stprintf(代替sprinft()和swprintf()),_tfopen(代替fopen()和_wfopen())。 MSDN中"Generic-Text Routine Mappings."標題下有完整的宏列表。

    字符串和TCHAR typedefs

    由于Win32 API文檔的函數列表使用函數的常用名字(例如,"SetWindowText"),所有的字符串都是用TCHAR來定義的。(除了XP中引入的只適用于 Unicode的API)。下面列出一些常用的typedefs,你可以在msdn中看到他們。

    type Meaning in MBCS builds Meaning in Unicode builds
    WCHARwchar_twchar_t
    LPSTR zero-terminated string of char (char*)zero-terminated string of char (char*)
    LPCSTR constant zero-terminated string of char (const char*)constant zero-terminated string of char (const char*)
    LPWSTRzero-terminated Unicode string (wchar_t*) zero-terminated Unicode string (wchar_t*)
    LPCWSTRconstant zero-terminated Unicode string (const wchar_t*)constant zero-terminated Unicode string (const wchar_t*)
    TCHARcharwchar_t
    LPTSTRzero-terminated string of TCHAR (TCHAR*) zero-terminated string of TCHAR (TCHAR*)
    LPCTSTR constant zero-terminated string of TCHAR (const TCHAR*)constant zero-terminated string of TCHAR (const TCHAR*)

    何時使用 TCHAR 和 Unicode

    到現在,你可能會問,我們為什么要使用Unicode。我已經用了很多年的char。下列3種情況下,使用Unicode將會使你受益:

  • 1.你的程序只運行在Windows NT系統中。
  • 2. 你的程序需要處理超過MAX_PATH個字符長的文件名。
  • 3. 你的程序需要使用XP中引入的只有Unicode版本的API.
  • Windows 9x 中大多數的 API 沒有實現 Unicode 版本。所以,如果你的程序要在windows 9x中運行,你必須使用MBCS APIs。然而,由于NT系統內部都使用Unicode,所以使用Unicode APIs將會加快你的程序的運行速度。每次,你傳遞一個字符串調用MBCS API,操作系統會把這個字符串轉換成Unicode字符串,然后調用對應的Unicode API。如果一個字符串被返回,操作系統還要把它轉變回去。盡管這個轉換過程被高度優化了,但它對速度造成的損失是無法避免的。
    只要你使用Unicode API,NT系統允許使用非常長的文件名(突破了MAX_PATH的限制,MAX_PATH=260)。使用Unicode API的另一個優點是你的程序會自動處理用戶輸入的各種語言。所以一個用戶可以輸入英文,中文或者日文,而你不需要額外編寫代碼去處理它們。
    最后,隨著windows 9x產品的淡出,微軟似乎正在拋棄MBCS APIs。例如,包含兩個字符串參數的SetWindowTheme() API只有Unicode版本的。使用Unicode來build你的程序將會簡化字符串的處理,你不必在MBCS和Unicdoe之間相互轉換。
    即使你現在不使用Unicode來build你的程序,你也應該使用TCHAR及其相關的宏。這樣做不僅可以的代碼可以很好地處理DBCS,而且如果將來你想用Unicode來build你的程序,你只需要改變一下預處理器中的設置就可以實現了。 ? http://www.cnblogs.com/Sonic2007/

    總結

    以上是生活随笔為你收集整理的Windbg内核调试(大杂烩)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    精品无码成人片一区二区98 | 日本精品久久久久中文字幕 | 成人性做爰aaa片免费看 | 乌克兰少妇xxxx做受 | 欧美35页视频在线观看 | 亚洲乱码日产精品bd | 粗大的内捧猛烈进出视频 | 亚洲欧洲无卡二区视頻 | 亚洲精品一区二区三区在线观看 | 国产特级毛片aaaaaaa高清 | 四十如虎的丰满熟妇啪啪 | 欧美日韩一区二区综合 | 性色欲情网站iwww九文堂 | 国产精品人人妻人人爽 | 色欲综合久久中文字幕网 | 国产精品第一国产精品 | 国产无套内射久久久国产 | 国产另类ts人妖一区二区 | 久久综合给合久久狠狠狠97色 | 人妻插b视频一区二区三区 | 无码人中文字幕 | 一本大道伊人av久久综合 | 巨爆乳无码视频在线观看 | 国产亚洲美女精品久久久2020 | 亚拍精品一区二区三区探花 | 色 综合 欧美 亚洲 国产 | 沈阳熟女露脸对白视频 | 欧美放荡的少妇 | 国内精品九九久久久精品 | 亚洲精品一区二区三区大桥未久 | 国产性生大片免费观看性 | 亚洲天堂2017无码 | 久久亚洲精品成人无码 | 日韩无套无码精品 | 国产偷国产偷精品高清尤物 | 亚洲乱亚洲乱妇50p | 玩弄中年熟妇正在播放 | 婷婷综合久久中文字幕蜜桃三电影 | 中文毛片无遮挡高清免费 | 日韩精品乱码av一区二区 | 丰满少妇熟乱xxxxx视频 | 性欧美熟妇videofreesex | 亚洲精品美女久久久久久久 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国产精品福利视频导航 | 精品乱码久久久久久久 | 国产一精品一av一免费 | 欧美freesex黑人又粗又大 | 国产人成高清在线视频99最全资源 | 亚洲国产精品久久人人爱 | 又粗又大又硬毛片免费看 | 国产精品va在线播放 | 无码人妻精品一区二区三区下载 | 国产精品丝袜黑色高跟鞋 | 日韩精品一区二区av在线 | 在线精品亚洲一区二区 | 亚洲一区二区三区香蕉 | 午夜福利不卡在线视频 | 亚洲gv猛男gv无码男同 | 成人欧美一区二区三区黑人 | 任你躁国产自任一区二区三区 | 99久久久无码国产aaa精品 | 亚洲s码欧洲m码国产av | 国产亚洲欧美日韩亚洲中文色 | 亚洲无人区一区二区三区 | yw尤物av无码国产在线观看 | 国产av无码专区亚洲a∨毛片 | 免费观看黄网站 | √8天堂资源地址中文在线 | 亚洲乱码国产乱码精品精 | 2019午夜福利不卡片在线 | 亚洲人成无码网www | 99久久人妻精品免费二区 | 蜜桃视频插满18在线观看 | 真人与拘做受免费视频一 | 思思久久99热只有频精品66 | 国产乡下妇女做爰 | 亚洲国产欧美日韩精品一区二区三区 | 欧美日韩一区二区免费视频 | 中文毛片无遮挡高清免费 | 久久99国产综合精品 | 97精品国产97久久久久久免费 | 国产亚洲欧美在线专区 | 亚洲高清偷拍一区二区三区 | 老司机亚洲精品影院无码 | 夜先锋av资源网站 | 2020久久香蕉国产线看观看 | 极品尤物被啪到呻吟喷水 | 无套内谢的新婚少妇国语播放 | 日韩精品乱码av一区二区 | 国产精品人人爽人人做我的可爱 | 图片区 小说区 区 亚洲五月 | 国产suv精品一区二区五 | 婷婷五月综合激情中文字幕 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 人人超人人超碰超国产 | 亚洲日韩av一区二区三区四区 | 又大又紧又粉嫩18p少妇 | 中文字幕人妻无码一区二区三区 | 精品欧洲av无码一区二区三区 | 精品久久8x国产免费观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 鲁鲁鲁爽爽爽在线视频观看 | 国产精品无码mv在线观看 | 亚洲欧洲日本无在线码 | 无套内谢的新婚少妇国语播放 | 中国女人内谢69xxxxxa片 | 久久综合给合久久狠狠狠97色 | 亚洲熟熟妇xxxx | 国产suv精品一区二区五 | 欧洲熟妇精品视频 | 亚洲精品国产第一综合99久久 | 人人妻人人澡人人爽欧美一区 | 奇米影视888欧美在线观看 | 四虎永久在线精品免费网址 | 亚洲国产欧美国产综合一区 | 国产片av国语在线观看 | 日本熟妇乱子伦xxxx | 久久国产精品二国产精品 | 爆乳一区二区三区无码 | 亚洲精品午夜国产va久久成人 | 中文字幕av日韩精品一区二区 | 久久久久亚洲精品男人的天堂 | 亚洲 激情 小说 另类 欧美 | 亚洲精品国偷拍自产在线观看蜜桃 | 成人影院yy111111在线观看 | 人妻互换免费中文字幕 | 国产午夜亚洲精品不卡下载 | 亚洲第一网站男人都懂 | 特黄特色大片免费播放器图片 | 亚洲色大成网站www | 亚洲成a人一区二区三区 | 天堂亚洲2017在线观看 | 国产亚洲精品久久久久久久 | 乌克兰少妇性做爰 | 久热国产vs视频在线观看 | 欧洲美熟女乱又伦 | 国产麻豆精品精东影业av网站 | 永久免费观看美女裸体的网站 | 欧美日韩一区二区三区自拍 | 国产午夜福利亚洲第一 | 999久久久国产精品消防器材 | 亚洲区小说区激情区图片区 | 亚洲色欲色欲欲www在线 | 国产成人综合美国十次 | 狠狠色噜噜狠狠狠7777奇米 | 四虎4hu永久免费 | 大屁股大乳丰满人妻 | 狂野欧美激情性xxxx | 亚洲精品一区二区三区大桥未久 | 真人与拘做受免费视频一 | 亚洲精品一区三区三区在线观看 | 福利一区二区三区视频在线观看 | 国产成人无码av片在线观看不卡 | 少妇性俱乐部纵欲狂欢电影 | 国产特级毛片aaaaaa高潮流水 | 欧美性猛交内射兽交老熟妇 | 国产在线无码精品电影网 | 婷婷色婷婷开心五月四房播播 | 国产口爆吞精在线视频 | 亚洲精品美女久久久久久久 | 久久久久久久人妻无码中文字幕爆 | 国产精品无码mv在线观看 | 狠狠色噜噜狠狠狠狠7777米奇 | 亚洲中文字幕久久无码 | 国产精品久久久av久久久 | 欧美日韩人成综合在线播放 | 成人无码视频在线观看网站 | 蜜桃臀无码内射一区二区三区 | 伊人久久大香线蕉亚洲 | 一个人看的www免费视频在线观看 | 欧美阿v高清资源不卡在线播放 | 日韩欧美中文字幕在线三区 | 欧美成人午夜精品久久久 | 亚洲综合伊人久久大杳蕉 | 国产午夜视频在线观看 | 欧美人与动性行为视频 | 久久伊人色av天堂九九小黄鸭 | 女人被男人躁得好爽免费视频 | 欧美国产日产一区二区 | 成人一区二区免费视频 | 精品人妻人人做人人爽 | 国产人妻精品一区二区三区 | 日韩人妻系列无码专区 | 久久人人爽人人人人片 | 欧美第一黄网免费网站 | 亚洲一区av无码专区在线观看 | 人人爽人人爽人人片av亚洲 | 欧美黑人性暴力猛交喷水 | 久久www免费人成人片 | 色婷婷欧美在线播放内射 | 亚洲性无码av中文字幕 | 久久久精品456亚洲影院 | 精品国产国产综合精品 | 日本精品人妻无码免费大全 | 亚洲爆乳精品无码一区二区三区 | 色五月五月丁香亚洲综合网 | 国产亚洲精品久久久久久国模美 | 少妇人妻大乳在线视频 | 水蜜桃亚洲一二三四在线 | 国产成人精品三级麻豆 | 国产乱人无码伦av在线a | 日本丰满熟妇videos | 一本久道高清无码视频 | 少妇无码一区二区二三区 | 久久久久久亚洲精品a片成人 | 性色欲网站人妻丰满中文久久不卡 | 一二三四在线观看免费视频 | 久久久久久九九精品久 | 4hu四虎永久在线观看 | 97夜夜澡人人双人人人喊 | 在线а√天堂中文官网 | 夜夜影院未满十八勿进 | 老头边吃奶边弄进去呻吟 | 欧美自拍另类欧美综合图片区 | 国产精品永久免费视频 | 精品夜夜澡人妻无码av蜜桃 | 精品乱子伦一区二区三区 | 四虎永久在线精品免费网址 | 亚洲日韩中文字幕在线播放 | 性开放的女人aaa片 | 无码免费一区二区三区 | 国产性生交xxxxx无码 | 夫妻免费无码v看片 | 欧美野外疯狂做受xxxx高潮 | 国产偷国产偷精品高清尤物 | 老司机亚洲精品影院 | 国产xxx69麻豆国语对白 | 熟妇人妻中文av无码 | 亚洲区欧美区综合区自拍区 | 亚洲精品鲁一鲁一区二区三区 | 亚洲成av人片在线观看无码不卡 | 国产精品亚洲专区无码不卡 | 国产高潮视频在线观看 | 久久人人爽人人人人片 | 天堂一区人妻无码 | 亚洲精品国产第一综合99久久 | 丁香花在线影院观看在线播放 | 伊在人天堂亚洲香蕉精品区 | 好爽又高潮了毛片免费下载 | 中文字幕精品av一区二区五区 | 少妇厨房愉情理9仑片视频 | 99久久精品无码一区二区毛片 | 无码精品人妻一区二区三区av | 中文字幕无码日韩欧毛 | 日本成熟视频免费视频 | 色婷婷综合中文久久一本 | 久久97精品久久久久久久不卡 | 无码人妻久久一区二区三区不卡 | 午夜熟女插插xx免费视频 | 天堂а√在线中文在线 | 亚洲中文字幕久久无码 | 成人一在线视频日韩国产 | 一本大道久久东京热无码av | 国产精品久免费的黄网站 | 亚洲日本va午夜在线电影 | 六月丁香婷婷色狠狠久久 | 久久综合久久自在自线精品自 | 国产成人精品久久亚洲高清不卡 | 亚洲经典千人经典日产 | 色诱久久久久综合网ywww | 亚洲色大成网站www国产 | 99久久婷婷国产综合精品青草免费 | 成人精品一区二区三区中文字幕 | 激情内射亚州一区二区三区爱妻 | 人妻aⅴ无码一区二区三区 | 午夜精品一区二区三区在线观看 | 成人aaa片一区国产精品 | 999久久久国产精品消防器材 | 国产精品无码mv在线观看 | 最近中文2019字幕第二页 | 午夜无码人妻av大片色欲 | 色一情一乱一伦一视频免费看 | 欧美成人免费全部网站 | 亚洲人成网站在线播放942 | 国产精品va在线播放 | 高清无码午夜福利视频 | 久久人人爽人人人人片 | 欧洲欧美人成视频在线 | 久热国产vs视频在线观看 | 亚洲国产成人a精品不卡在线 | 国产激情综合五月久久 | 日本一本二本三区免费 | 夜先锋av资源网站 | 少妇无码一区二区二三区 | 四虎影视成人永久免费观看视频 | 日韩欧美中文字幕公布 | 好男人社区资源 | 欧美精品一区二区精品久久 | 999久久久国产精品消防器材 | 少妇人妻偷人精品无码视频 | 在线观看国产一区二区三区 | 少妇高潮一区二区三区99 | 亚洲色偷偷偷综合网 | 久久熟妇人妻午夜寂寞影院 | 2020最新国产自产精品 | 国产精品无套呻吟在线 | 欧美肥老太牲交大战 | 老子影院午夜伦不卡 | 国产成人精品优优av | 欧美怡红院免费全部视频 | 无码人妻av免费一区二区三区 | 国产午夜亚洲精品不卡下载 | 99视频精品全部免费免费观看 | 国产成人精品优优av | 成人aaa片一区国产精品 | 日本精品人妻无码免费大全 | 漂亮人妻洗澡被公强 日日躁 | 成人免费视频一区二区 | 男人和女人高潮免费网站 | 欧洲极品少妇 | 国产suv精品一区二区五 | 一本精品99久久精品77 | 又大又黄又粗又爽的免费视频 | 欧美真人作爱免费视频 | 98国产精品综合一区二区三区 | 内射欧美老妇wbb | 无码国产乱人伦偷精品视频 | 色欲av亚洲一区无码少妇 | a片免费视频在线观看 | 欧美日韩在线亚洲综合国产人 | 亚洲欧美精品伊人久久 | 狠狠色色综合网站 | 99久久久无码国产aaa精品 | 国产精品人人爽人人做我的可爱 | 97无码免费人妻超级碰碰夜夜 | 国产精品久久久久久亚洲影视内衣 | 日日夜夜撸啊撸 | 无套内射视频囯产 | 午夜熟女插插xx免费视频 | av无码不卡在线观看免费 | 国产猛烈高潮尖叫视频免费 | 国产色视频一区二区三区 | 女人被男人躁得好爽免费视频 | 中文字幕无码免费久久9一区9 | 99久久精品国产一区二区蜜芽 | 蜜臀av在线播放 久久综合激激的五月天 | 久久亚洲国产成人精品性色 | 亚洲中文字幕在线无码一区二区 | 久久久精品456亚洲影院 | 99国产欧美久久久精品 | 小鲜肉自慰网站xnxx | 亚洲毛片av日韩av无码 | 成人一区二区免费视频 | 伊人久久大香线蕉av一区二区 | 撕开奶罩揉吮奶头视频 | 装睡被陌生人摸出水好爽 | 无码av岛国片在线播放 | 人妻人人添人妻人人爱 | 国产乱子伦视频在线播放 | 日本www一道久久久免费榴莲 | 亚洲成av人影院在线观看 | 爽爽影院免费观看 | 国产亚洲视频中文字幕97精品 | 精品一区二区三区无码免费视频 | 九九综合va免费看 | 2020久久超碰国产精品最新 | 日本护士xxxxhd少妇 | 中文字幕色婷婷在线视频 | 青草青草久热国产精品 | 欧美日韩视频无码一区二区三 | 亚洲精品久久久久久一区二区 | 免费国产黄网站在线观看 | 国产亚洲tv在线观看 | 青青草原综合久久大伊人精品 | 精品乱码久久久久久久 | 亚洲爆乳大丰满无码专区 | 国产精品自产拍在线观看 | 国产无遮挡又黄又爽又色 | 午夜精品久久久内射近拍高清 | 亚洲人成人无码网www国产 | 亚洲一区二区三区含羞草 | 国产成人无码一二三区视频 | 乌克兰少妇性做爰 | 骚片av蜜桃精品一区 | 中文久久乱码一区二区 | 免费无码av一区二区 | 亚洲国产av精品一区二区蜜芽 | 丰满肥臀大屁股熟妇激情视频 | 自拍偷自拍亚洲精品10p | 久久97精品久久久久久久不卡 | 麻花豆传媒剧国产免费mv在线 | 久久久久99精品成人片 | 久久99精品久久久久久 | 蜜桃视频韩日免费播放 | 给我免费的视频在线观看 | 日本一本二本三区免费 | 日本肉体xxxx裸交 | 少妇人妻大乳在线视频 | 日韩精品a片一区二区三区妖精 | 免费观看又污又黄的网站 | www成人国产高清内射 | 全球成人中文在线 | 色五月五月丁香亚洲综合网 | 免费无码av一区二区 | 欧美丰满少妇xxxx性 | 国产亚洲日韩欧美另类第八页 | 日本护士毛茸茸高潮 | 亚洲 日韩 欧美 成人 在线观看 | 人人澡人摸人人添 | 麻豆果冻传媒2021精品传媒一区下载 | 午夜福利一区二区三区在线观看 | 国产精品久久久av久久久 | 18禁黄网站男男禁片免费观看 | 国产精品沙发午睡系列 | 无码精品国产va在线观看dvd | 亚洲aⅴ无码成人网站国产app | 蜜臀aⅴ国产精品久久久国产老师 | 国产成人久久精品流白浆 | 国产熟妇高潮叫床视频播放 | 欧美丰满少妇xxxx性 | 野外少妇愉情中文字幕 | 亚洲午夜福利在线观看 | 久久久精品成人免费观看 | 日日天日日夜日日摸 | 国产精品资源一区二区 | 成人欧美一区二区三区黑人 | 中文字幕亚洲情99在线 | 18黄暴禁片在线观看 | 国产无套粉嫩白浆在线 | 青青青手机频在线观看 | 99国产欧美久久久精品 | 影音先锋中文字幕无码 | 国内精品久久久久久中文字幕 | 无码av中文字幕免费放 | 国产后入清纯学生妹 | 中文字幕人妻无码一区二区三区 | 日日夜夜撸啊撸 | 亚洲成a人片在线观看无码 | 色婷婷综合中文久久一本 | 久久精品国产一区二区三区 | 国产精品亚洲一区二区三区喷水 | 18黄暴禁片在线观看 | av无码不卡在线观看免费 | 国内老熟妇对白xxxxhd | 日韩欧美成人免费观看 | 国产女主播喷水视频在线观看 | 国产成人综合在线女婷五月99播放 | 久久99精品久久久久久动态图 | 捆绑白丝粉色jk震动捧喷白浆 | 人妻尝试又大又粗久久 | 久久成人a毛片免费观看网站 | 18禁止看的免费污网站 | 亚洲色欲色欲天天天www | 无码人中文字幕 | 日韩av无码一区二区三区不卡 | 国产亚洲美女精品久久久2020 | 领导边摸边吃奶边做爽在线观看 | 九九久久精品国产免费看小说 | 无码精品国产va在线观看dvd | 在线观看国产一区二区三区 | 久久精品女人天堂av免费观看 | 夜精品a片一区二区三区无码白浆 | 日本xxxx色视频在线观看免费 | 亚洲精品久久久久中文第一幕 | 精品国偷自产在线视频 | 四虎影视成人永久免费观看视频 | 亚洲aⅴ无码成人网站国产app | 亚无码乱人伦一区二区 | 一本色道久久综合亚洲精品不卡 | 少妇性俱乐部纵欲狂欢电影 | 色偷偷人人澡人人爽人人模 | 伊人久久大香线焦av综合影院 | 久久99精品国产麻豆 | 夜夜影院未满十八勿进 | 丁香花在线影院观看在线播放 | 极品尤物被啪到呻吟喷水 | 日日天干夜夜狠狠爱 | 国产熟女一区二区三区四区五区 | 国产在线精品一区二区高清不卡 | 丰满岳乱妇在线观看中字无码 | 成人精品天堂一区二区三区 | 99久久精品午夜一区二区 | 伊人久久大香线蕉亚洲 | 久久久久成人精品免费播放动漫 | 亚洲毛片av日韩av无码 | 99久久久国产精品无码免费 | 成人免费视频视频在线观看 免费 | 狠狠噜狠狠狠狠丁香五月 | 人妻天天爽夜夜爽一区二区 | 水蜜桃色314在线观看 | 无码av免费一区二区三区试看 | 超碰97人人射妻 | 欧美黑人性暴力猛交喷水 | 夜夜躁日日躁狠狠久久av | 国产亚洲视频中文字幕97精品 | 色综合久久久无码网中文 | 国产免费久久久久久无码 | 成人免费无码大片a毛片 | 人妻熟女一区 | 日本精品人妻无码77777 天堂一区人妻无码 | 夫妻免费无码v看片 | 强辱丰满人妻hd中文字幕 | 国产午夜无码精品免费看 | 亚洲无人区午夜福利码高清完整版 | 青青草原综合久久大伊人精品 | 国产精品久久久一区二区三区 | 激情五月综合色婷婷一区二区 | 性啪啪chinese东北女人 | 亚洲中文字幕在线无码一区二区 | 97资源共享在线视频 | 国产在线精品一区二区三区直播 | 狠狠综合久久久久综合网 | 人妻中文无码久热丝袜 | 999久久久国产精品消防器材 | 美女黄网站人色视频免费国产 | 小鲜肉自慰网站xnxx | 一个人免费观看的www视频 | 18无码粉嫩小泬无套在线观看 | 免费无码肉片在线观看 | 中文字幕亚洲情99在线 | 无码乱肉视频免费大全合集 | 国产精品a成v人在线播放 | 国产黑色丝袜在线播放 | 国产三级精品三级男人的天堂 | 日本高清一区免费中文视频 | 国产猛烈高潮尖叫视频免费 | 亚洲成av人在线观看网址 | 在线播放无码字幕亚洲 | 美女扒开屁股让男人桶 | 老熟女重囗味hdxx69 | 在线天堂新版最新版在线8 | 亚洲人成影院在线无码按摩店 | 久久熟妇人妻午夜寂寞影院 | 久久综合给合久久狠狠狠97色 | 国产一区二区三区四区五区加勒比 | 波多野结衣 黑人 | 亚洲国产成人a精品不卡在线 | 久久成人a毛片免费观看网站 | 两性色午夜免费视频 | 欧美第一黄网免费网站 | 亚洲の无码国产の无码影院 | 在线成人www免费观看视频 | 国産精品久久久久久久 | 日日摸夜夜摸狠狠摸婷婷 | 美女极度色诱视频国产 | 强奷人妻日本中文字幕 | 国内精品一区二区三区不卡 | 国产午夜无码精品免费看 | 野外少妇愉情中文字幕 | 偷窥日本少妇撒尿chinese | 中文字幕精品av一区二区五区 | 樱花草在线社区www | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 亚洲国产精品一区二区美利坚 | 天天拍夜夜添久久精品 | 少妇愉情理伦片bd | 欧美 亚洲 国产 另类 | 国产av人人夜夜澡人人爽麻豆 | 高清无码午夜福利视频 | 67194成是人免费无码 | 久激情内射婷内射蜜桃人妖 | 国产精品理论片在线观看 | 亚洲国产精品久久久天堂 | 成在人线av无码免观看麻豆 | 中文字幕色婷婷在线视频 | 亚洲精品美女久久久久久久 | 国产人妻精品一区二区三区 | 一本精品99久久精品77 | 亚拍精品一区二区三区探花 | 婷婷五月综合激情中文字幕 | 骚片av蜜桃精品一区 | 国产sm调教视频在线观看 | 免费播放一区二区三区 | 爆乳一区二区三区无码 | 免费观看黄网站 | 永久免费观看美女裸体的网站 | 欧美日韩人成综合在线播放 | 老熟妇乱子伦牲交视频 | 日本一区二区三区免费播放 | 初尝人妻少妇中文字幕 | 国产精品久久久久久亚洲毛片 | 国产精品人人爽人人做我的可爱 | 欧美日韩一区二区免费视频 | 精品久久久无码中文字幕 | 国内精品一区二区三区不卡 | 波多野结衣av一区二区全免费观看 | 国产情侣作爱视频免费观看 | 夜精品a片一区二区三区无码白浆 | 强辱丰满人妻hd中文字幕 | 精品国产福利一区二区 | 国产人妻精品一区二区三区 | 精品久久久久久人妻无码中文字幕 | 男人的天堂av网站 | 亚洲一区二区三区含羞草 | 中文字幕亚洲情99在线 | 曰韩无码二三区中文字幕 | 白嫩日本少妇做爰 | 亚洲日韩乱码中文无码蜜桃臀网站 | 露脸叫床粗话东北少妇 | 久久亚洲精品中文字幕无男同 | 亚洲娇小与黑人巨大交 | 丝袜人妻一区二区三区 | 我要看www免费看插插视频 | 国产综合久久久久鬼色 | 国产av无码专区亚洲awww | 激情五月综合色婷婷一区二区 | 国产精品香蕉在线观看 | 中文字幕av无码一区二区三区电影 | 少妇的肉体aa片免费 | 亚洲一区av无码专区在线观看 | 日韩精品一区二区av在线 | 四虎影视成人永久免费观看视频 | 欧美怡红院免费全部视频 | 中文字幕人妻丝袜二区 | 国产乱码精品一品二品 | 久久无码人妻影院 | 国产在线精品一区二区三区直播 | 国内综合精品午夜久久资源 | 性生交大片免费看l | 丰满少妇弄高潮了www | 午夜时刻免费入口 | 特黄特色大片免费播放器图片 | 小sao货水好多真紧h无码视频 | 久久久久99精品成人片 | 好爽又高潮了毛片免费下载 | 国产片av国语在线观看 | 国产麻豆精品精东影业av网站 | 强辱丰满人妻hd中文字幕 | 2020最新国产自产精品 | 久久久久成人片免费观看蜜芽 | 久久天天躁狠狠躁夜夜免费观看 | 国产午夜手机精彩视频 | 亚洲综合在线一区二区三区 | 国产成人精品久久亚洲高清不卡 | 日本护士xxxxhd少妇 | 国产综合在线观看 | 国产麻豆精品一区二区三区v视界 | 人妻无码αv中文字幕久久琪琪布 | 亚洲成a人片在线观看无码3d | 大乳丰满人妻中文字幕日本 | 少妇无套内谢久久久久 | 成人欧美一区二区三区黑人 | 18无码粉嫩小泬无套在线观看 | 中文字幕av无码一区二区三区电影 | 欧美老妇交乱视频在线观看 | 中文字幕av日韩精品一区二区 | 中文字幕无码av波多野吉衣 | 日韩av无码中文无码电影 | 国产办公室秘书无码精品99 | 国产在线无码精品电影网 | 国产97人人超碰caoprom | 欧美精品一区二区精品久久 | 久久久精品人妻久久影视 | aⅴ在线视频男人的天堂 | 撕开奶罩揉吮奶头视频 | 麻豆国产97在线 | 欧洲 | 午夜熟女插插xx免费视频 | 亚洲春色在线视频 | 黄网在线观看免费网站 | 亚洲精品www久久久 | aⅴ亚洲 日韩 色 图网站 播放 | 精品一区二区不卡无码av | 亚洲人成网站色7799 | 激情亚洲一区国产精品 | 日韩视频 中文字幕 视频一区 | 任你躁国产自任一区二区三区 | 国产成人一区二区三区别 | 亚洲国产欧美日韩精品一区二区三区 | 婷婷丁香六月激情综合啪 | 成人亚洲精品久久久久软件 | 亚洲热妇无码av在线播放 | 丰满人妻被黑人猛烈进入 | 亚洲熟女一区二区三区 | 亚洲成在人网站无码天堂 | 日韩视频 中文字幕 视频一区 | 人妻无码久久精品人妻 | 亚洲色无码一区二区三区 | 欧美性生交活xxxxxdddd | 野外少妇愉情中文字幕 | www成人国产高清内射 | 日本乱偷人妻中文字幕 | 一本精品99久久精品77 | 成人精品视频一区二区三区尤物 | 精品熟女少妇av免费观看 | 亚洲欧美色中文字幕在线 | 亚洲日本一区二区三区在线 | 亚洲综合无码久久精品综合 | 无码人妻精品一区二区三区不卡 | 成人一区二区免费视频 | 亚洲国产精品美女久久久久 | 欧洲美熟女乱又伦 | 最近免费中文字幕中文高清百度 | 人人澡人人妻人人爽人人蜜桃 | 久久综合激激的五月天 | 亚洲の无码国产の无码影院 | 日本精品久久久久中文字幕 | 曰韩无码二三区中文字幕 | 黑人玩弄人妻中文在线 | 狠狠色丁香久久婷婷综合五月 | 国产片av国语在线观看 | 国产亚洲精品久久久久久国模美 | 亚洲a无码综合a国产av中文 | 午夜熟女插插xx免费视频 | 性欧美疯狂xxxxbbbb | 俺去俺来也www色官网 | 亚洲日韩精品欧美一区二区 | 色妞www精品免费视频 | 国产疯狂伦交大片 | 激情国产av做激情国产爱 | 中文字幕中文有码在线 | 性欧美疯狂xxxxbbbb | v一区无码内射国产 | 女人被爽到呻吟gif动态图视看 | 色婷婷综合激情综在线播放 | 小sao货水好多真紧h无码视频 | 大地资源网第二页免费观看 | 波多野结衣乳巨码无在线观看 | 欧美放荡的少妇 | 国产色精品久久人妻 | 国产精品美女久久久网av | 377p欧洲日本亚洲大胆 | 亚洲码国产精品高潮在线 | 亚洲午夜久久久影院 | 亚洲热妇无码av在线播放 | 成人一区二区免费视频 | 又色又爽又黄的美女裸体网站 | 色五月丁香五月综合五月 | 国精产品一品二品国精品69xx | 亚洲 激情 小说 另类 欧美 | 无遮挡国产高潮视频免费观看 | 一本久久a久久精品vr综合 | 久久国产自偷自偷免费一区调 | 黑人巨大精品欧美一区二区 | 欧美日韩久久久精品a片 | 鲁大师影院在线观看 | 国产凸凹视频一区二区 | 国产一区二区三区四区五区加勒比 | 国产精品二区一区二区aⅴ污介绍 | 日本xxxx色视频在线观看免费 | 国产精品国产三级国产专播 | 色噜噜亚洲男人的天堂 | 免费中文字幕日韩欧美 | 精品无码国产一区二区三区av | 精品无人国产偷自产在线 | 女人色极品影院 | 国产内射爽爽大片视频社区在线 | 一区二区传媒有限公司 | 无码午夜成人1000部免费视频 | 精品久久久无码中文字幕 | 精品久久8x国产免费观看 | 撕开奶罩揉吮奶头视频 | 亚洲人成网站色7799 | 亚洲精品久久久久久一区二区 | 色综合久久久无码中文字幕 | 国内精品久久毛片一区二区 | 大乳丰满人妻中文字幕日本 | 97夜夜澡人人双人人人喊 | 国产午夜无码视频在线观看 | 国产亚洲美女精品久久久2020 | 波多野结衣av一区二区全免费观看 | 国产又粗又硬又大爽黄老大爷视 | 国内丰满熟女出轨videos | 给我免费的视频在线观看 | 欧美 日韩 人妻 高清 中文 | 青草青草久热国产精品 | 欧美性猛交xxxx富婆 | 国产亚洲tv在线观看 | 欧美午夜特黄aaaaaa片 | 一二三四社区在线中文视频 | 荫蒂被男人添的好舒服爽免费视频 | 爆乳一区二区三区无码 | 成人试看120秒体验区 | 久久久久人妻一区精品色欧美 | 在线 国产 欧美 亚洲 天堂 | 一本久久a久久精品vr综合 | 亚洲乱码日产精品bd | 亚洲熟悉妇女xxx妇女av | 大屁股大乳丰满人妻 | 国产精品美女久久久久av爽李琼 | 成人欧美一区二区三区 | 日产国产精品亚洲系列 | 丰满诱人的人妻3 | 久久综合九色综合97网 | 成人试看120秒体验区 | 亚洲精品久久久久中文第一幕 | 午夜精品久久久久久久 | 在线成人www免费观看视频 | 久久综合久久自在自线精品自 | 在线精品国产一区二区三区 | 国内老熟妇对白xxxxhd | 亚洲日本一区二区三区在线 | 狂野欧美性猛交免费视频 | 亚洲精品一区二区三区四区五区 | 成人性做爰aaa片免费看不忠 | 好屌草这里只有精品 | 久久久av男人的天堂 | 欧美喷潮久久久xxxxx | 色诱久久久久综合网ywww | 欧美肥老太牲交大战 | 一本色道久久综合狠狠躁 | 亚洲精品欧美二区三区中文字幕 | 精品无码av一区二区三区 | 国产av一区二区三区最新精品 | 亚洲欧美精品aaaaaa片 | 国产激情无码一区二区app | 久久天天躁狠狠躁夜夜免费观看 | 亚洲大尺度无码无码专区 | 狠狠色色综合网站 | 97精品国产97久久久久久免费 | 亚洲欧美日韩成人高清在线一区 | 一本大道伊人av久久综合 | 日日摸夜夜摸狠狠摸婷婷 | 久久久无码中文字幕久... | 精品国产aⅴ无码一区二区 | 精品久久综合1区2区3区激情 | 亚洲а∨天堂久久精品2021 | 国产艳妇av在线观看果冻传媒 | 中国女人内谢69xxxxxa片 | 性史性农村dvd毛片 | 无套内射视频囯产 | 国产激情一区二区三区 | 久久人人爽人人爽人人片av高清 | 日韩人妻无码一区二区三区久久99 | 人妻插b视频一区二区三区 | 欧美成人午夜精品久久久 | 精品一区二区三区无码免费视频 | 狂野欧美激情性xxxx | 日本一卡2卡3卡四卡精品网站 | 67194成是人免费无码 | 国产农村妇女高潮大叫 | 国产免费久久精品国产传媒 | 久久久久99精品成人片 | 国产在线aaa片一区二区99 | 日本一区二区三区免费播放 | 欧美日韩精品 | 国产激情无码一区二区 | 亚洲s码欧洲m码国产av | 男女下面进入的视频免费午夜 | 人妻尝试又大又粗久久 | 99久久久无码国产aaa精品 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 亚洲精品一区二区三区在线 | 久久久久久久女国产乱让韩 | 中文字幕久久久久人妻 | 精品久久综合1区2区3区激情 | 牲交欧美兽交欧美 | 激情国产av做激情国产爱 | 无码人妻av免费一区二区三区 | 国产亚洲视频中文字幕97精品 | 久久精品中文字幕大胸 | 无码人妻少妇伦在线电影 | 特大黑人娇小亚洲女 | 国产va免费精品观看 | 又粗又大又硬又长又爽 | 丰满肥臀大屁股熟妇激情视频 | 啦啦啦www在线观看免费视频 | 久久久婷婷五月亚洲97号色 | av无码久久久久不卡免费网站 | 久久久av男人的天堂 | 亚洲欧美综合区丁香五月小说 | 丰满少妇高潮惨叫视频 | 国内丰满熟女出轨videos | 精品国偷自产在线视频 | 亚洲色欲色欲天天天www | 国产人妻精品一区二区三区不卡 | 国产69精品久久久久app下载 | 熟妇人妻无码xxx视频 | 亚洲精品成人福利网站 | 国产99久久精品一区二区 | 99久久99久久免费精品蜜桃 | 内射老妇bbwx0c0ck | 亚洲日本va午夜在线电影 | 国产xxx69麻豆国语对白 | 精品水蜜桃久久久久久久 | 波多野结衣乳巨码无在线观看 | 国产激情精品一区二区三区 | 久久精品国产大片免费观看 | 水蜜桃色314在线观看 | 日韩成人一区二区三区在线观看 | 狠狠噜狠狠狠狠丁香五月 | 欧美 丝袜 自拍 制服 另类 | 国产日产欧产精品精品app | 国产两女互慰高潮视频在线观看 | 国产亚洲美女精品久久久2020 | 亚洲中文无码av永久不收费 | 精品国产一区二区三区四区 | 亚洲国产欧美国产综合一区 | 欧美精品在线观看 | 动漫av一区二区在线观看 | 国产在线aaa片一区二区99 | 成在人线av无码免观看麻豆 | 精品aⅴ一区二区三区 | 国产亚洲精品久久久久久久久动漫 | 久久无码专区国产精品s | 高清国产亚洲精品自在久久 | 欧美人与禽猛交狂配 | 欧美高清在线精品一区 | 亚洲人成网站在线播放942 | 色婷婷av一区二区三区之红樱桃 | 欧美人与动性行为视频 | 久久aⅴ免费观看 | 久久精品国产日本波多野结衣 | 国产明星裸体无码xxxx视频 | 久久综合给久久狠狠97色 | 久久精品人人做人人综合 | 亚洲无人区午夜福利码高清完整版 | 领导边摸边吃奶边做爽在线观看 | 在教室伦流澡到高潮hnp视频 | 2019nv天堂香蕉在线观看 | 国产精品无套呻吟在线 | 日韩人妻无码一区二区三区久久99 | 日韩无套无码精品 | 国产手机在线αⅴ片无码观看 | 国产xxx69麻豆国语对白 | 377p欧洲日本亚洲大胆 | 国内精品人妻无码久久久影院 | 国产精品视频免费播放 | 欧美精品国产综合久久 | 欧美精品一区二区精品久久 | 99久久人妻精品免费二区 | 无遮无挡爽爽免费视频 | 欧美午夜特黄aaaaaa片 | 国内综合精品午夜久久资源 | 亚洲色偷偷偷综合网 | 国产成人亚洲综合无码 | 国产精品无码一区二区三区不卡 | 四虎国产精品一区二区 | 国产精华av午夜在线观看 | 综合激情五月综合激情五月激情1 | 久久综合给久久狠狠97色 | 国产凸凹视频一区二区 | 久久精品国产一区二区三区 | 欧美日韩久久久精品a片 | 亚洲无人区一区二区三区 | 俄罗斯老熟妇色xxxx | 亚洲中文字幕va福利 | 国产精品亚洲五月天高清 | 中文字幕+乱码+中文字幕一区 | 领导边摸边吃奶边做爽在线观看 | 国产精品自产拍在线观看 | 波多野结衣乳巨码无在线观看 | 亚洲中文字幕va福利 | 国产亚洲精品精品国产亚洲综合 | 亚洲精品久久久久avwww潮水 | 内射欧美老妇wbb | 高潮毛片无遮挡高清免费 | 天干天干啦夜天干天2017 | 国产精品亚洲五月天高清 | 99久久婷婷国产综合精品青草免费 | 国产激情一区二区三区 | 丁香花在线影院观看在线播放 | 久久精品女人天堂av免费观看 | 国产精品美女久久久久av爽李琼 | 无遮挡国产高潮视频免费观看 | 亚洲码国产精品高潮在线 | 丝袜人妻一区二区三区 | 超碰97人人做人人爱少妇 | 国产婷婷色一区二区三区在线 | 成熟人妻av无码专区 | 国产高潮视频在线观看 | 黄网在线观看免费网站 | 99久久精品午夜一区二区 | 国产内射老熟女aaaa | 久久精品中文字幕一区 | 99国产精品白浆在线观看免费 | 一本久久伊人热热精品中文字幕 | 最近免费中文字幕中文高清百度 | 精品人妻中文字幕有码在线 | 精品人人妻人人澡人人爽人人 | 性生交大片免费看女人按摩摩 | 成人性做爰aaa片免费看不忠 | 亚洲成a人片在线观看日本 | 人妻aⅴ无码一区二区三区 | 午夜福利不卡在线视频 | 暴力强奷在线播放无码 | 国产一区二区三区日韩精品 | 亚洲午夜无码久久 | 日本精品人妻无码免费大全 | 精品国产一区二区三区四区 | 国产av无码专区亚洲awww | 久久人人97超碰a片精品 | 国产一区二区不卡老阿姨 | 两性色午夜视频免费播放 | 国产午夜亚洲精品不卡下载 | 精品乱码久久久久久久 | 97无码免费人妻超级碰碰夜夜 | 国产精品无码久久av | 亚洲第一无码av无码专区 | 欧美老妇与禽交 | 亚洲精品国偷拍自产在线麻豆 | 免费国产成人高清在线观看网站 | 亚洲国产成人av在线观看 | 亚洲国精产品一二二线 | 亚洲七七久久桃花影院 | 大胆欧美熟妇xx | 成人试看120秒体验区 | 国产精品无码mv在线观看 | 亚洲精品国偷拍自产在线麻豆 | 天堂亚洲免费视频 | 国产成人一区二区三区别 | 国产成人无码av一区二区 | 97精品国产97久久久久久免费 | 亚洲成色www久久网站 | 亚洲а∨天堂久久精品2021 | 无码av岛国片在线播放 | 欧美变态另类xxxx | 亚洲成色在线综合网站 | 中文字幕无码免费久久9一区9 | 国产免费久久久久久无码 | 在教室伦流澡到高潮hnp视频 | 综合人妻久久一区二区精品 | 久久国产精品精品国产色婷婷 | 国产精品视频免费播放 | 国产精品第一国产精品 | 色婷婷欧美在线播放内射 | 色噜噜亚洲男人的天堂 | 少妇高潮喷潮久久久影院 | 久久精品国产一区二区三区 | 久久精品无码一区二区三区 | 人妻人人添人妻人人爱 | 亚洲精品一区二区三区在线观看 | 狠狠躁日日躁夜夜躁2020 | 黑森林福利视频导航 | 国内精品久久毛片一区二区 | 国产婷婷色一区二区三区在线 | 久热国产vs视频在线观看 | 国产精品va在线观看无码 | 免费男性肉肉影院 | 国产亚洲欧美日韩亚洲中文色 | 999久久久国产精品消防器材 | 欧美日本精品一区二区三区 | 免费网站看v片在线18禁无码 | 久久99精品国产麻豆 | 国产av一区二区三区最新精品 | 色一情一乱一伦一区二区三欧美 | 天堂久久天堂av色综合 | 日本饥渴人妻欲求不满 | 欧美zoozzooz性欧美 | 丰满护士巨好爽好大乳 | 性生交大片免费看女人按摩摩 | 日本一区二区三区免费高清 | 亚洲s色大片在线观看 | 亚洲熟妇色xxxxx亚洲 | 中文精品无码中文字幕无码专区 | 内射后入在线观看一区 | 亚洲成av人影院在线观看 | 国产超级va在线观看视频 | 久久久久久亚洲精品a片成人 | 好屌草这里只有精品 | 国产午夜手机精彩视频 | 男女超爽视频免费播放 | 国产乱码精品一品二品 | 久久人人爽人人爽人人片av高清 | 99精品无人区乱码1区2区3区 | 欧美野外疯狂做受xxxx高潮 | 国产真实乱对白精彩久久 | 欧美丰满熟妇xxxx | 亚洲综合无码久久精品综合 | 男女性色大片免费网站 | 俺去俺来也在线www色官网 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 国产熟女一区二区三区四区五区 | 免费观看的无遮挡av | 四十如虎的丰满熟妇啪啪 | 国产精品人人爽人人做我的可爱 | 成熟人妻av无码专区 | 国产绳艺sm调教室论坛 | 少妇性俱乐部纵欲狂欢电影 | 亚洲 激情 小说 另类 欧美 | 亚洲国产欧美在线成人 | 精品无人国产偷自产在线 | 久久精品国产日本波多野结衣 | 全球成人中文在线 | 成人性做爰aaa片免费看 | 午夜成人1000部免费视频 | 午夜熟女插插xx免费视频 | 久久天天躁夜夜躁狠狠 | 国产疯狂伦交大片 | 亚洲色www成人永久网址 | 亚洲国产欧美国产综合一区 | 中文字幕人成乱码熟女app | 玩弄少妇高潮ⅹxxxyw | 国内揄拍国内精品少妇国语 | 欧美xxxx黑人又粗又长 | 亚洲精品成人av在线 | 无码播放一区二区三区 | 日日天日日夜日日摸 | 无码免费一区二区三区 | 香蕉久久久久久av成人 | 曰韩少妇内射免费播放 | 天天摸天天碰天天添 | 中文字幕av无码一区二区三区电影 | 精品人妻av区 | 亚洲爆乳精品无码一区二区三区 | 中文久久乱码一区二区 | 国产av无码专区亚洲awww | 国产麻豆精品精东影业av网站 | 国产真人无遮挡作爱免费视频 | 亚洲综合无码久久精品综合 | 国产在线精品一区二区三区直播 | 熟妇女人妻丰满少妇中文字幕 | 精品偷拍一区二区三区在线看 | 99精品国产综合久久久久五月天 | 性生交大片免费看女人按摩摩 | 久久99精品国产.久久久久 | 国产精品无码成人午夜电影 | 亚洲精品午夜无码电影网 | 欧美人妻一区二区三区 | 午夜理论片yy44880影院 | 精品无码国产一区二区三区av | 成人影院yy111111在线观看 | 乱人伦人妻中文字幕无码 | 日韩人妻无码一区二区三区久久99 | 台湾无码一区二区 | 中文字幕亚洲情99在线 | 国产一精品一av一免费 | 精品久久8x国产免费观看 | 中文亚洲成a人片在线观看 | 国产综合久久久久鬼色 | 亚洲gv猛男gv无码男同 | 又大又黄又粗又爽的免费视频 | 国产精品igao视频网 | 午夜理论片yy44880影院 | 色噜噜亚洲男人的天堂 | 国产精品99久久精品爆乳 | 国产亚洲精品久久久久久大师 | 牲交欧美兽交欧美 | 中文字幕av日韩精品一区二区 | 色一情一乱一伦一视频免费看 | 亚洲色成人中文字幕网站 | 粗大的内捧猛烈进出视频 | 日本饥渴人妻欲求不满 | 永久免费观看美女裸体的网站 | 欧美丰满熟妇xxxx | 精品久久综合1区2区3区激情 | 乱码av麻豆丝袜熟女系列 | 欧美亚洲日韩国产人成在线播放 | 精品久久久无码中文字幕 | 亚洲国产欧美在线成人 | 久久99精品久久久久婷婷 | 国产精品成人av在线观看 | 极品嫩模高潮叫床 | 日日碰狠狠躁久久躁蜜桃 | 国产亚洲美女精品久久久2020 | 色综合天天综合狠狠爱 | 骚片av蜜桃精品一区 | 国产欧美亚洲精品a | 亚洲欧美国产精品久久 | 九一九色国产 | 国产两女互慰高潮视频在线观看 | 国产美女极度色诱视频www | 一本久道久久综合婷婷五月 | 乱人伦人妻中文字幕无码 | 丁香花在线影院观看在线播放 | 亚洲欧美精品aaaaaa片 | 自拍偷自拍亚洲精品10p | 国产精品嫩草久久久久 | 亚洲中文字幕无码中文字在线 | 欧美人与禽猛交狂配 | 亚洲成av人片在线观看无码不卡 | 狠狠色噜噜狠狠狠狠7777米奇 | 久久www免费人成人片 | 国产亚洲精品久久久久久久 | 无码人妻少妇伦在线电影 | 成 人 免费观看网站 | 97se亚洲精品一区 | 亚洲一区二区三区偷拍女厕 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产在线精品一区二区高清不卡 | 亚洲精品国产a久久久久久 | 久久精品丝袜高跟鞋 | 中文字幕日韩精品一区二区三区 | 色婷婷av一区二区三区之红樱桃 | 久久97精品久久久久久久不卡 | 色情久久久av熟女人妻网站 | 小sao货水好多真紧h无码视频 | 人妻无码久久精品人妻 | 白嫩日本少妇做爰 | 蜜桃视频插满18在线观看 | 国产麻豆精品一区二区三区v视界 | 欧美 丝袜 自拍 制服 另类 | 国产 精品 自在自线 | 人人超人人超碰超国产 | 99在线 | 亚洲 | 欧美一区二区三区视频在线观看 | 99久久人妻精品免费一区 | 纯爱无遮挡h肉动漫在线播放 | 俄罗斯老熟妇色xxxx | а√天堂www在线天堂小说 | 亚洲国产av美女网站 | 国产乱人伦av在线无码 | 无码av中文字幕免费放 | 亚洲一区二区三区 | 天堂а√在线中文在线 | 精品欧洲av无码一区二区三区 | 日本熟妇人妻xxxxx人hd | 女人高潮内射99精品 | 国产亚洲人成在线播放 | 国产真人无遮挡作爱免费视频 | 色婷婷综合激情综在线播放 | 最新国产乱人伦偷精品免费网站 | 九九在线中文字幕无码 | 精品久久8x国产免费观看 | 丰满妇女强制高潮18xxxx | 亚洲男人av香蕉爽爽爽爽 | 正在播放老肥熟妇露脸 | 蜜桃av抽搐高潮一区二区 | 午夜成人1000部免费视频 | 图片小说视频一区二区 | 四虎国产精品免费久久 | 国产av无码专区亚洲a∨毛片 | 国产一区二区三区四区五区加勒比 | 国产成人午夜福利在线播放 | 亚洲精品久久久久avwww潮水 | 亚洲成色在线综合网站 | 久久久久免费精品国产 | 99久久精品国产一区二区蜜芽 | 国产精品18久久久久久麻辣 | 国产va免费精品观看 | 亚洲乱码国产乱码精品精 | 无码人妻久久一区二区三区不卡 | 中文字幕色婷婷在线视频 | 成人性做爰aaa片免费看不忠 | 中文字幕无码av激情不卡 | 久久久久99精品国产片 | www成人国产高清内射 | 午夜时刻免费入口 | 精品国产国产综合精品 | 四十如虎的丰满熟妇啪啪 | 亚洲国产av精品一区二区蜜芽 | 日韩精品久久久肉伦网站 | 久久亚洲a片com人成 | 免费视频欧美无人区码 | 国产成人无码av片在线观看不卡 | 人妻无码αv中文字幕久久琪琪布 | 国产午夜无码视频在线观看 | 国产精品.xx视频.xxtv | 亚洲s码欧洲m码国产av | 色婷婷综合中文久久一本 | 久久精品国产99久久6动漫 | 精品国产一区二区三区av 性色 | 国产精品igao视频网 | 激情亚洲一区国产精品 | 女人被男人躁得好爽免费视频 | 1000部夫妻午夜免费 | 人人妻人人澡人人爽欧美精品 | 三上悠亚人妻中文字幕在线 | 日韩欧美中文字幕在线三区 | 国产成人一区二区三区别 | 亚洲精品一区二区三区在线观看 | 国产激情无码一区二区 | 三级4级全黄60分钟 | 97资源共享在线视频 | 日韩精品成人一区二区三区 | 无码播放一区二区三区 | 日日躁夜夜躁狠狠躁 | 狠狠色噜噜狠狠狠7777奇米 | 亚洲色偷偷男人的天堂 | 亚洲国产精品毛片av不卡在线 | 国产精品美女久久久久av爽李琼 | 无码吃奶揉捏奶头高潮视频 | 亚洲一区二区三区国产精华液 | 国产亚洲精品精品国产亚洲综合 | 少妇无码一区二区二三区 | 精品国产一区二区三区四区 | 国产艳妇av在线观看果冻传媒 | 帮老师解开蕾丝奶罩吸乳网站 | 欧美精品无码一区二区三区 | 荡女精品导航 | 日韩欧美中文字幕在线三区 | 在教室伦流澡到高潮hnp视频 | 国产九九九九九九九a片 | 国产精品资源一区二区 | 亚洲国产一区二区三区在线观看 | 男女作爱免费网站 | 秋霞特色aa大片 | aa片在线观看视频在线播放 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产69精品久久久久app下载 | 男人扒开女人内裤强吻桶进去 | 亚洲va中文字幕无码久久不卡 | 伊人久久大香线蕉午夜 | 欧美丰满少妇xxxx性 | 亚洲人交乣女bbw | 一区二区三区乱码在线 | 欧洲 | 国产精品无码一区二区桃花视频 | 四虎国产精品一区二区 | 欧美成人高清在线播放 | 精品国产成人一区二区三区 | 国产精品va在线观看无码 | 国产精品久久久久影院嫩草 | 小sao货水好多真紧h无码视频 | 免费乱码人妻系列无码专区 | 日韩人妻少妇一区二区三区 | 国产精品久久久久久亚洲毛片 | 国产精品高潮呻吟av久久4虎 | 亚洲а∨天堂久久精品2021 | 中文字幕 亚洲精品 第1页 | 日产精品高潮呻吟av久久 | 日日橹狠狠爱欧美视频 | 狠狠综合久久久久综合网 | 国产精品亚洲专区无码不卡 | 国产免费久久久久久无码 | 午夜精品一区二区三区在线观看 | 精品国产乱码久久久久乱码 | 亚洲精品无码国产 | 国产在线一区二区三区四区五区 | 久久久久99精品国产片 | 国产特级毛片aaaaaaa高清 | 国产精品毛片一区二区 | 丰满岳乱妇在线观看中字无码 | 色 综合 欧美 亚洲 国产 | 国产精品香蕉在线观看 | 亚洲精品一区二区三区在线观看 | 亚洲理论电影在线观看 | 真人与拘做受免费视频一 | 国产欧美亚洲精品a | 久久无码专区国产精品s | 久久无码专区国产精品s | 国产一区二区三区日韩精品 | 内射白嫩少妇超碰 | 在线观看国产午夜福利片 | 久久久成人毛片无码 | 1000部啪啪未满十八勿入下载 | 乌克兰少妇xxxx做受 | 大色综合色综合网站 | 在线精品亚洲一区二区 | 国产亲子乱弄免费视频 | 久精品国产欧美亚洲色aⅴ大片 | 老太婆性杂交欧美肥老太 | 国产亚洲tv在线观看 | 欧美成人午夜精品久久久 | 久久伊人色av天堂九九小黄鸭 | 国产av久久久久精东av | 亚洲s色大片在线观看 | 男人的天堂av网站 | 在教室伦流澡到高潮hnp视频 | 日本熟妇人妻xxxxx人hd | 成人无码精品一区二区三区 | www国产亚洲精品久久网站 | 国产亚洲欧美日韩亚洲中文色 | 日韩av激情在线观看 | 亚洲成av人在线观看网址 | 久久国产精品萌白酱免费 | 国产精品久久国产精品99 | 国产精品国产三级国产专播 | 久久aⅴ免费观看 | 全黄性性激高免费视频 | 亚洲综合伊人久久大杳蕉 | 老熟女重囗味hdxx69 | 日本乱人伦片中文三区 | 麻豆国产丝袜白领秘书在线观看 | 伊在人天堂亚洲香蕉精品区 | 两性色午夜免费视频 | 熟妇人妻中文av无码 | 亚洲色偷偷偷综合网 | 国产亚洲视频中文字幕97精品 | 中文字幕乱妇无码av在线 | 精品无码国产一区二区三区av | 亚洲国产精品美女久久久久 | 国产 精品 自在自线 | 国产午夜手机精彩视频 | 乱中年女人伦av三区 | 国产成人无码a区在线观看视频app | 中文字幕人妻无码一区二区三区 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产国产精品人在线视 | 任你躁国产自任一区二区三区 | 日韩亚洲欧美精品综合 | 疯狂三人交性欧美 | 国产精品无码一区二区三区不卡 | 精品人妻中文字幕有码在线 | 蜜桃视频韩日免费播放 | 人人妻人人澡人人爽欧美一区九九 | 老熟妇乱子伦牲交视频 | 少妇太爽了在线观看 | 东京热一精品无码av | 国产内射爽爽大片视频社区在线 | 国产激情综合五月久久 | 国产卡一卡二卡三 | 88国产精品欧美一区二区三区 | 国产三级久久久精品麻豆三级 | 无码人妻丰满熟妇区五十路百度 | 国产av一区二区三区最新精品 | 久久精品国产一区二区三区 | 国产亚av手机在线观看 | 高清国产亚洲精品自在久久 | 又色又爽又黄的美女裸体网站 | 国内老熟妇对白xxxxhd | 日本护士毛茸茸高潮 | 一个人看的www免费视频在线观看 | 真人与拘做受免费视频一 | 国产亚洲人成在线播放 | 一本精品99久久精品77 | 麻豆人妻少妇精品无码专区 | 欧美丰满熟妇xxxx性ppx人交 | 精品 日韩 国产 欧美 视频 | 性做久久久久久久久 | 亚洲国产一区二区三区在线观看 | 国产区女主播在线观看 | 国产麻豆精品一区二区三区v视界 | 国产又爽又猛又粗的视频a片 | 国产热a欧美热a在线视频 | 人妻插b视频一区二区三区 | 国产疯狂伦交大片 | 久久久久免费精品国产 | 夫妻免费无码v看片 | 国产精品多人p群无码 | 牲欲强的熟妇农村老妇女视频 | 成 人 网 站国产免费观看 | 内射后入在线观看一区 | 久久久久人妻一区精品色欧美 | v一区无码内射国产 | 亚洲一区二区三区 | 免费无码一区二区三区蜜桃大 | 一区二区三区高清视频一 | 少妇性l交大片欧洲热妇乱xxx | 免费看男女做好爽好硬视频 | 成人女人看片免费视频放人 | 鲁一鲁av2019在线 | 亚洲欧美精品aaaaaa片 | 欧美精品无码一区二区三区 | 超碰97人人做人人爱少妇 | 国产色精品久久人妻 | 乱码av麻豆丝袜熟女系列 | 久久国产精品精品国产色婷婷 | 3d动漫精品啪啪一区二区中 | 久久久精品人妻久久影视 | 国产午夜视频在线观看 | 99re在线播放 | 亚洲精品综合五月久久小说 | 久久亚洲日韩精品一区二区三区 | 丰满人妻被黑人猛烈进入 | 国产免费久久精品国产传媒 | 久久综合色之久久综合 | 成人无码影片精品久久久 | 久久午夜无码鲁丝片秋霞 | 综合网日日天干夜夜久久 | 精品无码国产自产拍在线观看蜜 | 免费视频欧美无人区码 | 少女韩国电视剧在线观看完整 | 成年美女黄网站色大免费视频 | 丰满少妇熟乱xxxxx视频 | 亚洲国产精品毛片av不卡在线 | 女高中生第一次破苞av | 在线观看免费人成视频 | 黑人巨大精品欧美黑寡妇 | 99久久人妻精品免费一区 | 国内精品久久毛片一区二区 | 人人澡人摸人人添 | 欧美午夜特黄aaaaaa片 | 国产激情无码一区二区 | 黑人巨大精品欧美黑寡妇 | 人人澡人人透人人爽 | 初尝人妻少妇中文字幕 | 亚洲成a人片在线观看日本 | 国产高潮视频在线观看 | 玩弄人妻少妇500系列视频 | 风流少妇按摩来高潮 | 日韩无套无码精品 | 乱人伦人妻中文字幕无码久久网 | 无套内谢的新婚少妇国语播放 | 久久五月精品中文字幕 | 综合人妻久久一区二区精品 | 国产成人综合在线女婷五月99播放 | 老熟女重囗味hdxx69 | 人妻aⅴ无码一区二区三区 | 亚洲综合在线一区二区三区 | 无码人妻丰满熟妇区五十路百度 | 97无码免费人妻超级碰碰夜夜 | 精品国偷自产在线视频 | 亚洲男人av天堂午夜在 | 国产精品久久久午夜夜伦鲁鲁 | 大地资源中文第3页 | 久久99精品国产.久久久久 | 成在人线av无码免观看麻豆 | 少妇愉情理伦片bd | 强伦人妻一区二区三区视频18 | 激情亚洲一区国产精品 | 中文字幕乱码人妻无码久久 | 亚洲欧美色中文字幕在线 | 中文精品无码中文字幕无码专区 | 性欧美熟妇videofreesex | 人人妻人人澡人人爽人人精品浪潮 | 国产乱人偷精品人妻a片 | 思思久久99热只有频精品66 | 亚洲色大成网站www | 久久精品人妻少妇一区二区三区 | 日本丰满护士爆乳xxxx | 波多野结衣 黑人 | 亚洲精品一区二区三区四区五区 | 四虎国产精品一区二区 | 久在线观看福利视频 | 久久午夜夜伦鲁鲁片无码免费 | 欧美熟妇另类久久久久久不卡 | 免费乱码人妻系列无码专区 | 国产精品欧美成人 | 亚洲娇小与黑人巨大交 | 又大又硬又黄的免费视频 | 国产成人av免费观看 | 国产精品无套呻吟在线 | 精品午夜福利在线观看 | 亚洲精品国产精品乱码视色 | 四十如虎的丰满熟妇啪啪 | 未满成年国产在线观看 | 国产亲子乱弄免费视频 | 亚洲综合色区中文字幕 | 亚洲人成影院在线观看 | 日本欧美一区二区三区乱码 | 日本乱人伦片中文三区 | 国产熟妇高潮叫床视频播放 | 色诱久久久久综合网ywww | 女人被男人爽到呻吟的视频 | 黑人玩弄人妻中文在线 | 国产日产欧产精品精品app | 精品国产乱码久久久久乱码 | 日韩av无码一区二区三区 | 99久久久无码国产精品免费 | 无码人中文字幕 | 天堂无码人妻精品一区二区三区 | 亚洲 a v无 码免 费 成 人 a v | 1000部啪啪未满十八勿入下载 | 亚洲国产一区二区三区在线观看 | 色诱久久久久综合网ywww | 亚洲精品一区二区三区在线 | 99久久久无码国产精品免费 | 国内少妇偷人精品视频 | 久久国产36精品色熟妇 | 久久久国产精品无码免费专区 | 少妇邻居内射在线 | 国产av一区二区三区最新精品 | 国产成人人人97超碰超爽8 | 国产熟妇高潮叫床视频播放 | 性欧美牲交在线视频 | 中国女人内谢69xxxxxa片 | 久久无码中文字幕免费影院蜜桃 | 国产成人综合美国十次 | 老子影院午夜精品无码 | 国产麻豆精品精东影业av网站 | 免费无码午夜福利片69 | 在线a亚洲视频播放在线观看 | 国产熟妇高潮叫床视频播放 | 免费看少妇作爱视频 | 亚洲成a人片在线观看无码3d | 国产偷抇久久精品a片69 | 国产激情艳情在线看视频 | www国产精品内射老师 | aⅴ亚洲 日韩 色 图网站 播放 | 香蕉久久久久久av成人 | 人妻互换免费中文字幕 | 丰满人妻翻云覆雨呻吟视频 | 图片区 小说区 区 亚洲五月 | 亚洲中文字幕无码中字 | 欧美猛少妇色xxxxx | 欧美精品免费观看二区 | 久热国产vs视频在线观看 | 国产内射爽爽大片视频社区在线 | 国产精品亚洲专区无码不卡 | 无码人妻少妇伦在线电影 | 久久97精品久久久久久久不卡 | 午夜精品久久久久久久 | 欧美性猛交xxxx富婆 | 日本www一道久久久免费榴莲 | 国产乱人伦av在线无码 | 亚洲国产av精品一区二区蜜芽 | 国产精品久久久久久无码 | 人人超人人超碰超国产 | www一区二区www免费 | 男女下面进入的视频免费午夜 | 丰满少妇高潮惨叫视频 | 精品国产精品久久一区免费式 | 国产成人无码午夜视频在线观看 | 中国女人内谢69xxxx | 国产欧美精品一区二区三区 | 欧美性色19p | 中文字幕 人妻熟女 | 国产精品久久国产精品99 | 青春草在线视频免费观看 | 日日噜噜噜噜夜夜爽亚洲精品 | 高清不卡一区二区三区 | 国产一区二区三区日韩精品 | 日韩欧美中文字幕在线三区 | 人妻少妇精品无码专区动漫 | 亚洲色欲色欲欲www在线 | 国产在线无码精品电影网 | 内射老妇bbwx0c0ck | 亚洲gv猛男gv无码男同 | 俄罗斯老熟妇色xxxx | 377p欧洲日本亚洲大胆 | 亚洲成av人影院在线观看 | 牲欲强的熟妇农村老妇女 | 熟妇人妻激情偷爽文 | 欧美人妻一区二区三区 | 国产香蕉尹人综合在线观看 | 无码吃奶揉捏奶头高潮视频 | 婷婷综合久久中文字幕蜜桃三电影 | 亚洲a无码综合a国产av中文 | 天天综合网天天综合色 | 色综合久久久久综合一本到桃花网 | 久久亚洲精品中文字幕无男同 | 国产亚洲美女精品久久久2020 | 日韩av无码一区二区三区不卡 | 亚洲 欧美 激情 小说 另类 | 中文字幕亚洲情99在线 | 97se亚洲精品一区 | 日本va欧美va欧美va精品 | 成 人 网 站国产免费观看 | 婷婷综合久久中文字幕蜜桃三电影 | 国产精品丝袜黑色高跟鞋 | 日本丰满护士爆乳xxxx | 久久综合狠狠综合久久综合88 | 图片区 小说区 区 亚洲五月 | 男女爱爱好爽视频免费看 | 激情内射亚州一区二区三区爱妻 | 亚洲精品国偷拍自产在线观看蜜桃 | 久青草影院在线观看国产 | 成人免费无码大片a毛片 | 中国女人内谢69xxxx | 欧美日韩精品 | 亚洲人成无码网www | 少妇无码av无码专区在线观看 | 丝袜 中出 制服 人妻 美腿 | 国内精品九九久久久精品 | 欧美性色19p | 婷婷五月综合缴情在线视频 | 国产人妻人伦精品1国产丝袜 | 精品欧美一区二区三区久久久 | 精品久久久无码中文字幕 | 精品水蜜桃久久久久久久 | 精品无码国产一区二区三区av | 国产美女精品一区二区三区 | 久久综合激激的五月天 | 少妇无套内谢久久久久 | 欧美激情综合亚洲一二区 | 国产两女互慰高潮视频在线观看 | 国产无遮挡又黄又爽免费视频 | 亚洲成色www久久网站 | 成年女人永久免费看片 | av无码久久久久不卡免费网站 | 大色综合色综合网站 | 激情国产av做激情国产爱 | 色狠狠av一区二区三区 | 超碰97人人做人人爱少妇 | 搡女人真爽免费视频大全 | 夜夜夜高潮夜夜爽夜夜爰爰 | 又湿又紧又大又爽a视频国产 | 国产午夜无码精品免费看 | 大肉大捧一进一出好爽视频 | 国产性生大片免费观看性 | 国产无遮挡又黄又爽免费视频 | 精品无码国产自产拍在线观看蜜 | 久久久久亚洲精品中文字幕 | 国精产品一区二区三区 | 日日鲁鲁鲁夜夜爽爽狠狠 | 国产一区二区三区影院 | 无码纯肉视频在线观看 | 久久人妻内射无码一区三区 | 中文字幕无码免费久久99 | 99久久人妻精品免费二区 | 少妇无码一区二区二三区 | 国产在线精品一区二区三区直播 | 亚洲精品午夜国产va久久成人 | 无码毛片视频一区二区本码 | 丰满诱人的人妻3 | 激情综合激情五月俺也去 | 欧美日韩人成综合在线播放 | 久久国产36精品色熟妇 | 捆绑白丝粉色jk震动捧喷白浆 | 中文字幕av无码一区二区三区电影 | 天天躁夜夜躁狠狠是什么心态 | а天堂中文在线官网 | 欧美老妇交乱视频在线观看 | 中文字幕乱码亚洲无线三区 | 熟妇人妻无乱码中文字幕 | 欧洲精品码一区二区三区免费看 | 精品乱子伦一区二区三区 | 久久99精品久久久久久动态图 | 鲁一鲁av2019在线 | 领导边摸边吃奶边做爽在线观看 | 一二三四社区在线中文视频 | 久久精品人人做人人综合 | 亚洲精品国产a久久久久久 | 狠狠色色综合网站 | 国产成人精品久久亚洲高清不卡 | 久久久久成人精品免费播放动漫 |