/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2001 Apple Computer, Inc. All Rights Reserved. The * contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please * obtain a copy of the License at http://www.apple.com/publicsource and * read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please * see the License for the specific language governing rights and * limitations under the License. * * * @APPLE_LICENSE_HEADER_END@ * */ /* File: QTSSModule.cpp Contains: Implements object defined in QTSSModule.h */ #include #include "QTSSModule.h" #include "OSArrayObjectDeleter.h" #include "OSMemory.h" #include "StringParser.h" #include "Socket.h" Bool16 QTSSModule::sHasRTSPRequestModule = false; Bool16 QTSSModule::sHasOpenFileModule = false; Bool16 QTSSModule::sHasRTSPAuthenticateModule = false; QTSSAttrInfoDict::AttrInfo QTSSModule::sAttributes[] = { /*fields: fAttrName, fFuncPtr, fAttrDataType, fAttrPermission */ /* 0 */ { "qtssModName", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe }, /* 1 */ { "qtssModDesc", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModeWrite }, /* 2 */ { "qtssModVersion", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModeWrite }, /* 3 */ { "qtssModRoles", NULL, qtssAttrDataTypeUInt32, qtssAttrModeRead | qtssAttrModePreempSafe }, /* 4 */ { "qtssModPrefs", NULL, qtssAttrDataTypeQTSS_Object,qtssAttrModeRead | qtssAttrModePreempSafe | qtssAttrModeInstanceAttrAllowed }, /* 5 */ { "qtssModAttributes", NULL, qtssAttrDataTypeQTSS_Object, qtssAttrModeRead | qtssAttrModePreempSafe | qtssAttrModeInstanceAttrAllowed } }; void QTSSModule::Initialize() { //Setup all the dictionary stuff for (UInt32 x = 0; x < qtssModNumParams; x++) QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kModuleDictIndex)-> SetAttribute(x, sAttributes[x].fAttrName, sAttributes[x].fFuncPtr, sAttributes[x].fAttrDataType, sAttributes[x].fAttrPermission); } QTSSModule::QTSSModule(char* inName, char* inPath) : QTSSDictionary(QTSSDictionaryMap::GetMap(QTSSDictionaryMap::kModuleDictIndex)), fQueueElem(this), fPath(NULL), fFragment(NULL), fDispatchFunc(NULL), fPrefs(NULL), fAttributes(NULL) { if ((inPath != NULL) && (inPath[0] != '\0')) { // Create a code fragment if this module is being loaded from disk fFragment = NEW OSCodeFragment(inPath); fPath = NEW char[::strlen(inPath) + 2]; ::strcpy(fPath, inPath); } fAttributes = NEW QTSSDictionary( NULL, &fAttributesMutex ); this->SetVal(qtssModPrefs, &fPrefs, sizeof(fPrefs)); this->SetVal(qtssModAttributes, &fAttributes, sizeof(fAttributes)); // If there is a name, copy it into the module object's internal buffer if (inName != NULL) this->SetValue(qtssModName, 0, inName, ::strlen(inName), QTSSDictionary::kDontObeyReadOnly); ::memset(fRoleArray, 0, sizeof(fRoleArray)); } QTSS_Error QTSSModule::SetupModule(QTSS_CallbacksPtr inCallbacks, QTSS_MainEntryPointPtr inEntrypoint) { QTSS_Error theErr = QTSS_NoErr; // Load fragment from disk if necessary if ((fFragment != NULL) && (inEntrypoint == NULL)) theErr = this->LoadFromDisk(&inEntrypoint); if (theErr != QTSS_NoErr) return theErr; // At this point, we must have an entrypoint if (inEntrypoint == NULL) return QTSS_NotAModule; // Invoke the private initialization routine QTSS_PrivateArgs thePrivateArgs; thePrivateArgs.inServerAPIVersion = QTSS_API_VERSION; thePrivateArgs.inCallbacks = inCallbacks; thePrivateArgs.outStubLibraryVersion = 0; thePrivateArgs.outDispatchFunction = NULL; theErr = (inEntrypoint)(&thePrivateArgs); if (theErr != QTSS_NoErr) return theErr; if (thePrivateArgs.outStubLibraryVersion > thePrivateArgs.inServerAPIVersion) return QTSS_WrongVersion; // Set the dispatch function so we'll be able to invoke this module later on fDispatchFunc = thePrivateArgs.outDispatchFunction; return QTSS_NoErr; } QTSS_Error QTSSModule::LoadFromDisk(QTSS_MainEntryPointPtr* outEntrypoint) { static StrPtrLen sMainEntrypointName("_Main"); Assert(outEntrypoint != NULL); // Modules only need to be initialized if they reside on disk. if (fFragment == NULL) return QTSS_NoErr; if (!fFragment->IsValid()) return QTSS_NotAModule; // fPath is actually a path. Extract the file name. StrPtrLen theFileName(fPath); StringParser thePathParser(&theFileName); while (thePathParser.GetThru(&theFileName, kPathDelimiterChar)) ; Assert(theFileName.Len > 0); Assert(theFileName.Ptr != NULL); #ifdef __Win32__ StringParser theDLLTruncator(&theFileName); theDLLTruncator.ConsumeUntil(&theFileName, '.'); // strip off the ".DLL" #endif /** 08/16/01 quellish **/ #if __MacOSX__ StringParser theBundleTruncator(&theFileName); theBundleTruncator.ConsumeUntil(&theFileName, '.'); // strip off the ".bundle" #endif // At this point, theFileName points to the file name. Make this the module name. this->SetValue(qtssModName, 0, theFileName.Ptr, theFileName.Len, QTSSDictionary::kDontObeyReadOnly); // // The main entrypoint symbol name is the file name plus that _Main__ string up there. OSCharArrayDeleter theSymbolName(NEW char[theFileName.Len + sMainEntrypointName.Len + 2]); ::memcpy(theSymbolName, theFileName.Ptr, theFileName.Len); theSymbolName[theFileName.Len] = '\0'; ::strcat(theSymbolName, sMainEntrypointName.Ptr); *outEntrypoint = (QTSS_MainEntryPointPtr)fFragment->GetSymbol(theSymbolName.GetObject()); return QTSS_NoErr; } QTSS_Error QTSSModule::AddRole(QTSS_Role inRole) { // There can only be one QTSS_RTSPRequest processing module if ((inRole == QTSS_RTSPRequest_Role) && (sHasRTSPRequestModule)) return QTSS_RequestFailed; if ((inRole == QTSS_OpenFilePreProcess_Role) && (sHasOpenFileModule)) return QTSS_RequestFailed; // There can be only one module registered for QTSS_RTSPAuthenticate_Role if ((inRole == QTSS_RTSPAuthenticate_Role) && (sHasRTSPAuthenticateModule)) return QTSS_RequestFailed; switch (inRole) { // Map actual QTSS Role names to our private enum values. Turn on the proper one // in the role array case QTSS_Initialize_Role: fRoleArray[kInitializeRole] = true; break; case QTSS_Shutdown_Role: fRoleArray[kShutdownRole] = true; break; case QTSS_RTSPFilter_Role: fRoleArray[kRTSPFilterRole] = true; break; case QTSS_RTSPRoute_Role: fRoleArray[kRTSPRouteRole] = true; break; case QTSS_RTSPAuthenticate_Role: fRoleArray[kRTSPAthnRole] = true; break; case QTSS_RTSPAuthorize_Role: fRoleArray[kRTSPAuthRole] = true; break; case QTSS_RTSPPreProcessor_Role: fRoleArray[kRTSPPreProcessorRole] = true; break; case QTSS_RTSPRequest_Role: fRoleArray[kRTSPRequestRole] = true; break; case QTSS_RTSPPostProcessor_Role: fRoleArray[kRTSPPostProcessorRole] = true; break; case QTSS_RTSPSessionClosing_Role: fRoleArray[kRTSPSessionClosingRole] = true; break; case QTSS_RTPSendPackets_Role: fRoleArray[kRTPSendPacketsRole] = true; break; case QTSS_ClientSessionClosing_Role:fRoleArray[kClientSessionClosingRole] = true;break; case QTSS_RTCPProcess_Role: fRoleArray[kRTCPProcessRole] = true; break; case QTSS_ErrorLog_Role: fRoleArray[kErrorLogRole] = true; break; case QTSS_RereadPrefs_Role: fRoleArray[kRereadPrefsRole] = true; break; case QTSS_OpenFile_Role: fRoleArray[kOpenFileRole] = true; break; case QTSS_OpenFilePreProcess_Role: fRoleArray[kOpenFilePreProcessRole] = true; break; case QTSS_AdviseFile_Role: fRoleArray[kAdviseFileRole] = true; break; case QTSS_ReadFile_Role: fRoleArray[kReadFileRole] = true; break; case QTSS_CloseFile_Role: fRoleArray[kCloseFileRole] = true; break; case QTSS_RequestEventFile_Role: fRoleArray[kRequestEventFileRole] = true; break; case QTSS_RTSPIncomingData_Role: fRoleArray[kRTSPIncomingDataRole] = true; break; case QTSS_StateChange_Role: fRoleArray[kStateChangeRole] = true; break; default: return QTSS_BadArgument; } if (inRole == QTSS_RTSPRequest_Role) sHasRTSPRequestModule = true; if (inRole == QTSS_OpenFile_Role) sHasOpenFileModule = true; if (inRole == QTSS_RTSPAuthenticate_Role) sHasRTSPAuthenticateModule = true; // // Add this role to the array of roles attribute QTSS_Error theErr = this->SetValue(qtssModRoles, this->GetNumValues(qtssModRoles), &inRole, sizeof(inRole), QTSSDictionary::kDontObeyReadOnly); Assert(theErr == QTSS_NoErr); return QTSS_NoErr; }