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