📄 tdifuncs.c
字号:
*
* TdiFuncs_Connect
*
* This is called to make a connection with a remote computer
*
**********************************************************************/
NTSTATUS TdiFuncs_Connect(PFILE_OBJECT pfoConnection, UINT uiAddress, USHORT uiPort)
{
NTSTATUS NtStatus = STATUS_INSUFFICIENT_RESOURCES;
PIRP pIrp;
IO_STATUS_BLOCK IoStatusBlock = {0};
PDEVICE_OBJECT pTdiDevice;
TDI_CONNECTION_INFORMATION RequestConnectionInfo = {0};
TDI_CONNECTION_INFORMATION ReturnConnectionInfo = {0};
LARGE_INTEGER TimeOut = {0};
UINT NumberOfSeconds = 60*3;
char cBuffer[256] = {0};
PTRANSPORT_ADDRESS pTransportAddress = (PTRANSPORT_ADDRESS)&cBuffer;
PTDI_ADDRESS_IP pTdiAddressIp;
TDI_COMPLETION_CONTEXT TdiCompletionContext;
KeInitializeEvent(&TdiCompletionContext.kCompleteEvent, NotificationEvent, FALSE);
/*
* The TDI Device Object is required to send these requests to the TDI Driver.
*
*/
pTdiDevice = IoGetRelatedDeviceObject(pfoConnection);
/*
* Step 1: Build the IRP. TDI defines several macros and functions that can quickly
* create IRP's, etc. for variuos purposes. While this can be done manually
* it's easiest to use the macros.
*
* http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
*/
pIrp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, pTdiDevice, pfoConnection, &TdiCompletionContext.kCompleteEvent, &IoStatusBlock);
if(pIrp)
{
/*
* Step 2: Add the correct parameters into the IRP.
*/
/*
* Time out value
*/
TimeOut.QuadPart = 10000000L;
TimeOut.QuadPart *= NumberOfSeconds;
TimeOut.QuadPart = -(TimeOut.QuadPart);
/*
* Initialize the RequestConnectionInfo which specifies the address of the REMOTE computer
*
*/
RequestConnectionInfo.RemoteAddress = (PVOID)pTransportAddress;
RequestConnectionInfo.RemoteAddressLength = sizeof(PTRANSPORT_ADDRESS) + sizeof(TDI_ADDRESS_IP);
/*
* The number of transport addresses
*/
pTransportAddress->TAAddressCount = 1;
/*
* This next piece will essentially describe what the transport being opened is.
*
* AddressType = Type of transport
* AddressLength = Length of the address
* Address = A data structure that is essentially related to the chosen AddressType.
*
*/
pTransportAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
pTransportAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
pTdiAddressIp = (TDI_ADDRESS_IP *)&pTransportAddress->Address[0].Address;
/*
* The TDI_ADDRESS_IP data structure is essentially simmilar to the usermode sockets data structure.
*
* sin_port
* sin_zero
* in_addr
*/
/*
* Remember, these must be in NETWORK BYTE ORDER (Big Endian)
*/
pTdiAddressIp->sin_port = uiPort; /* Example: 1494 = 0x05D6 (Little Endian) or 0xD605 (Big Endian) */
pTdiAddressIp->in_addr = uiAddress; /* Example: 10.60.2.159 = 0A.3C.02.9F (Little Endian) or 9F.02.3C.0A (Big Endian) */
TdiBuildConnect(pIrp, pTdiDevice, pfoConnection, NULL, NULL, &TimeOut, &RequestConnectionInfo, &ReturnConnectionInfo);
NtStatus = IoCallDriver(pTdiDevice, pIrp);
/*
* If the status returned is STATUS_PENDING this means that the IRP will not be completed synchronously
* and the driver has queued the IRP for later processing. This is fine but we do not want to return this
* thread, we are a synchronous call so we want to wait until it has completed. The EVENT that we provided
* will be set when the IRP completes.
*/
if(NtStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&TdiCompletionContext.kCompleteEvent, Executive, KernelMode, FALSE, NULL);
/*
* Find the Status of the completed IRP
*/
NtStatus = IoStatusBlock.Status;
}
}
return NtStatus;
}
/**********************************************************************
*
* TdiFuncs_Send
*
* This API demonstrates how to send data
*
**********************************************************************/
NTSTATUS TdiFuncs_Send(PFILE_OBJECT pfoConnection, PVOID pData, UINT uiSendLength, UINT *pDataSent)
{
NTSTATUS NtStatus = STATUS_INSUFFICIENT_RESOURCES;
PIRP pIrp;
IO_STATUS_BLOCK IoStatusBlock = {0};
PDEVICE_OBJECT pTdiDevice;
PMDL pSendMdl;
TDI_COMPLETION_CONTEXT TdiCompletionContext;
KeInitializeEvent(&TdiCompletionContext.kCompleteEvent, NotificationEvent, FALSE);
/*
* The TDI Device Object is required to send these requests to the TDI Driver.
*
*/
pTdiDevice = IoGetRelatedDeviceObject(pfoConnection);
*pDataSent = 0;
/*
* The send requires an MDL which is what you may remember from DIRECT_IO. However,
* instead of using an MDL we need to create one.
*/
pSendMdl = IoAllocateMdl((PCHAR )pData, uiSendLength, FALSE, FALSE, NULL);
if(pSendMdl)
{
__try {
MmProbeAndLockPages(pSendMdl, KernelMode, IoModifyAccess);
} __except (EXCEPTION_EXECUTE_HANDLER) {
IoFreeMdl(pSendMdl);
pSendMdl = NULL;
};
if(pSendMdl)
{
/*
* Step 1: Build the IRP. TDI defines several macros and functions that can quickly
* create IRP's, etc. for variuos purposes. While this can be done manually
* it's easiest to use the macros.
*
* http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
*/
pIrp = TdiBuildInternalDeviceControlIrp(TDI_SEND, pTdiDevice, pfoConnection, &TdiCompletionContext.kCompleteEvent, &IoStatusBlock);
if(pIrp)
{
/*
* Step 2: Add the correct parameters into the IRP.
*/
TdiBuildSend(pIrp, pTdiDevice, pfoConnection, NULL, NULL, pSendMdl, 0, uiSendLength);
NtStatus = IoCallDriver(pTdiDevice, pIrp);
/*
* If the status returned is STATUS_PENDING this means that the IRP will not be completed synchronously
* and the driver has queued the IRP for later processing. This is fine but we do not want to return this
* thread, we are a synchronous call so we want to wait until it has completed. The EVENT that we provided
* will be set when the IRP completes.
*/
if(NtStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&TdiCompletionContext.kCompleteEvent, Executive, KernelMode, FALSE, NULL);
}
NtStatus = IoStatusBlock.Status;
*pDataSent = (UINT)IoStatusBlock.Information;
/*
* I/O Manager will free the MDL
*
if(pSendMdl)
{
MmUnlockPages(pSendMdl);
IoFreeMdl(pSendMdl);
} */
}
}
}
return NtStatus;
}
/**********************************************************************
*
* TdiFuncs_Disconnect
*
* This is called to disconnect from the remote computer
*
**********************************************************************/
NTSTATUS TdiFuncs_Disconnect(PFILE_OBJECT pfoConnection)
{
NTSTATUS NtStatus = STATUS_INSUFFICIENT_RESOURCES;
PIRP pIrp;
IO_STATUS_BLOCK IoStatusBlock = {0};
PDEVICE_OBJECT pTdiDevice;
TDI_CONNECTION_INFORMATION ReturnConnectionInfo = {0};
LARGE_INTEGER TimeOut = {0};
UINT NumberOfSeconds = 60*3;
TDI_COMPLETION_CONTEXT TdiCompletionContext;
KeInitializeEvent(&TdiCompletionContext.kCompleteEvent, NotificationEvent, FALSE);
/*
* The TDI Device Object is required to send these requests to the TDI Driver.
*
*/
pTdiDevice = IoGetRelatedDeviceObject(pfoConnection);
/*
* Step 1: Build the IRP. TDI defines several macros and functions that can quickly
* create IRP's, etc. for variuos purposes. While this can be done manually
* it's easiest to use the macros.
*
* http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
*/
pIrp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, pTdiDevice, pfoConnection, &TdiCompletionContext.kCompleteEvent, &IoStatusBlock);
if(pIrp)
{
/*
* Step 2: Add the correct parameters into the IRP.
*/
/*
* Time out value
*/
TimeOut.QuadPart = 10000000L;
TimeOut.QuadPart *= NumberOfSeconds;
TimeOut.QuadPart = -(TimeOut.QuadPart);
TdiBuildDisconnect(pIrp, pTdiDevice, pfoConnection, NULL, NULL, &TimeOut, TDI_DISCONNECT_ABORT, NULL, &ReturnConnectionInfo);
NtStatus = IoCallDriver(pTdiDevice, pIrp);
/*
* If the status returned is STATUS_PENDING this means that the IRP will not be completed synchronously
* and the driver has queued the IRP for later processing. This is fine but we do not want to return this
* thread, we are a synchronous call so we want to wait until it has completed. The EVENT that we provided
* will be set when the IRP completes.
*/
if(NtStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&TdiCompletionContext.kCompleteEvent, Executive, KernelMode, FALSE, NULL);
/*
* Find the Status of the completed IRP
*/
NtStatus = IoStatusBlock.Status;
}
}
return NtStatus;
}
/**********************************************************************
*
* TdiFuncs_DisAssociateTransportAndConnection
*
* This is called to disassociate the transport with the connection
*
**********************************************************************/
NTSTATUS TdiFuncs_DisAssociateTransportAndConnection(PFILE_OBJECT pfoConnection)
{
NTSTATUS NtStatus = STATUS_INSUFFICIENT_RESOURCES;
PIRP pIrp;
IO_STATUS_BLOCK IoStatusBlock = {0};
PDEVICE_OBJECT pTdiDevice;
TDI_COMPLETION_CONTEXT TdiCompletionContext;
KeInitializeEvent(&TdiCompletionContext.kCompleteEvent, NotificationEvent, FALSE);
/*
* The TDI Device Object is required to send these requests to the TDI Driver.
*
*/
pTdiDevice = IoGetRelatedDeviceObject(pfoConnection);
/*
* Step 1: Build the IRP. TDI defines several macros and functions that can quickly
* create IRP's, etc. for variuos purposes. While this can be done manually
* it's easiest to use the macros.
*
* http://msdn.microsoft.com/library/en-us/network/hh/network/34bldmac_f430860a-9ae2-4379-bffc-6b0a81092e7c.xml.asp?frame=true
*/
pIrp = TdiBuildInternalDeviceControlIrp(TDI_DISASSOCIATE_ADDRESS, pTdiDevice, pfoConnection, &TdiCompletionContext.kCompleteEvent, &IoStatusBlock);
if(pIrp)
{
/*
* Step 2: Add the correct parameters into the IRP.
*/
TdiBuildDisassociateAddress(pIrp, pTdiDevice, pfoConnection, NULL, NULL);
NtStatus = IoCallDriver(pTdiDevice, pIrp);
/*
* If the status returned is STATUS_PENDING this means that the IRP will not be completed synchronously
* and the driver has queued the IRP for later processing. This is fine but we do not want to return this
* thread, we are a synchronous call so we want to wait until it has completed. The EVENT that we provided
* will be set when the IRP completes.
*/
if(NtStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&TdiCompletionContext.kCompleteEvent, Executive, KernelMode, FALSE, NULL);
/*
* Find the Status of the completed IRP
*/
NtStatus = IoStatusBlock.Status;
}
}
return NtStatus;
}
/**********************************************************************
*
* TdiFuncs_CloseTdiOpenHandle
*
* This is called to close open handles.
*
**********************************************************************/
NTSTATUS TdiFuncs_CloseTdiOpenHandle(HANDLE hTdiHandle, PFILE_OBJECT pfoTdiFileObject)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
/*
* De-Reference the FILE_OBJECT and Close The Handle
*/
ObDereferenceObject(pfoTdiFileObject);
ZwClose(hTdiHandle);
return NtStatus;
}
/**********************************************************************
*
* TdiFuncs_CompleteIrp
*
* This is called when the IRP is completed
*
**********************************************************************
NTSTATUS TdiFuncs_CompleteIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
PTDI_COMPLETION_CONTEXT pTdiCompletionContext = (PTDI_COMPLETION_CONTEXT)Context;
Do not mark the IRP as pending, we created it we may overwrite memory locations
we don't want to !
return STATUS_CONTINUE_COMPLETION ;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -