//************************************************************************** // // 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 //===========================================================================