Button should send BM_SETSTATE message after it has changed its
[wine] / programs / taskmgr / affinity.c
1 /*
2  *  ReactOS Task Manager
3  *
4  *  affinity.c
5  *
6  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22     
23 #define WIN32_LEAN_AND_MEAN    /* Exclude rarely-used stuff from Windows headers */
24 #include <windows.h>
25 #include <commctrl.h>
26 #include <stdlib.h>
27 #include <malloc.h>
28 #include <memory.h>
29 #include <tchar.h>
30 #include <winnt.h>
31 #include <stdio.h>
32     
33 #include "taskmgr.h"
34 #include "perfdata.h"
35
36 HANDLE        hProcessAffinityHandle;
37
38 LRESULT CALLBACK AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
39
40 void ProcessPage_OnSetAffinity(void)
41 {
42     LV_ITEM            lvitem;
43     ULONG            Index;
44     DWORD            dwProcessId;
45     TCHAR            strErrorText[260];
46
47     for (Index=0; Index<(ULONG)ListView_GetItemCount(hProcessPageListCtrl); Index++) {
48         memset(&lvitem, 0, sizeof(LV_ITEM));
49         lvitem.mask = LVIF_STATE;
50         lvitem.stateMask = LVIS_SELECTED;
51         lvitem.iItem = Index;
52         ListView_GetItem(hProcessPageListCtrl, &lvitem);
53         if (lvitem.state & LVIS_SELECTED)
54             break;
55     }
56     dwProcessId = PerfDataGetProcessId(Index);
57     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
58         return;
59     hProcessAffinityHandle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION, FALSE, dwProcessId);
60     if (!hProcessAffinityHandle) {
61         GetLastErrorText(strErrorText, 260);
62         MessageBox(hMainWnd, strErrorText, _T("Unable to Access or Set Process Affinity"), MB_OK|MB_ICONSTOP);
63         return;
64     }
65     DialogBox(hInst, MAKEINTRESOURCE(IDD_AFFINITY_DIALOG), hMainWnd, (DLGPROC)AffinityDialogWndProc);
66     if (hProcessAffinityHandle)    {
67         CloseHandle(hProcessAffinityHandle);
68         hProcessAffinityHandle = NULL;
69     }
70 }
71
72 LRESULT CALLBACK AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
73 {
74     DWORD    dwProcessAffinityMask = 0;
75     DWORD    dwSystemAffinityMask = 0;
76     TCHAR    strErrorText[260];
77
78     switch (message) {
79     case WM_INITDIALOG:
80
81         /*
82          * Get the current affinity mask for the process and
83          * the number of CPUs present in the system
84          */
85         if (!GetProcessAffinityMask(hProcessAffinityHandle, &dwProcessAffinityMask, &dwSystemAffinityMask))    {
86             GetLastErrorText(strErrorText, 260);
87             EndDialog(hDlg, 0);
88             MessageBox(hMainWnd, strErrorText, _T("Unable to Access or Set Process Affinity"), MB_OK|MB_ICONSTOP);
89         }
90
91         /*
92          * Enable a checkbox for each processor present in the system
93          */
94         if (dwSystemAffinityMask & 0x00000001)
95             EnableWindow(GetDlgItem(hDlg, IDC_CPU0), TRUE);
96         if (dwSystemAffinityMask & 0x00000002)
97             EnableWindow(GetDlgItem(hDlg, IDC_CPU1), TRUE);
98         if (dwSystemAffinityMask & 0x00000004)
99             EnableWindow(GetDlgItem(hDlg, IDC_CPU2), TRUE);
100         if (dwSystemAffinityMask & 0x00000008)
101             EnableWindow(GetDlgItem(hDlg, IDC_CPU3), TRUE);
102         if (dwSystemAffinityMask & 0x00000010)
103             EnableWindow(GetDlgItem(hDlg, IDC_CPU4), TRUE);
104         if (dwSystemAffinityMask & 0x00000020)
105             EnableWindow(GetDlgItem(hDlg, IDC_CPU5), TRUE);
106         if (dwSystemAffinityMask & 0x00000040)
107             EnableWindow(GetDlgItem(hDlg, IDC_CPU6), TRUE);
108         if (dwSystemAffinityMask & 0x00000080)
109             EnableWindow(GetDlgItem(hDlg, IDC_CPU7), TRUE);
110         if (dwSystemAffinityMask & 0x00000100)
111             EnableWindow(GetDlgItem(hDlg, IDC_CPU8), TRUE);
112         if (dwSystemAffinityMask & 0x00000200)
113             EnableWindow(GetDlgItem(hDlg, IDC_CPU9), TRUE);
114         if (dwSystemAffinityMask & 0x00000400)
115             EnableWindow(GetDlgItem(hDlg, IDC_CPU10), TRUE);
116         if (dwSystemAffinityMask & 0x00000800)
117             EnableWindow(GetDlgItem(hDlg, IDC_CPU11), TRUE);
118         if (dwSystemAffinityMask & 0x00001000)
119             EnableWindow(GetDlgItem(hDlg, IDC_CPU12), TRUE);
120         if (dwSystemAffinityMask & 0x00002000)
121             EnableWindow(GetDlgItem(hDlg, IDC_CPU13), TRUE);
122         if (dwSystemAffinityMask & 0x00004000)
123             EnableWindow(GetDlgItem(hDlg, IDC_CPU14), TRUE);
124         if (dwSystemAffinityMask & 0x00008000)
125             EnableWindow(GetDlgItem(hDlg, IDC_CPU15), TRUE);
126         if (dwSystemAffinityMask & 0x00010000)
127             EnableWindow(GetDlgItem(hDlg, IDC_CPU16), TRUE);
128         if (dwSystemAffinityMask & 0x00020000)
129             EnableWindow(GetDlgItem(hDlg, IDC_CPU17), TRUE);
130         if (dwSystemAffinityMask & 0x00040000)
131             EnableWindow(GetDlgItem(hDlg, IDC_CPU18), TRUE);
132         if (dwSystemAffinityMask & 0x00080000)
133             EnableWindow(GetDlgItem(hDlg, IDC_CPU19), TRUE);
134         if (dwSystemAffinityMask & 0x00100000)
135             EnableWindow(GetDlgItem(hDlg, IDC_CPU20), TRUE);
136         if (dwSystemAffinityMask & 0x00200000)
137             EnableWindow(GetDlgItem(hDlg, IDC_CPU21), TRUE);
138         if (dwSystemAffinityMask & 0x00400000)
139             EnableWindow(GetDlgItem(hDlg, IDC_CPU22), TRUE);
140         if (dwSystemAffinityMask & 0x00800000)
141             EnableWindow(GetDlgItem(hDlg, IDC_CPU23), TRUE);
142         if (dwSystemAffinityMask & 0x01000000)
143             EnableWindow(GetDlgItem(hDlg, IDC_CPU24), TRUE);
144         if (dwSystemAffinityMask & 0x02000000)
145             EnableWindow(GetDlgItem(hDlg, IDC_CPU25), TRUE);
146         if (dwSystemAffinityMask & 0x04000000)
147             EnableWindow(GetDlgItem(hDlg, IDC_CPU26), TRUE);
148         if (dwSystemAffinityMask & 0x08000000)
149             EnableWindow(GetDlgItem(hDlg, IDC_CPU27), TRUE);
150         if (dwSystemAffinityMask & 0x10000000)
151             EnableWindow(GetDlgItem(hDlg, IDC_CPU28), TRUE);
152         if (dwSystemAffinityMask & 0x20000000)
153             EnableWindow(GetDlgItem(hDlg, IDC_CPU29), TRUE);
154         if (dwSystemAffinityMask & 0x40000000)
155             EnableWindow(GetDlgItem(hDlg, IDC_CPU30), TRUE);
156         if (dwSystemAffinityMask & 0x80000000)
157             EnableWindow(GetDlgItem(hDlg, IDC_CPU31), TRUE);
158
159
160         /*
161          * Check each checkbox that the current process
162          * has affinity with
163          */
164         if (dwProcessAffinityMask & 0x00000001)
165             SendMessage(GetDlgItem(hDlg, IDC_CPU0), BM_SETCHECK, BST_CHECKED, 0);
166         if (dwProcessAffinityMask & 0x00000002)
167             SendMessage(GetDlgItem(hDlg, IDC_CPU1), BM_SETCHECK, BST_CHECKED, 0);
168         if (dwProcessAffinityMask & 0x00000004)
169             SendMessage(GetDlgItem(hDlg, IDC_CPU2), BM_SETCHECK, BST_CHECKED, 0);
170         if (dwProcessAffinityMask & 0x00000008)
171             SendMessage(GetDlgItem(hDlg, IDC_CPU3), BM_SETCHECK, BST_CHECKED, 0);
172         if (dwProcessAffinityMask & 0x00000010)
173             SendMessage(GetDlgItem(hDlg, IDC_CPU4), BM_SETCHECK, BST_CHECKED, 0);
174         if (dwProcessAffinityMask & 0x00000020)
175             SendMessage(GetDlgItem(hDlg, IDC_CPU5), BM_SETCHECK, BST_CHECKED, 0);
176         if (dwProcessAffinityMask & 0x00000040)
177             SendMessage(GetDlgItem(hDlg, IDC_CPU6), BM_SETCHECK, BST_CHECKED, 0);
178         if (dwProcessAffinityMask & 0x00000080)
179             SendMessage(GetDlgItem(hDlg, IDC_CPU7), BM_SETCHECK, BST_CHECKED, 0);
180         if (dwProcessAffinityMask & 0x00000100)
181             SendMessage(GetDlgItem(hDlg, IDC_CPU8), BM_SETCHECK, BST_CHECKED, 0);
182         if (dwProcessAffinityMask & 0x00000200)
183             SendMessage(GetDlgItem(hDlg, IDC_CPU9), BM_SETCHECK, BST_CHECKED, 0);
184         if (dwProcessAffinityMask & 0x00000400)
185             SendMessage(GetDlgItem(hDlg, IDC_CPU10), BM_SETCHECK, BST_CHECKED, 0);
186         if (dwProcessAffinityMask & 0x00000800)
187             SendMessage(GetDlgItem(hDlg, IDC_CPU11), BM_SETCHECK, BST_CHECKED, 0);
188         if (dwProcessAffinityMask & 0x00001000)
189             SendMessage(GetDlgItem(hDlg, IDC_CPU12), BM_SETCHECK, BST_CHECKED, 0);
190         if (dwProcessAffinityMask & 0x00002000)
191             SendMessage(GetDlgItem(hDlg, IDC_CPU13), BM_SETCHECK, BST_CHECKED, 0);
192         if (dwProcessAffinityMask & 0x00004000)
193             SendMessage(GetDlgItem(hDlg, IDC_CPU14), BM_SETCHECK, BST_CHECKED, 0);
194         if (dwProcessAffinityMask & 0x00008000)
195             SendMessage(GetDlgItem(hDlg, IDC_CPU15), BM_SETCHECK, BST_CHECKED, 0);
196         if (dwProcessAffinityMask & 0x00010000)
197             SendMessage(GetDlgItem(hDlg, IDC_CPU16), BM_SETCHECK, BST_CHECKED, 0);
198         if (dwProcessAffinityMask & 0x00020000)
199             SendMessage(GetDlgItem(hDlg, IDC_CPU17), BM_SETCHECK, BST_CHECKED, 0);
200         if (dwProcessAffinityMask & 0x00040000)
201             SendMessage(GetDlgItem(hDlg, IDC_CPU18), BM_SETCHECK, BST_CHECKED, 0);
202         if (dwProcessAffinityMask & 0x00080000)
203             SendMessage(GetDlgItem(hDlg, IDC_CPU19), BM_SETCHECK, BST_CHECKED, 0);
204         if (dwProcessAffinityMask & 0x00100000)
205             SendMessage(GetDlgItem(hDlg, IDC_CPU20), BM_SETCHECK, BST_CHECKED, 0);
206         if (dwProcessAffinityMask & 0x00200000)
207             SendMessage(GetDlgItem(hDlg, IDC_CPU21), BM_SETCHECK, BST_CHECKED, 0);
208         if (dwProcessAffinityMask & 0x00400000)
209             SendMessage(GetDlgItem(hDlg, IDC_CPU22), BM_SETCHECK, BST_CHECKED, 0);
210         if (dwProcessAffinityMask & 0x00800000)
211             SendMessage(GetDlgItem(hDlg, IDC_CPU23), BM_SETCHECK, BST_CHECKED, 0);
212         if (dwProcessAffinityMask & 0x01000000)
213             SendMessage(GetDlgItem(hDlg, IDC_CPU24), BM_SETCHECK, BST_CHECKED, 0);
214         if (dwProcessAffinityMask & 0x02000000)
215             SendMessage(GetDlgItem(hDlg, IDC_CPU25), BM_SETCHECK, BST_CHECKED, 0);
216         if (dwProcessAffinityMask & 0x04000000)
217             SendMessage(GetDlgItem(hDlg, IDC_CPU26), BM_SETCHECK, BST_CHECKED, 0);
218         if (dwProcessAffinityMask & 0x08000000)
219             SendMessage(GetDlgItem(hDlg, IDC_CPU27), BM_SETCHECK, BST_CHECKED, 0);
220         if (dwProcessAffinityMask & 0x10000000)
221             SendMessage(GetDlgItem(hDlg, IDC_CPU28), BM_SETCHECK, BST_CHECKED, 0);
222         if (dwProcessAffinityMask & 0x20000000)
223             SendMessage(GetDlgItem(hDlg, IDC_CPU29), BM_SETCHECK, BST_CHECKED, 0);
224         if (dwProcessAffinityMask & 0x40000000)
225             SendMessage(GetDlgItem(hDlg, IDC_CPU30), BM_SETCHECK, BST_CHECKED, 0);
226         if (dwProcessAffinityMask & 0x80000000)
227             SendMessage(GetDlgItem(hDlg, IDC_CPU31), BM_SETCHECK, BST_CHECKED, 0);
228
229         return TRUE;
230
231     case WM_COMMAND:
232
233         /*
234          * If the user has cancelled the dialog box
235          * then just close it
236          */
237         if (LOWORD(wParam) == IDCANCEL) {
238             EndDialog(hDlg, LOWORD(wParam));
239             return TRUE;
240         }
241
242         /*
243          * The user has clicked OK -- so now we have
244          * to adjust the process affinity mask
245          */
246         if (LOWORD(wParam) == IDOK) {
247             /*
248              * First we have to create a mask out of each
249              * checkbox that the user checked.
250              */
251             if (SendMessage(GetDlgItem(hDlg, IDC_CPU0), BM_GETCHECK, 0, 0))
252                 dwProcessAffinityMask |= 0x00000001;
253             if (SendMessage(GetDlgItem(hDlg, IDC_CPU1), BM_GETCHECK, 0, 0))
254                 dwProcessAffinityMask |= 0x00000002;
255             if (SendMessage(GetDlgItem(hDlg, IDC_CPU2), BM_GETCHECK, 0, 0))
256                 dwProcessAffinityMask |= 0x00000004;
257             if (SendMessage(GetDlgItem(hDlg, IDC_CPU3), BM_GETCHECK, 0, 0))
258                 dwProcessAffinityMask |= 0x00000008;
259             if (SendMessage(GetDlgItem(hDlg, IDC_CPU4), BM_GETCHECK, 0, 0))
260                 dwProcessAffinityMask |= 0x00000010;
261             if (SendMessage(GetDlgItem(hDlg, IDC_CPU5), BM_GETCHECK, 0, 0))
262                 dwProcessAffinityMask |= 0x00000020;
263             if (SendMessage(GetDlgItem(hDlg, IDC_CPU6), BM_GETCHECK, 0, 0))
264                 dwProcessAffinityMask |= 0x00000040;
265             if (SendMessage(GetDlgItem(hDlg, IDC_CPU7), BM_GETCHECK, 0, 0))
266                 dwProcessAffinityMask |= 0x00000080;
267             if (SendMessage(GetDlgItem(hDlg, IDC_CPU8), BM_GETCHECK, 0, 0))
268                 dwProcessAffinityMask |= 0x00000100;
269             if (SendMessage(GetDlgItem(hDlg, IDC_CPU9), BM_GETCHECK, 0, 0))
270                 dwProcessAffinityMask |= 0x00000200;
271             if (SendMessage(GetDlgItem(hDlg, IDC_CPU10), BM_GETCHECK, 0, 0))
272                 dwProcessAffinityMask |= 0x00000400;
273             if (SendMessage(GetDlgItem(hDlg, IDC_CPU11), BM_GETCHECK, 0, 0))
274                 dwProcessAffinityMask |= 0x00000800;
275             if (SendMessage(GetDlgItem(hDlg, IDC_CPU12), BM_GETCHECK, 0, 0))
276                 dwProcessAffinityMask |= 0x00001000;
277             if (SendMessage(GetDlgItem(hDlg, IDC_CPU13), BM_GETCHECK, 0, 0))
278                 dwProcessAffinityMask |= 0x00002000;
279             if (SendMessage(GetDlgItem(hDlg, IDC_CPU14), BM_GETCHECK, 0, 0))
280                 dwProcessAffinityMask |= 0x00004000;
281             if (SendMessage(GetDlgItem(hDlg, IDC_CPU15), BM_GETCHECK, 0, 0))
282                 dwProcessAffinityMask |= 0x00008000;
283             if (SendMessage(GetDlgItem(hDlg, IDC_CPU16), BM_GETCHECK, 0, 0))
284                 dwProcessAffinityMask |= 0x00010000;
285             if (SendMessage(GetDlgItem(hDlg, IDC_CPU17), BM_GETCHECK, 0, 0))
286                 dwProcessAffinityMask |= 0x00020000;
287             if (SendMessage(GetDlgItem(hDlg, IDC_CPU18), BM_GETCHECK, 0, 0))
288                 dwProcessAffinityMask |= 0x00040000;
289             if (SendMessage(GetDlgItem(hDlg, IDC_CPU19), BM_GETCHECK, 0, 0))
290                 dwProcessAffinityMask |= 0x00080000;
291             if (SendMessage(GetDlgItem(hDlg, IDC_CPU20), BM_GETCHECK, 0, 0))
292                 dwProcessAffinityMask |= 0x00100000;
293             if (SendMessage(GetDlgItem(hDlg, IDC_CPU21), BM_GETCHECK, 0, 0))
294                 dwProcessAffinityMask |= 0x00200000;
295             if (SendMessage(GetDlgItem(hDlg, IDC_CPU22), BM_GETCHECK, 0, 0))
296                 dwProcessAffinityMask |= 0x00400000;
297             if (SendMessage(GetDlgItem(hDlg, IDC_CPU23), BM_GETCHECK, 0, 0))
298                 dwProcessAffinityMask |= 0x00800000;
299             if (SendMessage(GetDlgItem(hDlg, IDC_CPU24), BM_GETCHECK, 0, 0))
300                 dwProcessAffinityMask |= 0x01000000;
301             if (SendMessage(GetDlgItem(hDlg, IDC_CPU25), BM_GETCHECK, 0, 0))
302                 dwProcessAffinityMask |= 0x02000000;
303             if (SendMessage(GetDlgItem(hDlg, IDC_CPU26), BM_GETCHECK, 0, 0))
304                 dwProcessAffinityMask |= 0x04000000;
305             if (SendMessage(GetDlgItem(hDlg, IDC_CPU27), BM_GETCHECK, 0, 0))
306                 dwProcessAffinityMask |= 0x08000000;
307             if (SendMessage(GetDlgItem(hDlg, IDC_CPU28), BM_GETCHECK, 0, 0))
308                 dwProcessAffinityMask |= 0x10000000;
309             if (SendMessage(GetDlgItem(hDlg, IDC_CPU29), BM_GETCHECK, 0, 0))
310                 dwProcessAffinityMask |= 0x20000000;
311             if (SendMessage(GetDlgItem(hDlg, IDC_CPU30), BM_GETCHECK, 0, 0))
312                 dwProcessAffinityMask |= 0x40000000;
313             if (SendMessage(GetDlgItem(hDlg, IDC_CPU31), BM_GETCHECK, 0, 0))
314                 dwProcessAffinityMask |= 0x80000000;
315
316             /*
317              * Make sure they are giving the process affinity
318              * with at least one processor. I'd hate to see a
319              * process that is not in a wait state get deprived
320              * of it's cpu time.
321              */
322             if (!dwProcessAffinityMask) {
323                 MessageBox(hDlg, _T("The process must have affinity with at least one processor."), _T("Invalid Option"), MB_OK|MB_ICONSTOP);
324                 return TRUE;
325             }
326
327             /*
328              * Try to set the process affinity
329              */
330             if (!SetProcessAffinityMask(hProcessAffinityHandle, dwProcessAffinityMask)) {
331                 GetLastErrorText(strErrorText, 260);
332                 EndDialog(hDlg, LOWORD(wParam));
333                 MessageBox(hMainWnd, strErrorText, _T("Unable to Access or Set Process Affinity"), MB_OK|MB_ICONSTOP);
334             }
335
336             EndDialog(hDlg, LOWORD(wParam));
337             return TRUE;
338         }
339
340         break;
341     }
342
343     return 0;
344 }