Example #1
0
NTSTATUS PPJoy_AddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT FunctionalDeviceObject)
{
 NTSTATUS			ntStatus;
 PDEVICE_OBJECT		DeviceObject;
 PDEVICE_EXTENSION	DeviceExtension;

 PAGED_CODE ();

 PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_FENTRY, ("PPJoy_AddDevice(DriverObject=0x%p,FunctionalDeviceObject=0x%p)",DriverObject,FunctionalDeviceObject) );

 ntStatus= STATUS_SUCCESS;
 DeviceObject= FunctionalDeviceObject;
 DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

 /* This is where we initialise the DeviceExtension for each joystick */
 RtlZeroMemory (DeviceExtension,sizeof(DEVICE_EXTENSION));
 KeInitializeEvent (&DeviceExtension->RemoveEvent,SynchronizationEvent,FALSE);
 DeviceExtension->ActiveMap= 0;

 Globals.NumPresentJoys++;
 PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_BABBLE, ("PPJoy_AddDevice: Current number of joystick objects are now %d",Globals.NumPresentJoys) );

 /* Tell Io Manager we are done initialising */
 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

 PPJOY_EXITPROC (FILE_PPORTJOY|PPJOY_FEXIT_STATUSOK, "PPJoy_AddDevice", ntStatus);
 return ntStatus;
}
Example #2
0
// *****************************************************************************
NTSTATUS INTERNAL
    HGM_ActivateDevice
    (
    PDEVICE_OBJECT  DeviceObject
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;

    PDEVICE_EXTENSION   DeviceExtension;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE Thread;
    PVOID pkThread;
    PAGED_CODE();
    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    if(!DeviceExtension->ScanThread)
//    if(!Global.ThreadIniciado)
    {
//      Global.ThreadIniciado = 1;
      InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL)
      KeInitializeEvent(&(DeviceExtension->FinishThread), NotificationEvent, FALSE);
      KeInitializeEvent(&(DeviceExtension->DoScan), SynchronizationEvent, FALSE);
      KeInitializeEvent(&(DeviceExtension->ScanReady), SynchronizationEvent, FALSE);
      ntStatus = PsCreateSystemThread(&Thread, THREAD_ALL_ACCESS,
                                       &ObjectAttributes, NULL, NULL, ScaningThread, (PVOID) DeviceObject);
      ObReferenceObjectByHandle(Thread, THREAD_ALL_ACCESS, NULL, KernelMode, &pkThread,NULL);
      KeSetPriorityThread(pkThread, LOW_REALTIME_PRIORITY - 1);
      DeviceExtension->ScanThread = (PKTHREAD) pkThread;
    };
    return ntStatus;
} /* HGM_GetAttributes */
Example #3
0
NTSTATUS EXTERNAL
HbtnAddDevice(
    __in PDRIVER_OBJECT DrvObj,
    __in PDEVICE_OBJECT DevObj
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION   devext = NULL;

    PAGED_CODE ();
    TEnter(Func,("(DrvObj=%p,DevObj=%p)\n", DrvObj, DevObj));
    
    UNREFERENCED_PARAMETER(DrvObj);

    devext = GET_MINIDRIVER_DEVICE_EXTENSION(DevObj);
    RtlZeroMemory(devext, sizeof(*devext));
    devext->self = DevObj;
    devext->LowerDevObj = GET_NEXT_DEVICE_OBJECT(DevObj);
    IoInitializeRemoveLock(&devext->RemoveLock, HBTN_POOL_TAG, 0, 10);
    KeInitializeSpinLock(&devext->QueueLock);
    KeInitializeSpinLock(&devext->DataLock);
    InitializeListHead(&devext->PendingIrpList);
    IoCsqInitialize(&devext->IrpQueue, HbtnInsertIrp, HbtnRemoveIrp, 
        HbtnPeekNextIrp, HbtnAcquireLock, HbtnReleaseLock, HbtnCompleteCancelledIrp);

    status = OemAddDevice(devext);
    if (NT_SUCCESS(status))
    {
        DevObj->Flags &= ~DO_DEVICE_INITIALIZING;
        DevObj->Flags |= DO_POWER_PAGABLE;
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //HbtnAddDevice
Example #4
0
NTSTATUS PPJoy_LoadJoystickTiming (IN PDEVICE_OBJECT DeviceObject)
{
 NTSTATUS			ntStatus;
 PDEVICE_EXTENSION	DeviceExtension;
 PJOYTIMING			OldTiming;
 PJOYTIMING			NewTiming;

 PAGED_CODE();

 DeviceExtension= GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);

 if (!PPJOY_ComputeTimingSize(DeviceExtension->Config.JoyType))
 {
  PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE2, ("Joystick timing not required for this device") );
  return STATUS_SUCCESS;
 }

 PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE2, ("Attempting to read joystick timing from device registry key") );
 NewTiming= PPJoy_ReadDeviceTiming(DeviceObject,DeviceExtension->Config.JoyType);
 if (NewTiming)
 {
  PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE, ("Joystick timing successfully read from the device registry") );
  goto UpdateTiming;
 }

 PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE2, ("Attempting to read joystick timing from driver registry key") );
 NewTiming= PPJoy_ReadDriverTiming(DeviceObject,DeviceExtension->Config.JoyType);
 if (NewTiming)
 {
  PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE, ("Joystick timing successfully read from the driver registry") );
  goto UpdateTiming;
 }
    
 PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE2, ("Building default joystick timing for device") );
 NewTiming= PPJoy_BuildDefaultTiming(DeviceExtension->Config.JoyType);
 if (NewTiming)
 {
  PPJOY_DBGPRINT (FILE_TIMING|PPJOY_BABBLE, ("Joystick timing successfully built manually") );
  goto UpdateTiming;
 }

 return STATUS_UNSUCCESSFUL;

