368 lines
7.1 KiB
C
368 lines
7.1 KiB
C
/*++
|
|
|
|
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;
|
|
|
|
}
|