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.

213 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1991-2000 Microsoft Corporation
  3. Module Name:
  4. recover.cxx
  5. Abstract:
  6. Utility to recover data from a disk
  7. Author:
  8. Norbert P. Kusters (norbertk) 12-June-1991
  9. Revision History:
  10. --*/
  11. #define _NTAPI_ULIB_
  12. #include "ulib.hxx"
  13. #include "arg.hxx"
  14. #include "smsg.hxx"
  15. #include "rtmsg.h"
  16. #include "wstring.hxx"
  17. #include "path.hxx"
  18. #include "system.hxx"
  19. #include "ifssys.hxx"
  20. #include "substrng.hxx"
  21. #include "ulibcl.hxx"
  22. #include "ifsentry.hxx"
  23. int __cdecl
  24. main(
  25. )
  26. {
  27. STREAM_MESSAGE Message;
  28. DSTRING FsName;
  29. DSTRING LibraryName;
  30. HANDLE FsUtilityHandle;
  31. DSTRING RecoverString;
  32. RECOVER_FN Recover = NULL;
  33. ARGUMENT_LEXEMIZER arglex;
  34. ARRAY lex_array;
  35. ARRAY arg_array;
  36. STRING_ARGUMENT progname;
  37. FLAG_ARGUMENT help_arg;
  38. PATH_ARGUMENT path_arg;
  39. PWSTRING dosdrive = NULL;
  40. DSTRING ntdrive;
  41. NTSTATUS Status;
  42. PPATH CanonicalPath;
  43. PWSTRING DirsAndName;
  44. PWSTRING pwstring;
  45. if (!Message.Initialize(Get_Standard_Output_Stream(),
  46. Get_Standard_Input_Stream())) {
  47. return 1;
  48. }
  49. if (!lex_array.Initialize() || !arg_array.Initialize()) {
  50. return 1;
  51. }
  52. if (!arglex.Initialize(&lex_array)) {
  53. return 1;
  54. }
  55. arglex.PutStartQuotes("\"");
  56. arglex.PutEndQuotes("\"");
  57. arglex.PutSeparators(" \t");
  58. arglex.SetCaseSensitive(FALSE);
  59. if (!arglex.PrepareToParse()) {
  60. return 1;
  61. }
  62. if (!progname.Initialize("*") ||
  63. !help_arg.Initialize("/?") ||
  64. !path_arg.Initialize("*")) {
  65. return 1;
  66. }
  67. if (!arg_array.Put(&progname) ||
  68. !arg_array.Put(&help_arg) ||
  69. !arg_array.Put(&path_arg)) {
  70. return 1;
  71. }
  72. if (!arglex.DoParsing(&arg_array)) {
  73. Message.Set(MSG_INVALID_PARAMETER);
  74. Message.Display("%W", pwstring = arglex.QueryInvalidArgument());
  75. DELETE(pwstring);
  76. return 1;
  77. }
  78. if (help_arg.QueryFlag()) {
  79. Message.Set(MSG_RECOV_INFO);
  80. Message.Display("");
  81. Message.Set(MSG_RECOV_USAGE);
  82. Message.Display("");
  83. Message.Set(MSG_RECOV_INFO2);
  84. Message.Display("");
  85. return 0;
  86. }
  87. if (!path_arg.IsValueSet()) {
  88. Message.Set(MSG_RECOV_USAGE);
  89. Message.Display("");
  90. return 1;
  91. }
  92. // Make sure that the user has specified a file name
  93. DirsAndName = path_arg.GetPath()->QueryDirsAndName();
  94. if (!DirsAndName || DirsAndName->QueryChCount() == 0) {
  95. Message.Set(MSG_RECOV_NOT_SUPPORTED);
  96. Message.Display("");
  97. DELETE(DirsAndName);
  98. return 1;
  99. }
  100. DELETE(DirsAndName);
  101. CanonicalPath = path_arg.GetPath()->QueryFullPath();
  102. dosdrive = CanonicalPath->QueryDevice();
  103. // Make sure that drive is not remote.
  104. if (!dosdrive ||
  105. SYSTEM::QueryDriveType(dosdrive) == RemoteDrive) {
  106. Message.Set(MSG_RECOV_CANT_NETWORK);
  107. Message.Display();
  108. DELETE(dosdrive);
  109. DELETE(CanonicalPath);
  110. return 1;
  111. }
  112. if (!IFS_SYSTEM::DosDriveNameToNtDriveName(dosdrive, &ntdrive)) {
  113. DELETE(dosdrive);
  114. DELETE(CanonicalPath);
  115. return 1;
  116. }
  117. if (!IFS_SYSTEM::QueryFileSystemName(&ntdrive, &FsName, &Status)) {
  118. if( Status == STATUS_ACCESS_DENIED ) {
  119. Message.Set( MSG_DASD_ACCESS_DENIED );
  120. Message.Display( "" );
  121. } else {
  122. Message.Set( MSG_FS_NOT_DETERMINED );
  123. Message.Display( "%W", dosdrive );
  124. }
  125. DELETE(dosdrive);
  126. DELETE(CanonicalPath);
  127. return 1;
  128. }
  129. Message.Set(MSG_FILE_SYSTEM_TYPE);
  130. Message.Display("%W", &FsName);
  131. if (!LibraryName.Initialize("U") ||
  132. !LibraryName.Strcat(&FsName) ||
  133. !RecoverString.Initialize("Recover")) {
  134. Message.Set(MSG_FMT_NO_MEMORY);
  135. Message.Display("");
  136. DELETE(dosdrive);
  137. DELETE(CanonicalPath);
  138. return(1);
  139. }
  140. if ((Recover = (RECOVER_FN)SYSTEM::QueryLibraryEntryPoint(&LibraryName,
  141. &RecoverString,
  142. &FsUtilityHandle))
  143. != NULL) {
  144. Recover(CanonicalPath, &Message);
  145. SYSTEM::FreeLibraryHandle(FsUtilityHandle);
  146. } else {
  147. Message.Set(MSG_FS_NOT_SUPPORTED);
  148. Message.Display("%s%W", "RECOVER", &FsName);
  149. Message.Set(MSG_BLANK_LINE);
  150. Message.Display("");
  151. DELETE(dosdrive);
  152. DELETE(CanonicalPath);
  153. return(1);
  154. }
  155. DELETE(dosdrive);
  156. DELETE(CanonicalPath);
  157. return(0);
  158. }