UpdateTiming:

 OldTiming= DeviceExtension->Timing;
 DeviceExtension->Timing= NewTiming;

 PPJoy_InitTimingValues (DeviceObject);

 if (OldTiming)
  ExFreePool(OldTiming);

 return STATUS_SUCCESS;
}
Example #5
0
NTSTATUS PPJoy_Power (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 PDEVICE_EXTENSION  DeviceExtension;
 NTSTATUS           ntStatus;
 POWER_STATE		PowerState;
 POWER_STATE_TYPE	PowerType;
 PIO_STACK_LOCATION	Stack;

 PAGED_CODE ();

 PPJOY_DBGPRINT (FILE_POWER | PPJOY_FENTRY, ("Enter PPJoy_Power(DeviceObject=0x%p,Irp=0x%p)",DeviceObject,Irp) );

 DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

 ntStatus= PPJoy_EnterRequest (DeviceExtension);
 if (NT_SUCCESS(ntStatus))
 {
  Stack= IoGetCurrentIrpStackLocation (Irp);
  PowerType= Stack->Parameters.Power.Type;
  PowerState= Stack->Parameters.Power.State;

  if ((Stack->MinorFunction==IRP_MN_SET_POWER)&&
	  (PowerType==DevicePowerState)&&
	  (PowerState.DeviceState==PowerDeviceD0))
  {
   PPJOY_DBGPRINT (FILE_POWER|PPJOY_BABBLE, ("We got a device D0 power state request for our device. Set parallel port mode again") );

   /* Set the parallel port mode. */
   PPJoy_InitPortAndInterface (DeviceObject);
  }
 
  /* Must be called before IoSkipCurrentIrpStackLocation, else bugcheck */
  PoStartNextPowerIrp (Irp);
  /* Prepare IRP stack for next driver */
  IoSkipCurrentIrpStackLocation (Irp);

  /* We call PoCallDriver since this is a Power IRP */
  ntStatus=  PoCallDriver (GET_NEXT_DEVICE_OBJECT (DeviceObject),Irp);
 }
 else
 {
  /* Must be called even when the device is removed */
  PoStartNextPowerIrp (Irp);

  Irp->IoStatus.Information= 0;
  Irp->IoStatus.Status= ntStatus;
  IoCompleteRequest (Irp,IO_NO_INCREMENT);
 }

 PPJoy_LeaveRequest	(DeviceExtension);

 PPJOY_EXITPROC (FILE_POWER|PPJOY_FEXIT, "PPJOY_Power",ntStatus);
 return ntStatus;
}
//----------------------------------------------------------------------------------------------
//	AddDevice
//----------------------------------------------------------------------------------------------
NTSTATUS AddDevice(
	 IN PDRIVER_OBJECT	DriverObject
	,IN PDEVICE_OBJECT	DeviceObject )
{
	//	変数宣言
	PDEVICE_EXTENSION	DeviceExtension	= GET_MINIDRIVER_DEVICE_EXTENSION( DeviceObject );
	UCHAR				ThreadId;

	//	デバイス エクステンションの内容を初期化する
	RtlZeroMemory( DeviceExtension, sizeof( DEVICE_EXTENSION ) );

	//	I/O 要求制御
	DeviceExtension->DriverState	= Enable;
	DeviceExtension->DeviceState	= Disable;
	DeviceExtension->ReferenceCount	= 1;
	KeInitializeEvent( &DeviceExtension->ReferenceEnd, NotificationEvent, FALSE );

	//	ワーカ スレッド
	DeviceExtension->ThreadStateIo	= Disable;
	for( ThreadId = 0; ThreadId < ControllerCount; ThreadId ++ )
	{
		KeInitializeEvent(
			 &DeviceExtension->ThreadExitingIn[ThreadId]
			,SynchronizationEvent
			,FALSE );
		KeInitializeEvent(
			 &DeviceExtension->ThreadExitingOut[ThreadId]
			,SynchronizationEvent
			,FALSE );
	}

	//	IRP
	DeviceExtension->ThreadStateIdc	= Disable;
	KeInitializeEvent( &DeviceExtension->ThreadExitingIdc, SynchronizationEvent, FALSE );
	KeInitializeSpinLock( &DeviceExtension->LockIrp );

	//	USB
	DeviceExtension->NextDeviceObject	= GET_NEXT_DEVICE_OBJECT( DeviceObject );

	//	レポート
	KeInitializeSpinLock( &DeviceExtension->LockReport );

	//	デバイス エクステンションの初期化完了を通知する
	DeviceObject->Flags	&= ~DO_DEVICE_INITIALIZING;

	return( STATUS_SUCCESS );
}
Example #7
0
NTSTATUS PPJoy_LoadJoystickMapping (IN PDEVICE_OBJECT DeviceObject)
{
 NTSTATUS			ntStatus;
 PDEVICE_EXTENSION	DeviceExtension;

 PAGED_CODE();

 DeviceExtension= GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);

 if (DeviceExtension->Mapping)
 {
  PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_WARN, ("JoystickMapping already set - attempting to free memory") );
  ExFreePool(DeviceExtension->Mapping);
  DeviceExtension->Mapping= NULL;
 }
	 
 PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_BABBLE2, ("Attempting to read joystick mapping from device registry key") );
 DeviceExtension->Mapping= PPJoy_ReadDeviceMapping(DeviceObject,DeviceExtension->Config.JoyType);
 if(DeviceExtension->Mapping)
 {
  PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_BABBLE, ("Joystick mapping successfully read from the device registry") );
  return STATUS_SUCCESS;
 }

 PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_BABBLE2, ("Attempting to read joystick mapping from driver registry key") );
 DeviceExtension->Mapping= PPJoy_ReadDriverMapping(DeviceObject,DeviceExtension->Config.JoyType);
 if(DeviceExtension->Mapping)
 {
  PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_BABBLE, ("Joystick mapping successfully read from the driver registry") );
  return STATUS_SUCCESS;
 }
    
 PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_BABBLE2, ("Building default joystick mapping for device") );
 DeviceExtension->Mapping= PPJoy_BuildDefaultMapping(DeviceExtension->Config.JoyType);
 if(DeviceExtension->Mapping)
 {
  PPJOY_DBGPRINT (FILE_MAPPING|PPJOY_BABBLE, ("Joystick mapping successfully built manually") );
  return STATUS_SUCCESS;
 }

 return STATUS_UNSUCCESSFUL;
}
Example #8
0
void PPJoy_InitTimingValues (IN PDEVICE_OBJECT DeviceObject)
{
 PDEVICE_EXTENSION	DeviceExtension;
 LARGE_INTEGER		TickCount;

 PAGED_CODE();

 DeviceExtension= GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);

 if (DeviceExtension->Config.JoyType==IF_FMSBUDDYBOX)
 {
  PTIMING_FMSPPM	PPMTiming;
  PPPMBUDDYBOX		PPMParams;

  PPMTiming= (PTIMING_FMSPPM) DeviceExtension->Timing;
  PPMParams= &(DeviceExtension->Param.PPMBuddyBox);

  KeQueryPerformanceCounter(&TickCount);
  PPMParams->MaxPulseTicks.QuadPart= (TickCount.QuadPart*(PPMTiming->MaxPulseWidth/*us*/)/1000000);
  PPMParams->MinPulseTicks.QuadPart= (TickCount.QuadPart*(PPMTiming->MinPulseWidth/*us*/)/1000000);
  PPMParams->MinSyncTicks.QuadPart= (TickCount.QuadPart*(PPMTiming->MinSyncWidth/*us*/)/1000000);
 }
}
//----------------------------------------------------------------------------------------------
//	Power
//----------------------------------------------------------------------------------------------
NTSTATUS Power(
	 IN PDEVICE_OBJECT	DeviceObject
	,IN PIRP			Irp )
{
	//	変数宣言
	NTSTATUS			Status;
	PDEVICE_EXTENSION	DeviceExtension	= GET_MINIDRIVER_DEVICE_EXTENSION( DeviceObject );
	PIO_STACK_LOCATION	CurrentIrpStack;

	//	参照カウンタを加算する
	Status	= IncrementReference( DeviceExtension );
	if( !NT_SUCCESS( Status ) )
	{
		CompleteRequest( Irp, Status, 0 );
		return( Status );
	}

	//	マイナー ファンクションによって処理を振り分ける
	CurrentIrpStack	= IoGetCurrentIrpStackLocation( Irp );
	switch( CurrentIrpStack->MinorFunction )
	{
		case IRP_MN_SET_POWER:
			Status = SetPower( DeviceObject, DeviceExtension, Irp, CurrentIrpStack );
			break;

		default:
			//	IRP_MJ_POWER 要求を下位ドライバに送る
			Status	= SendPowerRequest( DeviceObject, Irp );
			break;
	}

	//	参照カウンタを減算する
	DecrementReference( DeviceExtension );

	return( Status );
}
Example #10
0
// *****************************************************************************
NTSTATUS  INTERNAL
    HGM_GetFeature
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   DeviceExtension;
    PIO_STACK_LOCATION  IrpStack;
    extern const int botones[];
    int prev;
    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_ReadReport(DeviceObject=0x%x,Irp=0x%x)", \
                    DeviceObject, Irp));

    /*
     * Get a pointer to the device extension.
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    /*
     * Get Stack location.
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * First check the size of the output buffer (there is no input buffer)
     */
    if( ((HID_XFER_PACKET*)Irp->UserBuffer)->reportBufferLen < 7 )
    {
        ntStatus = STATUS_BUFFER_TOO_SMALL;
    }

    if( DeviceExtension->fStarted == FALSE )
    {
        ntStatus = STATUS_DEVICE_NOT_READY ;
    }

    /*
     *  All the checking done so do device specific polling
     */
    if( NT_SUCCESS(ntStatus) )
    {
        PUCHAR ReportBuffer;
        unsigned short *Buttons;
        ReportBuffer = ((HID_XFER_PACKET*)Irp->UserBuffer)->reportBuffer;
        if(DeviceExtension->fetscan)
        {
          KeClearEvent(&(DeviceExtension->ScanReady));
          prev = DeviceExtension->psx.noAx;
          DeviceExtension->psx.noAx = 1;
          KeSetEvent(&(DeviceExtension->DoScan), 0, FALSE);
          KeWaitForSingleObject(&(DeviceExtension->ScanReady), UserRequest, KernelMode, FALSE, 0);
          DeviceExtension->psx.noAx = prev;
        };
        DeviceExtension->fetscan = 0;
        Buttons = (unsigned short*)ReportBuffer;
        #define ADD_BUTTON(a, b) (((a)>0) ? botones[(b)] : 0)
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.box, 0);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.cross, 1);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.circle, 2);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.triangle, 3);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.l1, 4);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.r1, 5);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.l2, 6);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.r2, 7);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.select, 8);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.start, 9);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.l3, 10);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.r3, 11);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.lf, 12);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.dn, 13);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.rt, 14);
        *Buttons |= ADD_BUTTON(DeviceExtension->psx.up, 15);
        ReportBuffer[2] = (UCHAR)DeviceExtension->DeviceID;
        ReportBuffer[3] = DeviceExtension->psx.lx;
        ReportBuffer[4] = DeviceExtension->psx.ly;
        Irp->IoStatus.Information = 8;
    } 
    else
    {
        Irp->IoStatus.Information = 0x0;
    }

    Irp->IoStatus.Status = ntStatus;


    HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT,  "HGM_ReadReport", ntStatus);

    return ntStatus;
} /* HGM_ReadReport */
Example #11
0
// *****************************************************************************
NTSTATUS  INTERNAL
    HGM_WriteReport
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   DeviceExtension;
    PIO_STACK_LOCATION  IrpStack;
    PUCHAR ReportBuffer;

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    /*
     * Get Stack location.
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * First check the size of the output buffer (there is no input buffer)
     */

    if( DeviceExtension->fStarted == FALSE )
    {
        ntStatus = STATUS_DEVICE_NOT_READY ;
    }

    /*
     *  All the checking done so do device specific polling
     */
    ReportBuffer = ((HID_XFER_PACKET*)Irp->UserBuffer)->reportBuffer;
    if( NT_SUCCESS(ntStatus) )
    {
        if(ReportBuffer[0] == 255)
        {
           Irp->IoStatus.Status = HGM_InitDevice(DeviceObject, Irp);
           return(Irp->IoStatus.Status);
        }
        if(ReportBuffer[0] == 2)
        {
           DeviceExtension->fetscan = 1;
           return(Irp->IoStatus.Status);
        };
        if(!DeviceExtension->psx.noFF)
        {
          DeviceExtension->psx.motorg = ReportBuffer[1];
          if(ReportBuffer[0] == 1)
            DeviceExtension->psx.motorc = 1;
          else
            DeviceExtension->psx.motorc = 0;
          DeviceExtension->querystill++;
        };
        if(DeviceExtension->querystill > 1000)
          KeSetEvent(&(DeviceExtension->DoScan), 0, FALSE);
        Irp->IoStatus.Information = sizeof(HID_XFER_PACKET);
    }
    else
    {
        Irp->IoStatus.Information = 0x0;
    }

    Irp->IoStatus.Status = ntStatus;

    return ntStatus;
} /* HGM_WriteReport */
Example #12
0
/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_InternalIoctl |
 *
 *          Process the Control IRPs sent to this device.
 *          <nl>This function cannot be pageable because reads/writes
 *          can be made at dispatch-level
 *
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS | success
 *  @rvalue   STATUS_NOT_SUPPORT | Irp function not supported
 *  @rvalue   ???            | ???
 *
 *****************************************************************************/
