亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 漫談兼容內核之十八:windows的lpc機制.txt

?? 漫談系統內核內幕 收集得很辛苦 呵呵 大家快下在吧
?? TXT
?? 第 1 頁 / 共 4 頁
字號:
      ExFreePool(CReply);
      ObDereferenceObject(NamedPort);
      return (STATUS_SUCCESS);
  }

  /* Prepare the connection. */
  if (WriteMap != NULL)
  {
      PSECTION_OBJECT SectionObject;
      LARGE_INTEGER SectionOffset;

      Status = ObReferenceObjectByHandle(WriteMap->SectionHandle,
                 SECTION_MAP_READ | SECTION_MAP_WRITE,
                 MmSectionObjectType, UserMode, (PVOID*)&SectionObject, NULL);
      . . . . . .

      SectionOffset.QuadPart = WriteMap->SectionOffset;
      WriteMap->TargetViewBase = 0;
      CReply->ReceiveClientViewSize = WriteMap->ViewSize;
      Status = MmMapViewOfSection(SectionObject, CRequest->ConnectingProcess,
                  &WriteMap->TargetViewBase, 0, CReply->ReceiveClientViewSize,
                  &SectionOffset, &CReply->ReceiveClientViewSize,
                  ViewUnmap, 0, PAGE_READWRITE);
      . . . . . .

      WriteMap->ViewBase = 0;
      Status = MmMapViewOfSection(SectionObject, PsGetCurrentProcess(),
                  &WriteMap->ViewBase, 0, WriteMap->ViewSize,
                  &SectionOffset, &WriteMap->ViewSize,
                  ViewUnmap, 0, PAGE_READWRITE);
      . . . . . .
     
      ObDereferenceObject(SectionObject);
  }
  if (ReadMap != NULL && CRequest->SendSectionObject != NULL)
  {
      LARGE_INTEGER SectionOffset;

      SectionOffset = CRequest->SendSectionOffset;
      ReadMap->ViewSize = CRequest->SendViewSize;
      ReadMap->ViewBase = 0;
      Status = MmMapViewOfSection(
                  CRequest->SendSectionObject, PsGetCurrentProcess(),
                  &ReadMap->ViewBase, 0, CRequest->SendViewSize,
                  &SectionOffset, &CRequest->SendViewSize,
                  ViewUnmap, 0, PAGE_READWRITE);
      . . . . . .
  }

  /* Finish the reply. */
  if (ReadMap != NULL)
  {
      CReply->SendServerViewBase = ReadMap->ViewBase;
  }
  else
  {
      CReply->SendServerViewBase = 0;
  }
  if (WriteMap != NULL)
  {
      CReply->ReceiveClientViewBase = WriteMap->TargetViewBase;
  }
  CReply->MaximumMessageSize = PORT_MAX_MESSAGE_LENGTH;

  /* Connect the two ports */
  OurPort->OtherPort = ConnectionRequest->Sender;
  OurPort->OtherPort->OtherPort = OurPort;
  EiReplyOrRequestPort(ConnectionRequest->Sender,
                        (PLPC_MESSAGE)CReply, LPC_REPLY, OurPort);
  ExFreePool(ConnectionRequest);
  ExFreePool(CReply);
  
  ObDereferenceObject(OurPort);
  ObDereferenceObject(NamedPort);

  return (STATUS_SUCCESS);
}[/code]

    如果接受連接請求,那么服務方也要創建一個通信端口,因為原來的連接端口是專門用來接收連接請求的。第一個參數ServerPortHandle就是用來返回新建通信端口的Handle。而NamedPortHandle當然就是連接端口的Handle,這是本次操作的目標對象。
    參數AcceptIt表示是否接受連接請求。
    參數WriteMap和ReadMap與NtConnectPort()中所用者相同。同樣,如果預期需要發送的數據量較大的話,服務方也要為此提供一個共享內存區。
    先看不接受連接請求時的情況,因為這比較簡單。這就是條件語句if (!AcceptIt)里面的操作:先將一個“拒絕連接”報文、即類型為LPC_CONNECTION_REFUSED的報文、通過EiReplyOrRequestPort()掛入對方端口的報文隊列,然后在對方端口的“信號量”上執行一次V操作,以喚醒正在等待的對方線程。這樣就行了。
    接受連接請求時的情況就比較復雜一點:
