/* * Initialize the socket library. This function is called by all of the * other functions in this file. * * Note that initialization is only required on Win32. * * Win32: try to load the winsock2 dll, and if that fails, load winsock. * This is really only neccesary on Windows95 as winsock2 is always * available on NT. Once the dll is available, it's initalized with * WSAStartup. */ void sysInitSocketLibrary() { static int initialized = 0; if (!initialized) { HANDLE hWinsock; WORD wVersionRequested = MAKEWORD(2, 0); WSADATA wsaData; int winsock2Available = 1; hWinsock = LoadLibrary("ws2_32.dll"); if (hWinsock == NULL) { hWinsock = LoadLibrary("wsock32.dll"); winsock2Available = 0; } if (hWinsock == NULL) { sysErrorExit(getMsgString(MSG_WSA_LOAD)); } if (WSAStartup(wVersionRequested, &wsaData) != 0) { sysErrorExit(getMsgString(MSG_WSA_START)); } if (winsock2Available) { sendDisconnect = (int (PASCAL FAR *)())GetProcAddress(hWinsock, "WSASendDisconnect"); } initialized = 1; } }
/* * Print an (obscure) error message to stderr and exit. If errno has * been set or there was a winsock error, then print the corresponding * error messages too. For an explanation of the WinSock error codes, see: * metalab.unc.edu/pub/micro/pc-stuff/ms-windows/winsock/winsock-1.1/winsock.html#ErrorCodes */ void sysErrorExit(char *msg) { #ifndef WIN_CONSOLE MessageBox(NULL, msg, JAVAWS_NAME, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY); #endif fprintf(stderr, getMsgString(MSG_SPLASH_EXIT)); if (errno != 0) { perror(msg); } else { fprintf(stderr, "\t%s\n", msg); } fprintf(stderr, "%s %d\n", getMsgString(MSG_WSA_ERROR), WSAGetLastError()); exit(-1); }
/* * Print an (obscure) error message and exit. */ void errorExit(char *msg) { char *msg1 = getMsgString(MSG_SPLASH_EXIT); fprintf(stderr, msg1); if (errno != 0) { perror(msg); } else { fprintf(stderr, "\t%s\n", msg); } splashExit(); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static int width = 0, height = 0; switch (message) { case WM_CONNECT: { SOCKADDR_IN iname; int length = sizeof(iname); SOCKET client; char cmd[1]; if ((client = accept(server, (SOCKADDR *)&iname, &length)) == -1) { errorExit(getMsgString(MSG_ACCEPT_FAILED)); } if (recv(client, cmd, 1, 0) == 1) { switch(cmd[0]) { case 'Z': sysCloseSocket(client); splashExit(); break; default: errorExit(getMsgString(MSG_SPLASH_CMND)); } } } case WM_DESTROY: { splashExit(); break; } default: { return DefWindowProc(hWnd, message, wParam, lParam); } } return 0; }
int sysSplash(int splashPort, char *splashFile) { WNDCLASS wce = {0}; HWND hWnd; MSG msg; int port; int ud = CW_USEDEFAULT; HINSTANCE hInstance = GetModuleHandle(NULL); if ((server = sysCreateListenerSocket(&port)) == INVALID_SOCKET) { errorExit(getMsgString(MSG_LISTENER_FAILED)); } /* Send our ephemeral port back to the parent process. The parent * process port number is splashPort. We send the port number back * to the parent as a 6 character string. */ { SOCKADDR_IN iname = {0}; SOCKET parent; HWND hWnd = NULL; char data[6]; if (splashPort <= 0) { errorExit(getMsgString(MSG_SPLASH_PORT)); } if ((parent = sysCreateClientSocket(splashPort)) == INVALID_SOCKET) { errorExit(getMsgString(MSG_SPLASH_SOCKET)); } sprintf(data, "%d", port); if (send(parent, data, 6, 0) != 6) { errorExit(getMsgString(MSG_SPLASH_SEND)); } sysCloseSocket(parent); } /* Check for NO Splash mode */ if (splashFile == NULL) { return 0; } // create a dummy window to get events on: wce.style = 0; wce.lpfnWndProc = (WNDPROC)WndProc; wce.hInstance = hInstance; wce.hCursor = LoadCursor(NULL, IDC_ARROW); wce.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wce.lpszClassName = "SplashDummy"; RegisterClass(&wce); hWnd = CreateWindow("SplashDummy", "Win32Splash", WS_OVERLAPPEDWINDOW, ud, ud, ud, ud, NULL, NULL, hInstance, NULL); /* Set a timer that will exit this process after TIMEOUT seconds */ if (SetTimer(hWnd, 0, TIMEOUT * 1000, (TIMERPROC)timeoutProc) == 0) { errorExit(getMsgString(MSG_SPLASH_TIMER)); } DoSplashInit(); DoSplashLoadFile(splashFile); /* Ask Win32 to notify us when there are pending connections on the * server socket. WM_CONNECT is an "event" defined here. */ WSAAsyncSelect(server, hWnd, WM_CONNECT, FD_ACCEPT); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } //return msg.wParam; return 0; }