NTSTATUS EXTERNAL
    HGM_InternalIoctl
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   DeviceExtension;
    PIO_STACK_LOCATION  IrpStack;

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,   \
                   ("HGM_InternalIoctl(DeviceObject=0x%x,Irp=0x%x)", \
                    DeviceObject, Irp));

    /*
     *  Get a pointer to the current location in the Irp
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     *  Get a pointer to the device extension
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);


    ntStatus = HGM_IncRequestCount( DeviceExtension );
    if (!NT_SUCCESS (ntStatus))
    {
        /*
         *  Someone sent us another plug and play IRP after removed
         */

        HGM_DBGPRINT(FILE_PNP | HGM_ERROR,\
                       ("HGM_InternalIoctl: PnP IRP after device was removed\n"));
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = ntStatus;
    } else
    {
        switch(IrpStack->Parameters.DeviceIoControl.IoControlCode)
        {
                
            case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
                HGM_DBGPRINT(FILE_IOCTL | HGM_BABBLE, \
                               ("IOCTL_HID_GET_DEVICE_DESCRIPTOR"));
                ntStatus = HGM_GetDeviceDescriptor(DeviceObject, Irp);
                break;

            case IOCTL_HID_GET_REPORT_DESCRIPTOR:
                HGM_DBGPRINT(FILE_IOCTL | HGM_BABBLE, \
                               ("IOCTL_HID_GET_REPORT_DESCRIPTOR"));
                ntStatus = HGM_GetReportDescriptor(DeviceObject, Irp);
                break;

            case IOCTL_HID_READ_REPORT:
                HGM_DBGPRINT(FILE_IOCTL | HGM_BABBLE,\
                               ("IOCTL_HID_READ_REPORT"));
                ntStatus = HGM_ReadReport(DeviceObject, Irp);
                break;

            case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
                HGM_DBGPRINT(FILE_IOCTL | HGM_BABBLE,\
                               ("IOCTL_HID_GET_DEVICE_ATTRIBUTES"));
                ntStatus = HGM_GetAttributes(DeviceObject, Irp);
                break;

            case IOCTL_HID_GET_FEATURE:
                HGM_DBGPRINT(FILE_IOCTL | HGM_BABBLE,\
                               ("IOCTL_HID_GET_FEATURE_REPORT"));
                ntStatus = HGM_GetFeature(DeviceObject, Irp);
                break;

            case IOCTL_HID_WRITE_REPORT:
                HGM_DBGPRINT(FILE_IOCTL | HGM_BABBLE,\
                               ("IOCTL_HID_WRITE_REPORT"));
                ntStatus = HGM_WriteReport(DeviceObject, Irp);
                break;

            default:
                ntStatus = STATUS_NOT_SUPPORTED;
                break;
        }


        /*
         * Set real return status in Irp
         */
        Irp->IoStatus.Status = ntStatus;

        HGM_DecRequestCount( DeviceExtension );
    }


    if(ntStatus != STATUS_PENDING)
    {
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        /*
         * NOTE: Real return status set in Irp->IoStatus.Status
         */
        ntStatus = STATUS_SUCCESS;
    } else
    {
        /*
         * No reason why there should be a status pending
         */
        HGM_DBGPRINT(FILE_IOCTL | HGM_ERROR, \
                       ("HGM_InternalIoctl: Pending Status !"));
        IoMarkIrpPending( Irp );
    }

    HGM_EXITPROC(FILE_IOCTL | HGM_FEXIT_STATUSOK, "HGM_InternalIoctl", ntStatus);

    return ntStatus;
} /* HGM_InternalIoctl */
Example #13
0
NTSTATUS
    HGM_Game2HID
    (
    IN  OUT PUHIDGAME_INPUT_DATA    pHIDData,
    IN PDEVICE_OBJECT       DeviceObject
    )
{
    #define ADD_BUTTON(a, b) ((((a)>0) & (map[(b)] < 16)) ? botones[map[(b)]] : 0 )
    int Id = 1, i;
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    HIDGAME_INPUT_DATA  LocalBuffer;
    PDEVICE_EXTENSION   DeviceExtension;
    PUCHAR map;
    PUCHAR finder;
    PUCHAR axismap;

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);
    RtlZeroMemory( &LocalBuffer, sizeof( LocalBuffer ) );

    if(DeviceExtension->psx.ScanMode == 0) 
      KeSetEvent(&(DeviceExtension->DoScan), 0, FALSE);
    else
      DeviceExtension->querystill++;

    ntStatus = DeviceExtension->psx.laststatus;
    map = DeviceExtension->psx.buttonmap;

    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.box, 0);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.cross, 1);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.circle, 2);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.triangle, 3);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.l1, 4);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.r1, 5);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.l2, 6);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.r2, 7);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.select, 8);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.start, 9);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.l3, 10);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.r3, 11);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.lf, 12);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.dn, 13);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.rt, 14);
    LocalBuffer.Buttons |= ADD_BUTTON(DeviceExtension->psx.up, 15);

    if(DeviceExtension->psx.Psx2) {
      finder = (PUCHAR) &(DeviceExtension->psx);
      for(i=0; i<16; i++)
      {
        switch(map[i])
        {
             case 16:
               LocalBuffer.AnalogButtons[0] = ((-1) * (256+finder[i]))+511;
               break;
             case 17:
               LocalBuffer.AnalogButtons[1] = ((-1) * (256+finder[i]))+511;
               break;
             case 18:
               LocalBuffer.AnalogButtons[2] = ((-1) * (256+finder[i]))+511;
               break;
             case 19:
               LocalBuffer.AnalogButtons[3] = ((-1) * (256+finder[i]))+511;
               break;
        }
      }
    };

    axismap = (PUCHAR) &DeviceExtension->psx.Ejes;

    LocalBuffer.Axis[axismap[0]] = DeviceExtension->psx.lx;
    LocalBuffer.Axis[axismap[1]] = DeviceExtension->psx.ly;
    LocalBuffer.Axis[axismap[2]] = DeviceExtension->psx.ry;
    LocalBuffer.Axis[axismap[3]] = DeviceExtension->psx.rx;

    for(i=0;i<4; i++)
      if((LocalBuffer.Axis[i] >= DeviceExtension->psx.min) &&
           (LocalBuffer.Axis[i] <= DeviceExtension->psx.max))
         LocalBuffer.Axis[i] = 127;
    C_ASSERT( sizeof( *pHIDData ) == sizeof( LocalBuffer ) );
    RtlCopyMemory( pHIDData, &LocalBuffer, sizeof( LocalBuffer ) );

    return ntStatus;

} /* HGM_Game2HID */
Example #14
0
/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_GetDeviceDescriptor |
 *
 *          Respond to HIDCLASS IOCTL_HID_GET_DEVICE_DESCRIPTOR
 *          by returning a device descriptor
 *
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS | success
 *  @rvalue   STATUS_BUFFER_TOO_SMALL |  need more memory
 *
 *****************************************************************************/
