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