rajkosto

restoreUser.js

Mar 25th, 2018
772
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // restores all the files from sdcard:/user-restoreme/ to the internal USER partition, overwriting any existing
  2. // may cause your device to not be able to launch properly after a reboot, but should be recoverable by initializing data in recovery
  3. // DO NOT CHANGE THE PARTITION ID TO SYSTEM TO TRY AND ADD CUSTOM STUFF TO SYSTEM, VERY LIKELY BRICK IF YOU DO
  4. // - by rajkosto 25.03.2018.
  5.  
  6. if (IFileSystem.prototype.CreateDir === undefined || IFileSystem.prototype.DeleteDir === undefined)
  7. {
  8.     throw new Error("Missing IFileSystem functions, update your PegaSwitch from git!")
  9. }
  10.  
  11. if (IFile.prototype.SetSize === undefined)
  12. {
  13.     throw new Error("Missing IFile functions, update your PegaSwitch from git!")
  14. }
  15.  
  16. IFile.prototype.ReadPart = function (offset, size, buf) {
  17.     if(size instanceof ArrayBuffer || ArrayBuffer.isView(size)) {
  18.         buf = size;
  19.         size = buf.byteLength;
  20.     }
  21.     var ipcRes = this.sc.ipcMsg(0).datau64(0, offset, size).bDescriptor(buf, size, 1).sendTo(this.handle);
  22.     var bytes_read = [ipcRes.data[0], ipcRes.data[1]];
  23.     return ipcRes.asResult().replaceValue(bytes_read);
  24. };
  25.  
  26. sc.getFSPPR = function () {
  27.     if (sc.closed_pr !== undefined) {
  28.         return;
  29.     }
  30.     sc.enableTurbo();
  31.     var i = 0;
  32.     var srv = null;
  33.     while (true) {
  34.         sc.ipcMsg(2).setType(5).sendTo('pm:shell');
  35.         var srvResult = sc.getService("fsp-pr");
  36.         if(srvResult.isOk) {
  37.             srv = srvResult.getValue();
  38.             break;
  39.         }
  40.         i++;
  41.     }
  42.     utils.log('Got fsp-pr handle after ' + i + ' iterations: ');
  43.     utils.log('fsp-pr handle: 0x' + srv.toString(16));
  44.     sc.svcCloseHandle(srv).assertOk();
  45.     sc.closed_pr = true;
  46. };
  47.  
  48. sc.getFSPPR();
  49. sc.enableTurbo();
  50.  
  51. if(sc.pr_handle) {
  52.     sc.svcCloseHandle(sc.pr_handle);
  53.     sc.pr_handle = undefined;
  54. }
  55.  
  56. sc.getService("fsp-pr", (fsppr) => {
  57.     var pid = sc.getService('fsp-srv', (tmp_hnd) => {
  58.         utils.log("got fspsrv handle: 0x" + tmp_hnd.toString(16));
  59.         sc.ipcMsg(1).sendPid().data(0).sendTo(tmp_hnd).assertOk();
  60.         return sc.read4(sc.ipcBufAddr, 0xC >> 2);
  61.     });
  62.     utils.log('Got process PID: '+pid.toString(16));
  63.    
  64.     var buf1_sz = 0x1C;
  65.     var buf2_sz = 0x2C;
  66.     var buf = sc.malloc(buf1_sz + buf2_sz);
  67.     var buf2 = utils.add2(buf, buf1_sz);
  68.    
  69.     // buffer init
  70.     sc.write4(1, buf, 0x0>>2);
  71.     sc.write8([0xFFFFFFFF, 0xFFFFFFFF], buf, 0x4 >> 2); // This is the permissions value.
  72.     sc.write4(buf1_sz, buf, 0xC >> 2);
  73.     sc.write4(buf1_sz, buf, 0x14 >> 2);
  74.    
  75.     sc.write4(1, buf2, 0x0 >> 2);
  76.     sc.write8([0xFFFFFFFF, 0xFFFFFFFF], buf2, 0x4 >> 2); // This is the permissions value -- actual perms = buf2_val & buf1_val
  77.     sc.write4(0xFFFFFFFF, buf2, 0x14 >> 2);
  78.     sc.write4(0xFFFFFFFF, buf2, 0x18 >> 2);
  79.     sc.write4(0xFFFFFFFF, buf2, 0x24 >> 2);
  80.     sc.write4(0xFFFFFFFF, buf2, 0x28 >> 2);
  81.    
  82.     /* Change to mount a particular title's romfs */
  83.     var tid = '0000000000000000';
  84.    
  85.     sc.ipcMsg(256).data(0).sendTo(fsppr).assertOk().show();
  86.     sc.ipcMsg(1).data(pid).sendTo(fsppr).assertOk().show();
  87.     sc.ipcMsg(0).data(2, [pid,0], utils.parseAddr(tid), buf1_sz, buf2_sz, pid, pid, 0, 0, 0, 0, 0).aDescriptor(buf, buf1_sz).aDescriptor(buf2, buf2_sz).sendTo(fsppr).assertOk().show();
  88.     sc.free(buf);
  89.     sc.free(buf2);
  90. });
  91.  
  92. foreachDirEntry = function(dir_obj, callback)
  93. {
  94.     var entryCount = utils.trunc32(dir_obj.GetEntryCount().assertOk());
  95.     if (entryCount > 0 && callback !== undefined)
  96.     {
  97.         var entryBuf = new Uint32Array(0x310 * entryCount);
  98.         dir_obj.GetEntries(entryBuf, entryCount).assertOk();
  99.         for (var entryIdx = 0; entryIdx < entryCount; entryIdx++)
  100.         {
  101.             var fn = utils.u8a2str(new Uint8Array(entryBuf.buffer, 0x310 * entryIdx, 0x300));
  102.             for (var strIdx=0; strIdx<fn.length; strIdx++)
  103.             {
  104.                 if (fn.charCodeAt(strIdx) === 0)
  105.                 {
  106.                     fn = fn.substring(0, strIdx);
  107.                     break;
  108.                 }
  109.             }
  110.             var eType = entryBuf[(0x310 * entryIdx + 0x304) >> 2];         
  111.             callback(fn, eType);
  112.         }
  113.     }
  114.    
  115.     return entryCount;
  116. };
  117.  
  118. copyFiles = function(src_dir, dst_dir)
  119. {
  120.     var thefiles = [];
  121.     foreachDirEntry(src_dir, function(fn, eType)
  122.     {
  123.         if (eType === 1) { thefiles.push(fn); }
  124.     });
  125.     //dont need handle to dst_dir anymore (and it will interfere with Commit ops)
  126.     var dst_dir_fs = dst_dir.fs;
  127.     var dst_dir_path = dst_dir.path;
  128.     dst_dir.Close(); dst_dir = null;
  129.  
  130.     var CHUNK_SIZE = 1024*1024;
  131.     var buf = new ArrayBuffer(CHUNK_SIZE);
  132.     for (var fileIdx=0; fileIdx<thefiles.length; fileIdx++)
  133.     {
  134.         var fn = thefiles[fileIdx];
  135.         utils.log('[Opening existing file] ' + src_dir.path + fn);
  136.         var f_src = src_dir.fs.OpenFile(src_dir.path + fn).assertOk();
  137.         var size = f_src.GetSize().assertOk();
  138.         utils.log('[Source file size] ' + src_dir.path + fn + ' = ' + size + ' bytes');
  139.  
  140.         var f_dst = null;
  141.         try
  142.         {
  143.             //try open existing destination file
  144.             f_dst = dst_dir_fs.OpenFile(dst_dir_path + fn);
  145.             if (f_dst.isOk) //file exists, so lets just resize it to target size
  146.             {
  147.                 f_dst = f_dst.assertOk();
  148.                 var dst_size = f_dst.GetSize().assertOk();
  149.                 if (!utils.eq(dst_size, size))
  150.                 {
  151.                     utils.log('[Resizing existing file] ' + dst_dir_path + fn + ' ' + dst_size + ' -> ' + size);
  152.                     f_dst.SetSize(dst_size).assertOk();
  153.                     var new_size = f_dst.GetSize().assertOk();
  154.                     utils.log('[Resize complete] ' + dst_dir_path + fn + ' now ' + new_size);
  155.                 }                
  156.             }
  157.             else
  158.             {
  159.                 utils.log('[Creating new file] ' + dst_dir_path + fn + ' with size ' + size + ' bytes');
  160.                 dst_dir_fs.CreateFile(dst_dir_path + fn, size).assertOk();
  161.                 utils.log('[Opening new file] ' + dst_dir_path + fn);          
  162.                 f_dst = dst_dir_fs.OpenFile(dst_dir_path + fn).assertOk();
  163.             }            
  164.             utils.log('[Open dst file OK] ' + dst_dir_path + fn);
  165.             var doneBytes = [0, 0];
  166.             for (var totalSize = size; !utils.eq(doneBytes, totalSize); )
  167.             {
  168.                 var currBlockSize = totalSize;
  169.                 if (!utils.nullptr(doneBytes)) { currBlockSize = utils.sub2(totalSize, doneBytes); }
  170.                 if ((currBlockSize[1] != 0) || (currBlockSize[0] > CHUNK_SIZE)) { currBlockSize = CHUNK_SIZE; }
  171.                 else { currBlockSize = utils.trunc32(currBlockSize); }
  172.                
  173.                 var read_bytes = f_src.ReadPart(doneBytes, currBlockSize, buf).assertOk();
  174.                 utils.log('[Read bytes] ' + '@' + doneBytes + ' (' + currBlockSize + ') returned ' + read_bytes );
  175.                 /*if ((read_bytes[1] != 0) || (read_bytes[0] != currBlockSize))
  176.                 {
  177.                     throw new Error("Read mismatch, wanted " + currBlockSize + " bytes, got " + read_bytes + " bytes");
  178.                 }*/
  179.  
  180.                 var sizeAfterWrite = utils.add2(doneBytes, read_bytes);
  181.                 f_dst.Write(doneBytes, buf, read_bytes).assertOk();
  182.                 utils.log('[Wrote bytes] ' + '@' + doneBytes + ' + ' + read_bytes);
  183.                 doneBytes = sizeAfterWrite;
  184.             }
  185.             utils.log('[Write file Complete] ' + dst_dir_path + fn + ' -> ' + doneBytes + ' bytes');
  186.             f_dst.Close(); f_dst = null;
  187.             utils.log('[Close file OK] ' + dst_dir_path + fn);
  188.         }
  189.         finally
  190.         {
  191.             if (f_dst !== null && f_dst instanceof IFile) { f_dst.Close(); f_dst = null; }
  192.             if (f_src !== null) { f_src.Close(); f_src = null; }
  193.         }
  194.     }
  195.  
  196.     return dst_dir;
  197. };
  198.  
  199. evaluateDirs = function(fs_obj, root_dir)
  200. {
  201.     var folders = [];
  202.    
  203.     var dir_obj = fs_obj.OpenDir(root_dir, 1); //directories only
  204.     if (!dir_obj.isOk) { return folders; } //no dirs
  205.     else { dir_obj = dir_obj.assertOk(); }
  206.    
  207.     folders.push(dir_obj.path); //this dir
  208.     for (var evalIdx=0; evalIdx<folders.length; evalIdx++)
  209.     {
  210.         if (evalIdx !== 0)
  211.         {
  212.             dir_obj = fs_obj.OpenDir(folders[evalIdx], 1);
  213.             if (!dir_obj.isOk) { throw new Error('Unable to open dir ' + folders[evalIdx] + ' for listing'); }         
  214.             else { dir_obj = dir_obj.assertOk(); }
  215.         }
  216.  
  217.         foreachDirEntry(dir_obj, function(fn) { folders.push(dir_obj.path + fn + '/'); });
  218.         dir_obj.Close(); dir_obj = null;
  219.     }
  220.  
  221.     return folders;
  222. };
  223.  
  224. sc.getService('fsp-srv', (fsp_handle) => {
  225.     utils.log('initialized fsp-srv handle: 0x' + fsp_handle.toString(16));
  226.     sc.ipcMsg(1).sendPid().datau64(0).sendTo(fsp_handle).assertOk();
  227.  
  228.     mountSDCard = function () {
  229.         var self = this;
  230.         return sc.ipcMsg(18).sendTo(fsp_handle).asResult()
  231.             .map((r) => new self.sc.IFileSystem(self.sc, r.movedHandles[0]));
  232.     };
  233.    
  234.     mountBisFatPart = function (partId) {
  235.         var pbuf = new ArrayBuffer(1); //just a null terminator
  236.         var self = this;
  237.         return sc.ipcMsg(11).datau32(partId).xDescriptor(pbuf, pbuf.byteLength, 0).sendTo(fsp_handle).asResult()
  238.             .map((r) => new self.sc.IFileSystem(self.sc, r.movedHandles[0]));
  239.     };
  240.  
  241.     var fs_sd = null;
  242.     var fs_user = null;
  243.  
  244.     try {
  245.         utils.log("Mounting SD card");
  246.         try { fs_sd = mountSDCard().assertOk(); }
  247.         catch(e) { throw new Error("Failed to open SD card. Is it inserted?"); }
  248.         fs_sd.partition = "SDCARD";
  249.         utils.log('SDCARD handle = 0x' + fs_sd.handle.toString(16));
  250.  
  251.         var sdFolderName = "/user-restoreme/";
  252.         utils.log('[Listing folders in SDCARD] ' + sdFolderName);
  253.         var dirList = evaluateDirs(fs_sd, sdFolderName);
  254.         if (dirList.length < 1)
  255.         {
  256.             throw new Error("Unable to list SDCARD dir contents or it's empty");
  257.         }
  258.         utils.log(dirList.length + ' folders found to be restored');
  259.        
  260.         utils.log("Mounting USER partition");
  261.         try { fs_user = mountBisFatPart(30).assertOk(); }
  262.         catch(e) { throw new Error("Failed to mount USER partition"); }
  263.         fs_user.partition = "USER";
  264.         utils.log('USER handle = 0x' + fs_user.handle.toString());        
  265.  
  266.         for (var dirIndex = 0; dirIndex < dirList.length; dirIndex++)
  267.         {
  268.             var left_side = dirList[dirIndex];
  269.             var right_side = '/' + left_side.substring(sdFolderName.length);
  270.            
  271.             utils.log('[Opening folder on SD] '+ left_side);
  272.             var dir_sd = fs_sd.OpenDir(left_side, 2).assertOk();
  273.             utils.log('[Opening folder on USER] '+ right_side);
  274.             var dir_user = fs_user.OpenDir(right_side, 2);
  275.             if (!dir_user.isOk)
  276.             {
  277.                 utils.log('[Making folder on USER] '+ right_side);
  278.                 fs_user.CreateDir(right_side).assertOk();
  279.                 utils.log('[Opening newly made folder] ' + right_side);            
  280.                 dir_user = fs_user.OpenDir(right_side, 2).assertOk();
  281.                 utils.log('[New folder opened OK] '+ right_side);
  282.             }
  283.             else
  284.             {
  285.                 dir_user = dir_user.assertOk();
  286.                 utils.log('[Existing folder opened OK] '+ right_side);
  287.             }
  288.    
  289.             try
  290.             {
  291.                 dir_user = copyFiles(dir_sd, dir_user); //because we might change dst_dir inside
  292.             }
  293.             finally
  294.             {
  295.                 if (dir_sd !== null) { dir_sd.Close(); dir_sd = null; }
  296.                 if (dir_user !== null) { dir_user.Close(); dir_user = null; }
  297.             }
  298.         }
  299.        
  300.         utils.log('[Closing file systems]');
  301.     }
  302.     finally
  303.     {
  304.         if (fs_user !== null) { fs_user.Close(); fs_user = null; }
  305.         if (fs_sd !== null) { fs_sd.Close(); fs_sd = null; }
  306.     }
  307. });
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×