Leaked source code of windows server 2003
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.
|
|
/****************************** Module Header ******************************\
* Module Name: libmgmt.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * This module contains the code to manage loading and freeing libraries * in use by USER. * * History: * 02-04-91 DavidPe Created. \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/*
* Globals local to this file * * * Number of hmodule entries in the module management table. */ int catomSysTableEntries;
/*
* Array of atoms that are the fully qualified path names of each managed * module. */ ATOM aatomSysLoaded[CLIBS];
/*
* Count of processes that have LoadModule()'d each module. */ int acatomSysUse[CLIBS];
/*
* Count of hooks set into each module. */ int acatomSysDepends[CLIBS];
/****************************************************************************\
* GetHmodTableIndex * * This routine is used to return the index of a given atom within the system * wide hmod atom table. If the atom is not found, an attempt to allocate a * new table entry is made. If the attempt fails, -1 is returned. * * History: * 02-04-91 DavidPe Ported. \****************************************************************************/
int GetHmodTableIndex( PUNICODE_STRING pstrLibName) { int i; ATOM atom; UNICODE_STRING strLibName;
/*
* Probe string */ try { strLibName = ProbeAndReadUnicodeString(pstrLibName); ProbeForReadUnicodeStringBuffer(strLibName); atom = UserAddAtom(strLibName.Buffer, FALSE); } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { return -1; }
/*
* If we can't add the atom we're hosed * so return an error. */ if (atom == 0) { return -1; }
/*
* Search for atom index */ for (i = 0; i < catomSysTableEntries && aatomSysLoaded[i] != atom; i++) ;
if (i == catomSysTableEntries) {
/*
* Find empty entry for atom */ for (i = 0; i < catomSysTableEntries && aatomSysLoaded[i]; i++) ;
/*
* Check if no empty entry found */ if (i == catomSysTableEntries) { if (i == CLIBS) { UserDeleteAtom(atom); RIPERR0(ERROR_NOT_ENOUGH_MEMORY, RIP_WARNING, "Memory allocation failed in GetHmodTableIndex");
return -1; }
/*
* Increase table size */ catomSysTableEntries++; }
/*
* Set entry */ aatomSysLoaded[i] = atom; acatomSysUse[i] = 0; acatomSysDepends[i] = 0; } else { UserDeleteAtom(atom); }
return i; }
/*****************************************************************************\
* AddHmodDependency * * This function merely increments the dependency count of a given hmod * atom table index. * * History: * 02-04-91 DavidPe Ported. \*****************************************************************************/
VOID AddHmodDependency( int iatom) { UserAssert(iatom >= 0); if (iatom < catomSysTableEntries) { acatomSysDepends[iatom]++; } }
/*****************************************************************************\
* RemoveHmodDependency * * This function removes a system dependency on a given index into the hmod * atom table. If all dependencies on the hmod have been removed (the Depends * count reaches zero) then the QS_SYSEXPUNGE bit is set in all message * queues so the eventually each process will do a free module on it. * * History: * 02-04-91 DavidPe Ported. \*****************************************************************************/
VOID RemoveHmodDependency( int iatom) {
UserAssert(iatom >= 0); if (iatom < catomSysTableEntries && --acatomSysDepends[iatom] == 0) {
if (acatomSysUse[iatom]) {
/*
* Cause each thread to check for expunged dlls * the next time they awake. */ gcSysExpunge++; gdwSysExpungeMask |= (1 << iatom); } else { aatomSysLoaded[iatom] = 0; } } }
/*****************************************************************************\
* xxxLoadHmodIndex * * This function attempts to load the hmodule specified by iatom into the * system hmod table. Updates the per-process bitmap accordingly. Returns * NULL on success. * * History: * 02-04-91 DavidPe Ported. \*****************************************************************************/
HANDLE xxxLoadHmodIndex( int iatom) { WCHAR pszLibName[MAX_PATH]; HANDLE hmod; UNICODE_STRING strLibrary; PTHREADINFO ptiCurrent = PtiCurrent();
UserAssert((!gptiRit || gptiRit->ppi != PtiCurrent()->ppi) && "Shouldn't load global hooks on system process - gptiRit->ppi is the system process");
if (iatom >= catomSysTableEntries) { RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Index out of range"); return NULL; }
UserGetAtomName(aatomSysLoaded[iatom], pszLibName, sizeof(pszLibName)/sizeof(WCHAR));
/*
* Call back the client to load the library. */ RtlInitUnicodeString(&strLibrary, pszLibName); hmod = ClientLoadLibrary(&strLibrary, (iatom == gihmodUserApiHook) ? goffPfnInitUserApiHook : 0);
if (hmod != NULL) { /*
* Check to make sure another thread hasn't loaded this library * while we were outside the critical section. */ if (!TESTHMODLOADED(ptiCurrent, iatom)) { /*
* Go ahead and bump the reference count. */ acatomSysUse[iatom]++; SETHMODLOADED(ptiCurrent, iatom, hmod);
} else { /*
* Another thread loaded it while we were outside the * critical section. Unload it so the system's * reference count is correct. */ ClientFreeLibrary(ptiCurrent->ppi->ahmodLibLoaded[iatom]); } }
return hmod; }
/***********************************************************************\
* DoSysExpunge * * This function is called when a thread wakes up and finds its * QS_SYSEXPUNGE wakebit set. * * History: * 02-04-91 DavidPe Ported. \***********************************************************************/
VOID xxxDoSysExpunge( PTHREADINFO pti) { int i;
/*
* Clear this first before we potentially leave the critical section. */ pti->ppi->cSysExpunge = gcSysExpunge;
/*
* Scan for libraries that have been freed */ for (i = 0; i < catomSysTableEntries; i++) { if ((acatomSysDepends[i] == 0) && (aatomSysLoaded[i] != 0) && TESTHMODLOADED(pti, i)) {
HANDLE hmodFree = pti->ppi->ahmodLibLoaded[i];
/*
* Clear this hmod for this process before we leave the * critical section. */ CLEARHMODLOADED(pti, i);
/*
* Decrement the count of processes that have loaded this * .dll. If there are no more, then destroy the reference * to this .dll. */ if (--acatomSysUse[i] == 0) { UserDeleteAtom(aatomSysLoaded[i]); aatomSysLoaded[i] = 0; gdwSysExpungeMask &= ~(1 << i); }
/*
* Call back the client to free the library... */ ClientFreeLibrary(hmodFree); } } }
|