DiskImage.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /** @file
  2. Functions to deal with Disk buffer.
  3. Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "HexEditor.h"
  7. #include <Protocol/BlockIo.h>
  8. extern EFI_HANDLE HImageHandleBackup;
  9. extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
  10. extern BOOLEAN HBufferImageNeedRefresh;
  11. extern BOOLEAN HBufferImageOnlyLineNeedRefresh;
  12. extern BOOLEAN HBufferImageMouseNeedRefresh;
  13. extern HEFI_EDITOR_GLOBAL_EDITOR HMainEditor;
  14. HEFI_EDITOR_DISK_IMAGE HDiskImage;
  15. HEFI_EDITOR_DISK_IMAGE HDiskImageBackupVar;
  16. //
  17. // for basic initialization of HDiskImage
  18. //
  19. HEFI_EDITOR_DISK_IMAGE HDiskImageConst = {
  20. NULL,
  21. 0,
  22. 0,
  23. 0
  24. };
  25. /**
  26. Initialization function for HDiskImage.
  27. @retval EFI_SUCCESS The operation was successful.
  28. @retval EFI_LOAD_ERROR A load error occurred.
  29. **/
  30. EFI_STATUS
  31. HDiskImageInit (
  32. VOID
  33. )
  34. {
  35. //
  36. // basically initialize the HDiskImage
  37. //
  38. CopyMem (&HDiskImage, &HDiskImageConst, sizeof (HDiskImage));
  39. CopyMem (&HDiskImageBackupVar, &HDiskImageConst, sizeof (HDiskImageBackupVar));
  40. return EFI_SUCCESS;
  41. }
  42. /**
  43. Backup function for HDiskImage. Only a few fields need to be backup.
  44. This is for making the Disk buffer refresh as few as possible.
  45. @retval EFI_SUCCESS The operation was successful.
  46. @retval EFI_OUT_OF_RESOURCES gST->ConOut of resources.
  47. **/
  48. EFI_STATUS
  49. HDiskImageBackup (
  50. VOID
  51. )
  52. {
  53. //
  54. // backup the disk name, offset and size
  55. //
  56. //
  57. SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
  58. HDiskImageBackupVar.Name = CatSPrint(NULL, L"%s", HDiskImage.Name);
  59. if (HDiskImageBackupVar.Name == NULL) {
  60. return EFI_OUT_OF_RESOURCES;
  61. }
  62. HDiskImageBackupVar.Offset = HDiskImage.Offset;
  63. HDiskImageBackupVar.Size = HDiskImage.Size;
  64. return EFI_SUCCESS;
  65. }
  66. /**
  67. Cleanup function for HDiskImage.
  68. @retval EFI_SUCCESS The operation was successful.
  69. **/
  70. EFI_STATUS
  71. HDiskImageCleanup (
  72. VOID
  73. )
  74. {
  75. SHELL_FREE_NON_NULL (HDiskImage.Name);
  76. SHELL_FREE_NON_NULL (HDiskImageBackupVar.Name);
  77. return EFI_SUCCESS;
  78. }
  79. /**
  80. Set FileName field in HFileImage.
  81. @param[in] Str File name to set.
  82. @param[in] Offset The offset.
  83. @param[in] Size The size.
  84. @retval EFI_SUCCESS The operation was successful.
  85. @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
  86. **/
  87. EFI_STATUS
  88. HDiskImageSetDiskNameOffsetSize (
  89. IN CONST CHAR16 *Str,
  90. IN UINTN Offset,
  91. IN UINTN Size
  92. )
  93. {
  94. if (Str == HDiskImage.Name) {
  95. //
  96. // This function might be called using HDiskImage.FileName as Str.
  97. // Directly return without updating HDiskImage.FileName.
  98. //
  99. return EFI_SUCCESS;
  100. }
  101. //
  102. // free the old file name
  103. //
  104. SHELL_FREE_NON_NULL (HDiskImage.Name);
  105. HDiskImage.Name = AllocateCopyPool (StrSize (Str), Str);
  106. if (HDiskImage.Name == NULL) {
  107. return EFI_OUT_OF_RESOURCES;
  108. }
  109. HDiskImage.Offset = Offset;
  110. HDiskImage.Size = Size;
  111. return EFI_SUCCESS;
  112. }
  113. /**
  114. Read a disk from disk into HBufferImage.
  115. @param[in] DeviceName filename to read.
  116. @param[in] Offset The offset.
  117. @param[in] Size The size.
  118. @param[in] Recover if is for recover, no information print.
  119. @retval EFI_SUCCESS The operation was successful.
  120. @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
  121. @retval EFI_LOAD_ERROR A load error occurred.
  122. @retval EFI_INVALID_PARAMETER A parameter was invalid.
  123. **/
  124. EFI_STATUS
  125. HDiskImageRead (
  126. IN CONST CHAR16 *DeviceName,
  127. IN UINTN Offset,
  128. IN UINTN Size,
  129. IN BOOLEAN Recover
  130. )
  131. {
  132. CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  133. EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
  134. EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
  135. EFI_HANDLE Handle;
  136. EFI_BLOCK_IO_PROTOCOL *BlkIo;
  137. EFI_STATUS Status;
  138. VOID *Buffer;
  139. CHAR16 *Str;
  140. UINTN Bytes;
  141. HEFI_EDITOR_LINE *Line;
  142. HBufferImage.BufferType = FileTypeDiskBuffer;
  143. DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
  144. if (DevicePath == NULL) {
  145. StatusBarSetStatusString (L"Cannot Find Device");
  146. return EFI_INVALID_PARAMETER;
  147. }
  148. DupDevicePath = DuplicateDevicePath(DevicePath);
  149. DupDevicePathForFree = DupDevicePath;
  150. //
  151. // get blkio interface
  152. //
  153. Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
  154. FreePool(DupDevicePathForFree);
  155. if (EFI_ERROR (Status)) {
  156. StatusBarSetStatusString (L"Read Disk Failed");
  157. return Status;
  158. }
  159. Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  160. if (EFI_ERROR (Status)) {
  161. StatusBarSetStatusString (L"Read Disk Failed");
  162. return Status;
  163. }
  164. //
  165. // if Offset exceeds LastBlock,
  166. // return error
  167. //
  168. if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) {
  169. StatusBarSetStatusString (L"Invalid Offset + Size");
  170. return EFI_LOAD_ERROR;
  171. }
  172. Bytes = BlkIo->Media->BlockSize * Size;
  173. Buffer = AllocateZeroPool (Bytes);
  174. if (Buffer == NULL) {
  175. StatusBarSetStatusString (L"Read Disk Failed");
  176. return EFI_OUT_OF_RESOURCES;
  177. }
  178. //
  179. // read from disk
  180. //
  181. Status = BlkIo->ReadBlocks (
  182. BlkIo,
  183. BlkIo->Media->MediaId,
  184. Offset,
  185. Bytes,
  186. Buffer
  187. );
  188. if (EFI_ERROR (Status)) {
  189. FreePool (Buffer);
  190. StatusBarSetStatusString (L"Read Disk Failed");
  191. return EFI_LOAD_ERROR;
  192. }
  193. HBufferImageFree ();
  194. //
  195. // convert buffer to line list
  196. //
  197. Status = HBufferImageBufferToList (Buffer, Bytes);
  198. FreePool (Buffer);
  199. if (EFI_ERROR (Status)) {
  200. StatusBarSetStatusString (L"Read Disk Failed");
  201. return Status;
  202. }
  203. Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
  204. if (EFI_ERROR (Status)) {
  205. StatusBarSetStatusString (L"Read Disk Failed");
  206. return EFI_OUT_OF_RESOURCES;
  207. }
  208. //
  209. // initialize some variables
  210. //
  211. HDiskImage.BlockSize = BlkIo->Media->BlockSize;
  212. HBufferImage.DisplayPosition.Row = 2;
  213. HBufferImage.DisplayPosition.Column = 10;
  214. HBufferImage.MousePosition.Row = 2;
  215. HBufferImage.MousePosition.Column = 10;
  216. HBufferImage.LowVisibleRow = 1;
  217. HBufferImage.HighBits = TRUE;
  218. HBufferImage.BufferPosition.Row = 1;
  219. HBufferImage.BufferPosition.Column = 1;
  220. if (!Recover) {
  221. Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
  222. if (Str == NULL) {
  223. StatusBarSetStatusString (L"Read Disk Failed");
  224. return EFI_OUT_OF_RESOURCES;
  225. }
  226. StatusBarSetStatusString (Str);
  227. SHELL_FREE_NON_NULL (Str);
  228. HMainEditor.SelectStart = 0;
  229. HMainEditor.SelectEnd = 0;
  230. }
  231. //
  232. // has line
  233. //
  234. if (HBufferImage.Lines != NULL) {
  235. HBufferImage.CurrentLine = CR (
  236. HBufferImage.ListHead->ForwardLink,
  237. HEFI_EDITOR_LINE,
  238. Link,
  239. EFI_EDITOR_LINE_LIST
  240. );
  241. } else {
  242. //
  243. // create a dummy line
  244. //
  245. Line = HBufferImageCreateLine ();
  246. if (Line == NULL) {
  247. StatusBarSetStatusString (L"Read Disk Failed");
  248. return EFI_OUT_OF_RESOURCES;
  249. }
  250. HBufferImage.CurrentLine = Line;
  251. }
  252. HBufferImage.Modified = FALSE;
  253. HBufferImageNeedRefresh = TRUE;
  254. HBufferImageOnlyLineNeedRefresh = FALSE;
  255. HBufferImageMouseNeedRefresh = TRUE;
  256. return EFI_SUCCESS;
  257. }
  258. /**
  259. Save lines in HBufferImage to disk.
  260. NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!
  261. @param[in] DeviceName The device name.
  262. @param[in] Offset The offset.
  263. @param[in] Size The size.
  264. @retval EFI_SUCCESS The operation was successful.
  265. @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
  266. @retval EFI_LOAD_ERROR A load error occurred.
  267. @retval EFI_INVALID_PARAMETER A parameter was invalid.
  268. **/
  269. EFI_STATUS
  270. HDiskImageSave (
  271. IN CHAR16 *DeviceName,
  272. IN UINTN Offset,
  273. IN UINTN Size
  274. )
  275. {
  276. CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  277. EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
  278. EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree;
  279. EFI_BLOCK_IO_PROTOCOL *BlkIo;
  280. EFI_STATUS Status;
  281. EFI_HANDLE Handle;
  282. VOID *Buffer;
  283. UINTN Bytes;
  284. //
  285. // if not modified, directly return
  286. //
  287. if (HBufferImage.Modified == FALSE) {
  288. return EFI_SUCCESS;
  289. }
  290. HBufferImage.BufferType = FileTypeDiskBuffer;
  291. DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
  292. if (DevicePath == NULL) {
  293. // StatusBarSetStatusString (L"Cannot Find Device");
  294. return EFI_INVALID_PARAMETER;
  295. }
  296. DupDevicePath = DuplicateDevicePath(DevicePath);
  297. DupDevicePathForFree = DupDevicePath;
  298. //
  299. // get blkio interface
  300. //
  301. Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
  302. FreePool(DupDevicePathForFree);
  303. if (EFI_ERROR (Status)) {
  304. // StatusBarSetStatusString (L"Read Disk Failed");
  305. return Status;
  306. }
  307. Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  308. if (EFI_ERROR (Status)) {
  309. // StatusBarSetStatusString (L"Read Disk Failed");
  310. return Status;
  311. }
  312. Bytes = BlkIo->Media->BlockSize * Size;
  313. Buffer = AllocateZeroPool (Bytes);
  314. if (Buffer == NULL) {
  315. return EFI_OUT_OF_RESOURCES;
  316. }
  317. //
  318. // concatenate the line list to a buffer
  319. //
  320. Status = HBufferImageListToBuffer (Buffer, Bytes);
  321. if (EFI_ERROR (Status)) {
  322. FreePool (Buffer);
  323. return Status;
  324. }
  325. //
  326. // write the buffer to disk
  327. //
  328. Status = BlkIo->WriteBlocks (
  329. BlkIo,
  330. BlkIo->Media->MediaId,
  331. Offset,
  332. Bytes,
  333. Buffer
  334. );
  335. FreePool (Buffer);
  336. if (EFI_ERROR (Status)) {
  337. return EFI_LOAD_ERROR;
  338. }
  339. //
  340. // now not modified
  341. //
  342. HBufferImage.Modified = FALSE;
  343. return EFI_SUCCESS;
  344. }