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