205 lines
7.4 KiB
C
205 lines
7.4 KiB
C
//==========================================================================
|
|
//
|
|
// Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// File: fixbtn.c
|
|
// Content: Code to overwrite the OEMData for SideWinder USB devices
|
|
// with values containing the correct number of buttons.
|
|
//
|
|
//
|
|
//==========================================================================
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <windows.h>
|
|
#include <regstr.h>
|
|
#include <aclapi.h>
|
|
|
|
#define TYPE_COUNT 6
|
|
|
|
struct
|
|
{
|
|
TCHAR tszKeyName[18];
|
|
BYTE rgbOEMData[8];
|
|
}
|
|
c_Types[TYPE_COUNT] = {
|
|
// Type key name OEMData to be set
|
|
TEXT("VID_045E&PID_001A"), { 0x00,0x00,0x08,0x10,0x08,0x00,0x00,0x00 }, // Precision Wheel
|
|
TEXT("VID_045E&PID_001B"), { 0x03,0x00,0x08,0x10,0x08,0x00,0x00,0x00 }, // FF 2
|
|
TEXT("VID_045E&PID_0026"), { 0x20,0x00,0x00,0x10,0x09,0x00,0x00,0x00 }, // Gamepad Pro
|
|
TEXT("VID_045E&PID_0034"), { 0x00,0x00,0x08,0x10,0x08,0x00,0x00,0x00 }, // FF Wheel 2
|
|
TEXT("VID_045E&PID_0038"), { 0x03,0x00,0x08,0x10,0x08,0x00,0x00,0x00 }, // Precision 2
|
|
TEXT("VID_045E&PID_0008"), { 0x03,0x00,0x08,0x10,0x0A,0x00,0x00,0x00 } // Precision Pro
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int WINAPI WinMain
|
|
(
|
|
HINSTANCE hInstance, // handle to current instance
|
|
HINSTANCE hPrevInstance, // handle to previous instance
|
|
LPSTR lpCmdLine, // pointer to command line
|
|
int nCmdShow // window show state
|
|
)
|
|
{
|
|
LONG lRc;
|
|
HKEY hkOEM;
|
|
int KeysUnwritten = TYPE_COUNT;
|
|
DWORD dwDisposition;
|
|
SECURITY_DESCRIPTOR SecurityDesc;
|
|
SID_IDENTIFIER_AUTHORITY authority = SECURITY_WORLD_SID_AUTHORITY;
|
|
EXPLICIT_ACCESS ExplicitAccess;
|
|
SECURITY_ATTRIBUTES sa;
|
|
PSECURITY_ATTRIBUTES pSA = NULL;
|
|
PSID pSid = NULL;
|
|
PACL pACL = NULL;
|
|
|
|
// If we're on any form of NT, set up all the things necessary to get
|
|
// everyone access to these keys.
|
|
// Also don't update the Precision Pro
|
|
if( ((int)GetVersion()) >= 0 )
|
|
{
|
|
HMODULE hAdvApiDLL = LoadLibrary( TEXT("ADVAPI32.DLL") );
|
|
|
|
if( hAdvApiDLL )
|
|
{
|
|
typedef VOID (WINAPI * DYNAMICBUILDTRUSTEEWITHSIDA) (PTRUSTEE_A pTrustee, PSID pSid);
|
|
|
|
typedef DWORD (WINAPI * DYNAMICSETENTRIESINACLA)
|
|
(ULONG cCountOfExplicitEntries, PEXPLICIT_ACCESS_A pListOfExplicitEntries, PACL OldAcl, PACL * NewAcl );
|
|
|
|
DYNAMICBUILDTRUSTEEWITHSIDA DynamicBuildTrusteeWithSidA;
|
|
DYNAMICSETENTRIESINACLA DynamicSetEntriesInAclA;
|
|
|
|
DynamicBuildTrusteeWithSidA = (DYNAMICBUILDTRUSTEEWITHSIDA)GetProcAddress( hAdvApiDLL, TEXT("BuildTrusteeWithSidA") );
|
|
DynamicSetEntriesInAclA = (DYNAMICSETENTRIESINACLA)GetProcAddress( hAdvApiDLL, TEXT("SetEntriesInAclA") );
|
|
|
|
if( DynamicBuildTrusteeWithSidA && DynamicSetEntriesInAclA )
|
|
{
|
|
DWORD dwErr;
|
|
|
|
// Describe the access we want to create the key with
|
|
ZeroMemory (&ExplicitAccess, sizeof(ExplicitAccess) );
|
|
ExplicitAccess.grfAccessPermissions = KEY_QUERY_VALUE | KEY_SET_VALUE
|
|
| KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS
|
|
| KEY_NOTIFY | KEY_CREATE_LINK
|
|
| DELETE | READ_CONTROL
|
|
| WRITE_DAC | WRITE_OWNER;
|
|
ExplicitAccess.grfAccessMode = SET_ACCESS; // discard any existing AC info
|
|
ExplicitAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
|
|
|
if (AllocateAndInitializeSid(
|
|
&authority,
|
|
1,
|
|
SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0,
|
|
&pSid
|
|
))
|
|
{
|
|
DynamicBuildTrusteeWithSidA(&(ExplicitAccess.Trustee), pSid );
|
|
|
|
dwErr = DynamicSetEntriesInAclA( 1, &ExplicitAccess, NULL, &pACL );
|
|
|
|
if( dwErr == ERROR_SUCCESS )
|
|
{
|
|
if( InitializeSecurityDescriptor( &SecurityDesc, SECURITY_DESCRIPTOR_REVISION ) )
|
|
{
|
|
if( SetSecurityDescriptorDacl( &SecurityDesc, TRUE, pACL, FALSE ) )
|
|
{
|
|
// Initialize a security attributes structure.
|
|
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
|
|
sa.lpSecurityDescriptor = &SecurityDesc;
|
|
sa.bInheritHandle = TRUE;// Use the security attributes to create a key.
|
|
|
|
pSA = &sa;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeLibrary( hAdvApiDLL );
|
|
}
|
|
|
|
// and don't write the Precision Pro key.
|
|
KeysUnwritten--;
|
|
}
|
|
|
|
lRc = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE, // handle of an open key
|
|
REGSTR_PATH_JOYOEM, // address of subkey name
|
|
0, // reserved
|
|
NULL, // address of class string
|
|
REG_OPTION_NON_VOLATILE, // special options flag
|
|
KEY_WRITE, // desired security access
|
|
pSA, // address of key security structure
|
|
&hkOEM, // address of buffer for opened handle
|
|
&dwDisposition // address of disposition value buffer
|
|
);
|
|
|
|
if( lRc == ERROR_SUCCESS )
|
|
{
|
|
int Idx;
|
|
HKEY hkType;
|
|
|
|
for( Idx = KeysUnwritten-1; Idx >= 0; Idx-- )
|
|
{
|
|
lRc = RegCreateKeyEx(
|
|
hkOEM, // handle of an open key
|
|
c_Types[Idx].tszKeyName, // address of subkey name
|
|
0, // reserved
|
|
NULL, // address of class string
|
|
REG_OPTION_NON_VOLATILE, // special options flag
|
|
KEY_WRITE, // desired security access
|
|
pSA, // address of key security structure
|
|
&hkType, // address of buffer for opened handle
|
|
&dwDisposition // address of disposition value buffer
|
|
);
|
|
if( lRc == ERROR_SUCCESS )
|
|
{
|
|
lRc = RegSetValueEx( hkType, REGSTR_VAL_JOYOEMDATA, 0,
|
|
REG_BINARY, c_Types[Idx].rgbOEMData, sizeof( c_Types[0].rgbOEMData ) );
|
|
|
|
if( lRc == ERROR_SUCCESS )
|
|
{
|
|
KeysUnwritten--;
|
|
}
|
|
|
|
RegCloseKey( hkType );
|
|
}
|
|
}
|
|
|
|
RegCloseKey( hkOEM );
|
|
|
|
}
|
|
|
|
|
|
//Cleanup pACL
|
|
if( pACL != NULL )
|
|
{
|
|
LocalFree( pACL );
|
|
}
|
|
|
|
//Cleanup pSid
|
|
if( pSid != NULL )
|
|
{
|
|
FreeSid( pSid );
|
|
}
|
|
|
|
|
|
|
|
if( KeysUnwritten )
|
|
{
|
|
MessageBox( 0, TEXT( "Update incomplete" ), TEXT( "Button fix" ), MB_ICONEXCLAMATION );
|
|
}
|
|
else
|
|
{
|
|
MessageBox( 0, TEXT( "Update OK" ), TEXT( "Button fix" ), 0 );
|
|
}
|
|
|
|
return KeysUnwritten;
|
|
};
|