|
|
//**************************************************************************
//
// MSGAMIO.H -- Xena Gaming Project
//
// Version 2.XX
//
// Copyright (c) 1997 Microsoft Corporation. All rights reserved.
//
// @doc
// @header MSGAMIO.H | Global includes and definitions for gameport driver interface
//**************************************************************************
#ifndef __MSGAMIO_H__
#define __MSGAMIO_H__
#ifdef SAITEK
#define MSGAMIO_NAME "SAIIO"
#else
#define MSGAMIO_NAME "MSGAMIO"
#endif
//---------------------------------------------------------------------------
// Version Information
//---------------------------------------------------------------------------
#define MSGAMIO_Major 0x02
#define MSGAMIO_Minor 0x00
#define MSGAMIO_Build 0x00
#define MSGAMIO_Version_Rc MSGAMIO_Major,MSGAMIO_Minor,0,MSGAMIO_Build
#define MSGAMIO_Version_Int ((MSGAMIO_Build << 16)+(MSGAMIO_Major << 8)+(MSGAMIO_Minor))
#define MSGAMIO_Version_Str "2.00.00\0"
#define MSGAMIO_Copyright_Str "Copyright � Microsoft Corporation, 1998\0"
#ifdef SAITEK
#define MSGAMIO_Company_Str "SaiTek Corporation\0"
#define MSGAMIO_Product_Str "SaiTek Gameport Driver Interface\0"
#ifdef WIN_NT
#define MSGAMIO_Filename_Str "Saiio.Sys\0"
#else
#define MSGAMIO_Filename_Str "Saiio.Vxd\0"
#endif
#else
#define MSGAMIO_Company_Str "Microsoft Corporation\0"
#define MSGAMIO_Product_Str "SideWinder Gameport Driver Interface\0"
#ifdef WIN_NT
#define MSGAMIO_Filename_Str "Msgamio.Sys\0"
#else
#define MSGAMIO_Filename_Str "Msgamio.Vxd\0"
#endif
#endif
//**************************************************************************
#ifndef RC_INVOKED // Skip Rest of File
//**************************************************************************
//---------------------------------------------------------------------------
// Global Limits
//---------------------------------------------------------------------------
#define MAX_MSGAMIO_SERVERS 4
#define MAX_MSGAMIO_CLIENTS 16
//---------------------------------------------------------------------------
// Transaction Types
//---------------------------------------------------------------------------
typedef enum { // @enum MSGAMIO_TRANSACTIONS | Device transaction types
MSGAMIO_TRANSACT_NONE, // @emem No transaction type
MSGAMIO_TRANSACT_RESET, // @emem Reset transaction type
MSGAMIO_TRANSACT_DATA, // @emem Data transaction type
MSGAMIO_TRANSACT_ID, // @emem Id transaction type
MSGAMIO_TRANSACT_STATUS, // @emem Status transaction type
MSGAMIO_TRANSACT_SPEED, // @emem Speed transaction type
MSGAMIO_TRANSACT_GODIGITAL, // @emem GoDigital transaction type
MSGAMIO_TRANSACT_GOANALOG // @emem GoAnalog transaction type
} MSGAMIO_TRANSACTION;
//---------------------------------------------------------------------------
// Types
//---------------------------------------------------------------------------
#ifndef STDCALL
#define STDCALL _stdcall
#endif
//---------------------------------------------------------------------------
// GUIDs
//---------------------------------------------------------------------------
#ifndef GUID_DEFINED
#define GUID_DEFINED
typedef struct { #pragma pack (1)
unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; #pragma pack()
} GUID, *PGUID;
#else
typedef GUID *PGUID;
#endif // GUID_DEFINED
__inline BOOLEAN STDCALL IsGUIDEqual (PGUID pGuid1, PGUID pGuid2) { ULONG i = sizeof(GUID); PUCHAR p1 = (PUCHAR)pGuid1; PUCHAR p2 = (PUCHAR)pGuid2;
while (i--) if (*p1++ != *p2++) return (FALSE); return (TRUE); }
//---------------------------------------------------------------------------
// Server GUIDs
//---------------------------------------------------------------------------
#ifdef SAITEK
#define MSGAMIO_MSGAME_GUID \
{0xcaca0c60,0xe40a,0x11d1,0x99,0x6f,0x44,0x45,0x53,0x54,0x00,0x01} #define MSGAMIO_GCKERNEL_GUID \
{0xcaca0c61,0xe40a,0x11d1,0x99,0x6f,0x44,0x45,0x53,0x54,0x00,0x01} #else
#define MSGAMIO_MSGAME_GUID \
{0xb9292380,0x628a,0x11d1,0xaa,0xa5,0x04,0x76,0xa6,0x00,0x00,0x00} #define MSGAMIO_GCKERNEL_GUID \
{0x95e69580,0x97d5,0x11d1,0x99,0x6f,0x00,0xa0,0x24,0xbe,0xbf,0xf5} #endif
//---------------------------------------------------------------------------
// Client GUIDs
//---------------------------------------------------------------------------
#define MSGAMIO_MIDAS_GUID \
{0x12D41A36,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_JUNO_GUID \
{0xC948CE81,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_JOLT_GUID \
{0xC948CE82,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_SHAZAM_GUID \
{0xC948CE83,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_FLASH_GUID \
{0xC948CE84,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_TILT_GUID \
{0xC948CE86,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_TILTUSB_GUID \
{0xC948CE89,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#define MSGAMIO_APOLLO_GUID \
{0xC948CE88,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF}
#ifdef SAITEK
#define MSGAMIO_LEDZEP_GUID \
{0xcaca0c62,0xe40a,0x11d1,0x99,0x6f,0x44,0x45,0x53,0x54,0x00,0x01} #else
#define MSGAMIO_LEDZEP_GUID \
{0xC948CE87,0x9026,0x11d0,0x9F,0xFE,0x00,0xA0,0xC9,0x11,0xF5,0xAF} #endif
//---------------------------------------------------------------------------
// Macros
//---------------------------------------------------------------------------
#ifndef STILL_TO_DO
#define STD0(txt) #txt
#define STD1(txt) STD0(txt)
#define STILL_TO_DO(txt) message("\nSTILL TO DO: "__FILE__"("STD1(__LINE__)"): "#txt"\n")
#endif
//---------------------------------------------------------------------------
// Control Codes
//---------------------------------------------------------------------------
#define IOCTL_INTERNAL_MSGAMIO_BASE 0xB00
#define IOCTL_INTERNAL_MSGAMIO_UNLOAD \
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_INTERNAL_MSGAMIO_BASE+0,METHOD_NEITHER,FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MSGAMIO_CONNECT_SERVER \
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_INTERNAL_MSGAMIO_BASE+1,METHOD_NEITHER,FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MSGAMIO_DISCONNECT_SERVER \
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_INTERNAL_MSGAMIO_BASE+2,METHOD_NEITHER,FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MSGAMIO_CONNECT_CLIENT \
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_INTERNAL_MSGAMIO_BASE+3,METHOD_NEITHER,FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MSGAMIO_DISCONNECT_CLIENT \
CTL_CODE(FILE_DEVICE_UNKNOWN,IOCTL_INTERNAL_MSGAMIO_BASE+4,METHOD_NEITHER,FILE_ANY_ACCESS)
//---------------------------------------------------------------------------
// Structures
//---------------------------------------------------------------------------
typedef struct { // @struct DRIVERSERVICES | Device services table
// @field ULONG | Size | Size of structure
ULONG Size;
// @field GUID | Server | Server GUID
GUID Server;
// @field VOID (*Connect)(ConnectInfo) | ConnectInfo | Connection service procedure
VOID (STDCALL *Connect)(PVOID ConnectInfo);
// @field VOID (*Disconnect)(ConnectInfo) | ConnectInfo | Disconnection service procedure
VOID (STDCALL *Disconnect)(PVOID ConnectInfo);
// @field VOID (*Transact)(PacketInfo) | PacketInfo | Transaction hook procedure
VOID (STDCALL *Transact)(PVOID PacketInfo);
// @field VOID (*Packet)(PacketData) | PacketData | Packet hook procedure
VOID (STDCALL *Packet)(PVOID PacketData);
// @field NTSTATUS (*ForceReset)(VOID) | None | Reset force feedback device
NTSTATUS (STDCALL *ForceReset)(VOID);
// @field NTSTATUS (*ForceId)(IdString) | IdString | Gets force feedback id string
NTSTATUS (STDCALL *ForceId)(PVOID IdString);
// @field NTSTATUS (*ForceStatus)(Status) | Status | Gets raw force feedback status
NTSTATUS (STDCALL *ForceStatus)(PVOID Status); // @field NTSTATUS (*ForceAckNak)(AckNak) | AckNak | Gets force feedback ack nak
NTSTATUS (STDCALL *ForceAckNak)(PUCHAR AckNak);
// @field NTSTATUS (*ForceNakAck)(NakAck) | NakAck | Gets force feedback nak ack
NTSTATUS (STDCALL *ForceNakAck)(PUCHAR NakAck);
// @field NTSTATUS (*ForceSync)(Sync) | Sync | Reads byte from gameport to sync
NTSTATUS (STDCALL *ForceSync)(PUCHAR Sync);
// @field ULONG (*Register)(Device, UnitId) | Device, UnitId | Registers device with Gckernel
ULONG (STDCALL *Register)(PGUID Device, ULONG UnitId);
// @field VOID (*Unregister) (Handle) | Handle | Unregisters device with Gckernel
VOID (STDCALL *Unregister) (ULONG Handle);
// @field VOID (*Notify) (Handle, DevInfo, PollData) | Handle, DevInfo, PollData | Sends packet for Gckernel processing
VOID (STDCALL *Notify) (ULONG Handle, PVOID DevInfo, PVOID PollData);
} MSGAMIO_CONNECTION, *PMSGAMIO_CONNECTION;
//---------------------------------------------------------------------------
// Global Procedures
//---------------------------------------------------------------------------
// @func NTSTATUS | MSGAMIO_DoConnection | Calls MSGAMIO internal control interface
// @parm ULONG | ControlCode | IO control code
// @parm PMSGAMIO_CONNECTION | ConnectInfo | Connection structure
// @rdesc Returns NT status code
// @comm Inline function
//---------------------------------------------------------------------------
// Private Procedures
//---------------------------------------------------------------------------
NTSTATUS STDCALL MSGAMIO_DoConnection (ULONG ControlCode, PMSGAMIO_CONNECTION InputBuffer);
//===========================================================================
// WDM Interface
//===========================================================================
#ifdef _NTDDK_
#ifdef SAITEK
#define MSGAMIO_DEVICE_NAME TEXT("\\Device\\Saiio")
#define MSGAMIO_DEVICE_NAME_U L"\\Device\\Saiio"
#define MSGAMIO_SYMBOLIC_NAME TEXT("\\DosDevices\\Saiio")
#define MSGAMIO_SYMBOLIC_NAME_U L"\\DosDevices\\Saiio"
#else
#define MSGAMIO_DEVICE_NAME TEXT("\\Device\\MsGamio")
#define MSGAMIO_DEVICE_NAME_U L"\\Device\\MsGamio"
#define MSGAMIO_SYMBOLIC_NAME TEXT("\\DosDevices\\MsGamio")
#define MSGAMIO_SYMBOLIC_NAME_U L"\\DosDevices\\MsGamio"
#endif
//---------------------------------------------------------------------------
__inline NTSTATUS STDCALL MSGAMIO_Connection (ULONG ControlCode, PMSGAMIO_CONNECTION ConnectInfo) //---------------------------------------------------------------------------
{ NTSTATUS ntStatus; PIRP pIrp; KEVENT Event; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; UNICODE_STRING ObjectName; IO_STATUS_BLOCK IoStatus;
//
// Validate parameters
//
ASSERT (ConnectInfo); ASSERT (KeGetCurrentIrql()<=DISPATCH_LEVEL);
//
// Retrieve the driver device object
//
RtlInitUnicodeString (&ObjectName, MSGAMIO_DEVICE_NAME_U); ntStatus = IoGetDeviceObjectPointer (&ObjectName, FILE_ALL_ACCESS, &FileObject, &DeviceObject); if (!NT_SUCCESS(ntStatus)) { KdPrint (("%s_Connection: IoGetDeviceObjectPointer (%ws) failed, status = 0x%X", MSGAMIO_NAME, ObjectName.Buffer, ntStatus)); return (ntStatus); } //
// Initialize the completion event
//
KeInitializeEvent (&Event, SynchronizationEvent, FALSE);
//
// Allocate internal I/O IRP
//
pIrp = IoBuildDeviceIoControlRequest (ControlCode, DeviceObject, ConnectInfo, sizeof (MSGAMIO_CONNECTION), NULL, 0, TRUE, &Event, &IoStatus); //
// Call MsGamIo synchronously
//
KdPrint (("%s_Connection: Calling %s (%lu)\n", MSGAMIO_NAME, MSGAMIO_NAME, ControlCode)); ntStatus = IoCallDriver (DeviceObject, pIrp); if (ntStatus == STATUS_PENDING) ntStatus = KeWaitForSingleObject (&Event, Suspended, KernelMode, FALSE, NULL);
//
// Check asynchronous status
//
if (!NT_SUCCESS (ntStatus)) KdPrint (("%s_Connection: %s (%lu) failed, Status = %X\n", MSGAMIO_NAME, MSGAMIO_NAME, ControlCode, ntStatus));
//
// Free file object associated with device
//
ObDereferenceObject (FileObject);
//
// Return status
//
return (ntStatus); }
#endif
//===========================================================================
// VXD Definitions
//===========================================================================
#ifndef _NTDDK_
#ifdef SAITEK
#define MSGAMIO_DEVICE_ID 0x11EF
#else
#define MSGAMIO_DEVICE_ID 0x1EF
#endif
#pragma warning (disable:4003)
Begin_Service_Table (MSGAMIO) Declare_Service (MSGAMIO_Service, LOCAL) End_Service_Table (MSGAMIO) #pragma warning (default:4003)
//---------------------------------------------------------------------------
__inline NTSTATUS STDCALL MSGAMIO_Connection (ULONG ControlCode, PMSGAMIO_CONNECTION ConnectInfo) //---------------------------------------------------------------------------
{ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
//
// First check if Vxd present
//
if (ConnectInfo) { _asm stc _asm xor eax, eax _asm xor ebx, ebx VxDCall (MSGAMIO_Service); _asm { jc Failure _asm mov [ntStatus], eax Failure: } }
if (!NT_SUCCESS(ntStatus)) KdPrint (("%s_Connection Failed to Find %s", MSGAMIO_NAME, MSGAMIO_Filename_Str));
//
// Then call for service
//
if (NT_SUCCESS(ntStatus)) { _asm mov eax, ControlCode _asm mov ebx, ConnectInfo VxDCall (MSGAMIO_Service); _asm mov [ntStatus], eax if (!NT_SUCCESS(ntStatus)) KdPrint (("%s_Connection Failed Service Call %ld", MSGAMIO_NAME, ControlCode)); }
//
// Return status
//
return (ntStatus); }
#endif // _NTDDK_
//**************************************************************************
#endif // RC_INVOKED // Skip Rest of File
//**************************************************************************
#endif // __MSGAMIO_H__
//===========================================================================
// End
//===========================================================================
|