улетевший

Профиль
Группа: Участник
Сообщений: 55
Регистрация: 16.11.2009
Репутация: нет Всего: нет
|
Нужно создать LSP модуль. Полазив по японско-китайским сайтам и http://www.microsoft.com/msj/0599/LayeredS...redService.aspx ... пишут что бы установить Layer (провайдер имеющий ChainLen = 0) нужно создать также Chain с ссылкой на наш Layer и дальше на базовый протокол, а сам Chain разместить поверх базового протокола. Вот накатал инсталялку, создает в каталоге обе записи о Layer'е и Chain'е. Chain для задуманной функциональности необходимо поставить поверх ТСП/ИП программой SpOrder.Exe. Вот сам код | Код | procedure TForm1.Button1Click(Sender: TObject); const Layer = '==LAYER=='; Chain = '==CHAIN=='; var EnumProto, LayerBuf, ChainBuf : LPWSAPROTOCOL_INFOW; WSAData: TWSADATA; LayerID, BaseID, Count, Error, i : Integer; len, oldprotect: dword; s : string; begin WSAStartup($202, WSAData); Len := $ffff; GetMem(EnumProto, Len); Count := WSCEnumProtocols(nil, EnumProto, Len, Error); for i:=0 to Count-1 do begin // Ищем MSAFD Tcpip [TCP/IP] (или любой другой протокол) if String(EnumProto.szProtocol) = 'MSAFD Tcpip [TCP/IP]' then begin LayerBuf := VirtualAlloc(0, SizeOf(TWSAPROTOCOL_INFOW), MEM_COMMIT, PAGE_READWRITE); // Копируем TWSAPROTOCOL_INFOW MSAFD Tcpip [TCP/IP], чтоб меньше движений делать Move(EnumProto, LayerBuf, SizeOf(TWSAPROTOCOL_INFOW)); Break; end; EnumProto := Pointer(dword(EnumProto)+SizeOf(TWSAPROTOCOL_INFOW)); end; LayerBuf.dwProviderFlags := PFL_HIDDEN ; // флаг для Layer LayerBuf.ProviderId := LayerGUID; LayerBuf.ProtocolChain.ChainLen := 0; // Указывает что это LSP FillChar(LayerBuf.szProtocol, 256, 0); Move(WideString(Layer),LayerBuf.szProtocol, length(Layer)*2); if WSCInstallProvider(LayerGUID, PWideChar(WideString('C:\Temp\LSP.dll')), LayerBuf, 1, Error) = 0 then MessageBox(0, PChar('Layer installed'),PChar('Install'), MB_ICONINFORMATION) else begin case Error of WSAEFAULT: s := 'WSAEFAULT: One or more of the arguments is not in a valid part of the user address space.'; WSAEINVAL: s := 'WSAEINVAL: One or more of the arguments are invalid.'; WSAENOBUFS: s := 'WSAENOBUFS: Memory cannot be allocated for buffers.'; WSANO_RECOVERY: s := 'WSANO_RECOVERY: The provider is already installed.'; WSASYSCALLFAILURE: s := 'WSASYSCALLFAILURE: A system call that should never fail has failed.'; WSA_NOT_ENOUGH_MEMORY: s := 'WSA_NOT_ENOUGH_MEMORY: Insufficient memory was available.'; end; MessageBox(0, PChar(s), PChar('Install'), MB_ICONERROR); end; GetMem(EnumProto, Len); Count := WSCEnumProtocols(nil, EnumProto, Len, Error); for i:=0 to Count-1 do begin // Ищем MSAFD Tcpip [TCP/IP] if String(EnumProto.szProtocol) = 'MSAFD Tcpip [TCP/IP]' then begin BaseID := EnumProto.dwCatalogEntryId; // Запоминаем его EntryId, он нужен для цепочки ChainBuf := VirtualAlloc(0, SizeOf(TWSAPROTOCOL_INFOW), MEM_COMMIT, PAGE_READWRITE); // Копируем прокол инфо чтоб меньше движений делать Move(EnumProto, ChainBuf, SizeOf(TWSAPROTOCOL_INFOW)); Break; end; EnumProto := Pointer(dword(EnumProto)+SizeOf(TWSAPROTOCOL_INFOW)); end; GetMem(EnumProto, Len); Count := WSCEnumProtocols(nil, EnumProto, Len, Error); // Нужно найти EntryId нашего Layer'a чтоб вставить в цепочку for i:=0 to Count-1 do begin if String(EnumProto.szProtocol) = Layer then begin LayerID := EnumProto.dwCatalogEntryId; Break; end; EnumProto := Pointer(dword(EnumProto)+SizeOf(TWSAPROTOCOL_INFOW)); end; // делаем цепочку ChainBuf.ProtocolChain.ChainLen := 2; ChainBuf.ProtocolChain.ChainEntries[0] := LayerID; ChainBuf.ProtocolChain.ChainEntries[1] := BaseID; CHainBuf.ProviderId := ChainGUID; FillChar(ChainBuf.szProtocol, 256, 0); Move(WideString(Chain),ChainBuf.szProtocol, length(Chain)*2); if WSCInstallProvider(ChainGUID, PWideChar(WideString('C:\Temp\LSP.dll')), ChainBuf, 1, Error) = 0 then MessageBox(0, PChar('Layer installed'),PChar('Install'), MB_ICONINFORMATION) else begin case Error of WSAEFAULT: s := 'WSAEFAULT: One or more of the arguments is not in a valid part of the user address space.'; WSAEINVAL: s := 'WSAEINVAL: One or more of the arguments are invalid.'; WSAENOBUFS: s := 'WSAENOBUFS: Memory cannot be allocated for buffers.'; WSANO_RECOVERY: s := 'WSANO_RECOVERY: The provider is already installed.'; WSASYSCALLFAILURE: s := 'WSASYSCALLFAILURE: A system call that should never fail has failed.'; WSA_NOT_ENOUGH_MEMORY: s := 'WSA_NOT_ENOUGH_MEMORY: Insufficient memory was available.'; end; MessageBox(0, PChar(s), PChar('Install'), MB_ICONERROR); end; end;
|
Сам lsp модуль | Код | library LSP;
uses Windows, SysUtils, Classes, WinSock2, WS2spi, SyncObjs, Messages, LSPStructures in 'LSPStructures.pas', Overlapped in 'Overlapped.pas';
const Layer = '==LAYER=='; {$R *.res}
var NextProcTable: LPWSPPROC_TABLE; glCS:TCriticalSection; cOverlapped: TOverlapped;
function WSPRecv(s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesRecvd, lpFlags: DWORD; lpOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE; lpThreadId: LPWSATHREADID; var lpErrno: Integer): Integer; stdcall; begin result := NextProcTable.lpWSPRecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd, lpFlags,lpOverlapped,lpCompletionRoutine,lpThreadId, lpErrno); end;
function WSPStartup(wVersionRequested: WORD; lpWSPData: LPWSPDATA; lpProtocolInfo: LPWSAPROTOCOL_INFOW; UpcallTable: WSPUPCALLTABLE; lpProcTable: LPWSPPROC_TABLE): Integer; stdcall; var Count, Error, i, iLen: integer; EnumBuf: LPWSAPROTOCOL_INFOW; Len, LayerID, NextLayerID, hDLL: dword; wDllPath, DllPath: PWideChar; WSPStartupFunc: LPWSPSTARTUP; begin Len := $ffff; GetMem(EnumBuf, Len); Count := WSCEnumProtocols(nil, EnumBuf, Len, Error); // Ищем свой номерок в каталоге for i:=0 to count-1 do begin if string(EnumBuf.szProtocol) = Layer then begin LayerID := EnumBuf.dwCatalogEntryId; break; end; EnumBuf := Pointer(Dword(EnumBuf)+SizeOf(TWSAPROTOCOL_INFOW)); end; // Ищем следующего провайдера относительно нас for i:=0 to lpProtocolInfo.ProtocolChain.ChainLen-1 do begin if lpProtocolInfo.ProtocolChain.ChainEntries[i] = LayerID then begin NextLayerID := lpProtocolInfo.ProtocolChain.ChainEntries[i+1]; break; end; end; GetMem(EnumBuf, Len); Count := WSCEnumProtocols(nil, EnumBuf, Len, Error); for i:=0 to count-1 do begin if EnumBuf.dwCatalogEntryId = NextLayerID then begin iLen := 256; GetMem(DllPath, iLen); WSCGetProviderPath(EnumBuf.ProviderId, DllPath, iLen, Error); GetMem(wDllPath, iLen); ExpandEnvironmentStringsW(DllPath, wDllPath, iLen); Break; end; EnumBuf := Pointer(Dword(EnumBuf)+SizeOf(TWSAPROTOCOL_INFOW)); end; hDLL := LoadLibraryW(wDllPath); WSPStartupFunc := LPWSPSTARTUP(GetProcAddress(hDLL,Pchar('WSPStartup'))); result := WSPStartupFunc(wVersionRequested, lpWSPData, lpProtocolInfo, UpcallTable, lpProcTable); NextProcTable := lpProcTable; lpProcTable.lpWSPRecv := WSPRecv; end;
procedure DllMain(dwReason : DWORD); begin case dwReason of DLL_PROCESS_ATTACH : begin cOverlapped := TOverlapped.create; glCS := TCriticalSection.Create; end; DLL_PROCESS_DETACH : begin end; DLL_THREAD_ATTACH : begin end; DLL_THREAD_DETACH : begin end; end; end;
exports WSPStartup;
begin DLLProc := @DLLMain; DLLMain(DLL_PROCESS_ATTACH); end.
|
Такой код отрубает винсок )) для восстановления нужно в командной строке написать netsh winsock reset, либо удалить провайдер функцией WSCDeinstallProvider, либюо использовать утилиту LSPFix.exe или другую, коих множество, на край можно самому написать. Так вот проблема я думаю в длл, нужно ее как-то по другому сделать, и вообще принцип построения LSD-DLL непонятен. Нужно передать параметры кому откуда, непонятно, запарка в WSPStartUp. Кажется разобрался, при вызове функции socket, винсок по заданным параметрам ищет удовлетворяющего запрос, этот провайдер смотрит нет ли в его цепочки lsp, и если есть вызывает Wspstartup следущего провайдера и т.д. "Пустая" Dll-lsp работает нормально, т.е установленая поверх базового провайдера, вызывается и передает управление следующему, если я указываю ссылку на мою функцию например WSPRecv, для этого нужно задать адрес нашей функции в lpProcTable, происходит перехват, вызов моей функции, но при этом связь с инетом прерывается, помогите найти ошибку. Это сообщение отредактировал(а) ButtonOFF - 22.11.2009, 14:16
|