windows-nt/Source/XPSP1/NT/base/screg/winreg/perflib/perfsec.c
2020-09-26 16:20:57 +08:00

354 lines
8.6 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++ BUILD Version: 0001 // Increment this if a change has global effects
Copyright (c) 1992-1994 Microsoft Corporation
Module Name:
perfsec.c
Abstract:
This file implements the _access checking functions used by the
performance registry API's
Author:
Bob Watson (a-robw)
Revision History:
8-Mar-95 Created (and extracted from Perflib.c
--*/
#define UNICODE
//
// Include files
//
#pragma warning(disable:4306)
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "ntconreg.h"
#include "perflib.h"
#pragma warning(default:4306)
#define INITIAL_SID_BUFFER_SIZE 4096
#define FREE_IF_ALLOC(x) if ((x) != NULL) {FREEMEM(x);}
BOOL
TestTokenForPriv(
HANDLE hToken,
LPTSTR szPrivName
)
/***************************************************************************\
* TestTokenForPriv
*
* Returns TRUE if the token passed has the specified privilege
*
* The token handle passed must have TOKEN_QUERY access.
*
* History:
* 03-07-95 a-robw Created
\***************************************************************************/
{
BOOL bStatus;
LUID PrivLuid;
PRIVILEGE_SET PrivSet;
LUID_AND_ATTRIBUTES PrivLAndA[1];
BOOL bReturn = FALSE;
// get value of priv
bStatus = LookupPrivilegeValue (
NULL,
szPrivName,
&PrivLuid);
if (!bStatus) {
// unable to lookup privilege
goto Exit_Point;
}
// build Privilege Set for function call
PrivLAndA[0].Luid = PrivLuid;
PrivLAndA[0].Attributes = 0;
PrivSet.PrivilegeCount = 1;
PrivSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
PrivSet.Privilege[0] = PrivLAndA[0];
// check for the specified priv in the token
bStatus = PrivilegeCheck (
hToken,
&PrivSet,
&bReturn);
if (bStatus) {
SetLastError (ERROR_SUCCESS);
}
//
// Tidy up
//
Exit_Point:
return(bReturn);
}
BOOL
TestClientForPriv (
BOOL *pbThread,
LPTSTR szPrivName
)
/***************************************************************************\
* TestClientForPriv
*
* Returns TRUE if our client has the specified privilege
* Otherwise, returns FALSE.
*
\***************************************************************************/
{
BOOL bResult;
BOOL bIgnore;
DWORD dwLastError;
BOOL bThreadFlag = FALSE; // assume data is from process or an error occurred
HANDLE hClient;
SetLastError (ERROR_SUCCESS);
bResult = OpenThreadToken(GetCurrentThread(), // This Thread
TOKEN_QUERY, //DesiredAccess
FALSE, // use context of calling thread
&hClient); //TokenHandle
if (!bResult) {
// unable to get a Thread Token, try a Process Token
bResult = OpenProcessToken(GetCurrentProcess(), // This Process
TOKEN_QUERY, //DesiredAccess
&hClient); //TokenHandle
} else {
// data is from current THREAD
bThreadFlag = TRUE;
}
if (bResult) {
try {
bResult = TestTokenForPriv( hClient, szPrivName );
} except (EXCEPTION_EXECUTE_HANDLER) {
bResult = FALSE;
}
bIgnore = CloseHandle( hClient );
ASSERT(bIgnore == TRUE);
} else {
dwLastError = GetLastError ();
}
// set thread flag if present
if (pbThread != NULL) {
try {
*pbThread = bThreadFlag;
} except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError (ERROR_INVALID_PARAMETER);
}
}
return(bResult);
}
LONG
GetProcessNameColMeth (
VOID
)
{
NTSTATUS Status;
HANDLE hPerflibKey;
OBJECT_ATTRIBUTES oaPerflibKey;
UNICODE_STRING PerflibSubKeyString;
UNICODE_STRING NameInfoValueString;
LONG lReturn = PNCM_SYSTEM_INFO;
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
DWORD dwBufLen;
DWORD dwRetBufLen;
PDWORD pdwValue;
RtlInitUnicodeString (
&PerflibSubKeyString,
L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");
InitializeObjectAttributes(
&oaPerflibKey,
&PerflibSubKeyString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = NtOpenKey(
&hPerflibKey,
MAXIMUM_ALLOWED,
&oaPerflibKey
);
if (NT_SUCCESS (Status)) {
// registry key opened, now read value.
// allocate enough room for the structure, - the last
// UCHAR in the struct, but + the data buffer (a dword)
dwBufLen = sizeof(KEY_VALUE_PARTIAL_INFORMATION) -
sizeof(UCHAR) + sizeof (DWORD);
pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ALLOCMEM (dwBufLen);
if (pKeyInfo != NULL) {
// initialize value name string
RtlInitUnicodeString (
&NameInfoValueString,
L"CollectUnicodeProcessNames");
dwRetBufLen = 0;
Status = NtQueryValueKey (
hPerflibKey,
&NameInfoValueString,
KeyValuePartialInformation,
(PVOID)pKeyInfo,
dwBufLen,
&dwRetBufLen);
if (NT_SUCCESS(Status)) {
// check value of return data buffer
pdwValue = (PDWORD)&pKeyInfo->Data[0];
if (*pdwValue == PNCM_MODULE_FILE) {
lReturn = PNCM_MODULE_FILE;
} else {
// all other values will cause this routine to return
// the default value of PNCM_SYSTEM_INFO;
}
}
FREEMEM (pKeyInfo);
}
// close handle
NtClose (hPerflibKey);
}
return lReturn;
}
LONG
GetPerfDataAccess (
VOID
)
{
NTSTATUS Status;
HANDLE hPerflibKey;
OBJECT_ATTRIBUTES oaPerflibKey;
UNICODE_STRING PerflibSubKeyString;
UNICODE_STRING NameInfoValueString;
LONG lReturn = CPSR_EVERYONE;
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
DWORD dwBufLen;
DWORD dwRetBufLen;
PDWORD pdwValue;
RtlInitUnicodeString (
&PerflibSubKeyString,
L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");
InitializeObjectAttributes(
&oaPerflibKey,
&PerflibSubKeyString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = NtOpenKey(
&hPerflibKey,
MAXIMUM_ALLOWED,
&oaPerflibKey
);
if (NT_SUCCESS (Status)) {
// registry key opened, now read value.
// allocate enough room for the structure, - the last
// UCHAR in the struct, but + the data buffer (a dword)
dwBufLen = sizeof(KEY_VALUE_PARTIAL_INFORMATION) -
sizeof(UCHAR) + sizeof (DWORD);
pKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ALLOCMEM (dwBufLen);
if (pKeyInfo != NULL) {
// see if the user right should be checked
// init value name string
RtlInitUnicodeString (
&NameInfoValueString,
L"CheckProfileSystemRight");
dwRetBufLen = 0;
Status = NtQueryValueKey (
hPerflibKey,
&NameInfoValueString,
KeyValuePartialInformation,
(PVOID)pKeyInfo,
dwBufLen,
&dwRetBufLen);
if (NT_SUCCESS(Status)) {
// check value of return data buffer
pdwValue = (PDWORD)&pKeyInfo->Data[0];
if (*pdwValue == CPSR_CHECK_ENABLED) {
lReturn = CPSR_CHECK_PRIVS;
} else {
// all other values will cause this routine to return
// the default value of CPSR_EVERYONE
}
}
FREEMEM (pKeyInfo);
}
// close handle
NtClose (hPerflibKey);
}
return lReturn;
}
BOOL
TestClientForAccess (
VOID
)
/***************************************************************************\
* TestClientForAccess
*
* Returns TRUE if our client is allowed to read the perflib key.
* Otherwise, returns FALSE.
*
\***************************************************************************/
{
HKEY hKeyPerflib;
DWORD dwStatus;
BOOL bResult = FALSE;
dwStatus = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
0L,
KEY_READ,
& hKeyPerflib);
if (dwStatus == ERROR_SUCCESS) {
RegCloseKey(hKeyPerflib);
bResult = TRUE;
}
return (bResult);
}