NTSTATUS INTERNAL
    HGM_GetDeviceDescriptor
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PHID_DESCRIPTOR pHidDescriptor;        /* Hid descriptor for this device */
    USHORT   cbReport;
    UCHAR               rgGameReport[MAXBYTES_GAME_REPORT] ;
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   DeviceExtension;
    PIO_STACK_LOCATION  IrpStack;

    PAGED_CODE ();

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_GetDeviceDescriptor(DeviceObject=0x%x,Irp=0x%x)",
                    DeviceObject, Irp));

    /*
     * Get a pointer to the current location in the Irp
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * Get a pointer to the device extension
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    /*
     *  Get a pointer to the HID_DESCRIPTOR
     */
    pHidDescriptor =  (PHID_DESCRIPTOR) Irp->UserBuffer;


    if( IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*pHidDescriptor)  )
    {

        HGM_DBGPRINT(FILE_IOCTL | HGM_ERROR,\
                       ("HGM_GetDeviceDescriptor: OutBufferLength(0x%x) < sizeof(HID_DESCRIPTOR)(0x%x)", \
                        IrpStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(*pHidDescriptor)));


        ntStatus = STATUS_BUFFER_TOO_SMALL;
    } else
    {
        /*
         * Generate the report
         */
        ntStatus =  HGM_GenerateReport(DeviceObject, rgGameReport, &cbReport);

        if( NT_SUCCESS(ntStatus) )
        {
            RtlZeroMemory( pHidDescriptor, sizeof(*pHidDescriptor) );
            /*
             * Copy device descriptor to HIDCLASS buffer
             */
            pHidDescriptor->bLength                         = sizeof(*pHidDescriptor);
            pHidDescriptor->bDescriptorType                 = HID_HID_DESCRIPTOR_TYPE;
            pHidDescriptor->bcdHID                          = HID_REVISION;
            pHidDescriptor->bCountry                        = 0; /*not localized*/
            pHidDescriptor->bNumDescriptors                 = HGM_NUMBER_DESCRIPTORS;
            pHidDescriptor->DescriptorList[0].bReportType   = HID_REPORT_DESCRIPTOR_TYPE ;
            pHidDescriptor->DescriptorList[0].wReportLength = cbReport;

            /*
             * Report how many bytes were copied
             */
            Irp->IoStatus.Information = sizeof(*pHidDescriptor);
        } else
        {
            Irp->IoStatus.Information = 0x0;
        }
    }

    HGM_EXITPROC(FILE_IOCTL |HGM_FEXIT_STATUSOK, "HGM_GetDeviceDescriptor", ntStatus);

    return ntStatus;
} /* HGM_GetDeviceDescriptor */
Example #15
0
NTSTATUS PPJoy_Ctl_CreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 NTSTATUS			ntStatus;
 PDEVICE_EXTENSION	DeviceExtension;
 int				Count;


 PAGED_CODE ();

 /* If it is not for one of our control devices - pass on to HID.sys */
 if (GET_NEXT_DEVICE_OBJECT(DeviceObject))
 {
  PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_HIDHACK, ("Not a control device - passing request on to HID.sys (PPJoy_Ctl_CreateClose)") );
  return HIDMajorFunctions[IoGetCurrentIrpStackLocation(Irp)->MajorFunction](DeviceObject,Irp);
 }

 PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_FENTRY, ("PPJoy_Ctl_CreateClose(DeviceObject=0x%p,Irp=0x%p)",DeviceObject,Irp) );

 DeviceExtension= GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

 ntStatus= PPJoy_EnterRequest (DeviceExtension);
 if (!NT_SUCCESS(ntStatus))
  goto Exit;


 switch(IoGetCurrentIrpStackLocation(Irp)->MajorFunction)
 {
  case IRP_MJ_CREATE:
		DeviceExtension->OpenCount++;
		PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_BABBLE, ("PPJoy_CreateClose:IRP_MJ_CREATE - open count %d",DeviceExtension->OpenCount) );
		Irp->IoStatus.Information= 0;
		break;

  case IRP_MJ_CLOSE:
		if (DeviceExtension->OpenCount)
		 DeviceExtension->OpenCount--;
		PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_BABBLE, ("PPJoy_CreateClose:IRP_MJ_CLOSE - open count %d",DeviceExtension->OpenCount) );
		if ((!(DeviceExtension->OpenCount))&&(DeviceExtension->Config.JoyType==IF_IOCTL))
		{
		 /* Last open handle the Virtual stick closed. Reset device to idle state */
		 PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_BABBLE2, ("PPJoy_CreateClose: reseting virtual joystick position") );
         RtlZeroMemory (&(DeviceExtension->RawInput),sizeof(DeviceExtension->RawInput));
         for (Count=0;Count<MAX_ANALOG_RAW;Count++)
          DeviceExtension->RawInput.Analog[Count]= (PPJOY_AXIS_MIN+PPJOY_AXIS_MAX)/2;	/* Centre */
		}
		Irp->IoStatus.Information= 0;
		break;

  default:
		PPJOY_DBGPRINT (FILE_PPORTJOY|PPJOY_WARN, ("PPJoy_CreateClose:Not handled IrpStack->MajorFunction 0x%x",IoGetCurrentIrpStackLocation(Irp)->MajorFunction) );
		ntStatus= STATUS_INVALID_PARAMETER;
		break;
 }

