Ejemplo n.º 1
0
VOID PrintUnknownDeviceIoctlCode(__in ULONG IoctlCode) {
  PCHAR baseCodeStr = "unknown";
  ULONG baseCode = DEVICE_TYPE_FROM_CTL_CODE(IoctlCode);
  ULONG functionCode = (IoctlCode & (~0xffffc003)) >> 2;

  DDbgPrint("   Unknown Code 0x%x\n", IoctlCode);

  switch (baseCode) {
  case IOCTL_STORAGE_BASE:
    baseCodeStr = "IOCTL_STORAGE_BASE";
    break;
  case IOCTL_DISK_BASE:
    baseCodeStr = "IOCTL_DISK_BASE";
    break;
  case IOCTL_VOLUME_BASE:
    baseCodeStr = "IOCTL_VOLUME_BASE";
    break;
  case MOUNTDEVCONTROLTYPE:
    baseCodeStr = "MOUNTDEVCONTROLTYPE";
    break;
  case MOUNTMGRCONTROLTYPE:
    baseCodeStr = "MOUNTMGRCONTROLTYPE";
    break;
  default:
    break;
  }
  UNREFERENCED_PARAMETER(functionCode);
  DDbgPrint("   BaseCode: 0x%x(%s) FunctionCode 0x%x(%d)\n", baseCode,
            baseCodeStr, functionCode, functionCode);
}
Ejemplo n.º 2
0
void BazisLib::DDK::DumpDeviceControlCode(const char *pszFormat, ULONG Code)
{
	char szCode[512];
	const char *pszCode = MapDeviceControlCode(Code);
	if (!pszCode)
	{
		sprintf(szCode, "[%08X; (devtype=%04X; code=%03X)]", Code, DEVICE_TYPE_FROM_CTL_CODE(Code), (Code >> 2) & 0x7FF);
		pszCode = szCode;
	}
/*******************************************************************************
*
*   函 数 名 : DispatchDeviceControl
*  功能描述 : 
*  参数列表 : pDriverObj    --  
*                  pIrp
*   说      明 : 
*  返回结果 :  成功返回 STATUS_SUCCESS
*
*******************************************************************************/
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, 
                                                     IN PIRP pIrp)
{
        NTSTATUS status               = STATUS_INVALID_DEVICE_REQUEST;	 // STATUS_UNSUCCESSFUL
        PIO_STACK_LOCATION pIrpStack  = IoGetCurrentIrpStackLocation(pIrp);
        ULONG uIoControlCode         = 0;
        PVOID pIoBuffer                     = NULL;
        ULONG uInSize                       = 0;
        ULONG uOutSize                    = 0;
        PHIDE_INFO pHi                      = NULL ;
        PPROTECT_PID_INFO pPi         = NULL ;
        PPROTECT_NAME_INFO  pNi  = NULL ;
        PDEVICE_EXTENSION pde = (PDEVICE_EXTENSION)pDevObj->DeviceExtension ;

        // Get the IoCtrl Code
        uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

        // Get the buffer info
        pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
        uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
        uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;


        KdBreakPoint() ;
        KeWaitForSingleObject(&pde->DeviceIoControlMutex, 
                                                Executive,
                                                KernelMode,
                                                FALSE,
                                                NULL) ;

        switch(uIoControlCode)
        {
        // 添加要保护的进程名
        case IOCTRL_ADD_PROTECT_NAME:
                {
                        pNi = (PPROTECT_NAME_INFO)pIoBuffer ;
                        if (sizeof(PROTECT_NAME_INFO) != uInSize || NULL == pNi)
                        {
                                break ;
                        }
                        // 这里可以判断一下返回值
                        if(AddProtectProcessName(pNi->ProcessName))
                        {
                                status = STATUS_SUCCESS ;
                        }
                }
                break ;
        case IOCTRL_ADD_PROTECT_PID:
                {
                        pPi = (PPROTECT_PID_INFO)pIoBuffer ;
                        if (sizeof(PROTECT_PID_INFO) != uInSize || NULL == pPi)
                        {
                                break ;
                        }
                        // 这里可以判断一下返回值
                        if( AddProtectProcessPID(pPi->uPID))
                        {
                                status = STATUS_SUCCESS ;
                        }
                }
                break ;
                // 处理隐藏进程
                case IOCTRL_HIDE:
                        {
                                // Receive data form Application
                                //dprintf("IOCTRL_HIDE\r\n");

                                // Do we have any data?
                                // 判断传进来的参数是否正确
                                pHi = (PHIDE_INFO)pIoBuffer ;
                                if (sizeof(HIDE_INFO) != uInSize || NULL == pHi)
                                {
                                        break ;
                                }
                                // 这里可以判断一下返回值
                                if( HideProcess(pDevObj, pHi->uPID) )
                                {
                                        status = STATUS_SUCCESS ;
                                }
                        }
                        break ;
                case IOCTRL_START_FILTER:
                        {
                                if (! pde->bIsFiltrateProcess)
                                {
                                        pde->bIsFiltrateProcess = true ;
                                        status = STATUS_SUCCESS ;
                                }
                        }
                        break ;
                case IOCTRL_STOP_FILTER:
                        {
                                if (pde->bIsFiltrateProcess)
                                {
                                        pde->bIsFiltrateProcess = false ;
                                        status = STATUS_SUCCESS ;
                                }
                        }
                        break ;
                //
                // TODO: Add execute code here.
                //

                default:
                        {
                                // Invalid code sent
                                dprintf("Unknown IOCTL: 0x%X (%04X,%04X)\r\n", 
                                          uIoControlCode,
                                          DEVICE_TYPE_FROM_CTL_CODE(uIoControlCode),
                                          IoGetFunctionCodeFromCtlCode(uIoControlCode));
                                status = STATUS_INVALID_PARAMETER;	
                        }
                        break;
        }

        if(status == STATUS_SUCCESS)
        {
                pIrp->IoStatus.Information = uOutSize;
        }
        else
        {
                pIrp->IoStatus.Information = 0;
        }

        // Complete the I/O Request
        pIrp->IoStatus.Status = status;

        KeReleaseMutex(&pde->DeviceIoControlMutex, FALSE) ;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        
        return status;
}
Ejemplo n.º 4
0
BOOLEAN
MiniSecondary_Ioctl (
	IN  PSECONDARY				Secondary,
	IN OUT PFLT_CALLBACK_DATA	Data
	)
{
	NTSTATUS			status;
	//PIO_STACK_LOCATION	iopb = IoGetCurrentIrpStackLocation( Irp );
	PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb;
    //KEVENT				waitEvent;
	ULONG				ioctlCode = iopb->Parameters.DeviceIoControl.Common.IoControlCode;
	ULONG				devType = DEVICE_TYPE_FROM_CTL_CODE(ioctlCode);
	UCHAR				function = (UCHAR)((ioctlCode & 0x00003FFC) >> 2);
	PVOID				inputBuffer, outputBuffer;
	IO_STATUS_BLOCK		ioStatusBlock;


	SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_TRACE, 
				   ("Secondary_Ioctl: IRP_MJ_DEVICE_CONTROL Entered, deviceType = %d, function = %d IOCTL_VOLUME_BASE = %d, MOUNTDEVCONTROLTYPE = %d\n",
					devType, function, IOCTL_VOLUME_BASE, MOUNTDEVCONTROLTYPE) );

	if (IS_WINDOWS2K() && Secondary->LfsDeviceExt->DiskDeviceObject == NULL) {

		NDASFS_ASSERT( LFS_BUG );
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}

	if (IS_WINDOWSXP_OR_LATER() && Secondary->LfsDeviceExt->MountVolumeDeviceObject == NULL) {

		NDASFS_ASSERT( LFS_BUG );
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}

	if (ioctlCode == IOCTL_VOLUME_SET_GPT_ATTRIBUTES) {

		Data->IoStatus.Status = STATUS_NOT_SUPPORTED;
		Data->IoStatus.Information = 0;

		return FLT_PREOP_COMPLETE;
	}

	SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE,
				   ("Open files from secondary: LfsDeviceExt = %p, iopb->MajorFunction = %x, iopb->MinorFunction = %x\n", 
					 Secondary->LfsDeviceExt, iopb->MajorFunction, iopb->MinorFunction) );

	inputBuffer = MinispyMapInputBuffer( iopb, Data->RequestorMode );
	outputBuffer = MinispyMapOutputBuffer( iopb, Data->RequestorMode );

	status = LfsFilterDeviceIoControl( IS_WINDOWS2K() ? Secondary->LfsDeviceExt->DiskDeviceObject : Secondary->LfsDeviceExt->MountVolumeDeviceObject,
									   ioctlCode,
									   inputBuffer,
									   iopb->Parameters.DeviceIoControl.Common.InputBufferLength,
									   outputBuffer,
									   iopb->Parameters.DeviceIoControl.Common.OutputBufferLength,
									   &ioStatusBlock.Information );


	SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_ERROR, ("%s: status = %x\n", __FUNCTION__, status) );

	Data->IoStatus.Status = status;
	Data->IoStatus.Information = ioStatusBlock.Information;

	return FLT_PREOP_COMPLETE;
}
Ejemplo n.º 5
0
NTSTATUS
DokanDispatchDeviceControl(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp)