1. 先創建一個通信端口,就是類型為EPORT_TYPE_SERVER_COMM_PORT的端口。
2. 然后為應答報文LpcMessage準備好一個內核版本、就是類型為EPORT_CONNECT_REPLY_MESSAGE的數據結構Creply。
3. 處理共享內存區的映射。注意這里做了三次映射:
? l 把由服務方提供的共享內存區映射到客戶進程的用戶空間,這是客戶方的接收區。“連接請求”報文中的ConnectingProcess提供了指向客戶進程的EPROCESS數據結構的指針。
? l 把由服務方提供的共享內存區映射到服務方自己的用戶空間,這是服務方進程的寫入區。
? l 把由客戶方提供的共享內存區映射到服務方的用戶空間,這是服務方進程的讀出區。
    注意這里在調用MmMapViewOfSection()時所給定的地址都是0,表示聽從分配。所分配的地址要通過WriteMap和ReadMap返回到用戶空間,特別是替客戶方進程代為映射的地址要通過應答報文發送給對方。
4. 使服務方通信端口和客戶方通信端口的指針OtherPort互相指向對方,即建立連接。
5. 通過EiReplyOrRequestPort()將應答報文掛入客戶方端口的報文隊列,但是并不喚醒客戶方線程。

    在完成了NtAcceptConnectPort()以后,服務方線程還需要對新創建的通信端口執行一下另一個系統調用NtCompleteConnectPort()。目的在于喚醒客戶方線程。注意此時的操作對象已經是新創建的通信端口,而不再是連接端口。

[code]NTSTATUS STDCALL
NtCompleteConnectPort (HANDLE hServerSideCommPort)
{
  NTSTATUS Status;
  PEPORT ReplyPort;

  . . . . . .
  /* Ask Ob to translate the port handle to EPORT */
  Status = ObReferenceObjectByHandle (hServerSideCommPort, PORT_ALL_ACCESS,
                        LpcPortObjectType, UserMode, (PVOID*)&ReplyPort, NULL);
  . . . . . .
  /* Verify EPORT type is a server-side reply port; otherwise tell the caller
    the port handle is not valid. */
  if (ReplyPort->Type != EPORT_TYPE_SERVER_COMM_PORT)
    {
       ObDereferenceObject (ReplyPort);
       return STATUS_INVALID_PORT_HANDLE;
    }

  ReplyPort->State = EPORT_CONNECTED_SERVER;
  /* Wake up the client thread that issued NtConnectPort. */
  KeReleaseSemaphore(&ReplyPort->OtherPort->Semaphore,
                         IO_NO_INCREMENT, 1, FALSE);
  /* Tell Ob we are no more interested in ReplyPort */  
  ObDereferenceObject (ReplyPort);
  return (STATUS_SUCCESS);
}[/code]

    前面,在NtAcceptConnectPort()的代碼中,雖然已經將應答報文掛入了客戶方端口的接收隊列,卻并未喚醒客戶方線程。現在就通過對其信號量的V操作將其喚醒。
    這樣,就建立起了客戶方與服務方的一對通信端口的連接。以后就可以通過這個連接通信了。一般總是服務方線程先通過NtReplyWaitReceivePort()或NtReplyWaitReceivePortEx()等待對方發來報文,由于Port機制實際上只用于LPC,客戶方發往服務方的一般都是服務請求報文,而服務方則根據具體的請求提供服務,然后發回應答報文、一般是返回結果。不過,也并沒有規定必須是服務方等待客戶方的報文,反過來也并無不可。
    不管是那一方,需要向對方發送一個報文時可以通過系統調用NtRequestPort()發送。

