|
|
1.1 root 1: /****************************************************************************
2:
3: PROGRAM: whelloc.c
4:
5: PURPOSE: RPC sample Windows client
6: Based on Win 3.0 SDK Generic template for Windows applications
7:
8: FUNCTIONS:
9:
10: WinMain() - calls initialization function, processes message loop
11: InitApplication() - initializes window data and registers window
12: InitInstance() - saves instance handle and creates main window
13: MainWndProc() - processes messages
14: About() - processes messages for "About" dialog box
15: Server() - processes messages for "Server" dialog box
16: Endpoint() - processes messages for "Endpoint" dialog box
17: Send() - processes messages for "Send" dialog box; sends on OK
18: MIDL_user_allocate() - memory allocation function needed by RPC
19: MIDL_user_free() - memory free function needed by RPC
20:
21: COMMENTS:
22:
23: Windows can have several copies of your application running at the
24: same time. The variable hInst keeps track of which instance this
25: application is so that processing will be to the correct window.
26:
27: ****************************************************************************/
28:
29: #include <windows.h> /* required for all Win applications */
1.1.1.2 ! root 30: #include <windowsx.h> /* select between win16 or win32 */
1.1 root 31: #include <stdio.h>
32: #include <string.h>
33: #include <rpc.h> /* required for all RPC applications */
34: #include <rpcndr.h> /* required for all RPC applications */
35: #include "whello.h" /* the RPC interface definitions */
36: #include "whelloc.h" /* client-specific header file */
37:
38: HANDLE hInst; /* current instance */
39: HCURSOR hHourGlass, hOld; /* during calls to RPC API functions */
40: char pszFail[MSGLEN]; /* RPC API failure message */
41:
42: RPC_STATUS status; /* returned by RPC API function */
1.1.1.2 ! root 43: unsigned char * pszUuid = NULL;
1.1 root 44: unsigned char * pszProtocolSequence = "ncacn_np";
45: unsigned char szNetworkAddress[UNCLEN+1];
46: unsigned char szEndpoint[PATHLEN+1];
47: unsigned char * pszOptions = NULL;
48: unsigned char * pszStringBinding = NULL;
49: unsigned char szString[MSGLEN];
50: int fBound; /* flag indicates whether bound to svr */
51:
52: /****************************************************************************
53:
54: FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
55:
56: PURPOSE: calls initialization function, processes message loop
57:
58: COMMENTS:
59:
60: Windows recognizes this function by name as the initial entry point
61: for the program. This function calls the application initialization
62: routine, if no other instance of the program is running, and always
63: calls the instance initialization routine. It then executes a message
64: retrieval and dispatch loop that is the top-level control structure
65: for the remainder of execution. The loop is terminated when a WM_QUIT
66: message is received, at which time this function exits the application
67: instance by returning the value passed by PostQuitMessage().
68:
69: If this function must abort before entering the message loop, it
70: returns the conventional value NULL.
71:
72: ****************************************************************************/
73: int APIENTRY WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
74: HANDLE hInstance; /* current instance */
75: HANDLE hPrevInstance; /* previous instance */
76: LPSTR lpCmdLine; /* command line */
77: int nCmdShow; /* show-window type (open/icon) */
78: {
79: MSG msg; /* message */
80: UNREFERENCED_PARAMETER(lpCmdLine);
81:
82:
83: if (!hPrevInstance) /* Other instances of app running? */
84: if (!InitApplication(hInstance)) /* Initialize shared things */
85: return (FALSE); /* Exits if unable to initialize */
86:
87: /* Perform initializations that apply to a specific instance */
88:
89: if (!InitInstance(hInstance, nCmdShow))
90: return (FALSE);
91:
92: /* Acquire and dispatch messages until a WM_QUIT message is received. */
93:
94: while (GetMessage(&msg, /* message structure */
95: NULL, /* handle of window receiving the message */
96: NULL, /* lowest message to examine */
97: NULL)) /* highest message to examine */
98: {
99: TranslateMessage(&msg); /* Translates virtual key codes */
100: DispatchMessage(&msg); /* Dispatches message to window */
101: }
102:
103:
104: return (msg.wParam); /* Returns the value from PostQuitMessage */
105: }
106:
107:
108: /****************************************************************************
109:
110: FUNCTION: InitApplication(HANDLE)
111:
112: PURPOSE: Initializes window data and registers window class
113:
114: COMMENTS:
115:
116: This function is called at initialization time only if no other
117: instances of the application are running. This function performs
118: initialization tasks that can be done once for any number of running
119: instances.
120:
121: In this case, we initialize a window class by filling out a data
122: structure of type WNDCLASS and calling the Windows RegisterClass()
123: function. Since all instances of this application use the same window
124: class, we only need to do this when the first instance is initialized.
125:
126:
127: ****************************************************************************/
128:
129: BOOL InitApplication(hInstance)
130: HANDLE hInstance; /* current instance */
131: {
132: WNDCLASS wc;
133:
134: /* Fill in window class structure with parameters that describe the */
135: /* main window. */
136:
137: wc.style = NULL; /* Class style(s). */
138: wc.lpfnWndProc = (WNDPROC)MainWndProc; /* Function to retrieve messages for */
139: /* windows of this class. */
140: wc.cbClsExtra = 0; /* No per-class extra data. */
141: wc.cbWndExtra = 0; /* No per-window extra data. */
142: wc.hInstance = hInstance; /* Application that owns the class. */
143: wc.hIcon = LoadIcon(hInstance, "HelloIcon"); /* loads icon */
144: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
145: wc.hbrBackground = GetStockObject(WHITE_BRUSH);
146: wc.lpszMenuName = "GenericMenu"; /* Name of menu resource in .RC file. */
147: wc.lpszClassName = "GenericWClass"; /* Name used in call to CreateWindow. */
148:
149: /* Register the window class and return success/failure code. */
150:
151: return (RegisterClass(&wc));
152:
153: }
154:
155:
156: /****************************************************************************
157:
158: FUNCTION: InitInstance(HANDLE, int)
159:
160: PURPOSE: Saves instance handle and creates main window
161:
162: COMMENTS:
163:
164: This function is called at initialization time for every instance of
165: this application. This function performs initialization tasks that
166: cannot be shared by multiple instances.
167:
168: In this case, we save the instance handle in a static variable and
169: create and display the main program window.
170:
171: ****************************************************************************/
172:
173: BOOL InitInstance(hInstance, nCmdShow)
174: HANDLE hInstance; /* Current instance identifier. */
175: int nCmdShow; /* Param for first ShowWindow() call. */
176: {
177: HWND hWnd; /* Main window handle. */
178:
179:
180: /* Save the instance handle in static variable, which will be used in */
181: /* many subsequence calls from this application to Windows. */
182:
183: hInst = hInstance;
184: hHourGlass = LoadCursor(NULL, IDC_WAIT);
185: /* Create a main window for this application instance. */
186:
187: hWnd = CreateWindow(
188: "GenericWClass", /* See RegisterClass() call. */
189: "RPC Sample Application", /* Text for window title bar. */
190: WS_OVERLAPPEDWINDOW, /* Window style. */
191: CW_USEDEFAULT, /* Default horizontal position. */
192: CW_USEDEFAULT, /* Default vertical position. */
193: CW_USEDEFAULT, /* Default width. */
194: CW_USEDEFAULT, /* Default height. */
195: NULL, /* Overlapped windows have no parent. */
196: NULL, /* Use the window class menu. */
197: hInstance, /* This instance owns this window. */
198: NULL /* Pointer not needed. */
199: );
200:
201: /* If window could not be created, return "failure" */
202:
203: if (!hWnd)
204: return (FALSE);
205:
206: /* initialize server name and endpoint variables */
207: strcpy(szString, "hello, world");
208: strcpy(szEndpoint, "\\pipe\\whello");
209: szNetworkAddress[0] = '\0';
210: fBound = FALSE;
211: Bind(hWnd);
212:
213: /* Make the window visible; update its client area; and return "success" */
214: ShowWindow(hWnd, nCmdShow); /* Show the window */
215: UpdateWindow(hWnd); /* Sends WM_PAINT message */
216: return (TRUE); /* Returns the value from PostQuitMessage */
217:
218: }
219:
220: /****************************************************************************
221:
222: FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
223:
224: PURPOSE: Processes messages
225:
226: MESSAGES:
227:
228: WM_COMMAND - application menu (About dialog box)
229: WM_DESTROY - destroy window
230:
231: COMMENTS:
232:
233: To process the IDM_ABOUT message, call MakeProcInstance() to get the
234: current instance address of the About() function. Then call Dialog
235: box which will create the box according to the information in your
236: generic.rc file and turn control over to the About() function. When
237: it returns, free the intance address.
238:
239: ****************************************************************************/
240:
241: long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
242: HWND hWnd; /* window handle */
243: UINT message; /* type of message */
244: WPARAM wParam; /* additional information */
245: LPARAM lParam; /* additional information */
246: {
1.1.1.2 ! root 247: DLGPROC lpProc; /* pointer to the dialog box function */
1.1 root 248:
249: switch (message) {
250: case WM_COMMAND: /* message: command from application menu */
251: switch (wParam) {
252: case IDM_ABOUT:
1.1.1.2 ! root 253: lpProc = MakeProcInstance(About, hInst);
1.1 root 254: DialogBox(hInst, /* current instance */
255: "AboutBox", /* resource to use */
256: hWnd, /* parent handle */
257: lpProc); /* About() instance address */
258: FreeProcInstance(lpProc);
259: break;
260:
261: case IDM_SERVER:
1.1.1.2 ! root 262: lpProc = MakeProcInstance(Server, hInst);
1.1 root 263: DialogBox(hInst, /* current instance */
264: "ServerBox", /* resource to use */
265: hWnd, /* parent handle */
266: lpProc); /* Server instance address */
267: FreeProcInstance(lpProc);
268: break;
269:
270: case IDM_ENDPOINT:
1.1.1.2 ! root 271: lpProc = MakeProcInstance(Endpoint, hInst);
1.1 root 272: DialogBox(hInst, /* current instance */
273: "EndpointBox", /* resource to use */
274: hWnd, /* parent handle */
275: lpProc); /* Server instance address */
276: FreeProcInstance(lpProc);
277: break;
278:
279: case IDM_SEND:
1.1.1.2 ! root 280: lpProc = MakeProcInstance(Send, hInst);
1.1 root 281: DialogBox(hInst, /* current instance */
282: "SendBox", /* resource to use */
283: hWnd, /* parent handle */
284: lpProc); /* Server instance address */
285: FreeProcInstance(lpProc);
286: break;
287:
288: case IDM_EXIT:
289: if (fBound == TRUE)
290: Shutdown(); /* shut down the server */
291: DestroyWindow(hWnd);
292: break;
293:
294: default: /* Lets Windows process it */
295: return (DefWindowProc(hWnd, message, wParam, lParam));
296: }
297: break;
298:
299: case WM_DESTROY: /* message: window being destroyed */
300: PostQuitMessage(0);
301: break;
302:
303: default: /* Passes it on if unprocessed */
304: return (DefWindowProc(hWnd, message, wParam, lParam));
305: }
306: return (NULL);
307: }
308:
309:
310: /****************************************************************************
311:
312: FUNCTION: Server(HWND, unsigned, WORD, LONG)
313:
314: PURPOSE: Processes messages for "Server" dialog box
315:
316: MESSAGES:
317:
318: WM_INITDIALOG - initialize dialog box
319: WM_COMMAND - Input received
320:
321: COMMENTS:
322:
323: No initialization is needed for this particular dialog box, but TRUE
324: must be returned to Windows.
325:
326: Wait for user to click on "Ok" button, then close the dialog box.
327:
328: ****************************************************************************/
329: BOOL APIENTRY Server(
330: HWND hDlg, /* window handle of the dialog box */
331: UINT message, /* type of message */
332: UINT wParam, /* message-specific information */
333: LONG lParam)
334: {
335: UNREFERENCED_PARAMETER(lParam);
336: switch (message) {
337:
338: case WM_INITDIALOG: /* message: initialize dialog box */
1.1.1.2 ! root 339: SetDlgItemText((HANDLE)hDlg, IDD_SERVERNAME, szNetworkAddress);
1.1 root 340: return (TRUE);
341:
342: case WM_COMMAND: /* message: received a command */
343: switch(wParam) {
344: case IDCANCEL: /* System menu close command? */
345: EndDialog( hDlg, FALSE );
346: return( TRUE );
347: case IDOK: /* "OK" box selected? */
348: GetDlgItemText( hDlg, IDD_SERVERNAME, szNetworkAddress, UNCLEN);
349: hOld = SetCursor(hHourGlass);
350: if (Bind(hDlg) != 0) {
351: EndDialog(hDlg, FALSE);
352: return(FALSE);
353: }
354: SetCursor(hOld);
355: EndDialog(hDlg, TRUE);
356: return(TRUE);
357: } /* end switch wParam */
358:
359: } /* end switch message */
360: return (FALSE); /* Didn't process a message */
361: }
362:
363: /****************************************************************************
364:
365: FUNCTION: About(HWND, unsigned, WORD, LONG)
366:
367: PURPOSE: Processes messages for "About" dialog box
368:
369: MESSAGES:
370:
371: WM_INITDIALOG - initialize dialog box
372: WM_COMMAND - Input received
373:
374: COMMENTS:
375:
376: No initialization is needed for this particular dialog box, but TRUE
377: must be returned to Windows.
378:
379: Wait for user to click on "Ok" button, then close the dialog box.
380:
381: ****************************************************************************/
382: BOOL APIENTRY About(
383: HWND hDlg, /* window handle of the dialog box */
384: UINT message, /* type of message */
385: UINT wParam, /* message-specific information */
386: LONG lParam)
387: {
388: UNREFERENCED_PARAMETER(lParam);
389:
390: switch (message) {
391: case WM_INITDIALOG: /* message: initialize dialog box */
392: return (TRUE);
393:
394: case WM_COMMAND: /* message: received a command */
395: if (wParam == IDOK /* "OK" box selected? */
396: || wParam == IDCANCEL) { /* System menu close command? */
397:
398: EndDialog(hDlg, TRUE); /* Exits the dialog box */
399: return (TRUE);
400: }
401: break;
402: }
403: return (FALSE); /* Didn't process a message */
404: }
405: /****************************************************************************
406:
407: FUNCTION: Endpoint(HWND, unsigned, WORD, LONG)
408:
409: PURPOSE: Processes messages for "Endpoint" dialog box
410:
411: MESSAGES:
412:
413: WM_INITDIALOG - initialize dialog box
414: WM_COMMAND - Input received
415:
416: COMMENTS:
417:
418: No initialization is needed for this particular dialog box, but TRUE
419: must be returned to Windows.
420:
421: Wait for user to click on "Ok" button, then close the dialog box.
422:
423: ****************************************************************************/
424: BOOL APIENTRY Endpoint(
425: HWND hDlg, /* window handle of the dialog box */
426: UINT message, /* type of message */
427: UINT wParam, /* message-specific information */
428: LONG lParam)
429: {
430: UNREFERENCED_PARAMETER(lParam);
431:
432: switch (message) {
433:
434: case WM_INITDIALOG: /* message: initialize dialog box */
435: SetDlgItemText( hDlg, IDD_ENDPOINTNAME, szEndpoint);
436: return (TRUE);
437:
438: case WM_COMMAND: /* message: received a command */
439: switch(wParam) {
440: case IDCANCEL: /* System menu close command? */
441: EndDialog( hDlg, FALSE );
442: return( TRUE );
443: case IDOK: /* "OK" box selected? */
444: GetDlgItemText( hDlg, IDD_ENDPOINTNAME, szEndpoint, PATHLEN);
445: hOld = SetCursor(hHourGlass);
446: if (Bind(hDlg) != 0) {
447: EndDialog(hDlg, FALSE);
448: return(FALSE);
449: }
450: SetCursor(hOld);
451: EndDialog(hDlg, TRUE);
452: return(TRUE);
453: } /* end switch wParam */
454:
455: } /* end switch message */
456: return (FALSE); /* Didn't process a message */
457: }
458:
459: /****************************************************************************
460:
461: FUNCTION: Send(HWND, unsigned, WORD, LONG)
462:
463: PURPOSE: Processes messages for "Send" dialog box
464:
465: MESSAGES:
466:
467: WM_INITDIALOG - initialize dialog box
468: WM_COMMAND - Input received
469:
470: COMMENTS:
471:
472: No initialization is needed for this particular dialog box, but TRUE
473: must be returned to Windows.
474:
475: Wait for user to click on "Ok" button, then close the dialog box.
476:
477: ****************************************************************************/
478:
479: BOOL APIENTRY Send(
480: HWND hDlg, /* window handle of the dialog box */
481: UINT message, /* type of message */
482: UINT wParam, /* message-specific information */
483: LONG lParam)
484: {
485: UNREFERENCED_PARAMETER(lParam);
486: switch (message) {
487:
488: case WM_INITDIALOG: /* message: initialize dialog box */
489: SetDlgItemText( hDlg, IDD_MESSAGE, szString);
490: return (TRUE);
491:
492: case WM_COMMAND: /* message: received a command */
493: switch(wParam) {
494: case IDCANCEL: /* System menu close command? */
495: EndDialog( hDlg, FALSE );
496: return( TRUE );
497: case IDOK: /* "OK" box selected? */
498: GetDlgItemText( hDlg, IDD_MESSAGE, szString, MSGLEN);
499: RpcTryExcept {
500: HelloProc(szString); /* make call with user message */
501: }
502: RpcExcept(1) {
503: MessageBox(hDlg,
504: EXCEPT_MSG,
505: "Remote Procedure Call",
506: MB_ICONINFORMATION);
507: }
508: RpcEndExcept
509: EndDialog(hDlg, TRUE);
510: return(TRUE);
511: } /* end switch wParam */
512:
513: } /* end switch message */
514: return (FALSE); /* Didn't process a message */
515: }
516:
517: /****************************************************************************
518:
519: FUNCTION: MIDL_user_allocate(size_t)
520:
521: PURPOSE: Allocate memory as needed by the RPC runtime library
522:
523: COMMENTS:
524:
525: The stubs or runtime libraries may need to allocate memory.
526: By convention, they call a user-specified function named
527: MIDL_user_allocate. In this application, no memory
528: management is needed, so a dummy function is provided.
529:
530: ****************************************************************************/
531:
532: void * MIDL_user_allocate(size_t len)
533: {
534: UNREFERENCED_PARAMETER(len);
535: return(NULL); // no memory management required
536: }
537:
538: /****************************************************************************
539:
540: FUNCTION: MIDL_user_free(void *)
541:
542: PURPOSE: Free memory as needed by the RPC runtime library
543:
544: COMMENTS:
545:
546: The stubs or runtime libraries may need to free memory.
547: By convention, they call a user-specified function named
548: MIDL_user_free. In this application, no memory allocation
549: is needed so a dummy function is provided.
550:
551: ****************************************************************************/
552:
553: void MIDL_user_free(void * ptr)
554: {
555: UNREFERENCED_PARAMETER(ptr);
556: return; // no memory management required
557: }
558:
559: /****************************************************************************
560:
561: FUNCTION: Bind(HWND)
562:
563: PURPOSE: Make RPC API calls to bind to the server application
564:
565: COMMENTS:
566:
567: The binding calls are made from InitInstance() and whenever
568: the user changes the server name or endpoint. If the bind
569: operation is successful, the global flag fBound is set to TRUE.
570:
571: The global flag fBound is used to determine whether to call
572: the RPC API function RpcBindingFree.
573:
574: ****************************************************************************/
575:
576:
577: RPC_STATUS Bind(HWND hWnd)
578: {
579: RPC_STATUS status;
580:
581: if (fBound == TRUE) { /* unbind only if bound */
582: status = RpcBindingFree(&hWHello); // remote calls done; unbind
583: if (status) {
584: MessageBox(hWnd, "RpcBindingFree failed", "RPC Error",
585: MB_ICONSTOP);
586: return(status);
587: }
588: else
589: fBound = FALSE; /* unbind successful; reset flag */
590: }
591: status = RpcStringBindingCompose(pszUuid,
592: pszProtocolSequence,
593: szNetworkAddress,
594: szEndpoint,
595: pszOptions,
596: &pszStringBinding);
597: if (status) {
598: sprintf(pszFail, "RpcStringBindingCompose failed: (0x%x)\nNetwork Address = %s\n",
599: status, szNetworkAddress);
600: MessageBox(hWnd, pszFail, "RPC Runtime Error", MB_ICONEXCLAMATION);
601: return(status);
602: }
603: status = RpcBindingFromStringBinding(pszStringBinding,
604: &hWHello);
605: if (status) {
606: sprintf(pszFail, "RpcBindingFromStringBinding failed:(0x%x)\nString = %s\n",
607: status, pszStringBinding);
608: MessageBox(hWnd, pszFail, "RPC Runtime Error", MB_ICONEXCLAMATION);
609: return(status);
610: }
611: fBound = TRUE; /* bind successful; reset flag */
612: return(status);
613: }
614:
615: /**** end whelloc.c ****/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.