📄 ulib.cxx
字号:
/*++
Copyright (c) 1990-2001 Microsoft Corporation
Module Name:
ulib.cxx
Abstract:
This module contains run-time, global support for the ULIB class library.
This support includes:
- creation of CLASS_DESCRIPTORs
- Global objects
- Ulib to Win32 API mapping functions
Environment:
ULIB, User Mode
Notes:
--*/
#include <pch.cxx>
#define _ULIB_MEMBER_
#include "ulib.hxx"
#include "error.hxx"
#if !defined( _AUTOCHECK_ ) && !defined( _SETUP_LOADER_ ) && !defined( _EFICHECK_ )
#include "system.hxx"
#include "array.hxx"
#include "arrayit.hxx"
#include "bitvect.hxx"
#include "dir.hxx"
#include "file.hxx"
#include "filestrm.hxx"
#include "filter.hxx"
#include "keyboard.hxx"
#include "message.hxx"
#include "wstring.hxx"
#include "path.hxx"
#include "pipestrm.hxx"
#include "prtstrm.hxx"
#include "screen.hxx"
#include "stream.hxx"
#include "timeinfo.hxx"
#include <locale.h>
#endif // _AUTOCHECK_ || _SETUP_LOADER_
#define EFICHK_DBUG_MASK EFI_DBUG_MASK
//
// Constants
//
CONST CLASS_ID NIL_CLASS_ID = 0;
#if !defined( _AUTOCHECK_ ) && !defined( _SETUP_LOADER_ )
#if DBG==1 || defined( EFI_DEBUG )
//
// UlibGlobalFlag is used to selectively enable debugging options at
// run-time.
//
ULONG UlibGlobalFlag = 0x00000000;
#ifdef EFI_DEBUG
extern "C" {
ULIB_EXPORT
VOID
__cdecl
DebugPrintfReal(
IN char* Format,
IN ...
)
#else
ULIB_EXPORT
VOID
DebugPrintfReal(
IN PCSTR Format,
IN ...
)
#endif
/*++
Routine Description:
Printf to the debug console.
Arguments:
Format - Supplies a printf style format string.
Return Value:
None.
--*/
{
va_list args;
va_start( args, Format );
#if !defined( _EFICHECK_ )
vsprintf( Buffer, Format, args );
#else
#if defined(EFI_DEBUG)
DEBUG((EFICHK_DBUG_MASK, (CHAR8 *)Format, args));
#endif
#endif
va_end( args );
#if !defined( _EFICHECK_ )
OutputDebugStringA( Buffer );
#endif
}
#if defined( _EFICHECK_ )
}
#endif
#endif // DBG
#if !defined( _EFICHECK_ )
//
// GLobal object pointers.
//
// Clients of the DLL cannot access the DLL's
// global data yet, so I have the delightful hacks to get at it.
ULIB_EXPORT
PSTREAM
Get_Standard_Input_Stream(
)
{
return Standard_Input_Stream;
}
ULIB_EXPORT
PSTREAM
Get_Standard_Output_Stream(
)
{
return Standard_Output_Stream;
}
ULIB_EXPORT
PSTREAM
Get_Standard_Error_Stream(
)
{
return Standard_Error_Stream;
}
PSTREAM Standard_Input_Stream;
PSTREAM Standard_Output_Stream;
PSTREAM Standard_Error_Stream;
#endif // _EFICHECK_
#endif // _AUTOCHECK_ || _SETUP_LOADER_
// Note: Who put this here? Currently it is being defined
// by applications. Something has to be done about this.
ERRSTACK* perrstk;
//
// Declare class descriptors for all classes.
//
DECLARE_CLASS( CLASS_DESCRIPTOR );
DECLARE_CLASS( ARRAY );
DECLARE_CLASS( ARRAY_ITERATOR );
DECLARE_CLASS( BITVECTOR );
DECLARE_CLASS( CONT_MEM );
DECLARE_CLASS( CONTAINER );
DECLARE_CLASS( DSTRING );
DECLARE_CLASS( FSTRING );
DECLARE_CLASS( HMEM );
DECLARE_CLASS( ITERATOR );
DECLARE_CLASS( LIST );
DECLARE_CLASS( LIST_ITERATOR );
DECLARE_CLASS( MEM );
DECLARE_CLASS( MESSAGE );
DECLARE_CLASS( OBJECT );
DECLARE_CLASS( SEQUENTIAL_CONTAINER );
DECLARE_CLASS( SORTABLE_CONTAINER );
DECLARE_CLASS( SORTED_LIST );
DECLARE_CLASS( SORTED_LIST_ITERATOR );
DECLARE_CLASS( STACK );
DECLARE_CLASS( WSTRING );
DECLARE_CLASS( STATIC_MEM_BLOCK_MGR );
DECLARE_CLASS( MEM_BLOCK_MGR );
#if !defined( _EFICHECK_ )
DECLARE_CLASS( ARGUMENT );
DECLARE_CLASS( ARGUMENT_LEXEMIZER );
DECLARE_CLASS( BSTRING );
DECLARE_CLASS( BDSTRING );
DECLARE_CLASS( BUFFER_STREAM );
DECLARE_CLASS( BYTE_STREAM );
DECLARE_CLASS( CHKDSK_MESSAGE );
DECLARE_CLASS( COMM_DEVICE );
DECLARE_CLASS( FILE_STREAM );
DECLARE_CLASS( FLAG_ARGUMENT );
DECLARE_CLASS( FSNODE );
DECLARE_CLASS( FSN_DIRECTORY );
DECLARE_CLASS( FSN_FILE );
DECLARE_CLASS( FSN_FILTER );
DECLARE_CLASS( KEYBOARD );
DECLARE_CLASS( LONG_ARGUMENT );
DECLARE_CLASS( MULTIPLE_PATH_ARGUMENT );
DECLARE_CLASS( PATH );
DECLARE_CLASS( PATH_ARGUMENT );
DECLARE_CLASS( PIPE );
DECLARE_CLASS( PIPE_STREAM );
DECLARE_CLASS( PROGRAM );
DECLARE_CLASS( PRINT_STREAM );
DECLARE_CLASS( REST_OF_LINE_ARGUMENT );
DECLARE_CLASS( SCREEN );
DECLARE_CLASS( STREAM_MESSAGE );
DECLARE_CLASS( STREAM );
DECLARE_CLASS( STRING_ARGUMENT );
DECLARE_CLASS( STRING_ARRAY );
DECLARE_CLASS( TIMEINFO );
DECLARE_CLASS( TIMEINFO_ARGUMENT );
#endif
#if defined( _AUTOCHECK_ )
DECLARE_CLASS( AUTOCHECK_MESSAGE );
DECLARE_CLASS( TM_AUTOCHECK_MESSAGE );
#endif // _AUTOCHECK_
#if defined( _EFICHECK_ )
DECLARE_CLASS( EFICHECK_MESSAGE );
#endif
//
// Local prototypes
//
STATIC
BOOLEAN
DefineClassDescriptors (
);
STATIC
BOOLEAN
UndefineClassDescriptors (
);
#if !defined( _AUTOCHECK_ ) && !defined( _SETUP_LOADER_ ) && !defined( _EFICHECK_ )
BOOLEAN
CreateStandardStreams (
);
PSTREAM
GetStandardStream (
IN HANDLE Handle,
IN STREAMACCESS Access
);
#endif // _AUTOCHECK_ || _SETUP_LOADER_
BOOLEAN
InitializeUlib (
IN HANDLE DllHandle,
IN ULONG Reason,
IN PVOID Reserved
)
/*++
Routine Description:
Initilize Ulib by constructing and initializing all global objects. These
include:
- all CLASS_DESCRIPTORs (class_cd)
- SYSTEM (System)
- Standard streams
Arguments:
DllHandle - Not used.
Reason - Supplies the reason why the entry point was called.
Reserved - Not used.
Return Value:
BOOLEAN - Returns TRUE if all global objects were succesfully constructed
and initialized.
--*/
{
UNREFERENCED_PARAMETER( DllHandle );
UNREFERENCED_PARAMETER( Reserved );
#if defined( _AUTOCHECK_ ) || defined( _SETUP_LOADER_ ) || defined( _EFICHECK_ )
UNREFERENCED_PARAMETER( Reason );
if (!DefineClassDescriptors()) {
UndefineClassDescriptors();
DebugAbort( "Ulib initialization failed!!!\n" );
return( FALSE );
}
#if defined(TRACE_ULIB_MEM_LEAK)
DebugPrint("ULIB.DLL got attached.\n");
#endif
#else // _AUTOCHECK_ and _SETUP_LOADER_ not defined
STATIC ULONG count = 0;
switch (Reason) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
if (count > 0) {
++count;
#if defined(TRACE_ULIB_MEM_LEAK)
DebugPrintTrace(("ULIB.DLL got attached %d times.\n", count));
#endif
return TRUE;
}
//
// Initialization of ULIB can no longer depend on
// the initialization of the standard streams since they don't seem
// to exist for Windows programs (no console...)
//
if( !DefineClassDescriptors()) {
UndefineClassDescriptors();
DebugAbort( "Ulib initialization failed!!!\n" );
return( FALSE );
}
#if defined(TRACE_ULIB_MEM_LEAK)
DebugPrint("ULIB.DLL got attached.\n");
#endif
CreateStandardStreams();
{
UINT Codepage;
char achCodepage[12] = ".OCP"; // ".", "uint in decimal", null
if (Codepage = GetConsoleOutputCP()) {
wsprintfA(achCodepage, ".%u", Codepage);
}
setlocale(LC_ALL, achCodepage);
}
count++;
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
if (count > 1) {
--count;
#if defined(TRACE_ULIB_MEM_LEAK)
DebugPrintTrace(("ULIB.DLL got detached. %d time(s) left.\n", count));
#endif
return TRUE;
}
if (count == 1) {
#if defined(TRACE_ULIB_MEM_LEAK)
DebugPrint("ULIB.DLL got detached.\n");
#endif
UndefineClassDescriptors();
DELETE(Standard_Input_Stream);
DELETE(Standard_Output_Stream);
DELETE(Standard_Error_Stream);
count--;
} else {
#if defined(TRACE_ULIB_MEM_LEAK)
DebugPrint("ULIB.DLL detached more than attached\n");
#endif
}
break;
break;
}
#endif // _AUTOCHECK || _SETUP_LOADER_
return( TRUE );
}
STATIC
BOOLEAN
DefineClassDescriptors (
)
/*++
Routine Description:
Defines all the class descriptors used by ULIB
Arguments:
None.
Return Value:
BOOLEAN - Returns TRUE if all class descriptors were succesfully
constructed and initialized.
--*/
{
// This is broken up into many ifs because of compiler limitations.
BOOLEAN Success = TRUE;
if (Success &&
#ifndef _EFICHECK_
DEFINE_CLASS_DESCRIPTOR( ARGUMENT ) &&
DEFINE_CLASS_DESCRIPTOR( ARGUMENT_LEXEMIZER ) &&
#endif
DEFINE_CLASS_DESCRIPTOR( ARRAY ) &&
DEFINE_CLASS_DESCRIPTOR( ARRAY_ITERATOR ) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -