1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS shutdown/logoff utility 4 * FILE: base/applications/shutdown/misc.c 5 * PURPOSE: Misc. functions used for the shutdown utility 6 * PROGRAMMERS: Lee Schroeder 7 */ 8 9 #include "precomp.h" 10 11 #include <stdio.h> 12 13 const DWORD defaultReason = SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER; 14 15 REASON shutdownReason[] = 16 { 17 {L"U" , 0, 0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER}, /* Other (Unplanned) */ 18 {L"E" , 0, 0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER}, /* Other (Unplanned) */ 19 {L"EP", 0, 0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED}, /* Other (Planned) */ 20 {L"U" , 0, 5, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_HUNG}, /* Other Failure: System Unresponsive */ 21 {L"E" , 1, 1, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_MAINTENANCE}, /* Hardware: Maintenance (Unplanned) */ 22 {L"EP", 1, 1, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED}, /* Hardware: Maintenance (Planned) */ 23 {L"E" , 1, 2, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_INSTALLATION}, /* Hardware: Installation (Unplanned) */ 24 {L"EP", 1, 2, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED}, /* Hardware: Installation (Planned) */ 25 {L"P" , 2, 3, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Upgrade (Planned) */ 26 {L"E" , 2, 4, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG}, /* Operating System: Reconfiguration (Unplanned) */ 27 {L"EP", 2, 4, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Reconfiguration (Planned) */ 28 {L"P" , 2, 16, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Service pack (Planned) */ 29 {L"U" , 2, 17, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_HOTFIX}, /* Operating System: Hotfix (Unplanned) */ 30 {L"P" , 2, 17, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_HOTFIX | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Hotfix (Planned) */ 31 {L"U" , 2, 18, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX}, /* Operating System: Security fix (Unplanned) */ 32 {L"P" , 2, 18, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Security fix (Planned) */ 33 {L"E" , 4, 1, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE}, /* Application: Maintenance (Unplanned) */ 34 {L"EP", 4, 1, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED}, /* Application: Maintenance (Planned) */ 35 {L"EP", 4, 2, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED}, /* Application: Installation (Planned) */ 36 {L"E" , 4, 5, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_HUNG}, /* Application: Unresponsive */ 37 {L"E" , 4, 6, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_UNSTABLE}, /* Application: Unstable */ 38 {L"U" , 5, 15, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_BLUESCREEN}, /* System Failure: Stop Error */ 39 {L"E" , 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY}, /* Security Issue */ 40 {L"U" , 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY}, /* Security Issue */ 41 {L"EP", 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY | SHTDN_REASON_FLAG_PLANNED}, /* Security Issue (Planned) */ 42 {L"E" , 5, 20, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY}, /* Loss of Network Connectivity (Unplanned) */ 43 {L"U" , 6, 11, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_CORDUNPLUGGED}, /* Power Failure: Cord Unplugged */ 44 {L"U" , 6, 12, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_ENVIRONMENT}, /* Power Failure: Environment */ 45 {L"P" , 7, 0, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_ENVIRONMENT} /* Legacy API shutdown (Planned) */ 46 }; 47 48 /* 49 * This command helps to work around the fact that the shutdown utility has 50 * different upper limits for the comment flag since each version of Windows 51 * seems to have different upper limits. 52 */ 53 BOOL CheckCommentLength(LPCWSTR comment) 54 { 55 DWORD finalLength = 0; 56 size_t strLength = 0; 57 DWORD osVersion = 0; 58 DWORD osMajorVersion = 0; 59 DWORD osMinorVersion = 0; 60 61 /* An empty string is always valid. */ 62 if (!comment || *comment == 0) 63 return TRUE; 64 65 /* Grab the version of the current Operating System. */ 66 osVersion = GetVersion(); 67 68 osMajorVersion = (DWORD)(LOBYTE(LOWORD(osVersion))); 69 osMinorVersion = (DWORD)(HIBYTE(LOWORD(osVersion))); 70 71 /* 72 * Check to make sure that the proper length is being used 73 * based upon the version of Windows currently being used. 74 */ 75 if (osMajorVersion == 5) /* Windows XP/2003 */ 76 { 77 if ((osMinorVersion == 1) || (osMinorVersion == 2)) 78 { 79 finalLength = 127; 80 } 81 } 82 else if (osMajorVersion == 6) /* Windows Vista/7/2008 */ 83 { 84 if ((osMinorVersion == 0) || (osMinorVersion == 1)) 85 { 86 finalLength = 512; 87 } 88 } 89 90 /* Grab the length of the comment string. */ 91 strLength = wcslen(comment); 92 93 /* 94 * Compare the size of the string to make sure 95 * it fits with the current version of Windows, 96 * and return TRUE or FALSE accordingly. 97 */ 98 return (strLength <= finalLength); 99 } 100 101 /* 102 * This function parses the reason code to a usable format that will specify 103 * why the user wants to shut the computer down. Although this is used for 104 * both client and server environments, use of a reason code is more important 105 * in a server environment since servers are supposed to be on all the time 106 * for easier access. 107 */ 108 DWORD ParseReasonCode(LPCWSTR code) 109 { 110 PREASON reasonptr; 111 int majorCode = 0; 112 int minorCode = 0; 113 LPWSTR tmpPrefix = NULL; 114 size_t codeSize; 115 116 /* If no reason code is specified, use "Other (Unplanned)" as the default option */ 117 if(code == NULL) 118 { 119 return defaultReason; 120 } 121 else 122 { 123 /* Store the size of the code so we can use it later */ 124 codeSize = (size_t)wcslen(code); 125 126 /* A colon cannot be the first or last character in the reason code */ 127 if ((code[0] == L':') || (code[codeSize] == L':')) 128 { 129 return defaultReason; 130 } 131 132 /* The minimum length that a reason code can be is 5-7 characters in length */ 133 if ((codeSize < 5) || (codeSize > 7)) 134 { 135 return defaultReason; 136 } 137 138 /* TODO: Add code for reason parsing here. */ 139 140 /* Make sure that the major and minor codes are within size limits */ 141 if ((majorCode > 7 ) || (majorCode < 0) || 142 (minorCode > 20) || (minorCode < 0)) 143 { 144 return defaultReason; 145 } 146 147 /* Figure out what flags to return */ 148 for (reasonptr = shutdownReason ; reasonptr->prefix ; reasonptr++) 149 { 150 if ((majorCode == reasonptr->major) && 151 (minorCode == reasonptr->minor) && 152 (_wcsicmp(tmpPrefix, reasonptr->prefix) != 0)) 153 { 154 return reasonptr->flag; 155 } 156 } 157 } 158 159 return defaultReason; 160 } 161 162 /* Writes the last error as both text and error code to the console */ 163 VOID DisplayError(DWORD dwError) 164 { 165 ConMsgPuts(StdErr, FORMAT_MESSAGE_FROM_SYSTEM, 166 NULL, dwError, LANG_USER_DEFAULT); 167 ConPrintf(StdErr, L"Error code: %lu\n", dwError); 168 } 169 170 /* EOF */ 171