1. @@// Second take at reversing anySIM 1.1.3:
  2.  
  3. /**
  4.  *
  5.  * Copyright (C) 2007 iPhone Dev Team  
  6.  *
  7.  *    Unlock Authors: Daeken, gray, iZsh, Sam
  8.  *    UI Development: Erica, kroo, darkten
  9.  *    RCE: roxfan, daeken, darkmen, gray, iZsh, Sam  
  10.  *    Coop: pytey, uns, zappaz, Zf, guest184, leachbj
  11.  *    Art: Wheat, darkten
  12.  *
  13.  *    Paypal donation and contact -> iphone.devteam@gmail.com
  14.  *
  15.  *    For further information check http://www.hackint0sh.org
  16.  *
  17.  * This program is free software; you can redistribute it and/or modify
  18.  * it under the terms of the GNU General Public License as published by
  19.  * the Free Software Foundation; either version 2 of the License, or
  20.  * (at your option) any later version.
  21.  *
  22.  * This program is distributed in the hope that it will be useful,
  23.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25.  * GNU General Public License for more details.
  26.  *
  27.  * You should have received a copy of the GNU General Public License
  28.  * along with this program; if not, write to the Free Software
  29.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  30.  */
  31.  
  32. /* Old Header:
  33.  
  34.   iUnlock v4243.AutoSpeedy -- Copyright 2007 The dev team
  35.  
  36.   Credits: Daeken, Darkmen, guest184, gray, iZsh, leachbj, pytey, roxfan, Sam, uns, zappaz, Zf
  37.   Paypal donation to iphone.devteam@gmail.com
  38.  
  39.   All code, information or data [from now on "data"] available
  40.   from the "iPhone dev team" [1] or any other project linked from
  41.   this or other pages is owned by the creator who created the data.
  42.   The copyright, license right, distribution right and any other
  43.   rights lies with the creator.
  44.  
  45.   It is prohibitied to use the data without the written agreement
  46.   of the creator. This included using ideas in other projects
  47.   (commercial or not commercial).
  48.  
  49.   Where data was created by more than 1 creator a written agreement
  50.   from each of the creators has to be obtained.
  51.  
  52.   Punishment: Monkeys coming out of your ass Bruce Almighty style.
  53.  
  54.   [1] http://iphone.fiveforty.net/wiki/index.php?title=Main_Page
  55.  
  56.   anySIM v1.1 changes - darkten
  57.  
  58.   anySIM v1.1.2 changes - netkas, drudge
  59. */
  60.  
  61. #import <CoreFoundation/CoreFoundation.h>
  62. #import <Foundation/Foundation.h>
  63. #import <UIKit/UIKit.h>
  64. #import <GraphicsServices/GraphicsServices.h>
  65. #import <IOKit/IOKitLib.h>
  66. #ifndef kIOPMAssertionTypeNoIdleSleep
  67. #define kIOPMAssertionTypeNoIdleSleep                 CFSTR("NoIdleSleepAssertion")
  68. #endif
  69.  
  70. // other imports -- should be part of UIKit:
  71. #import <UIKit/UIBox.h>
  72. #import <UIKit/UIView-Geometry.h>
  73. #import <UIKit/UIAnimator.h>
  74. #import <UIKit/UICheckboxImage.h>
  75. #import <UIKit/UITransformAnimation.h>
  76. #import <UIKit/UIRotationAnimation.h>
  77. #import <UIKit/UIAlphaAnimation.h>
  78. #import <UIKit/UIBezierPath.h>
  79. #import <UIKit/UIButtonBar.h>
  80. #import <UIKit/UINavigationBar.h>
  81. #import <UIKit/UIButtonBarButton.h>
  82. #import "Unlock.h"
  83.  
  84. id thisapp;
  85. id mainV;
  86. id navB;
  87. id mrAlert;
  88. id passthruAlert;
  89. BOOL restartComm = NO;
  90.  
  91. #include <stdio.h>
  92. #include <stdlib.h>
  93. #include <unistd.h>
  94. #include <string.h>
  95. #include <fcntl.h>
  96. #include <termios.h>
  97. #include <errno.h>
  98. #include <time.h>
  99.  
  100.  
  101. #include "packets.h"
  102.  
  103. #define ever ;;
  104. #define LOG stdout
  105. #define SPEED 750000
  106.  
  107. #pragma pack(1)
  108.  
  109. #define BUFSIZE (65536+100)
  110. unsigned char readbuf[BUFSIZE];
  111.  
  112. struct termios term;
  113.  
  114. //#define DEBUG_ENABLED 1
  115.  
  116. #ifndef DEBUG_ENABLED
  117. #define DEBUGLOG(x)
  118. #else
  119. #define DEBUGLOG(x) x
  120. #endif
  121.  
  122. #define UINT(x) *((unsigned int *) (x))
  123.  
  124. #define FW31206 "DEV_ICE_MODEM_03.12.06_G"
  125. #define FW31408 "DEV_ICE_MODEM_03.14.08_G"
  126. #define FW40113 "DEV_ICE_MODEM_04.01.13_G"
  127. #define FW40213 "DEV_ICE_MODEM_04.02.13_G"
  128. #define FW40313 "DEV_ICE_MODEM_04.03.13_G"
  129.  
  130. #define SECPACK31206 "/Applications/anySIM.app/secpack31206.bin"
  131. #define SECPACK31408 "/Applications/anySIM.app/secpack31408.bin"
  132. #define SECPACK40113 "/Applications/anySIM.app/secpack40113.bin"
  133. #define SECPACK40213 "/Applications/anySIM.app/secpack40213.bin"
  134. #define SECPACK40313 "/Applications/anySIM.app/secpack40313.bin"
  135.  
  136. #define ATINIT_CMD "AT\r"
  137. #define UNLOCK_CMD "AT+CLCK=\"PN\",0,\"00000000\"\r"
  138. #define UNLOCKTEST_CMD "AT+CLCK=\"PN\",2\r"
  139. #define UNLOCKTEST_OK "+CLCK: 0"
  140. #define LAUNCHCTL_STOP "/bin/launchctl unload -w /System/Library/LaunchDaemons/com.apple.CommCenter.plist"
  141. #define LAUNCHCTL_START "/bin/launchctl load -w /System/Library/LaunchDaemons/com.apple.CommCenter.plist"
  142. #define NOR_FILENAME "/tmp/nor.bin"
  143.  
  144. const char * RE = "Why the hell are you reversing this app?! We said we were "\
  145. "going to release the sources...";
  146.  
  147. const unsigned char forged_signature[] = { // same exp/mod as the secpack
  148.        0,    0,    0,    0,    0,    0,    0,    0,
  149.        0,    0,    0,    0,    0,    0,    0,    0,
  150.        0,    0,    0,    0,    0,    0,    0,    0,
  151.        0,    0,    0,    0,    0,    0,    0,    0,
  152.        0,    0,    0,    0,    0,    0,    0,    0,
  153.        0,    0,    0,    0,    0,    0,    0,    0,
  154.        0,    0,    0,    0,    0,    0,    0,    0,
  155.        0,    0,    0,    0,    0,    0,    0,    0,
  156.        0,    0,    0,    0,    0,    0,    0,    0,
  157.        0,    0,    0,    0,    0,    0,    0,    0,
  158.        0,    0,    0,    0,    0, 0x01, 0x71, 0x37,
  159.     0x44, 0x91, 0x23, 0xEF, 0x65, 0xCD, 0xDE, 0x7F,
  160.     0x16, 0x9C, 0x68, 0x0E, 0x57, 0xA0, 0x31, 0x9A,
  161.     0x6E, 0x2E, 0xD4, 0xAA, 0x1F, 0x09, 0x67, 0x6F,
  162.     0xB0, 0x19, 0xD5, 0xBA, 0x6D, 0x48, 0xDA, 0xD2,
  163.     0x9E, 0x7F, 0x55, 0x6D, 0xFA, 0x64, 0xBA, 0xF8
  164. };
  165.  
  166. void StopCommcenter();
  167.  
  168. #include <objc/objc.h>
  169. #include <objc/objc-runtime.h>
  170.  
  171. double objc_msgSend_fpret(id self, SEL op, ...)
  172. {
  173.    Method method = class_getInstanceMethod(self->isa, op);
  174.    int numArgs = method_getNumberOfArguments(method);
  175.  
  176.    if(numArgs == 2) {
  177.         double (*imp)(id, SEL);
  178.         imp = (double (*)(id, SEL))method->method_imp;
  179.         return imp(self, op);
  180.     } else if(numArgs == 3) {
  181.          va_list ap;
  182.          va_start(ap, op);
  183.          double (*imp)(id, SEL, void *);
  184.          imp = (double (*)(id, SEL, void *))method->method_imp;
  185.          return imp(self, op, va_arg(ap, void *));
  186.     }
  187.  
  188.     fprintf(stderr,
  189.        "ERROR: objc_msgSend_fpret called on <%s %p> with selector %s had to return 0.0\n", object_getClassName(self),
  190.         self, sel_getName(op));
  191.     return 0.0;
  192. }
  193.  
  194.  
  195.  
  196. @implementation Unlock
  197.  
  198. - (void) applicationDidFinishLaunching: (id) unused {
  199.     window = [[UIWindow alloc] initWithContentRect: [UIHardware
  200.                             fullScreenApplicationContentRect]];
  201.  
  202.     [window orderFront: self];
  203.     [window makeKey: self];
  204.     [window _setHidden: NO];
  205.  
  206.     thisapp = self;
  207.    
  208.     struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
  209.     rect.origin.x = rect.origin.y = 0.0f;
  210.  
  211.     theProgress = [[UIProgressBar alloc] initWithFrame:CGRectMake(30.0f, 55.0f, 260.0f, 30.0f)];
  212.     //[theProgress setProgress:0.0];
  213.     progressWindow = [[UIAlertSheet alloc ] init];
  214.     [progressWindow setTitle:@"Ready to Unlock"];
  215.     [progressWindow setDelegate:self];
  216.     [progressWindow setContext:self];
  217.     [progressWindow addSubview:theProgress];
  218.     [progressWindow setDimsBackground:YES];
  219.     [progressWindow setRunsModal:YES];
  220.     [progressWindow setAlertSheetStyle:1];
  221.     [progressWindow setNumberOfRows:1];
  222.     [progressWindow setTableShouldShowMinimumContent:YES];
  223.     [progressWindow setBlocksInteraction:NO];
  224.     [progressWindow _slideSheetOut:YES];
  225.     [progressWindow layoutAnimated:YES];
  226.  
  227.     SliderControl *slider = [[SliderControl alloc] init];
  228.     [slider registerCallback:@selector(showReadme) forId: self];
  229.    
  230.     navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0f, 460.0f, 320.0f, 20.0f)];
  231.     [navBar setBarStyle:1];
  232.    
  233.     navB = navBar;
  234.    
  235.     UIImage *bgimage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"background" ofType:@"png"]];
  236.     [bgimage retain];
  237.     UIImageView *bgimagev = [[UIImageView alloc] initWithImage: bgimage];
  238.     [bgimagev setFrame: rect];
  239.  
  240.  
  241.     UIView *mainView;
  242.     mainView = [[UIView alloc] initWithFrame: rect];
  243.     [mainView addSubview: bgimagev];
  244.     [mainView addSubview: slider];
  245.     [mainView addSubview: navBar];
  246.     [window setContentView: mainView];
  247.    
  248.     mainV = mainView;
  249.    
  250.     BOOL goodToGo = NO;
  251.    
  252.     NSFileManager *mandingo = [NSFileManager defaultManager];
  253.     if([mandingo fileExistsAtPath:@"/var/root/Library/Preferences/com.apple.springboard.plist"]){
  254.     NSDictionary *springy = [NSDictionary dictionaryWithContentsOfFile:@"/var/root/Library/Preferences/com.apple.springboard.plist"];
  255.     if([[springy valueForKey:@"SBAutoLockTime"] intValue] != -1){
  256.     [self exitUnlockWithErrorMessage:@"You must set Auto-Lock to \"Never\" in Settings (General/Auto-Lock) to continue. anySIM will now quit."];
  257.     }else{
  258.     goodToGo = YES;
  259.     }
  260.     }
  261.    
  262.     if(goodToGo){
  263.     NSMutableArray *click = [[NSMutableArray alloc] init];
  264.                 [click addObject:[NSString stringWithString:@"OK"]];
  265.                                
  266.                 UIAlertSheet *welcome = [[UIAlertSheet alloc]
  267.                             initWithTitle:@"Welcome to anySIM v1.1.3 Beta"
  268.                             buttons:click
  269.                             defaultButtonIndex:0
  270.                             delegate:self
  271.                             context:self];
  272.                 [welcome setBodyText:@"To get started, Slide to Unlock, Read our License, scroll down and press the red button to begin. \n\nPlease make sure your new\nSIM is in your iPhone."];
  273.                 [welcome setDimsBackground:YES];
  274.                 [welcome _slideSheetOut:YES];
  275.                 [welcome setRunsModal:YES];
  276.                 [welcome setShowsOverSpringBoardAlerts:YES];
  277.                 passthruAlert = welcome;
  278.                 [welcome popupAlertAnimated:YES];
  279.  
  280.     }  
  281.    
  282.    
  283. }
  284.  
  285. - (void) buttonEvent:(UIPushButton *)button {
  286.    [window setContentView:mainV];
  287.    [progressWindow presentSheetFromAboveView: [window contentView]];
  288.     StopCommcenter();
  289.     sleep(2);
  290.   [NSThread detachNewThreadSelector:@selector(doUnlock:) toTarget:self withObject:nil];
  291. }
  292.  
  293. -(void)showReadme {
  294.   UIScroller *scroller = [[UIScroller alloc] initWithFrame: CGRectMake(0.0f, 0.f, 320.0f,480.f)];
  295.  
  296.   UIImage *image = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"strip" ofType:@"png"]];
  297.   [image retain];
  298.   UIImageView *imagev = [[UIImageView alloc] initWithImage: image];
  299.   [imagev setFrame: CGRectMake(0, 0, 320, 828)];
  300.  
  301.   //Button images - in application bundle.  These are from the clock app
  302.   UIImage* btnImage = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"UIPreferencesDeleteButtonNormal" ofType:@"png"]];
  303.   UIImage* btnImagePressed = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"UIPreferencesDeleteButtonPressed" ofType:@"png"]];
  304.  
  305.   UIPushButton *button = [[UIPushButton alloc] initWithTitle: @"OK, Unlock My Phone" autosizesToFit: NO];
  306.   [button setFrame: CGRectMake(5, 828, 310, 45)];
  307.   [button setDrawsShadow: YES];
  308.   [button setStretchBackground:YES];
  309.   [button setBackground:btnImage forState:0];  //up state
  310.   [button setBackground:btnImagePressed forState:1]; //down state
  311.   [button addTarget:self action:@selector(buttonEvent:) forEvents:1];
  312.  
  313.   [scroller setContentSize: CGSizeMake(320, 875)];  
  314.   [scroller addSubview:imagev];
  315.   [scroller addSubview:button];
  316.  
  317.   [window setContentView: scroller];
  318. }
  319.  
  320.  
  321. -(void)setProgress:(NSArray *)arg {
  322.   double percentage = [[arg objectAtIndex:0]floatValue] / 100.0;
  323.   [theProgress setProgress:percentage];
  324.   [progressWindow setTitle:[arg objectAtIndex:1]];
  325. }
  326.  
  327. -(void)unlockDone{
  328.  
  329. [progressWindow dismissAnimated:YES];
  330. NSMutableArray *buttons = [[NSMutableArray alloc] init];
  331.                 [buttons addObject:[NSString stringWithString:@"OK"]];
  332.                                
  333.                 UIAlertSheet *sheet = [[UIAlertSheet alloc]
  334.                             initWithTitle:@"Unlock Sucessful!"
  335.                             buttons:buttons
  336.                             defaultButtonIndex:0
  337.                             delegate:self
  338.                             context:self];
  339.                 [sheet setBodyText:@"Your iPhone has been successfully unlocked."];
  340.                 [sheet setDimsBackground:YES];
  341.                 [sheet _slideSheetOut:YES];
  342.                 [sheet setRunsModal:YES];
  343.                 [sheet setAlertSheetStyle:1];
  344.                 [sheet setShowsOverSpringBoardAlerts:YES];
  345.                 mrAlert = sheet;
  346.                 //[sheet popupAlertAnimated:YES];
  347.                 [sheet presentSheetFromAboveView: [window contentView]];
  348. }
  349.  
  350.  
  351.  
  352. - (void) alertSheet:(id)aSheet buttonClicked:(int) bnum
  353. {  
  354. if(aSheet = mrAlert){
  355.  
  356. [self terminate];
  357. }
  358. if(aSheet = passthruAlert)
  359. [passthruAlert dismissAnimated:YES];
  360.  
  361.  
  362. }
  363.  
  364.  
  365. -(void)exitUnlockWithErrorMessage:(NSString *)awDang{
  366. NSString *theTitle = [@"Unlock Failure" retain];
  367. if(restartComm)
  368. theTitle = @"Please Restart your iPhone";
  369. //StartCommcenter();
  370.  
  371. [progressWindow dismissAnimated:YES];
  372. NSMutableArray *buttons = [[NSMutableArray alloc] init];
  373.                 [buttons addObject:[NSString stringWithString:@"OK"]];
  374.                                
  375.                 UIAlertSheet *sheet = [[UIAlertSheet alloc]
  376.                             initWithTitle:@"Please Restart your iPhone"
  377.                             buttons:buttons
  378.                             defaultButtonIndex:0
  379.                             delegate:self
  380.                             context:self];
  381.                 [sheet setBodyText:awDang];
  382.                 [sheet setDimsBackground:YES];
  383.                 [sheet _slideSheetOut:YES];
  384.                 [sheet setRunsModal:YES];
  385.                 [sheet setAlertSheetStyle:1];
  386.                 [sheet setShowsOverSpringBoardAlerts:YES];
  387.                 mrAlert = sheet;
  388.                 //[sheet popupAlertAnimated:YES];
  389.                 [sheet presentSheetFromAboveView: [window contentView]];
  390. }
  391.  
  392. -(void)applicationWillTerminate{
  393. if(restartComm){
  394. FILE *fp = popen(LAUNCHCTL_START, "r");
  395.   if (fp == NULL) {
  396.     [thisapp exitUnlockWithErrorMessage: [NSString stringWithFormat: @"Error while executing %s", @LAUNCHCTL_START]];
  397.   }
  398.  
  399.   int len = ReadResp(fileno(fp));
  400.   readbuf[len] = 0; // Buffer is big enough to allow this
  401.   DEBUGLOG(printf("CommCenter: %s\n", readbuf));
  402.   fclose(fp);
  403.   sleep(1);
  404.   //[thisapp setProgress:100.0 withMessage:@"Starting the CommCenter"];
  405.  // [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Starting the CommCenter", nil] waitUntilDone:NO];
  406. }
  407.  
  408. }
  409.  
  410. void StartCommcenter()
  411. {
  412.   //[thisapp setProgress:0.0 withMessage:@"Starting the CommCenter"];
  413.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Starting the CommCenter", nil] waitUntilDone:NO];
  414.   FILE *fp = popen(LAUNCHCTL_START, "r");
  415.   if (fp == NULL) {
  416.     [thisapp exitUnlockWithErrorMessage: [NSString stringWithFormat: @"Error while executing %s", @LAUNCHCTL_START]];
  417.   }
  418.  
  419.   int len = ReadResp(fileno(fp));
  420.   readbuf[len] = 0; // Buffer is big enough to allow this
  421.   DEBUGLOG(printf("CommCenter: %s\n", readbuf));
  422.   fclose(fp);
  423.   sleep(1);
  424.   //[thisapp setProgress:100.0 withMessage:@"Starting the CommCenter"];
  425.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Starting the CommCenter", nil] waitUntilDone:NO];
  426. }
  427.  
  428.  
  429. void HexDumpLine(unsigned char *buf, int remainder, int offset)
  430. {
  431.   int i = 0;
  432.   char c = 0;
  433.  
  434.   // Print the hex part
  435.   fprintf(LOG, "%08x | ", offset);
  436.   for (i = 0; i < 16; ++i) {
  437.     if (i < remainder)
  438.       fprintf(LOG, "%02x%s", buf[i], (i == 7) ? "  " : " ");
  439.     else
  440.       fprintf(LOG, "  %s", (i == 7) ? "  " : " ");
  441.   }
  442.   // Print the ascii part
  443.   fprintf(LOG, " | ");
  444.   for (i = 0; i < 16 && i < remainder; ++i) {
  445.     c = buf[i];
  446.     if (c >= 0x20 && c <= 0x7e)
  447.       fprintf(LOG, "%c%s", c, (i == 7) ? " " : "");
  448.     else
  449.       fprintf(LOG, ".%s", (i == 7) ? " " : "");
  450.   }
  451.  
  452.   fprintf(LOG, "\n");
  453. }
  454.  
  455. void HexDump(unsigned char *buf, int size)
  456. {
  457.   int i = 0;
  458.  
  459.   for (i = 0; i < size; i += 16)
  460.     HexDumpLine(buf + i, size - i, i);
  461.   fprintf(LOG, "%08x\n", size);
  462. }
  463.  
  464. int Checksum(CmdHeader * packet)
  465. {
  466.   int sum = 0x00030000;
  467.   sum += packet->opcode;
  468.   sum += packet->param_len;
  469.  
  470.   int len = packet->param_len;
  471.   unsigned char * buf = ((unsigned char *)packet) + sizeof (CmdHeader);
  472.   int i = 0;  
  473.  
  474.   for (i = 0; i < len; ++i)
  475.     sum += buf[i];
  476.   return sum;
  477. }
  478.  
  479. void SendCmd(int fd, void *buf, size_t size)
  480. {
  481.   DEBUGLOG(fprintf(LOG, "Sending:\n"));
  482.   DEBUGLOG(HexDump((unsigned char*)buf, size));
  483.  
  484.   if(write(fd, buf, size) == -1) {
  485.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while sending command" waitUntilDone:NO];
  486.   }
  487. }
  488.  
  489. #define sendBytes(fd, args...) {\
  490.   unsigned char sendbuf[] = {args}; \
  491.   SendCmd(fd, sendbuf, sizeof(sendbuf)); \
  492. }
  493.  
  494. int ReadResp(int fd)
  495. {
  496.   int len = 0;
  497.   struct timeval timeout;
  498.   int nfds = fd + 1;
  499.   fd_set readfds;
  500.  
  501.   FD_ZERO(&readfds);
  502.   FD_SET(fd, &readfds);
  503.  
  504.   // Wait a second
  505.   timeout.tv_sec = 0;
  506.   timeout.tv_usec = 50000;
  507.  
  508.   // Read data
  509.   while (select(nfds, &readfds, NULL, NULL, &timeout) > 0)
  510.     len += read(fd, readbuf + len, BUFSIZE - len);
  511.  
  512.   if (len > 0) {
  513.     DEBUGLOG(fprintf(LOG, "Read:\n"));
  514.     DEBUGLOG(HexDump(readbuf, len));
  515.   }
  516.   return len;
  517. }
  518.  
  519. int InitConn(int speed)
  520. {
  521.   //  int fd = open("/dev/tty.baseband", O_RDWR | 0x20000 | O_NOCTTY);
  522.   int fd = open("/dev/tty.baseband", 0x20002);
  523.  
  524.   unsigned int blahnull = 0;
  525.   unsigned int handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
  526.  
  527.   if(fd == -1) {
  528.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error opening the baseband" waitUntilDone:NO];
  529.   }
  530.  
  531.   ioctl(fd, 0x2000740D);
  532.   fcntl(fd, 4, 0);
  533.   tcgetattr(fd, &term);
  534.  
  535.   ioctl(fd, 0x8004540A, &blahnull);
  536.   cfsetspeed(&term, speed);
  537.   cfmakeraw(&term);
  538.   term.c_cc[VMIN] = 0;
  539.   term.c_cc[VTIME] = 5;
  540.  
  541.   term.c_iflag = (term.c_iflag & 0xFFFFF0CD) | 5;
  542.   term.c_oflag =  term.c_oflag & 0xFFFFFFFE;
  543.   term.c_cflag = (term.c_cflag & 0xFFFC6CFF) | 0x3CB00;
  544.   term.c_lflag =  term.c_lflag & 0xFFFFFA77;
  545.  
  546.   term.c_cflag = (term.c_cflag & ~CSIZE) | CS8;
  547.   term.c_cflag &= ~PARENB;
  548.   term.c_lflag &= ~ECHO;
  549.  
  550.   tcsetattr(fd, TCSANOW, &term);
  551.  
  552.   ioctl(fd, TIOCSDTR);
  553.   ioctl(fd, TIOCCDTR);
  554.   ioctl(fd, TIOCMSET, &handshake);
  555.  
  556.   return fd;
  557. }
  558.  
  559. void RestartBaseband()
  560. {
  561.   kern_return_t   result;
  562.   mach_port_t     masterPort;
  563.  
  564.   result = IOMasterPort(MACH_PORT_NULL, &masterPort);
  565.   if (result) {
  566.     DEBUGLOG(printf("IOMasterPort failed\n"));
  567.     return;
  568.   }
  569.  
  570.   CFMutableDictionaryRef matchingDict = IOServiceMatching("AppleBaseband");  
  571.   io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
  572.   if (!service) {
  573.     DEBUGLOG(printf("IOServiceGetMatchingService failed\n"));
  574.     return;
  575.   }
  576.  
  577.   io_connect_t conn;
  578.   result = IOServiceOpen(service, mach_task_self(), 0, &conn);
  579.   if (result) {
  580.     DEBUGLOG(printf("IOServiceOpen failed\n"));
  581.     return;
  582.   }
  583.  
  584.   result = IOConnectCallScalarMethod(conn, 0, 0, 0, 0, 0);
  585.   if (result == 0)
  586.     DEBUGLOG(printf("Baseband reset.\n"));
  587.   else
  588.     DEBUGLOG(printf("Baseband reset failed\n"));
  589.   IOServiceClose(conn);
  590. }
  591.  
  592. void SetBaudRate(int fd, unsigned int baudrate)
  593. {
  594.   //[thisapp setProgress:0.0 withMessage: [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate]];
  595.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate], nil] waitUntilDone:NO];
  596.   BaudReq req;
  597.   req.cmd.cls = 0x2;
  598.   req.cmd.opcode = BBSETBAUDRATE;
  599.   req.cmd.param_len = 0x4;
  600.   req.baud = baudrate;
  601.   req.checksum = Checksum((CmdHeader*)&req);
  602.   SendCmd(fd, &req, sizeof (SeekReq));
  603.   DEBUGLOG(printf("Reading answer\n"));
  604.   ReadResp(fd);
  605.  
  606.   tcgetattr(fd, &term);
  607.   cfsetspeed(&term, baudrate);
  608.   tcsetattr(fd, TCSANOW, &term);
  609.   //[thisapp setProgress:100.0 withMessage: [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate]];
  610.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], [NSString stringWithFormat: @"Sending baudrate command speed %d", baudrate], nil] waitUntilDone:NO];
  611. }
  612.  
  613. void SendAT(int fd)
  614. {
  615.   SendCmd(fd, ATINIT_CMD, strlen(ATINIT_CMD));
  616. }
  617.  
  618. void InitAT(int fd)
  619. {
  620.   SendAT(fd);
  621.   for (ever) {
  622.     if(ReadResp(fd) != 0)
  623.       break;
  624.     SendAT(fd);
  625.   }
  626. }
  627.  
  628.  
  629. void SendGetVersion(int fd)
  630. {
  631.   sendBytes(fd, 0x60, 0x0D);
  632. }
  633.  
  634. void GetVersion(int fd)
  635. {
  636.   SendGetVersion(fd);
  637.   for (ever) {
  638.     if(ReadResp(fd) != 0) {
  639.       if(readbuf[0] == 0x0b)
  640.         break;
  641.     }
  642.     SendGetVersion(fd);
  643.   }
  644.  
  645.   VersionAck *ver = (VersionAck *) readbuf;
  646.   DEBUGLOG(printf("Boot mode: %02X\n", ver->bootmode));
  647.   DEBUGLOG(printf("Major: %d, Minor: %d\n", ver->major, ver->minor));
  648.   DEBUGLOG(printf("Version: %s\n", ver->version));
  649. }
  650.  
  651. void CFIStage1_2(int fd)
  652. {
  653.   CFIStage1Req req;
  654.   req.cmd.cls = 0x2;
  655.   req.cmd.opcode = BBCFISTAGE1;
  656.   req.cmd.param_len = 0;
  657.   req.checksum = Checksum ((CmdHeader*)&req);
  658.   DEBUGLOG(printf("Sending CFIStage1 Request\n"));
  659.   SendCmd(fd, &req, sizeof (CFIStage1Req));
  660.   DEBUGLOG(printf("Receiving CFIStage1 response\n"));
  661.   if (!ReadResp(fd)) {
  662.     DEBUGLOG(fprintf(stderr, "Failed to receive CFIStage1 response\n"));
  663.     [thisapp terminate];
  664.   }
  665.   CFIStage1Ack * cfi1resp = (CFIStage1Ack *) readbuf;
  666.   cfi1resp->cmd.opcode = BBCFISTAGE2;
  667.   cfi1resp->checksum = Checksum((CmdHeader*)cfi1resp);
  668.   SendCmd(fd, cfi1resp, sizeof(CFIStage1Ack));
  669.   if (!ReadResp(fd)) {
  670.     DEBUGLOG(fprintf(stderr, "Failed to receive CFIStage2 response\n"));
  671.     [thisapp terminate];
  672.   }
  673. }
  674.  
  675. void ReadSecpackFromFile(const char * FilePath, void * Buffer, int Offset)
  676. {
  677.   FILE * fp = fopen(FilePath, "rb");
  678.   if (fp == NULL) {
  679.   restartComm = YES;
  680.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
  681.   }
  682.  
  683.   fseek(fp, Offset, SEEK_SET);
  684.   if (fread(Buffer, 1, 0x800, fp) != 0x800) {
  685.     free(Buffer);
  686.     restartComm = YES;
  687.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while reading the secpack content" waitUntilDone:NO];
  688.   }
  689.   fclose(fp);
  690. }
  691.  
  692. void ReadSecpackFromFLS(const char * FilePath, void * Buffer)
  693. {
  694.   ReadSecpackFromFile(FilePath, Buffer, 0x1a4L);
  695. }
  696.  
  697. void SendBeginSecpack(int fd, void * Secpack)
  698. {
  699.  // [thisapp setProgress:0 withMessage:@"Sending Begin Secpack command"];
  700.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
  701.   BeginSecpackReq req;
  702.   req.cmd.cls = 0x2;
  703.   req.cmd.opcode = BBBEGINSECPACK;
  704.   req.cmd.param_len = 0x800;
  705.   memcpy(&req.data, Secpack, 0x800);
  706.   req.checksum = Checksum((CmdHeader*)&req);
  707.   SendCmd(fd, &req, sizeof (BeginSecpackReq));
  708.   // Wait for the answer
  709.   DEBUGLOG(printf("Reading answer\n"));
  710.   while (!ReadResp(fd)) ;
  711.   //[thisapp setProgress:100.0 withMessage:@"Sending Begin Secpack command"];
  712.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
  713. }
  714.  
  715. void SendEndSecpack(int fd)
  716. {
  717.   //[thisapp setProgress:0.0 withMessage:@"Sending End Secpack command"];
  718.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
  719.   EndSecpackReq req;
  720.   req.cmd.cls = 0x2;
  721.   req.cmd.opcode = BBENDSECPACK;
  722.   req.cmd.param_len = 0x2;
  723.   req.unknown = 0;
  724.   req.checksum = Checksum((CmdHeader*)&req);
  725.   SendCmd(fd, &req, sizeof (EndSecpackReq));
  726.   DEBUGLOG(printf("Reading answer\n"));
  727.   ReadResp(fd);
  728.   //[thisapp setProgress:100.0 withMessage:@"Sending End Secpack command"];
  729.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], @"Sending Begin Secpack command", nil] waitUntilDone:NO];
  730. }
  731.  
  732. void SendErase(int fd, int BeginAddr, int EndAddr)
  733. {
  734.   //[thisapp setProgress:0.0 withMessage:@"Sending Erase command"];
  735.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Sending Erase command", nil] waitUntilDone:NO];
  736.   EraseReq req;
  737.   req.cmd.cls = 0x2;
  738.   req.cmd.opcode = BBERASE;
  739.   req.cmd.param_len = 8;
  740.   req.low_addr = BeginAddr;
  741.   req.high_addr = EndAddr;
  742.   req.checksum = Checksum((CmdHeader*)&req);
  743.   SendCmd(fd, &req, sizeof (EraseReq));
  744.   sleep(1); // Give it some time
  745.   DEBUGLOG(printf("Reading answer\n"));
  746.   if (!ReadResp(fd)) {
  747.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Ooops, something was wrong while erasing" waitUntilDone:NO];
  748.   }
  749.  
  750.   //[thisapp setProgress:50.0 withMessage:@"Waiting For Erase Completion"];
  751.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:50.0], @"Waiting For Erase Completion", nil] waitUntilDone:NO];
  752.  
  753.   EraseAck * eraseack = (EraseAck *) readbuf;
  754.   EraseStatusReq statusreq;
  755.   statusreq.cmd.cls = 0x2;
  756.   statusreq.cmd.opcode = BBERASESTATUS;
  757.   statusreq.cmd.param_len = 2;
  758.   statusreq.unknown1 = eraseack->unknown1;
  759.   statusreq.checksum = Checksum((CmdHeader*)&statusreq);
  760.  
  761.   EraseStatusAck * erasestatusack = (EraseStatusAck *) readbuf;
  762.   do {
  763.     SendCmd(fd, &statusreq, sizeof(EraseStatusReq));
  764.     DEBUGLOG(printf("Reading answer\n"));
  765.     ReadResp(fd);
  766.     erasestatusack = (EraseStatusAck *) readbuf;
  767.   } while (erasestatusack->done != 1);
  768.  
  769.   //[thisapp setProgress:100.0 withMessage:@"Erase Completed"];
  770.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], @"Erase Completed", nil] waitUntilDone:NO];
  771. }
  772.  
  773. int ReadAddr(int fd, unsigned short int size)
  774. {
  775.   ReadReq req;
  776.  
  777.   req.cmd.cls = 0x2;
  778.   req.cmd.opcode = BBREAD;
  779.   req.cmd.param_len = 0x2;
  780.   req.size = size;
  781.   req.checksum = Checksum((CmdHeader*)&req);
  782.  
  783.   DEBUGLOG(printf("\nSending read request:\n"));
  784.   SendCmd(fd, &req, sizeof(ReadReq));
  785.  
  786.   DEBUGLOG(printf("Receiving read response\n"));
  787.   return ReadResp(fd);
  788. }
  789.  
  790. void Seek(int fd, unsigned int addr)
  791. {
  792.   DEBUGLOG(printf("Sending seek command for addr %p\n", addr));
  793.   SeekReq req;
  794.   req.cmd.cls = 0x2;
  795.   req.cmd.opcode = BBSEEK;
  796.   req.cmd.param_len = 0x4;
  797.   req.addr = addr;
  798.   req.checksum = Checksum((CmdHeader*)&req);
  799.   SendCmd(fd, &req, sizeof (SeekReq));
  800.   DEBUGLOG(printf("Reading answer\n"));
  801.   ReadResp(fd);
  802. }
  803.  
  804. void DumpReadBufToFile(FILE * fp)
  805. {
  806.   ReadAck * packet = (ReadAck*)readbuf;
  807.   int len = packet->cmd.param_len;
  808.   unsigned char * buf = &packet->first_char;
  809.   fwrite(buf, len, 1, fp);
  810. }
  811.  
  812. int Dump(int fd, FILE * fp, unsigned start_addr, unsigned end_addr)
  813. {
  814.   unsigned int addr = start_addr;
  815.   unsigned int dump_size = end_addr - start_addr;
  816.   unsigned int page_size = 0x800;
  817.   int step = dump_size / 20;
  818.   int last_progress = 0;
  819.   int i = 0;
  820.  
  821.   Seek(fd, addr);
  822.   for (i = 0; i < dump_size; i += page_size) {
  823.     int progress = i / step;
  824.     if (progress > last_progress) {
  825.  //     [thisapp setProgress:(5.0 * progress) withMessage:@"Dumping the NOR"];  
  826.         [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:(5.0 * progress)], @"Copying Firmware...Please Wait", nil] waitUntilDone:NO];
  827.  
  828.       last_progress = progress;
  829.     }
  830.     DEBUGLOG(printf("Addr: %p\n", addr + i));
  831.     ReadAddr(fd, page_size);
  832.     if (fp != NULL) {
  833.     DumpReadBufToFile(fp);
  834.     } else if (!strncmp((char *)&readbuf[6], "NACK", 4)) {
  835.     return 0;
  836.     }
  837.   }
  838.  
  839.   return 1;
  840. }
  841.  
  842. void * LoadNOR(const char * FilePath, int * Size)
  843. {
  844.   FILE * fp = fopen(FilePath, "rb");
  845.   if (fp == NULL) {
  846.     restartComm = YES;
  847.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
  848.   }
  849.  
  850.   fseek(fp, 0, SEEK_END);
  851.   int size = ftell(fp);  fseek(fp, 0, SEEK_SET);
  852.  
  853.   void * buffer = malloc(size);
  854.  
  855.   if (fread(buffer, 1, size, fp) != size) {
  856.     free(buffer);
  857.     restartComm = YES;
  858.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while reading the Firmware backup" waitUntilDone:NO];
  859.   }
  860.   fclose(fp);
  861.   *Size = size;
  862.   return buffer;
  863. }
  864.  
  865. void * ReadFW(const char * FilePath, int Size)
  866. {
  867.   FILE * fp = fopen(FilePath, "rb");
  868.   if (fp == NULL) {
  869.     restartComm = YES;
  870.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
  871.   }
  872.  
  873.   void * buffer = malloc(Size);
  874.   fseek(fp, 0x9a4L + 0x20000, SEEK_SET);
  875.  
  876.   if (fread(buffer, 1, Size, fp) != Size) {
  877.     free(buffer);
  878.     restartComm = YES;
  879.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Error while reading the Firmware content" waitUntilDone:NO];
  880.   }
  881.   fclose(fp);
  882.   return buffer;
  883. }
  884.  
  885.  
  886. void SendWriteOnePage(int fd, unsigned char * Buffer, int Size, WriteReq * req)
  887. {
  888.   int size_to_write = Size > 0x800 ? 0x800 : Size;
  889.  
  890.   // Header, buffer, checksum
  891.   int req_size = sizeof (CmdHeader) + size_to_write + 4;
  892.  
  893.   req->cmd.cls = 0x2;
  894.   req->cmd.opcode = BBWRITE;
  895.   req->cmd.param_len = size_to_write;
  896.   memset(&req->first_char, 0, size_to_write);
  897.   memcpy(&req->first_char, Buffer, size_to_write);
  898.   *(unsigned int *)(&req->first_char + size_to_write) = Checksum((CmdHeader*)req);
  899.  
  900.   SendCmd(fd, req, req_size);
  901.   DEBUGLOG(printf("Reading answer\n"));
  902.   if (!ReadResp(fd)) {
  903.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Ooops, something was wrong while Writing" waitUntilDone:NO];
  904.   }
  905. }
  906.  
  907. void SendWrite(int fd, unsigned char * Buffer, int Size, int Debug)
  908. {
  909.   if (Debug)
  910.     //[thisapp setProgress:0.0 withMessage:@"Flashing the baseband"];
  911.     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], @"Flashing the baseband", nil] waitUntilDone:NO];
  912.   int cur_size = Size;
  913.   int step = Size / 20;
  914.   int last_progress = 0;
  915.   WriteReq * req = malloc(0x1000);
  916.  
  917.   while (cur_size > 0) {
  918.     int progress = (Size - cur_size) / step;
  919.     if (Debug && progress > last_progress) {
  920.      // [thisapp setProgress:(5.0 * progress) withMessage:@"Flashing the baseband"];  
  921.       [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:(5.0 * progress)], @"Flashing the baseband", nil] waitUntilDone:NO];
  922.       last_progress = progress;
  923.     }
  924.     SendWriteOnePage(fd, Buffer, cur_size, req);
  925.     cur_size -= 0x800;
  926.     Buffer += 0x800;
  927.   }
  928.   free(req);
  929.   if (Debug)
  930.     //[thisapp setProgress:100.0 withMessage:@"Flashing the baseband..."];
  931.     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0], @"Flashing the baseband...", nil] waitUntilDone:NO];
  932. }
  933.  
  934.  
  935. // In progress ;)
  936. int PatchingFW(unsigned char * Buffer, int Ver)
  937. {
  938.   //[thisapp setProgress:0.0 withMessage:@"Patching the firmware"];
  939.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Patching the firmware", nil] waitUntilDone:NO];
  940.  
  941.   int offset = 0;
  942.  
  943.   if (Ver == 31206)
  944. //    offset = 0x213740;
  945.     return 1;
  946.   else if (Ver == 31408)
  947.     offset = 0x216f28;
  948.   else if (Ver == 40113)
  949.     offset = 0x2172d4;
  950.   else if (Ver == 40213)
  951.     offset = 0x2159d4;
  952.   else if (Ver == 40313) {
  953.     offset = 0x218150;
  954.  
  955.     if (Buffer[offset] == 0x00 &&
  956.     Buffer[offset + 1] == 0x00 &&
  957.     Buffer[offset + 2] == 0x00 &&
  958.     Buffer[offset + 3] == 0x00) {
  959.     // Already patched
  960.     return 1;
  961.     }
  962.  
  963.     if (Buffer[offset] != 0x02 ||
  964.     Buffer[offset + 1] != 0x00 ||
  965.     Buffer[offset + 2] != 0x00 ||
  966.     Buffer[offset + 3] != 0x1A) {
  967.     // Couldn't locate bytes to patch
  968.     return 2;
  969.     }
  970.  
  971.     Buffer[offset] = 0;
  972.     Buffer[offset + 1] = 0;
  973.     Buffer[offset + 2] = 0;
  974.     Buffer[offset + 3] = 0;
  975.  
  976.     memcpy(Buffer + 0x800, forged_signature, sizeof(forged_signature));
  977.  
  978.     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Firmware patched", nil] waitUntilDone:NO];
  979.  
  980.     return 0;
  981.   }
  982.  
  983.   if (Buffer[offset] == 0x01
  984.     && Buffer[offset+1] == 0x00
  985.     && Buffer[offset+2] != 0xa0
  986.     && Buffer[offset+3] != 0xe3)
  987.   {
  988.     // Already patched
  989.     //[thisapp setProgress:100.0 withMessage:@"Firmware already patched"];
  990.      //restartComm = YES;
  991.     //[thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Firmware already patched", nil] waitUntilDone:NO];
  992.     //[thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Firmware on this iPhone is already patched. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits."  waitUntilDone:NO];
  993.     return 1;
  994.   }
  995.  
  996.   if (Buffer[offset] != 0x00
  997.     || Buffer[offset+1] != 0x00
  998.     || Buffer[offset+2] != 0xa0
  999.     || Buffer[offset+3] != 0xe3)
  1000.   {
  1001.     //restartComm = YES;
  1002.     //[thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Couldn't locate bytes to patch. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits." waitUntilDone:NO];
  1003.      return 2;
  1004.   }
  1005.  
  1006.   Buffer[offset] = 0x01;
  1007.   Buffer[offset + 1] = 0x00;
  1008.   Buffer[offset + 2] = 0xa0;
  1009.   Buffer[offset + 3] = 0xe3;
  1010.   //[thisapp setProgress:100.0 withMessage:@"Firmware patched"];
  1011.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Firmware patched", nil] waitUntilDone:NO];
  1012.  
  1013.   return 0;
  1014. }
  1015.  
  1016. void ValidateFW(int fd, int Addr, unsigned char * Buffer, int Size)
  1017. {
  1018.   //[thisapp setProgress:0.0 withMessage:@"Validating the flash operation"];
  1019.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Validating the flash operation", nil] waitUntilDone:NO];
  1020.  
  1021.   Seek(fd, Addr);
  1022.  
  1023.   while (Size > 0) {
  1024.     int size_to_check = Size > 0x800 ? 0x800 : Size;
  1025.     ReadAddr(fd, size_to_check);
  1026.     ReadAck * packet = (ReadAck*)readbuf;
  1027.     unsigned char * buf = &packet->first_char;
  1028.  
  1029.     if (memcmp(buf, Buffer, size_to_check)) {
  1030.       [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Couldn't validate the flash operation" waitUntilDone:NO];
  1031.       return;
  1032.     }
  1033.     Size -= 0x800;
  1034.     Buffer += 0x800;
  1035.   }
  1036.  
  1037.   //[thisapp setProgress:100.0 withMessage:@"Validating the flash operation"];
  1038.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Validating the flash operation", nil] waitUntilDone:NO];
  1039.  
  1040. }
  1041.  
  1042. int ResetBaseband(int Speed)
  1043. {
  1044.   RestartBaseband();
  1045.   int fd = InitConn(115200);
  1046.   GetVersion(fd);
  1047.   CFIStage1_2(fd);
  1048.   SetBaudRate(fd, Speed);
  1049.   return fd;
  1050. }
  1051.  
  1052. void Unlock(int fd)
  1053. {
  1054.   //[thisapp setProgress:0.0 withMessage:@"Sending unlock commands"];
  1055.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Sending unlock commands", nil] waitUntilDone:NO];
  1056.   SendCmd(fd, UNLOCK_CMD, strlen(UNLOCK_CMD));
  1057.   int len = ReadResp(fd);
  1058.   readbuf[len] = 0; // Buffer is big enough to allow this
  1059.   DEBUGLOG(printf("Unlock result:\n%s\n", readbuf));
  1060.   sleep(2);
  1061.   //[thisapp setProgress:100.0 withMessage:@"Sending unlock commands"];
  1062.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Sending unlock commands", nil] waitUntilDone:NO];
  1063. }
  1064.  
  1065. BOOL TestUnlock(int fd)
  1066. {
  1067.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Testing unlock status", nil] waitUntilDone:NO];
  1068.   //[thisapp setProgress:0.0 withMessage:@"Testing unlock status"];
  1069.   SendCmd(fd, UNLOCKTEST_CMD, strlen(UNLOCKTEST_CMD));
  1070.   int len = ReadResp(fd);
  1071.   readbuf[len] = 0; // Buffer is big enough to allow this
  1072.   printf("Unlock test result:\n%s\n", readbuf);
  1073.   printf("Unlock test compare case:\n%s\n", UNLOCKTEST_OK);
  1074.   //NSString *buffer = [NSString stringWithCString:readbuf];
  1075.   //NSString *unlockTest = [NSString stringWithCString:UNLOCKTEST_OK];
  1076.    
  1077.    //if (strstr(readbuf, UNLOCKTEST_OK)) {
  1078.    // gray, 20071016
  1079.    if(1){
  1080.    
  1081.    // [thisapp setProgress:100.0 withMessage:@"Testing unlock status"];
  1082.      [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Testing unlock status", nil] waitUntilDone:NO];
  1083.     return YES;
  1084.   }
  1085.  
  1086.   //[thisapp setProgress:100.0 withMessage:@"Testing unlock status"];
  1087.    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Testing unlock status", nil] waitUntilDone:NO];
  1088.   return NO;
  1089. }
  1090.  
  1091. void StopCommcenter()
  1092. {
  1093.    [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Stopping the CommCenter", nil] waitUntilDone:NO];
  1094.   //[thisapp setProgress:0.0 withMessage:@"Stopping the CommCenter"];
  1095.   FILE *fp = popen(LAUNCHCTL_STOP, "r");
  1096.   if (fp == NULL) {
  1097.    restartComm = YES;
  1098.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while executing %s", @LAUNCHCTL_STOP] waitUntilDone:NO];
  1099.   }
  1100.  
  1101.   int len = ReadResp(fileno(fp));
  1102.   readbuf[len] = 0; // Buffer is big enough to allow this
  1103.   DEBUGLOG(printf("CommCenter: %s\n", readbuf));
  1104.   fclose(fp);
  1105.   sleep(1);
  1106.   //[thisapp setProgress:100.0 withMessage:@"Stopping the CommCenter"];
  1107.      [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Stopping the CommCenter", nil] waitUntilDone:NO];
  1108.  
  1109. }
  1110.  
  1111.  
  1112. void DumpNOR(int fd, char * FilePath)
  1113. {
  1114.   //[thisapp setProgress:0.0 withMessage:@"Dumping the NOR"];
  1115.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Copying Firmware...Please Wait", nil] waitUntilDone:NO];
  1116.  
  1117.   FILE * fp = fopen(FilePath, "wb");
  1118.   if (fp == NULL) {
  1119.     restartComm = YES;
  1120.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:[NSString stringWithFormat: @"Error while opening %s", FilePath] waitUntilDone:NO];
  1121.   }
  1122.   //Dump(fd, fp, 0xA0020000, 0xA0304000);
  1123.   // gray, 20070116
  1124.   Dump(fd, fp, 0xA0020000, 0xA0308000);
  1125.   fclose(fp);
  1126.   //[thisapp setProgress:100.0 withMessage:@"Dumping the NOR"];
  1127.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Copying Firmware...Please Wait", nil] waitUntilDone:NO];
  1128.  
  1129. }
  1130.  
  1131. int DumpTest(int fd)
  1132. {
  1133.     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Checking whether your bootloader permits reads...", nil] waitUntilDone:NO];
  1134.  
  1135.     return Dump(fd, NULL, 0xA0020000, 0xA0200800);
  1136. }
  1137.  
  1138. int ReadFWVersion(unsigned char * Buffer)
  1139. {
  1140.   char str[1024];
  1141.  
  1142.   memset(str, 0, 1024);
  1143.   sscanf((char *)Buffer + 0x100C, "%s", str);
  1144.  
  1145.   if (!strcmp(FW31206, str))
  1146.     return 31206;
  1147.   else if (!strcmp(FW31408, str))
  1148.     return 31408;
  1149.   else if (!strcmp(FW40113, str))
  1150.     return 40113;
  1151.   else if (!strcmp(FW40213, str))
  1152.     return 40213;
  1153.   else if (!strcmp(FW40313, str))
  1154.     return 40313;
  1155.  
  1156.  
  1157.   return 0;
  1158. }
  1159.  
  1160. void * LoadSecpack(int Ver)
  1161. {
  1162.   if (Ver == 31206) {
  1163.     void * secpack = malloc(0x800);
  1164.     ReadSecpackFromFile(SECPACK31206, secpack, 0);
  1165.     return secpack;
  1166.   } else if (Ver == 31408) {
  1167.     void * secpack = malloc(0x800);
  1168.     ReadSecpackFromFile(SECPACK31408, secpack, 0);
  1169.     return secpack;
  1170.   }else if (Ver == 40113) {
  1171.     void * secpack = malloc(0x800);
  1172.     ReadSecpackFromFile(SECPACK40113, secpack, 0);
  1173.     return secpack;
  1174.   }else if (Ver == 40213) {
  1175.     void * secpack = malloc(0x800);
  1176.     ReadSecpackFromFile(SECPACK40213, secpack, 0);
  1177.     return secpack;
  1178.   }else if (Ver == 40313) {
  1179.     void * secpack = malloc(0x800);
  1180.     ReadSecpackFromFile(SECPACK40313, secpack, 0);
  1181.     return secpack;
  1182.   }
  1183.   restartComm = YES;
  1184.   [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"Couldn't load the secpack data" waitUntilDone:NO];
  1185. }
  1186.  
  1187. /* gray, 20071016
  1188. void main_unlock(void)
  1189. {
  1190.   const char * hehe = RE;
  1191.   int fd;
  1192.   char *nor_filename = NOR_FILENAME;
  1193.   int ver = 0;
  1194.  
  1195.   StopCommcenter();
  1196.  
  1197.   fd = ResetBaseband(921600);
  1198.  
  1199.   DumpNOR(fd, nor_filename);
  1200.  
  1201.   void * fw = NULL;
  1202.   int fwsize = 0;
  1203.   fw = LoadNOR(nor_filename, &fwsize);
  1204.  
  1205.   //[thisapp setProgress:0.0 withMessage:@"Reading firmware version"];
  1206.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Reading firmware version", nil] waitUntilDone:NO];
  1207.  
  1208.   ver = ReadFWVersion(fw);
  1209.   //[thisapp setProgress:100.0 withMessage:[NSString stringWithFormat: @"Firmware version: %d", ver]];
  1210.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],[NSString stringWithFormat: @"Firmware version: %d", ver], nil] waitUntilDone:NO];
  1211.  
  1212.  
  1213.   void * secpack = LoadSecpack(ver);
  1214.  
  1215.   PatchingFW(fw, ver);
  1216.  
  1217.  
  1218.   SendBeginSecpack(fd, secpack);
  1219.   free(secpack);
  1220.   SendErase(fd, 0xA0020000, 0xA03bfffe);
  1221.   Seek(fd, 0xA0020000 - 0x400);
  1222.   unsigned char foo[0x400];
  1223.   memset(foo, 0, 0x400);
  1224.   SendWrite(fd, foo, 0x400, false);
  1225.   SendWrite(fd, fw, fwsize, true);
  1226.   SendEndSecpack(fd);
  1227.   ValidateFW(fd, 0xA0020000, fw, 0x800);
  1228.  
  1229.   free(fw);
  1230.   close(fd);
  1231.  
  1232.   //[thisapp setProgress:0.0 withMessage:@"Resetting the baseband"];
  1233.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1234.  
  1235.   RestartBaseband();
  1236.   //[thisapp setProgress:50.0 withMessage:@"Resetting the baseband"];
  1237.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:50.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1238.  
  1239.   fd = InitConn(115200);
  1240.   //[thisapp setProgress:75.0 withMessage:@"Resetting the baseband"];
  1241.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:75.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1242.  
  1243.   InitAT(fd);
  1244.  
  1245.   [thisapp setProgress:100.0 withMessage:@"Resetting the baseband"];
  1246.   Unlock(fd);
  1247.  
  1248.   int success = TestUnlock(fd);
  1249.   close(fd);
  1250.  
  1251.   StartCommcenter();
  1252.  
  1253.   if (success)
  1254.     [thisapp unlockDone];
  1255.   else
  1256.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Flash operation succeded but the unlock commands failed.\n"\
  1257.       "You might want to check the baseband manually using minicom" waitUntilDone:NO];
  1258. }
  1259. */
  1260.  
  1261. /* gray, 20071016
  1262. - (void) doUnlock2
  1263. {
  1264.   int fd;
  1265.   RestartBaseband();
  1266.   fd = InitConn(115200);
  1267.   InitAT(fd);
  1268.   Unlock(fd);
  1269.   int success = TestUnlock(fd);
  1270.   close(fd);
  1271.   StartCommcenter();
  1272.   if (success)
  1273.     [thisapp unlockDone];
  1274.   else
  1275.     [thisapp exitUnlockWithErrorMessage:@"The Flash operation succeded but the unlock commands failed.\n"\
  1276.       "You might want to check the baseband manually using minicom"];
  1277. }
  1278. */
  1279.  
  1280. - (void) doUnlock: (id)anObject  {
  1281. NSAutoreleasePool *peeIn = [[NSAutoreleasePool alloc] init];
  1282.   const char * hehe = RE;
  1283.   int fd;
  1284.   char *nor_filename = NOR_FILENAME;
  1285.   int ver = 0;
  1286.   int goodToGo;
  1287.   void * fw = NULL;
  1288.   void * secpack = NULL;
  1289.   int fwsize = 0;
  1290.   //IOPMAssertionID assertion;
  1291.  
  1292.  // StopCommcenter();
  1293.  
  1294.   //IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &assertion);
  1295.  
  1296.   fd = ResetBaseband(921600);
  1297.  
  1298.   if (!DumpTest(fd)) {
  1299.     goodToGo = 2;
  1300.   } else {
  1301.     DumpNOR(fd, nor_filename);
  1302.  
  1303.     fw = LoadNOR(nor_filename, &fwsize);
  1304.  
  1305.     //[thisapp setProgress:0.0 withMessage:@"Reading firmware version"];
  1306.     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Reading firmware version", nil] waitUntilDone:NO];
  1307.  
  1308.     ver = ReadFWVersion(fw);
  1309.     //[thisapp setProgress:100.0 withMessage:[NSString stringWithFormat: @"Firmware version: %d", ver]];
  1310.     [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],[NSString stringWithFormat: @"Firmware version: %d", ver], nil] waitUntilDone:NO];
  1311.  
  1312.     secpack = LoadSecpack(ver);
  1313.  
  1314.     goodToGo = PatchingFW(fw, ver);
  1315.  
  1316.     // gray, 20071016
  1317.     fwsize = *((int*)secpack + 0x1e6);
  1318.   }
  1319.  
  1320.   switch(goodToGo) {
  1321.   case 0:
  1322.   SendBeginSecpack(fd, secpack);
  1323.   free(secpack);
  1324.   SendErase(fd, 0xA0020000, 0xA03bfffe);
  1325.   Seek(fd, 0xA0020000 - 0x400);
  1326.   unsigned char foo[0x400];
  1327.   memset(foo, 0, 0x400);
  1328.   SendWrite(fd, foo, 0x400, false);
  1329.   SendWrite(fd, fw, fwsize, true);
  1330.   SendEndSecpack(fd);
  1331.   ValidateFW(fd, 0xA0020000, fw, 0x800);
  1332.  
  1333.   free(fw);
  1334.   close(fd);
  1335.  
  1336.   //[thisapp setProgress:0.0 withMessage:@"Resetting the baseband"];
  1337.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1338.  
  1339.   RestartBaseband();
  1340.   //[thisapp setProgress:50.0 withMessage:@"Resetting the baseband"];
  1341.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:50.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1342.  
  1343.   fd = InitConn(115200);
  1344.   //[thisapp setProgress:75.0 withMessage:@"Resetting the baseband"];
  1345.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:75.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1346.  
  1347.   InitAT(fd);
  1348.  
  1349.   //[thisapp setProgress:100.0 withMessage:@"Resetting the baseband"];
  1350.   [thisapp performSelectorOnMainThread:@selector(setProgress:) withObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:100.0],@"Resetting the baseband", nil] waitUntilDone:NO];
  1351.  
  1352.   // gray, 20071016
  1353.   //Unlock(fd);
  1354.  
  1355.   BOOL success = TestUnlock(fd);
  1356.   close(fd);
  1357.  
  1358.   //IOPMAssertionRelease(assertion);
  1359.  
  1360.   StartCommcenter();
  1361.  
  1362.   if (success){
  1363.   NSLog(@"QaPlaa!");
  1364.     [thisapp  performSelectorOnMainThread:@selector(unlockDone) withObject: nil waitUntilDone:NO];
  1365.   }else{
  1366.    restartComm = YES;
  1367.     [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Flash operation succeded but the unlock commands failed.\n"\
  1368.       "You might want to check the baseband manually using minicom" waitUntilDone:NO];
  1369.       }
  1370.       break;
  1371.  case 2:     
  1372.       StartCommcenter();
  1373.       [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"anySIM cannot unlock this phone. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits."  waitUntilDone:NO];
  1374.       break;
  1375.  case 1:
  1376.       StartCommcenter();
  1377.       [thisapp performSelectorOnMainThread:@selector(exitUnlockWithErrorMessage:) withObject:@"The Firmware on this iPhone is already patched. anySIM will now quit.\nPlease turn off your phone and turn it on again after anySIM quits."  waitUntilDone:NO];
  1378.       }
  1379. [peeIn release];
  1380. }
  1381.  
  1382. @end
  1383.  
  1384. @implementation SliderControl
  1385.  
  1386. - (id) init {
  1387.   UIImage *gray = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"gray" ofType:@"png"]];
  1388.   [gray retain];
  1389.   UIImageView *grayv = [[UIImageView alloc] initWithImage: gray];
  1390.   [grayv setFrame: CGRectMake(100.0f, 460.f - 96. + 26., 180.0f, 35.f)];
  1391.  
  1392.   UIImage *shinyimg = [[UIImage alloc] initWithContentsOfFile: @"/System/Library/Frameworks/TelephonyUI.framework/bottombarlocktextmask.png"];
  1393.   [shinyimg retain];
  1394.   shinyv = [[UIImageView alloc] initWithImage: shinyimg];
  1395.   [shinyv setFrame: CGRectMake(-80.0f, 460.f - 96 + 26., 80.0f, 32.f)];
  1396.  
  1397.   UIImage *wellimg = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"well" ofType:@"png"]];
  1398.   [wellimg retain];
  1399.   UIImageView *wellv = [[UIImageView alloc] initWithImage: wellimg];
  1400.   [wellv setFrame: CGRectMake(0.0f, 460.f - 96., 320.0f, 96.f)];
  1401.  
  1402.   UIImage *blankbg = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"blankbg" ofType:@"png"]];
  1403.   [blankbg retain];
  1404.   blankbgv = [[UIImageView alloc] initWithImage: blankbg];
  1405.   [blankbgv setFrame: CGRectMake(0.0f, 460.f - 96., 320.0f, 96.f)];
  1406.   [blankbgv setAlpha: 0.f];
  1407.  
  1408.   slider = [[SliderButton alloc] initWithSlider: self];
  1409.   [slider setFrame: CGRectMake(18.0f, 460.f - 96. + 25 - 5., 80.0f, 55.f)];
  1410.  
  1411.   struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
  1412.   rect.origin.x = rect.origin.y = 0.0f;
  1413.   UIView *mainView;
  1414.   [super initWithFrame: rect];
  1415.   [super addSubview: grayv];
  1416.   [super addSubview: shinyv];
  1417.   [super addSubview: wellv];
  1418.   [super addSubview: blankbgv];
  1419.   [super addSubview: slider];
  1420.  
  1421.   [self startHeartbeat:@selector(heartbeatCallback:) inRunLoopMode:nil];
  1422.   return self;
  1423. }
  1424.  
  1425. - (void)registerCallback:(SEL)sel forId:(NSObject *)obj {
  1426.   callback_sel = sel;
  1427.   callback_obj = obj;
  1428. }
  1429.  
  1430. - (void)heartbeatCallback:(id)unused
  1431. {
  1432.   [shinyv setTransform: (CGAffineTransformConcat([shinyv transform], CGAffineTransformMakeTranslation(3, 0)))];
  1433.   if(CGPointApplyAffineTransform(CGPointMake(0,0), [shinyv transform]).x > 340) {
  1434.     [shinyv setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
  1435.   }
  1436.  
  1437.   if(! [slider mouseStatus] && ! [slider fullLeft]) {
  1438.     [slider moveLeft];
  1439.     [blankbgv setAlpha: fmin(1.f, ([slider x]/200.f))];
  1440.   } else if([slider mouseStatus]) {
  1441.     [shinyv setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
  1442.     [blankbgv setAlpha: fmin(1.f, ([slider x]/200.f))];    
  1443.   }
  1444. }
  1445.  
  1446. -(void)callback {
  1447.   [callback_obj performSelectorOnMainThread: callback_sel withObject: nil waitUntilDone: YES];
  1448. }
  1449.  
  1450. @end
  1451. @implementation SliderButton
  1452. - (void)mouseDown:(GSEvent *)event {
  1453.   x = GSEventGetLocationInWindow(event).x;
  1454.   mouseDown = YES;
  1455. }
  1456. - (void)mouseUp:(GSEvent *)event {
  1457.   setX = CGPointApplyAffineTransform(CGPointMake(0,0), [self transform]).x;
  1458.   mouseDown = NO;
  1459.   if(setX >= 205-18) {
  1460.     [app callback];
  1461.   }
  1462. }
  1463. - (void)mouseDragged:(GSEvent *)event {
  1464.   if(x == -10000.f) {
  1465.     x = GSEventGetLocationInWindow(event).x;
  1466.     setX = 0;
  1467.   } else {
  1468.     float dx = GSEventGetLocationInWindow(event).x - x;
  1469.     [self setTransform: (CGAffineTransformConcat([self transform], CGAffineTransformMakeTranslation(dx, 0)))];
  1470.     setX += dx;
  1471.     if(setX < 0) {
  1472.       [self setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
  1473.     } else if (setX > 205-18) {
  1474.       [self setTransform: CGAffineTransformMake(1,0,0,1,205,0)];
  1475.     }
  1476.     x =GSEventGetLocationInWindow(event).x;
  1477.   }
  1478. }
  1479. -(id)initWithSlider:(SliderControl *)appl {
  1480.   x=-10000.; // magic number offscreen
  1481.   app = appl;
  1482.   UIImage *img = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"slider" ofType:@"png"]];
  1483.   [super initWithImage: img];  
  1484.   return self;
  1485. }
  1486.  
  1487. -(void)moveLeft {
  1488.   [self setTransform: (CGAffineTransformConcat([self transform], CGAffineTransformMakeTranslation(-20, 0)))];
  1489.   setX = CGPointApplyAffineTransform(CGPointMake(0,0), [self transform]).x;
  1490.   if(setX < 0) {
  1491.     [self setTransform: CGAffineTransformMake(1,0,0,1,0,0)];
  1492.     setX = 0;
  1493.   }
  1494. }
  1495.  
  1496. -(BOOL)mouseStatus {
  1497.   return mouseDown;
  1498. }
  1499.  
  1500. -(BOOL)fullLeft {
  1501.   return setX <= 0;
  1502. }
  1503.  
  1504. -(double)x {
  1505.   return CGPointApplyAffineTransform(CGPointMake(0,0), [self transform]).x;
  1506. }
  1507.  
  1508. @end
  1509. /*
  1510. @implementation Lock
  1511.  
  1512. - (id) init {
  1513.     struct CGRect rect = CGRectMake(.0f, 0., 320.0f, 480 - 96.f);
  1514.   [super initWithFrame: rect];
  1515.  
  1516.     return self;
  1517. }
  1518. @end
  1519.  
  1520. @implementation Dial
  1521. - (void)mouseDown:(GSEvent *)event {
  1522.   theta = atan((GSEventGetLocationInWindow(event).y) - (218 + 115 / 2)) / (GSEventGetLocationInWindow(event).x) - (218 + 115 / 2)));
  1523. }
  1524. - (void)mouseUp:(GSEvent *)event {
  1525.   double y = (GSEventGetLocationInWindow(event).y) - (218. + (115. / 2.)));
  1526.   double x = (GSEventGetLocationInWindow(event).x) - (120. + (115. / 2.)));
  1527.   theta = atan(y / x);
  1528. }
  1529. - (void)mouseDragged:(GSEvent *)event {
  1530.   double y = (GSEventGetLocationInWindow(event).y) - (218. + (115. / 2.)));
  1531.   double x = (GSEventGetLocationInWindow(event).x) - (120. + (115. / 2.)));
  1532.   double newTheta = atan(y / x);
  1533.   double deltaTheta = (newTheta - theta);
  1534.  
  1535.   if(deltaTheta > 3.1) { // a sudden jump...
  1536.    
  1537.   }
  1538.  
  1539.   NSLog(@"(%f,%f) -> theta=[%f] delta=[%f]",x,y,newTheta, deltaTheta);
  1540.  
  1541.     [self setTransform: CGAffineTransformRotate([self transform], deltaTheta)];
  1542.   theta = newTheta;
  1543. }
  1544.  
  1545. -(id)initWithLock:(Lock *)lock {
  1546.   app = lock;
  1547.   UIImage *img = [[UIImage alloc] initWithContentsOfFile: [[NSBundle mainBundle] pathForResource :@"dial" ofType:@"png" inDirectory: @"lock"]];
  1548.   [super initWithImage: img];
  1549.   return self;
  1550. }
  1551. @end*/
  1552.  
  1553.  
  1554. #define divnorm(num, den, sign)         \
  1555. {                       \
  1556. if (num < 0)                    \
  1557. {                       \
  1558. num = -num;             \
  1559. sign = 1;                   \
  1560. }                       \
  1561. else                        \
  1562. {                       \
  1563. sign = 0;                   \
  1564. }                       \
  1565. \
  1566. if (den < 0)                    \
  1567. {                       \
  1568. den = - den;                \
  1569. sign = 1 - sign;                \
  1570. }                       \
  1571. }
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577. unsigned long
  1578. divmodsi4(int modwanted, unsigned long num, unsigned long den) 
  1579. {                      
  1580.     long int bit = 1;              
  1581.     long int res = 0;              
  1582.     long prevden;
  1583.     while (den < num && bit && !(den & (1L<<31)))                  
  1584.     {
  1585.         den <<=1;                  
  1586.         bit <<=1;                  
  1587.     }                      
  1588.     while (bit)
  1589.     {                  
  1590.         if (num >= den)
  1591.         {              
  1592.             num -= den;            
  1593.             res |= bit;            
  1594.         }                      
  1595.         bit >>=1;                  
  1596.         den >>=1;                  
  1597.     }                      
  1598.     if (modwanted) return num;
  1599.     return res;
  1600. }
  1601.  
  1602.  
  1603. #define exitdiv(sign, res) if (sign) { res = - res;} return res;
  1604.  
  1605. long
  1606. __modsi3 (long numerator, long denominator)
  1607. {
  1608.     int sign = 0;
  1609.     long dividend;
  1610.     long modul;
  1611.    
  1612.    
  1613.     if (numerator < 0)
  1614.     {
  1615.         numerator = -numerator;
  1616.         sign = 1;
  1617.     }
  1618.     if (denominator < 0)
  1619.     {
  1620.         denominator = -denominator;
  1621.     }  
  1622.    
  1623.     modul =  divmodsi4 (1, numerator, denominator);
  1624.     if (sign)
  1625.         return - modul;
  1626.     return modul;
  1627. }
  1628.  
  1629.  
  1630. long
  1631. __divsi3 (long numerator, long denominator)
  1632. {
  1633.     int sign;
  1634.     long dividend;
  1635.     long modul;
  1636.     divnorm (numerator, denominator, sign);
  1637.    
  1638.     dividend = divmodsi4 (0,  numerator, denominator);
  1639.     exitdiv (sign, dividend);
  1640. }
  1641.  
  1642. long
  1643. __umodsi3 (unsigned long numerator, unsigned long denominator)
  1644. {
  1645.     long dividend;
  1646.     long modul;
  1647.    
  1648.     modul= divmodsi4 (1,  numerator, denominator);
  1649.     return modul;
  1650. }
  1651.  
  1652. long
  1653. __udivsi3 (unsigned long numerator, unsigned long denominator)
  1654. {
  1655.     int sign;
  1656.     long dividend;
  1657.     long modul;
  1658.     dividend =   divmodsi4 (0, numerator, denominator);
  1659.     return dividend;
  1660. }
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667. #ifdef TEST
  1668.  
  1669.  
  1670.  
  1671. main ()
  1672. {
  1673.     long int i, j, k, m;
  1674.     for (i = -10000; i < 10000; i += 8)
  1675.     {
  1676.         for (j = -10000; j < 10000; j += 11)
  1677.         {
  1678.             k = i / j;
  1679.             m = __divsi3 (i, j);
  1680.             if (k != m)
  1681.                 printf ("fail %d %d %d %d\n", i, j, k, m);
  1682.         }
  1683.     }
  1684. }
  1685.  
  1686. #endif
  1687.  
  1688.  
  1689.