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.

269 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1998 Intel Corporation
  3. Module Name:
  4. rm.c
  5. Abstract:
  6. Shell app "rm"
  7. Revision History
  8. --*/
  9. #include "shell.h"
  10. /*
  11. *
  12. */
  13. #define FILE_INFO_SIZE (SIZE_OF_EFI_FILE_INFO + 1024)
  14. EFI_FILE_INFO *RmInfo;
  15. /*
  16. *
  17. */
  18. EFI_STATUS
  19. InitializeRM (
  20. IN EFI_HANDLE ImageHandle,
  21. IN EFI_SYSTEM_TABLE *SystemTable
  22. );
  23. VOID
  24. RemoveRM (
  25. IN SHELL_FILE_ARG *Arg,
  26. IN BOOLEAN Quite
  27. );
  28. /*
  29. *
  30. */
  31. EFI_DRIVER_ENTRY_POINT(InitializeRM)
  32. EFI_STATUS
  33. InitializeRM (
  34. IN EFI_HANDLE ImageHandle,
  35. IN EFI_SYSTEM_TABLE *SystemTable
  36. )
  37. {
  38. CHAR16 **Argv;
  39. UINTN Argc;
  40. UINTN Index;
  41. LIST_ENTRY FileList;
  42. LIST_ENTRY *Link;
  43. SHELL_FILE_ARG *Arg;
  44. /*
  45. * Check to see if the app is to install as a "internal command"
  46. * to the shell
  47. */
  48. InstallInternalShellCommand (
  49. ImageHandle, SystemTable, InitializeRM,
  50. L"rm", /* command */
  51. L"rm file/dir [file/dir]", /* command syntax */
  52. L"Remove file/directories", /* 1 line descriptor */
  53. NULL /* command help page */
  54. );
  55. /*
  56. * We are no being installed as an internal command driver, initialize
  57. * as an nshell app and run
  58. */
  59. InitializeShellApplication (ImageHandle, SystemTable);
  60. Argv = SI->Argv;
  61. Argc = SI->Argc;
  62. InitializeListHead (&FileList);
  63. RmInfo = AllocatePool (FILE_INFO_SIZE);
  64. if (!RmInfo) {
  65. Print (L"rm: out of memory\n");
  66. goto Done;
  67. }
  68. /*
  69. * Expand each arg
  70. */
  71. for (Index = 1; Index < Argc; Index += 1) {
  72. ShellFileMetaArg (Argv[Index], &FileList);
  73. }
  74. if (IsListEmpty(&FileList)) {
  75. Print (L"rm: no file specified\n");
  76. goto Done;
  77. }
  78. /*
  79. * Remove each file
  80. */
  81. for (Link=FileList.Flink; Link!=&FileList; Link=Link->Flink) {
  82. Arg = CR(Link, SHELL_FILE_ARG, Link, SHELL_FILE_ARG_SIGNATURE);
  83. RemoveRM (Arg, 0);
  84. }
  85. Done:
  86. ShellFreeFileList (&FileList);
  87. if (RmInfo) {
  88. FreePool (RmInfo);
  89. RmInfo = NULL;
  90. }
  91. return EFI_SUCCESS;
  92. }
  93. SHELL_FILE_ARG *
  94. RmCreateChild (
  95. IN SHELL_FILE_ARG *Parent,
  96. IN CHAR16 *FileName,
  97. IN OUT LIST_ENTRY *ListHead
  98. )
  99. {
  100. SHELL_FILE_ARG *Arg;
  101. UINTN Len;
  102. Arg = AllocateZeroPool (sizeof(SHELL_FILE_ARG));
  103. if (!Arg) {
  104. return NULL;
  105. }
  106. Arg->Signature = SHELL_FILE_ARG_SIGNATURE;
  107. Parent->Parent->Open (Parent->Handle, &Arg->Parent, L".", EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
  108. Arg->ParentName = StrDuplicate(Parent->FullName);
  109. Arg->FileName = StrDuplicate(FileName);
  110. /* append filename to parent's name to get the file's full name */
  111. Len = StrLen(Arg->ParentName);
  112. if (Len && Arg->ParentName[Len-1] == '\\') {
  113. Len -= 1;
  114. }
  115. Arg->FullName = PoolPrint(L"%.*s\\%s", Len, Arg->ParentName, FileName);
  116. /* open it */
  117. Arg->Status = Parent->Handle->Open (
  118. Parent->Handle,
  119. &Arg->Handle,
  120. Arg->FileName,
  121. EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
  122. 0
  123. );
  124. InsertTailList (ListHead, &Arg->Link);
  125. return Arg;
  126. }
  127. VOID
  128. RemoveRM (
  129. IN SHELL_FILE_ARG *Arg,
  130. IN BOOLEAN Quite
  131. )
  132. {
  133. EFI_STATUS Status;
  134. SHELL_FILE_ARG *Child;
  135. LIST_ENTRY Cleanup;
  136. UINTN Size;
  137. CHAR16 Str[2];
  138. Status = Arg->Status;
  139. InitializeListHead (&Cleanup);
  140. if (EFI_ERROR(Status)) {
  141. goto Done;
  142. }
  143. /*
  144. * If the file is a directory check it
  145. */
  146. Size = FILE_INFO_SIZE;
  147. Status = Arg->Handle->GetInfo(Arg->Handle, &GenericFileInfo, &Size, RmInfo);
  148. if (EFI_ERROR(Status)) {
  149. Print(L"rm: can not get info of %hs\n", Arg->FullName);
  150. goto Done;
  151. }
  152. if (RmInfo->Attribute & EFI_FILE_DIRECTORY) {
  153. /*
  154. * Remove all child entries from the directory
  155. */
  156. Arg->Handle->SetPosition (Arg->Handle, 0);
  157. for (; ;) {
  158. Size = FILE_INFO_SIZE;
  159. Status = Arg->Handle->Read (Arg->Handle, &Size, RmInfo);
  160. if (EFI_ERROR(Status) || Size == 0) {
  161. break;
  162. }
  163. /*
  164. * Skip "." and ".."
  165. */
  166. if (StriCmp(RmInfo->FileName, L".") == 0 ||
  167. StriCmp(RmInfo->FileName, L"..") == 0) {
  168. continue;
  169. }
  170. /*
  171. * Build a shell_file_arg for the sub-entry
  172. */
  173. Child = RmCreateChild (Arg, RmInfo->FileName, &Cleanup);
  174. /*
  175. * Remove it
  176. */
  177. if (!Quite) {
  178. Print (L"rm: remove subtree '%hs' [y/n]? ", Arg->FullName);
  179. Input (NULL, Str, 2);
  180. Print (L"\n");
  181. Status = (Str[0] == 'y' || Str[0] == 'Y') ? EFI_SUCCESS : EFI_ACCESS_DENIED;
  182. if (EFI_ERROR(Status)) {
  183. goto Done;
  184. }
  185. }
  186. Quite = TRUE;
  187. RemoveRM (Child, TRUE);
  188. /*
  189. * Close the handles
  190. */
  191. ShellFreeFileList (&Cleanup);
  192. }
  193. }
  194. /*
  195. * Remove the file
  196. */
  197. Status = Arg->Handle->Delete(Arg->Handle);
  198. Arg->Handle = NULL;
  199. Done:
  200. if (EFI_ERROR(Status)) {
  201. Print (L"rm %s : %hr\n", Arg->FullName, Status);
  202. } else {
  203. Print (L"rm %s [ok]\n", Arg->FullName);
  204. }
  205. }