windows-nt/Source/XPSP1/NT/base/tools/instaler/handledb.c
2020-09-26 16:20:57 +08:00

173 lines
3.8 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
handledb.c
Abstract:
This module contains the code to maintain an open handle data base for the
INSTALER program. This is used to track path names associated with open
handles so we can construct full paths from relative opens.
Author:
Steve Wood (stevewo) 11-Aug-1994
Revision History:
--*/
#include "instaler.h"
char *HandleTypes[] = {
"File/Key",
"File",
"Key"
};
POPENHANDLE_INFO
FindOpenHandle(
PPROCESS_INFO Process,
HANDLE Handle,
ULONG Type
)
{
PLIST_ENTRY Next, Head;
POPENHANDLE_INFO p;
Head = &Process->OpenHandleListHead;
Next = Head->Flink;
while (Next != Head) {
p = CONTAINING_RECORD( Next, OPENHANDLE_INFO, Entry );
if (p->Handle == Handle && (Type == (ULONG)-1 || p->Type == Type)) {
return p;
}
Next = Next->Flink;
}
return NULL;
}
BOOLEAN
AddOpenHandle(
PPROCESS_INFO Process,
HANDLE Handle,
ULONG Type,
PWSTR Name,
BOOLEAN InheritHandle
)
{
POPENHANDLE_INFO p;
if (Type == (ULONG)-1) {
return FALSE;
}
if (FindOpenHandle( Process, Handle, Type ) != NULL) {
return FALSE;
}
p = AllocMem( sizeof( *p ) );
if (p == NULL) {
return FALSE;
}
p->Handle = Handle;
p->Type = (USHORT)Type;
p->Inherit = InheritHandle;
p->Name = Name;
p->LengthOfName = (USHORT)(wcslen( Name ) * sizeof( WCHAR ));
if (Type == HANDLE_TYPE_FILE && p->LengthOfName == (3 * sizeof( WCHAR ))) {
p->RootDirectory = TRUE;
}
InsertHeadList( &Process->OpenHandleListHead, &p->Entry );
return TRUE;
}
BOOLEAN
DeleteOpenHandle(
PPROCESS_INFO Process,
HANDLE Handle,
ULONG Type
)
{
POPENHANDLE_INFO p;
p = FindOpenHandle( Process, Handle, Type );
if (p == NULL) {
//
// We will see lots of close calls for handles we dont care
// about. Ignore them quietly.
//
return FALSE;
}
RemoveEntryList( &p->Entry );
FreeMem( &p->QueryName );
FreeMem( &p );
return TRUE;
}
static BOOLEAN IgnoredFirstProcess = FALSE;
VOID
InheritHandles(
PPROCESS_INFO Process
)
{
PPROCESS_INFO ParentProcess;
PLIST_ENTRY Prev, Head;
POPENHANDLE_INFO p;
if (Process->ProcessInformation.InheritedFromUniqueProcessId == 0) {
return;
}
ParentProcess = FindProcessById( Process->ProcessInformation.InheritedFromUniqueProcessId );
if (ParentProcess == NULL) {
if (!IgnoredFirstProcess) {
IgnoredFirstProcess = TRUE;
}
else {
DbgEvent( INTERNALERROR, ("Unable to find parent process (%x)\n", Process->ProcessInformation.InheritedFromUniqueProcessId ) );
}
return;
}
Head = &ParentProcess->OpenHandleListHead;
Prev = Head->Blink;
while (Prev != Head) {
p = CONTAINING_RECORD( Prev, OPENHANDLE_INFO, Entry );
if (p->Inherit) {
if (!AddOpenHandle( Process,
p->Handle,
p->Type,
p->Name,
TRUE
)
) {
DbgEvent( INTERNALERROR, ("Unable to inherit %s handle (%x) for '%ws' from process (%x)\n",
HandleTypes[ 1+p->Type ],
p->Handle,
p->Name,
Process->ProcessInformation.InheritedFromUniqueProcessId
)
);
}
}
Prev = Prev->Blink;
}
return;
}