]> git.proxmox.com Git - mirror_smartmontools-debian.git/blob - os_win32/wtssendmsg.c
import smartmontools 7.0
[mirror_smartmontools-debian.git] / os_win32 / wtssendmsg.c
1 /*
2 * WTSSendMessage() command line tool
3 *
4 * Home page of code is: http://www.smartmontools.org
5 *
6 * Copyright (C) 2012 Christian Franke
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #define WINVER 0x0500
12 #define _WIN32_WINNT WINVER
13
14 char svnid[] = "$Id: wtssendmsg.c 4760 2018-08-19 18:45:53Z chrfranke $";
15
16 #include <stdio.h>
17 #include <string.h>
18
19 #define WIN32_LEAN_AND_MEAN
20 #include <windows.h>
21 #include <wtsapi32.h>
22
23
24 static int usage()
25 {
26 printf("wtssendmsg $Revision: 4760 $ - Display a message box on client desktops\n"
27 "Copyright (C) 2012 Christian Franke, smartmontools.org\n\n"
28 "Usage: wtssendmsg [-cas] [-v] [\"Caption\"] \"Message\"|-\n"
29 " wtssendmsg -v\n\n"
30 " -c Console session [default]\n"
31 " -a Active sessions\n"
32 " -s Connected sessions\n"
33 " -v List sessions\n"
34 );
35 return 1;
36 }
37
38 int main(int argc, const char **argv)
39 {
40 int mode = 0, verbose = 0, status = 0, i;
41 const char * message = 0, * caption = "";
42 char msgbuf[1024];
43 WTS_SESSION_INFOA * sessions; DWORD count;
44
45 for (i = 1; i < argc && argv[i][0] == '-' && argv[i][1]; i++) {
46 int j;
47 for (j = 1; argv[i][j]; j++)
48 switch (argv[i][j]) {
49 case 'c': mode = 0; break;
50 case 'a': mode = 1; break;
51 case 's': mode = 2; break;
52 case 'v': verbose = 1; break;
53 default: return usage();
54 }
55 }
56
57 if (i < argc) {
58 if (i+1 < argc)
59 caption = argv[i++];
60
61 message = argv[i++];
62 if (i < argc)
63 return usage();
64
65 if (!strcmp(message, "-")) {
66 // Read message from stdin
67 i = fread(msgbuf, 1, sizeof(msgbuf)-1, stdin);
68 if (i < 0) {
69 perror("stdin");
70 return 1;
71 }
72 msgbuf[i] = 0;
73 message = msgbuf;
74 }
75 }
76 else {
77 if (!verbose)
78 return usage();
79 }
80
81 // Get session list
82 if (!WTSEnumerateSessionsA(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count)) {
83 fprintf(stderr, "WTSEnumerateSessions() failed\n");
84 return 1;
85 }
86
87 for (i = 0; i < (int)count; i++) {
88
89 if (verbose) {
90 printf("Session %d (\"%s\", State=%d)%s",
91 i, sessions[i].pWinStationName, sessions[i].State,
92 (!message ? "\n" : ": "));
93 if (!message)
94 continue; // List sessions only
95 fflush(stdout);
96 }
97
98 if ( !strcmpi(sessions[i].pWinStationName, "Console")
99 || (mode >= 1 && sessions[i].State == WTSActive)
100 || (mode >= 2 && sessions[i].State == WTSConnected)) {
101
102 // Send Message, don't wait for OK button
103 DWORD result;
104 if (WTSSendMessageA(WTS_CURRENT_SERVER_HANDLE, sessions[i].SessionId,
105 (char *)caption, strlen(caption),
106 (char *)message, strlen(message),
107 MB_OK|MB_ICONEXCLAMATION, 0 /*Timeout*/,
108 &result, FALSE /*!Wait*/)) {
109 if (verbose)
110 printf("message sent\n");
111 }
112 else {
113 status = 1;
114 if (verbose)
115 printf("WTSSendMessage() failed with error=%d\n", (int)GetLastError());
116 else
117 fprintf(stderr, "Session %d (\"%s\", State=%d): WTSSendMessage() failed with error=%d\n",
118 i, sessions[i].pWinStationName, sessions[i].State, (int)GetLastError());
119 }
120 }
121 else {
122 if (verbose)
123 printf("ignored\n");
124 }
125 }
126
127 WTSFreeMemory(sessions);
128
129 return status;
130 }