Exit:
 /* Set the return status for operation in the IRP */
 Irp->IoStatus.Status= ntStatus;
 PPJoy_LeaveRequest	(DeviceExtension);

 /* Complete the IRP */
 IoCompleteRequest (Irp,IO_NO_INCREMENT);

 PPJOY_EXITPROC (FILE_PPORTJOY | PPJOY_FEXIT_STATUSOK, "PPJoy_Ctl_CreateClose", ntStatus);
 return ntStatus;
}
Example #16
0
NTSTATUS EXTERNAL
HbtnInternalIoctl(
    IN PDEVICE_OBJECT DevObj,
    IN PIRP           Irp
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION   devext = GET_MINIDRIVER_DEVICE_EXTENSION(DevObj);
    PIO_STACK_LOCATION  irpsp = IoGetCurrentIrpStackLocation(Irp);

    TEnter(Func,("(DevObj=%p,Irp=%p,IrpSp=%p,Ioctl=%s)\n",
                DevObj, Irp, irpsp,
                LookupName(irpsp->Parameters.DeviceIoControl.IoControlCode,
                           HidIoctlNames)));

    Irp->IoStatus.Information = 0;
    status = IoAcquireRemoveLock(&devext->RemoveLock, Irp);
    if (!NT_SUCCESS(status))
    {
        LogError(ERRLOG_DEVICE_REMOVED,
                 status,
                 UNIQUE_ERRID(0x10),
                 NULL,
                 NULL);
        TWarn(("received IRP after device was removed.\n"));
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }
    else if (!(devext->dwfHBtn & HBTNF_DEVICE_STARTED))
    {
        IoReleaseRemoveLock(&devext->RemoveLock, Irp);
        status = STATUS_DEVICE_NOT_READY;
        LogError(ERRLOG_DEVICE_NOT_STARTED,
                 status,
                 UNIQUE_ERRID(0x20),
                 NULL,
                 NULL);
        TWarn(("digitizer is not started.\n"));
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }
    else
    {
        switch(irpsp->Parameters.DeviceIoControl.IoControlCode)
        {
            case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
                status = GetDeviceDescriptor(devext, Irp);
                break;

            case IOCTL_HID_GET_REPORT_DESCRIPTOR:
                status = GetReportDescriptor(devext, Irp);
                break;

            case IOCTL_HID_READ_REPORT:
                status = ReadReport(devext, Irp);
                break;

            case IOCTL_HID_WRITE_REPORT:
                status = OemWriteReport(devext, Irp);
                break;

            case IOCTL_HID_GET_STRING:
                status = GetString(devext, Irp);
                break;

            case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
                status = GetAttributes(devext, Irp);
                break;

            case IOCTL_HID_ACTIVATE_DEVICE:
            case IOCTL_HID_DEACTIVATE_DEVICE:
                status = STATUS_SUCCESS;
                break;

            default:
                status = STATUS_NOT_SUPPORTED;
                LogError(ERRLOG_NOT_SUPPORTED,
                         status,
                         UNIQUE_ERRID(0x30),
                         NULL,
                         NULL);
                TWarn(("unsupported (IOCTL=%x).\n",
                           irpsp->Parameters.DeviceIoControl.IoControlCode));
                break;
        }

        if (status != STATUS_PENDING)
        {
            IoReleaseRemoveLock(&devext->RemoveLock, Irp);
            Irp->IoStatus.Status = status;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }
        else
        {
            IoMarkIrpPending(Irp);
        }
    }

    TExit(Func,("=%x\n", status));
    return status;
}       //HbtnInternalIoctl
Example #17
0
/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_GetReportDescriptor |
 *
 *          Respond to HIDCLASS IOCTL_HID_GET_REPORT_DESCRIPTOR
 *          by returning appropriate the report descriptor
 *
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS | success
 *  @rvalue   ???            | ???
 *
 *****************************************************************************/
NTSTATUS INTERNAL
    HGM_GetReportDescriptor
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    PDEVICE_EXTENSION     DeviceExtension;
    PIO_STACK_LOCATION    IrpStack;
    NTSTATUS              ntStatus;
    UCHAR                 rgGameReport[MAXBYTES_GAME_REPORT] ;
    USHORT                cbReport;

    PAGED_CODE ();

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_GetReportDescriptor(DeviceObject=0x%x,Irp=0x%x)",\
                    DeviceObject, Irp));

    /*
     * Get a pointer to the current location in the Irp
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * Get a pointer to the device extension
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);


    /*
     * Generate the report
     */
    ntStatus =  HGM_GenerateReport(DeviceObject, rgGameReport, &cbReport);

    if( NT_SUCCESS(ntStatus) )
    {
        if( cbReport >  (USHORT) IrpStack->Parameters.DeviceIoControl.OutputBufferLength )
        {
            ntStatus = STATUS_BUFFER_TOO_SMALL;

            HGM_DBGPRINT(FILE_IOCTL | HGM_ERROR,\
                           ("HGM_GetReportDescriptor: cbReport(0x%x) OutputBufferLength(0x%x)",\
                            cbReport, IrpStack->Parameters.DeviceIoControl.OutputBufferLength));

        } else
        {
            RtlCopyMemory( Irp->UserBuffer, rgGameReport, cbReport );
            /*
             * Report how many bytes were copied
             */
            Irp->IoStatus.Information = cbReport;
            ntStatus = STATUS_SUCCESS;
        }
    }

    HGM_EXITPROC(FILE_IOCTL |HGM_FEXIT_STATUSOK, "HGM_GetReportDescriptor", ntStatus);

    return ntStatus;
} /* HGM_GetReportDescriptor */
Example #18
0
/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_ReadReport |
 *
 *          Poll the gameport, remap the axis and button data and package
 *          into the defined HID report field.
 *          <nl>This routine cannot be pageable as HID can make reads at 
 *          dispatch-level.
 *
 *  @parm   IN PDRIVER_OBJECT | DeviceObject |
 *
 *          Pointer to the driver object
 *
 *  @parm   IN PIRP | Irp |
 *
 *          Pointer to an I/O Request Packet.
 *
 *  @rvalue   STATUS_SUCCESS  | success
 *  @rvalue   STATUS_DEVICE_NOT_CONNECTED | Device Failed to Quiesce 
 *                                          ( not connected )
 *  @rvalue   STATUS_TIMEOUT  | Could not determine exact transition time for 
 *                              one or more axis but not a failure.
 *
 *****************************************************************************/
NTSTATUS  INTERNAL
    HGM_ReadReport
    (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION   DeviceExtension;
    PIO_STACK_LOCATION  IrpStack;

    HGM_DBGPRINT(FILE_IOCTL | HGM_FENTRY,\
                   ("HGM_ReadReport(DeviceObject=0x%x,Irp=0x%x)", \
                    DeviceObject, Irp));

    /*
     * Get a pointer to the device extension.
     */

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

    /*
     * Get Stack location.
     */

    IrpStack = IoGetCurrentIrpStackLocation(Irp);

    /*
     * First check the size of the output buffer (there is no input buffer)
     */
    if( IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HIDGAME_INPUT_DATA) )
    {
        HGM_DBGPRINT(FILE_IOCTL | HGM_WARN,\
                       ("HGM_ReadReport: Buffer too small, output=0x%x need=0x%x", \
                        IrpStack->Parameters.DeviceIoControl.OutputBufferLength, 
                        sizeof(HIDGAME_INPUT_DATA) ) );

        ntStatus = STATUS_BUFFER_TOO_SMALL;
    }

    if( DeviceExtension->fStarted == FALSE )
    {
        ntStatus = STATUS_DEVICE_NOT_READY ;
    }

    /*
     *  All the checking done so do device specific polling
     */
    if( NT_SUCCESS(ntStatus) )
    {
        ntStatus = HGM_Game2HID( (PHIDGAME_INPUT_DATA)Irp->UserBuffer,
                                 DeviceObject );
        Irp->IoStatus.Information = sizeof(HIDGAME_INPUT_DATA);
    } 
    else
    {
        Irp->IoStatus.Information = 0x0;
    }

    Irp->IoStatus.Status = ntStatus;


    HGM_EXITPROC(FILE_IOCTL|HGM_FEXIT,  "HGM_ReadReport", ntStatus);

    return ntStatus;
} /* HGM_ReadReport */
Example #19
0
/*****************************************************************************
 *
 *  @doc    EXTERNAL
 *
 *  @func   NTSTATUS  | HGM_GenerateReport |
 *
 *          Generates a hid report descriptor for a n-axis, m-button joystick,
 *          depending on number of buttons and joy_hws_flags field.
 *
 *  @parm   IN PDEVICE_OBJECT | DeviceObject |
 *
 *          Pointer to the device object
 *
 *  @parm   IN OUT UCHAR * | rgGameReport[MAXBYTES_GAME_REPORT] |
 *
 *          Array that receives the HID report descriptor
 *
 *  @parm   OUT PUSHORT | pCbReport |
 *
 *          Address of a short integer that receives size of
 *          HID report descriptor.
 *
 *  @rvalue   STATUS_SUCCESS  | success
 *  @rvalue   STATUS_BUFFER_TOO_SMALL  | Need more memory for HID descriptor
 *
 *****************************************************************************/
