mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
442 lines
13 KiB
442 lines
13 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Spnetupg.c
|
|
|
|
Abstract:
|
|
|
|
Configuration routines for the disabling the nework services
|
|
|
|
Author:
|
|
|
|
Terry Kwan (terryk) 23-Nov-1993, provided code
|
|
Sunil Pai (sunilp) 23-Nov-1993, merged and modified code
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "spprecmp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
// Add item to the link list
|
|
|
|
NTSTATUS
|
|
SppNetAddItem(
|
|
PNODE *head,
|
|
PWSTR psz
|
|
)
|
|
{
|
|
NTSTATUS err = STATUS_SUCCESS;
|
|
|
|
*head = (PNODE)SpMemAlloc(sizeof(NODE));
|
|
if ( *head == NULL )
|
|
{
|
|
err = STATUS_NO_MEMORY;
|
|
} else
|
|
{
|
|
(*head)->pszService = (PWSTR) SpMemAlloc((wcslen(psz)+1)*sizeof(WCHAR));
|
|
if (((*head)->pszService)==NULL)
|
|
{
|
|
err = STATUS_NO_MEMORY;
|
|
} else
|
|
{
|
|
wcscpy((*head)->pszService,psz);
|
|
(*head)->Next = NULL;
|
|
}
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
NTSTATUS
|
|
SppNetAddList(
|
|
PNODE *head,
|
|
PWSTR psz
|
|
)
|
|
{
|
|
NTSTATUS err = STATUS_SUCCESS;
|
|
if ( *head == NULL )
|
|
{
|
|
err = SppNetAddItem( head, psz );
|
|
} else
|
|
{
|
|
PNODE pnodeTmp = *head;
|
|
while ((_wcsicmp(pnodeTmp->pszService,psz)!=0) && ( pnodeTmp->Next != NULL ))
|
|
pnodeTmp = pnodeTmp->Next;
|
|
|
|
if (_wcsicmp(pnodeTmp->pszService,psz)!=0)
|
|
{
|
|
// add only if not equal
|
|
err = SppNetAddItem( &(pnodeTmp->Next), psz );
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
|
|
// Clear up the link list
|
|
|
|
VOID
|
|
SppNetClearList(
|
|
PNODE *head
|
|
)
|
|
{
|
|
if ( *head != NULL )
|
|
{
|
|
if ((*head)->Next != NULL )
|
|
{
|
|
SppNetClearList(&((*head)->Next));
|
|
} else
|
|
{
|
|
SpMemFree ((*head)->pszService);
|
|
SpMemFree (*head);
|
|
(*head) = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// function to add a service to the NCPA\CurrentVersion\DisableList
|
|
|
|
NTSTATUS SppNetAddToDisabledList(
|
|
IN PWSTR pszService,
|
|
IN HANDLE hKeySoftware
|
|
)
|
|
{
|
|
NTSTATUS err = STATUS_SUCCESS;
|
|
HANDLE VersionKey;
|
|
PUCHAR buffer;
|
|
ULONG BufferSize;
|
|
PWSTR pszDisableList;
|
|
PWSTR pszTmp;
|
|
DWORD cbSize;
|
|
BOOL fExist;
|
|
OBJECT_ATTRIBUTES Obja;
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION)+2000;
|
|
buffer = SpMemAlloc(BufferSize);
|
|
|
|
do {
|
|
INIT_OBJA(&Obja, &UnicodeString, L"Microsoft\\Ncpa\\CurrentVersion");
|
|
Obja.RootDirectory = hKeySoftware;
|
|
|
|
if (!NT_SUCCESS( err = ZwOpenKey(&VersionKey, KEY_ALL_ACCESS, &Obja))){
|
|
break;
|
|
}
|
|
|
|
RtlInitUnicodeString(&UnicodeString, L"DisableList");
|
|
|
|
if (NT_SUCCESS(err = ZwQueryValueKey(VersionKey,&UnicodeString,
|
|
KeyValuePartialInformation,buffer,BufferSize,&cbSize))) {
|
|
|
|
// it exists
|
|
pszDisableList = (PWSTR)(((PKEY_VALUE_PARTIAL_INFORMATION)buffer)->Data);
|
|
// the old buffer size
|
|
cbSize = (((PKEY_VALUE_PARTIAL_INFORMATION)buffer)->DataLength);
|
|
fExist = TRUE;
|
|
|
|
}
|
|
else {
|
|
// not exists
|
|
pszDisableList = (PWSTR) SpMemAlloc((wcslen(pszService)+2)*sizeof(WCHAR));
|
|
if ( pszDisableList == NULL )
|
|
{
|
|
err = STATUS_NO_MEMORY;
|
|
ZwClose( VersionKey );
|
|
break;
|
|
}
|
|
fExist = FALSE;
|
|
// the last multi_sz terminate character
|
|
cbSize = sizeof(WCHAR);
|
|
}
|
|
|
|
pszTmp = pszDisableList;
|
|
if ( fExist ) {
|
|
// search until the end
|
|
pszTmp += (((PKEY_VALUE_PARTIAL_INFORMATION)buffer)->DataLength)/sizeof(WCHAR)-1;
|
|
}
|
|
|
|
// save the service name to the end of the
|
|
// DisableList Multi_SZ.
|
|
|
|
wcscpy(pszTmp, pszService );
|
|
pszTmp[wcslen(pszService)+1]=L'\0';
|
|
err = ZwSetValueKey(VersionKey,&UnicodeString,0,REG_MULTI_SZ, pszDisableList, cbSize+(wcslen(pszService)+1)*sizeof(WCHAR));
|
|
ZwClose(VersionKey);
|
|
|
|
} while ( FALSE );
|
|
SpMemFree(buffer);
|
|
return err;
|
|
}
|
|
|
|
// Get all the net service in the registry and put them in a link list
|
|
|
|
NTSTATUS SppNetGetAllNetServices(
|
|
PVOID SifHandle,
|
|
PNODE *head,
|
|
HANDLE hKeySoftware,
|
|
HANDLE hKeyCCSet
|
|
)
|
|
{
|
|
NTSTATUS err = STATUS_SUCCESS;
|
|
HANDLE MicrosoftKey;
|
|
HANDLE NetRulesKey;
|
|
PWSTR pszMicrosoftProductVersion;
|
|
PWSTR pszMicrosoftProductNetRules;
|
|
DWORD cchName;
|
|
PNODE tmpNode;
|
|
OBJECT_ATTRIBUTES Obja;
|
|
UNICODE_STRING UnicodeString;
|
|
PUCHAR buffer;
|
|
ULONG BufferSize,ServiceNameBufferSize,DependOnServiceBufferSize,PathBufferSize;
|
|
INT i, NumberOfValues;
|
|
PWSTR CurrentService;
|
|
PUCHAR ServiceNameBuffer;
|
|
PUCHAR DependOnServiceBuffer;
|
|
PWSTR pszPath;
|
|
|
|
pszMicrosoftProductVersion = SpMemAlloc((MAX_PATH+1+30)*sizeof(WCHAR));
|
|
pszMicrosoftProductNetRules = SpMemAlloc((MAX_PATH+1+30)*sizeof(WCHAR));
|
|
BufferSize = sizeof(KEY_BASIC_INFORMATION)+200;
|
|
ServiceNameBufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100;
|
|
DependOnServiceBufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION)+1000;
|
|
PathBufferSize = (MAX_PATH+1000)*sizeof(WCHAR);
|
|
buffer = SpMemAlloc(BufferSize);
|
|
ServiceNameBuffer = SpMemAlloc(ServiceNameBufferSize);
|
|
DependOnServiceBuffer = SpMemAlloc(DependOnServiceBufferSize);
|
|
pszPath = SpMemAlloc(PathBufferSize);
|
|
|
|
do {
|
|
INIT_OBJA(&Obja, &UnicodeString, L"Microsoft");
|
|
Obja.RootDirectory = hKeySoftware;
|
|
|
|
if (!NT_SUCCESS( err = ZwOpenKey(&MicrosoftKey, KEY_ALL_ACCESS, &Obja))){
|
|
break;
|
|
}
|
|
for( i = 0; NT_SUCCESS(ZwEnumerateKey(MicrosoftKey,i,
|
|
KeyBasicInformation,buffer,BufferSize,&cchName)); i++ ) {
|
|
// for each item under Software\Microsoft, check whether they
|
|
// are network component
|
|
((PKEY_BASIC_INFORMATION)buffer)->Name[((PKEY_BASIC_INFORMATION)buffer)->NameLength/sizeof(WCHAR)]=L'\0';
|
|
wcscpy(pszMicrosoftProductNetRules, ((PKEY_BASIC_INFORMATION)buffer)->Name);
|
|
wcscat(pszMicrosoftProductNetRules, L"\\CurrentVersion\\NetRules");
|
|
|
|
INIT_OBJA(&Obja, &UnicodeString, pszMicrosoftProductNetRules);
|
|
Obja.RootDirectory = MicrosoftKey;
|
|
|
|
if (NT_SUCCESS( err = ZwOpenKey(&NetRulesKey, KEY_ALL_ACCESS, &Obja)))
|
|
{
|
|
// if we can only the NetRule key, then it is for sure a
|
|
// network component
|
|
|
|
HANDLE VersionKey;
|
|
DWORD cbSize;
|
|
UNICODE_STRING ServiceNameString;
|
|
|
|
ZwClose( NetRulesKey );
|
|
|
|
wcscpy(pszMicrosoftProductVersion, ((PKEY_BASIC_INFORMATION)buffer)->Name);
|
|
wcscat(pszMicrosoftProductVersion, L"\\CurrentVersion");
|
|
|
|
INIT_OBJA(&Obja, &UnicodeString, pszMicrosoftProductVersion);
|
|
Obja.RootDirectory = MicrosoftKey;
|
|
|
|
RtlInitUnicodeString(&ServiceNameString, L"ServiceName");
|
|
|
|
if ((!NT_SUCCESS( err = ZwOpenKey(&VersionKey, KEY_ALL_ACCESS, &Obja)))) {
|
|
continue;
|
|
}
|
|
if ((!NT_SUCCESS( err = ZwQueryValueKey(VersionKey,
|
|
&ServiceNameString,
|
|
KeyValuePartialInformation,
|
|
ServiceNameBuffer,
|
|
ServiceNameBufferSize,
|
|
&cbSize))) ||
|
|
(!NT_SUCCESS(SppNetAddList(head,(PWSTR)((PKEY_VALUE_PARTIAL_INFORMATION)ServiceNameBuffer)->Data))))
|
|
{
|
|
ZwClose( VersionKey );
|
|
continue;
|
|
}
|
|
ZwClose( VersionKey );
|
|
}
|
|
}
|
|
ZwClose( MicrosoftKey );
|
|
err = STATUS_SUCCESS;
|
|
|
|
// find out each dependencies
|
|
|
|
for(tmpNode = *head;(tmpNode != NULL) && NT_SUCCESS(err);tmpNode=tmpNode->Next)
|
|
{
|
|
HANDLE ServiceKey;
|
|
DWORD cbSize;
|
|
PWSTR pszDependOnService;
|
|
UNICODE_STRING DependOnServiceString;
|
|
|
|
wcscpy(pszPath,L"Services\\");
|
|
wcscat(pszPath,tmpNode->pszService);
|
|
|
|
INIT_OBJA(&Obja, &UnicodeString, pszPath);
|
|
Obja.RootDirectory = hKeyCCSet;
|
|
|
|
RtlInitUnicodeString(&DependOnServiceString, L"DependOnService");
|
|
|
|
if ((!NT_SUCCESS( err = ZwOpenKey(&ServiceKey, KEY_ALL_ACCESS, &Obja)))) {
|
|
err = STATUS_SUCCESS;
|
|
continue;
|
|
}
|
|
|
|
if ((!NT_SUCCESS( err = ZwQueryValueKey(ServiceKey,
|
|
&DependOnServiceString,
|
|
KeyValuePartialInformation,
|
|
DependOnServiceBuffer,
|
|
DependOnServiceBufferSize,
|
|
&cbSize)))) {
|
|
// does not exit
|
|
err = STATUS_SUCCESS;
|
|
ZwClose(ServiceKey);
|
|
continue;
|
|
}
|
|
ZwClose(ServiceKey);
|
|
|
|
pszDependOnService = (PWSTR)(((PKEY_VALUE_PARTIAL_INFORMATION)DependOnServiceBuffer)->Data);
|
|
|
|
// Add each dependencies into the list
|
|
for( CurrentService=pszDependOnService;(*CurrentService!=L'\0') && NT_SUCCESS(err);)
|
|
{
|
|
err = SppNetAddList( head, CurrentService);
|
|
while ((*CurrentService)!=L'\0')
|
|
CurrentService++;
|
|
// skip the terminated character
|
|
CurrentService++;
|
|
}
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Add other net services to disable to the list from the section
|
|
// SIF_NET_SERVICES_TO_DISABLE
|
|
//
|
|
|
|
NumberOfValues = SpCountLinesInSection(SifHandle, SIF_NET_SERVICES_TO_DISABLE);
|
|
for(i = 0; NT_SUCCESS(err) && i < NumberOfValues ; i++) {
|
|
CurrentService = SpGetSectionLineIndex(SifHandle, SIF_NET_SERVICES_TO_DISABLE, i, 0);
|
|
if( CurrentService == NULL ) {
|
|
SpFatalSifError(SifHandle,SIF_NET_SERVICES_TO_DISABLE,NULL,i,0);
|
|
}
|
|
err = SppNetAddList( head, CurrentService );
|
|
}
|
|
SpMemFree(pszMicrosoftProductVersion);
|
|
SpMemFree(pszMicrosoftProductNetRules);
|
|
SpMemFree(buffer);
|
|
SpMemFree(ServiceNameBuffer);
|
|
SpMemFree(DependOnServiceBuffer);
|
|
SpMemFree(pszPath);
|
|
return err;
|
|
}
|
|
|
|
// Disable Disable Network Component
|
|
|
|
NTSTATUS
|
|
SppNetDisableServices(
|
|
PNODE ServiceList,
|
|
HANDLE hKeySoftware,
|
|
HANDLE hKeyCCSet
|
|
)
|
|
{
|
|
PNODE tmpNode = ServiceList;
|
|
NTSTATUS err = STATUS_SUCCESS;
|
|
PWSTR pszPath;
|
|
PUCHAR buffer;
|
|
ULONG PathBufferSize,BufferSize;
|
|
|
|
PathBufferSize = (MAX_PATH+1000)*sizeof(WCHAR);
|
|
BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION)+200;
|
|
|
|
pszPath = SpMemAlloc(PathBufferSize);
|
|
buffer = SpMemAlloc(BufferSize);
|
|
|
|
for ( ; tmpNode != NULL; tmpNode = tmpNode->Next )
|
|
{
|
|
HKEY ServiceKey;
|
|
DWORD dwStart;
|
|
DWORD dwNewStart = 4;
|
|
DWORD cbSize = sizeof(DWORD);
|
|
OBJECT_ATTRIBUTES Obja;
|
|
UNICODE_STRING UnicodeString;
|
|
UNICODE_STRING StartString;
|
|
UNICODE_STRING OldStartString;
|
|
|
|
wcscpy(pszPath,L"Services\\");
|
|
wcscat(pszPath,tmpNode->pszService);
|
|
|
|
INIT_OBJA(&Obja, &UnicodeString, pszPath);
|
|
Obja.RootDirectory = hKeyCCSet;
|
|
|
|
if (!NT_SUCCESS( err = ZwOpenKey(&ServiceKey, KEY_ALL_ACCESS, &Obja))) {
|
|
continue;
|
|
}
|
|
|
|
RtlInitUnicodeString(&StartString, L"Start");
|
|
RtlInitUnicodeString(&OldStartString, L"OldStart");
|
|
|
|
if (NT_SUCCESS( err = ZwQueryValueKey(ServiceKey,
|
|
&OldStartString,
|
|
KeyValuePartialInformation,
|
|
buffer,
|
|
BufferSize,
|
|
&cbSize))) {
|
|
// already exist OldStart, so skip this one.
|
|
ZwClose(ServiceKey);
|
|
continue;
|
|
}
|
|
|
|
if (!NT_SUCCESS( err = ZwQueryValueKey(ServiceKey,
|
|
&StartString,
|
|
KeyValuePartialInformation,
|
|
buffer,
|
|
BufferSize,
|
|
&cbSize))) {
|
|
ZwClose(ServiceKey);
|
|
continue;
|
|
}
|
|
dwStart = *((DWORD*)(&(((PKEY_VALUE_PARTIAL_INFORMATION)buffer)->Data)));
|
|
|
|
if ((!NT_SUCCESS(err = ZwSetValueKey(ServiceKey,&OldStartString,0,REG_DWORD, &dwStart, sizeof(DWORD)))) ||
|
|
(!NT_SUCCESS(err = ZwSetValueKey(ServiceKey,&StartString,0,REG_DWORD, &dwNewStart, sizeof(DWORD)))) ||
|
|
(!NT_SUCCESS(err = SppNetAddToDisabledList( tmpNode->pszService, hKeySoftware )))) {
|
|
ZwClose(ServiceKey);
|
|
continue;
|
|
}
|
|
ZwClose(ServiceKey);
|
|
}
|
|
SpMemFree(pszPath);
|
|
SpMemFree(buffer);
|
|
return(err);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS SpDisableNetwork(
|
|
IN PVOID SifHandle,
|
|
IN HANDLE hKeySoftwareHive,
|
|
IN HANDLE hKeyControlSet
|
|
)
|
|
{
|
|
PNODE ServiceList = NULL;
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
|
Status = SppNetGetAllNetServices( SifHandle, &ServiceList, hKeySoftwareHive, hKeyControlSet );
|
|
if(!NT_SUCCESS(Status)) {
|
|
return(Status);
|
|
}
|
|
Status = SppNetDisableServices( ServiceList, hKeySoftwareHive, hKeyControlSet );
|
|
SppNetClearList( &ServiceList );
|
|
return Status;
|
|
}
|