Process Hacker
sessshad.c
Go to the documentation of this file.
1 /*
2  * Process Hacker -
3  * session shadow configuration
4  *
5  * Copyright (C) 2011-2013 wj32
6  *
7  * This file is part of Process Hacker.
8  *
9  * Process Hacker is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Process Hacker is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <phapp.h>
24 #include <settings.h>
25 #include <windowsx.h>
26 #include <winsta.h>
27 
28 #define SIP(String, Integer) { (String), (PVOID)(Integer) }
29 
30 static PH_KEY_VALUE_PAIR VirtualKeyPairs[] =
31 {
32  SIP(L"0", '0'),
33  SIP(L"1", '1'),
34  SIP(L"2", '2'),
35  SIP(L"3", '3'),
36  SIP(L"4", '4'),
37  SIP(L"5", '5'),
38  SIP(L"6", '6'),
39  SIP(L"7", '7'),
40  SIP(L"8", '8'),
41  SIP(L"9", '9'),
42  SIP(L"A", 'A'),
43  SIP(L"B", 'B'),
44  SIP(L"C", 'C'),
45  SIP(L"D", 'D'),
46  SIP(L"E", 'E'),
47  SIP(L"F", 'F'),
48  SIP(L"G", 'G'),
49  SIP(L"H", 'H'),
50  SIP(L"I", 'I'),
51  SIP(L"J", 'J'),
52  SIP(L"K", 'K'),
53  SIP(L"L", 'L'),
54  SIP(L"M", 'M'),
55  SIP(L"N", 'N'),
56  SIP(L"O", 'O'),
57  SIP(L"P", 'P'),
58  SIP(L"Q", 'Q'),
59  SIP(L"R", 'R'),
60  SIP(L"S", 'S'),
61  SIP(L"T", 'T'),
62  SIP(L"U", 'U'),
63  SIP(L"V", 'V'),
64  SIP(L"W", 'W'),
65  SIP(L"X", 'X'),
66  SIP(L"Y", 'Y'),
67  SIP(L"Z", 'Z'),
68  SIP(L"{backspace}", VK_BACK),
69  SIP(L"{delete}", VK_DELETE),
70  SIP(L"{down}", VK_DOWN),
71  SIP(L"{end}", VK_END),
72  SIP(L"{enter}", VK_RETURN),
73  SIP(L"{F2}", VK_F2),
74  SIP(L"{F3}", VK_F3),
75  SIP(L"{F4}", VK_F4),
76  SIP(L"{F5}", VK_F5),
77  SIP(L"{F6}", VK_F6),
78  SIP(L"{F7}", VK_F7),
79  SIP(L"{F8}", VK_F8),
80  SIP(L"{F9}", VK_F9),
81  SIP(L"{F10}", VK_F10),
82  SIP(L"{F11}", VK_F11),
83  SIP(L"{F12}", VK_F12),
84  SIP(L"{home}", VK_HOME),
85  SIP(L"{insert}", VK_INSERT),
86  SIP(L"{left}", VK_LEFT),
87  SIP(L"{-}", VK_SUBTRACT),
88  SIP(L"{pagedown}", VK_NEXT),
89  SIP(L"{pageup}", VK_PRIOR),
90  SIP(L"{+}", VK_ADD),
91  SIP(L"{prtscrn}", VK_SNAPSHOT),
92  SIP(L"{right}", VK_RIGHT),
93  SIP(L"{spacebar}", VK_SPACE),
94  SIP(L"{*}", VK_MULTIPLY),
95  SIP(L"{tab}", VK_TAB),
96  SIP(L"{up}", VK_UP)
97 };
98 
99 INT_PTR CALLBACK PhpSessionShadowDlgProc(
100  _In_ HWND hwndDlg,
101  _In_ UINT uMsg,
102  _In_ WPARAM wParam,
103  _In_ LPARAM lParam
104  );
105 
107  _In_ HWND ParentWindowHandle,
108  _In_ ULONG SessionId
109  )
110 {
111  if (SessionId == NtCurrentPeb()->SessionId)
112  {
113  PhShowError(ParentWindowHandle, L"You cannot remote control the current session.");
114  return;
115  }
116 
117  DialogBoxParam(
119  MAKEINTRESOURCE(IDD_SHADOWSESSION),
120  ParentWindowHandle,
122  (LPARAM)SessionId
123  );
124 }
125 
126 INT_PTR CALLBACK PhpSessionShadowDlgProc(
127  _In_ HWND hwndDlg,
128  _In_ UINT uMsg,
129  _In_ WPARAM wParam,
130  _In_ LPARAM lParam
131  )
132 {
133  switch (uMsg)
134  {
135  case WM_INITDIALOG:
136  {
137  HWND virtualKeyComboBox;
138  PH_INTEGER_PAIR hotkey;
139  ULONG i;
140  PWSTR stringToSelect;
141 
142  SetProp(hwndDlg, L"SessionId", (HANDLE)(ULONG)lParam);
143  PhCenterWindow(hwndDlg, GetParent(hwndDlg));
144 
145  hotkey = PhGetIntegerPairSetting(L"SessionShadowHotkey");
146 
147  // Set up the hotkeys.
148 
149  virtualKeyComboBox = GetDlgItem(hwndDlg, IDC_VIRTUALKEY);
150  stringToSelect = L"{*}";
151 
152  for (i = 0; i < sizeof(VirtualKeyPairs) / sizeof(PH_KEY_VALUE_PAIR); i++)
153  {
154  ComboBox_AddString(virtualKeyComboBox, VirtualKeyPairs[i].Key);
155 
156  if ((ULONG)VirtualKeyPairs[i].Value == (ULONG)hotkey.X)
157  {
158  stringToSelect = VirtualKeyPairs[i].Key;
159  }
160  }
161 
162  PhSelectComboBoxString(virtualKeyComboBox, stringToSelect, FALSE);
163 
164  // Set up the modifiers.
165 
166  Button_SetCheck(GetDlgItem(hwndDlg, IDC_SHIFT), hotkey.Y & KBDSHIFT);
167  Button_SetCheck(GetDlgItem(hwndDlg, IDC_CTRL), hotkey.Y & KBDCTRL);
168  Button_SetCheck(GetDlgItem(hwndDlg, IDC_ALT), hotkey.Y & KBDALT);
169  }
170  break;
171  case WM_DESTROY:
172  {
173  RemoveProp(hwndDlg, L"SessionId");
174  }
175  break;
176  case WM_COMMAND:
177  {
178  switch (LOWORD(wParam))
179  {
180  case IDCANCEL:
181  EndDialog(hwndDlg, IDCANCEL);
182  break;
183  case IDOK:
184  {
185  ULONG sessionId = (ULONG)GetProp(hwndDlg, L"SessionId");
186  ULONG virtualKey;
187  ULONG modifiers;
188  WCHAR computerName[64];
189  ULONG computerNameLength = 64;
190 
191  virtualKey = VK_MULTIPLY;
193  VirtualKeyPairs,
194  sizeof(VirtualKeyPairs),
195  PhaGetDlgItemText(hwndDlg, IDC_VIRTUALKEY)->Buffer,
196  &virtualKey
197  );
198 
199  modifiers = 0;
200 
201  if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_SHIFT)) == BST_CHECKED)
202  modifiers |= KBDSHIFT;
203  if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_CTRL)) == BST_CHECKED)
204  modifiers |= KBDCTRL;
205  if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_ALT)) == BST_CHECKED)
206  modifiers |= KBDALT;
207 
208  if (GetComputerName(computerName, &computerNameLength))
209  {
210  if (WinStationShadow(NULL, computerName, sessionId, (UCHAR)virtualKey, (USHORT)modifiers))
211  {
212  PH_INTEGER_PAIR hotkey;
213 
214  hotkey.X = virtualKey;
215  hotkey.Y = modifiers;
216  PhSetIntegerPairSetting(L"SessionShadowHotkey", hotkey);
217 
218  EndDialog(hwndDlg, IDOK);
219  }
220  else
221  {
222  PhShowStatus(hwndDlg, L"Unable to remote control the session", 0, GetLastError());
223  }
224  }
225  else
226  {
227  PhShowError(hwndDlg, L"The computer name is too long.");
228  }
229  }
230  break;
231  }
232  }
233  break;
234  }
235 
236  return FALSE;
237 }