代碼:
//METHOD_OUT_DIREC方式
NTSTATUS COMM_DirectOutIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID pInputBuffer, pOutputBuffer;
ULONG outputLength, inputLength;
DbgPrint("COMM_DirectOutIo\r\n");
outputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
pOutputBuffer = NULL;
if(Irp->MdlAddress)
pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if(pInputBuffer && pOutputBuffer)
{
DbgPrint("COMM_DirectOutIo UserModeMessage = '%s'", pInputBuffer);
RtlCopyMemory(pOutputBuffer, pInputBuffer, outputLength);
*sizeofWrite = outputLength;
status = STATUS_SUCCESS;
}
return status;
}
// METHOD_IN_DIRECT
NTSTATUS COMM_DirectInIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID pInputBuffer, pOutputBuffer;
ULONG outputLength, inputLength;
DbgPrint("COMM_DirectInIo\r\n");
outputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
pOutputBuffer = NULL;
if(Irp->MdlAddress)
pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if(pInputBuffer && pOutputBuffer)
{
DbgPrint("COMM_DirectInIo UserModeMessage = '%s'", pInputBuffer);
RtlCopyMemory(pOutputBuffer, pInputBuffer, outputLength);
*sizeofWrite = outputLength;
status = STATUS_SUCCESS;
}
return status;
}
// METHOD_BUFFERED
NTSTATUS COMM_BufferedIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID pInputBuffer, pOutputBuffer;
ULONG outputLength, inputLength;
DbgPrint("COMM_BufferedIo\r\n");
outputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
pOutputBuffer = Irp->AssociatedIrp.SystemBuffer;
if(pInputBuffer && pOutputBuffer)
{
DbgPrint("COMM_BufferedIo UserModeMessage = '%s'", pInputBuffer);
RtlCopyMemory(pOutputBuffer, pInputBuffer, outputLength);
*sizeofWrite = outputLength;
status = STATUS_SUCCESS;
}
return status;
}
// METHOD_NEITHER
NTSTATUS COMM_NeitherIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *sizeofWrite)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PVOID pInputBuffer, pOutputBuffer;
ULONG outputLength, inputLength;
DbgPrint("COMM_NeitherIo\r\n");
outputLength = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;
inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
pInputBuffer = pIoStackIrp->Parameters.DeviceIoControl.Type3InputBuffer;
pOutputBuffer = Irp->UserBuffer;
if(pInputBuffer && pOutputBuffer)
{
DbgPrint("COMM_NeitherIo UserModeMessage = '%s'", pInputBuffer);
RtlCopyMemory(pOutputBuffer, pInputBuffer, outputLength);
*sizeofWrite = outputLength;
status = STATUS_SUCCESS;
}
return status;
}
代碼比較簡(jiǎn)單,都是取得輸入的數(shù)據(jù),然后把數(shù)據(jù)直接拷貝到輸出,傳輸給應(yīng)用層。
應(yīng)用層的代碼:
procedure TfrmMain.Send_Recv_Data(AInData: String; var AOutData:String;
IoctlCode: DWORD);
var
dwReturn: DWORD;
inData:array[0..1023] of char;
outData:array[0..1023] of char;
begin
StrPCopy(inData, AInData);
if m_hCommDevice <> 0 then
begin
DeviceIoControl(m_hCommDevice, IoctlCode, @inData, Length(inData), @outData, Length(outData), dwReturn, nil);
AOutData := StrPas(@outData);
end;
end;
上面是進(jìn)行發(fā)送和接受的過(guò)程。
代碼:
procedure TfrmMain. btnDirect_IN_IOClick (Sender: TObject);
var
outData:String;
begin
Send_Recv_Data(Trim(edtDirect_in_in.Text), outData, IOCTL_COMM_DIRECT_IN_IO);
edtDirect_in_out.Text := outData;
end;
這是 direct_in方式通信,其他通信方式類(lèi)似,大家可以參考代碼了,這里就不列舉了,由于代碼比較簡(jiǎn)單,我就不多說(shuō)了,大家還是看代碼吧,很好明白。最后,給個(gè)測(cè)試圖: