Новичок
Профиль
Группа: Участник
Сообщений: 34
Регистрация: 28.4.2008
Репутация: 1 Всего: 1
|
Here is my attempt : **************** Код | program Project1;
{$APPTYPE CONSOLE}
uses windows, SysUtils, NtDefs in 'NtDefs.pas', rspFltUser in 'FltUser.pas', scanuk_h in 'scanuk_h.pas';
const SCANNER_DEFAULT_REQUEST_COUNT = 5; SCANNER_DEFAULT_THREAD_COUNT = 2; SCANNER_MAX_THREAD_COUNT = 64; FoulString:String = 'foul'; type _SCANNER_THREAD_CONTEXT = record Port: THandle; Completion: THandle; end; SCANNER_THREAD_CONTEXT = _SCANNER_THREAD_CONTEXT; PSCANNER_THREAD_CONTEXT = ^_SCANNER_THREAD_CONTEXT; // type _SCANNER_MESSAGE = packed record MessageHeader: FILTER_MESSAGE_HEADER; (**) (* Required structure header.*) (**)
(**) (* Private scanner-specific fields begin here.*) (**) Notification: SCANNER_NOTIFICATION; (**) (* Overlapped structure: this is not really part of the message*) (* However we embed it instead of using a separately allocated overlap structure*) (**) // FOverlapped: TOverlapped; FPOverlapped: POverlapped;
//
end; SCANNER_MESSAGE = _SCANNER_MESSAGE; PSCANNER_MESSAGE = ^_SCANNER_MESSAGE;
_SCANNER_REPLY_MESSAGE = packed record ReplyHeader: FILTER_REPLY_HEADER; (**) (* Required structure header.*) (**)
(**) (* Private scanner-specific fields begin here.*) (**) Reply: SCANNER_REPLY; end; SCANNER_REPLY_MESSAGE = _SCANNER_REPLY_MESSAGE; PSCANNER_REPLY_MESSAGE = ^_SCANNER_REPLY_MESSAGE; //
procedure Usage(); begin WriteLn('Connects to the scanner filter and scans buffers '#13#10'');
WriteLN('Usage: scanuser [requests per thread] [number of threads(1-64)]'#13#10''); end;
function ScanBuffer( Buffer:PUCHAR;BufferSize:Cardinal): BOOL; var p: PUCHAR; searchStringLength: ULONG; begin searchStringLength:=sizeof(FoulString)-sizeof(UCHAR); // for{while} P:=Buffer to (Buffer+BufferSize-searchStringLength) { // p++} //do begin
// if RtlEqualMemory(p,FoulString,searchStringLength) //then begin WriteLN('Found a string'#13#10''); (**) (* Once we find our search string, we're not interested in seeing*) (* whether it appears again.*) (**) begin result:= LongBool(1); exit; end; end; end; begin result:= LongBool(0); exit; end; end;
var FOverlapped: TOverlapped; FPOverlapped: POverlapped; Ovlp: OVERLAPPED; function ScannerWorker(Context:PSCANNER_THREAD_CONTEXT): DWORD; var notification: PSCANNER_NOTIFICATION; replyMessage: SCANNER_REPLY_MESSAGE; message: PSCANNER_MESSAGE; pOvlp:LPOVERLAPPED; cResult: BOOL; outSize: DWORD; hr: HRESULT; key: DWORD;
begin while LongBool(1) do begin
(**) (* Poll for messages from the filter component to scan.*) (**) cResult:= GetQueuedCompletionStatus(Context^.Completion,outSize,key,FPOverlapped,INFINITE); // message:= CONTAINING_RECORD(pOvlp,SCANNER_MESSAGE,Ovlp); (**) (* Obtain the message: note that the message we sent down via FltGetMessage() may NOT be*) (* the one dequeued off the completion queue: this is solely because there are multiple*) (* threads per single port handle. Any of the FilterGetMessage() issued messages can be*) (* completed in random order - and we will just dequeue a random one.*) (**) if ( not cResult) then begin (**) (* An error occured.*) (**) hr:=(GetLastError()); break; {<= !!!b possible in "switch" - then remove this line} end; writeLn('Received message, size %d'#13#10'',pOvlp.InternalHigh);
notification:= @message.Notification; assert(notification.BytesToScan<=SCANNER_READ_BUFFER_SIZE);
// __analysis_assume(notification.BytesToScan<=SCANNER_READ_BUFFER_SIZE); cResult:= ScanBuffer(@notification^.Contents, notification^.BytesToScan); replyMessage.ReplyHeader.Status:= 0; replyMessage.ReplyHeader.MessageId:= message.MessageHeader.MessageId; replyMessage.Reply.SafeToOpen:=not cResult; WriteLN('Replying message, SafeToOpen: %d'#13#10'',replyMessage.Reply.SafeToOpen);
(**) (* Need to invert the boolean -- result is true if found*) (* foul language, in which case SafeToOpen should be set to false.*) (**) hr:= FilterReplyMessage(Context.Port,@replyMessage,sizeof(replyMessage));
if SUCCEEDED(hr) then begin
WriteLN('Replied message'#13#10''); end else begin
WriteLN('Scanner: Error replying message. Error = 0x%X'#13#10'',hr); break; {<= !!!b possible in "switch" - then remove this line} end; ZeroMemory(@message.FPOverlapped,sizeof(OVERLAPPED));
hr:= FilterGetMessage(Context.Port,@message.MessageHeader,{(Ovlp)}600,@message.FPOverlapped);
if hr<>(ERROR_IO_PENDING) then begin break; {<= !!!b possible in "switch" - then remove this line} end; end; if ( not SUCCEEDED( hr )) then begin if hr=(ERROR_INVALID_HANDLE) then begin (**) (* Scanner port disconncted.*) (**) WriteLN('Scanner: Port is disconnected, probably due to scanner filter unloading.'#13#10''); end else begin WriteLN('Scanner: Unknown error occured. Error = 0x%X'#13#10'',hr); end; end; //free(message); begin result:= hr; exit; end; end; /// procedure main({argc: integer;argv:Integer } {!!!3 unknown typedef}); var requestCount: DWORD; threadCount: DWORD; threads: array [0..Pred(SCANNER_MAX_THREAD_COUNT)] of THandle; context: SCANNER_THREAD_CONTEXT; port: THandle; completion: THandle; msg: PSCANNER_MESSAGE; threadId: DWORD; retVal: DWORD; hr: HRESULT; i: DWORD; j: DWORD; (**) (* Check how many threads and per thread requests are desired.*) (**) label main_cleanup; begin requestCount:=SCANNER_DEFAULT_REQUEST_COUNT; threadCount:=SCANNER_DEFAULT_THREAD_COUNT; retVal:=0;
if paramCount>1 then // if argc>1 // then begin requestCount:=StrToInt(ParamStr(1)); if paramCount>1 // if argc>2 then begin threadCount:=StrToInt(ParamStr(2)); end; if ((requestCount <= 0) or (threadCount <= 0 )or( threadCount > 64)) then begin Usage(); begin // result:= 1; exit; end; end; end; WriteLN('Scanner: Connecting to the filter ...'#13#10''); (**) (* Open a commuication channel to the filter*) (**) hr:= FilterConnectCommunicationPort(ScannerPortName,0,0{nil},0,0{nil},@port); if (hr<>S_Ok) then begin WriteLN('ERROR: Connecting to filter port: %d',hr); begin // result:= 2; exit; end; end; completion:= CreateIoCompletionPort(port,0{nil},0,threadCount); (**) (* Create a completion port to associate with this handle.*) (**) if completion=0{nil} then begin WriteLN('ERROR: Creating completion port: %d',GetLastError()); CloseHandle(port); begin // result:= 3; exit; end; end; WriteLN('Scanner: Port = 0x%p Completion = 0x%p',port,completion); context.Port:= port; context.Completion:= completion; (**) (* Create specified number of threads.*) (**) for{while} i:=0 to Pred(threadCount) { i++} do begin threads[i]:= CreateThread(nil,0,@ScannerWorker,POinter(context.port),0,threadId);
if threads[i]=0{nil} then begin
(**) (* Couldn't create thread.*) (**) hr:= GetLastError(); WriteLN('ERROR: Couldn'#39't create thread: %d',hr); goto main_cleanup; end; for{while} j:=0 to Pred(requestCount) { j++} do begin (**) (* Allocate the message.*) (**) msg:= AllocMem(sizeof(SCANNER_MESSAGE)); if msg=nil then begin hr:= ERROR_NOT_ENOUGH_MEMORY; goto main_cleanup; end; ZeroMemory(@msg.FPOverlapped,sizeof(OVERLAPPED)); //Context.Port,@message.MessageHeader,{(Ovlp)}600,@message.FPOverlapped hr:= FilterGetMessage(port,@msg.MessageHeader,{(Ovlp)}600,@msg.FPOverlapped); (**) (* Request messages from the filter driver.*) (**) if hr<>(ERROR_IO_PENDING) then begin freeMem(msg); goto main_cleanup; end; end; end; hr:= S_OK; WaitForMultipleObjects(i, @threads, TRUE, INFINITE);
main_cleanup: WriteLN('Scanner: All done. Result = 0x%08x'#13#10'',hr); CloseHandle(port); CloseHandle(completion); begin // result:= hr; exit; end; end; /// begin { TODO -oUser -cConsole Main : Insert code here } main(); end.
|
**************** Many thanks
|