#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
评论2