/*++

Routine Description:

        This device control dispatcher handles IOCTLs.

Arguments:

        DeviceObject - Context for the activity.
        Irp          - The device control argument block.

Return Value:

        NTSTATUS

--*/

{
  PDokanVCB vcb;
  PDokanDCB dcb;
  PIO_STACK_LOCATION irpSp;
  NTSTATUS status = STATUS_NOT_IMPLEMENTED;
  ULONG controlCode = 0;
  ULONG outputLength = 0;
  // {DCA0E0A5-D2CA-4f0f-8416-A6414657A77A}
  // GUID dokanGUID = { 0xdca0e0a5, 0xd2ca, 0x4f0f, { 0x84, 0x16, 0xa6, 0x41,
  // 0x46, 0x57, 0xa7, 0x7a } };

  __try {
    Irp->IoStatus.Information = 0;

    irpSp = IoGetCurrentIrpStackLocation(Irp);
    outputLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;

    controlCode = irpSp->Parameters.DeviceIoControl.IoControlCode;

    if (controlCode != IOCTL_EVENT_WAIT && controlCode != IOCTL_EVENT_INFO &&
        controlCode != IOCTL_KEEPALIVE) {

      DDbgPrint("==> DokanDispatchIoControl\n");
      DDbgPrint("  ProcessId %lu\n", IoGetRequestorProcessId(Irp));
    }

    if (DeviceObject->DriverObject == NULL ||
        DeviceObject->ReferenceCount < 0) {
      status = STATUS_DEVICE_DOES_NOT_EXIST;
      __leave;
    }

    vcb = DeviceObject->DeviceExtension;
    PrintIdType(vcb);
    if (GetIdentifierType(vcb) == DGL) {
      status = GlobalDeviceControl(DeviceObject, Irp);
      __leave;
    } else if (GetIdentifierType(vcb) == DCB) {
      status = DiskDeviceControlWithLock(DeviceObject, Irp);
      __leave;
    } else if (GetIdentifierType(vcb) != VCB) {
      status = STATUS_INVALID_PARAMETER;
      __leave;
    }
    dcb = vcb->Dcb;

    switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_EVENT_WAIT:
      DDbgPrint("  IOCTL_EVENT_WAIT\n");
      status = DokanRegisterPendingIrpForEvent(DeviceObject, Irp);
      break;

    case IOCTL_EVENT_INFO:
      // DDbgPrint("  IOCTL_EVENT_INFO\n");
      status = DokanCompleteIrp(DeviceObject, Irp);
      break;

    case IOCTL_EVENT_RELEASE:
      DDbgPrint("  IOCTL_EVENT_RELEASE\n");
      status = DokanEventRelease(DeviceObject, Irp);
      break;

    case IOCTL_EVENT_WRITE:
      DDbgPrint("  IOCTL_EVENT_WRITE\n");
      status = DokanEventWrite(DeviceObject, Irp);
      break;

    case IOCTL_KEEPALIVE:
      DDbgPrint("  IOCTL_KEEPALIVE\n");
      if (IsFlagOn(vcb->Flags, VCB_MOUNTED)) {
        ExEnterCriticalRegionAndAcquireResourceExclusive(&dcb->Resource);
        DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT);
        ExReleaseResourceAndLeaveCriticalRegion(&dcb->Resource);
        status = STATUS_SUCCESS;
      } else {
        DDbgPrint(" device is not mounted\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
      }
      break;

    case IOCTL_RESET_TIMEOUT:
      status = DokanResetPendingIrpTimeout(DeviceObject, Irp);
      break;

    case IOCTL_GET_ACCESS_TOKEN:
      status = DokanGetAccessToken(DeviceObject, Irp);
      break;

    default: {
      ULONG baseCode = DEVICE_TYPE_FROM_CTL_CODE(
          irpSp->Parameters.DeviceIoControl.IoControlCode);
      status = STATUS_NOT_IMPLEMENTED;
      // In case of IOCTL_STORAGE_BASE or IOCTL_DISK_BASE OR
      // FILE_DEVICE_NETWORK_FILE_SYSTEM or MOUNTDEVCONTROLTYPE ioctl type, pass
      // to DiskDeviceControl to avoid code duplication
      // TODO: probably not the best way to pass down Irp...
      if (baseCode == IOCTL_STORAGE_BASE || baseCode == IOCTL_DISK_BASE ||
          baseCode == FILE_DEVICE_NETWORK_FILE_SYSTEM ||
          baseCode == MOUNTDEVCONTROLTYPE) {
        status = DiskDeviceControlWithLock(dcb->DeviceObject, Irp);
      }

      if (status == STATUS_NOT_IMPLEMENTED) {
        PrintUnknownDeviceIoctlCode(
            irpSp->Parameters.DeviceIoControl.IoControlCode);
      }
    } break;
    } // switch IoControlCode

  } __finally {

    if (status != STATUS_PENDING) {
      if (IsDeletePending(DeviceObject)) {
        DDbgPrint("  DeviceObject is invalid, so prevent BSOD");
        status = STATUS_DEVICE_REMOVED;
      }
      DokanCompleteIrpRequest(Irp, status, Irp->IoStatus.Information);
    }

    if (controlCode != IOCTL_EVENT_WAIT && controlCode != IOCTL_EVENT_INFO &&
        controlCode != IOCTL_KEEPALIVE) {

      DokanPrintNTStatus(status);
      DDbgPrint("<== DokanDispatchIoControl\n");
    }
  }

  return status;
}
Ejemplo n.º 6
0
NTSTATUS
FatCommonDeviceControl (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for doing Device control operations called
    by both the fsd and fsp threads

Arguments:

    Irp - Supplies the Irp to process

    InFsp - Indicates if this is the fsp thread or someother thread

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp;
    KEVENT WaitEvent;
    PVOID CompletionContext = NULL;

    PVCB Vcb;
    PFCB Fcb;
    PCCB Ccb;

#if __NDAS_FAT_PRIMARY__

	if (IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL && 
		IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode == IOCTL_INSERT_PRIMARY_SESSION) {

		PVOLUME_DEVICE_OBJECT	VolDo = CONTAINING_RECORD( IoGetCurrentIrpStackLocation(Irp)->DeviceObject, 
														   VOLUME_DEVICE_OBJECT, 
														   DeviceObject );
		PSESSION_INFORMATION	inputBuffer = (PSESSION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
		ULONG					inputBufferLength = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.InputBufferLength;
		ULONG					outputBufferLength;
		PULONG					outputBuffer;
		PPRIMARY_SESSION		primarySession;

		if (inputBufferLength != sizeof(SESSION_INFORMATION)) {

			FatCompleteRequest( IrpContext, Irp, Status = STATUS_INVALID_PARAMETER );
			return Status;
		} 

		outputBufferLength = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.OutputBufferLength;
		outputBuffer = (PULONG)Irp->AssociatedIrp.SystemBuffer;

		primarySession = PrimarySession_Create( IrpContext, VolDo, inputBuffer, Irp );

		ASSERT( primarySession );

		FatCompleteRequest( IrpContext, NULL, 0 );
		Status = STATUS_PENDING;
		return Status;
	}

#endif

    //
    //  Get a pointer to the current Irp stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatCommonDeviceControl\n", 0);
    DebugTrace( 0, Dbg, "Irp           = %08lx\n", Irp);
    DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction);

    //
    //  Decode the file object, the only type of opens we accept are
    //  user volume opens.
    //

    if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb ) != UserVolumeOpen) {

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );

        DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER);
        return STATUS_INVALID_PARAMETER;
    }

