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; }
// ***************************************************************************** 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 */
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
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; }
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 ); }
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; }
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 ); }
// ***************************************************************************** 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 */
// ***************************************************************************** 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 */
/***************************************************************************** * * @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 */
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 */
/***************************************************************************** * * @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 */
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; }
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
/***************************************************************************** * * @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 */
/***************************************************************************** * * @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 */
/***************************************************************************** * * @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 */
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; }