⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdiclient.c

📁 好东东
💻 C
📖 第 1 页 / 共 3 页
字号:

Routine Description:

	Free recvContext.

Arguments:

	lpContext	- pointer to recvContext.

Return Value:

    NT status code.

--*/
{
	if ( lpContext->pIrp )
	{
		IoFreeIrp ( lpContext->pIrp );
		lpContext->pIrp = NULL;
	}
	if ( lpContext->bLocked )
	{
		MmUnlockPages ( lpContext->pMdl );
		lpContext->bLocked = FALSE;
	}
	if ( lpContext->pMdl )
	{
		IoFreeMdl ( lpContext->pMdl );
		lpContext->pMdl = NULL;
	}
	return STATUS_SUCCESS;
}
/**************************************************************************************************/
/*                                                                                                */
/* Build and send down an Irp for Receive.                                                        */
/*                                                                                                */
/* Notes:                                                                                         */
/*        1) This routine is NOT synchronous (no particular reason it's not, other than to show   */
/*           off asynchronous operation of an Irp).                                               */
/*                                                                                                */
/*        2) There are indications that an MDL and probe-and-lock are needed even if the buffer   */
/*           is from the non-paged pool.  Eg, microsoft.public.win32.programmer.kernel,           */
/*           "MmProbeAndLockPages bug checks," dave porter, 2001-03-02.  But see the further      */
/*           discussion in comp.os.ms-windows.programmer.nt.kernel-mode, "Free MDL in completion  */
/*           routine," 1999/05/09.                                                                */
/*                                                                                                */
/*        3) Although not documented, it appears that the Irp, the Mdl and the locking are undone */
/*           by the transport.  There are claims to that effect in several places in newsgroups,  */
/*           and freeing the MDL always caused errors in a test (eg, bad pool caller or touching  */
/*           paged storage at wrong IRQL).  Further, testing showed that IoFreeMdl() was being    */
/*           called by somebody (presumably, the transport) for a given MDL.                      */
/*                                                                                                */
/*        4) The supplied context (pCtx) is an event, which the I/O completion routine for the    */
/*           Receive Irp will signal.                                                             */
/*                                                                                                */
/**************************************************************************************************/
NTSTATUS TDIQueryNetworkInformation( PDEVICE_OBJECT DeviceObject, PIRP Irp )
{
	PDEVICE_EXTENSION deviceExtension;
	PIO_STACK_LOCATION IrpStack;
	IO_STATUS_BLOCK	IoStatus;
	NTSTATUS	status;
	ULONG		InputLength, OutputLength;
	ULONG		QType;
	PIRP		pIrp;
	KEVENT		Event;
	PMDL		pMdl;
	ULONG_PTR	virtualAddress;
	
	EXCEPTION_POINTERS        * pExceptionInfo;
	ULONG                       lclExceptionCode;
	PVOID                       lclExceptionAddr;
	BOOLEAN	pageLocked;

	deviceExtension = DeviceObject->DeviceExtension;
	IrpStack	= IoGetCurrentIrpStackLocation(Irp);
	QType		= *((ULONG *)Irp->AssociatedIrp.SystemBuffer);
	DebugPrint(("QueryNetworkInformation: QType = %x\n", QType ));
	KeInitializeEvent(&Event, NotificationEvent, FALSE);
	pIrp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION ,
		deviceExtension->TDILowerDeviceObject,   // TDI driver's device object.
		deviceExtension->lpTransAddrFileObject, // Address file object.
		&Event,       // Event to be signalled when Irp completes.
		&IoStatus     // I/O status block.
		);
	if (NULL==pIrp)
        return STATUS_INSUFFICIENT_RESOURCES;
	virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress);
	OutputLength	= MmGetMdlByteCount(Irp->MdlAddress);
	pMdl = IoAllocateMdl( (PVOID)virtualAddress, OutputLength, FALSE, FALSE, NULL);
	pageLocked = FALSE;
	_try{
		MmProbeAndLockPages(pMdl, KernelMode, IoModifyAccess );
		pageLocked = TRUE;
	}
	_except(
		pExceptionInfo = GetExceptionInformation(),                                                                                                                                                                                                    
		lclExceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode,                                                                                                                                                                             
		lclExceptionAddr = pExceptionInfo->ExceptionRecord->ExceptionAddress,                                                                                                                                                                          
		EXCEPTION_EXECUTE_HANDLER                                                                                                                                                                                                                      
		)                                                                                                                                                                                                                                               
	{                                                                                                                                                                                                                                                    
		DebugPrint((".TDIClnRecv:  MmProbeAndLockPages() failed.  Error = 0x%08x at 0x%08x\n",
			lclExceptionCode, lclExceptionAddr));
		status = lclExceptionCode;                                                                                                                                                                                                                          
		goto done;
	}         
	TdiBuildQueryInformation ( pIrp, deviceExtension->TDILowerDeviceObject,
		deviceExtension->lpTransAddrFileObject,
		NULL, NULL, QType, pMdl );
	status = IoCallDriver ( deviceExtension->TDILowerDeviceObject, pIrp );
	if (STATUS_PENDING==status)
		KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0);
done:
	status = ((STATUS_SUCCESS==status) || (STATUS_PENDING==status)) ? IoStatus.Status : status;
	Irp->IoStatus.Information = IoStatus.Information;
	DebugPrint(("QueryInfo: status %x, Info %d\n", status, Irp->IoStatus.Information ));

	return status;
}

NTSTATUS
TDIClnSetEventHandler(
                      PFILE_OBJECT   pAddrFileObj,    // Address file object.
                      PDEVICE_OBJECT pTcpDevObj,      // TDI driver's device object.
                      LONG           EventType,       // Type of event.
                      PVOID          pEventHandler,   // Event handler routine.
                      PVOID          pEventContext    // Context for event handler.
					  )
