Simple Win32/text application to query the SM (incomplete/untested).
authorEmanuele Aliberti <ea@iol.it>
Thu, 14 Apr 2005 21:46:14 +0000 (21:46 +0000)
committerEmanuele Aliberti <ea@iol.it>
Thu, 14 Apr 2005 21:46:14 +0000 (21:46 +0000)
svn path=/trunk/; revision=14621

reactos/subsys/system/sm/makefile [new file with mode: 0644]
reactos/subsys/system/sm/sm.c [new file with mode: 0644]
reactos/subsys/system/sm/sm.rc [new file with mode: 0644]

diff --git a/reactos/subsys/system/sm/makefile b/reactos/subsys/system/sm/makefile
new file mode 100644 (file)
index 0000000..5a35b96
--- /dev/null
@@ -0,0 +1,28 @@
+# $Id$\r
+# \r
+#  ReactOS Win32 SM Query Tool\r
+# \r
+PATH_TO_TOP = ../../..\r
+TOOLS_PATH = $(PATH_TO_TOP)/tools\r
+\r
+TARGET_TYPE = program\r
+\r
+TARGET_APPTYPE = console\r
+\r
+TARGET_NAME = sm\r
+\r
+TARGET_INSTALLDIR = system32\r
+\r
+TARGET_CFLAGS = -D__USE_W32API -DANONYMOUSUNIONS -Wall -Werror\r
+\r
+TARGET_OBJECTS = $(TARGET_NAME).o\r
+\r
+TARGET_SDKLIBS = smdll.a ntdll.a\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+include $(TOOLS_PATH)/depend.mk\r
+\r
+# EOF\r
diff --git a/reactos/subsys/system/sm/sm.c b/reactos/subsys/system/sm/sm.c
new file mode 100644 (file)
index 0000000..fed4247
--- /dev/null
@@ -0,0 +1,239 @@
+/*\r
+ *  ReactOS Win32 Applications\r
+ *  Copyright (C) 2005 ReactOS Team\r
+ *\r
+ *  This program is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+/* $Id$\r
+ *\r
+ * COPYRIGHT : See COPYING in the top level directory\r
+ * PROJECT   : ReactOS/Win32 Session Manager Control Tool\r
+ * FILE      : subsys/system/sm/sm.c\r
+ * PROGRAMMER: Emanuele Aliberti (ea@reactos.com)\r
+ */\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#define NTOS_MODE_USER\r
+#include <ntos.h>\r
+#include <sm/helper.h>\r
+\r
+#define SM_CMD(n) cmd_##n\r
+#define SM_CMD_DECL(n) int SM_CMD(n)(int argc, char * argv[])\r
+#define SM_CMD_CALL(n,c,v) SM_CMD(n)((c),(v))\r
+\r
+HANDLE hSmApiPort = (HANDLE) 0;\r
+\r
+typedef struct _SM_CMD_DESCRIPTOR\r
+{\r
+       const char * Name;\r
+       int (*EntryPoint)(int,char**);\r
+       const char * Synopsis;\r
+       const char * Description;\r
+       \r
+} SM_CMD_DESCRIPTOR, *PSM_CMD_DESCRIPTOR;\r
+\r
+SM_CMD_DECL(boot);\r
+SM_CMD_DECL(help);\r
+SM_CMD_DECL(info);\r
+SM_CMD_DECL(reboot);\r
+SM_CMD_DECL(shutdown);\r
+\r
+/* internal commands directory */\r
+SM_CMD_DESCRIPTOR Command [] =\r
+{\r
+       {"boot",     SM_CMD(boot),     "boot subsystem_name",   "bootstrap an optional environment subsystem;"},\r
+       {"help",     SM_CMD(help),     "help [command]",        "print help for command;"},\r
+       {"info",     SM_CMD(info),     "info [subsystem_id]",   "print information about a booted subsystem\n"\r
+                                                               "if subsystem_id is omitted, a list of booted\n"\r
+                                                               "environment subsystems is printed."},\r
+       {"reboot",   SM_CMD(reboot),   "reboot subsystem_id",   "reboot an optional environment subsystem;"},\r
+       {"shutdown", SM_CMD(shutdown), "shutdown subsystem_id", "shutdown an optional environment subsystem;"},\r
+};\r
+\r
+PSM_CMD_DESCRIPTOR LookupCommand (const char * CommandName)\r
+{\r
+       int i;\r
+       const int command_count = (sizeof Command / sizeof Command[0]);\r
+       \r
+       /* parse the command... */\r
+\r
+       for (i=0; (i < command_count); i ++)\r
+       {\r
+               if (0 == strcmp(CommandName, Command[i].Name))\r
+               {\r
+                       break;\r
+               }\r
+       }\r
+       if (i == command_count)\r
+       {\r
+               fprintf(stderr, "Unknown command '%s'.\n", CommandName);\r
+               return NULL;\r
+       }\r
+       return & Command [i];\r
+}\r
+\r
+/* user commands */\r
+\r
+SM_CMD_DECL(boot)\r
+{\r
+       int rc = EXIT_SUCCESS;\r
+       ANSI_STRING ProgramA;\r
+       UNICODE_STRING ProgramW;\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+       if (3 == argc)\r
+       {\r
+               RtlInitAnsiString (& ProgramA, argv[2]);\r
+               RtlAnsiStringToUnicodeString (& ProgramW, & ProgramA, TRUE);\r
+               Status = SmExecuteProgram (hSmApiPort, & ProgramW);\r
+               RtlFreeUnicodeString (& ProgramW);\r
+               if (STATUS_SUCCESS != Status)\r
+               {\r
+                       printf ("Status 0x%08lx\n", Status);\r
+               }\r
+       }\r
+       else\r
+       {\r
+               argv[2]="boot";\r
+               return SM_CMD_CALL(help,3,argv);\r
+       }\r
+       return rc;\r
+}\r
+\r
+SM_CMD_DECL(help)\r
+{\r
+       int i = 0;\r
+       PSM_CMD_DESCRIPTOR cmd = NULL;\r
+       int rc = EXIT_SUCCESS;\r
+\r
+       switch (argc)\r
+       {\r
+       case 2:\r
+               for (i=0; (i < (sizeof Command / sizeof Command[0])); i ++)\r
+               {\r
+                       printf("%s\n", Command[i].Synopsis);\r
+               }\r
+               break;\r
+       case 3:\r
+               cmd = LookupCommand (argv[2]);\r
+               if (NULL == cmd)\r
+               {\r
+                       rc = EXIT_FAILURE;\r
+                       break;\r
+               }\r
+               printf("%s\n%s\n\n%s\n",\r
+                       cmd->Name,\r
+                       cmd->Synopsis,\r
+                       cmd->Description);\r
+               break;\r
+       }\r
+       return rc;\r
+}\r
+\r
+SM_CMD_DECL(info)\r
+{\r
+       int rc = EXIT_SUCCESS;\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+       SM_BASIC_INFORMATION bi = {0,};\r
+       ULONG ReturnDataLength = sizeof bi;\r
+\r
+       Status = SmQueryInformation (hSmApiPort,\r
+                                    SmBasicInformation,\r
+                                    & bi,\r
+                                    sizeof bi,\r
+                                    & ReturnDataLength);\r
+       if (STATUS_SUCCESS == Status)\r
+       {\r
+               int i = 0;\r
+\r
+               printf ("SSID PID      Flags\n");\r
+               for (i = 0; i < bi.SubSystemCount; i ++)\r
+               {\r
+                       printf ("%04x %08lx %04x\n",\r
+                                       bi.SubSystem[i].Id,\r
+                                       bi.SubSystem[i].ProcessId,\r
+                                       bi.SubSystem[i].Flags);\r
+               }\r
+       }\r
+       else\r
+       {\r
+               printf ("Status 0x%08lx\n", Status);\r
+               rc = EXIT_FAILURE;\r
+       }\r
+       return rc;\r
+}\r
+\r
+SM_CMD_DECL(shutdown)\r
+{\r
+       int rc = EXIT_SUCCESS;\r
+       \r
+       fprintf(stderr,"not implemented\n");\r
+       return rc;\r
+}\r
+\r
+SM_CMD_DECL(reboot)\r
+{\r
+       int rc = SM_CMD(shutdown)(argc,argv);\r
+       if(EXIT_SUCCESS == rc)\r
+       {\r
+               rc = SM_CMD(boot)(argc,argv);\r
+       }\r
+       return rc;\r
+}\r
+\r
+/* print command's synopsys */\r
+int print_synopsys (int argc, char *argv[])\r
+{\r
+       fprintf (stderr, "ReactOS/Win32 Session Manager Control Tool\n\n");\r
+       printf ("Usage:\n"\r
+               "\tsm\n"\r
+               "\tsm help [command]\n"\r
+               "\tsm command [arguments]\n\n"\r
+               "'sm help' will print the list of valid commands.\n");\r
+       return EXIT_SUCCESS;\r
+}\r
+\r
+/* parse and execute */\r
+int pande (int argc, char *argv[])\r
+{\r
+       PSM_CMD_DESCRIPTOR Command = NULL;\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+       /* Lookup the user command... */        \r
+       Command = LookupCommand (argv[1]);\r
+       if (NULL == Command)\r
+       {\r
+               return EXIT_FAILURE;\r
+       } \r
+       /* Connect to the SM in non-registering mode. */\r
+       Status = SmConnectApiPort (0, 0, 0, & hSmApiPort);\r
+       if (STATUS_SUCCESS == Status)\r
+       {       \r
+               /* ...and execute it */\r
+               return Command->EntryPoint (argc, argv);\r
+       }\r
+       fprintf (stderr, "Failed to connect to the Session Manager! (Status=0x%08lx)\n", Status);\r
+       return EXIT_FAILURE;\r
+}\r
+\r
+int main (int argc, char *argv[])\r
+{\r
+       return (1==argc)\r
+               ? print_synopsys (argc, argv)\r
+               : pande (argc, argv);\r
+}\r
+/* EOF */\r
diff --git a/reactos/subsys/system/sm/sm.rc b/reactos/subsys/system/sm/sm.rc
new file mode 100644 (file)
index 0000000..0de4b78
--- /dev/null
@@ -0,0 +1,4 @@
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS/Win32 Session Manager Control Tool\0"\r
+#define REACTOS_STR_INTERNAL_NAME      "sm\0"\r
+#define REACTOS_STR_ORIGINAL_FILENAME  "sm.exe\0"\r
+#include <reactos/version.rc>\r