windows-nt/Source/XPSP1/NT/shell/services/hdsrv/pipeclnt/main.cpp
2020-09-26 16:20:57 +08:00

238 lines
6.9 KiB
C++

#include <tchar.h>
#include <stdio.h>
#include <io.h>
#include <objbase.h>
#ifndef UNICODE
#error This has to be UNICODE
#endif
#define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
int Do(int argc, wchar_t* argv[]);
static BOOL fUnicode = TRUE;
static SECURITY_ATTRIBUTES _sa = {0};
static ACL* _pacl = NULL;
static SID* _psidLocalUsers = NULL;
static SECURITY_DESCRIPTOR* _psd = NULL;
HRESULT _InitSecurityDescriptor();
extern "C"
{
int __cdecl wmain(int argc, wchar_t* argv[])
{
return Do(argc, argv);
}
}
VOID InstanceThread(LPVOID lpvParam)
{
BYTE bRequest[4096];
DWORD cbBytesRead;
BOOL fSuccess;
HANDLE hPipe = (HANDLE)lpvParam;
/* EnterCriticalSection(&g_cs);
++g_cReply;
cReply = g_cReply;
LeaveCriticalSection(&g_cs);*/
fSuccess = ReadFile(hPipe, bRequest, sizeof(bRequest), &cbBytesRead,
NULL);
if (fSuccess && cbBytesRead)
{
// printf(TEXT("[%08u]"), cReply);
if (fUnicode)
{
wprintf((LPWSTR)bRequest);
}
else
{
printf((LPSTR)bRequest);
}
}
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
int Do(int argc, wchar_t* argv[])
{
if (argc >= 3)
{
TCHAR szPipeName[MAX_PATH];
wsprintf(szPipeName, TEXT("\\\\%s\\pipe\\%s"), argv[1], argv[2]);
if (4 == argc)
{
if (lstrcmpi(argv[3], TEXT("/a")))
{
fUnicode = FALSE;
}
}
// The main loop creates an instance of the named pipe and
// then waits for a client to connect to it. When the client
// connects, a thread is created to handle communications
// with that client, and the loop is repeated.
do
{
HRESULT hres = _InitSecurityDescriptor();
if (SUCCEEDED(hres))
{
HANDLE hPipe = CreateNamedPipe(
szPipeName, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
256, // output buffer size
4096, // input buffer size
10 * 1000, // client time-out
&_sa);
if (hPipe != INVALID_HANDLE_VALUE)
{
// Wait for the client to connect; if it succeeds,
// the function returns a nonzero value. If the function returns
// zero, GetLastError returns ERROR_PIPE_CONNECTED.
BOOL fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE :
(GetLastError() == ERROR_PIPE_CONNECTED);
if (fConnected)
{
DWORD dwThreadId;
// Create a thread for this client.
HANDLE hThread = CreateThread(
NULL, // no security attribute
0, // default stack size
(LPTHREAD_START_ROUTINE) InstanceThread,
(LPVOID) hPipe, // thread parameter
0, // not suspended
&dwThreadId); // returns thread ID
if (hThread)
{
BOOL f = CloseHandle(hThread);
}
}
else
{
// The client could not connect, so close the pipe.
CloseHandle(hPipe);
}
}
}
}
while (1);
}
else
{
wprintf(L"\nUsage: \n\n");
wprintf(L"pipeclnt MachineName PipeName [/a]\n\n");
wprintf(L" MachineName: e.g.: stephstm_dev (no leading '\\\\')\n");
wprintf(L" Use '.' for local machine\n");
wprintf(L" PipeName: The pipename, usually the debuggee module name\n");
wprintf(L" [/a]: Treat the incoming data as ANSI (default is UNICODE)\n\n");
}
return 0;
}
HRESULT _InitSecurityDescriptor()
{
HRESULT hres;
if (_pacl)
{
hres = S_OK;
}
else
{
hres = E_FAIL;
SID_IDENTIFIER_AUTHORITY sidAuthNT = SECURITY_WORLD_SID_AUTHORITY;
if (AllocateAndInitializeSid(&sidAuthNT, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, (void**)&_psidLocalUsers))
{
DWORD cbacl = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) -
sizeof(DWORD/*ACCESS_ALLOWED_ACE.SidStart*/) +
GetLengthSid(_psidLocalUsers);
_pacl = (ACL*)LocalAlloc(LPTR, cbacl);
if (_pacl)
{
if (InitializeAcl(_pacl, cbacl, ACL_REVISION))
{
if (AddAccessAllowedAce(_pacl, ACL_REVISION, FILE_ALL_ACCESS,
_psidLocalUsers))
{
_psd = (SECURITY_DESCRIPTOR*)LocalAlloc(LPTR,
sizeof(SECURITY_DESCRIPTOR));
if (_psd)
{
if (InitializeSecurityDescriptor(_psd,
SECURITY_DESCRIPTOR_REVISION))
{
if (SetSecurityDescriptorDacl(_psd, TRUE,
_pacl, FALSE))
{
if (IsValidSecurityDescriptor(_psd))
{
_sa.nLength = sizeof(_sa);
_sa.lpSecurityDescriptor = _psd;
_sa.bInheritHandle = TRUE;
hres = S_OK;
}
}
}
}
else
{
hres = E_OUTOFMEMORY;
}
}
}
}
else
{
hres = E_OUTOFMEMORY;
}
}
if (FAILED(hres))
{
if (_psidLocalUsers)
{
FreeSid(_psidLocalUsers);
}
if (_pacl)
{
LocalFree((HLOCAL)_pacl);
}
if (_psd)
{
LocalFree((HLOCAL)_psd);
}
}
}
return hres;
}