📄 cpprun.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 1999 - 2000 Mark Roddy
//
// Hollis Technology Solutions
// 94 Dow Road
// Hollis, NH 03049
// info@hollistech.com
// www.hollistech.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// www.fsf.org
//
//
//
// Synopsis:
//
//
// Version Information:
//
// $Header: /cpprun/sys/cpplib/cpprun.cpp 4 1/01/00 11:00p Markr $
//
///////////////////////////////////////////////////////////////////////////////
#define HTS_UNIQUE_FILE_ID 0x1204002
#include "htscpp_internal.h"
//
// we appropriate DriverEntry so the driver must use another name for this routine.
//
#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS
Cp_DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
#ifdef __cplusplus
}
#endif /* __cplusplus */
static
void __cdecl onexitinit (
void
);
static
PVFV __cdecl onexit (
PVFV func
);
static
void __cdecl callPVFVArray (
PVFV * pfbegin,
PVFV * pfend
);
static
void __cdecl doexit (
int code,
int quick,
int retcaller
);
static VOID
_CppDriverUnload(PDRIVER_OBJECT DriverObject);
static PDRIVER_UNLOAD clientUnload = NULL;
NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
onexitinit();
callPVFVArray(__crtXca, __crtXcz);
//
// call the clients driver entry routine.
//
NTSTATUS Status = Cp_DriverEntry(DriverObject, RegistryPath);
if (NT_SUCCESS(Status)) {
//
// we have to steal the unload vector if it exists
//
if (DriverObject->DriverUnload) {
clientUnload = DriverObject->DriverUnload;
DriverObject->DriverUnload = _CppDriverUnload;
}
} else {
//
// call the d'tors for global and static objects?
//
doexit (0, 0, 1);
}
return Status;
}
static
VOID
_CppDriverUnload(PDRIVER_OBJECT DriverObject)
{
//
// call the clients unload routine
//
if (clientUnload) {
clientUnload(DriverObject);
}
//
// do what is appropriate for destorying global objects
//
doexit (0, 0, 1);
return;
}
//
// this must be externally visible!
//
int __cdecl atexit (
PVFV func
)
{
return (onexit(func) == NULL) ? -1 : 0;
}
//
// this was "initterm" but we ain't initting any 'terms' I can think
// of. What we are doing is calling an array of functions.
//
void __cdecl callPVFVArray (
PVFV * pfbegin,
PVFV * pfend
)
{
while ( pfbegin < pfend )
{
/*
* if current table entry is non-NULL, call thru it.
*/
if ( *pfbegin != NULL )
(**pfbegin)();
++pfbegin;
}
}
//
// the CRT code had some ugly stuff that created a variable length array of
// function pointers. This was scrapped in favor of a linked list.
//
typedef struct {
LIST_ENTRY link; // double linked list of exit functions
PVFV exitFunc;
} EXIT_FUNC_LIST, *PEXIT_FUNC_LIST;
LIST_ENTRY exitList;
void __cdecl onexitinit (
void
)
{
//
// this is a bit easier
//
InitializeListHead(&exitList);
}
PVFV __cdecl onexit (
PVFV func
)
{
PEXIT_FUNC_LIST pFuncListEntry =
(PEXIT_FUNC_LIST)malloc(sizeof(EXIT_FUNC_LIST), 'EPcO');
if (!pFuncListEntry) {
return NULL;
}
pFuncListEntry->exitFunc = func;
//
// gee, creating a lifo list is rather trivial
//
InsertHeadList(&exitList, &pFuncListEntry->link);
return func;
}
void drainExit()
{
PEXIT_FUNC_LIST pFuncListEntry;
while(!IsListEmpty(&exitList)) {
//
// this cast relies on link being the first field of
// EXIT_FUNC_LIST.
//
pFuncListEntry = (PEXIT_FUNC_LIST) RemoveHeadList(&exitList);
AssertAlways((PVOID) pFuncListEntry == (PVOID)&pFuncListEntry->link);
//
// wrap this in a try/except handler?
//
if (pFuncListEntry->exitFunc) {
pFuncListEntry->exitFunc();
}
free(pFuncListEntry);
}
}
void __cdecl doexit (
int code,
int quick,
int retcaller
)
{
if (!quick) {
drainExit();
}
return;
}
///////////////////////////////////////////////////////////////////////////////
//
// Change History Log
//
// $Log: /cpprun/sys/cpplib/cpprun.cpp $
//
// 4 1/01/00 11:00p Markr
//
// 3 12/31/99 4:29p Markr
//
// 2 12/17/99 8:30a Markr
//
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -