Put Netware specific entry point code that is only used by utilities into nlm_entrypoint.cpp. Otherwise, it causes problems for applications that have their own Netware entry point.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@950 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
@@ -595,16 +595,12 @@
|
||||
FSTATIC zDIO_WRITE_FUNC gv_zDIOWriteFunc = NULL;
|
||||
FSTATIC zRENAME_FUNC gv_zRenameFunc = NULL;
|
||||
|
||||
static void * gv_MyModuleHandle = NULL;
|
||||
static FLMATOMIC gv_NetWareStartupCount = 0;
|
||||
void * gv_MyModuleHandle = NULL;
|
||||
FLMATOMIC gv_NetWareStartupCount = 0;
|
||||
rtag_t gv_lAllocRTag = 0;
|
||||
|
||||
static FLMINT64 gv_NssRootKey;
|
||||
static FLMBOOL gv_bNSSKeyInitialized = FALSE;
|
||||
static SEMAPHORE gv_lFlmSyncSem = 0;
|
||||
static FLMBOOL gv_bUnloadCalled = FALSE;
|
||||
static FLMBOOL gv_bMainRunning = FALSE;
|
||||
static F_EXIT_FUNC gv_fnExit = NULL;
|
||||
|
||||
#if !defined( __MWERKS__)
|
||||
extern unsigned long ReadInternalClock(void);
|
||||
@@ -640,10 +636,6 @@
|
||||
FLMINT lStatus,
|
||||
RCODE defaultRc);
|
||||
|
||||
extern "C" int nlm_main(
|
||||
int iArgC,
|
||||
char ** ppszArgV);
|
||||
|
||||
extern FLMATOMIC gv_openFiles;
|
||||
|
||||
#endif
|
||||
@@ -2603,409 +2595,6 @@ extern "C" void f_fatalRuntimeError( void)
|
||||
EnterDebugger();
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Desc: Startup routine for the NLM - that gets the main going in
|
||||
its own thread.
|
||||
*********************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" void * f_nlmMainStub(
|
||||
void * hThread,
|
||||
void * pData)
|
||||
{
|
||||
ARG_DATA * pArgData = (ARG_DATA *)pData;
|
||||
struct LoadDefinitionStructure * moduleHandle = pArgData->moduleHandle;
|
||||
|
||||
(void)hThread;
|
||||
|
||||
(void)kSetThreadName( (void *)kCurrentThread(),
|
||||
(BYTE *)pArgData->pszThreadName);
|
||||
|
||||
nlm_main( pArgData->iArgC, pArgData->ppszArgV);
|
||||
|
||||
Free( pArgData->ppszArgV);
|
||||
Free( pArgData->pszArgs);
|
||||
Free( pArgData->pszThreadName);
|
||||
Free( pArgData);
|
||||
|
||||
gv_bMainRunning = FALSE;
|
||||
|
||||
if( !gv_bUnloadCalled)
|
||||
{
|
||||
KillMe( moduleHandle);
|
||||
}
|
||||
|
||||
kExitThread( NULL);
|
||||
return( NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Desc: Signals the f_nlmEntryPoint thread to release the console.
|
||||
*********************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
void SynchronizeStart( void)
|
||||
{
|
||||
if (gv_lFlmSyncSem)
|
||||
{
|
||||
(void)kSemaphoreSignal( gv_lFlmSyncSem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Desc: Startup routine for the NLM.
|
||||
*********************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" LONG f_nlmEntryPoint(
|
||||
struct LoadDefinitionStructure * moduleHandle,
|
||||
struct ScreenStruct * initScreen,
|
||||
char * commandLine,
|
||||
char * loadDirectoryPath,
|
||||
LONG uninitializedDataLength,
|
||||
LONG fileHandle,
|
||||
LONG (*ReadRoutine)
|
||||
(LONG handle,
|
||||
LONG offset,
|
||||
char * buffer,
|
||||
LONG length),
|
||||
LONG customDataOffset,
|
||||
LONG customDataSize)
|
||||
{
|
||||
char * pszTmp;
|
||||
char * pszArgStart;
|
||||
int iArgC;
|
||||
int iTotalArgChars;
|
||||
int iArgSize;
|
||||
char ** ppszArgV = NULL;
|
||||
char * pszArgs = NULL;
|
||||
char * pszDestArg;
|
||||
bool bFirstPass = true;
|
||||
char cEnd;
|
||||
ARG_DATA * pArgData = NULL;
|
||||
LONG sdRet = 0;
|
||||
char * pszThreadName;
|
||||
char * pszModuleName;
|
||||
int iModuleNameLen;
|
||||
int iThreadNameLen;
|
||||
int iLoadDirPathSize;
|
||||
void * hThread = NULL;
|
||||
|
||||
(void)initScreen;
|
||||
(void)uninitializedDataLength;
|
||||
(void)fileHandle;
|
||||
(void)ReadRoutine;
|
||||
(void)customDataOffset;
|
||||
(void)customDataSize;
|
||||
|
||||
if( f_atomicInc( &gv_NetWareStartupCount) != 1)
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
gv_MyModuleHandle = moduleHandle;
|
||||
gv_bUnloadCalled = FALSE;
|
||||
|
||||
// Allocate the needed resource tags
|
||||
|
||||
if( (gv_lAllocRTag = AllocateResourceTag( gv_MyModuleHandle,
|
||||
"FLAIM Memory", AllocSignature)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Syncronized start
|
||||
|
||||
if (moduleHandle->LDFlags & 4)
|
||||
{
|
||||
gv_lFlmSyncSem = kSemaphoreAlloc( (BYTE *)"FLAIM_SYNC", 0);
|
||||
}
|
||||
|
||||
// Initialize NSS
|
||||
|
||||
if( RC_BAD( f_nssInitialize()))
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pszModuleName = (char *)(&moduleHandle->LDFileName[ 1]);
|
||||
iModuleNameLen = (int)(moduleHandle->LDFileName[ 0]);
|
||||
|
||||
// First pass: Count the arguments in the command line
|
||||
// and determine how big of a buffer we will need.
|
||||
// Second pass: Put argments into allocated buffer.
|
||||
|
||||
Parse_Args:
|
||||
|
||||
iTotalArgChars = 0;
|
||||
iArgC = 0;
|
||||
|
||||
iLoadDirPathSize = f_strlen( (const char *)loadDirectoryPath);
|
||||
iArgSize = iLoadDirPathSize + iModuleNameLen;
|
||||
|
||||
if( !bFirstPass)
|
||||
{
|
||||
ppszArgV[ iArgC] = pszDestArg;
|
||||
f_memcpy( pszDestArg, loadDirectoryPath, iLoadDirPathSize);
|
||||
f_memcpy( &pszDestArg[ iLoadDirPathSize], pszModuleName, iModuleNameLen);
|
||||
pszDestArg[ iArgSize] = 0;
|
||||
pszDestArg += (iArgSize + 1);
|
||||
}
|
||||
|
||||
iArgC++;
|
||||
iTotalArgChars += iArgSize;
|
||||
pszTmp = commandLine;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Skip leading blanks.
|
||||
|
||||
while( *pszTmp && *pszTmp == ' ')
|
||||
{
|
||||
pszTmp++;
|
||||
}
|
||||
|
||||
if( *pszTmp == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( *pszTmp == '"' || *pszTmp == '\'')
|
||||
{
|
||||
cEnd = *pszTmp;
|
||||
pszTmp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cEnd = ' ';
|
||||
}
|
||||
|
||||
pszArgStart = pszTmp;
|
||||
iArgSize = 0;
|
||||
|
||||
// Count the characters in the parameter.
|
||||
|
||||
while( *pszTmp && *pszTmp != cEnd)
|
||||
{
|
||||
iArgSize++;
|
||||
pszTmp++;
|
||||
}
|
||||
|
||||
if( !iArgSize && cEnd == ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// If 2nd pass, save the argument.
|
||||
|
||||
if( !bFirstPass)
|
||||
{
|
||||
ppszArgV[ iArgC] = pszDestArg;
|
||||
|
||||
if( iArgSize)
|
||||
{
|
||||
f_memcpy( pszDestArg, pszArgStart, iArgSize);
|
||||
}
|
||||
|
||||
pszDestArg[ iArgSize] = 0;
|
||||
pszDestArg += (iArgSize + 1);
|
||||
}
|
||||
|
||||
iArgC++;
|
||||
iTotalArgChars += iArgSize;
|
||||
|
||||
// Skip trailing quote or blank.
|
||||
|
||||
if( *pszTmp)
|
||||
{
|
||||
pszTmp++;
|
||||
}
|
||||
}
|
||||
|
||||
if( bFirstPass)
|
||||
{
|
||||
if ((ppszArgV = (char **)Alloc( sizeof( char *) * iArgC,
|
||||
gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( (pszArgs = (char *)Alloc( iTotalArgChars + iArgC,
|
||||
gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pszDestArg = pszArgs;
|
||||
bFirstPass = false;
|
||||
goto Parse_Args;
|
||||
}
|
||||
|
||||
iThreadNameLen = (int)(moduleHandle->LDName[ 0]);
|
||||
|
||||
if( (pszThreadName = (char *)Alloc( iThreadNameLen + 1, gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
f_memcpy( pszThreadName, (char *)(&moduleHandle->LDName[ 1]), iThreadNameLen);
|
||||
pszThreadName[ iThreadNameLen] = 0;
|
||||
|
||||
if( (pArgData = (ARG_DATA *)Alloc( sizeof( ARG_DATA),
|
||||
gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pArgData->ppszArgV = ppszArgV;
|
||||
pArgData->pszArgs = pszArgs;
|
||||
pArgData->iArgC = iArgC;
|
||||
pArgData->moduleHandle = moduleHandle;
|
||||
pArgData->pszThreadName = pszThreadName;
|
||||
|
||||
gv_bMainRunning = TRUE;
|
||||
|
||||
if( (hThread = kCreateThread( (BYTE *)"FTK main",
|
||||
f_nlmMainStub, NULL, 32768, (void *)pArgData)) == NULL)
|
||||
{
|
||||
gv_bMainRunning = FALSE;
|
||||
sdRet = 2;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( kSetThreadLoadHandle( hThread, (LONG)moduleHandle) != 0)
|
||||
{
|
||||
(void)kDestroyThread( hThread);
|
||||
gv_bMainRunning = FALSE;
|
||||
sdRet = 2;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( kScheduleThread( hThread) != 0)
|
||||
{
|
||||
(void)kDestroyThread( hThread);
|
||||
gv_bMainRunning = FALSE;
|
||||
sdRet = 2;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Synchronized start
|
||||
|
||||
if( moduleHandle->LDFlags & 4)
|
||||
{
|
||||
(void)kSemaphoreWait( gv_lFlmSyncSem);
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if( sdRet != 0)
|
||||
{
|
||||
f_atomicDec( &gv_NetWareStartupCount);
|
||||
|
||||
if( ppszArgV)
|
||||
{
|
||||
Free( ppszArgV);
|
||||
}
|
||||
|
||||
if( pszArgs)
|
||||
{
|
||||
Free( pszArgs);
|
||||
}
|
||||
|
||||
if( pszThreadName)
|
||||
{
|
||||
Free( pszThreadName);
|
||||
}
|
||||
|
||||
if( pArgData)
|
||||
{
|
||||
Free( pArgData);
|
||||
}
|
||||
|
||||
if( gv_lFlmSyncSem)
|
||||
{
|
||||
kSemaphoreFree( gv_lFlmSyncSem);
|
||||
gv_lFlmSyncSem = 0;
|
||||
}
|
||||
|
||||
if( !gv_bUnloadCalled)
|
||||
{
|
||||
KillMe( moduleHandle);
|
||||
}
|
||||
}
|
||||
|
||||
return( sdRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" void f_nlmExitPoint(void)
|
||||
{
|
||||
if( f_atomicDec( &gv_NetWareStartupCount) > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gv_bUnloadCalled = TRUE;
|
||||
|
||||
if( gv_fnExit)
|
||||
{
|
||||
(*gv_fnExit)();
|
||||
gv_fnExit = NULL;
|
||||
}
|
||||
|
||||
while( gv_bMainRunning)
|
||||
{
|
||||
kYieldThread();
|
||||
}
|
||||
|
||||
f_nssUninitialize();
|
||||
|
||||
if( gv_lFlmSyncSem)
|
||||
{
|
||||
kSemaphoreFree( gv_lFlmSyncSem);
|
||||
gv_lFlmSyncSem = 0;
|
||||
}
|
||||
|
||||
if( gv_lAllocRTag)
|
||||
{
|
||||
ReturnResourceTag( gv_lAllocRTag, 1);
|
||||
gv_lAllocRTag = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" void exit(
|
||||
int exitCode)
|
||||
{
|
||||
(void)exitCode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" int atexit(
|
||||
F_EXIT_FUNC fnExit)
|
||||
{
|
||||
gv_fnExit = fnExit;
|
||||
return( 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FLM_NLM
|
||||
|
||||
|
||||
475
ftk/src/nlm_entrypoint.cpp
Normal file
475
ftk/src/nlm_entrypoint.cpp
Normal file
@@ -0,0 +1,475 @@
|
||||
//-------------------------------------------------------------------------
|
||||
// Desc: Entry point for Netware utilities
|
||||
// Tabs: 3
|
||||
//
|
||||
// Copyright (c) 2006 Novell, Inc. All Rights Reserved.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the GNU General Public
|
||||
// License as published by the Free Software Foundation.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, contact Novell, Inc.
|
||||
//
|
||||
// To contact Novell about this file by physical or electronic mail,
|
||||
// you may find current contact information at www.novell.com
|
||||
//
|
||||
// $Id$
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#include "ftksys.h"
|
||||
#include "ftknlm.h"
|
||||
|
||||
static SEMAPHORE gv_lFlmSyncSem = 0;
|
||||
static FLMBOOL gv_bUnloadCalled = FALSE;
|
||||
static FLMBOOL gv_bMainRunning = FALSE;
|
||||
static F_EXIT_FUNC gv_fnExit = NULL;
|
||||
|
||||
// Variables defined in ftknlm.cpp
|
||||
|
||||
extern FLMATOMIC gv_NetWareStartupCount;
|
||||
extern void * gv_MyModuleHandle;
|
||||
extern rtag_t gv_lAllocRTag;
|
||||
|
||||
#if defined( FLM_NLM)
|
||||
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
|
||||
RCODE f_nssInitialize( void);
|
||||
|
||||
void f_nssUninitialize( void);
|
||||
|
||||
extern "C" int nlm_main(
|
||||
int iArgC,
|
||||
char ** ppszArgV);
|
||||
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Desc: Startup routine for the NLM - that gets the main going in
|
||||
its own thread.
|
||||
*********************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" void * f_nlmMainStub(
|
||||
void * hThread,
|
||||
void * pData)
|
||||
{
|
||||
ARG_DATA * pArgData = (ARG_DATA *)pData;
|
||||
struct LoadDefinitionStructure * moduleHandle = pArgData->moduleHandle;
|
||||
|
||||
(void)hThread;
|
||||
|
||||
(void)kSetThreadName( (void *)kCurrentThread(),
|
||||
(BYTE *)pArgData->pszThreadName);
|
||||
|
||||
nlm_main( pArgData->iArgC, pArgData->ppszArgV);
|
||||
|
||||
Free( pArgData->ppszArgV);
|
||||
Free( pArgData->pszArgs);
|
||||
Free( pArgData->pszThreadName);
|
||||
Free( pArgData);
|
||||
|
||||
gv_bMainRunning = FALSE;
|
||||
|
||||
if( !gv_bUnloadCalled)
|
||||
{
|
||||
KillMe( moduleHandle);
|
||||
}
|
||||
|
||||
kExitThread( NULL);
|
||||
return( NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Desc: Signals the f_nlmEntryPoint thread to release the console.
|
||||
*********************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
void SynchronizeStart( void)
|
||||
{
|
||||
if (gv_lFlmSyncSem)
|
||||
{
|
||||
(void)kSemaphoreSignal( gv_lFlmSyncSem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************
|
||||
Desc: Startup routine for the NLM.
|
||||
*********************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" LONG f_nlmEntryPoint(
|
||||
struct LoadDefinitionStructure * moduleHandle,
|
||||
struct ScreenStruct * initScreen,
|
||||
char * commandLine,
|
||||
char * loadDirectoryPath,
|
||||
LONG uninitializedDataLength,
|
||||
LONG fileHandle,
|
||||
LONG (*ReadRoutine)
|
||||
(LONG handle,
|
||||
LONG offset,
|
||||
char * buffer,
|
||||
LONG length),
|
||||
LONG customDataOffset,
|
||||
LONG customDataSize)
|
||||
{
|
||||
char * pszTmp;
|
||||
char * pszArgStart;
|
||||
int iArgC;
|
||||
int iTotalArgChars;
|
||||
int iArgSize;
|
||||
char ** ppszArgV = NULL;
|
||||
char * pszArgs = NULL;
|
||||
char * pszDestArg;
|
||||
bool bFirstPass = true;
|
||||
char cEnd;
|
||||
ARG_DATA * pArgData = NULL;
|
||||
LONG sdRet = 0;
|
||||
char * pszThreadName;
|
||||
char * pszModuleName;
|
||||
int iModuleNameLen;
|
||||
int iThreadNameLen;
|
||||
int iLoadDirPathSize;
|
||||
void * hThread = NULL;
|
||||
|
||||
(void)initScreen;
|
||||
(void)uninitializedDataLength;
|
||||
(void)fileHandle;
|
||||
(void)ReadRoutine;
|
||||
(void)customDataOffset;
|
||||
(void)customDataSize;
|
||||
|
||||
if( f_atomicInc( &gv_NetWareStartupCount) != 1)
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
gv_MyModuleHandle = moduleHandle;
|
||||
gv_bUnloadCalled = FALSE;
|
||||
|
||||
// Allocate the needed resource tags
|
||||
|
||||
if( (gv_lAllocRTag = AllocateResourceTag( gv_MyModuleHandle,
|
||||
"FLAIM Memory", AllocSignature)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Syncronized start
|
||||
|
||||
if (moduleHandle->LDFlags & 4)
|
||||
{
|
||||
gv_lFlmSyncSem = kSemaphoreAlloc( (BYTE *)"FLAIM_SYNC", 0);
|
||||
}
|
||||
|
||||
// Initialize NSS
|
||||
|
||||
if( RC_BAD( f_nssInitialize()))
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pszModuleName = (char *)(&moduleHandle->LDFileName[ 1]);
|
||||
iModuleNameLen = (int)(moduleHandle->LDFileName[ 0]);
|
||||
|
||||
// First pass: Count the arguments in the command line
|
||||
// and determine how big of a buffer we will need.
|
||||
// Second pass: Put argments into allocated buffer.
|
||||
|
||||
Parse_Args:
|
||||
|
||||
iTotalArgChars = 0;
|
||||
iArgC = 0;
|
||||
|
||||
iLoadDirPathSize = f_strlen( (const char *)loadDirectoryPath);
|
||||
iArgSize = iLoadDirPathSize + iModuleNameLen;
|
||||
|
||||
if( !bFirstPass)
|
||||
{
|
||||
ppszArgV[ iArgC] = pszDestArg;
|
||||
f_memcpy( pszDestArg, loadDirectoryPath, iLoadDirPathSize);
|
||||
f_memcpy( &pszDestArg[ iLoadDirPathSize], pszModuleName, iModuleNameLen);
|
||||
pszDestArg[ iArgSize] = 0;
|
||||
pszDestArg += (iArgSize + 1);
|
||||
}
|
||||
|
||||
iArgC++;
|
||||
iTotalArgChars += iArgSize;
|
||||
pszTmp = commandLine;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Skip leading blanks.
|
||||
|
||||
while( *pszTmp && *pszTmp == ' ')
|
||||
{
|
||||
pszTmp++;
|
||||
}
|
||||
|
||||
if( *pszTmp == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( *pszTmp == '"' || *pszTmp == '\'')
|
||||
{
|
||||
cEnd = *pszTmp;
|
||||
pszTmp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cEnd = ' ';
|
||||
}
|
||||
|
||||
pszArgStart = pszTmp;
|
||||
iArgSize = 0;
|
||||
|
||||
// Count the characters in the parameter.
|
||||
|
||||
while( *pszTmp && *pszTmp != cEnd)
|
||||
{
|
||||
iArgSize++;
|
||||
pszTmp++;
|
||||
}
|
||||
|
||||
if( !iArgSize && cEnd == ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// If 2nd pass, save the argument.
|
||||
|
||||
if( !bFirstPass)
|
||||
{
|
||||
ppszArgV[ iArgC] = pszDestArg;
|
||||
|
||||
if( iArgSize)
|
||||
{
|
||||
f_memcpy( pszDestArg, pszArgStart, iArgSize);
|
||||
}
|
||||
|
||||
pszDestArg[ iArgSize] = 0;
|
||||
pszDestArg += (iArgSize + 1);
|
||||
}
|
||||
|
||||
iArgC++;
|
||||
iTotalArgChars += iArgSize;
|
||||
|
||||
// Skip trailing quote or blank.
|
||||
|
||||
if( *pszTmp)
|
||||
{
|
||||
pszTmp++;
|
||||
}
|
||||
}
|
||||
|
||||
if( bFirstPass)
|
||||
{
|
||||
if ((ppszArgV = (char **)Alloc( sizeof( char *) * iArgC,
|
||||
gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( (pszArgs = (char *)Alloc( iTotalArgChars + iArgC,
|
||||
gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pszDestArg = pszArgs;
|
||||
bFirstPass = false;
|
||||
goto Parse_Args;
|
||||
}
|
||||
|
||||
iThreadNameLen = (int)(moduleHandle->LDName[ 0]);
|
||||
|
||||
if( (pszThreadName = (char *)Alloc( iThreadNameLen + 1, gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
f_memcpy( pszThreadName, (char *)(&moduleHandle->LDName[ 1]), iThreadNameLen);
|
||||
pszThreadName[ iThreadNameLen] = 0;
|
||||
|
||||
if( (pArgData = (ARG_DATA *)Alloc( sizeof( ARG_DATA),
|
||||
gv_lAllocRTag)) == NULL)
|
||||
{
|
||||
sdRet = 1;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pArgData->ppszArgV = ppszArgV;
|
||||
pArgData->pszArgs = pszArgs;
|
||||
pArgData->iArgC = iArgC;
|
||||
pArgData->moduleHandle = moduleHandle;
|
||||
pArgData->pszThreadName = pszThreadName;
|
||||
|
||||
gv_bMainRunning = TRUE;
|
||||
|
||||
if( (hThread = kCreateThread( (BYTE *)"FTK main",
|
||||
f_nlmMainStub, NULL, 32768, (void *)pArgData)) == NULL)
|
||||
{
|
||||
gv_bMainRunning = FALSE;
|
||||
sdRet = 2;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( kSetThreadLoadHandle( hThread, (LONG)moduleHandle) != 0)
|
||||
{
|
||||
(void)kDestroyThread( hThread);
|
||||
gv_bMainRunning = FALSE;
|
||||
sdRet = 2;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if( kScheduleThread( hThread) != 0)
|
||||
{
|
||||
(void)kDestroyThread( hThread);
|
||||
gv_bMainRunning = FALSE;
|
||||
sdRet = 2;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Synchronized start
|
||||
|
||||
if( moduleHandle->LDFlags & 4)
|
||||
{
|
||||
(void)kSemaphoreWait( gv_lFlmSyncSem);
|
||||
}
|
||||
|
||||
Exit:
|
||||
|
||||
if( sdRet != 0)
|
||||
{
|
||||
f_atomicDec( &gv_NetWareStartupCount);
|
||||
|
||||
if( ppszArgV)
|
||||
{
|
||||
Free( ppszArgV);
|
||||
}
|
||||
|
||||
if( pszArgs)
|
||||
{
|
||||
Free( pszArgs);
|
||||
}
|
||||
|
||||
if( pszThreadName)
|
||||
{
|
||||
Free( pszThreadName);
|
||||
}
|
||||
|
||||
if( pArgData)
|
||||
{
|
||||
Free( pArgData);
|
||||
}
|
||||
|
||||
if( gv_lFlmSyncSem)
|
||||
{
|
||||
kSemaphoreFree( gv_lFlmSyncSem);
|
||||
gv_lFlmSyncSem = 0;
|
||||
}
|
||||
|
||||
if( !gv_bUnloadCalled)
|
||||
{
|
||||
KillMe( moduleHandle);
|
||||
}
|
||||
}
|
||||
|
||||
return( sdRet);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" void f_nlmExitPoint(void)
|
||||
{
|
||||
if( f_atomicDec( &gv_NetWareStartupCount) > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gv_bUnloadCalled = TRUE;
|
||||
|
||||
if( gv_fnExit)
|
||||
{
|
||||
(*gv_fnExit)();
|
||||
gv_fnExit = NULL;
|
||||
}
|
||||
|
||||
while( gv_bMainRunning)
|
||||
{
|
||||
kYieldThread();
|
||||
}
|
||||
|
||||
f_nssUninitialize();
|
||||
|
||||
if( gv_lFlmSyncSem)
|
||||
{
|
||||
kSemaphoreFree( gv_lFlmSyncSem);
|
||||
gv_lFlmSyncSem = 0;
|
||||
}
|
||||
|
||||
if( gv_lAllocRTag)
|
||||
{
|
||||
ReturnResourceTag( gv_lAllocRTag, 1);
|
||||
gv_lAllocRTag = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" void exit(
|
||||
int exitCode)
|
||||
{
|
||||
(void)exitCode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_RING_ZERO_NLM)
|
||||
extern "C" int atexit(
|
||||
F_EXIT_FUNC fnExit)
|
||||
{
|
||||
gv_fnExit = fnExit;
|
||||
return( 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FLM_NLM
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if defined( FLM_OSX)
|
||||
void gv_fnlm2()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Desc:
|
||||
****************************************************************************/
|
||||
#if !defined( FLM_NLM)
|
||||
int ftknlmDummy2( void)
|
||||
{
|
||||
return( 0);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user