我使用以下过程从delphi调用驱动程序
procedure TfrmReceiver.Button2Click(Sender: TObject);
label main_cleanup;
var
hr: HRESULT;
ScannerPortName:pWideChar;
msg: PSCANNER_MESSAGE;
threadId: DWORD;
context: SCANNER_THREAD_CONTEXT;
retVal: DWORD;
i,j: integer;
threads: array [0..Pred(64)] of THandle;
requestCount: DWORD;
begin
requestCount :=5;
ScannerPortName:='\ScannerPort';
hr:=FilterConnectCommunicationPort(ScannerPortName,0, Nil, 0, Nil,@hport);
if hr=s_ok then begin
showmessage('Connected');
completion:= CreateIoCompletionPort(hport,0{nil},0,2);
if completion=0 then begin
showmessage('Port error!');
CloseHandle(hport);
end else begin
showmessage('Ok');
msg:= AllocMem(sizeof(SCANNER_MESSAGE));
if msg=nil then
begin
showmessage('No memory!');
exit;
end;
(**)
(* Create specified number of threads.*)
(**)
context.port := completion;
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
hr:= GetLastError();
ShowMessage('Thread error!');
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
showmessage('No memory!');
goto main_cleanup;
end;
// ZeroMemory(@msg.FPOverlapped,sizeof(OVERLAPPED));
//Context.Port,@message.MessageHeader,{(Ovlp)}600,@message.FPOverlapped
hr:= FilterGetMessage(hport,@Msg^.MessageHeader,DWORD(@PSCANNER_MESSAGE(0)^.FOverlapped),@Msg^.FOverlapped);
if hr = (ERROR_IO_PENDING)
then begin
ShowMessage('Err!');
freeMem(msg);
goto main_cleanup;
end;
end;
end;
hr:= S_OK;
// WaitForMultipleObjects(i, @threads, TRUE, INFINITE);
main_cleanup:
//CloseHandle(hport);
//CloseHandle(completion);
end;
end else
showmessage('Not Connected'); //-->
end;
并在此函数中接收数据,但返回的缓冲区始终为空,我不知道为什么,这是应该返回缓冲区的地方,这是正确的调用来接收重叠缓冲区吗?
cResult:= GetQueuedCompletionStatus(completion,outSize,key,pOvlp,INFINITE);
Msg := PSCANNER_MESSAGE(@PSCANNER_MESSAGE(pOvlp)^.FOverlapped);
全功能
function ScannerWorker(Context:PSCANNER_THREAD_CONTEXT): DWORD;
var
notification: PSCANNER_NOTIFICATION;
replyMessage: pSCANNER_REPLY_MESSAGE;
msg: pSCANNER_MESSAGE;
pOvlp:POverlapped;
cResult: BOOL;
outSize: cardinal;
hr: HRESULT;
key: cardinal;
sText: AnsiString;
begin
while True do begin
(**)
(* Poll for messages from the filter component to scan.*)
(**)
cResult:= GetQueuedCompletionStatus(completion,outSize,key,pOvlp,INFINITE);
Msg := PSCANNER_MESSAGE(@PSCANNER_MESSAGE(pOvlp)^.FOverlapped);
If Not(cResult) Then
begin
// HR := HRESULT_FROM_WIN32(GetLastError());
ShowMessage('Msg Error');
Break;
end;
notification:= @msg.Notification;
// __analysis_assume(notification.BytesToScan<=SCANNER_READ_BUFFER_SIZE);
//cResult:= ScanBuffer(@notification^.Contents, notification^.BytesToScan);
//replyMessage.ReplyHeader.Status:= 0;
replyMessage.ReplyHeader.MessageId:= msg.MessageHeader.MessageId;
replyMessage.Reply.SafeToOpen:=True;
//WriteLN('Replying message, SafeToOpen: %d'#13#10'',replyMessage.Reply.SafeToOpen);
hr:= FilterReplyMessage(hport,@replyMessage,sizeof(replyMessage));
If Not(hr=s_ok) Then
begin
// HR := HRESULT_FROM_WIN32(GetLastError());
ShowMessage('Msg SError');
end;
SetString(sText, notification.Contents, 1024);
frmReceiver.Memo1.Lines.Add('Ok '+sText);
HR := FilterGetMessage(hport,@Msg^.MessageHeader,DWORD(@PSCANNER_MESSAGE(0)^.FOverlapped),@Msg^.FOverlapped);
If HR = (ERROR_IO_PENDING) Then Break;
end;
result:= hr;
end;