2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
13 #include <afs/param.h>
26 /* global instance for test program */
29 /* global window for debugging */
32 /* binding handle we're connected to */
33 RPC_BINDING_HANDLE main_remoteHandle
;
35 /* cache of formatting info */
36 main_formatCache_t
*main_allFormatsp
;
38 /* file name from dialog box */
39 char main_fileName
[256];
41 /* screen display image size */
42 RECT screenRect
; /* whole screen */
44 RECT cb1Rect
; /* button for first command */
46 RECT cb2Rect
; /* button for 2nd command */
48 RECT cb3Rect
; /* guess */
50 RECT cb4Rect
; /* guess */
52 RECT nameRect
; /* the edit name rectangle */
54 RECT typesRect
; /* types rectangle */
56 RECT resultsRect
; /* results rectangle */
58 RECT statusRect
; /* status line */
61 /* height of a text line */
64 /* function to divide up the screen space among the rectangles */
65 void main_Layout(HWND hWnd
)
70 /* make the screen have 4 buttons on the top, then then name under
71 * that, and the results below that.
72 * NB ALL RECTS store width and height instead of right and bottom
74 GetClientRect(hWnd
, &screenRect
);
75 buttonWidth
= screenRect
.right
/ 4;
76 stripeHeight
= screenRect
.bottom
/ 10;
79 cb1Rect
.bottom
= stripeHeight
;
81 cb1Rect
.right
= buttonWidth
;
84 cb2Rect
.bottom
= stripeHeight
;
85 cb2Rect
.left
= buttonWidth
;
86 cb2Rect
.right
= buttonWidth
;
89 cb3Rect
.bottom
= stripeHeight
;
90 cb3Rect
.left
= 2*buttonWidth
;
91 cb3Rect
.right
= buttonWidth
;
94 cb4Rect
.bottom
= stripeHeight
;
95 cb4Rect
.left
= 3*buttonWidth
;
96 cb4Rect
.right
= buttonWidth
;
98 nameRect
.top
= stripeHeight
;
99 nameRect
.bottom
= (3*lineHeight
)/2;
101 nameRect
.right
= (80*screenRect
.right
)/100;
103 statusRect
.top
= screenRect
.bottom
- (3*lineHeight
)/2;
104 statusRect
.bottom
= (3*lineHeight
)/2;
106 statusRect
.right
= screenRect
.right
;
108 /* what's left goes to the results and type frames */
109 resultsRect
.top
= nameRect
.bottom
+ stripeHeight
;
110 resultsRect
.bottom
= screenRect
.bottom
-resultsRect
.top
-statusRect
.bottom
;
111 resultsRect
.left
= screenRect
.right
/3;
112 resultsRect
.right
= (2*screenRect
.right
)/3;
114 typesRect
.top
= nameRect
.bottom
+ stripeHeight
;
115 typesRect
.bottom
= screenRect
.bottom
-typesRect
.top
-statusRect
.bottom
;
117 typesRect
.right
= screenRect
.right
/3;
120 /****************************************************************************
122 FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
124 PURPOSE: calls initialization function, processes message loop
126 ****************************************************************************/
128 int APIENTRY
WinMain(
130 HANDLE hPrevInstance
,
138 if (!InitApplication(hInstance
))
141 if (!InitInstance(hInstance
, nCmdShow
))
144 while (GetMessage(&msg
, NULL
, 0, 0)) {
145 TranslateMessage(&msg
);
146 DispatchMessage(&msg
);
152 /****************************************************************************
154 FUNCTION: InitApplication(HANDLE)
156 PURPOSE: Initializes window data and registers window class
158 ****************************************************************************/
160 BOOL
InitApplication(HANDLE hInstance
)
164 /* create window class */
165 wc
.style
= CS_DBLCLKS
; /* double-click messages */
166 wc
.lpfnWndProc
= (WNDPROC
) MainWndProc
;
169 wc
.hInstance
= hInstance
;
170 wc
.hIcon
= LoadIcon(NULL
, IDI_APPLICATION
);
171 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
172 wc
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
173 wc
.lpszMenuName
= "InputMenu";
174 wc
.lpszClassName
= "InputWClass";
176 return (RegisterClass(&wc
));
180 /****************************************************************************
182 FUNCTION: InitInstance(HANDLE, int)
184 PURPOSE: Saves instance handle and creates main window
186 ****************************************************************************/
194 TEXTMETRIC textmetric
;
198 /* create window itself */
201 "OSI Remote Debugging Application",
202 WS_OVERLAPPEDWINDOW
, /* horz & vert scroll bars */
217 GetTextMetrics(hDC
, &textmetric
);
218 lineHeight
= textmetric
.tmExternalLeading
+ textmetric
.tmHeight
;
219 ReleaseDC(hWnd
, hDC
);
221 main_allFormatsp
= NULL
;
225 /* now create children */
226 cb1Wnd
= CreateWindow("button", "Debug Server",
228 cb1Rect
.left
, cb1Rect
.top
, cb1Rect
.right
, cb1Rect
.bottom
,
229 hWnd
, (void *) IDM_CMD1
, hInst
, 0);
231 cb2Wnd
= CreateWindow("button", "Quit",
233 cb2Rect
.left
, cb2Rect
.top
, cb2Rect
.right
, cb2Rect
.bottom
,
234 hWnd
, (void *) IDM_CMD2
, hInst
, 0);
236 cb3Wnd
= CreateWindow("button", "Save to file",
238 cb3Rect
.left
, cb3Rect
.top
, cb3Rect
.right
, cb3Rect
.bottom
,
239 hWnd
, (void *) IDM_CMD3
, hInst
, 0);
241 cb4Wnd
= CreateWindow("button", "[Future 1]",
243 cb4Rect
.left
, cb4Rect
.top
, cb4Rect
.right
, cb4Rect
.bottom
,
244 hWnd
, (void *) IDM_CMD4
, hInst
, 0);
246 nameWnd
= CreateWindow("edit", "milkyway:1",
247 WS_CHILD
|WS_VISIBLE
|WS_BORDER
|ES_LEFT
,
248 nameRect
.left
, nameRect
.top
, nameRect
.right
, nameRect
.bottom
,
249 hWnd
, (void *) IDM_NAME
, hInst
, 0);
251 typesWnd
= CreateWindow("listbox", "Collections",
252 WS_CHILD
|WS_VISIBLE
| WS_CAPTION
| LBS_STANDARD
,
253 typesRect
.left
, typesRect
.top
, typesRect
.right
, typesRect
.bottom
,
254 hWnd
, (void *) IDM_TYPES
, hInst
, 0);
256 resultsWnd
= CreateWindow("listbox", "Results",
257 WS_CHILD
|WS_VISIBLE
| WS_CAPTION
| LBS_NOTIFY
|WS_VSCROLL
|WS_BORDER
,
258 resultsRect
.left
, resultsRect
.top
, resultsRect
.right
, resultsRect
.bottom
,
259 hWnd
, (void *) IDM_RESULTS
, hInst
, 0);
261 statusWnd
= CreateWindow("edit", "",
262 WS_CHILD
|WS_VISIBLE
|WS_BORDER
,
263 statusRect
.left
, statusRect
.top
, statusRect
.right
, statusRect
.bottom
,
264 hWnd
, (void *) IDM_STATUS
, hInst
, 0);
266 ShowWindow(hWnd
, nCmdShow
);
272 main_formatCache_t
*main_GetFormatCache(RPC_BINDING_HANDLE handle
, char *typep
,
273 long region
, long index
)
275 main_formatCache_t
*fcp
;
277 osi_remFormat_t format
;
279 for(fcp
= main_allFormatsp
; fcp
; fcp
= fcp
->nextp
) {
280 if (strcmp(typep
, fcp
->typep
) == 0 && fcp
->region
== region
281 && fcp
->index
== index
) {
282 /* found info, so return yes or not based
283 * upon whether there's a label.
285 if (fcp
->labelp
) return fcp
;
290 /* if we get here, we don't have a definitive answer; try to get one */
292 dbrpc_GetFormat(handle
, typep
, region
, index
, &format
, &code
);
295 code
= RpcExceptionCode();
299 /* now, if code is 0 we win, and 1 means we know the entry doesn't exist.
300 * otherwise, we've failed and return such.
302 if (code
== 0 || code
== 1) {
303 fcp
= (main_formatCache_t
*) malloc(sizeof(*fcp
));
304 fcp
->typep
= (char *) malloc(strlen(typep
)+1);
305 strcpy(fcp
->typep
, typep
);
306 fcp
->region
= region
;
309 fcp
->labelp
= (char *) malloc(strlen(format
.label
)+1);
310 strcpy(fcp
->labelp
, format
.label
);
312 else fcp
->labelp
= NULL
; /* no such entry */
313 fcp
->format
= format
.format
;
315 /* now thread it on */
316 fcp
->nextp
= main_allFormatsp
;
317 main_allFormatsp
= fcp
;
318 if (fcp
->labelp
) return fcp
;
325 /* take a name and return a working binding to the server. Server must be
326 * exporting a dbrpc interface.
328 main_GetBinding(char *name
, RPC_BINDING_HANDLE
*handlep
)
330 RPC_NS_HANDLE tempContext
; /* context used for iteration */
331 RPC_BINDING_HANDLE thp
; /* temp handle we're using now */
336 code
= RpcNsBindingImportBegin(RPC_C_NS_SYNTAX_DCE
, name
, *dbrpc_v1_0_c_ifspecp
,
337 (UUID
*) 0, &tempContext
);
338 if (code
!= RPC_S_OK
) return code
;
340 /* this next line is useful when trying to debug things */
341 // RpcNsMgmtHandleSetExpAge(tempContext, 0);
343 valid
= 0; /* is thp valid? */
345 code
= RpcNsBindingImportNext(tempContext
, &thp
);
346 if (code
== RPC_S_NO_MORE_BINDINGS
) break; /* we're done */
348 if (code
!= RPC_S_OK
) {
349 RpcNsBindingImportDone(&tempContext
);
353 /* otherwise we have a putatively good binding; try it out
354 * with the probe interface and see if it really works
356 code
= RpcMgmtSetComTimeout(thp
, 2);
363 code
= RpcExceptionCode();
367 /* now, if call worked, we're done */
368 if (code
== 0) break;
370 /* else cleanup the binding and try again */
371 RpcBindingFree(&thp
);
374 /* cleanup and return */
375 RpcNsBindingImportDone(&tempContext
);
381 main_GetBinding(char *hostNamep
, UUID
*exportIDp
, RPC_BINDING_HANDLE
*handlep
)
383 char *stringBindingp
;
385 RPC_BINDING_HANDLE handle
;
387 code
= RpcStringBindingCompose(NULL
, "ncacn_ip_tcp", hostNamep
, NULL
, NULL
,
389 if (code
) return code
;
391 code
= RpcBindingFromStringBinding(stringBindingp
, &handle
);
394 code
= RpcMgmtSetComTimeout(handle
, /* short, but not too short, timeout */ 3);
396 RpcBindingFree(&handle
);
400 code
= RpcBindingSetObject(handle
, exportIDp
);
402 RpcBindingFree(&handle
);
410 RpcStringFree(&stringBindingp
);
414 main_RetrieveType(char *typep
, RPC_BINDING_HANDLE remoteHandle
, HWND hlistBox
, int drawSeparator
)
419 osi_remGetInfoParms_t status
;
421 main_formatCache_t
*fcp
;
426 /* setup separator */
427 wsprintf(separator
, "====");
429 /* now lookup available stats collections by opening "type" well-known
433 dbrpc_Open(remoteHandle
, typep
, &fd
, &code
);
436 code
= RpcExceptionCode();
444 /* now iterate over all info */
448 dbrpc_GetInfo(remoteHandle
, &fd
, &status
, &code
);
451 code
= RpcExceptionCode();
455 if (code
!= 0) break;
457 /* draw separator, if we should. DrawSeparator tells us if
458 * we generally should do it, and addedAny, as a hack, tell us
459 * also if we're in the first pass or not, due to the fact
460 * that we don't set it until below.
462 if (drawSeparator
&& addedAny
)
463 SendMessage(hlistBox
, LB_ADDSTRING
, 0, (long) separator
);
465 /* we know there's something there */
468 /* put out all the strings */
469 for(i
=0; i
<status
.scount
; i
++) {
470 fcp
= main_GetFormatCache(remoteHandle
, typep
,
471 OSI_DBRPC_REGIONSTRING
, i
);
473 wsprintf(tstring
, "%s: %s", fcp
->labelp
, status
.sdata
[i
]);
475 wsprintf(tstring
, "%s", status
.sdata
[i
]);
476 SendMessage(hlistBox
, LB_ADDSTRING
, 0, (long) tstring
);
479 /* put out all the integers */
480 for(i
=0; i
<status
.icount
; i
++) {
481 fcp
= main_GetFormatCache(remoteHandle
, typep
,
482 OSI_DBRPC_REGIONINT
, i
);
484 if (fcp
->format
& OSI_DBRPC_HEX
)
485 wsprintf(tstring
, "%s: 0x%x", fcp
->labelp
, status
.idata
[i
]);
486 else if (fcp
->format
& OSI_DBRPC_SIGNED
)
487 wsprintf(tstring
, "%s: %d", fcp
->labelp
, status
.idata
[i
]);
489 wsprintf(tstring
, "%s: %u", fcp
->labelp
, status
.idata
[i
]);
491 wsprintf(tstring
, "%u", status
.idata
[i
]);
492 SendMessage(hlistBox
, LB_ADDSTRING
, 0, (long) tstring
);
497 SendMessage(hlistBox
, LB_ADDSTRING
, 0, (long) "[No entries]");
499 /* finally close the FD */
501 dbrpc_Close(remoteHandle
, &fd
, &closeCode
);
504 closeCode
= RpcExceptionCode();
508 /* now, we succeed if code is 0 or EOF */
509 if (code
== 0 || code
== OSI_DBRPC_EOF
) return 0;
513 /****************************************************************************
515 FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
517 PURPOSE: Processes messages
519 ****************************************************************************/
521 LONG APIENTRY
MainWndProc(
529 HDC hDC
; /* display-context variable */
530 PAINTSTRUCT ps
; /* paint structure */
539 if (LOWORD(wParam
) == IDM_ABOUT
) {
540 lpProcAbout
= (FARPROC
) About
;
549 if (LOWORD(wParam
) == IDM_HELP
) {
550 WinHelp(hWnd
, "osidebug.hlp", HELP_CONTENTS
, 0L);
553 if (LOWORD(wParam
) == IDM_CMD1
) {
560 SendMessage(typesWnd
, LB_RESETCONTENT
, 0, 0);
561 SendMessage(resultsWnd
, LB_RESETCONTENT
, 0, 0);
562 GetWindowText(nameWnd
, tbuffer
, sizeof(tbuffer
));
563 if (main_remoteHandle
!= NULL
) {
564 RpcBindingFree(&main_remoteHandle
);
565 main_remoteHandle
= NULL
;
568 /* parse milkyway:3 into host milkyway, UUID 3 */
569 strcpy(hostName
, tbuffer
);
570 tp
= strrchr(hostName
, ':');
575 osi_LongToUID(longID
, &exportID
);
578 osi_LongToUID(0, &exportID
);
580 code
= main_GetBinding(hostName
, &exportID
, &main_remoteHandle
);
582 code
= main_RetrieveType("type", main_remoteHandle
, typesWnd
, 0);
584 wsprintf(tbuffer
, "Can't obtain collection names, code %d",
586 main_SetStatus(tbuffer
);
588 else main_SetStatus("Done.");
591 wsprintf(tbuffer
, "Bind failed, code %d", code
);
592 main_SetStatus(tbuffer
);
594 InvalidateRect(hWnd
, &screenRect
, TRUE
);
596 else if (LOWORD(wParam
) == IDM_CMD2
) {
600 else if (LOWORD(wParam
) == IDM_CMD3
) {
604 (FARPROC
) FileProc
) == FALSE
) break;
606 /* otherwise we have a file name, so go on */
607 fileHandle
= CreateFile(main_fileName
,
608 GENERIC_READ
| GENERIC_WRITE
,
612 FILE_ATTRIBUTE_NORMAL
,
613 /* template */ NULL
);
614 if (fileHandle
== INVALID_HANDLE_VALUE
) break;
615 for(index
=0;;index
++) {
616 code
= SendMessage(resultsWnd
, LB_GETTEXT
, index
, (long) tbuffer
);
617 if (code
== LB_ERR
) break;
618 strcat(tbuffer
, "\n");
619 WriteFile(fileHandle
, tbuffer
, strlen(tbuffer
), &junk
, NULL
);
620 } /* for loop writing out data */
621 CloseHandle(fileHandle
);
624 else if (LOWORD(wParam
) == IDM_CMD4
) {
626 main_SetStatus("Future 1 not implemented");
628 else if (LOWORD(wParam
) == IDM_TYPES
) {
629 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
630 /* if we get here, someone selected a collection to retrieve */
631 SendMessage(resultsWnd
, LB_RESETCONTENT
, 0, 0);
632 index
= SendMessage(typesWnd
, LB_GETCURSEL
, 0, 0);
633 if (index
!= LB_ERR
|| main_remoteHandle
== NULL
) {
634 SendMessage(typesWnd
, LB_GETTEXT
, index
, (long) tbuffer
);
635 code
=main_RetrieveType(tbuffer
, main_remoteHandle
, resultsWnd
, 1);
637 wsprintf(tbuffer
, "Can't fetch collection, code %d", code
);
638 main_SetStatus(tbuffer
);
640 else main_SetStatus("Done.");
642 else main_SetStatus("Internal inconsistency finding selection!");
646 return (DefWindowProc(hWnd
, message
, wParam
, lParam
));
650 /* make kids draw, too */
651 InvalidateRect(hWnd
, &screenRect
, TRUE
);
653 hDC
= BeginPaint (hWnd
, &ps
);
654 /* nothing to draw, right? */
660 MoveWindow(cb1Wnd
, cb1Rect
.left
, cb1Rect
.top
, cb1Rect
.right
, cb1Rect
.bottom
, 1);
661 MoveWindow(cb2Wnd
, cb2Rect
.left
, cb2Rect
.top
, cb2Rect
.right
, cb2Rect
.bottom
, 1);
662 MoveWindow(cb3Wnd
, cb3Rect
.left
, cb3Rect
.top
, cb3Rect
.right
, cb3Rect
.bottom
, 1);
663 MoveWindow(cb4Wnd
, cb4Rect
.left
, cb4Rect
.top
, cb4Rect
.right
, cb4Rect
.bottom
, 1);
664 MoveWindow(nameWnd
, nameRect
.left
, nameRect
.top
, nameRect
.right
, nameRect
.bottom
, 1);
665 MoveWindow(statusWnd
, statusRect
.left
, statusRect
.top
, statusRect
.right
,
666 statusRect
.bottom
, 1);
667 MoveWindow(typesWnd
, typesRect
.left
, typesRect
.top
, typesRect
.right
,
668 typesRect
.bottom
, 1);
669 MoveWindow(resultsWnd
, resultsRect
.left
, resultsRect
.top
, resultsRect
.right
,
670 resultsRect
.bottom
, 1);
678 return (DefWindowProc(hWnd
, message
, wParam
, lParam
));
684 /****************************************************************************
686 FUNCTION: About(HWND, unsigned, WORD, LONG)
688 PURPOSE: Processes messages for "About" dialog box
692 WM_INITDIALOG - initialize dialog box
693 WM_COMMAND - Input received
695 ****************************************************************************/
697 BOOL APIENTRY
FileProc(
708 DlgDirList(hDlg
, "*.*", IDM_FILEBOX
, IDM_FILENAME
, DDL_DIRECTORY
|DDL_DRIVES
);
712 if (LOWORD(wParam
) == IDOK
) {
713 GetDlgItemText(hDlg
, IDM_FILENAME
, main_fileName
, sizeof(main_fileName
));
714 EndDialog(hDlg
, TRUE
);
717 else if (LOWORD(wParam
) == IDCANCEL
) {
718 EndDialog(hDlg
, FALSE
);
721 else if (LOWORD(wParam
) == IDM_FILEBOX
) {
722 switch (HIWORD(wParam
)) {
724 code
= DlgDirSelectEx(hDlg
, tname
, sizeof(tname
), IDM_FILEBOX
);
726 /* have a selection */
727 strcpy(main_fileName
, tname
);
728 EndDialog(hDlg
, TRUE
);
732 DlgDirList(hDlg
, tname
, IDM_FILEBOX
, IDM_FILENAME
, DDL_DIRECTORY
|DDL_DRIVES
);
741 UNREFERENCED_PARAMETER(lParam
);
755 if (LOWORD(wParam
) == IDOK
) {
756 EndDialog(hDlg
, TRUE
);
762 UNREFERENCED_PARAMETER(lParam
);
765 void main_SetStatus(char *status
)
767 SetWindowText(statusWnd
, status
);
768 InvalidateRect(statusWnd
, (RECT
*) 0, 1);
769 UpdateWindow(statusWnd
);