/* nthibr.c - tests whether an MS Windows system partition is hibernated */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2007,2008,2009,2011 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ //======== INCLUDES ==========================================================// //Common Utilities #include //NULL #include //grub_*size_t #include //grub_disk_t, grub_disk_*() #include //grub_file_t, grub_file_*() #include //grub_str*(), grub_*puts(), grub_*printf() //Module Management #include //GRUB_MOD_*() #include //grub_extcmd_*t, grub_*register_extcmd() #include //grub_arg_*, ARG_TYPE_* #include //grub_err_t, GRUB_ERR_*, grub_error() //Internationalization #include //N_() //======== PRAGMAS ===========================================================// //permit use of the zero-initializer '{0}' for structures #pragma GCC diagnostic ignored "-Wmissing-field-initializers" //======== TYPE DEFINITIONS ==================================================// typedef struct grub_arg_option grub_arg_option; //======== MODULE VARIABLES ==================================================// GRUB_MOD_LICENSE("GPLv3+"); static grub_extcmd_t cmd; static const grub_arg_option options[] = { { .longarg = "exit-codes", .shortarg = 'x', .flags = 0x0, .doc = N_("Display return codes used by this command and exit."), .arg = NULL, .type = ARG_TYPE_NONE }, {0} //end of list }; //======== FUNCTIONS =========================================================// static grub_err_t grub_cmd_nthibr ( grub_extcmd_context_t ctxt, int argc, char* args[] ){ grub_err_t status = GRUB_ERR_NONE; char *szPartName, szFilePath[32], szFileMagic[5] = {'\0'}; grub_ssize_t length; grub_disk_t hPart; grub_file_t hFile = NULL; #define ABORT(_code, _message) { \ status = grub_error((_code), (_message)); \ goto exit; \ } //If requested, print return codes and exit; else, proceed if (ctxt->state[0].set) { grub_printf( N_( "CODE MEANING\n" "---- -------\n" " %2d system hibernated\n" " %2d system not hibernated\n" " %2d hibernation file too small\n" " %2d hibernation file not found\n" " %2d partition not found\n" " %2d invalid partition specifier\n" " %2d too few/many arguments provided\n" ), GRUB_ERR_NONE, GRUB_ERR_TEST_FAILURE, GRUB_ERR_BAD_FILE_TYPE, GRUB_ERR_FILE_NOT_FOUND, GRUB_ERR_BAD_FILENAME, GRUB_ERR_UNKNOWN_DEVICE, GRUB_ERR_BAD_ARGUMENT ); goto exit; } //Check argument count if (!argc) { ABORT( GRUB_ERR_BAD_ARGUMENT, N_("too few arguments specified") ); } else if (argc > 1) { ABORT( GRUB_ERR_BAD_ARGUMENT, N_("too many arguments specified") ); } szPartName = args[0]; length = (grub_ssize_t) grub_strlen(szPartName); //Check if partition specifier 'looks right' if (szPartName[0] != '(' || szPartName[length-1] != ')') ABORT( GRUB_ERR_BAD_FILENAME, N_("invalid partition specifier") ); //Check if partition actually exists szPartName[length-1] = '\0'; if (NULL == (hPart = grub_disk_open(szPartName+1))) { ABORT( GRUB_ERR_UNKNOWN_DEVICE, N_("partition not found") ); } else { grub_disk_close(hPart); szPartName[length-1] = ')'; } //Build path to 'hiberfil.sys' grub_strncpy(szFilePath, szPartName, sizeof(szFilePath) - 1); grub_strncat ( szFilePath, "/hiberfil.sys", sizeof(szFilePath) - grub_strlen(szFilePath) - 1 ); //Try to open 'hiberfil.sys' if (NULL == (hFile = grub_file_open(szFilePath))) { ABORT( GRUB_ERR_FILE_NOT_FOUND, N_("'hiberfil.sys' not found") ); } //Try to read magic number of 'hiberfil.sys' length = (grub_ssize_t) (sizeof(szFileMagic) - 1); if (grub_file_read(hFile, szFileMagic, length) < length) ABORT( GRUB_ERR_BAD_FILE_TYPE, N_("'hiberfil.sys' too small") ); //Return SUCCESS if magic indicates file is active; else return FAILURE if (0 == grub_strncasecmp("hibr", szFileMagic, length)) { grub_puts(N_("The system is hibernated.")); } else { grub_puts(N_("The system is NOT hibernated.")); status = GRUB_ERR_TEST_FAILURE; } exit: //Ensure 'hiberfil.sys' is closed if (hFile) grub_file_close(hFile); #undef ABORT return status; } //grub_cmd_nthibr() GRUB_MOD_INIT(nthibr) { cmd = grub_register_extcmd ( "nthibr", //name grub_cmd_nthibr, //function 0x0, //flags = NONE N_("DEVICE"), //summary = NONE N_("Test whether an NT system partition is hibernated."), //description options //switches ); } //GRUB_MOD_INIT() GRUB_MOD_FINI(nthibr) { grub_unregister_extcmd(cmd); } //GRUB_MOD_FINI()