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