]>
Commit | Line | Data |
---|---|---|
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 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2, or (at your option) | |
11 | * any later version. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * (for example COPYING); If not, see <http://www.gnu.org/licenses/>. | |
15 | * | |
16 | */ | |
17 | ||
18 | #define WINVER 0x0500 | |
19 | #define _WIN32_WINNT WINVER | |
20 | ||
21 | char svnid[] = "$Id: wtssendmsg.c 4431 2017-08-08 19:38:15Z chrfranke $"; | |
22 | ||
23 | #include <stdio.h> | |
24 | #include <string.h> | |
25 | ||
26 | #define WIN32_LEAN_AND_MEAN | |
27 | #include <windows.h> | |
28 | #include <wtsapi32.h> | |
29 | ||
30 | ||
31 | static int usage() | |
32 | { | |
33 | printf("wtssendmsg $Revision: 4431 $ - Display a message box on client desktops\n" | |
34 | "Copyright (C) 2012 Christian Franke, smartmontools.org\n\n" | |
35 | "Usage: wtssendmsg [-cas] [-v] [\"Caption\"] \"Message\"|-\n" | |
36 | " wtssendmsg -v\n\n" | |
37 | " -c Console session [default]\n" | |
38 | " -a Active sessions\n" | |
39 | " -s Connected sessions\n" | |
40 | " -v List sessions\n" | |
41 | ); | |
42 | return 1; | |
43 | } | |
44 | ||
45 | int main(int argc, const char **argv) | |
46 | { | |
47 | int mode = 0, verbose = 0, status = 0, i; | |
48 | const char * message = 0, * caption = ""; | |
49 | char msgbuf[1024]; | |
50 | WTS_SESSION_INFOA * sessions; DWORD count; | |
51 | ||
52 | for (i = 1; i < argc && argv[i][0] == '-' && argv[i][1]; i++) { | |
53 | int j; | |
54 | for (j = 1; argv[i][j]; j++) | |
55 | switch (argv[i][j]) { | |
56 | case 'c': mode = 0; break; | |
57 | case 'a': mode = 1; break; | |
58 | case 's': mode = 2; break; | |
59 | case 'v': verbose = 1; break; | |
60 | default: return usage(); | |
61 | } | |
62 | } | |
63 | ||
64 | if (i < argc) { | |
65 | if (i+1 < argc) | |
66 | caption = argv[i++]; | |
67 | ||
68 | message = argv[i++]; | |
69 | if (i < argc) | |
70 | return usage(); | |
71 | ||
72 | if (!strcmp(message, "-")) { | |
73 | // Read message from stdin | |
74 | i = fread(msgbuf, 1, sizeof(msgbuf)-1, stdin); | |
75 | if (i < 0) { | |
76 | perror("stdin"); | |
77 | return 1; | |
78 | } | |
79 | msgbuf[i] = 0; | |
80 | message = msgbuf; | |
81 | } | |
82 | } | |
83 | else { | |
84 | if (!verbose) | |
85 | return usage(); | |
86 | } | |
87 | ||
88 | // Get session list | |
89 | if (!WTSEnumerateSessionsA(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count)) { | |
90 | fprintf(stderr, "WTSEnumerateSessions() failed\n"); | |
91 | return 1; | |
92 | } | |
93 | ||
94 | for (i = 0; i < (int)count; i++) { | |
95 | ||
96 | if (verbose) { | |
97 | printf("Session %d (\"%s\", State=%d)%s", | |
98 | i, sessions[i].pWinStationName, sessions[i].State, | |
99 | (!message ? "\n" : ": ")); | |
100 | if (!message) | |
101 | continue; // List sessions only | |
102 | fflush(stdout); | |
103 | } | |
104 | ||
105 | if ( !strcmpi(sessions[i].pWinStationName, "Console") | |
106 | || (mode >= 1 && sessions[i].State == WTSActive) | |
107 | || (mode >= 2 && sessions[i].State == WTSConnected)) { | |
108 | ||
109 | // Send Message, don't wait for OK button | |
110 | DWORD result; | |
111 | if (WTSSendMessageA(WTS_CURRENT_SERVER_HANDLE, sessions[i].SessionId, | |
112 | (char *)caption, strlen(caption), | |
113 | (char *)message, strlen(message), | |
114 | MB_OK|MB_ICONEXCLAMATION, 0 /*Timeout*/, | |
115 | &result, FALSE /*!Wait*/)) { | |
116 | if (verbose) | |
117 | printf("message sent\n"); | |
118 | } | |
119 | else { | |
120 | status = 1; | |
121 | if (verbose) | |
122 | printf("WTSSendMessage() failed with error=%d\n", (int)GetLastError()); | |
123 | else | |
124 | fprintf(stderr, "Session %d (\"%s\", State=%d): WTSSendMessage() failed with error=%d\n", | |
125 | i, sessions[i].pWinStationName, sessions[i].State, (int)GetLastError()); | |
126 | } | |
127 | } | |
128 | else { | |
129 | if (verbose) | |
130 | printf("ignored\n"); | |
131 | } | |
132 | } | |
133 | ||
134 | WTSFreeMemory(sessions); | |
135 | ||
136 | return status; | |
137 | } |