MainHexEditor.c 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372
  1. /** @file
  2. Defines the Main Editor data type -
  3. - Global variables
  4. - Instances of the other objects of the editor
  5. - Main Interfaces
  6. Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  7. SPDX-License-Identifier: BSD-2-Clause-Patent
  8. **/
  9. #include "HexEditor.h"
  10. #include "EditStatusBar.h"
  11. #include "EditInputBar.h"
  12. HEFI_EDITOR_COLOR_ATTRIBUTES HOriginalColors;
  13. INTN HOriginalMode;
  14. //
  15. // the first time editor launch
  16. //
  17. BOOLEAN HEditorFirst;
  18. //
  19. // it's time editor should exit
  20. //
  21. BOOLEAN HEditorExit;
  22. BOOLEAN HEditorMouseAction;
  23. extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
  24. extern HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar;
  25. extern BOOLEAN HBufferImageMouseNeedRefresh;
  26. extern BOOLEAN HBufferImageNeedRefresh;
  27. extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
  28. HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
  29. HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar;
  30. //
  31. // basic initialization for MainEditor
  32. //
  33. HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = {
  34. &HBufferImage,
  35. {
  36. {0, 0}
  37. },
  38. {
  39. 0,
  40. 0
  41. },
  42. NULL,
  43. FALSE,
  44. NULL,
  45. 0,
  46. 0,
  47. 1,
  48. 1
  49. };
  50. /**
  51. Help info that will be displayed.
  52. **/
  53. EFI_STRING_ID HexMainMenuHelpInfo[] = {
  54. STRING_TOKEN(STR_HEXEDIT_HELP_TITLE),
  55. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  56. STRING_TOKEN(STR_HEXEDIT_HELP_LIST_TITLE),
  57. STRING_TOKEN(STR_HEXEDIT_HELP_DIV),
  58. STRING_TOKEN(STR_HEXEDIT_HELP_GO_TO_OFFSET),
  59. STRING_TOKEN(STR_HEXEDIT_HELP_SAVE_BUFFER),
  60. STRING_TOKEN(STR_HEXEDIT_HELP_EXIT),
  61. STRING_TOKEN(STR_HEXEDIT_HELP_SELECT_START),
  62. STRING_TOKEN(STR_HEXEDIT_HELP_SELECT_END),
  63. STRING_TOKEN(STR_HEXEDIT_HELP_CUT),
  64. STRING_TOKEN(STR_HEXEDIT_HELP_PASTE),
  65. STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_FILE),
  66. STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_DISK),
  67. STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_MEMORY),
  68. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  69. STRING_TOKEN(STR_HEXEDIT_HELP_EXIT_HELP),
  70. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  71. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  72. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  73. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  74. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  75. STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  76. STRING_TOKEN(STR_HEXEDIT_HELP_DIV),
  77. 0
  78. };
  79. /**
  80. show help menu.
  81. @retval EFI_SUCCESS The operation was successful.
  82. **/
  83. EFI_STATUS
  84. HMainCommandDisplayHelp (
  85. VOID
  86. )
  87. {
  88. INT32 CurrentLine;
  89. CHAR16 *InfoString;
  90. EFI_KEY_DATA KeyData;
  91. EFI_STATUS Status;
  92. UINTN EventIndex;
  93. //
  94. // print helpInfo
  95. //
  96. for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) {
  97. InfoString = HiiGetString(gShellDebug1HiiHandle, HexMainMenuHelpInfo[CurrentLine]
  98. , NULL);
  99. ShellPrintEx (0,CurrentLine+1,L"%E%s%N",InfoString);
  100. }
  101. //
  102. // scan for ctrl+w
  103. //
  104. while (TRUE) {
  105. Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
  106. if (EFI_ERROR (Status) || (EventIndex != 0)) {
  107. continue;
  108. }
  109. Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
  110. if (EFI_ERROR (Status)) {
  111. continue;
  112. }
  113. if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) ||
  114. (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) {
  115. //
  116. // For consoles that don't support/report shift state,
  117. // CTRL+W is translated to L'W' - L'A' + 1.
  118. //
  119. if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {
  120. break;
  121. }
  122. } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&
  123. ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&
  124. ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) {
  125. //
  126. // For consoles that supports/reports shift state,
  127. // make sure that only CONTROL shift key is pressed.
  128. //
  129. if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {
  130. break;
  131. }
  132. }
  133. }
  134. // update screen with buffer's info
  135. HBufferImageNeedRefresh = TRUE;
  136. HBufferImageOnlyLineNeedRefresh = FALSE;
  137. HBufferImageRefresh ();
  138. return EFI_SUCCESS;
  139. }
  140. /**
  141. Move cursor to specified lines.
  142. @retval EFI_SUCCESS The operation was successful.
  143. **/
  144. EFI_STATUS
  145. HMainCommandGoToOffset (
  146. VOID
  147. )
  148. {
  149. UINTN Size;
  150. UINT64 Offset;
  151. EFI_STATUS Status;
  152. UINTN FRow;
  153. UINTN FCol;
  154. //
  155. // variable initialization
  156. //
  157. Size = 0;
  158. Offset = 0;
  159. FRow = 0;
  160. FCol = 0;
  161. //
  162. // get offset
  163. //
  164. Status = InputBarSetPrompt (L"Go To Offset: ");
  165. if (EFI_ERROR (Status)) {
  166. return Status;
  167. }
  168. Status = InputBarSetStringSize (8);
  169. if (EFI_ERROR (Status)) {
  170. return Status;
  171. }
  172. while (1) {
  173. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  174. //
  175. // ESC pressed
  176. //
  177. if (Status == EFI_NOT_READY) {
  178. return EFI_SUCCESS;
  179. }
  180. //
  181. // THE input string length should > 0
  182. //
  183. if (StrLen (InputBarGetString()) > 0) {
  184. Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
  185. if (EFI_ERROR (Status)) {
  186. StatusBarSetStatusString (L"Invalid Offset");
  187. return EFI_SUCCESS;
  188. }
  189. break;
  190. }
  191. }
  192. Size = HBufferImageGetTotalSize ();
  193. if (Offset >= Size) {
  194. StatusBarSetStatusString (L"Invalid Offset");
  195. return EFI_SUCCESS;
  196. }
  197. FRow = (UINTN)DivU64x32(Offset , 0x10) + 1;
  198. FCol = (UINTN)ModU64x32(Offset , 0x10) + 1;
  199. HBufferImageMovePosition (FRow, FCol, TRUE);
  200. HBufferImageNeedRefresh = TRUE;
  201. HBufferImageOnlyLineNeedRefresh = FALSE;
  202. HBufferImageMouseNeedRefresh = TRUE;
  203. return EFI_SUCCESS;
  204. }
  205. /**
  206. Save current opened buffer.
  207. If is file buffer, you can save to current file name or
  208. save to another file name.
  209. @retval EFI_SUCCESS The operation was successful.
  210. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  211. @retval EFI_LOAD_ERROR A load error occurred.
  212. **/
  213. EFI_STATUS
  214. HMainCommandSaveBuffer (
  215. VOID
  216. )
  217. {
  218. EFI_STATUS Status;
  219. BOOLEAN Done;
  220. CHAR16 *FileName;
  221. BOOLEAN OldFile;
  222. CHAR16 *Str;
  223. EFI_FILE_INFO *Info;
  224. SHELL_FILE_HANDLE ShellFileHandle;
  225. if (HMainEditor.BufferImage->BufferType != FileTypeFileBuffer) {
  226. if (!HMainEditor.BufferImage->Modified) {
  227. return EFI_SUCCESS;
  228. }
  229. Status = InputBarSetPrompt (L"Dangerous to save disk/mem buffer. Save (Yes/No/Cancel) ? ");
  230. if (EFI_ERROR (Status)) {
  231. return Status;
  232. }
  233. //
  234. // the answer is just one character
  235. //
  236. Status = InputBarSetStringSize (1);
  237. if (EFI_ERROR (Status)) {
  238. return Status;
  239. }
  240. //
  241. // loop for user's answer
  242. // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
  243. //
  244. while (1) {
  245. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  246. //
  247. // ESC pressed
  248. //
  249. if (Status == EFI_NOT_READY) {
  250. return EFI_SUCCESS;
  251. }
  252. switch (InputBarGetString()[0]) {
  253. case L'y':
  254. case L'Y':
  255. //
  256. // want to save this buffer first
  257. //
  258. Status = HBufferImageSave (
  259. NULL,
  260. HMainEditor.BufferImage->DiskImage->Name,
  261. HMainEditor.BufferImage->DiskImage->Offset,
  262. HMainEditor.BufferImage->DiskImage->Size,
  263. HMainEditor.BufferImage->MemImage->Offset,
  264. HMainEditor.BufferImage->MemImage->Size,
  265. HMainEditor.BufferImage->BufferType
  266. );
  267. if (EFI_ERROR (Status)) {
  268. StatusBarSetStatusString (L"BufferSave: Problems Writing");
  269. return Status;
  270. }
  271. return EFI_SUCCESS;
  272. case L'n':
  273. case L'N':
  274. //
  275. // the file won't be saved
  276. //
  277. return EFI_SUCCESS;
  278. case L'c':
  279. case L'C':
  280. return EFI_SUCCESS;
  281. }
  282. //
  283. // end of switch
  284. //
  285. }
  286. //
  287. // ENDOF WHILE
  288. //
  289. }
  290. //
  291. // ENDOF != FILEBUFFER
  292. //
  293. // This command will save currently opened file to disk.
  294. // You can choose save to another file name or just save to
  295. // current file name.
  296. // Below is the scenario of Save File command: (
  297. // Suppose the old file name is A )
  298. // 1. An Input Bar will be prompted: "File To Save: [ old file name]"
  299. // IF user press ESC, Save File command ends .
  300. // IF user press Enter, input file name will be A.
  301. // IF user inputs a new file name B, input file name will be B.
  302. //
  303. // 2. IF input file name is A, go to do Step 3.
  304. // IF input file name is B, go to do Step 4.
  305. //
  306. // 3. IF A is read only, Status Bar will show "Access Denied"
  307. // and Save File commands ends.
  308. // IF A is not read only, save file buffer to disk
  309. // and remove Modified flag in Title Bar , then Save File command ends.
  310. //
  311. // 4. IF B does not exist, create this file and save file buffer to it.
  312. // Go to do Step 7.
  313. // IF B exits, do Step 5.
  314. //
  315. // 5. An Input Bar will be prompted:
  316. // "File Exists. Overwrite ( Yes/No/Cancel ) ?"
  317. // IF user press 'y' or 'Y', do Step 6.
  318. // IF user press 'n' or 'N', Save File commands ends.
  319. // IF user press 'c' or 'C' or ESC, Save File commands ends.
  320. //
  321. // 6. IF B is a read-only file, Status Bar will show "Access Denied"
  322. // and Save File commands ends.
  323. // IF B can be read and write, save file buffer to B.
  324. //
  325. // 7. Update File Name field in Title Bar to B
  326. // and remove the Modified flag in Title Bar.
  327. //
  328. Str = CatSPrint(NULL,
  329. L"File to Save: [%s]",
  330. HMainEditor.BufferImage->FileImage->FileName
  331. );
  332. if (Str == NULL) {
  333. return EFI_OUT_OF_RESOURCES;
  334. }
  335. if (StrLen (Str) >= 50) {
  336. //
  337. // replace the long file name with "..."
  338. //
  339. Str[46] = L'.';
  340. Str[47] = L'.';
  341. Str[48] = L'.';
  342. Str[49] = L']';
  343. Str[50] = L'\0';
  344. }
  345. Status = InputBarSetPrompt (Str);
  346. if (EFI_ERROR (Status)) {
  347. return Status;
  348. }
  349. Status = InputBarSetStringSize (100);
  350. if (EFI_ERROR (Status)) {
  351. return Status;
  352. }
  353. //
  354. // get new file name
  355. //
  356. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  357. //
  358. // if user pressed ESC
  359. //
  360. if (Status == EFI_NOT_READY) {
  361. SHELL_FREE_NON_NULL (Str);
  362. return EFI_SUCCESS;
  363. }
  364. SHELL_FREE_NON_NULL (Str);
  365. //
  366. // if just enter pressed, so think save to current file name
  367. //
  368. if (StrLen (InputBarGetString()) == 0) {
  369. FileName = CatSPrint(NULL,
  370. L"%s",
  371. HMainEditor.BufferImage->FileImage->FileName
  372. );
  373. } else {
  374. FileName = CatSPrint(NULL, L"%s", InputBarGetString());
  375. }
  376. if (FileName == NULL) {
  377. return EFI_OUT_OF_RESOURCES;
  378. }
  379. if (!IsValidFileName (FileName)) {
  380. StatusBarSetStatusString (L"Invalid File Name");
  381. SHELL_FREE_NON_NULL (FileName);
  382. return EFI_SUCCESS;
  383. }
  384. OldFile = FALSE;
  385. //
  386. // save to the old file
  387. //
  388. if (StringNoCaseCompare (
  389. &FileName,
  390. &HMainEditor.BufferImage->FileImage->FileName
  391. ) == 0) {
  392. OldFile = TRUE;
  393. }
  394. if (OldFile) {
  395. //
  396. // if the file is read only, so can not write back to it.
  397. //
  398. if (HMainEditor.BufferImage->FileImage->ReadOnly) {
  399. StatusBarSetStatusString (L"Access Denied");
  400. SHELL_FREE_NON_NULL (FileName);
  401. return EFI_SUCCESS;
  402. }
  403. } else {
  404. Status = ShellOpenFileByName (FileName, &ShellFileHandle, EFI_FILE_MODE_READ, 0);
  405. if (!EFI_ERROR (Status)) {
  406. Info = ShellGetFileInfo(ShellFileHandle);
  407. ShellCloseFile(&ShellFileHandle);
  408. //
  409. // check if read only
  410. //
  411. if (Info->Attribute & EFI_FILE_READ_ONLY) {
  412. StatusBarSetStatusString (L"Access Denied");
  413. SHELL_FREE_NON_NULL (FileName);
  414. return EFI_SUCCESS;
  415. }
  416. SHELL_FREE_NON_NULL(Info);
  417. //
  418. // ask user whether to overwrite this file
  419. //
  420. Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");
  421. if (EFI_ERROR (Status)) {
  422. SHELL_FREE_NON_NULL (FileName);
  423. return Status;
  424. }
  425. Status = InputBarSetStringSize (1);
  426. if (EFI_ERROR (Status)) {
  427. SHELL_FREE_NON_NULL (FileName);
  428. return Status;
  429. }
  430. Done = FALSE;
  431. while (!Done) {
  432. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  433. if (Status == EFI_NOT_READY) {
  434. SHELL_FREE_NON_NULL (FileName);
  435. return EFI_SUCCESS;
  436. }
  437. switch (InputBarGetString()[0]) {
  438. case L'y':
  439. case L'Y':
  440. Done = TRUE;
  441. break;
  442. case L'n':
  443. case L'N':
  444. SHELL_FREE_NON_NULL (FileName);
  445. return EFI_SUCCESS;
  446. case L'c':
  447. case L'C':
  448. SHELL_FREE_NON_NULL (FileName);
  449. return EFI_SUCCESS;
  450. } // switch
  451. } // while
  452. } // if opened existing file
  453. } // if OldFile
  454. //
  455. // save file back to disk
  456. //
  457. Status = HBufferImageSave (
  458. FileName,
  459. HMainEditor.BufferImage->DiskImage->Name,
  460. HMainEditor.BufferImage->DiskImage->Offset,
  461. HMainEditor.BufferImage->DiskImage->Size,
  462. HMainEditor.BufferImage->MemImage->Offset,
  463. HMainEditor.BufferImage->MemImage->Size,
  464. FileTypeFileBuffer
  465. );
  466. SHELL_FREE_NON_NULL (FileName);
  467. if (EFI_ERROR (Status)) {
  468. return EFI_LOAD_ERROR;
  469. }
  470. return EFI_SUCCESS;
  471. }
  472. /**
  473. Load a disk buffer editor.
  474. @retval EFI_SUCCESS The operation was successful.
  475. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  476. @retval EFI_LOAD_ERROR A load error occurred.
  477. **/
  478. EFI_STATUS
  479. HMainCommandSelectStart (
  480. VOID
  481. )
  482. {
  483. UINTN Start;
  484. Start = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;
  485. //
  486. // last line
  487. //
  488. if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
  489. if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
  490. StatusBarSetStatusString (L"Invalid Block Start");
  491. return EFI_LOAD_ERROR;
  492. }
  493. }
  494. if (HMainEditor.SelectEnd != 0 && Start > HMainEditor.SelectEnd) {
  495. StatusBarSetStatusString (L"Invalid Block Start");
  496. return EFI_LOAD_ERROR;
  497. }
  498. HMainEditor.SelectStart = Start;
  499. HBufferImageNeedRefresh = TRUE;
  500. return EFI_SUCCESS;
  501. }
  502. /**
  503. Load a disk buffer editor.
  504. @retval EFI_SUCCESS The operation was successful.
  505. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  506. @retval EFI_LOAD_ERROR A load error occurred.
  507. **/
  508. EFI_STATUS
  509. HMainCommandSelectEnd (
  510. VOID
  511. )
  512. {
  513. UINTN End;
  514. End = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;
  515. //
  516. // last line
  517. //
  518. if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
  519. if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
  520. StatusBarSetStatusString (L"Invalid Block End");
  521. return EFI_LOAD_ERROR;
  522. }
  523. }
  524. if (HMainEditor.SelectStart != 0 && End < HMainEditor.SelectStart) {
  525. StatusBarSetStatusString (L"Invalid Block End");
  526. return EFI_SUCCESS;
  527. }
  528. HMainEditor.SelectEnd = End;
  529. HBufferImageNeedRefresh = TRUE;
  530. return EFI_SUCCESS;
  531. }
  532. /**
  533. Cut current line to clipboard.
  534. @retval EFI_SUCCESS The operation was successful.
  535. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  536. @retval EFI_LOAD_ERROR A load error occurred.
  537. **/
  538. EFI_STATUS
  539. HMainCommandCut (
  540. VOID
  541. )
  542. {
  543. UINTN Index;
  544. LIST_ENTRY *Link;
  545. UINT8 *Buffer;
  546. UINTN Count;
  547. //
  548. // not select, so not allowed to cut
  549. //
  550. if (HMainEditor.SelectStart == 0) {
  551. StatusBarSetStatusString (L"No Block is Selected");
  552. return EFI_SUCCESS;
  553. }
  554. //
  555. // not select, so not allowed to cut
  556. //
  557. if (HMainEditor.SelectEnd == 0) {
  558. StatusBarSetStatusString (L"No Block is Selected");
  559. return EFI_SUCCESS;
  560. }
  561. Link = HMainEditor.BufferImage->ListHead->ForwardLink;
  562. for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) {
  563. Link = Link->ForwardLink;
  564. }
  565. Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1;
  566. Buffer = AllocateZeroPool (Count);
  567. if (Buffer == NULL) {
  568. return EFI_OUT_OF_RESOURCES;
  569. }
  570. //
  571. // cut the selected area
  572. //
  573. HBufferImageDeleteCharacterFromBuffer (
  574. HMainEditor.SelectStart - 1,
  575. Count,
  576. Buffer
  577. );
  578. //
  579. // put to clipboard
  580. //
  581. HClipBoardSet (Buffer, Count);
  582. HBufferImageNeedRefresh = TRUE;
  583. HBufferImageOnlyLineNeedRefresh = FALSE;
  584. if (!HMainEditor.BufferImage->Modified) {
  585. HMainEditor.BufferImage->Modified = TRUE;
  586. }
  587. //
  588. // now no select area
  589. //
  590. HMainEditor.SelectStart = 0;
  591. HMainEditor.SelectEnd = 0;
  592. return EFI_SUCCESS;
  593. }
  594. /**
  595. Paste line to file buffer.
  596. @retval EFI_SUCCESS The operation was successful.
  597. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  598. @retval EFI_LOAD_ERROR A load error occurred.
  599. **/
  600. EFI_STATUS
  601. HMainCommandPaste (
  602. VOID
  603. )
  604. {
  605. BOOLEAN OnlyLineRefresh;
  606. HEFI_EDITOR_LINE *Line;
  607. UINT8 *Buffer;
  608. UINTN Count;
  609. UINTN FPos;
  610. Count = HClipBoardGet (&Buffer);
  611. if (Count == 0 || Buffer == NULL) {
  612. StatusBarSetStatusString (L"Nothing to Paste");
  613. return EFI_SUCCESS;
  614. }
  615. Line = HMainEditor.BufferImage->CurrentLine;
  616. OnlyLineRefresh = FALSE;
  617. if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead && Line->Size + Count < 0x10) {
  618. //
  619. // is at last line, and after paste will not exceed
  620. // so only this line need to be refreshed
  621. //
  622. // if after add, the line is 0x10, then will append a new line
  623. // so the whole page will need be refreshed
  624. //
  625. OnlyLineRefresh = TRUE;
  626. }
  627. FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1;
  628. HBufferImageAddCharacterToBuffer (FPos, Count, Buffer);
  629. if (OnlyLineRefresh) {
  630. HBufferImageNeedRefresh = FALSE;
  631. HBufferImageOnlyLineNeedRefresh = TRUE;
  632. } else {
  633. HBufferImageNeedRefresh = TRUE;
  634. HBufferImageOnlyLineNeedRefresh = FALSE;
  635. }
  636. if (!HMainEditor.BufferImage->Modified) {
  637. HMainEditor.BufferImage->Modified = TRUE;
  638. }
  639. return EFI_SUCCESS;
  640. }
  641. /**
  642. Exit editor.
  643. @retval EFI_SUCCESS The operation was successful.
  644. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  645. @retval EFI_LOAD_ERROR A load error occurred.
  646. **/
  647. EFI_STATUS
  648. HMainCommandExit (
  649. VOID
  650. )
  651. {
  652. EFI_STATUS Status;
  653. //
  654. // Below is the scenario of Exit command:
  655. // 1. IF currently opened file is not modified, exit the editor and
  656. // Exit command ends.
  657. // IF currently opened file is modified, do Step 2
  658. //
  659. // 2. An Input Bar will be prompted:
  660. // "File modified. Save ( Yes/No/Cancel )?"
  661. // IF user press 'y' or 'Y', currently opened file will be saved and
  662. // Editor exits
  663. // IF user press 'n' or 'N', currently opened file will not be saved
  664. // and Editor exits.
  665. // IF user press 'c' or 'C' or ESC, Exit command ends.
  666. //
  667. //
  668. // if file has been modified, so will prompt user
  669. // whether to save the changes
  670. //
  671. if (HMainEditor.BufferImage->Modified) {
  672. Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
  673. if (EFI_ERROR (Status)) {
  674. return Status;
  675. }
  676. Status = InputBarSetStringSize (1);
  677. if (EFI_ERROR (Status)) {
  678. return Status;
  679. }
  680. while (1) {
  681. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  682. //
  683. // ESC pressed
  684. //
  685. if (Status == EFI_NOT_READY) {
  686. return EFI_SUCCESS;
  687. }
  688. switch (InputBarGetString()[0]) {
  689. case L'y':
  690. case L'Y':
  691. //
  692. // write file back to disk
  693. //
  694. Status = HBufferImageSave (
  695. HMainEditor.BufferImage->FileImage->FileName,
  696. HMainEditor.BufferImage->DiskImage->Name,
  697. HMainEditor.BufferImage->DiskImage->Offset,
  698. HMainEditor.BufferImage->DiskImage->Size,
  699. HMainEditor.BufferImage->MemImage->Offset,
  700. HMainEditor.BufferImage->MemImage->Size,
  701. HMainEditor.BufferImage->BufferType
  702. );
  703. if (!EFI_ERROR (Status)) {
  704. HEditorExit = TRUE;
  705. }
  706. return Status;
  707. case L'n':
  708. case L'N':
  709. HEditorExit = TRUE;
  710. return EFI_SUCCESS;
  711. case L'c':
  712. case L'C':
  713. return EFI_SUCCESS;
  714. }
  715. }
  716. }
  717. HEditorExit = TRUE;
  718. return EFI_SUCCESS;
  719. }
  720. /**
  721. Load a file from disk to editor.
  722. @retval EFI_SUCCESS The operation was successful.
  723. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  724. @retval EFI_LOAD_ERROR A load error occurred.
  725. **/
  726. EFI_STATUS
  727. HMainCommandOpenFile (
  728. VOID
  729. )
  730. {
  731. BOOLEAN Done;
  732. EFI_STATUS Status;
  733. EDIT_FILE_TYPE BufferType;
  734. BufferType = HMainEditor.BufferImage->BufferType;
  735. //
  736. // This command will open a file from current working directory.
  737. // Read-only file can also be opened. But it can not be modified.
  738. // Below is the scenario of Open File command:
  739. // 1. IF currently opened file has not been modified, directly go to step .
  740. // IF currently opened file has been modified, an Input Bar will be
  741. // prompted as :
  742. // "File Modified. Save ( Yes/No/Cancel) ?"
  743. // IF user press 'y' or 'Y', currently opened file will be saved.
  744. // IF user press 'n' or 'N', currently opened file will
  745. // not be saved.
  746. // IF user press 'c' or 'C' or ESC, Open File command ends and
  747. // currently opened file is still opened.
  748. //
  749. // 2. An Input Bar will be prompted as : "File Name to Open: "
  750. // IF user press ESC, Open File command ends and
  751. // currently opened file is still opened.
  752. // Any other inputs with a Return will cause
  753. // currently opened file close.
  754. //
  755. // 3. IF user input file name is an existing file ,
  756. // this file will be read and opened.
  757. // IF user input file name is a new file, this file will be created
  758. // and opened. This file's type ( UNICODE or ASCII ) is the same with
  759. // the old file.
  760. //
  761. //
  762. // if current file is modified, so you need to choose whether to
  763. // save it first.
  764. //
  765. if (HMainEditor.BufferImage->Modified) {
  766. Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
  767. if (EFI_ERROR (Status)) {
  768. return Status;
  769. }
  770. //
  771. // the answer is just one character
  772. //
  773. Status = InputBarSetStringSize (1);
  774. if (EFI_ERROR (Status)) {
  775. return Status;
  776. }
  777. //
  778. // loop for user's answer
  779. // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
  780. //
  781. Done = FALSE;
  782. while (!Done) {
  783. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  784. //
  785. // ESC pressed
  786. //
  787. if (Status == EFI_NOT_READY) {
  788. return EFI_SUCCESS;
  789. }
  790. switch (InputBarGetString()[0]) {
  791. case L'y':
  792. case L'Y':
  793. //
  794. // want to save this buffer first
  795. //
  796. Status = HBufferImageSave (
  797. HMainEditor.BufferImage->FileImage->FileName,
  798. HMainEditor.BufferImage->DiskImage->Name,
  799. HMainEditor.BufferImage->DiskImage->Offset,
  800. HMainEditor.BufferImage->DiskImage->Size,
  801. HMainEditor.BufferImage->MemImage->Offset,
  802. HMainEditor.BufferImage->MemImage->Size,
  803. HMainEditor.BufferImage->BufferType
  804. );
  805. if (EFI_ERROR (Status)) {
  806. return Status;
  807. }
  808. MainTitleBarRefresh (
  809. HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
  810. HMainEditor.BufferImage->BufferType,
  811. HMainEditor.BufferImage->FileImage->ReadOnly,
  812. FALSE,
  813. HMainEditor.ScreenSize.Column,
  814. HMainEditor.ScreenSize.Row,
  815. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
  816. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0
  817. );
  818. Done = TRUE;
  819. break;
  820. case L'n':
  821. case L'N':
  822. //
  823. // the file won't be saved
  824. //
  825. Done = TRUE;
  826. break;
  827. case L'c':
  828. case L'C':
  829. return EFI_SUCCESS;
  830. }
  831. }
  832. }
  833. //
  834. // TO get the open file name
  835. //
  836. Status = InputBarSetPrompt (L"File Name to Open: ");
  837. if (EFI_ERROR (Status)) {
  838. HBufferImageRead (
  839. HMainEditor.BufferImage->FileImage->FileName,
  840. HMainEditor.BufferImage->DiskImage->Name,
  841. HMainEditor.BufferImage->DiskImage->Offset,
  842. HMainEditor.BufferImage->DiskImage->Size,
  843. HMainEditor.BufferImage->MemImage->Offset,
  844. HMainEditor.BufferImage->MemImage->Size,
  845. BufferType,
  846. TRUE
  847. );
  848. return Status;
  849. }
  850. Status = InputBarSetStringSize (100);
  851. if (EFI_ERROR (Status)) {
  852. Status = HBufferImageRead (
  853. HMainEditor.BufferImage->FileImage->FileName,
  854. HMainEditor.BufferImage->DiskImage->Name,
  855. HMainEditor.BufferImage->DiskImage->Offset,
  856. HMainEditor.BufferImage->DiskImage->Size,
  857. HMainEditor.BufferImage->MemImage->Offset,
  858. HMainEditor.BufferImage->MemImage->Size,
  859. BufferType,
  860. TRUE
  861. );
  862. return Status;
  863. }
  864. while (1) {
  865. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  866. //
  867. // ESC pressed
  868. //
  869. if (Status == EFI_NOT_READY) {
  870. Status = HBufferImageRead (
  871. HMainEditor.BufferImage->FileImage->FileName,
  872. HMainEditor.BufferImage->DiskImage->Name,
  873. HMainEditor.BufferImage->DiskImage->Offset,
  874. HMainEditor.BufferImage->DiskImage->Size,
  875. HMainEditor.BufferImage->MemImage->Offset,
  876. HMainEditor.BufferImage->MemImage->Size,
  877. BufferType,
  878. TRUE
  879. );
  880. return Status;
  881. }
  882. //
  883. // THE input string length should > 0
  884. //
  885. if (StrLen (InputBarGetString()) > 0) {
  886. //
  887. // CHECK if filename's valid
  888. //
  889. if (!IsValidFileName (InputBarGetString())) {
  890. HBufferImageRead (
  891. HMainEditor.BufferImage->FileImage->FileName,
  892. HMainEditor.BufferImage->DiskImage->Name,
  893. HMainEditor.BufferImage->DiskImage->Offset,
  894. HMainEditor.BufferImage->DiskImage->Size,
  895. HMainEditor.BufferImage->MemImage->Offset,
  896. HMainEditor.BufferImage->MemImage->Size,
  897. BufferType,
  898. TRUE
  899. );
  900. StatusBarSetStatusString (L"Invalid File Name");
  901. return EFI_SUCCESS;
  902. }
  903. break;
  904. }
  905. }
  906. //
  907. // read from disk
  908. //
  909. Status = HBufferImageRead (
  910. InputBarGetString(),
  911. HMainEditor.BufferImage->DiskImage->Name,
  912. HMainEditor.BufferImage->DiskImage->Offset,
  913. HMainEditor.BufferImage->DiskImage->Size,
  914. HMainEditor.BufferImage->MemImage->Offset,
  915. HMainEditor.BufferImage->MemImage->Size,
  916. FileTypeFileBuffer,
  917. FALSE
  918. );
  919. if (EFI_ERROR (Status)) {
  920. HBufferImageRead (
  921. HMainEditor.BufferImage->FileImage->FileName,
  922. HMainEditor.BufferImage->DiskImage->Name,
  923. HMainEditor.BufferImage->DiskImage->Offset,
  924. HMainEditor.BufferImage->DiskImage->Size,
  925. HMainEditor.BufferImage->MemImage->Offset,
  926. HMainEditor.BufferImage->MemImage->Size,
  927. BufferType,
  928. TRUE
  929. );
  930. return EFI_LOAD_ERROR;
  931. }
  932. return EFI_SUCCESS;
  933. }
  934. /**
  935. Load a disk buffer editor.
  936. @retval EFI_SUCCESS The operation was successful.
  937. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  938. @retval EFI_LOAD_ERROR A load error occurred.
  939. @retval EFI_NOT_FOUND The disk was not found.
  940. **/
  941. EFI_STATUS
  942. HMainCommandOpenDisk (
  943. VOID
  944. )
  945. {
  946. UINT64 Size;
  947. UINT64 Offset;
  948. CHAR16 *DeviceName;
  949. EFI_STATUS Status;
  950. BOOLEAN Done;
  951. EDIT_FILE_TYPE BufferType;
  952. //
  953. // variable initialization
  954. //
  955. Size = 0;
  956. Offset = 0;
  957. BufferType = HMainEditor.BufferImage->BufferType;
  958. //
  959. // if current file is modified, so you need to choose
  960. // whether to save it first.
  961. //
  962. if (HMainEditor.BufferImage->Modified) {
  963. Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
  964. if (EFI_ERROR (Status)) {
  965. return Status;
  966. }
  967. //
  968. // the answer is just one character
  969. //
  970. Status = InputBarSetStringSize (1);
  971. if (EFI_ERROR (Status)) {
  972. return Status;
  973. }
  974. //
  975. // loop for user's answer
  976. // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
  977. //
  978. Done = FALSE;
  979. while (!Done) {
  980. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  981. //
  982. // ESC pressed
  983. //
  984. if (Status == EFI_NOT_READY) {
  985. return EFI_SUCCESS;
  986. }
  987. switch (InputBarGetString()[0]) {
  988. case L'y':
  989. case L'Y':
  990. //
  991. // want to save this buffer first
  992. //
  993. Status = HBufferImageSave (
  994. HMainEditor.BufferImage->FileImage->FileName,
  995. HMainEditor.BufferImage->DiskImage->Name,
  996. HMainEditor.BufferImage->DiskImage->Offset,
  997. HMainEditor.BufferImage->DiskImage->Size,
  998. HMainEditor.BufferImage->MemImage->Offset,
  999. HMainEditor.BufferImage->MemImage->Size,
  1000. BufferType
  1001. );
  1002. if (EFI_ERROR (Status)) {
  1003. return Status;
  1004. }
  1005. MainTitleBarRefresh (
  1006. HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
  1007. HMainEditor.BufferImage->BufferType,
  1008. HMainEditor.BufferImage->FileImage->ReadOnly,
  1009. FALSE,
  1010. HMainEditor.ScreenSize.Column,
  1011. HMainEditor.ScreenSize.Row,
  1012. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
  1013. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0
  1014. );
  1015. Done = TRUE;
  1016. break;
  1017. case L'n':
  1018. case L'N':
  1019. //
  1020. // the file won't be saved
  1021. //
  1022. Done = TRUE;
  1023. break;
  1024. case L'c':
  1025. case L'C':
  1026. return EFI_SUCCESS;
  1027. }
  1028. }
  1029. }
  1030. //
  1031. // get disk block device name
  1032. //
  1033. Status = InputBarSetPrompt (L"Block Device to Open: ");
  1034. if (EFI_ERROR (Status)) {
  1035. return Status;
  1036. }
  1037. Status = InputBarSetStringSize (100);
  1038. if (EFI_ERROR (Status)) {
  1039. return Status;
  1040. }
  1041. while (1) {
  1042. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  1043. //
  1044. // ESC pressed
  1045. //
  1046. if (Status == EFI_NOT_READY) {
  1047. return EFI_SUCCESS;
  1048. }
  1049. //
  1050. // THE input string length should > 0
  1051. //
  1052. if (StrLen (InputBarGetString()) > 0) {
  1053. break;
  1054. }
  1055. }
  1056. DeviceName = CatSPrint(NULL, L"%s", InputBarGetString());
  1057. if (DeviceName == NULL) {
  1058. return EFI_OUT_OF_RESOURCES;
  1059. }
  1060. //
  1061. // get starting offset
  1062. //
  1063. Status = InputBarSetPrompt (L"First Block No.: ");
  1064. if (EFI_ERROR (Status)) {
  1065. return Status;
  1066. }
  1067. Status = InputBarSetStringSize (16);
  1068. if (EFI_ERROR (Status)) {
  1069. return Status;
  1070. }
  1071. while (1) {
  1072. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  1073. //
  1074. // ESC pressed
  1075. //
  1076. if (Status == EFI_NOT_READY) {
  1077. return EFI_SUCCESS;
  1078. }
  1079. //
  1080. // THE input string length should > 0
  1081. //
  1082. if (StrLen (InputBarGetString()) > 0) {
  1083. Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
  1084. if (EFI_ERROR (Status)) {
  1085. continue;
  1086. }
  1087. break;
  1088. }
  1089. }
  1090. //
  1091. // get Number of Blocks:
  1092. //
  1093. Status = InputBarSetPrompt (L"Number of Blocks: ");
  1094. if (EFI_ERROR (Status)) {
  1095. return Status;
  1096. }
  1097. Status = InputBarSetStringSize (8);
  1098. if (EFI_ERROR (Status)) {
  1099. return Status;
  1100. }
  1101. while (1) {
  1102. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  1103. //
  1104. // ESC pressed
  1105. //
  1106. if (Status == EFI_NOT_READY) {
  1107. return EFI_SUCCESS;
  1108. }
  1109. //
  1110. // THE input string length should > 0
  1111. //
  1112. if (StrLen (InputBarGetString()) > 0) {
  1113. Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
  1114. if (EFI_ERROR (Status)) {
  1115. continue;
  1116. }
  1117. if (Size == 0) {
  1118. continue;
  1119. }
  1120. break;
  1121. }
  1122. }
  1123. Status = HBufferImageRead (
  1124. NULL,
  1125. DeviceName,
  1126. (UINTN)Offset,
  1127. (UINTN)Size,
  1128. 0,
  1129. 0,
  1130. FileTypeDiskBuffer,
  1131. FALSE
  1132. );
  1133. if (EFI_ERROR (Status)) {
  1134. HBufferImageRead (
  1135. HMainEditor.BufferImage->FileImage->FileName,
  1136. HMainEditor.BufferImage->DiskImage->Name,
  1137. HMainEditor.BufferImage->DiskImage->Offset,
  1138. HMainEditor.BufferImage->DiskImage->Size,
  1139. HMainEditor.BufferImage->MemImage->Offset,
  1140. HMainEditor.BufferImage->MemImage->Size,
  1141. BufferType,
  1142. TRUE
  1143. );
  1144. return EFI_NOT_FOUND;
  1145. }
  1146. return EFI_SUCCESS;
  1147. }
  1148. /**
  1149. Load memory content to editor
  1150. @retval EFI_SUCCESS The operation was successful.
  1151. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  1152. @retval EFI_LOAD_ERROR A load error occurred.
  1153. @retval EFI_NOT_FOUND The disk was not found.
  1154. **/
  1155. EFI_STATUS
  1156. HMainCommandOpenMemory (
  1157. VOID
  1158. )
  1159. {
  1160. UINT64 Size;
  1161. UINT64 Offset;
  1162. EFI_STATUS Status;
  1163. BOOLEAN Done;
  1164. EDIT_FILE_TYPE BufferType;
  1165. //
  1166. // variable initialization
  1167. //
  1168. Size = 0;
  1169. Offset = 0;
  1170. BufferType = HMainEditor.BufferImage->BufferType;
  1171. //
  1172. // if current buffer is modified, so you need to choose
  1173. // whether to save it first.
  1174. //
  1175. if (HMainEditor.BufferImage->Modified) {
  1176. Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
  1177. if (EFI_ERROR (Status)) {
  1178. return Status;
  1179. }
  1180. //
  1181. // the answer is just one character
  1182. //
  1183. Status = InputBarSetStringSize (1);
  1184. if (EFI_ERROR (Status)) {
  1185. return Status;
  1186. }
  1187. //
  1188. // loop for user's answer
  1189. // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
  1190. //
  1191. Done = FALSE;
  1192. while (!Done) {
  1193. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  1194. //
  1195. // ESC pressed
  1196. //
  1197. if (Status == EFI_NOT_READY) {
  1198. return EFI_SUCCESS;
  1199. }
  1200. switch (InputBarGetString()[0]) {
  1201. case L'y':
  1202. case L'Y':
  1203. //
  1204. // want to save this buffer first
  1205. //
  1206. Status = HBufferImageSave (
  1207. HMainEditor.BufferImage->FileImage->FileName,
  1208. HMainEditor.BufferImage->DiskImage->Name,
  1209. HMainEditor.BufferImage->DiskImage->Offset,
  1210. HMainEditor.BufferImage->DiskImage->Size,
  1211. HMainEditor.BufferImage->MemImage->Offset,
  1212. HMainEditor.BufferImage->MemImage->Size,
  1213. BufferType
  1214. );
  1215. if (EFI_ERROR (Status)) {
  1216. return Status;
  1217. }
  1218. MainTitleBarRefresh (
  1219. HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
  1220. HMainEditor.BufferImage->BufferType,
  1221. HMainEditor.BufferImage->FileImage->ReadOnly,
  1222. FALSE,
  1223. HMainEditor.ScreenSize.Column,
  1224. HMainEditor.ScreenSize.Row,
  1225. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
  1226. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size :0
  1227. );
  1228. Done = TRUE;
  1229. break;
  1230. case L'n':
  1231. case L'N':
  1232. //
  1233. // the file won't be saved
  1234. //
  1235. Done = TRUE;
  1236. break;
  1237. case L'c':
  1238. case L'C':
  1239. return EFI_SUCCESS;
  1240. }
  1241. }
  1242. }
  1243. //
  1244. // get starting offset
  1245. //
  1246. Status = InputBarSetPrompt (L"Starting Offset: ");
  1247. if (EFI_ERROR (Status)) {
  1248. return Status;
  1249. }
  1250. Status = InputBarSetStringSize (8);
  1251. if (EFI_ERROR (Status)) {
  1252. return Status;
  1253. }
  1254. while (1) {
  1255. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  1256. //
  1257. // ESC pressed
  1258. //
  1259. if (Status == EFI_NOT_READY) {
  1260. return EFI_SUCCESS;
  1261. }
  1262. //
  1263. // THE input string length should > 0
  1264. //
  1265. if (StrLen (InputBarGetString()) > 0) {
  1266. Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
  1267. if (EFI_ERROR (Status)) {
  1268. continue;
  1269. }
  1270. break;
  1271. }
  1272. }
  1273. //
  1274. // get Number of Blocks:
  1275. //
  1276. Status = InputBarSetPrompt (L"Buffer Size: ");
  1277. if (EFI_ERROR (Status)) {
  1278. return Status;
  1279. }
  1280. Status = InputBarSetStringSize (8);
  1281. if (EFI_ERROR (Status)) {
  1282. return Status;
  1283. }
  1284. while (1) {
  1285. Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);
  1286. //
  1287. // ESC pressed
  1288. //
  1289. if (Status == EFI_NOT_READY) {
  1290. return EFI_SUCCESS;
  1291. }
  1292. //
  1293. // THE input string length should > 0
  1294. //
  1295. if (StrLen (InputBarGetString()) > 0) {
  1296. Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
  1297. if (EFI_ERROR (Status)) {
  1298. continue;
  1299. }
  1300. if (Size == 0) {
  1301. continue;
  1302. }
  1303. break;
  1304. }
  1305. }
  1306. if ((Offset + Size - 1)> 0xffffffff) {
  1307. StatusBarSetStatusString (L"Invalid parameter");
  1308. return EFI_LOAD_ERROR;
  1309. }
  1310. Status = HBufferImageRead (
  1311. NULL,
  1312. NULL,
  1313. 0,
  1314. 0,
  1315. (UINTN)Offset,
  1316. (UINTN)Size,
  1317. FileTypeMemBuffer,
  1318. FALSE
  1319. );
  1320. if (EFI_ERROR (Status)) {
  1321. StatusBarSetStatusString (L"Read Device Error!");
  1322. HBufferImageRead (
  1323. HMainEditor.BufferImage->FileImage->FileName,
  1324. HMainEditor.BufferImage->DiskImage->Name,
  1325. HMainEditor.BufferImage->DiskImage->Offset,
  1326. HMainEditor.BufferImage->DiskImage->Size,
  1327. HMainEditor.BufferImage->MemImage->Offset,
  1328. HMainEditor.BufferImage->MemImage->Size,
  1329. BufferType,
  1330. TRUE
  1331. );
  1332. return EFI_NOT_FOUND;
  1333. }
  1334. return EFI_SUCCESS;
  1335. }
  1336. MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = {
  1337. NULL,
  1338. NULL, /* Ctrl - A */
  1339. NULL, /* Ctrl - B */
  1340. NULL, /* Ctrl - C */
  1341. HMainCommandSelectEnd, /* Ctrl - D */
  1342. HMainCommandDisplayHelp, /* Ctrl - E */
  1343. NULL, /* Ctrl - F */
  1344. HMainCommandGoToOffset, /* Ctrl - G */
  1345. NULL, /* Ctrl - H */
  1346. HMainCommandOpenDisk, /* Ctrl - I */
  1347. NULL, /* Ctrl - J */
  1348. NULL, /* Ctrl - K */
  1349. NULL, /* Ctrl - L */
  1350. HMainCommandOpenMemory, /* Ctrl - M */
  1351. NULL, /* Ctrl - N */
  1352. HMainCommandOpenFile, /* Ctrl - O */
  1353. NULL, /* Ctrl - P */
  1354. HMainCommandExit, /* Ctrl - Q */
  1355. NULL, /* Ctrl - R */
  1356. HMainCommandSaveBuffer, /* Ctrl - S */
  1357. HMainCommandSelectStart, /* Ctrl - T */
  1358. NULL, /* Ctrl - U */
  1359. HMainCommandPaste, /* Ctrl - V */
  1360. NULL, /* Ctrl - W */
  1361. HMainCommandCut, /* Ctrl - X */
  1362. NULL, /* Ctrl - Y */
  1363. NULL, /* Ctrl - Z */
  1364. };
  1365. CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {
  1366. {
  1367. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),
  1368. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),
  1369. HMainCommandGoToOffset
  1370. },
  1371. {
  1372. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),
  1373. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),
  1374. HMainCommandSaveBuffer
  1375. },
  1376. {
  1377. STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),
  1378. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),
  1379. HMainCommandExit
  1380. },
  1381. {
  1382. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START),
  1383. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),
  1384. HMainCommandSelectStart
  1385. },
  1386. {
  1387. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END),
  1388. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),
  1389. HMainCommandSelectEnd
  1390. },
  1391. {
  1392. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT),
  1393. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),
  1394. HMainCommandCut
  1395. },
  1396. {
  1397. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE),
  1398. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),
  1399. HMainCommandPaste
  1400. },
  1401. {
  1402. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),
  1403. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),
  1404. HMainCommandOpenFile
  1405. },
  1406. {
  1407. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),
  1408. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),
  1409. HMainCommandOpenDisk
  1410. },
  1411. {
  1412. STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),
  1413. STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10),
  1414. HMainCommandOpenMemory
  1415. },
  1416. {
  1417. 0,
  1418. 0,
  1419. NULL
  1420. }
  1421. };
  1422. /**
  1423. Init function for MainEditor
  1424. @retval EFI_SUCCESS The operation was successful.
  1425. @retval EFI_LOAD_ERROR A load error occurred.
  1426. **/
  1427. EFI_STATUS
  1428. HMainEditorInit (
  1429. VOID
  1430. )
  1431. {
  1432. EFI_STATUS Status;
  1433. EFI_HANDLE *HandleBuffer;
  1434. UINTN HandleCount;
  1435. UINTN Index;
  1436. //
  1437. // basic initialization
  1438. //
  1439. CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));
  1440. //
  1441. // set screen attributes
  1442. //
  1443. HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;
  1444. HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);
  1445. HOriginalColors = HMainEditor.ColorAttributes.Colors;
  1446. HOriginalMode = gST->ConOut->Mode->Mode;
  1447. //
  1448. // query screen size
  1449. //
  1450. gST->ConOut->QueryMode (
  1451. gST->ConOut,
  1452. gST->ConOut->Mode->Mode,
  1453. &(HMainEditor.ScreenSize.Column),
  1454. &(HMainEditor.ScreenSize.Row)
  1455. );
  1456. //
  1457. // Find TextInEx in System Table ConsoleInHandle
  1458. // Per UEFI Spec, TextInEx is required for a console capable platform.
  1459. //
  1460. Status = gBS->HandleProtocol (
  1461. gST->ConsoleInHandle,
  1462. &gEfiSimpleTextInputExProtocolGuid,
  1463. (VOID**)&HMainEditor.TextInputEx
  1464. );
  1465. if (EFI_ERROR (Status)) {
  1466. return Status;
  1467. }
  1468. //
  1469. // Find mouse in System Table ConsoleInHandle
  1470. //
  1471. Status = gBS->HandleProtocol (
  1472. gST->ConsoleInHandle,
  1473. &gEfiSimplePointerProtocolGuid,
  1474. (VOID**)&HMainEditor.MouseInterface
  1475. );
  1476. if (EFI_ERROR (Status)) {
  1477. //
  1478. // If there is no Simple Pointer Protocol on System Table
  1479. //
  1480. HandleBuffer = NULL;
  1481. HMainEditor.MouseInterface = NULL;
  1482. Status = gBS->LocateHandleBuffer (
  1483. ByProtocol,
  1484. &gEfiSimplePointerProtocolGuid,
  1485. NULL,
  1486. &HandleCount,
  1487. &HandleBuffer
  1488. );
  1489. if (!EFI_ERROR (Status) && HandleCount > 0) {
  1490. //
  1491. // Try to find the first available mouse device
  1492. //
  1493. for (Index = 0; Index < HandleCount; Index++) {
  1494. Status = gBS->HandleProtocol (
  1495. HandleBuffer[Index],
  1496. &gEfiSimplePointerProtocolGuid,
  1497. (VOID**)&HMainEditor.MouseInterface
  1498. );
  1499. if (!EFI_ERROR (Status)) {
  1500. break;
  1501. }
  1502. }
  1503. }
  1504. if (HandleBuffer != NULL) {
  1505. FreePool (HandleBuffer);
  1506. }
  1507. }
  1508. if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) {
  1509. HMainEditor.MouseAccumulatorX = 0;
  1510. HMainEditor.MouseAccumulatorY = 0;
  1511. HMainEditor.MouseSupported = TRUE;
  1512. }
  1513. //
  1514. // below will call the five components' init function
  1515. //
  1516. Status = MainTitleBarInit (L"UEFI HEXEDIT");
  1517. if (EFI_ERROR (Status)) {
  1518. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
  1519. return EFI_LOAD_ERROR;
  1520. }
  1521. Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions);
  1522. if (EFI_ERROR (Status)) {
  1523. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
  1524. return EFI_LOAD_ERROR;
  1525. }
  1526. Status = MenuBarInit (HexEditorMenuItems);
  1527. if (EFI_ERROR (Status)) {
  1528. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
  1529. return EFI_LOAD_ERROR;
  1530. }
  1531. Status = StatusBarInit ();
  1532. if (EFI_ERROR (Status)) {
  1533. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);
  1534. return EFI_LOAD_ERROR;
  1535. }
  1536. InputBarInit (HMainEditor.TextInputEx);
  1537. Status = HBufferImageInit ();
  1538. if (EFI_ERROR (Status)) {
  1539. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);
  1540. return EFI_LOAD_ERROR;
  1541. }
  1542. Status = HClipBoardInit ();
  1543. if (EFI_ERROR (Status)) {
  1544. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);
  1545. return EFI_LOAD_ERROR;
  1546. }
  1547. //
  1548. // clear whole screen and enable cursor
  1549. //
  1550. gST->ConOut->ClearScreen (gST->ConOut);
  1551. gST->ConOut->EnableCursor (gST->ConOut, TRUE);
  1552. //
  1553. // initialize EditorFirst and EditorExit
  1554. //
  1555. HEditorFirst = TRUE;
  1556. HEditorExit = FALSE;
  1557. HEditorMouseAction = FALSE;
  1558. return EFI_SUCCESS;
  1559. }
  1560. /**
  1561. Cleanup function for MainEditor.
  1562. @retval EFI_SUCCESS The operation was successful.
  1563. @retval EFI_LOAD_ERROR A load error occurred.
  1564. **/
  1565. EFI_STATUS
  1566. HMainEditorCleanup (
  1567. VOID
  1568. )
  1569. {
  1570. EFI_STATUS Status;
  1571. //
  1572. // call the five components' cleanup function
  1573. //
  1574. MainTitleBarCleanup ();
  1575. MenuBarCleanup ();
  1576. StatusBarCleanup ();
  1577. InputBarCleanup ();
  1578. Status = HBufferImageCleanup ();
  1579. if (EFI_ERROR (Status)) {
  1580. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);
  1581. }
  1582. Status = HClipBoardCleanup ();
  1583. if (EFI_ERROR (Status)) {
  1584. ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);
  1585. }
  1586. //
  1587. // restore old mode
  1588. //
  1589. if (HOriginalMode != gST->ConOut->Mode->Mode) {
  1590. gST->ConOut->SetMode (gST->ConOut, HOriginalMode);
  1591. }
  1592. gST->ConOut->SetAttribute (
  1593. gST->ConOut,
  1594. EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)
  1595. );
  1596. gST->ConOut->ClearScreen (gST->ConOut);
  1597. return EFI_SUCCESS;
  1598. }
  1599. /**
  1600. Refresh function for MainEditor.
  1601. @retval EFI_SUCCESS The operation was successful.
  1602. **/
  1603. EFI_STATUS
  1604. HMainEditorRefresh (
  1605. VOID
  1606. )
  1607. {
  1608. BOOLEAN NameChange;
  1609. BOOLEAN ReadChange;
  1610. NameChange = FALSE;
  1611. ReadChange = FALSE;
  1612. if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) {
  1613. if (HMainEditor.BufferImage->DiskImage != NULL &&
  1614. HBufferImageBackupVar.DiskImage != NULL &&
  1615. (HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset ||
  1616. HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size) ){
  1617. NameChange = TRUE;
  1618. }
  1619. } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) {
  1620. if (HMainEditor.BufferImage->MemImage != NULL &&
  1621. HBufferImageBackupVar.MemImage != NULL &&
  1622. (HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset ||
  1623. HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size) ){
  1624. NameChange = TRUE;
  1625. }
  1626. } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) {
  1627. if ( HMainEditor.BufferImage->FileImage != NULL &&
  1628. HMainEditor.BufferImage->FileImage->FileName != NULL &&
  1629. HBufferImageBackupVar.FileImage != NULL &&
  1630. HBufferImageBackupVar.FileImage->FileName != NULL &&
  1631. StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0 ) {
  1632. NameChange = TRUE;
  1633. }
  1634. }
  1635. if ( HMainEditor.BufferImage->FileImage != NULL &&
  1636. HBufferImageBackupVar.FileImage != NULL &&
  1637. HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly ) {
  1638. ReadChange = TRUE;
  1639. }
  1640. //
  1641. // to aVOID screen flicker
  1642. // the stall value is from experience
  1643. //
  1644. gBS->Stall (50);
  1645. //
  1646. // call the components refresh function
  1647. //
  1648. if (HEditorFirst
  1649. || NameChange
  1650. || HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType
  1651. || HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified
  1652. || ReadChange ) {
  1653. MainTitleBarRefresh (
  1654. HMainEditor.BufferImage->BufferType == FileTypeFileBuffer&&HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Name:NULL,
  1655. HMainEditor.BufferImage->BufferType,
  1656. (BOOLEAN)(HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->ReadOnly:FALSE),
  1657. HMainEditor.BufferImage->Modified,
  1658. HMainEditor.ScreenSize.Column,
  1659. HMainEditor.ScreenSize.Row,
  1660. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer&&HMainEditor.BufferImage->MemImage!=NULL?HMainEditor.BufferImage->MemImage->Offset:0,
  1661. HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Size :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer&&HMainEditor.BufferImage->MemImage!=NULL?HMainEditor.BufferImage->MemImage->Size :0
  1662. );
  1663. HBufferImageRefresh ();
  1664. }
  1665. if (HEditorFirst
  1666. || HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row
  1667. || HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column
  1668. || StatusBarGetRefresh()) {
  1669. StatusBarRefresh (
  1670. HEditorFirst,
  1671. HMainEditor.ScreenSize.Row,
  1672. HMainEditor.ScreenSize.Column,
  1673. (UINTN)(-1),
  1674. (UINTN)(-1),
  1675. FALSE
  1676. );
  1677. HBufferImageRefresh ();
  1678. }
  1679. if (HEditorFirst) {
  1680. HBufferImageRefresh ();
  1681. }
  1682. //
  1683. // EditorFirst is now set to FALSE
  1684. //
  1685. HEditorFirst = FALSE;
  1686. return EFI_SUCCESS;
  1687. }
  1688. /**
  1689. Handle the mouse input.
  1690. @param[in] MouseState The current mouse state.
  1691. @param[out] BeforeLeftButtonDown helps with selections.
  1692. @retval EFI_SUCCESS The operation was successful.
  1693. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  1694. @retval EFI_LOAD_ERROR A load error occurred.
  1695. @retval EFI_NOT_FOUND The disk was not found.
  1696. **/
  1697. EFI_STATUS
  1698. HMainEditorHandleMouseInput (
  1699. IN EFI_SIMPLE_POINTER_STATE MouseState,
  1700. OUT BOOLEAN *BeforeLeftButtonDown
  1701. )
  1702. {
  1703. INT32 TextX;
  1704. INT32 TextY;
  1705. UINTN FRow;
  1706. UINTN FCol;
  1707. BOOLEAN HighBits;
  1708. LIST_ENTRY *Link;
  1709. HEFI_EDITOR_LINE *Line;
  1710. UINTN Index;
  1711. BOOLEAN Action;
  1712. Action = FALSE;
  1713. //
  1714. // have mouse movement
  1715. //
  1716. if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
  1717. //
  1718. // handle
  1719. //
  1720. TextX = HGetTextX (MouseState.RelativeMovementX);
  1721. TextY = HGetTextY (MouseState.RelativeMovementY);
  1722. HBufferImageAdjustMousePosition (TextX, TextY);
  1723. Action = TRUE;
  1724. }
  1725. if (MouseState.LeftButton) {
  1726. HighBits = HBufferImageIsAtHighBits (
  1727. HMainEditor.BufferImage->MousePosition.Column,
  1728. &FCol
  1729. );
  1730. //
  1731. // not at an movable place
  1732. //
  1733. if (FCol == 0) {
  1734. //
  1735. // now just move mouse pointer to legal position
  1736. //
  1737. //
  1738. // move mouse position to legal position
  1739. //
  1740. HMainEditor.BufferImage->MousePosition.Column -= 10;
  1741. if (HMainEditor.BufferImage->MousePosition.Column > 24) {
  1742. HMainEditor.BufferImage->MousePosition.Column--;
  1743. FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
  1744. } else {
  1745. if (HMainEditor.BufferImage->MousePosition.Column < 24) {
  1746. FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
  1747. } else {
  1748. //
  1749. // == 24
  1750. //
  1751. FCol = 9;
  1752. }
  1753. }
  1754. HighBits = TRUE;
  1755. }
  1756. FRow = HMainEditor.BufferImage->BufferPosition.Row +
  1757. HMainEditor.BufferImage->MousePosition.Row -
  1758. HMainEditor.BufferImage->DisplayPosition.Row;
  1759. if (HMainEditor.BufferImage->NumLines < FRow) {
  1760. //
  1761. // dragging
  1762. //
  1763. //
  1764. // now just move mouse pointer to legal position
  1765. //
  1766. FRow = HMainEditor.BufferImage->NumLines;
  1767. HighBits = TRUE;
  1768. }
  1769. Link = HMainEditor.BufferImage->ListHead->ForwardLink;
  1770. for (Index = 0; Index < FRow - 1; Index++) {
  1771. Link = Link->ForwardLink;
  1772. }
  1773. Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
  1774. //
  1775. // dragging
  1776. //
  1777. //
  1778. // now just move mouse pointer to legal position
  1779. //
  1780. if (FCol > Line->Size) {
  1781. if (*BeforeLeftButtonDown) {
  1782. HighBits = FALSE;
  1783. if (Line->Size == 0) {
  1784. if (FRow > 1) {
  1785. FRow--;
  1786. FCol = 16;
  1787. } else {
  1788. FRow = 1;
  1789. FCol = 1;
  1790. }
  1791. } else {
  1792. FCol = Line->Size;
  1793. }
  1794. } else {
  1795. FCol = Line->Size + 1;
  1796. HighBits = TRUE;
  1797. }
  1798. }
  1799. HBufferImageMovePosition (FRow, FCol, HighBits);
  1800. HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row;
  1801. HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;
  1802. *BeforeLeftButtonDown = TRUE;
  1803. Action = TRUE;
  1804. } else {
  1805. //
  1806. // else of if LButton
  1807. //
  1808. // release LButton
  1809. //
  1810. if (*BeforeLeftButtonDown) {
  1811. Action = TRUE;
  1812. }
  1813. //
  1814. // mouse up
  1815. //
  1816. *BeforeLeftButtonDown = FALSE;
  1817. }
  1818. if (Action) {
  1819. return EFI_SUCCESS;
  1820. }
  1821. return EFI_NOT_FOUND;
  1822. }
  1823. /**
  1824. Handle user key input. will route it to other components handle function.
  1825. @retval EFI_SUCCESS The operation was successful.
  1826. @retval EFI_OUT_OF_RESOURCES A memory allocation occurred.
  1827. @retval EFI_LOAD_ERROR A load error occurred.
  1828. **/
  1829. EFI_STATUS
  1830. HMainEditorKeyInput (
  1831. VOID
  1832. )
  1833. {
  1834. EFI_KEY_DATA KeyData;
  1835. EFI_STATUS Status;
  1836. EFI_SIMPLE_POINTER_STATE MouseState;
  1837. BOOLEAN NoShiftState;
  1838. BOOLEAN LengthChange;
  1839. UINTN Size;
  1840. UINTN OldSize;
  1841. BOOLEAN BeforeMouseIsDown;
  1842. BOOLEAN MouseIsDown;
  1843. BOOLEAN FirstDown;
  1844. BOOLEAN MouseDrag;
  1845. UINTN FRow;
  1846. UINTN FCol;
  1847. UINTN SelectStartBackup;
  1848. UINTN SelectEndBackup;
  1849. //
  1850. // variable initialization
  1851. //
  1852. OldSize = 0;
  1853. FRow = 0;
  1854. FCol = 0;
  1855. LengthChange = FALSE;
  1856. MouseIsDown = FALSE;
  1857. FirstDown = FALSE;
  1858. MouseDrag = FALSE;
  1859. do {
  1860. Status = EFI_SUCCESS;
  1861. HEditorMouseAction = FALSE;
  1862. //
  1863. // backup some key elements, so that can aVOID some refresh work
  1864. //
  1865. HMainEditorBackup ();
  1866. //
  1867. // wait for user key input
  1868. //
  1869. //
  1870. // change priority of checking mouse/keyboard activity dynamically
  1871. // so prevent starvation of keyboard.
  1872. // if last time, mouse moves then this time check keyboard
  1873. //
  1874. if (HMainEditor.MouseSupported) {
  1875. Status = HMainEditor.MouseInterface->GetState (
  1876. HMainEditor.MouseInterface,
  1877. &MouseState
  1878. );
  1879. if (!EFI_ERROR (Status)) {
  1880. BeforeMouseIsDown = MouseIsDown;
  1881. Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);
  1882. if (!EFI_ERROR (Status)) {
  1883. if (!BeforeMouseIsDown) {
  1884. //
  1885. // mouse down
  1886. //
  1887. if (MouseIsDown) {
  1888. FRow = HBufferImage.BufferPosition.Row;
  1889. FCol = HBufferImage.BufferPosition.Column;
  1890. SelectStartBackup = HMainEditor.SelectStart;
  1891. SelectEndBackup = HMainEditor.SelectEnd;
  1892. FirstDown = TRUE;
  1893. }
  1894. } else {
  1895. SelectStartBackup = HMainEditor.SelectStart;
  1896. SelectEndBackup = HMainEditor.SelectEnd;
  1897. //
  1898. // begin to drag
  1899. //
  1900. if (MouseIsDown) {
  1901. if (FirstDown) {
  1902. if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
  1903. HMainEditor.SelectStart = 0;
  1904. HMainEditor.SelectEnd = 0;
  1905. HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;
  1906. MouseDrag = TRUE;
  1907. FirstDown = FALSE;
  1908. }
  1909. } else {
  1910. if ((
  1911. (HBufferImage.BufferPosition.Row - 1) *
  1912. 0x10 +
  1913. HBufferImage.BufferPosition.Column
  1914. ) >= HMainEditor.SelectStart
  1915. ) {
  1916. HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
  1917. 0x10 +
  1918. HBufferImage.BufferPosition.Column;
  1919. } else {
  1920. HMainEditor.SelectEnd = 0;
  1921. }
  1922. }
  1923. //
  1924. // end of if RelativeX/Y
  1925. //
  1926. } else {
  1927. //
  1928. // mouse is up
  1929. //
  1930. if (MouseDrag) {
  1931. if (HBufferImageGetTotalSize () == 0) {
  1932. HMainEditor.SelectStart = 0;
  1933. HMainEditor.SelectEnd = 0;
  1934. FirstDown = FALSE;
  1935. MouseDrag = FALSE;
  1936. }
  1937. if ((
  1938. (HBufferImage.BufferPosition.Row - 1) *
  1939. 0x10 +
  1940. HBufferImage.BufferPosition.Column
  1941. ) >= HMainEditor.SelectStart
  1942. ) {
  1943. HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
  1944. 0x10 +
  1945. HBufferImage.BufferPosition.Column;
  1946. } else {
  1947. HMainEditor.SelectEnd = 0;
  1948. }
  1949. if (HMainEditor.SelectEnd == 0) {
  1950. HMainEditor.SelectStart = 0;
  1951. }
  1952. }
  1953. FirstDown = FALSE;
  1954. MouseDrag = FALSE;
  1955. }
  1956. if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) {
  1957. if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {
  1958. HBufferImageNeedRefresh = TRUE;
  1959. } else {
  1960. if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {
  1961. HBufferImageNeedRefresh = TRUE;
  1962. } else {
  1963. HBufferImageOnlyLineNeedRefresh = TRUE;
  1964. }
  1965. }
  1966. }
  1967. }
  1968. HEditorMouseAction = TRUE;
  1969. HBufferImageMouseNeedRefresh = TRUE;
  1970. } else if (Status == EFI_LOAD_ERROR) {
  1971. StatusBarSetStatusString (L"Invalid Mouse Movement ");
  1972. }
  1973. }
  1974. }
  1975. //
  1976. // CheckEvent() returns Success when non-partial key is pressed.
  1977. //
  1978. Status = gBS->CheckEvent (HMainEditor.TextInputEx->WaitForKeyEx);
  1979. if (!EFI_ERROR (Status)) {
  1980. Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData);
  1981. if (!EFI_ERROR (Status)) {
  1982. //
  1983. // dispatch to different components' key handling function
  1984. // so not everywhere has to set this variable
  1985. //
  1986. HBufferImageMouseNeedRefresh = TRUE;
  1987. //
  1988. // clear previous status string
  1989. //
  1990. StatusBarSetRefresh();
  1991. //
  1992. // NoShiftState: TRUE when no shift key is pressed.
  1993. //
  1994. NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);
  1995. //
  1996. // dispatch to different components' key handling function
  1997. //
  1998. if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&KeyData)) {
  1999. Status = EFI_SUCCESS;
  2000. } else if (NoShiftState && KeyData.Key.ScanCode == SCAN_NULL) {
  2001. Status = HBufferImageHandleInput (&KeyData.Key);
  2002. } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) {
  2003. Status = HBufferImageHandleInput (&KeyData.Key);
  2004. } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_F1) && KeyData.Key.ScanCode <= SCAN_F12)) {
  2005. Status = MenuBarDispatchFunctionKey (&KeyData.Key);
  2006. } else {
  2007. StatusBarSetStatusString (L"Unknown Command");
  2008. HBufferImageMouseNeedRefresh = FALSE;
  2009. }
  2010. if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
  2011. //
  2012. // not already has some error status
  2013. //
  2014. if (StrCmp (L"", StatusBarGetString()) == 0) {
  2015. StatusBarSetStatusString (L"Disk Error. Try Again");
  2016. }
  2017. }
  2018. }
  2019. //
  2020. // decide if has to set length warning
  2021. //
  2022. if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
  2023. LengthChange = FALSE;
  2024. } else {
  2025. //
  2026. // still the old buffer
  2027. //
  2028. if (HBufferImage.BufferType != FileTypeFileBuffer) {
  2029. Size = HBufferImageGetTotalSize ();
  2030. switch (HBufferImage.BufferType) {
  2031. case FileTypeDiskBuffer:
  2032. OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
  2033. break;
  2034. case FileTypeMemBuffer:
  2035. OldSize = HBufferImage.MemImage->Size;
  2036. break;
  2037. default:
  2038. OldSize = 0;
  2039. break;
  2040. }
  2041. if (!LengthChange) {
  2042. if (OldSize != Size) {
  2043. StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
  2044. }
  2045. }
  2046. if (OldSize != Size) {
  2047. LengthChange = TRUE;
  2048. } else {
  2049. LengthChange = FALSE;
  2050. }
  2051. }
  2052. }
  2053. }
  2054. //
  2055. // after handling, refresh editor
  2056. //
  2057. HMainEditorRefresh ();
  2058. } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);
  2059. return Status;
  2060. }
  2061. /**
  2062. Backup function for MainEditor.
  2063. **/
  2064. VOID
  2065. HMainEditorBackup (
  2066. VOID
  2067. )
  2068. {
  2069. HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart;
  2070. HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd;
  2071. HBufferImageBackup ();
  2072. }