[code]NTSTATUS STDCALL
NtRequestPort (IN HANDLE PortHandle, IN PLPC_MESSAGE LpcMessage)
{
   . . . . . .
  
   Status = ObReferenceObjectByHandle(PortHandle, PORT_ALL_ACCESS,
                    LpcPortObjectType, UserMode, (PVOID*)&Port, NULL);
   . . . . . .
   Status = LpcRequestPort(Port->OtherPort, LpcMessage);
   ObDereferenceObject(Port);
   return(Status);
}[/code]

    顯然,具體的操作是由LpcRequestPort()完成的。區別在于LpcRequestPort()要求使用指向EPORT數據結構的指針,而傳給NtRequestPort()的是Handle,需要加以轉換。Handle本質上是數組下標,所以從Handle到結構指針的轉換開銷并不大。

[code][NtRequestPort() > LpcRequestPort()]

NTSTATUS STDCALL LpcRequestPort (IN PEPORT  Port,
                                   IN PLPC_MESSAGE  LpcMessage)
{
   NTSTATUS Status;
  
   DPRINT("LpcRequestPort(PortHandle %08x, LpcMessage %08x)\n", Port, LpcMessage);

#ifdef __USE_NT_LPC__
   /* Check the message's type */
   if (LPC_NEW_MESSAGE == LpcMessage->MessageType)
   {
      LpcMessage->MessageType = LPC_DATAGRAM;
   }
   else if (LPC_DATAGRAM == LpcMessage->MessageType)
   {
      return STATUS_INVALID_PARAMETER;
   }
   else if (LpcMessage->MessageType > LPC_CLIENT_DIED)
   {
      return STATUS_INVALID_PARAMETER;
   }
   /* Check the range offset */
   if (0 != LpcMessage->VirtualRangesOffset)
   {
      return STATUS_INVALID_PARAMETER;
   }
#endif

   Status = EiReplyOrRequestPort(Port, LpcMessage, LPC_DATAGRAM, Port);
   KeReleaseSemaphore(&Port->Semaphore, IO_NO_INCREMENT, 1, FALSE );
   return(Status);
}[/code]

    可見,NtRequestPort()只是發送,而并不等待對方的回應。如果需要等待回應的話可以采用另一個系統調用NtRequestWaitReplyPort()。
    需要向對方發送應答報文時可以用NtReplyPort()。

