]>
Commit | Line | Data |
---|---|---|
ee38a438 GI |
1 | /* |
2 | * WTSSendMessage() command line tool | |
3 | * | |
a86ec89e | 4 | * Home page of code is: http://www.smartmontools.org |
ee38a438 | 5 | * |
f9e10201 | 6 | * Copyright (C) 2012 Christian Franke |
ee38a438 | 7 | * |
ff28b140 | 8 | * SPDX-License-Identifier: GPL-2.0-or-later |
ee38a438 GI |
9 | */ |
10 | ||
11 | #define WINVER 0x0500 | |
12 | #define _WIN32_WINNT WINVER | |
13 | ||
ff28b140 | 14 | char svnid[] = "$Id: wtssendmsg.c 4760 2018-08-19 18:45:53Z chrfranke $"; |
ee38a438 GI |
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 | { | |
ff28b140 | 26 | printf("wtssendmsg $Revision: 4760 $ - Display a message box on client desktops\n" |
ee38a438 GI |
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 | } |