source: trunk/src/win32k/utils/Win32kCC.c@ 4174

Last change on this file since 4174 was 4164, checked in by bird, 25 years ago

Merged in the Grace branch. New Win32k!

File size: 22.2 KB
Line 
1/* $Id: Win32kCC.c,v 1.2 2000-09-02 21:08:22 bird Exp $
2 *
3 * Win32CC - Win32k Control Center.
4 *
5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11
12/*******************************************************************************
13* Defined Constants And Macros *
14*******************************************************************************/
15
16/*
17 * Private Window Messages
18 */
19#define WM_SETCONTROLS (WM_USER + 10)
20#define WM_QUERYCONTROLS (WM_USER + 11)
21
22
23/*
24 * Include defines
25 */
26#define INCL_DOSERRORS
27#define INCL_DOSFILEMGR
28#define INCL_DOSRESOURCES
29#define INCL_WINERRORS
30#define INCL_WINDIALOGS
31#define INCL_WINMESSAGEMGR
32#define INCL_WINSTDSPIN
33#define INCL_WINBUTTONS
34#define INCL_WINWINDOWMGR
35
36/*******************************************************************************
37* Header Files *
38*******************************************************************************/
39#include <os2.h>
40
41#include <string.h>
42#include <stdio.h>
43#include <stdarg.h>
44#include <malloc.h>
45
46#include <Win32k.h>
47#include <devSegDf.h> /* Win32k segment definitions. */
48#include <Options.h>
49
50#include "Win32kCC.h"
51
52
53
54/*******************************************************************************
55* Structures and Typedefs *
56*******************************************************************************/
57typedef struct _WIN32KCC
58{
59 HWND hwnd;
60 HAB hab;
61 BOOL fDirty;
62
63 K32OPTIONS Options;
64 K32OPTIONS NewOptions;
65 K32STATUS Status;
66
67} WIN32KCC, *PWIN32KCC;
68
69
70/*******************************************************************************
71* Global Variables *
72*******************************************************************************/
73BOOL fNotExit; /* Global variable used to stop WM_QUITS.
74 * As long as this is true the message
75 * loop will never exit, but ignore all
76 * WM_QUITs.
77 */
78
79/*******************************************************************************
80* Internal Functions *
81*******************************************************************************/
82MRESULT EXPENTRY Win32kCCDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
83BOOL Complain(HWND hwndOwner, int id, ...);
84PCSZ getLastErrorMsg(HAB hab);
85PSZ getMessage(ULONG id);
86
87
88
89
90/**
91 * Main function.
92 * (No parameters)
93 * @returns -1 WinInitialize failed.
94 * -2 Failed to create message queue.
95 * -3 Failed to load dialog.
96 * 0 Dialog was closed using cancel.
97 * 1 Dialog was close using ok.
98 */
99int main(void)
100{
101 HAB hab;
102 HMQ hmq;
103 ULONG rc = 0;
104 HWND hwnd;
105
106 /*
107 * Initialize PM.
108 */
109 hab = WinInitialize(0);
110 if (hab == NULLHANDLE)
111 {
112 return -1;
113 }
114
115 /*
116 * Create Message Queue.
117 */
118 hmq = WinCreateMsgQueue(hab, 0);
119 if (hmq == NULLHANDLE)
120 {
121 WinTerminate(hab);
122 return -2;
123 }
124
125 /*
126 * Init Win32k library.
127 */
128 rc = libWin32kInit();
129 if (rc != NO_ERROR)
130 {
131 switch (rc)
132 {
133 case ERROR_FILE_NOT_FOUND:
134 Complain(HWND_DESKTOP, IDS_ERR_WIN32K_NOT_LOADED);
135 break;
136
137 default:
138 Complain(HWND_DESKTOP, IDS_ERR_WIN32K_OPEN_FAILED, rc);
139 }
140 }
141
142 /*
143 * Load the dialog.
144 */
145 hwnd = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP,
146 Win32kCCDlgProc,
147 NULLHANDLE,
148 DL_WIN32KCC,
149 NULL);
150
151 /*
152 * Process the dialog.
153 */
154 if (hwnd != NULLHANDLE)
155 {
156 QMSG qmsg;
157 do
158 {
159 fNotExit = FALSE;
160 while(WinGetMsg(hab, &qmsg, NULLHANDLE, NULLHANDLE, NULLHANDLE))
161 WinDispatchMsg(hab, &qmsg);
162 } while (fNotExit);
163
164
165 }
166 else
167 {
168 Complain(HWND_DESKTOP,
169 IDS_ERR_DIALOGLOAD,
170 DL_WIN32KCC,
171 WinGetLastError(hab),
172 getLastErrorMsg(hab)
173 );
174 rc = -3;
175 }
176
177 /*
178 * Cleanup.
179 */
180 WinDestroyMsgQueue(hmq);
181 WinTerminate(hab);
182 libWin32kTerm();
183
184 return rc;
185}
186
187#pragma info(noord) /*remove annoying (and possible incorrect) messages on the MP* macros */
188
189/**
190 * Dialog procedure for the DL_WIN32KCC dialog.
191 * (See PMREF for the general specifications of this function.)
192 */
193MRESULT EXPENTRY Win32kCCDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
194{
195 PWIN32KCC pThis;
196
197
198 /*
199 * Get instance data pointer (pThis).
200 */
201 if (msg != WM_INITDLG)
202 {
203 pThis = (PWIN32KCC)WinQueryWindowPtr(hwnd, QWL_USER);
204 if (pThis == NULL)
205 return WinDefDlgProc(hwnd, msg, mp1, mp2);
206 }
207
208
209 /*
210 * Message switch.
211 */
212 switch (msg)
213 {
214 /*
215 * Sets the controls according to the data from win32k.
216 *
217 * mr: Focus changed or not.
218 * mp1: hwnd of dialog
219 * mp2: (user data) (NULL)
220 */
221 case WM_INITDLG:
222 {
223
224 /*
225 * Initiate controls (ie. behaviour not data).
226 * - Ranges of the info level spinbuttons.
227 * - Max length of the max heap size entry fields.
228 */
229 WinSendDlgItemMsg(hwnd, SB_LDR_PE_INFOLEVEL, SPBM_SETLIMITS, (MPARAM)4, (MPARAM)0);
230 WinSendDlgItemMsg(hwnd, SB_LDR_ELF_INFOLEVEL, SPBM_SETLIMITS, (MPARAM)4, (MPARAM)0);
231
232 WinSendDlgItemMsg(hwnd, SB_HEAP_RES_MAX, SPBM_SETLIMITS, (MPARAM)32678, (MPARAM)128);
233 WinSendDlgItemMsg(hwnd, SB_HEAP_SWP_MAX, SPBM_SETLIMITS, (MPARAM)32678, (MPARAM)128);
234
235
236 /*
237 * Init and set instance data.
238 */
239 pThis = malloc(sizeof(*pThis));
240 if (pThis == NULL)
241 {
242 /* complain, dismiss and return. */
243 Complain(hwnd, IDS_ERR_MALLOC_FAILED, __FILE__, __LINE__, __FUNCTION__);
244 WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
245 return FALSE;
246 }
247 pThis->hwnd = hwnd;
248 pThis->hab = WinQueryAnchorBlock(hwnd);
249 if (!WinSetWindowPtr(hwnd, QWL_USER, pThis))
250 {
251 /* complain, dismiss and return. */
252 Complain(hwnd, IDS_ERR_SET_INSTACEDATA,
253 WinGetLastError(pThis->hab),
254 getLastErrorMsg(pThis->hab));
255 WinDismissDlg(hwnd, 0);
256 WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
257 free(pThis);
258 return FALSE;
259 }
260
261 /*
262 * Send a set controls message which gets data from
263 * win32k and puts it into the controls.
264 */
265 WinSendMsg(hwnd, WM_SETCONTROLS, NULL, NULL);
266 break;
267 }
268
269
270 /*
271 * The user wants me to do something...
272 */
273 case WM_COMMAND:
274 switch (SHORT1FROMMP(mp1))
275 {
276 /*
277 * The user pushed the "Apply" button.
278 */
279 case PB_APPLY:
280 {
281 /* Check and get data from the dialog. */
282 if (WinSendMsg(hwnd, WM_QUERYCONTROLS, (MPARAM)TRUE, NULL)
283 && pThis->fDirty
284 )
285 {
286 APIRET rc;
287 rc = libWin32kSetOptions(&pThis->NewOptions);
288 if (rc != NO_ERROR)
289 Complain(hwnd, IDS_ERR_SETPOPTIONS, rc);
290 WinSendMsg(hwnd, WM_SETCONTROLS, NULL, NULL);
291 }
292 }
293 break;
294
295
296 /*
297 * User pushed the "Refresh" button.
298 */
299 case PB_REFRESH:
300 WinSendMsg(hwnd, WM_SETCONTROLS, NULL, NULL);
301 break;
302
303
304 /*
305 * The user pushed the "Close" button.
306 */
307 case DID_OK:
308 /* Check if data is dirty */
309 if (!WinSendMsg(hwnd, WM_QUERYCONTROLS, (MPARAM)FALSE, NULL) || pThis->fDirty)
310 {
311 if (WinMessageBox(HWND_DESKTOP, hwnd,
312 getMessage(IDM_INFO_DIRTY),
313 "Win32k Control Center", 0, MB_YESNO | MB_WARNING | MB_MOVEABLE)
314 != MBID_YES)
315 {
316 fNotExit = TRUE;
317 return NULL;
318 }
319 }
320 /* Close the dialog */
321 fNotExit = FALSE;
322 WinDismissDlg(hwnd, 0);
323 WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
324 break;
325 }
326 return NULL;
327
328
329 /*
330 * Close window. Typically sent when Alt-F4 pressed or system-menu-Close is selected.
331 */
332 case WM_CLOSE:
333 fNotExit = TRUE;
334 WinSendMsg(hwnd, WM_COMMAND,
335 MPFROMSHORT(DID_OK), MPFROM2SHORT(CMDSRC_MENU, FALSE));
336 break;
337
338
339 /*
340 * Window is destroyed (last message which ever should reach us!)
341 * -Free instance data
342 * -Set the instance data pointer to NULL (just in case).
343 */
344 case WM_DESTROY:
345 {
346 free(pThis);
347 WinSetWindowPtr(hwnd, QWL_USER, NULL);
348 break;
349 }
350
351
352 /*
353 * Gets data from win32k.
354 * Sets the controls according to the data from win32k.
355 *
356 * mr: reserved
357 * mp1: reserved
358 * mp2: reserved
359 */
360 case WM_SETCONTROLS:
361 {
362 APIRET rc;
363 CHAR szNumber[16];
364
365
366 /*
367 * Call Win32k.sys to get options and statuses.
368 */
369 memset(&pThis->Options, 0, sizeof(K32OPTIONS));
370 pThis->Options.cb = sizeof(K32OPTIONS);
371 memset(&pThis->Status, 0, sizeof(K32STATUS));
372 pThis->Status.cb = sizeof(K32STATUS);
373 rc = libWin32kQueryOptionsStatus(&pThis->Options, &pThis->Status);
374 if (rc != NO_ERROR)
375 {
376 Complain(hwnd, IDS_ERR_QUERYOPTIONSTATUS, rc);
377 fNotExit = FALSE;
378 WinDismissDlg(hwnd, 0);
379 WinPostMsg(hwnd, WM_QUIT, NULL, NULL);
380 return NULL;
381 }
382
383 /*
384 * Set the controls.
385 */
386 /* logging */
387 WinSendDlgItemMsg(hwnd, CB_LOGGING_ENABLED, BM_SETCHECK, (MPARAM)(pThis->Options.fLogging), NULL);
388 WinSendDlgItemMsg(hwnd, RB_LOGGING_COM1, BM_SETCHECK, (MPARAM)(pThis->Options.usCom == 0x3f8), NULL);
389 WinSendDlgItemMsg(hwnd, RB_LOGGING_COM2, BM_SETCHECK, (MPARAM)(pThis->Options.usCom == 0x2f8), NULL);
390 WinSendDlgItemMsg(hwnd, RB_LOGGING_COM3, BM_SETCHECK, (MPARAM)(pThis->Options.usCom == 0x3e8), NULL);
391 WinSendDlgItemMsg(hwnd, RB_LOGGING_COM4, BM_SETCHECK, (MPARAM)(pThis->Options.usCom == 0x2e8), NULL);
392
393 /* loaders */
394 WinSendDlgItemMsg(hwnd, CB_LDR_DISABLE_ALL, BM_SETCHECK, (MPARAM)(pThis->Options.fNoLoader), NULL);
395 /* PE */
396 WinSendDlgItemMsg(hwnd, RB_LDR_PE_PURE, BM_SETCHECK, (MPARAM)(pThis->Options.fPE == FLAGS_PE_PE2LX), NULL);
397 WinSendDlgItemMsg(hwnd, RB_LDR_PE_MIXED, BM_SETCHECK, (MPARAM)(pThis->Options.fPE == FLAGS_PE_MIXED), NULL);
398 WinSendDlgItemMsg(hwnd, RB_LDR_PE_PE, BM_SETCHECK, (MPARAM)(pThis->Options.fPE == FLAGS_PE_PE), NULL);
399 WinSendDlgItemMsg(hwnd, RB_LDR_PE_NOT, BM_SETCHECK, (MPARAM)(pThis->Options.fPE == FLAGS_PE_NOT), NULL);
400 WinSendDlgItemMsg(hwnd, SB_LDR_PE_INFOLEVEL, SPBM_SETCURRENTVALUE, (MPARAM)(pThis->Options.ulInfoLevel), NULL); /* FIXME to be changed */
401 /* Elf */
402 WinSendDlgItemMsg(hwnd, CB_LDR_ELF_ENABLED, BM_SETCHECK, (MPARAM)(pThis->Options.fElf), NULL);
403 WinSendDlgItemMsg(hwnd, SB_LDR_ELF_INFOLEVEL, SPBM_SETCURRENTVALUE, (MPARAM)(pThis->Options.ulInfoLevel), NULL); /* FIXME to be changed */
404 /* UNIX Shell Scripts */
405 WinSendDlgItemMsg(hwnd, CB_LDR_SHELL_SCRIPTS, BM_SETCHECK, (MPARAM)(pThis->Options.fUNIXScript), NULL);
406 /* JAVA */
407 WinSendDlgItemMsg(hwnd, CB_LDR_JAVA, BM_SETCHECK, (MPARAM)(pThis->Options.fJava), NULL);
408 /* REXX Scripts */
409 WinSendDlgItemMsg(hwnd, CB_LDR_REXX, BM_SETCHECK, (MPARAM)(pThis->Options.fREXXScript), NULL);
410
411 /* heaps */
412 /* Resident */
413 WinSendDlgItemMsg(hwnd, SB_HEAP_RES_MAX, SPBM_SETCURRENTVALUE, (MPARAM)(pThis->Options.cbResHeapMax / 1024), NULL);
414 sprintf(szNumber, "%d", pThis->Status.cbResHeapInit / 1024);
415 WinSetDlgItemText(hwnd, TX_HEAP_RES_INIT_VAL, szNumber);
416 sprintf(szNumber, "%d", pThis->Status.cbResHeapUsed / 1024);
417 WinSetDlgItemText(hwnd, TX_HEAP_RES_USED_VAL, szNumber);
418 /* Swappable */
419 WinSendDlgItemMsg(hwnd, SB_HEAP_SWP_MAX, SPBM_SETCURRENTVALUE, (MPARAM)(pThis->Options.cbSwpHeapMax / 1024), NULL);
420 sprintf(szNumber, "%d", pThis->Status.cbSwpHeapInit / 1024);
421 WinSetDlgItemText(hwnd, TX_HEAP_SWP_INIT_VAL, szNumber);
422 sprintf(szNumber, "%d", pThis->Status.cbSwpHeapUsed / 1024);
423 WinSetDlgItemText(hwnd, TX_HEAP_SWP_USED_VAL, szNumber);
424
425 pThis->fDirty = FALSE;
426 return NULL;
427 }
428
429
430 /*
431 * Validate data in the controls. Complains accoring to mp1.
432 * Put the data into the win32k option struct.
433 *
434 * mr: Valid indicator.
435 * TRUE: Valid data.
436 * FALSE: Not valid data.
437 * mp1: BOOL fComplain.
438 * TRUE: Do complain about errors. The pThis->Options struct
439 * is updated on successful return.
440 * FALSE: Do not complain about errors, and don't update the
441 * pThis->Options struct.
442 * mp2: reserved.
443 */
444 case WM_QUERYCONTROLS:
445 {
446 BOOL fComplain = (BOOL)mp1;
447 ULONG ul;
448
449 /*
450 * Init temporary option struct.
451 */
452 memset(&pThis->NewOptions, 0, sizeof(K32OPTIONS));
453 pThis->NewOptions.cb = sizeof(K32OPTIONS);
454
455 /*
456 * Logging.
457 */
458 pThis->NewOptions.fLogging = WinSendDlgItemMsg(hwnd, CB_LOGGING_ENABLED, BM_QUERYCHECK, NULL, NULL) != 0;
459 if (WinSendDlgItemMsg(hwnd, RB_LOGGING_COM1, BM_QUERYCHECK, NULL, NULL))
460 pThis->NewOptions.usCom = 0x3f8;
461 else if (WinSendDlgItemMsg(hwnd, RB_LOGGING_COM2, BM_QUERYCHECK, NULL, NULL))
462 pThis->NewOptions.usCom = 0x2f8;
463 else if (WinSendDlgItemMsg(hwnd, RB_LOGGING_COM3, BM_QUERYCHECK, NULL, NULL))
464 pThis->NewOptions.usCom = 0x3e8;
465 else if (WinSendDlgItemMsg(hwnd, RB_LOGGING_COM4, BM_QUERYCHECK, NULL, NULL))
466 pThis->NewOptions.usCom = 0x2e8;
467 else
468 {
469 if (fComplain)
470 Complain(hwnd, IDS_ERR_NO_COM_RADIOBUTTON);
471 return (MPARAM)FALSE;
472 }
473
474 /*
475 * Loaders
476 */
477 pThis->NewOptions.fNoLoader = WinSendDlgItemMsg(hwnd, CB_LDR_DISABLE_ALL, BM_QUERYCHECK, NULL, NULL) != 0;
478 /* PE */
479 if (WinSendDlgItemMsg(hwnd, RB_LDR_PE_PURE, BM_QUERYCHECK, NULL, NULL))
480 pThis->NewOptions.fPE = FLAGS_PE_PE2LX;
481 else if (WinSendDlgItemMsg(hwnd, RB_LDR_PE_MIXED, BM_QUERYCHECK, NULL, NULL))
482 pThis->NewOptions.fPE = FLAGS_PE_MIXED;
483 else if (WinSendDlgItemMsg(hwnd, RB_LDR_PE_PE, BM_QUERYCHECK, NULL, NULL))
484 pThis->NewOptions.fPE = FLAGS_PE_PE;
485 else if (WinSendDlgItemMsg(hwnd, RB_LDR_PE_NOT, BM_QUERYCHECK, NULL, NULL))
486 pThis->NewOptions.fPE = FLAGS_PE_NOT;
487 else
488 {
489 if (fComplain)
490 Complain(hwnd, IDS_ERR_NO_PE_RADIOBUTTON);
491 return (MPARAM)FALSE;
492 }
493 if (!WinSendDlgItemMsg(hwnd, SB_LDR_PE_INFOLEVEL, SPBM_QUERYVALUE, (MPARAM)&ul, MPFROM2SHORT(0, SPBQ_UPDATEIFVALID)))
494 {
495 if (fComplain)
496 {
497 Complain(hwnd, IDS_ERR_INVALID_INFOLEVEL);
498 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, SB_LDR_PE_INFOLEVEL));
499 }
500 return (MPARAM)FALSE;
501 }
502 pThis->NewOptions.ulInfoLevel = ul; /* FIXME to be changed */
503
504 /* Elf */
505 pThis->NewOptions.fElf = WinSendDlgItemMsg(hwnd, CB_LDR_ELF_ENABLED, BM_QUERYCHECK, NULL, NULL) != 0;
506 if (!WinSendDlgItemMsg(hwnd, SB_LDR_ELF_INFOLEVEL, SPBM_QUERYVALUE, (MPARAM)&ul, MPFROM2SHORT(0, SPBQ_UPDATEIFVALID)))
507 {
508 if (fComplain)
509 {
510 Complain(hwnd, IDS_ERR_INVALID_INFOLEVEL);
511 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, SB_LDR_ELF_INFOLEVEL));
512 }
513 return (MPARAM)FALSE;
514 }
515 //pThis->NewOptions.ulInfoLevel = ul; /* FIXME to be changed */
516 /* UNIX Shell Scripts */
517 pThis->NewOptions.fUNIXScript = WinSendDlgItemMsg(hwnd, CB_LDR_SHELL_SCRIPTS, BM_QUERYCHECK, NULL, NULL) != 0;
518 /* JAVA */
519 pThis->NewOptions.fJava = WinSendDlgItemMsg(hwnd, CB_LDR_JAVA, BM_QUERYCHECK, NULL, NULL) != 0;
520 /* REXX Scripts */
521 pThis->NewOptions.fREXXScript = WinSendDlgItemMsg(hwnd, CB_LDR_REXX, BM_QUERYCHECK, NULL, NULL) != 0;
522
523 /*
524 * Heaps
525 */
526 /* Resident */
527 if (!WinSendDlgItemMsg(hwnd, SB_HEAP_RES_MAX, SPBM_QUERYVALUE, (MPARAM)&ul, MPFROM2SHORT(0, SPBQ_UPDATEIFVALID)))
528 {
529 if (fComplain)
530 {
531 Complain(hwnd, IDS_ERR_INVALID_MAXHEAPSIZE);
532 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, SB_HEAP_RES_MAX));
533 }
534 return (MPARAM)FALSE;
535 }
536 pThis->NewOptions.cbResHeapMax = ul*1024;
537 /* Swappable */
538 if (!WinSendDlgItemMsg(hwnd, SB_HEAP_SWP_MAX, SPBM_QUERYVALUE, (MPARAM)&ul, MPFROM2SHORT(0, SPBQ_UPDATEIFVALID)))
539 {
540 if (fComplain)
541 {
542 Complain(hwnd, IDS_ERR_INVALID_MAXHEAPSIZE);
543 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, SB_HEAP_SWP_MAX));
544 }
545 return (MPARAM)FALSE;
546 }
547 pThis->NewOptions.cbSwpHeapMax = ul*1024;
548
549 /*
550 * Check if there is any change and set the fDirty flag accordingly.
551 */
552 pThis->fDirty = memcmp(&pThis->NewOptions, &pThis->Options, sizeof(K32OPTIONS)) != 0;
553 return (MPARAM)TRUE;
554 }
555
556
557 }
558
559 /*
560 * Return thru the default dialog procedure.
561 */
562 return WinDefDlgProc(hwnd, msg, mp1, mp2);
563}
564
565
566/**
567 * Pops up a message box displaying some complaint or error.
568 * @returns Success indicator.
569 * @param hwndOwner Handle of owner window.
570 * @param id String table id of the message.
571 * @param ... Arguments passed on to vsprintf to format the message.
572 */
573BOOL Complain(HWND hwndOwner, int id, ...)
574{
575 ULONG rc;
576 char szMsg[1024];
577 char szMsgOutput[4096];
578
579
580 /*
581 * Load the string and format it.
582 */
583 if (WinLoadString(WinQueryAnchorBlock(hwndOwner), 0, id, sizeof(szMsg), szMsg))
584 {
585 va_list args;
586 va_start(args, id);
587 vsprintf(szMsgOutput, szMsg, args);
588 va_end(args);
589 }
590 else
591 sprintf(szMsgOutput, "Failed to load the message id %id.\n", id);
592
593
594 /*
595 * Show message.
596 */
597 rc = WinMessageBox(HWND_DESKTOP, hwndOwner,
598 szMsgOutput,
599 "Win32k Control Center - error",
600 0,
601 MB_APPLMODAL | MB_ICONHAND | MB_OK | MB_MOVEABLE);
602 if (rc == (ULONG)MBID_ERROR)
603 {
604 rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
605 szMsgOutput,
606 "Win32k Control Center - error",
607 0,
608 MB_ICONHAND | MB_OK | MB_MOVEABLE);
609 }
610
611
612 /*
613 * Return according to rc.
614 */
615 return rc != MBID_ERROR;
616}
617
618
619/**
620 * Gets the message string for the last error message.
621 * @returns Pointer to message string.
622 * @param hab Handle of application anchor block.
623 */
624PCSZ getLastErrorMsg(HAB hab)
625{
626 char *pszErrInfo;
627 PERRINFO pErrInfo = WinGetErrorInfo(hab);
628
629 if (pErrInfo != NULL && pErrInfo->cDetailLevel > 0)
630 {
631 pszErrInfo = (char*)(void*)pErrInfo;
632 pszErrInfo += ((PUSHORT)(void*)(pszErrInfo + pErrInfo->offaoffszMsg))[pErrInfo->cDetailLevel-1];
633 }
634 else
635 pszErrInfo = "<none>";
636
637 return pszErrInfo;
638}
639
640
641/**
642 * Gets a message from the executable resources.
643 * @returns Pointer to read-only string.
644 * NULL if not found/error.
645 * @param id String Id.
646 */
647PSZ getMessage(ULONG id)
648{
649 PSZ psz;
650
651 if (DosGetResource(NULLHANDLE, RT_MESSAGE, id / 16 + 1, (PPVOID)(void*)&psz) == NO_ERROR)
652 {
653 psz +=2;
654 id %= 16;
655 while (id-- > 0)
656 psz += 1 + *psz;
657 return psz+1;
658 }
659 else
660 psz = NULL;
661
662 return psz;
663}
664
665
Note: See TracBrowser for help on using the repository browser.