windows-nt/Source/XPSP1/NT/base/subsys/sm/sfc/files/sfcfiles.c

368 lines
7.1 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
sfcfiles.c
Abstract:
Routines to initialize and retrieve a list of files to be proected by the
system.
Author:
Wesley Witt (wesw) 18-Dec-1998
Revision History:
Andrew Ritz (andrewr) 2-Jul-199 -- added comments
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "sfcfiles.h"
#if defined(_AMD64_)
#include "amd64_wks.h"
#elif defined(_IA64_)
#include "ia64_wks.h"
#elif defined(_X86_)
#include "x86_per.h"
#undef SFCFILES_SKU_TABLET
#undef SFCFILES_SKU_MEDIA
#include "x86_wks.h"
#define SFCFILES_SKU_TABLET
#include "x86_wks.h"
#undef SFCFILES_SKU_TABLET
#define SFCFILES_SKU_MEDIA
#include "x86_wks.h"
#else
#error "No Target Platform"
#endif
//
// Globals
//
//
// module handle
//
HMODULE SfcInstanceHandle;
//
// pointer to tier2 files for this system
//
PPROTECT_FILE_ENTRY Tier2Files;
//
// number of files in the tier 2 list. there must always be at least one file
// in the list of protected files
//
ULONG CountTier2Files;
DWORD
SfcDllEntry(
HINSTANCE hInstance,
DWORD Reason,
LPVOID Context
)
/*++
Routine Description:
Main Dll Entrypoint
Arguments:
hInstance - handle to dll module
Reason - reason for calling function
Context - reserved
Return Value:
always TRUE
--*/
{
if (Reason == DLL_PROCESS_ATTACH) {
SfcInstanceHandle = hInstance;
//
// we don't need thread attach/detach notifications
//
LdrDisableThreadCalloutsForDll( hInstance );
}
return TRUE;
}
#if !defined(_AMD64_) && !defined(_IA64_)
DWORD
SfcReadDwordRegVal(
PCWSTR szKeyName,
PCWSTR szValueName,
DWORD dwDefaultVal
)
{
NTSTATUS Status;
DWORD dwRet = dwDefaultVal;
HKEY hKey = NULL;
UNICODE_STRING Name;
OBJECT_ATTRIBUTES Attrs;
ULONG Length;
//
// This will be larger than we actually need
//
struct {
KEY_VALUE_PARTIAL_INFORMATION Info;
DWORD dwData;
} Buffer;
RtlInitUnicodeString(&Name, szKeyName);
InitializeObjectAttributes(&Attrs, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &Attrs);
if(!NT_SUCCESS(Status)) {
hKey = NULL;
goto exit;
}
RtlInitUnicodeString(&Name, szValueName);
Status = NtQueryValueKey(hKey, &Name, KeyValuePartialInformation, (PVOID) &Buffer, sizeof(Buffer), &Length);
if(!NT_SUCCESS(Status) || Buffer.Info.Type != REG_DWORD || Buffer.Info.DataLength != sizeof(DWORD)) {
goto exit;
}
dwRet = *((LPDWORD) Buffer.Info.Data);
exit:
if(hKey != NULL) {
NtClose(hKey);
}
return dwRet;
}
static const WCHAR szTabletPCKey[] = L"\\Registry\\Machine\\System\\WPA\\TabletPC";
static const WCHAR szTabletPCValue[] = L"Installed";
static const WCHAR szMediaCenterKey[] = L"\\Registry\\Machine\\System\\WPA\\MediaCenter";
static const WCHAR szMediaCenterValue[] = L"Installed";
FORCEINLINE
BOOL
SfcIsTabletPC(
VOID
)
{
return SfcReadDwordRegVal(szTabletPCKey, szTabletPCValue, 0) != 0;
}
FORCEINLINE
BOOL
SfcIsMediaCenter(
VOID
)
{
return SfcReadDwordRegVal(szMediaCenterKey, szMediaCenterValue, 0) != 0;
}
#endif
NTSTATUS
SfcFilesInit(
void
)
/*++
Routine Description:
Initialization routine. This routine must be called before
SfcGetFiles() can do any work. The initialization routine
determines what embedded file list we should use based on
product type and architecture.
Arguments:
NONE.
Return Value:
NTSTATUS code indicating outcome.
--*/
{
NTSTATUS Status;
OSVERSIONINFOEXW ver;
//
// set the tier2 file pointer based on the product we're running on
//
//
// retrieve product information
//
RtlZeroMemory( &ver, sizeof(ver) );
ver.dwOSVersionInfoSize = sizeof(ver);
Status = RtlGetVersion( (LPOSVERSIONINFOW)&ver );
if (!NT_SUCCESS(Status)) {
return Status;
}
if (ver.wProductType == VER_NT_WORKSTATION) {
#if !defined(_AMD64_) && !defined(_IA64_)
if (ver.wSuiteMask & VER_SUITE_PERSONAL)
{
Tier2Files = PerFiles;
CountTier2Files = CountPerFiles;
}
else if(SfcIsTabletPC()) {
Tier2Files = TabFiles;
CountTier2Files = CountTabFiles;
}
else if(SfcIsMediaCenter()) {
Tier2Files = MedFiles;
CountTier2Files = CountMedFiles;
}
else
#endif
{
Tier2Files = WksFiles;
CountTier2Files = CountWksFiles;
}
} else {
return STATUS_NOT_SUPPORTED;
}
return STATUS_SUCCESS;
}
NTSTATUS
SfcGetFiles(
OUT PPROTECT_FILE_ENTRY *Files,
OUT PULONG FileCount
)
/*++
Routine Description:
Retreives pointers to the file list and file count. Note that we refer to
a "tier2" list here but in actuality there is no tier 1 list.
Arguments:
Files - pointer to a PPROTECT_FILE_ENTRY, which is filled in with a pointer
to the actual protected files list.
FileCount - pointer to a ULONG which is filled in with the file count.
Return Value:
NTSTATUS code indicating outcome.
--*/
{
NTSTATUS Status;
if (CountTier2Files == 0) {
Status = SfcFilesInit();
if (!NT_SUCCESS(Status)) {
*Files = NULL;
*FileCount = 0;
return Status;
}
}
ASSERT(Tier2Files != NULL);
ASSERT(CountTier2Files != 0);
*Files = Tier2Files;
*FileCount = CountTier2Files;
return STATUS_SUCCESS;
}
NTSTATUS
pSfcGetFilesList(
IN DWORD ListMask,
OUT PPROTECT_FILE_ENTRY *Files,
OUT PULONG FileCount
)
/*++
Routine Description:
Retreives pointers to the requested file list and file count.
This is an internal testing routine that is used so that we can retrieve
any file list on a given machine so testing does not have to install more
than one build to get at multiple file lists
Arguments:
ListMask - specifies a SFCFILESMASK_* constant
Files - pointer to a PPROTECT_FILE_ENTRY, which is filled in with a pointer
to the actual protected files list.
FileCount - pointer to a ULONG which is filled in with the file count.
Return Value:
NTSTATUS code indicating outcome.
--*/
{
NTSTATUS RetVal = STATUS_SUCCESS;
if (!Files || !FileCount) {
return(STATUS_INVALID_PARAMETER);
}
switch (ListMask) {
case SFCFILESMASK_PROFESSIONAL:
*Files = WksFiles;
*FileCount = CountWksFiles;
break;
#if !defined(_AMD64_) && !defined(_IA64_)
case SFCFILESMASK_PERSONAL:
*Files = PerFiles;
*FileCount = CountPerFiles;
break;
case SFCFILESMASK_TABLET:
*Files = TabFiles;
*FileCount = CountTabFiles;
break;
case SFCFILESMASK_MEDIACTR:
*Files = MedFiles;
*FileCount = CountMedFiles;
break;
#endif
default:
RetVal = STATUS_INVALID_PARAMETER;
}
return RetVal;
}