[code]NTSTATUS STDCALL
NtReplyPort (IN HANDLE PortHandle, IN PLPC_MESSAGE LpcReply)
{
   NTSTATUS Status;
   PEPORT Port;
  
   DPRINT("NtReplyPort(PortHandle %x, LpcReply %x)\n", PortHandle, LpcReply);
  
   Status = ObReferenceObjectByHandle(PortHandle, PORT_ALL_ACCESS,
                        LpcPortObjectType, UserMode, (PVOID*)&Port, NULL);
   . . . . . .
   Status = EiReplyOrRequestPort(Port->OtherPort, LpcReply, LPC_REPLY, Port);
   KeReleaseSemaphore(&Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
  
   ObDereferenceObject(Port);
  
   return(Status);
}[/code]

    當然,這是純粹的發送應答報文,如果是發送應答報文并且等待下一個請求,那就要用NtReplyWaitReceivePort(),這讀者已經在前面看到了。

    可見,Port是一種功能相當強、相當齊全、結構又相當完整的綜合性的進程間通信機制,這樣的機制理應提供給應用軟件的開發者,或者在Win32 API上提供相應的庫函數,或是把有關的系統調用公諸于世。但是微軟卻并不這么干,倒是一方面諱莫如深,一方面供自己的軟件內部使用。這樣,如果都來開發應用軟件,那別的公司如何能與微軟公平競爭呢?正因為如此,美國一直有人在呼吁甚至提起訴訟,要把操作系統和應用軟件的開發分拆開來,不能讓同一家公司既做操作系統又做應用軟件。另一方面,這也可以解釋為什么總是有這許多人熱衷于探究Windows和相關產品的“Undocumented…”、“…Internals”、“Inside…”。

    最后還要提一下,有些資料中還提到Windows有一種“快捷LPC(QuickLPC)”機制。這就是建立在上一篇漫談中講到的“事件對”基礎上的LPC。早期Windows上的csrss通信太頻繁了,需要有一種非常輕快的進程間通信手段,所以才有了QuickLPC。現在,一方面是csrss的功能大都移到了內核中,一方面是處理器的速度也有了量級的提高,QuickLPC就變得不那么重要了。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲欧美一区二区在线观看| 一区二区三区四区不卡在线| 91美女蜜桃在线| 日韩主播视频在线| 亚洲欧美在线视频观看| 日韩欧美的一区| 欧美视频一区在线观看| 成人一区二区三区| 精品一区二区三区免费播放| 午夜精品视频一区| 亚洲另类在线视频| 中文字幕亚洲不卡| 欧美精品一区二区三区一线天视频| 欧美无砖专区一中文字| www.色精品| 丁香啪啪综合成人亚洲小说| 久热成人在线视频| 日韩激情一二三区| 亚洲综合激情另类小说区| 中文字幕日韩av资源站| 国产日韩一级二级三级| 欧美变态tickling挠脚心| 欧美日韩一级二级| 在线观看一区二区精品视频| 91在线云播放| 不卡视频一二三四| thepron国产精品| av亚洲精华国产精华精华| 国产精品一区久久久久| 精品一区二区三区蜜桃| 偷窥少妇高潮呻吟av久久免费| 一区二区三区日韩精品| 亚洲精品自拍动漫在线| 亚洲欧美成人一区二区三区| 国产日产欧美一区二区视频| 久久久亚洲精品石原莉奈 | 在线观看国产一区二区| 成人动漫一区二区在线| 风间由美一区二区三区在线观看 | 久久精品男人天堂av| 日韩久久久久久| 日韩一级免费观看| 精品欧美一区二区在线观看| 欧美电影免费提供在线观看| 日韩一区二区三区免费观看| 日韩视频一区二区| 精品成人私密视频| 国产亚洲综合性久久久影院| 中文字幕免费一区| 综合欧美一区二区三区| 亚洲美女少妇撒尿| 亚洲一线二线三线久久久| 亚洲一区日韩精品中文字幕| 亚洲国产精品欧美一二99| 亚洲va欧美va人人爽午夜| 日韩精品一二区| 九九**精品视频免费播放| 国产乱人伦偷精品视频不卡 | 国产福利电影一区二区三区| 国产成人在线观看| 不卡的av中国片| 欧美日韩高清在线| 欧美精品一区二区三区一线天视频 | 懂色av中文一区二区三区| 不卡视频在线观看| 欧美色区777第一页| 欧美一级精品在线| 国产视频一区二区在线| 国产精品国产三级国产普通话三级 | 一区二区在线免费观看| 日av在线不卡| 处破女av一区二区| 91福利在线免费观看| 欧美一级片在线| 久久色在线视频| 樱花草国产18久久久久| 久久成人18免费观看| 成人av综合一区| 欧美一区二区三区色| 久久欧美中文字幕| 一区二区在线观看免费视频播放| 蜜桃精品视频在线| 99久久久免费精品国产一区二区| 欧美疯狂性受xxxxx喷水图片| 国产欧美一区二区三区在线看蜜臀 | 亚洲国产精品成人久久综合一区| 亚洲美女视频在线| 国内精品久久久久影院一蜜桃| 91一区一区三区| 精品国产一区二区三区久久影院| 亚洲欧美日韩电影| 国产主播一区二区三区| 在线日韩av片| 中文字幕的久久| 免费观看成人av| 欧美视频中文字幕| 中文字幕精品—区二区四季| 日韩精品亚洲一区二区三区免费| 成人精品免费看| 精品久久免费看| 亚洲动漫第一页| 色天天综合色天天久久| 久久精品亚洲精品国产欧美kt∨| 五月综合激情婷婷六月色窝| 91亚洲国产成人精品一区二三 | 中文字幕第一区第二区| 美女在线一区二区| 欧美日韩综合一区| 亚洲人亚洲人成电影网站色| 久国产精品韩国三级视频| 在线免费亚洲电影| 亚洲欧美在线观看| 成人福利视频网站| 精品国产乱码久久久久久牛牛| 亚洲国产精品久久一线不卡| 97se亚洲国产综合自在线观| 国产欧美视频在线观看| 国产一区在线观看视频| 欧美成人激情免费网| 美女在线视频一区| 欧美一区二区三区婷婷月色| 亚洲无人区一区| 欧美天天综合网| 亚洲综合色在线| 在线精品观看国产| 亚洲一区二区三区四区中文字幕| 99久久免费视频.com| 国产精品久久久久久久久图文区| 国产一级精品在线| 国产亚洲精品资源在线26u| 久久99国产精品麻豆| 欧美sm美女调教| 国产精品一区二区在线观看网站| 日韩精品一区二区在线| 加勒比av一区二区| 精品久久久久久久一区二区蜜臀| 久久精品噜噜噜成人88aⅴ| 欧美一卡二卡在线| 激情综合网天天干| 欧美精品一区二区三区蜜桃| 国产在线精品一区二区夜色| 精品国产一区二区精华| 国产在线播放一区二区三区| 精品日韩欧美在线| 免费久久精品视频| 欧美日韩国产另类一区| 性做久久久久久免费观看| 欧美福利视频一区| 久久99国产精品久久99| 久久精品夜色噜噜亚洲aⅴ| 成人sese在线| 亚洲视频香蕉人妖| 欧美日韩大陆一区二区| 秋霞午夜av一区二区三区| 欧美videos中文字幕| 国产高清成人在线| 亚洲欧美日韩国产成人精品影院 | 亚洲人成精品久久久久| 欧洲一区二区av| 日产国产欧美视频一区精品| 欧美mv和日韩mv国产网站| 成人精品一区二区三区四区 | 日韩一卡二卡三卡四卡| 国产乱子伦一区二区三区国色天香| 亚洲国产高清在线| 欧美性受xxxx| 国产一二三精品| 亚洲欧美日韩一区二区三区在线观看 | 亚洲成人激情社区| 欧美精品一区二区三区视频| jlzzjlzz亚洲日本少妇| 亚洲成人激情社区| 久久精品一区二区三区av| 在线观看不卡视频| 狠狠色狠狠色综合日日91app| 亚洲天堂精品在线观看| 欧美电影在线免费观看| 成人午夜电影网站| 日日摸夜夜添夜夜添精品视频| 久久九九久精品国产免费直播| 91麻豆国产自产在线观看| 日本美女一区二区| 亚洲人成7777| 久久久五月婷婷| 欧美性猛交xxxxxxxx| 国产成人亚洲综合a∨婷婷| 亚洲小少妇裸体bbw| 国产欧美一区二区三区沐欲| 欧美美女喷水视频| 菠萝蜜视频在线观看一区| 日本不卡一二三区黄网| 成人欧美一区二区三区白人 | 捆绑调教一区二区三区| 一区二区在线免费观看| 久久婷婷国产综合精品青草| 欧洲精品一区二区三区在线观看| 国产老妇另类xxxxx| 天天综合网天天综合色| 亚洲欧美aⅴ...| 国产视频亚洲色图|