00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <barry/barry.h>
00027 #include <iostream>
00028 #include <vector>
00029 #include <string>
00030 #include <cstring>
00031 #include <algorithm>
00032 #include <getopt.h>
00033 #include <fstream>
00034 #include <string.h>
00035
00036
00037 #define CMD_LIST "dir"
00038 #define CMD_ERASE "erase"
00039 #define CMD_LOAD "load"
00040 #define CMD_SCREENSHOT "screenshot"
00041 #define CMD_SETTIME "settime"
00042 #define CMD_EVENTLOG "eventlog"
00043 #define CMD_CLEAR_LOG "cleareventlog"
00044 #define CMD_SAVE "save"
00045 #define CMD_DEVICEINFO "deviceinfo"
00046 #define CMD_WIPE "wipe"
00047 #define CMD_LOGSTRACES "logstacktraces"
00048 #define CMD_RESETFACTORY "resettofactory"
00049
00050
00051 #define TIME_FMT "%Y-%m-%d %H:%M:%S"
00052 #define TIME_FMT_EXAMPLE "yyyy-mm-dd HH:MM:SS"
00053
00054 using namespace std;
00055 using namespace Barry;
00056
00057 void Usage()
00058 {
00059 int major, minor;
00060 const char *Version = Barry::Version(major, minor);
00061
00062 cerr
00063 << "bjavaloader - Command line USB Blackberry Java Loader\n"
00064 << " Copyright 2008-2009, Nicolas VIVIEN.\n"
00065 << " Copyright 2005-2009, Net Direct Inc. (http://www.netdirect.ca/)\n"
00066 << " Using: " << Version << "\n"
00067 << "\n"
00068 << " -a Wipe applications only\n"
00069 << " -i Wipe filesystem only\n"
00070 << " -f Force erase, if module is in use\n"
00071 << " -h This help\n"
00072 << " -s List sibling in module list\n"
00073 << " -p pin PIN of device to talk with\n"
00074 << " If only one device is plugged in, this flag is optional\n"
00075 << " -P pass Simplistic method to specify device password\n"
00076 << " -v Dump protocol data during operation\n"
00077 << "\n"
00078 << "commands\n"
00079 << "\n"
00080 << " " << CMD_LIST << " [-s]\n"
00081 << " Lists modules on the handheld\n"
00082 << "\n"
00083 << " " << CMD_DEVICEINFO << "\n"
00084 << " Provides information on the handheld\n"
00085 << "\n"
00086 << " " << CMD_LOAD << " <.cod file> ...\n"
00087 << " Loads modules onto the handheld\n"
00088 << "\n"
00089 << " " << CMD_SAVE << " <module name> ...\n"
00090 << " Retrieves modules from the handheld and writes to .cod file\n"
00091 << " Note: will overwrite existing files!\n"
00092 << "\n"
00093 << " " << CMD_WIPE << " [-a | -i]\n"
00094 << " Wipes the handheld\n"
00095 << " Use Caution: Wiping filesystem will remove all data\n"
00096 << " such as messages, contacts, etc.\n"
00097 << " Wiping applications will remove all .cod files\n"
00098 << " on the device, including OS .cod files.\n"
00099 << "\n"
00100 << " " << CMD_RESETFACTORY << "\n"
00101 << " Reset IT policy to factory defaults\n"
00102 << " Use Caution: Resetting IT policy to factory defaults will\n"
00103 << " also perform a filesystem wipe which will remove\n"
00104 << " all data such as messages, contacts, etc.\n"
00105 << "\n"
00106 << " " << CMD_ERASE << " [-f] <module name> ...\n"
00107 << " Erase module from handheld\n"
00108 << "\n"
00109 << " " << CMD_EVENTLOG << "\n"
00110 << " Retrieves the handheld event log\n"
00111 << "\n"
00112 << " " << CMD_CLEAR_LOG << "\n"
00113 << " Clears the handheld event log\n"
00114 << "\n"
00115 << " " << CMD_LOGSTRACES << "\n"
00116 << " Dump the stack traces for all threads to the event log\n"
00117 << "\n"
00118 << " " << CMD_SCREENSHOT << " <.bmp file>\n"
00119 << " Make a screenshot of handheld\n"
00120 << "\n"
00121 << " " << CMD_SETTIME << " [" << TIME_FMT_EXAMPLE << "]\n"
00122 << " Sets the time on the handheld to the current time\n"
00123 << " Or the time specified as an argument to " << CMD_SETTIME << "\n"
00124 << " If given as argument, current system timezone is assumed\n"
00125 << endl;
00126 }
00127
00128
00129 class AutoClose
00130 {
00131 FILE *fp;
00132
00133 public:
00134 AutoClose(FILE *fh) : fp(fh) {}
00135 ~AutoClose()
00136 {
00137 fclose(fp);
00138 }
00139 };
00140
00141 void SetTime(Barry::Mode::JavaLoader *javaloader, const char *timestr)
00142 {
00143 time_t when;
00144
00145 if( timestr ) {
00146 struct tm timeinfo;
00147 memset(&timeinfo, 0, sizeof(timeinfo));
00148
00149
00150 char *p = strptime(timestr, TIME_FMT, &timeinfo);
00151
00152
00153
00154
00155 if( p == NULL || p != (timestr + strlen(timestr)) ) {
00156 throw runtime_error(string("Unable to parse time string: ") + timestr);
00157 }
00158
00159 when = mktime(&timeinfo);
00160 } else {
00161 time(&when);
00162 }
00163
00164 javaloader->SetTime(when);
00165 }
00166
00167 void SendAppFile(Barry::Mode::JavaLoader *javaloader, const char *filename)
00168 {
00169 ifstream file(filename);
00170 javaloader->LoadApp(file);
00171 }
00172
00173 void GetScreenshot(Barry::Mode::JavaLoader *javaloader, const char *filename)
00174 {
00175
00176
00177
00178
00179 JLScreenInfo info;
00180 Data image;
00181 javaloader->GetScreenshot(info, image);
00182
00183
00184
00185 Data bitmap(-1, GetTotalBitmapSize(info));
00186 ScreenshotToBitmap(info, image, bitmap);
00187
00188
00189 FILE *fp = fopen(filename, "wb");
00190 if (fp == NULL) {
00191 throw runtime_error(string("Can't open: ") + filename);
00192 }
00193 AutoClose ac(fp);
00194
00195 fwrite(bitmap.GetData(), bitmap.GetSize(), 1, fp);
00196 }
00197
00198 void SaveModule(Barry::Mode::JavaLoader *javaloader, const char *filename)
00199 {
00200 string fname(filename), module;
00201
00202 size_t ext_index = fname.rfind(".cod");
00203 if( ext_index != string::npos ) {
00204
00205 module = fname.substr(0, ext_index);
00206 }
00207 else {
00208
00209 module = fname;
00210
00211 fname.append(".cod");
00212 }
00213
00214 ofstream file(fname.c_str(), ios::binary | ios::trunc);
00215 javaloader->Save(module.c_str(), file);
00216 }
00217
00218
00219 int main(int argc, char *argv[])
00220 {
00221 cout.sync_with_stdio(true);
00222
00223
00224 try {
00225
00226 uint32_t pin = 0;
00227 bool list_siblings = false,
00228 force_erase = false,
00229 data_dump = false,
00230 wipe_apps = true,
00231 wipe_fs = true;
00232 string password;
00233 vector<string> params;
00234 string busname;
00235 string devname;
00236 string iconvCharset;
00237 Usb::EndpointPair epOverride;
00238
00239
00240 for(;;) {
00241 int cmd = getopt(argc, argv, "aifhsp:P:v");
00242 if( cmd == -1 )
00243 break;
00244
00245 switch( cmd )
00246 {
00247 case 'p':
00248 pin = strtoul(optarg, NULL, 16);
00249 break;
00250
00251 case 'P':
00252 password = optarg;
00253 break;
00254
00255 case 'f':
00256 force_erase = true;
00257 break;
00258
00259 case 's':
00260 list_siblings = true;
00261 break;
00262
00263 case 'v':
00264 data_dump = true;
00265 break;
00266
00267 case 'a':
00268 wipe_fs = false;
00269 break;
00270
00271 case 'i':
00272 wipe_apps = false;
00273 break;
00274
00275 case 'h':
00276 default:
00277 Usage();
00278 return 0;
00279 }
00280 }
00281
00282 argc -= optind;
00283 argv += optind;
00284
00285 if( argc < 1 ) {
00286 cerr << "missing command" << endl;
00287 Usage();
00288 return 1;
00289 }
00290
00291
00292 string cmd = argv[0];
00293 argc --;
00294 argv ++;
00295
00296
00297 for (; argc > 0; argc --, argv ++) {
00298 params.push_back(string(argv[0]));
00299 }
00300
00301
00302
00303 Barry::Init(data_dump);
00304
00305
00306
00307
00308 Barry::Probe probe;
00309 int activeDevice = probe.FindActive(pin);
00310 if( activeDevice == -1 ) {
00311 cerr << "No device selected, or PIN not found" << endl;
00312 return 1;
00313 }
00314
00315
00316 Barry::Controller con(probe.Get(activeDevice));
00317 Barry::Mode::JavaLoader javaloader(con);
00318
00319
00320
00321
00322 javaloader.Open(password.c_str());
00323 javaloader.StartStream();
00324
00325 if( cmd == CMD_LIST ) {
00326 JLDirectory dir;
00327 javaloader.GetDirectory(dir, list_siblings);
00328 cout << dir;
00329 }
00330 else if( cmd == CMD_LOAD ) {
00331 if( params.size() == 0 ) {
00332 cerr << "specify at least one .cod file to load" << endl;
00333 Usage();
00334 return 1;
00335 }
00336
00337 vector<string>::iterator i = params.begin(), end = params.end();
00338 for( ; i != end; ++i ) {
00339 cout << "loading " << (*i) << "... ";
00340 SendAppFile(&javaloader, (*i).c_str());
00341 cout << "done." << endl;
00342 }
00343 }
00344 else if( cmd == CMD_ERASE ) {
00345 if( params.size() == 0 ) {
00346 cerr << "specify at least one module to erase" << endl;
00347 Usage();
00348 return 1;
00349 }
00350
00351 vector<string>::iterator i = params.begin(), end = params.end();
00352 for( ; i != end; ++i ) {
00353 cout << "erasing: " << (*i) << "... ";
00354 if( force_erase )
00355 javaloader.ForceErase((*i));
00356 else
00357 javaloader.Erase((*i));
00358 cout << "done." << endl;
00359 }
00360 }
00361 else if( cmd == CMD_SCREENSHOT ) {
00362 if( params.size() == 0 ) {
00363 cerr << "specify a .bmp filename" << endl;
00364 Usage();
00365 return 1;
00366 }
00367
00368 GetScreenshot(&javaloader, params[0].c_str());
00369 }
00370 else if( cmd == CMD_SETTIME ) {
00371 if( params.size() > 0 ) {
00372 SetTime(&javaloader, params[0].c_str());
00373 } else {
00374 SetTime(&javaloader, NULL);
00375 }
00376 }
00377 else if( cmd == CMD_EVENTLOG ) {
00378 JLEventlog log;
00379 javaloader.GetEventlog(log);
00380 cout << log;
00381 }
00382 else if( cmd == CMD_CLEAR_LOG ) {
00383 javaloader.ClearEventlog();
00384 }
00385 else if( cmd == CMD_LOGSTRACES ) {
00386 javaloader.LogStackTraces();
00387 }
00388 else if( cmd == CMD_SAVE ) {
00389 if( params.size() == 0 ) {
00390 cerr << "specify at least one module to save" << endl;
00391 Usage();
00392 return 1;
00393 }
00394
00395 vector<string>::iterator i = params.begin(), end = params.end();
00396 for( ; i != end; ++i ) {
00397 cout << "saving: " << (*i) << "... ";
00398 SaveModule(&javaloader, (*i).c_str());
00399 cout << "done." << endl;
00400 }
00401 }
00402 else if( cmd == CMD_DEVICEINFO ) {
00403 JLDeviceInfo info;
00404 javaloader.DeviceInfo(info);
00405 cout << info;
00406 }
00407 else if( cmd == CMD_WIPE ) {
00408 cout
00409 << "Use Caution: Wiping filesystem will remove all data\n"
00410 << " such as messages, contacts, etc.\n"
00411 << " Wiping applications will remove all .cod files\n"
00412 << " on the device, including OS .cod files.\n\n"
00413 << "Continue with wipe? (yes/no) ";
00414 string confirm;
00415 getline(cin, confirm);
00416 if( confirm == "yes" ) {
00417 javaloader.Wipe(wipe_apps, wipe_fs);
00418 }
00419 else {
00420 cout << "Response of 'yes' not received, aborting." << endl;
00421 }
00422 }
00423 else if( cmd == CMD_RESETFACTORY ) {
00424 cout
00425 << "Use Caution: Resetting IT policy to factory defaults will\n"
00426 << " also perform a filesystem wipe which will remove\n"
00427 << " all data such as messages, contacts, etc.\n\n"
00428 << "Continue with wipe? (yes/no) ";
00429 string confirm;
00430 getline(cin, confirm);
00431 if( confirm == "yes" ) {
00432 javaloader.ResetToFactory();
00433 }
00434 else {
00435 cout << "Response of 'yes' not received, aborting." << endl;
00436 }
00437 }
00438 else {
00439 cerr << "invalid command \"" << cmd << "\"" << endl;
00440 Usage();
00441 return 1;
00442 }
00443
00444
00445 javaloader.StopStream();
00446
00447 }
00448 catch( Usb::Error &ue) {
00449 std::cout << endl;
00450 std::cerr << "Usb::Error caught: " << ue.what() << endl;
00451 return 1;
00452 }
00453 catch( Barry::Error &se ) {
00454 std::cout << endl;
00455 std::cerr << "Barry::Error caught: " << se.what() << endl;
00456 return 1;
00457 }
00458 catch( std::exception &e ) {
00459 std::cout << endl;
00460 std::cerr << "std::exception caught: " << e.what() << endl;
00461 return 1;
00462 }
00463
00464 return 0;
00465 }
00466