Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
Server.c
Upload User: dq031136
Upload Date: 2022-08-08
Package Size: 802k
Code Size: 19k
Category:
Visual C++ Books
Development Platform:
C++ Builder
- #define STRICT
- #include <windows.h>
- #include "server.h"
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- // clients[] is a global array of
- // structures used to keep track
- // of the multiple instances of
- // the server side of the named
- // pipe. As a client connects
- // to a given instance, a new
- // server thread is created and
- // added to the array.
- WRTHANDLE clients[MAX_PIPE_INSTANCES];
- DWORD clientCount = 0; // Global count of connected clients.
- HWND hWnd;
- HANDLE hInst;
- CHAR lpBuffer[255];
- int APIENTRY WinMain (HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- MSG msg;
- WNDCLASS wc;
- UNREFERENCED_PARAMETER( lpCmdLine );
- UNREFERENCED_PARAMETER( hPrevInstance );
- //
- // Detect platform and exit gracefully if not Windows NT.
- //
- {
- OSVERSIONINFO osvi;
- osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
- GetVersionEx (&osvi);
- if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
- LoadString(hInst, IDS_WRONGOS, lpBuffer, sizeof(lpBuffer));
- MessageBox (NULL, lpBuffer, "SERVER32", MB_OK | MB_ICONSTOP);
- return 0;
- }
- }
- hInst = hInstance;
- wc.style = 0;
- wc.lpfnWndProc = (WNDPROC)MainWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon (hInstance, "npserver");
- wc.hCursor = LoadCursor (NULL, IDC_ARROW);
- wc.hbrBackground = GetStockObject (WHITE_BRUSH);
- wc.lpszMenuName = "PipeMenu";
- wc.lpszClassName = "PipeWClass";
- RegisterClass(&wc);
- LoadString(hInst, IDS_WINDOWTITLE, lpBuffer, sizeof(lpBuffer));
- hWnd = CreateWindow ("PipeWClass",
- lpBuffer,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
- ShowWindow (hWnd, nCmdShow);
- while (GetMessage (&msg, NULL, 0, 0))
- DispatchMessage (&msg);
- return (msg.wParam);
- }
- LONG CALLBACK MainWndProc (HWND hwnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
- {
- LONG lpServerThreadID;
- PAINTSTRUCT paintStruct;
- HDC hDC;
- switch (message)
- {
- case WM_PAINT:
- // DrawBranch is used to paint the spools and text to the window.
- hDC = BeginPaint (hwnd, &paintStruct);
- DrawBranch (hDC);
- EndPaint (hwnd, &paintStruct);
- return(0);
- case WM_CREATE :
- // Create the first instance of a server side of the pipe.
- CreateThread ((LPSECURITY_ATTRIBUTES)NULL, // No security.
- (DWORD)0, // Same stack size.
- (LPTHREAD_START_ROUTINE)ServerProc,// Thread procedure.
- (LPVOID)&hwnd, // Parameter.
- (DWORD)0, // Start immediatly.
- (LPDWORD)&lpServerThreadID); // Thread ID.
- return (0);
- case WM_DESTROY :
- PostQuitMessage (0);
- return (0);
- }
- return DefWindowProc (hwnd, message, wParam, lParam);
- }
- /*************************************************************************
- *
- * PROCEDURE: ServerProc (HWND *hWnd)
- *
- * A thread procedure, which creates an instance of the server side of
- * the named pipe, and then blocks waiting for a client to connect.
- * Once the client connects, a global array is updated with the specific
- * clients information, and this procedure is called again
- * to launch another waiting server thread. After launching the new
- * thread, this thread begins to loop, reading the named pipe. When
- * a message comes from its client, it uses TellAll() to broadcast
- * the message to the other clients in the array.
- *
- * CALLED BY:
- *
- * ServerProc();
- * WinMain();
- *
- * CALLS TO:
- *
- * TellAll();
- * ServerProc().
- *
- * COMMENTS:
- *
- * Clients is a global array which hold information on each client
- * connected to the named pipe. This procedure recieves a buffer.
- * It then steps through this global array, and for each client it
- * writes the buffer.
- *
- *************************************************************************/
- VOID ServerProc(HWND *hWnd)
- {
- HANDLE hPipe; // Pipe handle.
- CHAR inBuf[IN_BUF_SIZE] = ""; // Input buffer for pipe.
- DWORD ServerThreadID; // Used for CreateThread().
- CHAR errorBuf[LINE_LEN] = ""; // Used for error messages.
- DWORD bytesRead; // Used in ReadFile().
- DWORD retCode; // Used to trap return codes.
- DWORD clientIndex; // Index into global array, for this
- // instances client.
- DWORD lastError; // Traps returns from GetLastError().
- BOOL ExitLoop = FALSE; // Boolean Flag to exit loop.
- OVERLAPPED OverLapWrt; // Overlapped structure for writing.
- HANDLE hEventWrt; // Event handle for overlapped write.
- OVERLAPPED OverLapRd; // Overlapped structure for reading.
- HANDLE hEventRd; // Event handle for overlapped reads.
- DWORD bytesTransRd; // Bytes transferred by overlapped.
- PSECURITY_DESCRIPTOR pSD;
- SECURITY_ATTRIBUTES sa;
- // create a security NULL security
- // descriptor, one that allows anyone
- // to write to the pipe... WARNING
- // entering NULL as the last attribute
- // of the CreateNamedPipe() will
- // indicate that you wish all
- // clients connecting to it to have
- // all of the same security attributes
- // as the user that started the
- // pipe server.
- pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
- SECURITY_DESCRIPTOR_MIN_LENGTH);
- if (pSD == NULL)
- {
- MessageBox (*hWnd, "Error in LocalAlloc for pSD",
- "Debug: ServerProc()", MB_OK);
- return;
- }
- if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
- {
- wsprintf (errorBuf, "Error: InitializeSecurityDescriptor() %d",
- GetLastError());
- MessageBox (*hWnd, errorBuf, "Debug: ServerProc()", MB_OK);
- LocalFree((HLOCAL)pSD);
- return;
- }
- // add a NULL disc. ACL to the
- // security descriptor.
- if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE))
- {
- wsprintf (errorBuf, "Error: SetSecurityDescriptorDacl() %d",
- GetLastError());
- MessageBox (*hWnd, errorBuf, "Debug: ServerProc()", MB_OK);
- LocalFree((HLOCAL)pSD);
- return;
- }
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = pSD;
- sa.bInheritHandle = TRUE;
- // Create a local named pipe with
- // the name '\.PIPEtest'. The
- // '.' signifies local pipe.
- hPipe = CreateNamedPipe ("\\.\PIPE\test", // Pipe name = 'test'.
- PIPE_ACCESS_DUPLEX // 2 way pipe.
- | FILE_FLAG_OVERLAPPED, // Use overlapped structure.
- PIPE_WAIT // Wait on messages.
- | PIPE_READMODE_MESSAGE // Specify message mode pipe.
- | PIPE_TYPE_MESSAGE,
- MAX_PIPE_INSTANCES, // Maximum instance limit.
- OUT_BUF_SIZE, // Buffer sizes.
- IN_BUF_SIZE,
- TIME_OUT, // Specify time out.
- &sa); // Security attributes.
- // Check Errors.
- if ((DWORD)hPipe == 0xFFFFFFFF)
- {
- retCode = GetLastError(); // Report any error, it should always succeed.
- LoadString(hInst, IDS_ERRORCODE, lpBuffer, sizeof(lpBuffer));
- wsprintf (errorBuf, lpBuffer, retCode);
- LoadString(hInst, IDS_DEBUGTITLE, lpBuffer, sizeof(lpBuffer));
- MessageBox (*hWnd, errorBuf, lpBuffer,
- MB_ICONINFORMATION | MB_OK | MB_APPLMODAL);
- };
- // Block until a client connects.
- ConnectNamedPipe(hPipe, NULL);
- // Create and init overlap for writing.
- hEventWrt = CreateEvent (NULL, TRUE, FALSE, NULL);
- memset (&OverLapWrt, 0, sizeof(OVERLAPPED));
- OverLapWrt.hEvent = hEventWrt;
- // Set the clientIndex, then increment
- // the count. Fill in the structure
- // for this client in the array.
- clientIndex = clientCount++;
- clients[clientIndex].hPipe = hPipe;
- clients[clientIndex].live = TRUE;
- clients[clientIndex].overLap = OverLapWrt;
- clients[clientIndex].hEvent = hEventWrt;
- // Create and init overlap for reading.
- hEventRd = CreateEvent(NULL,TRUE,FALSE,NULL);
- memset (&OverLapRd, 0, sizeof(OVERLAPPED));
- OverLapRd.hEvent = hEventRd;
- // Read from the client, the first
- // first message should always be
- // the clients user name.
- retCode = ReadFile (hPipe, inBuf, PLEASE_READ, &bytesRead, &OverLapRd);
- if (!retCode)
- lastError = GetLastError();
- if (lastError == ERROR_IO_PENDING) // Wait on read if need be.
- WaitForSingleObject (hEventRd, (DWORD)-1);
- // Put client's name in the array.
- strcpy (clients[clientIndex].Name, inBuf);
- // Create a thread which will make
- // another server instance of the
- // named pipe.
- CreateThread ((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
- (DWORD)0, // Use same stack size.
- (LPTHREAD_START_ROUTINE)ServerProc, // Thread procedure.
- (LPVOID)hWnd, // Parameter to pass.
- (DWORD)0, // Run immediately.
- (LPDWORD)&ServerThreadID); // Thread identifier.
- TellAll(""); // Forces a paint, draws a red spool
- // and name for this client.
- // Do loop which basically reads from
- // this specific client, and then
- // uses TellAll() to broadcast the
- // message to all the connected
- // clients.
- do{
- // Read the pipe.
- retCode = ReadFile (hPipe, inBuf, PLEASE_READ, &bytesRead, &OverLapRd);
- // Check for three kinds of errors:
- // If Error = IO_PENDING, wait til
- // the event handle signals success,
- // If BROKEN_PIPE, exit the do loop.
- // Any other error, flag it to the
- // user and exit the do loop.
- if (!retCode)
- {
- lastError = GetLastError();
- switch (lastError)
- {
- // IO_PENDING, wait on the event.
- case ERROR_IO_PENDING:
- WaitForSingleObject (hEventRd, (DWORD)-1);
- break;
- // Pipe is broken, exit the loop.
- case ERROR_BROKEN_PIPE:
- ExitLoop = TRUE;
- break;
- // Something else is wrong, exit the
- // the loop after telling the user.
- default:
- LoadString(hInst, IDS_READERROR, lpBuffer, sizeof(lpBuffer));
- wsprintf (errorBuf, lpBuffer, lastError);
- LoadString(hInst, IDS_DEBUGINFO, lpBuffer, sizeof(lpBuffer));
- MessageBox (*hWnd, errorBuf, lpBuffer, MB_OK);
- ExitLoop = TRUE;
- break;
- }
- }
- if (!ExitLoop)
- {
- GetOverlappedResult (hPipe, &OverLapRd, &bytesTransRd, FALSE);
- // Use TellAll to broadcast the message.
- if (bytesTransRd)
- TellAll(inBuf);
- else
- TellAll("");
- }
- }while(!ExitLoop);
- clients[clientIndex].live = FALSE; // Turns spool gray.
- CloseHandle (hPipe); // Close handles.
- CloseHandle (hEventRd);
- CloseHandle (hEventWrt);
- DisconnectNamedPipe (hPipe); // Close pipe instance.
- ExitThread(0); // Clean up and die.
- }
- /* To write the buffer (input parameter) to all of the clients listed
- in the global array "clients". Clients is a global array which hold information on each client
- connected to the named pipe. This procedure recieves a buffer.
- It then steps through this global array, and for each client it
- writes the buffer. */
- VOID TellAll( CHAR *buffer )
- {
- DWORD i; // Index through array.
- DWORD bytesWritten; // Used in WriteFile().
- DWORD retCode; // Traps return codes.
- CHAR Buf[LINE_LEN]; // Message Buffer.
- DWORD lastError; // Traps returns from GetLastError().
- for(i=0; i < clientCount; i++) // For all clients in the array.
- {
- // If client isn't alive, don't waste
- // time writing to it.
- if (clients[i].live)
- {
- retCode = WriteFile (clients[i].hPipe, buffer, strlen(buffer),
- &bytesWritten, &clients[i].overLap);
- // Check 3 kinds of errors: IO_PENDING,
- // NO_DATA, or other. Wait on event
- // handle if IO_PENDING, else, if it's
- // anything other than NO_DATA (pipe
- // client disconnected), flag the user.
- // In any case, if it's not IO_PENDING,
- // clients[i].live = FALSE, spool turns
- // gray.
- if (!retCode)
- {
- lastError = GetLastError();
- // IO_PENDING, wait on event handle.
- if (lastError == ERROR_IO_PENDING)
- {
- WaitForSingleObject (clients[i].hEvent, (DWORD)-1);
- }
- else
- {
- // If not NO_DATA, flag user.
- if (lastError != ERROR_NO_DATA)
- {
- LoadString(hInst, IDS_DEBUGLAST, lpBuffer, sizeof(lpBuffer));
- wsprintf (Buf, "%s = %d", buffer, GetLastError());
- MessageBox(hWnd, Buf, lpBuffer, MB_OK);
- }
- clients[i].live = FALSE;
- }
- }
- } //if client.live
- } // for loop
- // Paint window with new information.
- InvalidateRect(hWnd, NULL, TRUE);
- }
- /*
- To draw one of four bitmaps for each client, depending upon the clients
- status (alive = red spool, dead or disconnected = gray), and location in
- the array. It also draws the clients user name beside the spool.
- This procedure is executed when the WM_PAINT message is trapped. */
- VOID DrawBranch(HDC hDC)
- {
- // Spool bitmaps.
- HBITMAP hEndLive, hEndDead, hMidLive, hMidDead, hBitMap;
- HDC hDCMem;
- int X, Y;
- BITMAP bm;
- POINT ptSize, ptOrg;
- DWORD index;
- // Load bitmaps: two red (live),
- // two dead (gray). End = end
- // of tree (last client to connect),
- // mid means in the middle somewhere.
- hEndLive = LoadBitmap (hInst, "EndLive");
- hEndDead = LoadBitmap (hInst, "EndDead");
- hMidLive = LoadBitmap (hInst, "MidLive");
- hMidDead = LoadBitmap (hInst, "MidDead");
- // For each client, determine if
- // if alive or not, and position;
- // then blt appropriate map and
- // clients name.
- for (index = 0; index < clientCount; index++)
- {
- if (index < clientCount - 1) // ClientCount - 1 = last (end) client.
- {
- if(clients[index].live) // If live = red, else = gray.
- hBitMap = hMidLive;
- else
- hBitMap = hMidDead;
- }
- else
- {
- if(clients[index].live) // If live = red, else = gray.
- hBitMap = hEndLive;
- else
- hBitMap = hEndDead;
- }
- // Calculate coordinates:
- X = BITMAP_X; // X position is constant.
- Y = index * BITMAP_Y; // Y is based on index in the array.
- // Blt the chosen map.
- hDCMem = CreateCompatibleDC(hDC);
- SelectObject(hDCMem, hBitMap);
- SetMapMode(hDCMem, GetMapMode(hDC));
- GetObject(hBitMap, sizeof(BITMAP), &bm);
- ptSize.x = bm.bmWidth;
- ptSize.y = bm.bmHeight;
- DPtoLP (hDC, &ptSize, 1);
- ptOrg.x = 0;
- ptOrg.y = 0;
- DPtoLP (hDCMem, &ptOrg, 1);
- BitBlt(hDC, X, Y, ptSize.x, ptSize.y,
- hDCMem, ptOrg.x, ptOrg.y, SRCCOPY);
- X = NAME_X; // Relocate X,Y for clients name.
- Y += NAME_Y;
- // Write name next to spool.
- TextOut (hDC, X, Y, clients[index].Name, strlen(clients[index].Name));
- DeleteDC(hDCMem);
- }
- }