/**************************************************************************************************/
/*                                                                                                */
/* Set up an event handler.                                                                       */
/*                                                                                                */
/* Note:  This routine is synchronous.                                                            */
/*                                                                                                */
/**************************************************************************************************/
{
	NTSTATUS            status;
	KEVENT              Event;
	IO_STATUS_BLOCK     IoStatus;
	PIRP				pIrp;
	do {                                                 // Single-iteration loop, to make possible escape via break.
		KeInitializeEvent(&Event, NotificationEvent, FALSE);
		// Get an Irp for internal device ioctl.
		pIrp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER,
			pTcpDevObj,   // TDI driver's device object.
			pAddrFileObj, // Address file object.
			&Event,       // Event to be signalled when Irp completes.
			&IoStatus     // I/O status block.
			);
		if (NULL==pIrp)
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			break;
		}
		TdiBuildSetEventHandler(pIrp,
			pTcpDevObj,
			pAddrFileObj,
			NULL,                    // I/O completion routine.
			NULL,                    // Context for I/O completion routine.
			EventType,
			pEventHandler,           // Event handler routine.
			pEventContext            // Context for event handler routine.
			);
		
		status = IoCallDriver(pTcpDevObj, pIrp);
		
		if (STATUS_PENDING==status)                      // Have to wait on this Irp?
			KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0);
// Problem from IoCallDriver() or Problem discovered in completion?
		if ( ( STATUS_SUCCESS!=status && STATUS_PENDING!=status	)
			|| ( STATUS_PENDING==status && 0!=IoStatus.Status ) )
		{
			// Note:  If problem was in IoCallDriver(), IoStatus.Status probably won't be meaningful.
			DebugPrint(("TDIClnSetEventHandler:  Problem in IoCallDriver().  status = 0x%08x, IoStatus.Status = 0x%08x\n",
				STATUS_PENDING==status ? 0 : status , IoStatus.Status));
		}
    } while(0);                                       // End 'do-while' single-iteration loop.
	
	status = ((STATUS_SUCCESS==status) || (STATUS_PENDING==status)) ? IoStatus.Status : status;
	
	return status;
}                                                     // End TDIClnSetEventHandler().


NTSTATUS
TDIOpenTransportAddress(
                    PWSTR          pTransDevName,     // Transport device name.
                    PHANDLE        pHandle,           // Output handle address.
                    PFILE_OBJECT * ppAddrFileObj,     // Output address file object.
                    USHORT         Port               // Port to open.
					)
/**************************************************************************************************/
/*                                                                                                */
/* Open transport address.                                                                        */
/*                                                                                                */
/**************************************************************************************************/
{
	NTSTATUS                    status;
	UNICODE_STRING              TransDeviceName;
	OBJECT_ATTRIBUTES           Attr;
	IO_STATUS_BLOCK             IoStatus;
	PTA_IP_ADDRESS				pSin;
	PFILE_FULL_EA_INFORMATION	pEa;
	char Buffer[sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_IP_ADDRESS)];
	
	ASSERT ( *pHandle == NULL );
	ASSERT ( *ppAddrFileObj == NULL );
	RtlInitUnicodeString(&TransDeviceName,               // Build Unicode transport device name.
		pTransDevName
		);
	
	InitializeObjectAttributes(&Attr,                    // Attributes (to be initialized);
		&TransDeviceName,
		OBJ_CASE_INSENSITIVE
		|
		OBJ_KERNEL_HANDLE,        // Only in kernel mode but in any process.
		0,
		0
		);
	pEa					= (PFILE_FULL_EA_INFORMATION)Buffer;
	pEa->NextEntryOffset= 0;
	pEa->Flags			= 0;
	pEa->EaNameLength	= TDI_TRANSPORT_ADDRESS_LENGTH;    // Length of TdiTransportAddress, namely of "TransportAddress" string less 1 (ie, without terminator).
	RtlCopyMemory ( pEa->EaName, TdiTransportAddress, pEa->EaNameLength + 1 );
	pEa->EaValueLength	= sizeof(TA_IP_ADDRESS);          // Length of structure.

    // Point to Buffer just after what's been used (ie, after terminator).
	pSin				=(PTA_IP_ADDRESS) ( pEa->EaName + pEa->EaNameLength + 1);
	pSin->TAAddressCount= 1;                                                                                                                                                                                                                                     
	pSin->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
	pSin->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
	pSin->Address[0].Address[0].sin_port = Port;
	pSin->Address[0].Address[0].in_addr = 0;//0x601a8c0;		// 192.168.1.6
	RtlZeroMemory ( pSin->Address[ 0 ].Address[ 0 ].sin_zero, sizeof ( pSin->Address[ 0 ].Address[ 0 ].sin_zero ) );
	
	status = ZwCreateFile(pHandle,                       // Actual open of transport address.
		GENERIC_READ | GENERIC_WRITE,
		&Attr,
		&IoStatus,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN_IF,
		0,
		pEa,	//NULL,
		sizeof ( Buffer )
		);
	
	if (!NT_SUCCESS(status))
	{
		DebugPrint(("ZwCreateFile failed with status %x\n", status ));
		return status;
	}
	
	status = ObReferenceObjectByHandle(*pHandle,         // Get the object pointer for the address file object's handle.
		GENERIC_READ | GENERIC_WRITE,
		0,
		KernelMode,
		(PVOID *)ppAddrFileObj,
		NULL
		);
	
	if (!NT_SUCCESS(status))
	{
		DebugPrint(("ObReferenceObject failed with status %x\n", status ));
		ZwClose ( *pHandle );
		*pHandle = NULL;
	}
	return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -