affinity.c 17 KB
Newer Older
1 2 3 4 5 6
/*
 *  ReactOS Task Manager
 *
 *  affinity.c
 *
 *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
7
 *  Copyright (C) 2008  Vladimir Pankratov
8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22
 */
23 24 25 26

#include <stdio.h>
#include <stdlib.h>

27 28 29
#include <windows.h>
#include <commctrl.h>
#include <winnt.h>
30

31
#include "wine/unicode.h"
32 33 34 35 36
#include "taskmgr.h"
#include "perfdata.h"

HANDLE        hProcessAffinityHandle;

37
WCHAR    wszUnable2Access[255];
38

39
static INT_PTR CALLBACK
40
AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
41
{
42 43
    DWORD_PTR dwProcessAffinityMask = 0;
    DWORD_PTR dwSystemAffinityMask = 0;
44
    WCHAR     wstrErrorText[256];
45 46 47 48 49 50 51 52 53

    switch (message) {
    case WM_INITDIALOG:

        /*
         * Get the current affinity mask for the process and
         * the number of CPUs present in the system
         */
        if (!GetProcessAffinityMask(hProcessAffinityHandle, &dwProcessAffinityMask, &dwSystemAffinityMask))    {
54
            GetLastErrorText(wstrErrorText, sizeof(wstrErrorText)/sizeof(WCHAR));
55
            EndDialog(hDlg, 0);
56
            LoadStringW(hInst, IDS_AFFINITY_UNABLE2ACCESS, wszUnable2Access, sizeof(wszUnable2Access)/sizeof(WCHAR));
57
            MessageBoxW(hMainWnd, wstrErrorText, wszUnable2Access, MB_OK|MB_ICONSTOP);
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
        }

        /*
         * Enable a checkbox for each processor present in the system
         */
        if (dwSystemAffinityMask & 0x00000001)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU0), TRUE);
        if (dwSystemAffinityMask & 0x00000002)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU1), TRUE);
        if (dwSystemAffinityMask & 0x00000004)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU2), TRUE);
        if (dwSystemAffinityMask & 0x00000008)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU3), TRUE);
        if (dwSystemAffinityMask & 0x00000010)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU4), TRUE);
        if (dwSystemAffinityMask & 0x00000020)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU5), TRUE);
        if (dwSystemAffinityMask & 0x00000040)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU6), TRUE);
        if (dwSystemAffinityMask & 0x00000080)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU7), TRUE);
        if (dwSystemAffinityMask & 0x00000100)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU8), TRUE);
        if (dwSystemAffinityMask & 0x00000200)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU9), TRUE);
        if (dwSystemAffinityMask & 0x00000400)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU10), TRUE);
        if (dwSystemAffinityMask & 0x00000800)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU11), TRUE);
        if (dwSystemAffinityMask & 0x00001000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU12), TRUE);
        if (dwSystemAffinityMask & 0x00002000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU13), TRUE);
        if (dwSystemAffinityMask & 0x00004000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU14), TRUE);
        if (dwSystemAffinityMask & 0x00008000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU15), TRUE);
        if (dwSystemAffinityMask & 0x00010000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU16), TRUE);
        if (dwSystemAffinityMask & 0x00020000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU17), TRUE);
        if (dwSystemAffinityMask & 0x00040000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU18), TRUE);
        if (dwSystemAffinityMask & 0x00080000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU19), TRUE);
        if (dwSystemAffinityMask & 0x00100000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU20), TRUE);
        if (dwSystemAffinityMask & 0x00200000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU21), TRUE);
        if (dwSystemAffinityMask & 0x00400000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU22), TRUE);
        if (dwSystemAffinityMask & 0x00800000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU23), TRUE);
        if (dwSystemAffinityMask & 0x01000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU24), TRUE);
        if (dwSystemAffinityMask & 0x02000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU25), TRUE);
        if (dwSystemAffinityMask & 0x04000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU26), TRUE);
        if (dwSystemAffinityMask & 0x08000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU27), TRUE);
        if (dwSystemAffinityMask & 0x10000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU28), TRUE);
        if (dwSystemAffinityMask & 0x20000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU29), TRUE);
        if (dwSystemAffinityMask & 0x40000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU30), TRUE);
        if (dwSystemAffinityMask & 0x80000000)
            EnableWindow(GetDlgItem(hDlg, IDC_CPU31), TRUE);


        /*
         * Check each checkbox that the current process
         * has affinity with
         */
        if (dwProcessAffinityMask & 0x00000001)
134
            SendMessageW(GetDlgItem(hDlg, IDC_CPU0), BM_SETCHECK, BST_CHECKED, 0);
135
        if (dwProcessAffinityMask & 0x00000002)
136
            SendMessageW(GetDlgItem(hDlg, IDC_CPU1), BM_SETCHECK, BST_CHECKED, 0);
137
        if (dwProcessAffinityMask & 0x00000004)
138
            SendMessageW(GetDlgItem(hDlg, IDC_CPU2), BM_SETCHECK, BST_CHECKED, 0);
139
        if (dwProcessAffinityMask & 0x00000008)
140
            SendMessageW(GetDlgItem(hDlg, IDC_CPU3), BM_SETCHECK, BST_CHECKED, 0);
141
        if (dwProcessAffinityMask & 0x00000010)
142
            SendMessageW(GetDlgItem(hDlg, IDC_CPU4), BM_SETCHECK, BST_CHECKED, 0);
143
        if (dwProcessAffinityMask & 0x00000020)
144
            SendMessageW(GetDlgItem(hDlg, IDC_CPU5), BM_SETCHECK, BST_CHECKED, 0);
145
        if (dwProcessAffinityMask & 0x00000040)
146
            SendMessageW(GetDlgItem(hDlg, IDC_CPU6), BM_SETCHECK, BST_CHECKED, 0);
147
        if (dwProcessAffinityMask & 0x00000080)
148
            SendMessageW(GetDlgItem(hDlg, IDC_CPU7), BM_SETCHECK, BST_CHECKED, 0);
149
        if (dwProcessAffinityMask & 0x00000100)
150
            SendMessageW(GetDlgItem(hDlg, IDC_CPU8), BM_SETCHECK, BST_CHECKED, 0);
151
        if (dwProcessAffinityMask & 0x00000200)
152
            SendMessageW(GetDlgItem(hDlg, IDC_CPU9), BM_SETCHECK, BST_CHECKED, 0);
153
        if (dwProcessAffinityMask & 0x00000400)
154
            SendMessageW(GetDlgItem(hDlg, IDC_CPU10), BM_SETCHECK, BST_CHECKED, 0);
155
        if (dwProcessAffinityMask & 0x00000800)
156
            SendMessageW(GetDlgItem(hDlg, IDC_CPU11), BM_SETCHECK, BST_CHECKED, 0);
157
        if (dwProcessAffinityMask & 0x00001000)
158
            SendMessageW(GetDlgItem(hDlg, IDC_CPU12), BM_SETCHECK, BST_CHECKED, 0);
159
        if (dwProcessAffinityMask & 0x00002000)
160
            SendMessageW(GetDlgItem(hDlg, IDC_CPU13), BM_SETCHECK, BST_CHECKED, 0);
161
        if (dwProcessAffinityMask & 0x00004000)
162
            SendMessageW(GetDlgItem(hDlg, IDC_CPU14), BM_SETCHECK, BST_CHECKED, 0);
163
        if (dwProcessAffinityMask & 0x00008000)
164
            SendMessageW(GetDlgItem(hDlg, IDC_CPU15), BM_SETCHECK, BST_CHECKED, 0);
165
        if (dwProcessAffinityMask & 0x00010000)
166
            SendMessageW(GetDlgItem(hDlg, IDC_CPU16), BM_SETCHECK, BST_CHECKED, 0);
167
        if (dwProcessAffinityMask & 0x00020000)
168
            SendMessageW(GetDlgItem(hDlg, IDC_CPU17), BM_SETCHECK, BST_CHECKED, 0);
169
        if (dwProcessAffinityMask & 0x00040000)
170
            SendMessageW(GetDlgItem(hDlg, IDC_CPU18), BM_SETCHECK, BST_CHECKED, 0);
171
        if (dwProcessAffinityMask & 0x00080000)
172
            SendMessageW(GetDlgItem(hDlg, IDC_CPU19), BM_SETCHECK, BST_CHECKED, 0);
173
        if (dwProcessAffinityMask & 0x00100000)
174
            SendMessageW(GetDlgItem(hDlg, IDC_CPU20), BM_SETCHECK, BST_CHECKED, 0);
175
        if (dwProcessAffinityMask & 0x00200000)
176
            SendMessageW(GetDlgItem(hDlg, IDC_CPU21), BM_SETCHECK, BST_CHECKED, 0);
177
        if (dwProcessAffinityMask & 0x00400000)
178
            SendMessageW(GetDlgItem(hDlg, IDC_CPU22), BM_SETCHECK, BST_CHECKED, 0);
179
        if (dwProcessAffinityMask & 0x00800000)
180
            SendMessageW(GetDlgItem(hDlg, IDC_CPU23), BM_SETCHECK, BST_CHECKED, 0);
181
        if (dwProcessAffinityMask & 0x01000000)
182
            SendMessageW(GetDlgItem(hDlg, IDC_CPU24), BM_SETCHECK, BST_CHECKED, 0);
183
        if (dwProcessAffinityMask & 0x02000000)
184
            SendMessageW(GetDlgItem(hDlg, IDC_CPU25), BM_SETCHECK, BST_CHECKED, 0);
185
        if (dwProcessAffinityMask & 0x04000000)
186
            SendMessageW(GetDlgItem(hDlg, IDC_CPU26), BM_SETCHECK, BST_CHECKED, 0);
187
        if (dwProcessAffinityMask & 0x08000000)
188
            SendMessageW(GetDlgItem(hDlg, IDC_CPU27), BM_SETCHECK, BST_CHECKED, 0);
189
        if (dwProcessAffinityMask & 0x10000000)
190
            SendMessageW(GetDlgItem(hDlg, IDC_CPU28), BM_SETCHECK, BST_CHECKED, 0);
191
        if (dwProcessAffinityMask & 0x20000000)
192
            SendMessageW(GetDlgItem(hDlg, IDC_CPU29), BM_SETCHECK, BST_CHECKED, 0);
193
        if (dwProcessAffinityMask & 0x40000000)
194
            SendMessageW(GetDlgItem(hDlg, IDC_CPU30), BM_SETCHECK, BST_CHECKED, 0);
195
        if (dwProcessAffinityMask & 0x80000000)
196
            SendMessageW(GetDlgItem(hDlg, IDC_CPU31), BM_SETCHECK, BST_CHECKED, 0);
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

        return TRUE;

    case WM_COMMAND:

        /*
         * If the user has cancelled the dialog box
         * then just close it
         */
        if (LOWORD(wParam) == IDCANCEL) {
            EndDialog(hDlg, LOWORD(wParam));
            return TRUE;
        }

        /*
         * The user has clicked OK -- so now we have
         * to adjust the process affinity mask
         */
        if (LOWORD(wParam) == IDOK) {
            /*
             * First we have to create a mask out of each
             * checkbox that the user checked.
             */
220
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU0), BM_GETCHECK, 0, 0))
221
                dwProcessAffinityMask |= 0x00000001;
222
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU1), BM_GETCHECK, 0, 0))
223
                dwProcessAffinityMask |= 0x00000002;
224
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU2), BM_GETCHECK, 0, 0))
225
                dwProcessAffinityMask |= 0x00000004;
226
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU3), BM_GETCHECK, 0, 0))
227
                dwProcessAffinityMask |= 0x00000008;
228
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU4), BM_GETCHECK, 0, 0))
229
                dwProcessAffinityMask |= 0x00000010;
230
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU5), BM_GETCHECK, 0, 0))
231
                dwProcessAffinityMask |= 0x00000020;
232
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU6), BM_GETCHECK, 0, 0))
233
                dwProcessAffinityMask |= 0x00000040;
234
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU7), BM_GETCHECK, 0, 0))
235
                dwProcessAffinityMask |= 0x00000080;
236
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU8), BM_GETCHECK, 0, 0))
237
                dwProcessAffinityMask |= 0x00000100;
238
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU9), BM_GETCHECK, 0, 0))
239
                dwProcessAffinityMask |= 0x00000200;
240
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU10), BM_GETCHECK, 0, 0))
241
                dwProcessAffinityMask |= 0x00000400;
242
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU11), BM_GETCHECK, 0, 0))
243
                dwProcessAffinityMask |= 0x00000800;
244
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU12), BM_GETCHECK, 0, 0))
245
                dwProcessAffinityMask |= 0x00001000;
246
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU13), BM_GETCHECK, 0, 0))
247
                dwProcessAffinityMask |= 0x00002000;
248
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU14), BM_GETCHECK, 0, 0))
249
                dwProcessAffinityMask |= 0x00004000;
250
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU15), BM_GETCHECK, 0, 0))
251
                dwProcessAffinityMask |= 0x00008000;
252
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU16), BM_GETCHECK, 0, 0))
253
                dwProcessAffinityMask |= 0x00010000;
254
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU17), BM_GETCHECK, 0, 0))
255
                dwProcessAffinityMask |= 0x00020000;
256
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU18), BM_GETCHECK, 0, 0))
257
                dwProcessAffinityMask |= 0x00040000;
258
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU19), BM_GETCHECK, 0, 0))
259
                dwProcessAffinityMask |= 0x00080000;
260
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU20), BM_GETCHECK, 0, 0))
261
                dwProcessAffinityMask |= 0x00100000;
262
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU21), BM_GETCHECK, 0, 0))
263
                dwProcessAffinityMask |= 0x00200000;
264
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU22), BM_GETCHECK, 0, 0))
265
                dwProcessAffinityMask |= 0x00400000;
266
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU23), BM_GETCHECK, 0, 0))
267
                dwProcessAffinityMask |= 0x00800000;
268
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU24), BM_GETCHECK, 0, 0))
269
                dwProcessAffinityMask |= 0x01000000;
270
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU25), BM_GETCHECK, 0, 0))
271
                dwProcessAffinityMask |= 0x02000000;
272
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU26), BM_GETCHECK, 0, 0))
273
                dwProcessAffinityMask |= 0x04000000;
274
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU27), BM_GETCHECK, 0, 0))
275
                dwProcessAffinityMask |= 0x08000000;
276
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU28), BM_GETCHECK, 0, 0))
277
                dwProcessAffinityMask |= 0x10000000;
278
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU29), BM_GETCHECK, 0, 0))
279
                dwProcessAffinityMask |= 0x20000000;
280
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU30), BM_GETCHECK, 0, 0))
281
                dwProcessAffinityMask |= 0x40000000;
282
            if (SendMessageW(GetDlgItem(hDlg, IDC_CPU31), BM_GETCHECK, 0, 0))
283 284 285 286 287 288
                dwProcessAffinityMask |= 0x80000000;

            /*
             * Make sure they are giving the process affinity
             * with at least one processor. I'd hate to see a
             * process that is not in a wait state get deprived
289
             * of its cpu time.
290 291
             */
            if (!dwProcessAffinityMask) {
292 293 294 295
                WCHAR wszErrorMsg[255];
                WCHAR wszErrorTitle[255];
                LoadStringW(hInst, IDS_AFFINITY_ERROR_MESSAGE, wszErrorMsg, sizeof(wszErrorMsg)/sizeof(WCHAR));
                LoadStringW(hInst, IDS_AFFINITY_ERROR_TITLE, wszErrorTitle, sizeof(wszErrorTitle)/sizeof(WCHAR));
296
                MessageBoxW(hDlg, wszErrorMsg, wszErrorTitle, MB_OK|MB_ICONSTOP);
297 298 299 300 301 302 303
                return TRUE;
            }

            /*
             * Try to set the process affinity
             */
            if (!SetProcessAffinityMask(hProcessAffinityHandle, dwProcessAffinityMask)) {
304
                GetLastErrorText(wstrErrorText, sizeof(wstrErrorText)/sizeof(WCHAR));
305
                EndDialog(hDlg, LOWORD(wParam));
306
                LoadStringW(hInst, IDS_AFFINITY_UNABLE2ACCESS, wszUnable2Access, sizeof(wszUnable2Access)/sizeof(WCHAR));
307
                MessageBoxW(hMainWnd, wstrErrorText, wszUnable2Access, MB_OK|MB_ICONSTOP);
308 309 310 311 312 313 314 315 316 317 318
            }

            EndDialog(hDlg, LOWORD(wParam));
            return TRUE;
        }

        break;
    }

    return 0;
}
319 320 321

void ProcessPage_OnSetAffinity(void)
{
322
    LV_ITEMW         lvitem;
323
    ULONG            Index, Count;
324
    DWORD            dwProcessId;
325
    WCHAR            wstrErrorText[256];
326

327 328
    Count = SendMessageW(hProcessPageListCtrl, LVM_GETITEMCOUNT, 0, 0);
    for (Index=0; Index<Count; Index++) {
329
        memset(&lvitem, 0, sizeof(LV_ITEMW));
330 331 332
        lvitem.mask = LVIF_STATE;
        lvitem.stateMask = LVIS_SELECTED;
        lvitem.iItem = Index;
333
        SendMessageW(hProcessPageListCtrl, LVM_GETITEMW, 0, (LPARAM) &lvitem);
334 335 336
        if (lvitem.state & LVIS_SELECTED)
            break;
    }
337 338

    Count = SendMessageW(hProcessPageListCtrl, LVM_GETSELECTEDCOUNT, 0, 0);
339
    dwProcessId = PerfDataGetProcessId(Index);
340
    if ((Count != 1) || (dwProcessId == 0))
341 342 343
        return;
    hProcessAffinityHandle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION, FALSE, dwProcessId);
    if (!hProcessAffinityHandle) {
344
        GetLastErrorText(wstrErrorText, sizeof(wstrErrorText)/sizeof(WCHAR));
345
        LoadStringW(hInst, IDS_AFFINITY_UNABLE2ACCESS, wszUnable2Access, sizeof(wszUnable2Access)/sizeof(WCHAR));
346
        MessageBoxW(hMainWnd, wstrErrorText, wszUnable2Access, MB_OK|MB_ICONSTOP);
347 348
        return;
    }
349
    DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_AFFINITY_DIALOG), hMainWnd, AffinityDialogWndProc);
350 351 352 353 354
    if (hProcessAffinityHandle)    {
        CloseHandle(hProcessAffinityHandle);
        hProcessAffinityHandle = NULL;
    }
}