|
|
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.