#define IOCTL_VOLUME_BASE   ((ULONG) 'V')
#define MOUNTDEVCONTROLTYPE  ((ULONG) 'M')

	DebugTrace2( 0, Dbg2, 
				("FatCommonDeviceControl: deviceType = %d, function = %d IOCTL_VOLUME_BASE = %d, MOUNTDEVCONTROLTYPE = %d\n",
				  DEVICE_TYPE_FROM_CTL_CODE(IrpSp->Parameters.DeviceIoControl.IoControlCode), 
				  (UCHAR)((IrpSp->Parameters.DeviceIoControl.IoControlCode & 0x00003FFC) >> 2), IOCTL_VOLUME_BASE, MOUNTDEVCONTROLTYPE) );

#if __NDAS_FAT__
	if (CONTAINING_RECORD(Vcb, VOLUME_DEVICE_OBJECT, Vcb)->NetdiskEnableMode == NETDISK_SECONDARY)
		SetFlag( IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT );
#endif

    //
    //  A few IOCTLs actually require some intervention on our part
    //

    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {

    case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:


#if __NDAS_FAT_WIN2K_SUPPORT__

		if (!IS_WINDOWSXP_OR_LATER()) {

			ASSERT( FALSE );
			IoSkipCurrentIrpStackLocation( Irp );
			break;
		}

#endif

        //
        //  This is sent by the Volume Snapshot driver (Lovelace).
        //  We flush the volume, and hold all file resources
        //  to make sure that nothing more gets dirty. Then we wait
        //  for the IRP to complete or cancel.
        //

        SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
        FatAcquireExclusiveVolume( IrpContext, Vcb );

		FatFlushAndCleanVolume( IrpContext,
                                Irp,
                                Vcb,
                                FlushWithoutPurge );

        KeInitializeEvent( &WaitEvent, NotificationEvent, FALSE );
        CompletionContext = &WaitEvent;

        //
        //  Get the next stack location, and copy over the stack location
        //

        IoCopyCurrentIrpStackLocationToNext( Irp );

        //
        //  Set up the completion routine
        //

        IoSetCompletionRoutine( Irp,
                                FatDeviceControlCompletionRoutine,
                                CompletionContext,
                                TRUE,
                                TRUE,
                                TRUE );
        break;

    default:

        //
        //  FAT doesn't need to see this on the way back, so skip ourselves.
        //

        IoSkipCurrentIrpStackLocation( Irp );
        break;
    }

    //
    //  Send the request.
    //

    Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);

    if (Status == STATUS_PENDING && CompletionContext) {

        KeWaitForSingleObject( &WaitEvent,
                               Executive,
                               KernelMode,
                               FALSE,
                               NULL );

        Status = Irp->IoStatus.Status;
    }

	//DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> Information %08lx\n", Irp->IoStatus.Information);

    //
    //  If we had a context, the IRP remains for us and we will complete it.
    //  Handle it appropriately.
    //

    if (CompletionContext) {

        //
        //  Release all the resources that we held because of a
        //  VOLSNAP_FLUSH_AND_HOLD. 
        //

        ASSERT( IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES );

        FatReleaseVolume( IrpContext, Vcb );

        //
        //  If we had no context, the IRP will complete asynchronously.
        //

    } else {

        Irp = NULL;
    }

	FatCompleteRequest( IrpContext, Irp, Status );

    DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> %08lx\n", Status);

    return Status;
}
Ejemplo n.º 7
0
NTSTATUS 
DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
	NTSTATUS status               = STATUS_INVALID_DEVICE_REQUEST;	 // STATUS_UNSUCCESSFUL
	PIO_STACK_LOCATION pIrpStack  = IoGetCurrentIrpStackLocation(pIrp);
	ULONG uIoControlCode          = 0;
	PVOID pIoBuffer				  = NULL;
	ULONG uInSize                 = 0;
	ULONG uOutSize                = 0;

	// Get the IoCtrl Code
	uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

	pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
	uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	switch(uIoControlCode)
	{
		case IOCTL_HELLO_WORLD:
			{			
				dprintf("MY_CTL_CODE(0)=%d\r\n,MY_CTL_CODE");

				// Return success
				status = STATUS_SUCCESS;
			}
			break;

		case IOCTRL_REC_FROM_APP:
			{
				// Receive data form Application
				//dprintf("IOCTRL_REC_FROM_APP\r\n");

				// Do we have any data?
				if( uInSize > 0 )
				{
					dprintf("Get Data from App: %ws\r\n", pIoBuffer);
				}

				// Return success
				status = STATUS_SUCCESS;
			}
			break;

		case IOCTRL_SEND_TO_APP:
			{
				// Send data to Application
				//dprintf("IOCTRL_SEND_TO_APP\r\n");
			
				// If we have enough room copy the data upto the App - note copy the terminating character as well...
				if( uOutSize >= strlen( DATA_TO_APP ) + 1 )
				{
					RtlCopyMemory(  pIoBuffer,
									DATA_TO_APP, 
									strlen( DATA_TO_APP ) + 1 );

					// Update the length for the App
					pIrp->IoStatus.Information = strlen( DATA_TO_APP ) + 1;

					dprintf("Send Data to App: %s\r\n", pIoBuffer);
					
					// Return success
					status = STATUS_SUCCESS;
				}
			}
			break;
			
		//
		// TODO: Add execute code here.
		//

		default:
			{
				// Invalid code sent
				dprintf("Unknown IOCTL: 0x%X (%04X,%04X)\r\n", 
                                          uIoControlCode,
                                          DEVICE_TYPE_FROM_CTL_CODE(uIoControlCode),
                                          IoGetFunctionCodeFromCtlCode(uIoControlCode));
				status = STATUS_INVALID_PARAMETER;	
			}
			break;
	}

	if(status == STATUS_SUCCESS)
	{
		pIrp->IoStatus.Information = uOutSize;
	}
	else
	{
		pIrp->IoStatus.Information = 0;
	}

	// Complete the I/O Request
	pIrp->IoStatus.Status = status;

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return status;
}
Ejemplo n.º 8
0
NTSTATUS FWDispatch(
								   IN PDEVICE_OBJECT		DeviceObject,
								   IN PIRP					Irp
								   )
{
	NTSTATUS			Status = STATUS_SUCCESS;
	PIO_STACK_LOCATION	irpStack;
	PDEVICE_EXTENSION	deviceExtension;
	PVOID				ioBuf;
	ULONG				inBufLength, outBufLength;
	ULONG				ioControlCode;
	ULONG_PTR			 num=0;

	irpStack = IoGetCurrentIrpStackLocation(Irp);
	deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

	Irp->IoStatus.Information = 0;

	//
	// Get the pointer to the input/output buffer and it's length
	//

	ioBuf = Irp->AssociatedIrp.SystemBuffer;
	inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
	outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
	ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
	// Irp->UserBuffer;		// If METHOD_NEITHER, This is Output Buffer

	switch (ioControlCode)
	{
	case IOCTL_SETUPFW:
		{
			//

			if (g_AlreadyHookTCPIP)
			{
				InterlockedExchange(&g_InterceptTCPIPRcv, 1);
			}
			else
			{
				Status=	FWHookTcpipRecvHandler();
				if (NT_SUCCESS(Status))
				{
					InterlockedExchange(&g_InterceptTCPIPRcv, 1);
					g_AlreadyHookTCPIP	=	1;
				}
			}
			break;
		}
	case IOCTL_UNSETFW:
		{
			//
			InterlockedExchange(&g_InterceptTCPIPRcv, 0);
			//UNHOOK的行为就放到驱动卸载时候了
			break;
		}
	case IOCTL_PENDDINGCHECKPORT:
		{
			//pendding进去
			IoMarkIrpPending(Irp);
			ExInterlockedInsertHeadList(&g_AskUserConnectListHeader, &Irp->Tail.Overlay.ListEntry, &g_AskUserConnectListLock);
			Status= STATUS_PENDING;
			Irp->IoStatus.Status = Status;
			return Status;
			break;
		}
	case IOCTL_SETONEPORTSTATUS:
		{
			Status = SetupPortStatus(ioBuf, 1);
			break;
		}
	case IOCTL_RESPONSEPORTASK:
		{
			Status = ResponsePortAsk((PFIREWALL_ASKUSER)ioBuf);
			break;
		}
	case IOCTL_ReleasePENDDINGCHECKPORT:
		{
			Status = ReleasePenddingCheckPortIrp();
			break;
		}
	case IOCTL_GETPORTSTATUS:
		{
			Status = GetPortRules(ioBuf, &outBufLength);
			if (Status==STATUS_INFO_LENGTH_MISMATCH)
			{
				Status	=	STATUS_SUCCESS;
			}
			Irp->IoStatus.Information	=	outBufLength;
			break;
		}

	default:
		{
			//Status = STATUS_INVALID_PARAMETER;
			kprintf("[SuperCI]  Unknown IOCTL: 0x%X (%04X,%04X)\n",
				ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode),
				IoGetFunctionCodeFromCtlCode(ioControlCode));


			break;
		}
	}


	Irp->IoStatus.Status = Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);


	return Status;

}
Ejemplo n.º 9
0
static VOID UsbChief_EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request,
				 IN size_t OutputBufferLength, IN size_t InputBufferLength,
				 IN ULONG IoControlCode)
{
	NTSTATUS Status;
	size_t Length = 0;
	PIOCTL_DATA data;
	PDEVICE_CONTEXT pDeviceContext;
	UCHAR test[4096];
	UCHAR *config;
	WORD *version;
	URB Urb;
	WDF_USB_INTERFACE_SELECT_SETTING_PARAMS interfaceParams;
	ULONG i;
	UNREFERENCED_PARAMETER(OutputBufferLength);
	UNREFERENCED_PARAMETER(InputBufferLength);
	UNREFERENCED_PARAMETER(Queue);

	PAGED_CODE();

	pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

	Length = 0;
	switch(IoControlCode) {
	case IOCTL_VENDOR_WRITE:

		if (InputBufferLength != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &data, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtIoDeviceControl: IOCTL_VENDOR_WRITE %x, Index %x, Value %x, Max Length %d, Buf %p\n",
				      data->Request, data->Index, data->Value, data->Length, data->Buffer));

		if (Length != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Failed to retrieve buffer: %d/%d\n", Length, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		memset(&Urb, 0, sizeof(Urb));
		Urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
		Urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
		Urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x40;
		Urb.UrbControlVendorClassRequest.TransferBufferLength = data->Length;
		Urb.UrbControlVendorClassRequest.TransferBuffer = (PVOID)data->Buffer;
		Urb.UrbControlVendorClassRequest.Request = data->Request;
		Urb.UrbControlVendorClassRequest.Value = data->Value;
		Urb.UrbControlVendorClassRequest.Index = data->Index;

		if (DebugLevel & DEBUG_IOCTL) {
			for(i = 0; i < data->Length; i++)
				DbgPrint("%02X ", ((PUCHAR)data->Buffer)[i]);
			DbgPrint("\n");
		}
		Status = WdfUsbTargetDeviceSendUrbSynchronously(pDeviceContext->WdfUsbTargetDevice, NULL, NULL, &Urb);

		if (!NT_SUCCESS(Status)) {
			UsbChief_DbgPrint(0, ("WdfUsbTargetDeviceSendControlTransferSynchronously failed\n"));
		}
		break;

	case IOCTL_VENDOR_READ:
		if (InputBufferLength != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &data, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtIoDeviceControl: IOCTL_VENDOR_READ %x, Index %x, Value %x, Max Length %d, Buf %p\n",
				      data->Request, data->Index, data->Value, data->Length, data->Buffer));

		if (Length != sizeof(*data)) {
			UsbChief_DbgPrint(0, ("Failed to retrieve buffer: %d/%d\n", Length, sizeof(*data)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		if (data->Length > sizeof(test)) {
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		memset(&Urb, 0, sizeof(Urb));
		Urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
		Urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
		Urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0xc0;
		Urb.UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
		Urb.UrbControlVendorClassRequest.TransferBufferLength = data->Length;
		Urb.UrbControlVendorClassRequest.TransferBuffer = test;
		Urb.UrbControlVendorClassRequest.Request = data->Request;
		Urb.UrbControlVendorClassRequest.Value = data->Value;
		Urb.UrbControlVendorClassRequest.Index = data->Index;

		Status = WdfUsbTargetDeviceSendUrbSynchronously(pDeviceContext->WdfUsbTargetDevice, NULL, NULL, &Urb);

		if (DebugLevel & DEBUG_IOCTL && NT_SUCCESS(Status)) {
			for(i = 0; i < Urb.UrbControlVendorClassRequest.TransferBufferLength; i++)
				DbgPrint("%02X ", ((PUCHAR)test)[i]);
			DbgPrint("\n");
		}

		if (Urb.UrbControlVendorClassRequest.TransferBufferLength)
			memcpy((PVOID)data->Buffer, test, Urb.UrbControlVendorClassRequest.TransferBufferLength);
		Length = Urb.UrbControlVendorClassRequest.TransferBufferLength;
		break;

	case IOCTL_SELECT_CONFIGURATION:

		if (InputBufferLength != sizeof(*config)) {
			UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*config)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		config = 0;
		Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, (PVOID)&config, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		if (Length != sizeof(*config)) {
			UsbChief_DbgPrint(0, ("Invalid Length: %d/%d\n", Length, sizeof(*config)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: IOCTL_SELECT_CONFIGURATION %x\n", *config));

		if (!pDeviceContext->UsbInterface) {
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING (&interfaceParams, *config);

		Status = WdfUsbInterfaceSelectSetting(pDeviceContext->UsbInterface, WDF_NO_OBJECT_ATTRIBUTES,
						      &interfaceParams);
		break;

	case IOCTL_GET_FIRMWARE_VERSION:
		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: GET_FIRMWARE_VERSION\n"));

		Status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &version, &Length);
		if (!NT_SUCCESS(Status))
			goto out;

		if (Length != sizeof(*version)) {
			UsbChief_DbgPrint(0, ("Invalid Length: %d/%d\n", Length, sizeof(*version)));
			Status = STATUS_INVALID_DEVICE_REQUEST;
			goto out;
		}

		*version = pDeviceContext->UsbDeviceDescriptor.bcdDevice;
		break;

	default:
		UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl %08x (Device %x, Method %x) unknown\n",
				      IoControlCode, DEVICE_TYPE_FROM_CTL_CODE(IoControlCode),
				      METHOD_FROM_CTL_CODE(IoControlCode)));
		Status = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}
out:
	UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: Status %08x, Length %d\n", Status, Length));
	WdfRequestCompleteWithInformation(Request, Status, Length);
}