2025-11-28 00:35:46 +09:00

283 lines
7.5 KiB
C

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) 1999 - 2006 Microsoft Corporation. All rights reserved.
Module Name:
common.c
Abstract:
Pipe and error displaying routines for AuthzSample
--*/
#include<windows.h>
#include<stdio.h>
#include<tchar.h>
//////////////////////////////////////////////////////////////////////
DWORD DisplayAPIError(TCHAR *pszAPI,BOOL bConsole,
BOOL bMsgBox, BOOL bExit)
{
LPVOID lpvMessageBuffer;
TCHAR szErrMsgBuffer[500];
DWORD nWrote;
DWORD dwError;
dwError = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
//... now display this string
_stprintf_s( szErrMsgBuffer, 500 * sizeof(TCHAR),
TEXT("ERROR: API = %s.\n"
"ERROR CODE = %d.\n"
" = 0x%x.\n"
"MESSAGE = %s.\n"),
pszAPI, dwError,dwError,(char*)lpvMessageBuffer);
if (bConsole)
WriteConsole( GetStdHandle(STD_OUTPUT_HANDLE),szErrMsgBuffer,
lstrlen(szErrMsgBuffer),&nWrote,NULL);
if (bMsgBox)
MessageBox(GetDesktopWindow(),szErrMsgBuffer,TEXT("Execution Error"), MB_OK);
OutputDebugString(szErrMsgBuffer);
// Free the buffer allocated by the system
LocalFree(lpvMessageBuffer);
if (bExit)
ExitProcess(dwError);
return dwError;
}
void HandleError(DWORD dwErr, TCHAR *pszAPI, BOOL fAPI, BOOL fExit)
{
if (fAPI) {
DisplayAPIError(pszAPI,TRUE, TRUE, fExit);
}
else
{
_tprintf(TEXT("%s"),pszAPI);
if (dwErr)
_tprintf(TEXT("%u\n"),dwErr);
if (fExit)
ExitProcess(0);
}
return;
}
BOOL
BuildGenericAccessAcl(
PACL* ppAcl,
PDWORD cbAclSize
)
/*++
Routine Description
This function builds a Dacl which grants the creator of the objects
GENERIC_ALL (Full Control) and Everyone GENERIC_READ, GENERIC_WRITE and
GENERIC_EXECUTE access to the object.
This Dacl allows for higher security than a NULL Dacl, as this only grants
the creator/owner write access to the security descriptor, and grants
Everyone the ability to "use" the object. This scenario prevents a
malevolent user from disrupting service by preventing arbitrary access
manipulation.
Arguments
PACL* pAcl - Pointer to buffer for pointer to allocated PACL. Must be
freed with LocalFree
PDWORD cbAclSize - Pointer to dword receiving size of acl.
Return value
Bool, true on success, false on error
--*/
{
DWORD dwAclSize;
SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY siaCreator = SECURITY_CREATOR_SID_AUTHORITY;
PSID pEveryoneSid = NULL;
PSID pOwnerSid = NULL;
BOOL bSuccess = FALSE;
__try {
//
// compute size of acl
//
dwAclSize = sizeof(ACL) +
2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
GetSidLengthRequired( 1 ) + // well-known Everyone Sid
GetSidLengthRequired( 1 ) ; // well-known Creator Owner Sid
(*ppAcl) = LocalAlloc(0,dwAclSize);
if(*ppAcl == NULL) {
HandleError(GetLastError(), TEXT("LocalAlloc"), TRUE, TRUE);
__leave;
}
*cbAclSize = dwAclSize;
InitializeAcl(*ppAcl,dwAclSize,ACL_REVISION);
//
// build well known sids
//
// build EVERYONE SID
AllocateAndInitializeSid( &siaWorld, 1, SECURITY_WORLD_RID,
0,0,0,0,0,0,0,
&pEveryoneSid
);
// build Creator/Owner SID
AllocateAndInitializeSid( &siaCreator, 1, SECURITY_CREATOR_OWNER_RID,
0,0,0,0,0,0,0,
&pOwnerSid
);
if (!AddAccessAllowedAce( *ppAcl,
ACL_REVISION,
GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
pEveryoneSid
)) {
HandleError(GetLastError(),TEXT("AddAccessAllowedAce"),TRUE,TRUE);
__leave;
}
if (!AddAccessAllowedAce( *ppAcl,
ACL_REVISION,
GENERIC_ALL,
pOwnerSid
)) {
HandleError(GetLastError(),TEXT("AddAccessAllowedAce (2)"),TRUE,TRUE);
__leave;
}
bSuccess = TRUE;
}
__finally {
if (pEveryoneSid) FreeSid(pEveryoneSid);
if (pOwnerSid) FreeSid(pOwnerSid);
}
return bSuccess;
}
BOOL SetupNamedPipe (PHANDLE phPipe, LPTSTR szPipeName)
{
PACL pDacl = NULL;
DWORD cbDacl;
SECURITY_ATTRIBUTES sa = {0};
SECURITY_DESCRIPTOR sd = {0};
BOOL bSuccess = FALSE;
__try
{
*phPipe = INVALID_HANDLE_VALUE;
if (!InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION)) {
HandleError(GetLastError(),TEXT("InitializeSecurityDescriptor"),TRUE,TRUE);
__leave;
}
if (!BuildGenericAccessAcl(&pDacl,&cbDacl)) {
HandleError(0,TEXT("Error setting up pipe dacl"),FALSE,TRUE);
__leave;
}
if (!SetSecurityDescriptorDacl(&sd,TRUE,pDacl,FALSE)) {
HandleError(GetLastError(),TEXT("SetSecurityDescriptorDacl"),TRUE,TRUE);
__leave;
}
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
// setup pipe and wait for a connection
*phPipe = CreateNamedPipe( szPipeName,
FILE_FLAG_OVERLAPPED|PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE |PIPE_READMODE_MESSAGE|PIPE_WAIT,1,0,0,
NMPWAIT_USE_DEFAULT_WAIT,&sa);
if (*phPipe == INVALID_HANDLE_VALUE) {
HandleError(GetLastError(),TEXT("CreateNamedPipe"),TRUE,TRUE);
__leave;
}
bSuccess = TRUE;
}
__finally {
// free mem BuildGenericAccessAcl allocated
if (pDacl) { LocalFree(pDacl);}
}
return bSuccess;
}
BOOL WriteToPipe(HANDLE hPipe, BYTE* pData, DWORD cbData)
{
DWORD dwErr;
BOOL bRet = TRUE;
INT nBytesWrote = 0;
bRet = WriteFile(hPipe,pData,cbData,&nBytesWrote,NULL);
if (!bRet)
{
dwErr = GetLastError();
// if ERROR_BROKEN_PIPE or ERROR_NO_DATA then pipe naturally ended
if ( !( dwErr == ERROR_BROKEN_PIPE || dwErr == ERROR_NO_DATA))
HandleError(dwErr,TEXT("WriteFile"),TRUE,TRUE);
}
return bRet;
}
DWORD ReadFromPipe(HANDLE hPipe, BYTE* pBuffer, DWORD cbBuffer)
{
DWORD dwErr;
BOOL bRet = TRUE;
INT nBytesRead = 0;
bRet = ReadFile(hPipe, pBuffer, cbBuffer, &nBytesRead, NULL);
if (!bRet)
{
dwErr = GetLastError();
// if ERROR_BROKEN_PIPE or ERROR_NO_DATA then pipe naturally ended
if ( !( dwErr == ERROR_BROKEN_PIPE || dwErr == ERROR_NO_DATA))
HandleError(dwErr,TEXT("ReadFile"),TRUE,TRUE);
}
return nBytesRead;
}