• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            asm, c, c++ are my all
            -- Core In Computer
            posts - 139,  comments - 123,  trackbacks - 0
            [轉(zhuǎn)]windows核心編程--內(nèi)存映射文件

            與虛擬內(nèi)存一樣,內(nèi)存映射文件可以用來保留一個地址空間的區(qū)域,并將物理存儲器提交給該區(qū)域。它們之間的差別是,物理存儲器來自一個已經(jīng)位于磁盤上的文件,而不是系統(tǒng)的頁文件。一旦該文件被映射,就可以訪問它,就像整個文件已經(jīng)加載內(nèi)存一樣。

            內(nèi)存映射文件可以用于3個不同的目的:

            ? 系統(tǒng)使用內(nèi)存映射文件,以便加載和執(zhí)行. e x e和D L L文件。這可以大大節(jié)省頁文件空間和應用程序啟動運行所需的時間。

            ? 可以使用內(nèi)存映射文件來訪問磁盤上的數(shù)據(jù)文件。這使你可以不必對文件執(zhí)行I / O操作,并且可以不必對文件內(nèi)容進行緩存。

            ? 可以使用內(nèi)存映射文件,使同一臺計算機上運行的多個進程能夠相互之間共享數(shù)據(jù)。Wi n d o w s確實提供了其他一些方法,以便在進程之間進行數(shù)據(jù)通信,但是這些方法都是使用內(nèi)存映射文件來實現(xiàn)的,這使得內(nèi)存映射文件成為單個計算機上的多個進程互相進行通信的最有效的方法。

            內(nèi)存映射的可執(zhí)行文件和DLL文件

            當線程調(diào)用C r e a t e P r o c e s s時,系統(tǒng)將執(zhí)行下列操作步驟:

            1) 系統(tǒng)找出在調(diào)用C r e a t e P r o c e s s時設定的. e x e文件。如果找不到這個. e x e文件,進程將無法創(chuàng)建,C r e a t e P r o c e s s將返回FA L S E。

            2) 系統(tǒng)創(chuàng)建一個新進程內(nèi)核對象。

            3) 系統(tǒng)為這個新進程創(chuàng)建一個私有地址空間。

            4) 系統(tǒng)保留一個足夠大的地址空間區(qū)域,用于存放該. e x e文件。該區(qū)域需要的位置在. e x e文件本身中設定。按照默認設置, . e x e文件的基地址是0 x 0 0 4 0 0 0 0 0(這個地址可能不同于在6 4位Windows 2000上運行的6 4位應用程序的地址),但是,可以在創(chuàng)建應用程序的. e x e文件時重載這個地址,方法是在鏈接應用程序時使用鏈接程序的/ B A S E選項。

            5) 系統(tǒng)注意到支持已保留區(qū)域的物理存儲器是在磁盤上的. e x e文件中,而不是在系統(tǒng)的頁文件中。

            當. e x e文件被映射到進程的地址空間中之后,系統(tǒng)將訪問. e x e文件的一個部分,該部分列出了包含. e x e文件中的代碼要調(diào)用的函數(shù)的D L L文件。然后,系統(tǒng)為每個D L L文件調(diào)用L o a d L i b r a r y函數(shù),如果任何一個D L L需要更多的D L L,那么系統(tǒng)將調(diào)用L o a d L i b r a r y函數(shù),以便加載這些D L L。每當調(diào)用L o a d L i b r a r y來加載一個D L L時,系統(tǒng)將執(zhí)行下列操作步驟,它們均類似上面的第4和第5個步驟:

            1) 系統(tǒng)保留一個足夠大的地址空間區(qū)域,用于存放該D L L文件。該區(qū)域需要的位置在D L L文件本身中設定。按照默認設置, M i c r o s o f t的Visual C++ 建立的D L L文件基地址是0 x 1 0 0 0 0 0 0 0(這個地址可能不同于在6 4位Windows 2000上運行的6 4位D L L的地址)但是,你可以在創(chuàng)建D L L文件時重載這個地址,方法是使用鏈接程序的/ B A S E選項。Wi n d o w s提供的所有標準系統(tǒng)D L L都擁有不同的基地址,這樣,如果加載到單個地址空間,它們就不會重疊。

            2) 如果系統(tǒng)無法在該D L L的首選基地址上保留一個區(qū)域,其原因可能是該區(qū)域已經(jīng)被另一個D L L或. e x e占用,也可能是因為該區(qū)域不夠大,此時系統(tǒng)將設法尋找另一個地址空間的區(qū)域來保留該D L L。

            3) 系統(tǒng)會注意到支持已保留區(qū)域的物理存儲器位于磁盤上的D L L文件中,而不是在系統(tǒng)的頁文件中。

            如果由于某個原因系統(tǒng)無法映射. e x e和所有必要的D L L文件,那么系統(tǒng)就會向用戶顯示一個消息框,并且釋放進程的地址空間和進程對象。
            當所有的. e x e和D L L文件都被映射到進程的地址空間之后,系統(tǒng)就可以開始執(zhí)行. e x e文件的啟動代碼。當. e x e文件被映射后,系統(tǒng)將負責所有的分頁、緩沖和高速緩存的處理。
            在可執(zhí)行文件或DLL的多個實例之間共享靜態(tài)數(shù)據(jù) (通過定義共享的節(jié))

            全局數(shù)據(jù)和靜態(tài)數(shù)據(jù)不能被同一個. e x e或D L L文件的多個映像共享,這是個安全的默認設置。但是,在某些情況下,讓一個. e x e文件的多個映像共享一個變量的實例是非常有用和方便的。例如,Wi n d o w s沒有提供任何簡便的方法來確定用戶是否在運行應用程序的多個實例。但是,如果能夠讓所有實例共享單個全局變量,那么這個全局變量就能夠反映正在運行的實例的數(shù)量。
            ?內(nèi)存映射數(shù)據(jù)文件

            操作系統(tǒng)使得內(nèi)存能夠?qū)⒁粋€數(shù)據(jù)文件映射到進程的地址空間中。因此,對大量的數(shù)據(jù)進行操作是非常方便的。

            為了理解用這種方法來使用內(nèi)存映射文件的功能,讓我們看一看如何用4種方法來實現(xiàn)一個程序,以便將文件中的所有字節(jié)的順序進行倒序。

            方法1:一個文件,一個緩存

            第一種方法也是理論上最簡單的方法,它需要分配足夠大的內(nèi)存塊來存放整個文件。該文件被打開,它的內(nèi)容被讀入內(nèi)存塊,然后該文件被關(guān)閉。文件內(nèi)容進入內(nèi)存后,我們就可以對所有字節(jié)的順序進行倒序,方法是將第一個字節(jié)倒騰為最后一個字節(jié),第二個字節(jié)倒騰為倒數(shù)第二個字節(jié),依次類推。這個倒騰操作將一直進行下去直到文件的中間位置。當所有的字節(jié)都已經(jīng)倒騰之后,就可以重新打開該文件,并用內(nèi)存塊的內(nèi)容來改寫它的內(nèi)容。

            這種方法實現(xiàn)起來非常容易,但是它有兩個缺點。首先,必須分配一個與文件大小相同的內(nèi)存塊。如果文件比較小,那么這沒有什么問題。但是如果文件非常大,比如說有2 G B大,那該怎么辦呢?一個3 2位的系統(tǒng)不允許應用程序提交那么大的物理內(nèi)存塊。因此大文件需要使用不同的方法。

            第二,如果進程在運行過程的中間被中斷,也就是說當?shù)剐蚝蟮淖止?jié)被重新寫入該文件時進程被中斷,那么文件的內(nèi)容就會遭到破壞。防止出現(xiàn)這種情況的最簡單的方法是在對它的內(nèi)容進行倒序之前先制作一個原始文件的拷貝。如果整個進程運行成功,那么可以刪除該文件的拷貝。這種方法需要更多的磁盤空間。

            ?方法2:兩個文件,一個緩存

            在第二種方法中,你打開現(xiàn)有的文件,并且在磁盤上創(chuàng)建一個長度為0的新文件。然后分配一個比較小的內(nèi)部緩存,比如說8 KB。你找到離原始文件結(jié)尾還有8 KB的位置,將這最后的8 KB讀入緩存,將字節(jié)倒序,再將緩存中的內(nèi)容寫入新創(chuàng)建的文件。這個尋找、讀入、倒序和寫入的操作過程要反復進行,直到到達原始文件的開頭。如果文件的長度不是8 KB的倍數(shù),那么必須進行某些特殊的處理。當原始文件完全處理完畢之后,將原始文件和新文件關(guān)閉,并刪除原始文件。

            這種方法實現(xiàn)起來比第一種方法要復雜一些。它對內(nèi)存的使用效率要高得多,因為它只需要分配一個8 KB的緩存塊,但是它存在兩個大問題。首先,它的處理速度比第一種方法要慢,原因是在每個循環(huán)操作過程中,在執(zhí)行讀入操作之前,必須對原始文件進行尋找操作。第二,這種方法可能要使用大量的硬盤空間。如果原始文件是400 MB,那么隨著進程的不斷運行,新文件就會增大為400 MB。在原始文件被刪除之前,兩個文件總共需要占用800 MB的磁盤空間。這比應該需要的空間大400 MB。由于存在這個缺點,因此引來了下一個方法。

            ?方法3:一個文件,兩個緩存

            如果使用這個方法,那么我們假設程序初始化時分配了兩個獨立的8 KB緩存。程序?qū)⑽募牡谝粋€8 KB讀入一個緩存,再將文件的第二個8 KB 讀入另一個緩存。然后進程將兩個緩存的內(nèi)容進行倒序,并將第一個緩存的內(nèi)容寫回文件的結(jié)尾處,將第二個緩存的內(nèi)容寫回同一個文件的開始處。每個迭代操作不斷進行(以8 KB為單位,從文件的開始和結(jié)尾處移動文件塊)。如果文件的長度不是16 KB的倍數(shù),并且有兩個8 KB的文件塊相重疊,那么就需要進行一些特殊的處理。這種特殊處理比上一種方法中的特殊處理更加復雜,不過這難不倒經(jīng)驗豐富的編程員。

            與前面的兩種方法相比,這種方法在節(jié)省硬盤空間方面有它的優(yōu)點。由于所有內(nèi)容都是從同一個文件讀取并寫入同一個文件,因此不需要增加額外的磁盤空間,至于內(nèi)存的使用,這種方法也不錯,它只需要使用16 KB的內(nèi)存。當然,這種方法也許是最難實現(xiàn)的方法。與第一種方法一樣,如果進程被中斷,本方法會導致數(shù)據(jù)文件被破壞。

            下面讓我們來看一看如何使用內(nèi)存映射文件來完成這個過程。

            方法4:一個文件,零緩存

            當使用內(nèi)存映射文件對文件內(nèi)容進行倒序時,你打開該文件,然后告訴系統(tǒng)將虛擬地址空間的一個區(qū)域進行倒序。你告訴系統(tǒng)將文件的第一個字節(jié)映射到該保留區(qū)域的第一個字節(jié)。然后可以訪問該虛擬內(nèi)存的區(qū)域,就像它包含了這個文件一樣。實際上,如果在文件的結(jié)尾處有一個單個0字節(jié),那么只需要調(diào)用C運行期函數(shù)_ s t r r e v,就可以對文件中的數(shù)據(jù)進行倒序操作。

            這種方法的最大優(yōu)點是,系統(tǒng)能夠為你管理所有的文件緩存操作。不必分配任何內(nèi)存,或者將文件數(shù)據(jù)加載到內(nèi)存,也不必將數(shù)據(jù)重新寫入該文件,或者釋放任何內(nèi)存塊。但是,內(nèi)存映射文件仍然可能出現(xiàn)因為電源故障之類的進程中斷而造成數(shù)據(jù)被破壞的問題。


            ?使用內(nèi)存映射文件

            若要使用內(nèi)存映射文件,必須執(zhí)行下列操作步驟:

            1) 創(chuàng)建或打開一個文件內(nèi)核對象,該對象用于標識磁盤上你想用作內(nèi)存映射文件的文件。

            2) 創(chuàng)建一個文件映射內(nèi)核對象,告訴系統(tǒng)該文件的大小和你打算如何訪問該文件。

            3) 讓系統(tǒng)將文件映射對象的全部或一部分映射到你的進程地址空間中。

            當完成對內(nèi)存映射文件的使用時,必須執(zhí)行下面這些步驟將它清除:

            1) 告訴系統(tǒng)從你的進程的地址空間中撤消文件映射內(nèi)核對象的映像。

            2) 關(guān)閉文件映射內(nèi)核對象。

            3) 關(guān)閉文件內(nèi)核對象。

            步驟1:創(chuàng)建或打開文件內(nèi)核對象

            若要創(chuàng)建或打開一個文件內(nèi)核對象,總是要調(diào)用C r e a t e F i l e函數(shù):

            										HANDLE CreateFile(
               PCSTR pszFileName,
               DWORD dwDesiredAccess,
               DWORD dwShareMode,
               PSECURITY_ATTRIBUTES psa,
               DWORD dwCreationDisposition,
               DWORD dwFlagsAndAttributes,
               HANDLE hTemplateFile);
            								

            步驟2:創(chuàng)建一個文件映射內(nèi)核對象

            調(diào)用C r e a t e F i l e函數(shù),就可以將文件映像的物理存儲器的位置告訴操作系統(tǒng)。你傳遞的路徑名用于指明支持文件映像的物理存儲器在磁盤(或網(wǎng)絡或光盤)上的確切位置。這時,必須告訴系統(tǒng),文件映射對象需要多少物理存儲器。若要進行這項操作,可以調(diào)用C r e a t e F i l e M a p p i n g函數(shù):

            										HANDLE CreateFileMapping(
               HANDLE hFile,
               PSECURITY_ATTRIBUTES psa,
               DWORD fdwProtect,
               DWORD dwMaximumSizeHigh,
               DWORD dwMaximumSizeLow,
               PCTSTR pszName);
            								

            步驟3:將文件數(shù)據(jù)映射到進程的地址空間

            當創(chuàng)建了一個文件映射對象后,仍然必須讓系統(tǒng)為文件的數(shù)據(jù)保留一個地址空間區(qū)域,并將文件的數(shù)據(jù)作為映射到該區(qū)域的物理存儲器進行提交??梢酝ㄟ^調(diào)用M a p Vi e w O f F i l e函數(shù)來進行這項操作:

            										PVOID MapViewOfFile(
               HANDLE hFileMappingObject,
               DWORD dwDesiredAccess,
               DWORD dwFileOffsetHigh,
               DWORD dwFileOffsetLow,
               SIZE_T dwNumberOfBytesToMap);
            								

            步驟4:從進程的地址空間中撤消文件數(shù)據(jù)的映像

            當不再需要保留映射到你的進程地址空間區(qū)域中的文件數(shù)據(jù)時,可以通過調(diào)用下面的函數(shù)將它釋放:

            										BOOL UnmapViewOfFile(PVOID pvBaseAddress);
            								

            為了提高速度,系統(tǒng)將文件的數(shù)據(jù)頁面進行高速緩存,并且在對文件的映射視圖進行操作時不立即更新文件的磁盤映像。如果需要確保你的更新被寫入磁盤,可以強制系統(tǒng)將修改過的數(shù)據(jù)的一部分或全部重新寫入磁盤映像中,方法是調(diào)用F l u s h Vi e w O f F i l e函數(shù):

            										BOOL FlushViewOfFile(
               PVOID pvAddress,
               SIZE_T dwNumberOfBytesToFlush);
            								

            步驟5和步驟6:關(guān)閉文件映射對象和文件對象

            不用說,你總是要關(guān)閉你打開了的內(nèi)核對象。如果忘記關(guān)閉,在你的進程繼續(xù)運行時會出現(xiàn)資源泄漏的問題。當然,當你的進程終止運行時,系統(tǒng)會自動關(guān)閉你的進程已經(jīng)打開但是忘記關(guān)閉的任何對象。但是如果你的進程暫時沒有終止運行,你將會積累許多資源句柄。因此你始終都應該編寫清楚而又“正確的”代碼,以便關(guān)閉你已經(jīng)打開的任何對象。若要關(guān)閉文件映射對象和文件對象,只需要兩次調(diào)用C l o s e H a n d l e函數(shù),每個句柄調(diào)用一次:

            讓我們更加仔細地觀察一下這個進程。下面的偽代碼顯示了一個內(nèi)存映射文件的例子:

            										HANDLE hFile = CreateFile(...);
            HANDLE hFileMapping = CreateFileMapping(hFile, ...);
            PVOID pvFile = MapViewOfFile(hFileMapping, ...);
            
            // Use the memory-mapped file.
            
            UnmapViewOfFile(pvFile);
            CloseHandle(hFileMapping);
            CloseHandle(hFile);
            								

            上面的代碼顯示了對內(nèi)存映射文件進行操作所用的“預期”方法。但是,它沒有顯示,當你調(diào)用M a p Vi e w O f F i l e時系統(tǒng)對文件對象和文件映射對象的使用計數(shù)的遞增情況。這個副作用是很大的,因為它意味著我們可以將上面的代碼段重新編寫成下面的樣子:

            										HANDLE hFile = CreateFile(...);
            HANDLE hFileMapping = CreateFileMapping(hFile, ...);
            CloseHandle(hFile);
            PVOID pvFile = MapViewOfFile(hFileMapping, ...);
            CloseHandle(hFileMapping);
            
            // Use the memory-mapped file.
            
            UnmapViewOfFile(pvFile);
            								

            當對內(nèi)存映射文件進行操作時,通常要打開文件,創(chuàng)建文件映射對象,然后使用文件映射對象將文件的數(shù)據(jù)視圖映射到進程的地址空間。由于系統(tǒng)遞增了文件對象和文件映射對象的內(nèi)部使用計數(shù),因此可以在你的代碼開始運行時關(guān)閉這些對象,以消除資源泄漏的可能性。

            如果用同一個文件來創(chuàng)建更多的文件映射對象,或者映射同一個文件映射對象的多個視圖,那么就不能較早地調(diào)用C l o s e H a n d l e函數(shù)——以后你可能還需要使用它們的句柄,以便分別對C r e a t e F i l e M a p p i n g和M a p Vi e w O f F i l e函數(shù)進行更多的調(diào)用。

            使用內(nèi)存映射文件來處理大文件
            使用內(nèi)存映射文件在進程之間共享數(shù)據(jù)

            Wi n d o w s總是出色地提供各種機制,使應用程序能夠迅速而方便地共享數(shù)據(jù)和信息。這些機制包括R P C、C O M、O L E、D D E、窗口消息(尤其是W M _ C O P Y D ATA)、剪貼板、郵箱、管道和套接字等。在Wi n d o w s中,在單個計算機上共享數(shù)據(jù)的最低層機制是內(nèi)存映射文件。不錯,如果互相進行通信的所有進程都在同一臺計算機上的話,上面提到的所有機制均使用內(nèi)存映射文件從事它們的煩瑣工作。如果要求達到較高的性能和較小的開銷,內(nèi)存映射文件是舉手可得的最佳機制。

            數(shù)據(jù)共享方法是通過讓兩個或多個進程映射同一個文件映射對象的視圖來實現(xiàn)的,這意味著它們將共享物理存儲器的同一個頁面。因此,當一個進程將數(shù)據(jù)寫入一個共享文件映射對象的視圖時,其他進程可以立即看到它們視圖中的數(shù)據(jù)變更情況。注意,如果多個進程共享單個文件映射對象,那么所有進程必須使用相同的名字來表示該文件映射對象。

            讓我們觀察一個例子,啟動一個應用程序。當一個應用程序啟動時,系統(tǒng)調(diào)用C r e a t e F i l e函數(shù),打開磁盤上的. e x e文件。然后系統(tǒng)調(diào)用C r e a t e F i l e M a p p i n g函數(shù),創(chuàng)建一個文件映射對象。最后,系統(tǒng)代表新創(chuàng)建的進程調(diào)用M a p Vi e w O f F i l e E x函數(shù)(它帶有S E C _ I M A G E標志),這樣, . e x e文件就可以映射到進程的地址空間。這里調(diào)用的是M a p Vi e w O f F i l e E x,而不是M a p Vi e w O f F i l e,這樣,文件的映像將被映射到存放在. e x e文件映像中的基地址中。系統(tǒng)創(chuàng)建該進程的主線程,將該映射視圖的可執(zhí)行代碼的第一個字節(jié)的地址放入線程的指令指針,然后C P U啟動該代碼的運行。

            如果用戶運行同一個應用程序的第二個實例,系統(tǒng)就認為規(guī)定的. e x e文件已經(jīng)存在一個文件映射對象,因此不會創(chuàng)建新的文件對象或者文件映射對象。相反,系統(tǒng)將第二次映射該文件的一個視圖,這次是在新創(chuàng)建的進程的地址空間環(huán)境中映射的。系統(tǒng)所做的工作是將相同的文件同時映射到兩個地址空間。顯然,這是對內(nèi)存的更有效的使用,因為兩個進程將共享包含正在執(zhí)行的這部分代碼的物理存儲器的同一個頁面。

            與所有內(nèi)核對象一樣,可以使用3種方法與多個進程共享對象,這3種方法是句柄繼承性、句柄命名和句柄復制。
            ?內(nèi)存映射文件與數(shù)據(jù)視圖的相關(guān)性

            附錄:

            系統(tǒng)允許你映射一個文件的相同數(shù)據(jù)的多個視圖。例如,你可以將文件開頭的10 KB映射到一個視圖,然后將同一個文件的頭4 KB映射到另一個視圖。只要你是映射相同的文件映射對象,系統(tǒng)就會確保映射的視圖數(shù)據(jù)的相關(guān)性。例如,如果你的應用程序改變了一個視圖中的文件內(nèi)容,那么所有其他視圖均被更新以反映這個變化。這是因為盡管頁面多次被映射到進程的虛擬地址空間,但是系統(tǒng)只將數(shù)據(jù)放在單個R A M頁面上。如果多個進程映射單個數(shù)據(jù)文件的視圖,那么數(shù)據(jù)仍然是相關(guān)的,因為在數(shù)據(jù)文件中,每個R A M頁面只有一個實例——正是這個R A M頁面被映射到多個進程的地址空間。

            注意Wi n d o w s允許創(chuàng)建若干個由單個數(shù)據(jù)文件支持的文件映射對象。Wi n d o w s不能保證這些不同的文件映射對象的視圖具有相關(guān)性。它只能保證單個文件映射對象的多個視圖具有相關(guān)性。

            然而,當對文件進行操作時,沒有理由使另一個應用程序無法調(diào)用C r e a t e F i l e函數(shù)以打開由另一個進程映射的同一個文件。這個新進程可以使用R e a d F i l e和Wr i t e F i l e函數(shù)來讀取該文件的數(shù)據(jù)和將數(shù)據(jù)寫入該文件。當然,每當一個進程調(diào)用這些函數(shù)時,它必須從內(nèi)存緩沖區(qū)讀取文件數(shù)據(jù)或者將文件數(shù)據(jù)寫入內(nèi)存緩沖區(qū)。該內(nèi)存緩沖區(qū)必須是進程自己創(chuàng)建的一個緩沖區(qū),而不是映射文件使用的內(nèi)存緩沖區(qū)。當兩個應用程序打開同一個文件時,問題就可能產(chǎn)生:一個進程可以調(diào)用R e a d F i l e函數(shù)來讀取文件的一個部分,并修改它的數(shù)據(jù),然后使用Wr i t e F i l e函數(shù)將數(shù)據(jù)重新寫入文件,而第二個進程的文件映射對象卻不知道第一個進程執(zhí)行的這些操作。由于這個原因,當你為將被內(nèi)存映射的文件調(diào)用C r e a t e F i l e函數(shù)時,最好將d w S h a r e M o d e參數(shù)的值設置為0。這樣就可以告訴系統(tǒng),你想要單獨訪問這個文件,而其他進程都不能打開它。

            只讀文件不存在相關(guān)性問題,因此它們可以作為很好的內(nèi)存映射文件。內(nèi)存映射文件決不應該用于共享網(wǎng)絡上的可寫入文件,因為系統(tǒng)無法保證數(shù)據(jù)視圖的相關(guān)性。如果某個人的計算機更新了文件的內(nèi)容,其他內(nèi)存中含有原始數(shù)據(jù)的計算機將不知道它的信息已經(jīng)被修改。

            posted on 2006-10-11 13:46 Jerry Cat 閱讀(759) 評論(0)  編輯 收藏 引用

            <2006年10月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(7)

            隨筆檔案

            最新隨筆

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            青青青青久久精品国产h| 久久久久精品国产亚洲AV无码 | 久久亚洲AV成人出白浆无码国产 | 亚洲中文字幕无码久久2020| 18岁日韩内射颜射午夜久久成人| 97精品伊人久久久大香线蕉 | 久久e热在这里只有国产中文精品99| 国产99久久久国产精免费| 伊人久久综合热线大杳蕉下载| 久久精品国产99久久香蕉| 久久婷婷国产剧情内射白浆 | 久久九色综合九色99伊人| 国产69精品久久久久观看软件| 欧美丰满熟妇BBB久久久| 97超级碰碰碰碰久久久久| 亚洲人成无码www久久久| 国产亚洲精品美女久久久| 亚洲成av人片不卡无码久久| 久久精品国产第一区二区三区| 久久精品亚洲福利| 国产精品久久久久久| 香蕉久久影院| 国产叼嘿久久精品久久| 亚洲AV无码一区东京热久久| 精品人妻伦一二三区久久| AAA级久久久精品无码片| 久久久久亚洲精品日久生情| 国产精品女同一区二区久久| 久久人人妻人人爽人人爽| 久久久久久久91精品免费观看| 国产美女久久精品香蕉69| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 日韩久久久久久中文人妻| 久久夜色精品国产噜噜亚洲a| 亚洲综合精品香蕉久久网97 | 国产亚洲精久久久久久无码AV| 成人久久精品一区二区三区| 人妻无码αv中文字幕久久| 亚洲综合伊人久久综合| 99久久香蕉国产线看观香| 久久人人爽人人爽人人片AV高清|