Source code of Windows XP (NT5)
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.

207 lines
5.4 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. comp.c
  5. Abstract:
  6. Shell app "comp" - compare two files
  7. Revision History
  8. --*/
  9. #include "shell.h"
  10. #define COPY_SIZE (64*1024)
  11. VOID *CpBuffer;
  12. /*
  13. *
  14. */
  15. EFI_STATUS
  16. InitializeComp (
  17. IN EFI_HANDLE ImageHandle,
  18. IN EFI_SYSTEM_TABLE *SystemTable
  19. );
  20. VOID
  21. CopyCP (
  22. IN SHELL_FILE_ARG *Src,
  23. IN SHELL_FILE_ARG *Dst,
  24. IN BOOLEAN CreateSubDir
  25. );
  26. /*
  27. *
  28. */
  29. EFI_DRIVER_ENTRY_POINT(InitializeComp)
  30. EFI_STATUS
  31. InitializeComp (
  32. IN EFI_HANDLE ImageHandle,
  33. IN EFI_SYSTEM_TABLE *SystemTable
  34. )
  35. {
  36. CHAR16 **Argv;
  37. UINTN Argc;
  38. LIST_ENTRY File1List;
  39. LIST_ENTRY File2List;
  40. SHELL_FILE_ARG *File1Arg, *File2Arg;
  41. UINTN Size, ReadSize;
  42. UINT8 *File1Buffer;
  43. UINT8 *File2Buffer;
  44. UINTN NotTheSameCount;
  45. EFI_STATUS Status;
  46. UINTN Index, Count;
  47. UINTN Address;
  48. /*
  49. * Check to see if the app is to install as a "internal command"
  50. * to the shell
  51. */
  52. InstallInternalShellCommand (
  53. ImageHandle, SystemTable, InitializeComp,
  54. L"comp", /* command */
  55. L"comp file1 file2", /* command syntax */
  56. L"Compare two files", /* 1 line descriptor */
  57. NULL /* command help page */
  58. );
  59. /*
  60. * We are not being installed as an internal command driver, initialize
  61. * as an nshell app and run
  62. */
  63. InitializeShellApplication (ImageHandle, SystemTable);
  64. InitializeListHead (&File1List);
  65. InitializeListHead (&File2List);
  66. File1Buffer = File2Buffer = NULL;
  67. Argv = SI->Argv;
  68. Argc = SI->Argc;
  69. if (Argc < 3) {
  70. Print (L"cp: no files specified\n");
  71. goto Done;
  72. }
  73. /*
  74. * Expand the source file list
  75. */
  76. ShellFileMetaArg (Argv[1], &File1List);
  77. File1Arg = CR(File1List.Flink, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
  78. if ((EFI_ERROR(File1Arg->Status) && File1Arg->Status != EFI_NOT_FOUND) ||
  79. !File1Arg->Handle ) {
  80. Print (L"comp: could not open file1 %hs - %r\n", File1Arg->FullName, File1Arg->Status);
  81. goto Done;
  82. }
  83. if (File1Arg->Info && (File1Arg->Info->Attribute & EFI_FILE_DIRECTORY)) {
  84. Print(L"comp: file1 can not be a directory\n");
  85. goto Done;
  86. }
  87. ShellFileMetaArg (Argv[2], &File2List);
  88. File2Arg = CR(File2List.Flink, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
  89. if ((EFI_ERROR(File2Arg->Status) && File2Arg->Status != EFI_NOT_FOUND) ||
  90. !File2Arg->Handle ) {
  91. Print (L"comp: could not open file2 %hs - %r\n", File2Arg->FullName, File2Arg->Status);
  92. goto Done;
  93. }
  94. if (File2Arg->Info && (File2Arg->Info->Attribute & EFI_FILE_DIRECTORY)) {
  95. Print(L"comp: file2 can not be a directory\n");
  96. goto Done;
  97. }
  98. File1Buffer = AllocatePool (COPY_SIZE);
  99. File2Buffer = AllocatePool (COPY_SIZE);
  100. if (!File1Buffer || !File2Buffer) {
  101. Print(L"comp: out of memory\n");
  102. goto Done;
  103. }
  104. /*
  105. * Compare files
  106. */
  107. Print(L"Compare %s to %s\n", File1Arg->FullName, File2Arg->FullName);
  108. File1Arg->Handle->SetPosition (File1Arg->Handle, 0);
  109. File2Arg->Handle->SetPosition (File2Arg->Handle, 0);
  110. Size = COPY_SIZE;
  111. for (NotTheSameCount = 0, Address = 0; Size > 0 && NotTheSameCount < 10;) {
  112. Size = COPY_SIZE;
  113. Status = File1Arg->Handle->Read (File1Arg->Handle, &Size, File1Buffer);
  114. if (EFI_ERROR(Status)) {
  115. Print(L"- read error file1: %r\n", Status);
  116. NotTheSameCount++;
  117. break;
  118. }
  119. ReadSize = COPY_SIZE;
  120. Status = File2Arg->Handle->Read (File2Arg->Handle, &ReadSize, File2Buffer);
  121. if (EFI_ERROR(Status)) {
  122. Print(L"- read error file2: %r\n", Status);
  123. NotTheSameCount++;
  124. break;
  125. }
  126. if (ReadSize != Size) {
  127. Print(L"- File size miss match\n");
  128. NotTheSameCount++;
  129. break;
  130. }
  131. /*
  132. * Diff the buffer
  133. */
  134. for (Index = 0; (Index < Size) && (NotTheSameCount < 10); Index++) {
  135. if (File1Buffer[Index] != File2Buffer[Index] ) {
  136. for (Count = 1; Count < 0x20; Count++) {
  137. if (File1Buffer[Index + Count] == File2Buffer[Index + Count]) {
  138. break;
  139. }
  140. }
  141. Print (L"Miscompare #%d File1: %s\n", NotTheSameCount + 1, File1Arg->FullName);
  142. DumpHex (1, Address + Index, Count, &File1Buffer[Index]);
  143. Print (L"File2: %s\n", File2Arg->FullName);
  144. DumpHex (1, Address + Index, Count, &File2Buffer[Index]);
  145. Print (L"\n");
  146. NotTheSameCount++;
  147. Index += Count;
  148. }
  149. }
  150. Address += Size;
  151. }
  152. if (!NotTheSameCount) {
  153. Print(L"[ok]\n");
  154. Status = EFI_SUCCESS;
  155. } else {
  156. Status = EFI_NOT_FOUND;
  157. }
  158. Done:
  159. if (File1Buffer) {
  160. FreePool (File1Buffer);
  161. }
  162. if (File2Buffer) {
  163. FreePool (File2Buffer);
  164. }
  165. ShellFreeFileList (&File1List);
  166. ShellFreeFileList (&File2List);
  167. return Status;
  168. }