📄 tmcrt.c
字号:
if ( EncodedHandle->Magic == TMCRT_MAGIC_PATTERN )
{
PTMCRT_CONTEXT pCRT = (PTMCRT_CONTEXT)GlobalContext[EncodedHandle->DSPNumber];
if ( !pCRT )
{
return (0xffffffff);
}
if ( ( EncodedHandle->StdType == kLevel2StdinHandle ) ||
( EncodedHandle->StdType == kLevel2StdoutHandle ) ||
( EncodedHandle->StdType == kLevel2StderrHandle ) )
{
return (0xffffffff);
}
}
return _lseek ( Handle, Offset, Origin );
}
DWORD OpenFunc ( PCHAR PathName, DWORD Flags, DWORD Mode )
{
#ifdef USE_DVD
if ( strcmp ( PathName, DVDCtl_FILENAME ) == 0 )
{
return kDVDControHandle;
}
#endif
if ( TraceFlag )
{
ODS("[OpenFunc|PathName:%s|Flags:%x|Mode:%x]", PathName, Flags, Mode );
}
return _open ( PathName, Flags,Mode );
}
DWORD CloseFunc ( DWORD Handle )
{
#ifdef USE_DVD
if (Handle == kDVDControHandle )
return 0;
#endif
if ( TraceFlag )
{
ODS("[CloseFunc|Handle:%x]", Handle );
}
return _close ( Handle );
}
Bool cruntimeInit ( void )
{
UInt32 Idx;
HKEY RegistryHandle;
ULONG BytesXfered;
for ( Idx = 0 ; Idx < constTMMANMaximumDeviceCount ; Idx++ )
{
GlobalContext[Idx] = NULL;
}
if ( ERROR_SUCCESS == RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
constTMManRegistryPath,
0,
KEY_READ,
&RegistryHandle ) )
{
BytesXfered = sizeof ( ULONG );
if ( ERROR_SUCCESS != RegQueryValueEx(
RegistryHandle,
TEXT("TMCRTDebug"),
NULL,
NULL,
&TraceFlag,
&BytesXfered ) )
{
TraceFlag = False;
}
BytesXfered = sizeof ( ULONG );
if ( ERROR_SUCCESS != RegQueryValueEx(
RegistryHandle,
TEXT("DefaultEndianness"),
NULL,
NULL,
&g_Endian,
&BytesXfered ) )
{
g_Endian = True;
}
RegCloseKey( RegistryHandle );
}
if ( TM1IF_init(
(RPCServ_OpenFunc) OpenFunc,
(RPCServ_OpenDllFunc) OpenDLLFunc,
(RPCServ_CloseFunc) CloseFunc,
(RPCServ_ReadFunc) ReadFunc,
(RPCServ_WriteFunc) WriteFunc,
(RPCServ_SeekFunc) LseekFunc,
(RPCServ_IsattyFunc) IsattyFunc,
(RPCServ_FstatFunc) FstatFunc,
(RPCServ_FcntlFunc) FcntlFunc,
(RPCServ_StatFunc) StatFunc,
(RPCServ_ExitFunc) ExitCodeFunc,
(Bool)g_Endian) != True )
{
return False;
}
if ( TM1IF_start_serving() == TM1IF_Serving_Failed )
{
TM1IF_term( );
return False;
}
}
void cruntimeExit ( void )
{
TM1IF_term( );
}
UInt32 cruntimeCreate(
UInt32 DSPNumber,
UInt32 ArgumentCount,
UInt8* ArgumentVector[],
CRunTimeParameterBlock* Parameters,
UInt32* CRTHandlePointer )
{
DWORD Written;
UInt32 PathIdx;
PTMCRT_CONTEXT pCRT;
DWORD ServerStatus;
tmmanDSPInfo Caps;
HKEY RegistryHandle;
ULONG BytesXfered;
HANDLE StartEventHandle;
TCHAR Path[constTMManPathLength];
TCHAR StartEventName[MAX_PATH];
TMCRT_STD_HANDLE EncodedStdInHandle, EncodedStdOutHandle, EncodedStdErrHandle;
fExitProcess = FALSE;
if ( ( pCRT = malloc ( sizeof ( TMCRT_CONTEXT ) ) ) == NULL )
{
goto cruntimeCreateExit1;
}
GlobalContext[Parameters->VirtualNodeNumber] = pCRT;
pCRT->OptionBitmap = Parameters->OptionBitmap;
pCRT->DSPNumber = DSPNumber;
pCRT->StdInHandle = (HANDLE)Parameters->StdInHandle;
pCRT->StdOutHandle = (HANDLE)Parameters->StdOutHandle;
pCRT->StdErrHandle = (HANDLE)Parameters->StdErrHandle;
pCRT->VirtualNodeNumber = Parameters->VirtualNodeNumber;
pCRT->ArgumentCount = ArgumentCount;
pCRT->ArgumentVector = ArgumentVector;
pCRT->SynchObject = (HANDLE)Parameters->SynchronizationObject;
pCRT->fServerLoaded = FALSE;
pCRT->fTargetExited = FALSE;
pCRT->ExitCode = ~0;
if ( tmmanDSPOpen ( pCRT->DSPNumber , &pCRT->DSPHandle ) != statusSuccess )
{
goto cruntimeCreateExit2;
}
if ( pCRT->OptionBitmap & constCRunTimeFlagsAllocConsole )
{
AllocConsole();
SetConsoleTitle("TriMedia Console");
// check for the windows size only we are allocating a new console.
if ( pCRT->OptionBitmap & constCRunTimeFlagsUseWindowSize )
{
COORD Coord;
Coord.Y = (WORD)Parameters->WindowSize;
Coord.X = 80;
SetConsoleScreenBufferSize ( GetStdHandle(STD_OUTPUT_HANDLE), Coord );
}
pCRT->StdInHandle = GetStdHandle(STD_INPUT_HANDLE);
pCRT->StdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
pCRT->StdErrHandle = GetStdHandle(STD_ERROR_HANDLE);
}
if ( ( pCRT->ExitObject =
CreateEvent (NULL, TRUE, FALSE, NULL ) ) == NULL )
{
goto cruntimeCreateExit3;
}
if ( tmmanDSPGetInfo ( pCRT->DSPHandle, &Caps ) != statusSuccess )
{
goto cruntimeCreateExit2;
}
// make the stdin , stdout and stderr handles.
// totally screwed up, but can't help it.
EncodedStdInHandle.Magic =
EncodedStdOutHandle.Magic =
EncodedStdErrHandle.Magic = TMCRT_MAGIC_PATTERN;
EncodedStdInHandle.StdType = kLevel2StdinHandle;
EncodedStdOutHandle.StdType = kLevel2StdoutHandle;
EncodedStdErrHandle.StdType = kLevel2StderrHandle;
EncodedStdInHandle.DSPNumber =
EncodedStdOutHandle.DSPNumber =
EncodedStdErrHandle.DSPNumber = pCRT->VirtualNodeNumber;
if (!TM1IF_add_node_info(
pCRT->VirtualNodeNumber,
pCRT->ArgumentCount,
pCRT->ArgumentVector,
*(PDWORD)&EncodedStdInHandle,
*(PDWORD)&EncodedStdOutHandle,
*(PDWORD)&EncodedStdErrHandle,
Caps.SDRAM.MappedAddress - Caps.SDRAM.PhysicalAddress,
Caps.SDRAM.PhysicalAddress,
Caps.SDRAM.PhysicalAddress + Caps.SDRAM.Size,
(void*)pCRT->DSPNumber ))
{
goto cruntimeCreateExit4;
}
pCRT->fServerLoaded = TRUE;
if ( ERROR_SUCCESS == RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
constTMManRegistryPath,
0,
KEY_READ,
&RegistryHandle ) )
{
HANDLE RegistryHandleDLLPath;
PCHAR PathBuffer;
ULONG PathIdx, BytesXfered;
if ( ERROR_SUCCESS == RegOpenKeyEx(
RegistryHandle,
TEXT("DLLpath"),
0,
KEY_READ,
&RegistryHandleDLLPath ) )
{
for ( PathIdx = 0 ; PathIdx < MAX_PATH_INDEX ; PathIdx++ )
{
TCHAR Key[MAX_PATH];
BytesXfered = 0;
wsprintf ( Key, TEXT("%u"), PathIdx );
if ( ERROR_SUCCESS != RegQueryValueEx(
RegistryHandleDLLPath,
Key,
NULL,
NULL,
NULL,
&BytesXfered ) )
{
break;
}
if ( NULL == ( PathBuffer = malloc ( BytesXfered ) ) )
{
break;
}
if ( ERROR_SUCCESS != RegQueryValueEx(
RegistryHandleDLLPath,
Key,
NULL,
NULL,
PathBuffer,
&BytesXfered ) )
{
free ( PathBuffer );
break;
}
OpenDll_add_dll_path ( PathBuffer );
free ( PathBuffer );
}
RegCloseKey ( RegistryHandleDLLPath );
}
RegCloseKey ( RegistryHandle );
}
*CRTHandlePointer = (UInt32)pCRT;
/* signal the event that TMMon/TMGMon are waiting on */
wsprintf (
StartEventName,
TEXT("TMCRTStartEvent%d"),
pCRT->DSPNumber );
if ( NULL != ( StartEventHandle = OpenEvent (
EVENT_ALL_ACCESS,
TRUE,
StartEventName ) ) )
{
SetEvent ( StartEventHandle );
CloseHandle ( StartEventHandle );
}
return True;
cruntimeCreateExit5:
TM1IF_remove_node_info( pCRT->VirtualNodeNumber );
cruntimeCreateExit4:
CloseHandle ( pCRT->ExitObject );
cruntimeCreateExit3:
if ( pCRT->OptionBitmap & constCRunTimeFlagsAllocConsole )
{
FreeConsole();
}
tmmanDSPClose ( pCRT->DSPHandle );
cruntimeCreateExit2:
free ( pCRT );
cruntimeCreateExit1:
return False;
}
Bool cruntimeDestroy (
UInt32 CRTHandle,
UInt32 *ExitCodePointer )
{
PTMCRT_CONTEXT pCRT = (PTMCRT_CONTEXT)CRTHandle;
Bool ExitCodeValid;
//fprintf ( stderr, "[cruntimeDestroy|ExitCode:%x|NodeID:%x:pCRT:%x]",
// pCRT->ExitCode, pCRT->VirtualNodeNumber, pCRT );
/*
RPCServ should have created thread by now so we block here on our global event
to be signalled
*/
fExitProcess = TRUE;
SetEvent ( pCRT->ExitObject );
ExitCodeValid = pCRT->fTargetExited;
*ExitCodePointer = pCRT->ExitCode;
if ( pCRT->OptionBitmap & constCRunTimeFlagsAllocConsole )
{
FreeConsole();
}
CloseHandle ( pCRT->ExitObject );
TM1IF_remove_node_info( pCRT->VirtualNodeNumber );
tmmanDSPClose ( pCRT->DSPHandle );
GlobalContext[pCRT->VirtualNodeNumber] = NULL;
free ( pCRT );
return ExitCodeValid;
}
/*
StripCR
Unix is a brain dead OS, it cannot undestrand input string terminated with CRLF.
And of course trimedia will blindly follow what Unix does.
So we have to strip all CR in the input that is being read from
StdIn. This function does that and accordingly reduces the lenth of the
string that is read in.
*/
VOID StripCR ( PCHAR pBuffer, DWORD *BytesRead )
{
DWORD Idx, InnerIdx;
DWORD OrigLength = *BytesRead;
for ( Idx = 0; Idx < *BytesRead ; Idx++ )
{
if ( ( pBuffer[Idx] == '\r' ) && ( pBuffer[Idx + 1] == '\n' ) )
{
(*BytesRead)--;
for ( InnerIdx = Idx ; InnerIdx < *BytesRead ; InnerIdx++ )
{
pBuffer[InnerIdx] = pBuffer[InnerIdx+1];
}
}
}
}
UInt32 crtPrintf ( HANDLE FileHandle, UInt8* Format, ...)
{
DWORD BytesWritten;
UInt8 Buffer[1024];
DWORD ItemsWritten;
va_list ArgumentList;
va_start ( ArgumentList, Format );
ItemsWritten = vsprintf ( Buffer, Format, ArgumentList );
va_end ( ArgumentList );
WriteFile ( FileHandle, Buffer, strlen ( Buffer ), &BytesWritten, NULL );
return ItemsWritten;
}
UInt32 ODS(
UInt8* FormatString,
... )
{
UInt32 Items;
UInt8 Buffer[1024];
va_list Arguments;
va_start ( Arguments, FormatString );
Items = vsprintf ( Buffer, FormatString, Arguments );
va_end ( Arguments );
OutputDebugString ( Buffer );
OutputDebugString ( "\n" );
return Items;
}
void WarningBox ( TCHAR* ErrorString )
{
MessageBox ( NULL,
ErrorString,
TEXT("TriMedia Manager : tmcrt.dll : WARNING"),
MB_OK | MB_ICONWARNING | MB_DEFBUTTON1 | MB_APPLMODAL );
}
BOOL WINAPI DLLInitialize (
PVOID DllHandle,
DWORD dwReason,
PVOID pvContext )
{
tmmanVersion Version;
TCHAR szTemp[1024];
switch ( dwReason )
{
case DLL_PROCESS_ATTACH :
Version.Major = verGetFileMajorVersion() ;
Version.Minor = verGetFileMinorVersion() ;
tmmanNegotiateVersion ( constTMManDefault, &Version );
if ( ( Version.Major != verGetFileMajorVersion() ) ||
( Version.Minor != verGetFileMinorVersion()) )
{
wsprintf ( szTemp,
TEXT("TriMedia C Run Time Server (tmcrt.dll) Version[%d.%d] is INCOMPATIBLE With TMMan32.dll Version[%d.%d]\n"),
verGetFileMajorVersion(), verGetFileMinorVersion(),
Version.Major, Version.Minor );
WarningBox ( szTemp );
return FALSE;
}
break;
case DLL_PROCESS_DETACH :
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -