Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

529 lines
14 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. libFileImage.c
  5. Abstract:
  6. Definition of the File Image - the complete image of the file that
  7. resides in memory
  8. --*/
  9. #ifndef _LIB_FILE_IMAGE
  10. #define _LIB_FILE_IMAGE
  11. #include "libMisc.h"
  12. STATIC EFI_EDITOR_LINE* FileImageCreateNode (VOID);
  13. STATIC VOID FileImageDeleteLines (VOID);
  14. #define FILE_ATTRIBUTES EFI_FILE_MODE_READ | \
  15. EFI_FILE_MODE_WRITE | \
  16. EFI_FILE_MODE_CREATE
  17. #define FILE_READ_WRITE EFI_FILE_MODE_READ | \
  18. EFI_FILE_MODE_WRITE
  19. #define FILE_CREATE EFI_FILE_MODE_READ | \
  20. EFI_FILE_MODE_WRITE | \
  21. EFI_FILE_MODE_CREATE
  22. STATIC EFI_STATUS FileImageInit (EFI_HANDLE);
  23. STATIC EFI_STATUS FileImageCleanup (VOID);
  24. STATIC EFI_STATUS FileImageOpen (VOID);
  25. STATIC EFI_STATUS FileImageRead (VOID);
  26. STATIC EFI_STATUS FileImageClose (VOID);
  27. STATIC EFI_STATUS FileImageWrite (VOID);
  28. STATIC EFI_STATUS FileImageSetFilename (CHAR16*);
  29. EFI_EDITOR_FILE_IMAGE FileImage = {
  30. NULL,
  31. NULL,
  32. NULL,
  33. 0,
  34. UNICODE_FILE,
  35. USE_LF,
  36. NULL,
  37. NULL,
  38. NULL,
  39. NULL,
  40. NULL,
  41. FileImageCleanup,
  42. FileImageInit,
  43. FileImageOpen,
  44. FileImageRead,
  45. FileImageClose,
  46. FileImageWrite,
  47. FileImageSetFilename,
  48. FALSE
  49. };
  50. EFI_EDITOR_FILE_IMAGE FileImageConst = {
  51. NULL,
  52. NULL,
  53. NULL,
  54. 0,
  55. UNICODE_FILE,
  56. USE_LF,
  57. NULL,
  58. NULL,
  59. NULL,
  60. NULL,
  61. NULL,
  62. FileImageCleanup,
  63. FileImageInit,
  64. FileImageOpen,
  65. FileImageRead,
  66. FileImageClose,
  67. FileImageWrite,
  68. FileImageSetFilename,
  69. FALSE
  70. };
  71. STATIC
  72. EFI_STATUS
  73. FileImageInit (
  74. IN EFI_HANDLE ImageHandle
  75. )
  76. {
  77. EFI_STATUS Status;
  78. EFI_EDITOR_LINE *Line;
  79. CHAR16 *CurDir;
  80. UINTN i;
  81. EFI_DEVICE_PATH *DevicePath;
  82. CopyMem (&FileImage, &FileImageConst, sizeof(FileImage));
  83. Status = BS->HandleProtocol (ImageHandle,&LoadedImageProtocol,&FileImage.LoadedImage);
  84. if (EFI_ERROR(Status)) {
  85. Print (L"Could not obtain Loaded Image Protocol\n");
  86. return EFI_LOAD_ERROR;
  87. }
  88. if (FileImage.LoadedImage->DeviceHandle != NULL) {
  89. Status = BS->HandleProtocol (FileImage.LoadedImage->DeviceHandle,&DevicePathProtocol,&FileImage.DevicePath);
  90. if (EFI_ERROR(Status)) {
  91. Print (L"Could not obtain Device Path Protocol\n");
  92. return EFI_LOAD_ERROR;
  93. }
  94. Status = BS->HandleProtocol (FileImage.LoadedImage->DeviceHandle,&FileSystemProtocol,&FileImage.Vol);
  95. if (EFI_ERROR(Status)) {
  96. Print (L"Could not obtain File System Protocol\n");
  97. return EFI_LOAD_ERROR;
  98. }
  99. } else {
  100. CurDir = ShellCurDir(NULL);
  101. if (CurDir == NULL) {
  102. Print (L"Could not get current working directory\n");
  103. return EFI_LOAD_ERROR;
  104. }
  105. for (i=0; i < StrLen(CurDir) && CurDir[i] != ':'; i++);
  106. CurDir[i] = 0;
  107. DevicePath = (EFI_DEVICE_PATH *)ShellGetMap (CurDir);
  108. if (DevicePath == NULL) {
  109. Print (L"Could not open volume for the filesystem\n");
  110. return EFI_LOAD_ERROR;
  111. }
  112. Status = LibDevicePathToInterface (&FileSystemProtocol, DevicePath, &FileImage.Vol);
  113. if (EFI_ERROR(Status)) {
  114. Print (L"Could not obtain File System Protocol\n");
  115. return EFI_LOAD_ERROR;
  116. }
  117. }
  118. Status = FileImage.Vol->OpenVolume(FileImage.Vol,&FileImage.CurrentDir);
  119. if (EFI_ERROR(Status)) {
  120. Print (L"Could not open volume for the filesystem\n");
  121. return EFI_LOAD_ERROR;
  122. }
  123. FileImage.FileName = PoolPrint(L"NewFile.txt");
  124. FileImage.ListHead = AllocatePool(sizeof(LIST_ENTRY));
  125. InitializeListHead(FileImage.ListHead);
  126. Line = FileImageCreateNode();
  127. MainEditor.FileBuffer->CurrentLine = FileImage.ListHead->Flink;
  128. return EFI_SUCCESS;
  129. }
  130. STATIC
  131. EFI_STATUS
  132. FileImageOpen (
  133. VOID
  134. )
  135. {
  136. EFI_STATUS Status;
  137. Status = FileImage.CurrentDir->Open (FileImage.CurrentDir,&FileImage.FileHandle,FileImage.FileName,FILE_ATTRIBUTES,0);
  138. if (EFI_ERROR(Status)) {
  139. MainEditor.StatusBar->SetStatusString(L"File Could Not be Opened");
  140. return EFI_NOT_FOUND;
  141. }
  142. FileImage.FileIsOpen = TRUE;
  143. return EFI_SUCCESS;
  144. }
  145. STATIC
  146. EFI_STATUS
  147. FileImageCleanup (
  148. VOID
  149. )
  150. {
  151. EFI_EDITOR_LINE *Blank;
  152. FreePool (FileImage.FileName);
  153. FileImageDeleteLines ();
  154. Blank = LineCurrent();
  155. RemoveEntryList(&Blank->Link);
  156. FreePool(Blank->Buffer);
  157. FreePool(Blank);
  158. FreePool(FileImage.ListHead);
  159. return EFI_SUCCESS;
  160. }
  161. STATIC
  162. EFI_STATUS
  163. FileImageRead (
  164. VOID
  165. )
  166. {
  167. EFI_EDITOR_LINE *Line = NULL;
  168. UINTN i = 0;
  169. UINTN LineSize;
  170. VOID *FileBuffer;
  171. CHAR16 *UnicodeBuffer;
  172. CHAR8 *AsciiBuffer;
  173. LIST_ENTRY *Blank;
  174. UINTN FileSize = 0x100000;
  175. FileBuffer = AllocatePool(FileSize);
  176. if ( FileBuffer == NULL ) {
  177. EditorError(EFI_OUT_OF_RESOURCES,L"Could not allocate File Buffer");
  178. return EFI_SUCCESS;
  179. }
  180. FileImage.FileHandle->Read(FileImage.FileHandle,&FileSize,FileBuffer);
  181. if (FileSize == 0) {
  182. FreePool (FileBuffer);
  183. return EFI_SUCCESS;
  184. }
  185. AsciiBuffer = FileBuffer;
  186. if (AsciiBuffer[0] == 0xff && AsciiBuffer[1] == 0xfe) {
  187. FileImage.FileType = UNICODE_FILE;
  188. FileSize /= 2;
  189. UnicodeBuffer = FileBuffer;
  190. ++UnicodeBuffer;
  191. FileSize--;
  192. } else {
  193. FileImage.FileType = ASCII_FILE;
  194. }
  195. FileImageDeleteLines ();
  196. Blank = FileImage.ListHead->Flink;
  197. RemoveEntryList (Blank);
  198. for (i = 0; i < FileSize; i++) {
  199. for (LineSize = i; LineSize < FileSize; LineSize++) {
  200. if (FileImage.FileType == ASCII_FILE) {
  201. if (AsciiBuffer[LineSize] == CHAR_CR) {
  202. FileImage.NewLineType = USE_CRLF;
  203. break;
  204. } else if (AsciiBuffer[LineSize] == CHAR_LF) {
  205. break;
  206. }
  207. } else {
  208. if (UnicodeBuffer[LineSize] == CHAR_CR) {
  209. FileImage.NewLineType = USE_CRLF;
  210. break;
  211. } else if (UnicodeBuffer[LineSize] == CHAR_LF) {
  212. break;
  213. }
  214. }
  215. }
  216. LineSize -= i;
  217. Line = FileImageCreateNode ();
  218. if (Line == NULL) {
  219. EditorError(EFI_OUT_OF_RESOURCES,L"FileImageRead: Could Not Allocate another Line");
  220. break;
  221. }
  222. Line->Buffer = AllocateZeroPool(LineSize*2+2);
  223. if (Line->Buffer == NULL) {
  224. EditorError(EFI_OUT_OF_RESOURCES,L"FileImageRead: Could not allocate buffer");
  225. RemoveEntryList(&Line->Link);
  226. break;
  227. }
  228. for (Line->Size = 0; Line->Size < LineSize; Line->Size++) {
  229. if (FileImage.FileType == ASCII_FILE) {
  230. Line->Buffer[Line->Size] = (CHAR16)AsciiBuffer[i];
  231. } else {
  232. Line->Buffer[Line->Size] = UnicodeBuffer[i];
  233. }
  234. i++;
  235. }
  236. Line->Size++;
  237. if (FileImage.NewLineType == USE_CRLF) {
  238. ++i;
  239. }
  240. Line->Buffer[LineSize] = 0;
  241. }
  242. FreePool (FileBuffer);
  243. InsertTailList(FileImage.ListHead,Blank);
  244. MainEditor.FileBuffer->FilePosition.Row = 1;
  245. MainEditor.FileBuffer->FilePosition.Column = 1;
  246. MainEditor.FileBuffer->CurrentLine = FileImage.ListHead->Flink;
  247. MainEditor.StatusBar->SetPosition(1,1);
  248. UnicodeBuffer = PoolPrint(L"%d Lines Read",FileImage.NumLines);
  249. MainEditor.StatusBar->SetStatusString(UnicodeBuffer);
  250. FreePool (UnicodeBuffer);
  251. FileImage.FileHandle->Close(FileImage.FileHandle);
  252. FileImage.FileIsOpen = FALSE;
  253. return EFI_SUCCESS;
  254. }
  255. STATIC
  256. VOID
  257. GetNewLine (
  258. CHAR8 *Buffer,
  259. UINT8 *Size
  260. )
  261. {
  262. UINT8 size = 0;
  263. if (FileImage.NewLineType == USE_CRLF) {
  264. Buffer[size] = 0x0d;
  265. size++;
  266. if (FileImage.FileType == UNICODE_FILE) {
  267. Buffer[size] = 0x00;
  268. size++;
  269. }
  270. }
  271. Buffer[size] = 0x0a;
  272. size++;
  273. if (FileImage.FileType == UNICODE_FILE) {
  274. Buffer[size] = 0x00;
  275. size++;
  276. }
  277. *Size = size;
  278. }
  279. STATIC
  280. EFI_STATUS
  281. FileImageWrite (
  282. VOID
  283. )
  284. {
  285. LIST_ENTRY *Link;
  286. EFI_EDITOR_LINE *Line;
  287. CHAR16 *Str;
  288. VOID *Buffer;
  289. EFI_STATUS Status;
  290. UINTN Length = 0;
  291. UINTN NumLines = 1;
  292. CHAR8 NewLineBuffer[4];
  293. UINT8 NewLineSize;
  294. Status = FileImage.CurrentDir->Open (FileImage.CurrentDir,&FileImage.FileHandle,FileImage.FileName,FILE_READ_WRITE,0);
  295. if (!EFI_ERROR(Status)) {
  296. Status = FileImage.FileHandle->Delete (FileImage.FileHandle);
  297. if (EFI_ERROR(Status)) {
  298. EditorError(Status,L"Error Deleting File");
  299. /* return EFI_SUCCESS; */
  300. }
  301. }
  302. Status = FileImage.CurrentDir->Open(FileImage.CurrentDir,&FileImage.FileHandle,FileImage.FileName,FILE_CREATE,0);
  303. if (EFI_ERROR(Status)) {
  304. EditorError(Status,L"Error Accessing File");
  305. return EFI_SUCCESS;
  306. }
  307. GetNewLine(NewLineBuffer,&NewLineSize);
  308. if (FileImage.FileType == UNICODE_FILE) {
  309. UINT8 Marker1 = 0xff,Marker2 = 0xfe;
  310. Length = 1;
  311. FileImage.FileHandle->Write(FileImage.FileHandle,&Length,&Marker1);
  312. Length = 1;
  313. FileImage.FileHandle->Write(FileImage.FileHandle,&Length,&Marker2);
  314. }
  315. for (Link = FileImage.ListHead->Flink;
  316. Link != FileImage.ListHead->Blink; Link = Link->Flink) {
  317. Line = CR(Link,EFI_EDITOR_LINE,Link,EFI_EDITOR_LINE_LIST);
  318. Line->Buffer[Line->Size-1] = 0;
  319. if (FileImage.FileType == ASCII_FILE) {
  320. (CHAR8*)Buffer = AllocatePool(Line->Size);
  321. UnicodeToAscii(Line->Buffer,Line->Size,(CHAR8*)Buffer);
  322. Length = Line->Size - 1;
  323. } else {
  324. Length = (Line->Size*2) - 2;
  325. (CHAR16*)Buffer = PoolPrint(L"%s",Line->Buffer);
  326. }
  327. Status = FileImage.FileHandle->Write(FileImage.FileHandle,&Length,Buffer);
  328. FreePool(Buffer);
  329. if (EFI_ERROR(Status)) {
  330. EditorError(Status,L"Error Writing File");
  331. return EFI_SUCCESS;
  332. }
  333. Length = NewLineSize;
  334. Status = FileImage.FileHandle->Write(FileImage.FileHandle,&Length,NewLineBuffer);
  335. if (EFI_ERROR(Status)) {
  336. EditorError(Status,L"Error Writing Newline");
  337. return EFI_SUCCESS;
  338. }
  339. NumLines++;
  340. }
  341. MainEditor.FileModified = FALSE;
  342. MainEditor.TitleBar->Refresh();
  343. Str = PoolPrint(L"Wrote %d Lines",NumLines);
  344. MainEditor.StatusBar->SetStatusString(Str);
  345. FreePool(Str);
  346. Status = FileImage.FileHandle->Close(FileImage.FileHandle);
  347. if ( EFI_ERROR(Status) ) {
  348. EditorError(Status,L"Error Closing File");
  349. return EFI_SUCCESS;
  350. }
  351. return EFI_SUCCESS;
  352. }
  353. STATIC
  354. EFI_STATUS
  355. FileImageClose (
  356. VOID
  357. )
  358. {
  359. FileImageDeleteLines ();
  360. MainEditor.FileBuffer->FilePosition.Row = 1;
  361. MainEditor.FileBuffer->FilePosition.Column = 1;
  362. MainEditor.StatusBar->SetPosition(1,1);
  363. MainEditor.FileBuffer->SetPosition(TEXT_START_ROW,TEXT_START_COLUMN);
  364. MainEditor.FileModified = FALSE;
  365. MainEditor.TitleBar->Refresh();
  366. return EFI_SUCCESS;
  367. }
  368. STATIC
  369. EFI_STATUS
  370. FileImageSetFilename (
  371. IN CHAR16* Filename
  372. )
  373. {
  374. if (Filename == NULL) {
  375. return EFI_LOAD_ERROR;
  376. }
  377. if (FileImage.FileName != NULL) {
  378. FreePool(FileImage.FileName);
  379. }
  380. FileImage.FileName = PoolPrint(L"%s",Filename);
  381. return EFI_SUCCESS;
  382. }
  383. STATIC
  384. VOID
  385. FileImageDeleteLines (
  386. VOID
  387. )
  388. {
  389. EFI_EDITOR_LINE *Line;
  390. LIST_ENTRY *Blank;
  391. LIST_ENTRY *Item;
  392. Blank = FileImage.ListHead->Blink;
  393. RemoveEntryList(Blank);
  394. while (!IsListEmpty(FileImage.ListHead)) {
  395. Item = FileImage.ListHead->Flink;
  396. RemoveEntryList(Item);
  397. Line = CR(Item,EFI_EDITOR_LINE,Link,EFI_EDITOR_LINE_LIST);
  398. if (Line->Buffer != NULL && Line->Buffer != (CHAR16*)BAD_POINTER) {
  399. FreePool(Line->Buffer);
  400. }
  401. FreePool (Line);
  402. FileImage.NumLines--;
  403. }
  404. InsertTailList(FileImage.ListHead,Blank);
  405. MainEditor.FileBuffer->CurrentLine = Blank;
  406. FileImage.NumLines = 1;
  407. }
  408. STATIC
  409. EFI_EDITOR_LINE*
  410. FileImageCreateNode (
  411. VOID
  412. )
  413. {
  414. EFI_EDITOR_LINE *Line;
  415. Line = AllocatePool (sizeof(EFI_EDITOR_LINE));
  416. if ( Line == NULL ) {
  417. EditorError(EFI_OUT_OF_RESOURCES,L"FileImageCreateNode: Could not allocate Node");
  418. return NULL;
  419. }
  420. Line->Signature = EFI_EDITOR_LINE_LIST;
  421. Line->Size = 1;
  422. Line->Buffer = PoolPrint(L" \0");
  423. FileImage.NumLines++;
  424. InsertTailList(FileImage.ListHead,&Line->Link);
  425. return Line;
  426. }
  427. #endif /* _LIB_FILE_IMAGE */