This is alphalock.c in view mode; [Download] [Up]
/* ** ** NAME ** alphalock -- disable/enable AlphaLock (Command-Shift) for ** NeXT hardware running NeXTSTEP ** Release 2.1, 2.2, 3.0, 3.0J, 3.1, or 3.2. ** ** ** = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ** ** UPDATED INFO ** ** Turns out that you don't need to do this patching stuff ** ** (at least not for higher releases of NeXTSTEP). You ** ** will only see command-shift being treated as shift-lock ** ** if no *other* key is given that function. So, just use ** ** /NextDeveloper/Demos/Keyboard.app ** ** to create a key-mapping where the function of shift-lock ** ** is assigned to some key combination that you will never ** ** ever hit. ** ** ** ** Due to this, which I consider a superior solution anyway, ** ** I doubt I'll ever be doing any new versions of this ** ** alphalock program. Garance/Jan 27/1997 ** ** = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ** ** COMPILE: ** cc -DDEBUG -s -O -o alphalock alphalock.c ** or cc -s -O -object -o alphalock alphalock.c ** ** COMMENTS: ** Must be run as root! ** Note that you'd have to compile this on the "least recent" ** system you're still using (assuming you want to use one ** binary on all the systems you're running). ** ** sum of /sdmach used to base this patch: ** Release 2.1 -> 09308 692 ** Release 2.2 -> 19164 707 ** Release 3.0 -> 40389 784 ** Release 3.1 -> 32892 806 ** Release 3.2 -> 57530 762 ** ** For those technically(?) inclined: check "_CalcModBit" (using ** otool) in /sdmach and look for code surrounding "_alphaLock"! ** hint: otool -t -V -p _CalcModBit /sdmach | more ** ** AUTHOR ** Felix A. Lugo (original version, supported NS 2.1) ** coco@ihcoco.att.com ** Garance A Drosehn (added support for NS 2.2, 3.0, 3.1) ** (added "enable" and "disable" parameters) ** (added support for NS 3.2) ** gad@eclipse.its.rpi.edu */ #define EXPORT_BOOLEAN #include <sys/boolean.h> // <mach/boolean.h> in NS3.0 #include <sys/file.h> #define CHK_COUNT 6 // # of fullwords we cross-check #define CHK_PATCH 4 // subscript of first word to patch #define CHK_ADDR_V21 0x0405b200 // start check four fullwords before #define PATCH_ADDR_21 0x0405b210 // the Release 2.1 patch address #define CHK_ADDR_V22 0x0405cf58 // start check four fullwords before #define PATCH_ADDR_22 0x0405cf68 // the Release 2.2 patch address #define CHK_ADDR_V30 0x0406e174 // start check four fullwords before #define PATCH_ADDR_30 0x0406e184 // the Release 3.0 patch address #define CHK_ADDR_V31 0x04072ab0 // start check four fullwords before #define PATCH_ADDR_31 0x04072ac0 // the Release 3.1 patch address #define CHK_ADDR_V32 0x04073e48 // start check four fullwords before #define PATCH_ADDR_32 0x04073e58 // the Release 3.2 patch address #define PATCH 0x57c07c00 // value for alphalock neutralized #define PATCH2 0xC08623C0 // second word (need for NS3.0) long chk_data[CHK_COUNT]; char rel_matched[10]; boolean_t checkrel( int, long , const long *, const char * ); int main(int argc, char *argv[]) { int fd; long data[2], orig[2], addr; static long chk_21[CHK_COUNT] = { 0x60224AB9, 0x040A3D80, 0x661A4AB9, 0x040A3D84, /* orig: */ 0x57c07c01, 0xC08623C0 }; static long chk_22[CHK_COUNT] = { 0x60304AB9, 0x040A7788, 0x66284AB9, 0x040A778C, /* orig: */ 0x57c07c01, 0xC08623C0 }; static long chk_30[CHK_COUNT] = { 0x601A4AB9, 0x040ADF7C, 0x66124AB9, 0x040ADF78, /* orig: */ 0x57c049c0, 0x448023C0 }; static long chk_31[CHK_COUNT] = { 0x601A4AB9, 0x040B31CC, 0x66124AB9, 0x040B31C8, /* orig: */ 0x57c049c0, 0x448023C0 }; static long chk_32[CHK_COUNT] = { 0x601A4AB9, 0x040B49E0, 0x66124AB9, 0x040B49DC, /* orig: */ 0x57C049C0, 0x448023C0 }; static long patch[2] = { 0x57c07c00, 0xC08623C0 }; fd = open( "/dev/kmem", O_RDWR ); if ( fd == -1 ) { printf( "Alphalock must run as root!\n" ); exit( 1 ); } if ( checkrel(fd, CHK_ADDR_V21, chk_21, "2.1" ) ) { addr = PATCH_ADDR_21; orig[0] = chk_21[CHK_PATCH]; orig[1] = chk_21[CHK_PATCH+1]; } else if ( checkrel(fd, CHK_ADDR_V22, chk_22, "2.2" ) ) { addr = PATCH_ADDR_22; orig[0] = chk_22[CHK_PATCH]; orig[1] = chk_22[CHK_PATCH+1]; } else if ( checkrel(fd, CHK_ADDR_V30, chk_30, "3.0" ) ) { /* this also seems to work for 3.0J */ addr = PATCH_ADDR_30; orig[0] = chk_30[CHK_PATCH]; orig[1] = chk_30[CHK_PATCH+1]; } else if ( checkrel(fd, CHK_ADDR_V31, chk_31, "3.1" ) ) { addr = PATCH_ADDR_31; orig[0] = chk_31[CHK_PATCH]; orig[1] = chk_31[CHK_PATCH+1]; } else if ( checkrel(fd, CHK_ADDR_V32, chk_32, "3.2" ) ) { addr = PATCH_ADDR_32; orig[0] = chk_32[CHK_PATCH]; orig[1] = chk_32[CHK_PATCH+1]; } else { close( fd ); printf( "Unknown kernel for Alphalock!\n" ); printf( "(doesn't seem to be any of Release 2.1, 2.2, 3.0, 3.0J, 3.1, or 3.2)\n" ); exit( 4 ); } // assume the user wants to toggle the setting if ( chk_data[CHK_PATCH] == orig[0] && chk_data[CHK_PATCH +1] == orig[1]) { data[0] = patch[0]; data[1] = patch[1]; } else if ( chk_data[CHK_PATCH] == patch[0] && chk_data[CHK_PATCH+1] == patch[1] ) { data[0] = orig[0]; data[1] = orig[1]; } else { close( fd ); printf( "Kernel not compatible with Alphalock!\n" ); exit( 4 ); } // check for explicit request of setting if ( argc > 1 ) { if ( !strcmp(argv[1], "enable") ) { data[0] = orig[0]; data[1] = orig[1]; } else if ( !strcmp(argv[1], "disable") ) { data[0] = patch[0]; data[1] = patch[1]; } else { printf( "Invalid paramater, expecting \"enable\" or \"disable\"\n" ); close( fd ); exit( 5 ); } } if ( chk_data[CHK_PATCH] != data[0] ) { if ( lseek( fd, addr, L_SET ) == -1 ) { close( fd ); exit( 6 ); } if ( write( fd, &data, sizeof( data ) ) != sizeof( data ) ) { close( fd ); exit( 7 ); } } close( fd ); if ( data[0] == patch[0] ) { printf( "AlphaLock on release %s Disabled\n", rel_matched ); } else { printf( "AlphaLock on release %s Enabled\n", rel_matched ); } return( 0 ); } boolean_t checkrel( int fd, long startchk, const long checkval[CHK_COUNT], const char * rel_char ) { if ( lseek( fd, startchk, L_SET ) == -1 ) { close( fd ); exit( 2 ); } if ( read( fd, chk_data, CHK_COUNT * 4 ) != CHK_COUNT * 4 ) { close( fd ); exit( 3 ); } #ifdef DEBUG printf( "check %s = %08X %08X %08X %08X - %08X %08X\n", rel_char, chk_data[0], chk_data[1], chk_data[2], chk_data[3], chk_data[4], chk_data[5] ); #endif /* DEBUG */ if ( (checkval[0] == chk_data[0]) && (checkval[1] == chk_data[1]) && (checkval[2] == chk_data[2]) && (checkval[3] == chk_data[3]) ) { #ifdef DEBUG printf("Looks like release %s alright\n", rel_char); #endif /* DEBUG */ strcpy(rel_matched, rel_char); return TRUE ; } return FALSE ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.