xref: /reactos/base/applications/shutdown/misc.c (revision f34a30fe)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3*c2c66affSColin Finck  * PROJECT:         ReactOS shutdown/logoff utility
4*c2c66affSColin Finck  * FILE:            base/applications/shutdown/misc.c
5*c2c66affSColin Finck  * PURPOSE:         Misc. functions used for the shutdown utility
6*c2c66affSColin Finck  * PROGRAMMERS:     Lee Schroeder
7*c2c66affSColin Finck  */
8*c2c66affSColin Finck 
9*c2c66affSColin Finck #include "precomp.h"
10*c2c66affSColin Finck 
11*c2c66affSColin Finck #include <stdio.h>
12*c2c66affSColin Finck 
13*c2c66affSColin Finck const DWORD defaultReason = SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER;
14*c2c66affSColin Finck 
15*c2c66affSColin Finck REASON shutdownReason[] =
16*c2c66affSColin Finck {
17*c2c66affSColin Finck     {L"U" , 0,  0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER},                                             /* Other (Unplanned) */
18*c2c66affSColin Finck     {L"E" , 0,  0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER},                                             /* Other (Unplanned) */
19*c2c66affSColin Finck     {L"EP", 0,  0, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED},                 /* Other (Planned) */
20*c2c66affSColin Finck     {L"U" , 0,  5, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_HUNG},                                              /* Other Failure: System Unresponsive */
21*c2c66affSColin Finck     {L"E" , 1,  1, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_MAINTENANCE},                                    /* Hardware: Maintenance (Unplanned) */
22*c2c66affSColin Finck     {L"EP", 1,  1, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED},        /* Hardware: Maintenance (Planned) */
23*c2c66affSColin Finck     {L"E" , 1,  2, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_INSTALLATION},                                   /* Hardware: Installation (Unplanned) */
24*c2c66affSColin Finck     {L"EP", 1,  2, SHTDN_REASON_MAJOR_HARDWARE | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED},       /* Hardware: Installation (Planned) */
25*c2c66affSColin Finck     {L"P" , 2,  3, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE | SHTDN_REASON_FLAG_PLANNED},     /* Operating System: Upgrade (Planned) */
26*c2c66affSColin Finck     {L"E" , 2,  4, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG},                                /* Operating System: Reconfiguration (Unplanned) */
27*c2c66affSColin Finck     {L"EP", 2,  4, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED},    /* Operating System: Reconfiguration (Planned) */
28*c2c66affSColin Finck     {L"P" , 2, 16, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_RECONFIG | SHTDN_REASON_FLAG_PLANNED},    /* Operating System: Service pack (Planned) */
29*c2c66affSColin Finck     {L"U" , 2, 17, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_HOTFIX},                                  /* Operating System: Hotfix (Unplanned) */
30*c2c66affSColin Finck     {L"P" , 2, 17, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_HOTFIX | SHTDN_REASON_FLAG_PLANNED},      /* Operating System: Hotfix (Planned) */
31*c2c66affSColin Finck     {L"U" , 2, 18, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX},                             /* Operating System: Security fix (Unplanned) */
32*c2c66affSColin Finck     {L"P" , 2, 18, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_SECURITYFIX | SHTDN_REASON_FLAG_PLANNED}, /* Operating System: Security fix (Planned) */
33*c2c66affSColin Finck     {L"E" , 4,  1, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE},                                 /* Application: Maintenance (Unplanned) */
34*c2c66affSColin Finck     {L"EP", 4,  1, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE | SHTDN_REASON_FLAG_PLANNED},     /* Application: Maintenance (Planned) */
35*c2c66affSColin Finck     {L"EP", 4,  2, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_INSTALLATION | SHTDN_REASON_FLAG_PLANNED},    /* Application: Installation (Planned) */
36*c2c66affSColin Finck     {L"E" , 4,  5, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_HUNG},                                        /* Application: Unresponsive */
37*c2c66affSColin Finck     {L"E" , 4,  6, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_UNSTABLE},                                    /* Application: Unstable */
38*c2c66affSColin Finck     {L"U" , 5, 15, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_BLUESCREEN},                                       /* System Failure: Stop Error */
39*c2c66affSColin Finck     {L"E" , 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY},                                         /* Security Issue */
40*c2c66affSColin Finck     {L"U" , 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY},                                         /* Security Issue */
41*c2c66affSColin Finck     {L"EP", 5, 19, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_SECURITY | SHTDN_REASON_FLAG_PLANNED},             /* Security Issue (Planned) */
42*c2c66affSColin Finck     {L"E" , 5, 20, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY},                             /* Loss of Network Connectivity (Unplanned) */
43*c2c66affSColin Finck     {L"U" , 6, 11, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_CORDUNPLUGGED},                                     /* Power Failure: Cord Unplugged */
44*c2c66affSColin Finck     {L"U" , 6, 12, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_ENVIRONMENT},                                       /* Power Failure: Environment */
45*c2c66affSColin Finck     {L"P" , 7,  0, SHTDN_REASON_MAJOR_POWER | SHTDN_REASON_MINOR_ENVIRONMENT}                                        /* Legacy API shutdown (Planned) */
46*c2c66affSColin Finck };
47*c2c66affSColin Finck 
48*c2c66affSColin Finck /*
49*c2c66affSColin Finck  * This function parses the reason code to a usable format that will specify
50*c2c66affSColin Finck  * why the user wants to shut the computer down. Although this is used for
51*c2c66affSColin Finck  * both client and server environments, use of a reason code is more important
52*c2c66affSColin Finck  * in a server environment since servers are supposed to be on all the time
53*c2c66affSColin Finck  * for easier access.
54*c2c66affSColin Finck  */
ParseReasonCode(LPCWSTR code)55*c2c66affSColin Finck DWORD ParseReasonCode(LPCWSTR code)
56*c2c66affSColin Finck {
57*c2c66affSColin Finck     PREASON reasonptr;
58*c2c66affSColin Finck     int majorCode = 0;
59*c2c66affSColin Finck     int minorCode = 0;
60*c2c66affSColin Finck     LPWSTR tmpPrefix = NULL;
61*c2c66affSColin Finck     size_t codeSize;
62*c2c66affSColin Finck 
63*c2c66affSColin Finck     /* If no reason code is specified, use "Other (Unplanned)" as the default option */
64*c2c66affSColin Finck     if(code == NULL)
65*c2c66affSColin Finck     {
66*c2c66affSColin Finck         return defaultReason;
67*c2c66affSColin Finck     }
68*c2c66affSColin Finck     else
69*c2c66affSColin Finck     {
70*c2c66affSColin Finck         /* Store the size of the code so we can use it later */
71*c2c66affSColin Finck         codeSize = (size_t)wcslen(code);
72*c2c66affSColin Finck 
73*c2c66affSColin Finck         /* A colon cannot be the first or last character in the reason code */
74*c2c66affSColin Finck         if ((code[0] == L':') || (code[codeSize] == L':'))
75*c2c66affSColin Finck         {
76*c2c66affSColin Finck             return defaultReason;
77*c2c66affSColin Finck         }
78*c2c66affSColin Finck 
79*c2c66affSColin Finck         /* The minimum length that a reason code can be is 5-7 characters in length */
80*c2c66affSColin Finck         if ((codeSize < 5) || (codeSize > 7))
81*c2c66affSColin Finck         {
82*c2c66affSColin Finck             return defaultReason;
83*c2c66affSColin Finck         }
84*c2c66affSColin Finck 
85*c2c66affSColin Finck         /* TODO: Add code for reason parsing here. */
86*c2c66affSColin Finck 
87*c2c66affSColin Finck         /* Make sure that the major and minor codes are within size limits */
88*c2c66affSColin Finck         if ((majorCode > 7 ) || (majorCode < 0) ||
89*c2c66affSColin Finck             (minorCode > 20) || (minorCode < 0))
90*c2c66affSColin Finck         {
91*c2c66affSColin Finck             return defaultReason;
92*c2c66affSColin Finck         }
93*c2c66affSColin Finck 
94*c2c66affSColin Finck         /* Figure out what flags to return */
95*c2c66affSColin Finck         for (reasonptr = shutdownReason ; reasonptr->prefix ; reasonptr++)
96*c2c66affSColin Finck         {
97*c2c66affSColin Finck             if ((majorCode == reasonptr->major) &&
98*c2c66affSColin Finck                 (minorCode == reasonptr->minor) &&
99*c2c66affSColin Finck                 (_wcsicmp(tmpPrefix, reasonptr->prefix) != 0))
100*c2c66affSColin Finck             {
101*c2c66affSColin Finck                 return reasonptr->flag;
102*c2c66affSColin Finck             }
103*c2c66affSColin Finck         }
104*c2c66affSColin Finck     }
105*c2c66affSColin Finck 
106*c2c66affSColin Finck     return defaultReason;
107*c2c66affSColin Finck }
108*c2c66affSColin Finck 
109*c2c66affSColin Finck /* Writes the last error as both text and error code to the console */
DisplayError(DWORD dwError)110*c2c66affSColin Finck VOID DisplayError(DWORD dwError)
111*c2c66affSColin Finck {
112*c2c66affSColin Finck     ConMsgPuts(StdErr, FORMAT_MESSAGE_FROM_SYSTEM,
113*c2c66affSColin Finck                NULL, dwError, LANG_USER_DEFAULT);
114*c2c66affSColin Finck     ConPrintf(StdErr, L"Error code: %lu\n", dwError);
115*c2c66affSColin Finck }
116*c2c66affSColin Finck 
117*c2c66affSColin Finck /* EOF */
118