代码改变世界

用Delphi写的SPI(LSP)的部分代码

2011-03-20 10:52  邱鹏  阅读(1160)  评论(0编辑  收藏  举报
//------------------------------------------------------------------------------
// Created by Sima huapeng 2001
//  服务提供者的标准入口函数,这里的主要工作是根据lpProtocolInfo找出已经被替换的
//  的服务函数的路径,然后加载,并利用被替换的服务提供者的WSPStartup得到的30多个
//  服务函数指针。需要首先保存这些函数指针,然后将lpProcTable结构中的30个服务函数
//  指针都设置成自己的,这样,相应的函数请求首先经过我们自己的函数,然后用这些函数
//  可以设当得处理,再调用原来的,将请求转发,完成整个通信。
function WSPStartup(wVersionRequested   : WORD;
                    lpWSPData           : LPWSPDATA;
                    lpProtocolInfo      : LPWSAPROTOCOL_INFOW;
                    UpcallTable         : WSPUPCALLTABLE;
                    lpProcTable         : LPWSPPROC_TABLE
                    )                   : Integer; stdcall;
var
  WSPStartupFunc:LPWSPSTARTUP;
  sLibPath:string;
  hLibHandle:hModule;
begin
    try
        // 进入临界区
        glCS.Enter;
        try
            if not GetHookProvider(lpProtocolInfo,slibPath) then
            begin
                Result:=WSAEPROVIDERFAILEDINIT;
                dbError('GetHookProvider Error');
                Exit;
            end;

            hLibHandle:=LoadLibrary(pChar(sLibPath));
            if hLibHandle<>0 then
            begin
                WSPStartupFunc:= LPWSPSTARTUP(GetProcaddress(hLibHandle,pchar('WSPStartup')));
                if assigned(WSPStartupFunc) then
                begin
                    Result:=WSPStartupFunc(wVersionRequested,lpWSPData,lpProtocolInfo,UpcallTable,lpProcTable);
                    if Result<>ERROR_SUCCESS then
                    begin
                        dbError('WSPStartupFunc Error');
                        Exit;
                    end;

                    // Don't filter QOS
                    if (XP1_QOS_SUPPORTED = (lpProtocolInfo.dwServiceFlags1 and XP1_QOS_SUPPORTED)) then
                    begin
                        Result:=0;
                        dbError('XP1_QOS_SUPPORTED Error');
                        Exit;
                    end;

                    // 保存被替换的服务提供者的30个函数指针
                    NextProcTable:=lpProcTable^;

                    // 将我们需要截获的服务函数指针设置成自己的函数
                    lpProcTable.lpWSPSocket         :=WSPSocket;
                    lpProcTable.lpWSPCloseSocket    :=WSPCloseSocket;
                    lpProcTable.lpWSPConnect        :=WSPConnect;
                    lpProcTable.lpWSPAccept         :=WSPAccept;
                    lpProcTable.lpWSPSend           :=WSPSend;
                    lpProcTable.lpWSPSendTo         :=WSPSendTo;
                    lpProcTable.lpWSPRecv           :=WSPRecv;
                    lpProcTable.lpWSPRecvFrom       :=WSPRecvFrom;
                end
                else
                begin
                    Result:=WSAEPROVIDERFAILEDINIT;
                    dbError('GetProcaddress Error');
                end;
            end
            else
            begin
                Result:=WSAEPROVIDERFAILEDINIT;
                dbError('LoadLibrary Error form '+ sLibPath);
            end;
        finally
            // 退出临界区
            glCS.Leave;
        end;
    except
        Result:=-1;
        dbPrint('WSPStartup Error');
    end;
end;

exports
  WSPStartup  Name 'WSPStartup';

begin
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
end.