wprintf(L"Waiting for the client's connection...\n");
if (!ConnectNamedPipe(hNamedPipe, NULL))
{
if (ERROR_PIPE_CONNECTED != GetLastError())
{
dwError = GetLastError();
wprintf(L"ConnectNamedPipe failed w/err 0x%08lx\n", dwError);
goto Cleanup;
}
}
wprintf(L"Client is connected.\n");
//
// Receive a request from client.
//
BOOL fFinishRead = FALSE;
do
{
wchar_t chRequest[BUFFER_SIZE];
DWORD cbRequest, cbRead;
cbRequest = sizeof(chRequest);
fFinishRead = ReadFile(
hNamedPipe, // Handle of the pipe
chRequest, // Buffer to receive data
cbRequest, // Size of buffer in bytes
&cbRead, // Number of bytes read
NULL // Not overlapped I/O
);
if (!fFinishRead && ERROR_MORE_DATA != GetLastError())
{
dwError = GetLastError();
wprintf(L"ReadFile from pipe failed w/err 0x%08lx\n", dwError);
goto Cleanup;
}
wprintf(L"Receive %ld bytes from client: \"%s\"\n", cbRead, chRequest);
} while (!fFinishRead); // Repeat loop if ERROR_MORE_DATA
//
// Send a response from server to client.
//
wchar_t chResponse[] = RESPONSE_MESSAGE;
DWORD cbResponse, cbWritten;
cbResponse = sizeof(chResponse);
if (!WriteFile(
hNamedPipe, // Handle of the pipe
chResponse, // Buffer to write
cbResponse, // Number of bytes to write
&cbWritten, // Number of bytes written
NULL // Not overlapped I/O
))
{
dwError = GetLastError();
wprintf(L"WriteFile to pipe failed w/err 0x%08lx\n", dwError);
goto Cleanup;
}
wprintf(L"Send %ld bytes to client: \"%s\"\n", cbWritten, chResponse);
// Flush the pipe to allow the client to read the pipe's contents
// before disconnecting. Then disconnect the client's connection.
FlushFileBuffers(hNamedPipe);
DisconnectNamedPipe(hNamedPipe);
Cleanup:
// Centralized cleanup for all allocated resources.
if (pSa != NULL)
{
FreePipeSecurity(pSa);
pSa = NULL;
}
if (hNamedPipe != INVALID_HANDLE_VALUE)
{
CloseHandle(hNamedPipe);
hNamedPipe = INVALID_HANDLE_VALUE;
}
return dwError;
}
//
// FUNCTION: CreatePipeSecurity(PSECURITY_ATTRIBUTES *)
//
// PURPOSE: The CreatePipeSecurity function creates and initializes a new
// SECURITY_ATTRIBUTES structure to allow Authenticated Users read and
// write access to a pipe, and to allow the Administrators group full
// access to the pipe.
//
// PARAMETERS:
// * ppSa - output a pointer to a SECURITY_ATTRIBUTES structure that allows
// Authenticated Users read and write access to a pipe, and allows the
// Administrators group full access to the pipe. The structure must be
// freed by calling FreePipeSecurity.
//
// RETURN VALUE: Returns TRUE if the function succeeds.
//
// EXAMPLE CALL:
//
// PSECURITY_ATTRIBUTES pSa = NULL;
// if (CreatePipeSecurity(&pSa))
// {
// // Use the security attributes
// // ...
//
// FreePipeSecurity(pSa);
// }
//
BOOL CreatePipeSecurity(PSECURITY_ATTRIBUTES *ppSa)
{
BOOL fSucceeded = TRUE;
DWORD dwError = ERROR_SUCCESS;
PSECURITY_DESCRIPTOR pSd = NUL