|
|
//==========================================================================
//
// 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; };
|