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.

470 lines
11 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. cdp.c
  5. Abstract:
  6. A user mode app that allows simple commands to be sent to a
  7. selected scsi device.
  8. Environment:
  9. User mode only
  10. Revision History:
  11. 03-26-96 : Created
  12. --*/
  13. //
  14. // this module may be compiled at warning level 4 with the following
  15. // warnings disabled:
  16. //
  17. #pragma warning(disable:4200) // array[0]
  18. #pragma warning(disable:4201) // nameless struct/unions
  19. #pragma warning(disable:4214) // bit fields other than int
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <assert.h>
  27. #include <windows.h>
  28. // #include "bootstatus.h"
  29. #ifdef DBG
  30. #define dbg(x) x
  31. #define HELP_ME() printf("Reached line %4d\n", __LINE__);
  32. #else
  33. #define dbg(x) /* x */
  34. #define HELP_ME() /* printf("Reached line %4d\n", __LINE__); */
  35. #endif
  36. #define ARGUMENT_USED(x) (x == NULL)
  37. //
  38. // The default size of the safemode.dat file - it must be large enough that the
  39. // data stream isn't a resident attribute of the metadata or the loader's
  40. // NTFS implementation can't write to it.
  41. //
  42. #define DEFAULT_SAFEMODE_FILE_SIZE 0x800
  43. typedef struct {
  44. PCHAR Name;
  45. PCHAR Description;
  46. BOOLEAN LockData;
  47. ULONG (*Function)(HANDLE BootStatusData, int argc, char *argv[]);
  48. } COMMAND;
  49. DWORD TestCommand(HANDLE BootStatusData, int argc, char *argv[]);
  50. DWORD Disable(HANDLE BootStatusData, int argc, char *argv[]);
  51. DWORD Enable(HANDLE BootStatusData, int argc, char *argv[]);
  52. DWORD Create(HANDLE BootStatusData, int argc, char *argv[]);
  53. DWORD SetFlags(HANDLE BootStatusData, int argc, char *argv[]);
  54. DWORD ClearFlags(HANDLE BootStatusData, int argc, char *argv[]);
  55. DWORD ListSettings(HANDLE BootStatusData, int argc, char *argv[]);
  56. DWORD ListCommand(int argc, char *argv[]);
  57. //
  58. // List of commands
  59. // all command names are case sensitive
  60. // arguments are passed into command routines
  61. // list must be terminated with NULL command
  62. // command will not be listed in help if description == NULL
  63. //
  64. COMMAND CommandArray[] = {
  65. {"create", "Creates the boot status data file", FALSE, Create},
  66. {"disable", "Disables Auto Advanced Boot", TRUE, Disable},
  67. {"enable", "Enables Auto Advanced Boot", TRUE, Enable},
  68. {"set", "Sets the boot status flags", TRUE, SetFlags},
  69. {"settings","Lists the Auto Advanced Boot settings", TRUE, ListSettings},
  70. {NULL, NULL, FALSE, NULL}
  71. };
  72. int __cdecl main(int argc, char *argv[])
  73. {
  74. int i = 0;
  75. HANDLE bootStatusData;
  76. if(argc < 2) {
  77. printf("Usage: %s <command> [parameters]\n", argv[0]);
  78. printf("possible commands: \n");
  79. ListCommand(argc, argv);
  80. printf("\n");
  81. return -1;
  82. }
  83. //
  84. // Iterate through the command array and find the correct function to
  85. // call.
  86. //
  87. while(CommandArray[i].Name != NULL) {
  88. if(strcmp(argv[1], CommandArray[i].Name) == 0) {
  89. NTSTATUS status;
  90. if(CommandArray[i].LockData) {
  91. status = RtlLockBootStatusData(&bootStatusData);
  92. if(!NT_SUCCESS(status)) {
  93. printf("Error %#08lx opening boot status bootStatusData\n",
  94. status);
  95. return -1;
  96. }
  97. } else {
  98. bootStatusData = NULL;
  99. }
  100. (CommandArray[i].Function)(bootStatusData, (argc - 1), &(argv[1]));
  101. break;
  102. }
  103. i++;
  104. }
  105. if(CommandArray[i].Name == NULL) {
  106. printf("Unknown command %s\n", argv[1]);
  107. }
  108. RtlUnlockBootStatusData(bootStatusData);
  109. return 0;
  110. }
  111. DWORD TestCommand(HANDLE BootStatusData, int argc, char *argv[])
  112. /*++
  113. Routine Description:
  114. Tests the command "parsing"
  115. Arguments:
  116. device - a file handle to send the ioctl to
  117. argc - the number of additional arguments. should be zero
  118. argv - the additional arguments
  119. Return Value:
  120. STATUS_SUCCESS if successful
  121. The value of GetLastError() from the point of failure
  122. --*/
  123. {
  124. int i;
  125. UNREFERENCED_PARAMETER(BootStatusData);
  126. printf("Test - %d additional arguments\n", argc);
  127. for(i = 0; i < argc; i++) {
  128. printf("arg %d: %s\n", i, argv[i]);
  129. }
  130. return STATUS_SUCCESS;
  131. }
  132. DWORD ListCommand(int argc, char *argv[])
  133. /*++
  134. Routine Description:
  135. Prints out the command list
  136. Arguments:
  137. device - unused
  138. argc - unused
  139. argv - unused
  140. Return Value:
  141. STATUS_SUCCESS
  142. --*/
  143. {
  144. int i = 0;
  145. UNREFERENCED_PARAMETER(argc);
  146. UNREFERENCED_PARAMETER(argv);
  147. while(CommandArray[i].Name != NULL) {
  148. if(CommandArray[i].Description != NULL) {
  149. printf("\t%s - %s\n",
  150. CommandArray[i].Name,
  151. CommandArray[i].Description);
  152. }
  153. i++;
  154. }
  155. return STATUS_SUCCESS;
  156. }
  157. DWORD
  158. Create(
  159. HANDLE Unused,
  160. int argc,
  161. char *argv[]
  162. )
  163. {
  164. BOOLEAN enabled;
  165. NTSTATUS status;
  166. status = RtlCreateBootStatusDataFile();
  167. if(!NT_SUCCESS(status)) {
  168. printf("Error %#08lx creating boot status data\n", status);
  169. }
  170. return status;
  171. }
  172. DWORD
  173. Enable(
  174. HANDLE BootStatusData,
  175. int argc,
  176. char *argv[]
  177. )
  178. {
  179. BOOLEAN enabled;
  180. NTSTATUS status;
  181. status = RtlGetSetBootStatusData(BootStatusData,
  182. TRUE,
  183. RtlBsdItemAabEnabled,
  184. &enabled,
  185. sizeof(BOOLEAN),
  186. NULL);
  187. if(!NT_SUCCESS(status)) {
  188. printf("Error %#08lx reading boot status data\n", status);
  189. return status;
  190. }
  191. printf("Enabling Automatic Advanced Boot\n");
  192. printf("Previous setting was %s\n", enabled ? "enabled" : "disabled");
  193. enabled = TRUE;
  194. status = RtlGetSetBootStatusData(BootStatusData,
  195. FALSE,
  196. RtlBsdItemAabEnabled,
  197. &enabled,
  198. sizeof(BOOLEAN),
  199. NULL);
  200. if(!NT_SUCCESS(status)) {
  201. printf("Error %#08lx writing boot status data\n", status);
  202. }
  203. return status;
  204. }
  205. DWORD
  206. Disable(
  207. HANDLE BootStatusData,
  208. int argc,
  209. char *argv[]
  210. )
  211. {
  212. BOOLEAN enabled;
  213. NTSTATUS status;
  214. status = RtlGetSetBootStatusData(BootStatusData,
  215. TRUE,
  216. RtlBsdItemAabEnabled,
  217. &enabled,
  218. sizeof(BOOLEAN),
  219. NULL);
  220. if(!NT_SUCCESS(status)) {
  221. printf("Error %#08lx reading boot status data\n", status);
  222. return status;
  223. }
  224. printf("Disabling Automatic Advanced Boot\n");
  225. printf("Previous setting was %s\n", enabled ? "enabled" : "disabled");
  226. enabled = FALSE;
  227. status = RtlGetSetBootStatusData(BootStatusData,
  228. FALSE,
  229. RtlBsdItemAabEnabled,
  230. &enabled,
  231. sizeof(BOOLEAN),
  232. NULL);
  233. if(!NT_SUCCESS(status)) {
  234. printf("Error %#08lx writing boot status data\n", status);
  235. }
  236. return status;
  237. }
  238. DWORD
  239. ListSettings(
  240. HANDLE BootStatusData,
  241. int argc,
  242. char *argv[]
  243. )
  244. {
  245. BOOLEAN flag;
  246. NTSTATUS status;
  247. status = RtlGetSetBootStatusData(BootStatusData,
  248. TRUE,
  249. RtlBsdItemAabEnabled,
  250. &flag,
  251. sizeof(BOOLEAN),
  252. NULL);
  253. if(!NT_SUCCESS(status)) {
  254. printf("Error %#08lx reading boot status data\n", status);
  255. return status;
  256. }
  257. printf("Automatic Advanced Boot is %s\n", flag ? "enabled" : "disabled");
  258. status = RtlGetSetBootStatusData(BootStatusData,
  259. TRUE,
  260. RtlBsdItemAabTimeout,
  261. &flag,
  262. sizeof(BOOLEAN),
  263. NULL);
  264. if(!NT_SUCCESS(status)) {
  265. printf("Error %#08lx reading boot status data\n", status);
  266. return status;
  267. }
  268. printf("Automatic Advanced Boot timeout is %d seconds\n", (UCHAR) flag);
  269. status = RtlGetSetBootStatusData(BootStatusData,
  270. TRUE,
  271. RtlBsdItemBootGood,
  272. &flag,
  273. sizeof(BOOLEAN),
  274. NULL);
  275. if(!NT_SUCCESS(status)) {
  276. printf("Error %#08lx reading boot status data\n", status);
  277. return status;
  278. }
  279. printf("LastBootSucceeded = %#x\n", flag);
  280. status = RtlGetSetBootStatusData(BootStatusData,
  281. TRUE,
  282. RtlBsdItemBootShutdown,
  283. &flag,
  284. sizeof(BOOLEAN),
  285. NULL);
  286. if(!NT_SUCCESS(status)) {
  287. printf("Error %#08lx reading boot status data\n", status);
  288. return status;
  289. }
  290. printf("LastBootShutdown = %#x\n", flag);
  291. return STATUS_SUCCESS;
  292. }
  293. DWORD SetFlags(HANDLE BootStatusData, int argc, char *argv[])
  294. {
  295. int count;
  296. if(argc <= 1) {
  297. printf("usage: autosafeboot set <Boot|Shutdown>=<value> ...");
  298. return 0;
  299. }
  300. for(count = 1; count < argc; count++) {
  301. PUCHAR nameString;
  302. PUCHAR valueString;
  303. ULONG index;
  304. UCHAR value;
  305. index = -1;
  306. //
  307. // match the string.
  308. //
  309. nameString = argv[count];
  310. valueString = strrchr(nameString, '=');
  311. if(valueString == NULL) {
  312. printf("** element \"%s\" not understood\n", nameString);
  313. continue;
  314. }
  315. valueString[0] = '\0';
  316. valueString += 1;
  317. value = (UCHAR) atoi(valueString);
  318. if(_stricmp(nameString, "boot") == 0) {
  319. printf("Setting LastBootSucceeded to %#x\n", value);
  320. index = RtlBsdItemBootGood;
  321. } else if(_stricmp(nameString, "shutdown") == 0) {
  322. printf("Setting LastBootShutdown to %#x\n", value);
  323. index = RtlBsdItemBootShutdown;
  324. }
  325. if(index != -1) {
  326. NTSTATUS status;
  327. status = RtlGetSetBootStatusData(BootStatusData,
  328. FALSE,
  329. index,
  330. &value,
  331. sizeof(UCHAR),
  332. NULL);
  333. if(!NT_SUCCESS(status)) {
  334. printf("Error %#08lx reading boot status data\n", status);
  335. continue;
  336. }
  337. } else {
  338. printf("** element \"%s=%s\" not understood\n", nameString, valueString);
  339. }
  340. }
  341. return 0;
  342. }