NTSTATUS INTERNAL
    HGM_GenerateReport
    (
    IN PDEVICE_OBJECT       DeviceObject,
    OUT UCHAR               rgGameReport[MAXBYTES_GAME_REPORT],
    OUT PUSHORT             pCbReport
    )
{
    PDEVICE_EXTENSION   DeviceExtension;
    NTSTATUS    ntStatus;
    UCHAR       *pucReport;
    int Idx;
    UCHAR numaxes;

    PAGED_CODE();

    DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION(DeviceObject);

    pucReport = rgGameReport;

#define NEXT_BYTE( pReport, Data )   \
            *pReport++ = Data;

#define NEXT_LONG( pReport, Data )   \
            *(((LONG UNALIGNED*)(pReport))++) = Data;

#define ITEM_DEFAULT        0x00 /* Data, Array, Absolute, No Wrap, Linear, Preferred State, Has no NULL */
#define ITEM_VARIABLE       0x02 /* as ITEM_DEFAULT but value is a variable, not an array */
#define ITEM_HASNULL        0x40 /* as ITEM_DEFAULT but values out of range are considered NULL */
#define ITEM_ANALOG_AXIS    ITEM_VARIABLE
#define ITEM_DIGITAL_POV    (ITEM_VARIABLE|ITEM_HASNULL)
#define ITEM_BUTTON         ITEM_VARIABLE
#define ITEM_PADDING        0x01 /* Constant (nothing else applies) */

      switch(DeviceExtension->psx.type)
      {
        case 0:
        case 1:
        case 2:
          numaxes = 4;
          break;
        case 9:
          numaxes = 3;
          break;
        default:
          numaxes = 2;
      };

    /* USAGE_PAGE (Generic Desktop) */
    NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
    NEXT_BYTE(pucReport,    HID_USAGE_PAGE_GENERIC);

    /* USAGE (Joystick | GamePad ) */
    NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
    NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_GAMEPAD);

    /* Logical Min is the smallest value that could be produced by a poll */
    NEXT_BYTE(pucReport,    HIDP_GLOBAL_LOG_MIN_1);
    NEXT_BYTE(pucReport,    0 );

    /* Logical Max is the largest value that could be produced by a poll */
    NEXT_BYTE(pucReport,    HIDP_GLOBAL_LOG_MAX_2);
    NEXT_BYTE(pucReport,    255 );
    NEXT_BYTE(pucReport,    0 );

    NEXT_BYTE(pucReport,    HIDP_MAIN_COLLECTION);
    NEXT_BYTE(pucReport,    0x01 );

      NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
      NEXT_BYTE(pucReport,    HID_USAGE_PAGE_GENERIC);

      NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
      NEXT_BYTE(pucReport,    0x01);

      NEXT_BYTE(pucReport,    HIDP_MAIN_COLLECTION);
      NEXT_BYTE(pucReport,    0x00 );

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_X);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_Y);
        if(numaxes > 2)
        {
          NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
          NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_Z);
          if(numaxes > 3)
          {
            NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
            NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_RZ);
          };
        };
        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
        NEXT_BYTE(pucReport,    8);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
        NEXT_BYTE(pucReport,    numaxes);

        NEXT_BYTE(pucReport,    HIDP_MAIN_INPUT_1);
        NEXT_BYTE(pucReport,    ITEM_VARIABLE);

      NEXT_BYTE(pucReport,    HIDP_MAIN_ENDCOLLECTION);
      if(numaxes != 4)
      {
        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    0);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
        NEXT_BYTE(pucReport,    8);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
        NEXT_BYTE(pucReport,    4-numaxes);

        NEXT_BYTE(pucReport,    HIDP_MAIN_INPUT_1);
        NEXT_BYTE(pucReport,    ITEM_PADDING);
      };
// Digital Buttons
      NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
      NEXT_BYTE(pucReport,    HID_USAGE_PAGE_BUTTON); // Boton

      NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_MIN_1);
      NEXT_BYTE(pucReport,    1 );

      NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_MAX_1);
      NEXT_BYTE(pucReport,    16 );

      NEXT_BYTE(pucReport,    HIDP_GLOBAL_LOG_MAX_1);
      NEXT_BYTE(pucReport,    1 );

      NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
      NEXT_BYTE(pucReport,    0x1);

      NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
      NEXT_BYTE(pucReport,    16);

      NEXT_BYTE(pucReport,    HIDP_MAIN_INPUT_1);
      NEXT_BYTE(pucReport,    ITEM_VARIABLE);
// Analog Buttons
      if(DeviceExtension->psx.Psx2)
      {
      NEXT_BYTE(pucReport,    HIDP_GLOBAL_LOG_MAX_2);
      NEXT_BYTE(pucReport,    255);
      NEXT_BYTE(pucReport,    1);

      NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
      NEXT_BYTE(pucReport,    HID_USAGE_PAGE_GENERIC);

      NEXT_BYTE(pucReport,    HIDP_MAIN_COLLECTION);
      NEXT_BYTE(pucReport,    0x00 );

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_RX);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_RY);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_DIAL);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_GENERIC_SLIDER);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
        NEXT_BYTE(pucReport,    16);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
        NEXT_BYTE(pucReport,    4);

        NEXT_BYTE(pucReport,    HIDP_MAIN_INPUT_1);
        NEXT_BYTE(pucReport,    ITEM_VARIABLE);

      NEXT_BYTE(pucReport,    HIDP_MAIN_ENDCOLLECTION);

      } else {
        NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
        NEXT_BYTE(pucReport,    HID_USAGE_PAGE_GENERIC);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    0);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
        NEXT_BYTE(pucReport,    16);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
        NEXT_BYTE(pucReport,    4);

        NEXT_BYTE(pucReport,    HIDP_MAIN_INPUT_1);
        NEXT_BYTE(pucReport,    ITEM_PADDING);
      };

// FF

      NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
      NEXT_BYTE(pucReport,    HID_USAGE_PAGE_GENERIC);


      NEXT_BYTE(pucReport,    HIDP_MAIN_COLLECTION);
      NEXT_BYTE(pucReport,    0x00 );

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    1);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    2);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_LOG_MAX_2);
        NEXT_BYTE(pucReport,    255 );
        NEXT_BYTE(pucReport,    0 );

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
        NEXT_BYTE(pucReport,    8);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
        NEXT_BYTE(pucReport,    2);

        NEXT_BYTE(pucReport,    HIDP_MAIN_OUTPUT_1);
        NEXT_BYTE(pucReport,    ITEM_VARIABLE);

      NEXT_BYTE(pucReport,    HIDP_MAIN_ENDCOLLECTION);

// Info
      NEXT_BYTE(pucReport,    HIDP_GLOBAL_USAGE_PAGE_1);
      NEXT_BYTE(pucReport,    HID_USAGE_PAGE_GENERIC);


      NEXT_BYTE(pucReport,    HIDP_MAIN_COLLECTION);
      NEXT_BYTE(pucReport,    0x00 );

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    1);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    2);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    3);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    4);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    5);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    6);

        NEXT_BYTE(pucReport,    HIDP_LOCAL_USAGE_1);
        NEXT_BYTE(pucReport,    7);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_LOG_MAX_2);
        NEXT_BYTE(pucReport,    255 );
        NEXT_BYTE(pucReport,    0 );

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_SIZE);
        NEXT_BYTE(pucReport,    8);

        NEXT_BYTE(pucReport,    HIDP_GLOBAL_REPORT_COUNT_1);
        NEXT_BYTE(pucReport,    7);

        NEXT_BYTE(pucReport,    HIDP_MAIN_FEATURE_1);
        NEXT_BYTE(pucReport,    ITEM_VARIABLE);

      NEXT_BYTE(pucReport,    HIDP_MAIN_ENDCOLLECTION);

   /* End of collection,  We're done ! */
   NEXT_BYTE(pucReport,  HIDP_MAIN_ENDCOLLECTION);

#undef NEXT_BYTE
#undef NEXT_LONG

    if( pucReport - rgGameReport > MAXBYTES_GAME_REPORT)
    {
        ntStatus   = STATUS_BUFFER_TOO_SMALL;
        *pCbReport = 0x0;
        RtlZeroMemory(rgGameReport, sizeof(rgGameReport));
    } else
    {
        *pCbReport = (USHORT) (pucReport - rgGameReport);
        ntStatus = STATUS_SUCCESS;
    }

    HGM_DBGPRINT( FILE_HIDJOY | HGM_GEN_REPORT,\
                    ("HGM_GenerateReport: ReportSize=0x%x",\
                     *pCbReport) );

    HGM_EXITPROC(FILE_HIDJOY | HGM_FEXIT_STATUSOK, "HGM_GenerateReport", ntStatus);

    return ( ntStatus );
} /* HGM_GenerateReport */
Example #20
0
NTSTATUS PPJoy_Ctl_Power (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 NTSTATUS           ntStatus;
 POWER_STATE		PowerState;
 POWER_STATE_TYPE	PowerType;
 PIO_STACK_LOCATION	Stack;
 PDEVICE_EXTENSION	DeviceExtension;

 PAGED_CODE ();

 /* If it is not for one of our control devices - pass on to HID.sys */
 if (GET_NEXT_DEVICE_OBJECT(DeviceObject))
 {
  PPJOY_DBGPRINT (FILE_POWER|PPJOY_HIDHACK, ("Not a control device - passing request on to HID.sys (PPJoy_Ctl_Power)") );
  return HIDMajorFunctions[IoGetCurrentIrpStackLocation(Irp)->MajorFunction](DeviceObject,Irp);
 }

 PPJOY_DBGPRINT (FILE_POWER | PPJOY_FENTRY, ("Enter PPJoy_Ctl_Power(DeviceObject=0x%p,Irp=0x%p)",DeviceObject,Irp) );

 DeviceExtension = GET_MINIDRIVER_DEVICE_EXTENSION (DeviceObject);

 ntStatus= PPJoy_EnterRequest (DeviceExtension);
 if (NT_SUCCESS(ntStatus))
 {
  Stack= IoGetCurrentIrpStackLocation (Irp);
  PowerType= Stack->Parameters.Power.Type;
  PowerState= Stack->Parameters.Power.State;
  PPJOY_DBGPRINT (FILE_POWER|PPJOY_BABBLE, ("Received Power IRP %s",PowerMinorFunctionString(Stack->MinorFunction)) );

  switch (Stack->MinorFunction)
  {
   case IRP_MN_SET_POWER:
		PPJOY_DBGPRINT (FILE_POWER|PPJOY_BABBLE, ("Request to set %s state to %s",					\
					((PowerType==SystemPowerState)?"System":"Device"),								\
                     ((PowerType==SystemPowerState)?DbgSystemPowerString(PowerState.SystemState):	\
					 DbgDevicePowerString(PowerState.DeviceState))) );

		if ((PowerType==DevicePowerState)||(PowerType==SystemPowerState))
         ntStatus= STATUS_SUCCESS;
		break;

   case IRP_MN_QUERY_POWER:
		ntStatus= STATUS_SUCCESS;
		break;

   case IRP_MN_WAIT_WAKE:
   case IRP_MN_POWER_SEQUENCE:
   default:
		ntStatus= STATUS_NOT_SUPPORTED;
        break;
  }
 }

 /* Must be before IoCompleteRequest(), else bugcheck! */
 PoStartNextPowerIrp (Irp);

 /* We are the lowest level driver for this device, complete IRP */
 if (ntStatus!=STATUS_NOT_SUPPORTED)
  Irp->IoStatus.Status= ntStatus;
 IoCompleteRequest (Irp,IO_NO_INCREMENT);
 
 PPJoy_LeaveRequest	(DeviceExtension);

 PPJOY_EXITPROC (FILE_POWER|PPJOY_FEXIT, "PPJOY_Ctl_Power",ntStatus);
 return ntStatus;
}