📄 sm.c
字号:
/*
* ReactOS Win32 Applications
* Copyright (C) 2005 ReactOS Team
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS/Win32 Session Manager Control Tool
* FILE : subsys/system/sm/sm.c
* PROGRAMMER: Emanuele Aliberti (ea@reactos.com)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include "resource.h"
#define WIN32_NO_STATUS
#include <windows.h>
#include <lpctypes.h>
#include <lpcfuncs.h>
#include <rtlfuncs.h>
#include <sm/helper.h>
VOID PrintWin32Error(PWCHAR,DWORD); /* win32err.c */
#define SM_CMD(n) cmd_##n
#define SM_CMD_DECL(n) int SM_CMD(n)(int argc, char * argv[])
#define SM_CMD_CALL(n,c,v) SM_CMD(n)((c),(v))
HANDLE hSmApiPort = (HANDLE) 0;
VOID STDCALL PrintStatusError (NTSTATUS Status)
{
DWORD Win32Error = RtlNtStatusToDosError (Status);
PrintWin32Error (L"sm", Win32Error);
}
typedef struct _SM_CMD_DESCRIPTOR
{
TCHAR Name[RC_STRING_MAX_SIZE];
int (*EntryPoint)(int,TCHAR**);
TCHAR Synopsis[RC_STRING_MAX_SIZE];
TCHAR Description[RC_STRING_MAX_SIZE];
} SM_CMD_DESCRIPTOR, *PSM_CMD_DESCRIPTOR;
SM_CMD_DECL(boot);
SM_CMD_DECL(help);
SM_CMD_DECL(info);
SM_CMD_DECL(reboot);
SM_CMD_DECL(shutdown);
/* internal commands directory */
SM_CMD_DESCRIPTOR Command [] =
{
{"boot", SM_CMD(boot), _T("boot subsystem_name"), _T("bootstrap an optional environment subsystem;")},
{"help", SM_CMD(help), _T("help [command]"), _T("print help for command;")},
{"info", SM_CMD(info), _T("info [subsystem_id]"), _T("print information about a booted subsystem\n"
"if subsystem_id is omitted, a list of booted\n"
"environment subsystems is printed.")},
{"reboot", SM_CMD(reboot), _T("reboot subsystem_id"), _T("reboot an optional environment subsystem;")},
{"shutdown", SM_CMD(shutdown), _T("shutdown subsystem_id"), _T("shutdown an optional environment subsystem;")},
};
TCHAR UsageMessage[RC_STRING_MAX_SIZE];
void loadlang(PSM_CMD_DESCRIPTOR );
PSM_CMD_DESCRIPTOR LookupCommand (const TCHAR * CommandName)
{
int i;
const int command_count = (sizeof Command / sizeof Command[0]);
/* parse the command... */
for (i=0; (i < command_count); i ++)
{
if (0 == _tcscmp(CommandName, Command[i].Name))
{
break;
}
}
if (i == command_count)
{
LoadString( GetModuleHandle(NULL), IDS_Unknown, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_ftprintf(stderr, UsageMessage, CommandName);
return NULL;
}
return & Command [i];
}
/* user commands */
SM_CMD_DECL(boot)
{
int rc = EXIT_SUCCESS;
ANSI_STRING ProgramA;
UNICODE_STRING ProgramW;
NTSTATUS Status = STATUS_SUCCESS;
if (3 == argc)
{
#ifndef _UNICODE
RtlInitAnsiString (& ProgramA, argv[2]);
RtlAnsiStringToUnicodeString (& ProgramW, & ProgramA, TRUE);
Status = SmExecuteProgram (hSmApiPort, & ProgramW);
RtlFreeUnicodeString (& ProgramW);
#else
ProgramW = &argv[2];
Status = SmExecuteProgram (hSmApiPort, & ProgramW);
#endif
if (STATUS_SUCCESS != Status)
{
PrintStatusError (Status);
}
}
else
{
argv[2]=_T("boot");
return SM_CMD_CALL(help,3,argv);
}
return rc;
}
SM_CMD_DECL(help)
{
unsigned int i = 0;
PSM_CMD_DESCRIPTOR cmd = NULL;
int rc = EXIT_SUCCESS;
switch (argc)
{
case 2:
for (i=0; (i < (sizeof Command / sizeof Command[0])); i ++)
{
_tprintf(_T("%s\n"), Command[i].Synopsis);
}
break;
case 3:
cmd = LookupCommand (argv[2]);
if (NULL == cmd)
{
rc = EXIT_FAILURE;
break;
}
_tprintf(_T("%s\n%s\n\n%s\n"),
cmd->Name,
cmd->Synopsis,
cmd->Description);
break;
}
return rc;
}
SM_CMD_DECL(info)
{
int rc = EXIT_SUCCESS;
NTSTATUS Status = STATUS_SUCCESS;
SM_INFORMATION_CLASS InformationClass = SmBasicInformation;
union {
SM_BASIC_INFORMATION bi;
SM_SUBSYSTEM_INFORMATION ssi;
} Info;
ULONG DataLength = 0;
ULONG ReturnDataLength = 0;
INT i = 0;
RtlZeroMemory (& Info, sizeof Info);
switch (argc)
{
case 2: /* sm info */
InformationClass = SmBasicInformation;
DataLength = sizeof Info.bi;
break;
case 3: /* sm info id */
InformationClass = SmSubSystemInformation;
DataLength = sizeof Info.ssi;
Info.ssi.SubSystemId = atol(argv[2]);
break;
default:
return EXIT_FAILURE;
break;
}
Status = SmQueryInformation (hSmApiPort,
InformationClass,
& Info,
DataLength,
& ReturnDataLength);
if (STATUS_SUCCESS != Status)
{
PrintStatusError (Status);
return EXIT_FAILURE;
}
switch (argc)
{
case 2:
LoadString( GetModuleHandle(NULL), IDS_SM1, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_tprintf(UsageMessage);
LoadString( GetModuleHandle(NULL), IDS_SM2, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
for (i = 0; i < Info.bi.SubSystemCount; i ++)
{
_tprintf(UsageMessage,
Info.bi.SubSystem[i].Id,
Info.bi.SubSystem[i].ProcessId,
Info.bi.SubSystem[i].Flags);
}
break;
case 3:
LoadString( GetModuleHandle(NULL), IDS_ID, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_tprintf (UsageMessage, Info.ssi.SubSystemId, Info.ssi.Flags, Info.ssi.ProcessId);
wprintf(L" NSRootNode: '%s'\n", Info.ssi.NameSpaceRootNode);
break;
default:
break;
}
return rc;
}
SM_CMD_DECL(shutdown)
{
int rc = EXIT_SUCCESS;
LoadString( GetModuleHandle(NULL), IDS_Not_Imp, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_ftprintf(stderr,UsageMessage);
return rc;
}
SM_CMD_DECL(reboot)
{
int rc = SM_CMD(shutdown)(argc,argv);
if(EXIT_SUCCESS == rc)
{
rc = SM_CMD(boot)(argc,argv);
}
return rc;
}
/* print command's synopsys */
int print_synopsys (int argc, TCHAR *argv[])
{
LoadString( GetModuleHandle(NULL), IDS_Mangers, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_ftprintf (stderr, UsageMessage);
LoadString( GetModuleHandle(NULL), IDS_USING, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_tprintf (UsageMessage);
return EXIT_SUCCESS;
}
/* parse and execute */
int pande (int argc, TCHAR *argv[])
{
PSM_CMD_DESCRIPTOR Command = NULL;
NTSTATUS Status = STATUS_SUCCESS;
/* Lookup the user command... */
Command = LookupCommand (argv[1]);
if (NULL == Command)
{
return EXIT_FAILURE;
}
/* Connect to the SM in non-registering mode. */
Status = SmConnectApiPort (0, 0, 0, & hSmApiPort);
if (STATUS_SUCCESS == Status)
{
/* ...and execute it */
return Command->EntryPoint (argc, argv);
}
LoadString( GetModuleHandle(NULL), IDS_FAILS_MNG, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
_ftprintf (stderr, UsageMessage, Status);
return EXIT_FAILURE;
}
void loadlang(PSM_CMD_DESCRIPTOR cmd)
{
int i=0;
if (cmd==NULL) return;
for (i=0;i < 5; i++)
{
LoadString( GetModuleHandle(NULL), IDS_boot+i, (LPTSTR) &cmd->Synopsis[i],RC_STRING_MAX_SIZE);
}
}
int _tmain (int argc, TCHAR *argv[])
{
loadlang(Command);
return (1==argc)
? print_synopsys (argc, argv)
: pande (argc, argv);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -