/******************************************************************************* * * 模 块 名:DBService 文件名:ServiceInit.c * 相关文件:ServiceInit.h * z提交日期:2012.2.1 作 者:Alex * 版 本:0.1 * 模块描述: * 相当于事务处理模块的构造和析构模块 * ServiceInit(); * ServiceDeInit(); * 修改记录: * 日 期 版本 修改人 修改内容 * * *******************************************************************************/ #ifdef _WIN32 #define _SERVICEINIT_CPP #include "IOCmpltThread.h" //#include #include #include #include #include #include "DbService.h" #include "MessageThread.h" #include "ServiceInit.h" #include "debug.h" #include "DataBuffers.h" #include "ResponseManager.h" #include "DBInterface.h" //#define CTYPE_GBK 936 //#define CTYPE_UTF8 65001 CUDPMessageReceiveThread * g_pMessageReceiveThread = NULL; CIOCmpltThread * g_pIOCmpltThread = NULL; CDataBufferManager* g_pDataBuffers = NULL; CResponseManager* g_pResponses = NULL; int g_aStyleRecomList[MAX_STYLE_NUM+1]; TQNAITEM g_lstCommonQnA[200]; TNOTICEITEM g_lstPublicNotice[MAX_NOTICE_NUM]; int g_nCommonQnANum = 0, g_nPublicNoticeNum = 0; HINSTANCE g_hDBAccessDll = NULL, g_hParamDll = NULL; extern MHTHREADLIST g_lstMessageHandleThreads; TCLIENTVERSION* g_pVersionClient = NULL; TTESTVERSION* g_pVersionClientTest = NULL; int g_nClientTypeNum = 0, g_nClientTestNum = 0; HANDLE g_hEvClientCheck = NULL; char g_strStyleFileDir[256] = ""; char g_strWebFileDir[256] = ""; char g_strMusicFileDir[256] = ""; char g_strMusicLocation[8] = ""; char g_strServiceDir[256] = ""; //UINT g_locale_ctype = 0; /* void UpdateStyleInfo() { typedef int (*CM_GetStyleTracksInfo)( int len, BYTE data[], char tracks[4][8][16][3] ); //加载ComposeModule HINSTANCE hStyleDll = LoadLibrary( "StyleUpdate.dll" ); if( hStyleDll==NULL ){ DWORD dwRet = GetLastError(); DebugPrint( "载入风格模块失败, 程序终止! errcode=%d", dwRet ); return; } CM_GetStyleTracksInfo f_CM_GetStyleTracksInfo = (CM_GetStyleTracksInfo)GetProcAddress( hStyleDll, "CM_GetStyleTracksInfo" ); if( !( f_CM_GetStyleTracksInfo ) ){ DebugPrint( "获取风格模块访问函数失败, 程序终止!\n" ); return; } char strFileName[256]; char buf[20]; int id = 1; while( true ){ //打开原风格文件 strcpy( strFileName, g_strStyleFileDir ); UINT nDir = ((UINT)id-1) >> 13; sprintf( buf, "%08X\\", nDir ); strcat( strFileName, buf ); sprintf( buf, "%08X.YSF", id ); strcat( strFileName, buf ); FILE *fp = fopen( strFileName, "r+b" ); if( !fp ){ int err = GetLastError(); DebugPrint( "修改完毕,或文件读取错误err=%d\n", err ); return; } else{ //读取原风格信息 fseek( fp, 0, SEEK_END ); int len = ftell( fp ); int nDataSize = len - sizeof(TSTYLEINFO0); BYTE * pData = new BYTE[nDataSize]; TMAKESTYLEINFO infoNew; TSTYLEINFO0 infoOld; fseek( fp, 0, SEEK_SET ); fread( &infoOld, 1, sizeof(TSTYLEINFO0), fp ); fread( pData, 1, nDataSize, fp ); //读取轨道信息 char tracks[4][8][16][3]; int size = sizeof( tracks ); memset( tracks, -1, size ); int err = f_CM_GetStyleTracksInfo( nDataSize, pData, tracks ); if( 0==err ){ //修改info // infoNew.idStyle = id; memcpy( infoNew.detail.type, infoOld.detail.type, sizeof(infoOld.detail.type) ); memcpy( infoNew.detail.chordRecom, infoOld.detail.chordRecom, sizeof(infoOld.detail.chordRecom) ); memcpy( infoNew.detail.aIntroBars, infoOld.detail.aIntroBars, sizeof(infoOld.detail.aIntroBars) ); memcpy( infoNew.detail.aEndingBars, infoOld.detail.aEndingBars, sizeof(infoOld.detail.aEndingBars) ); for( int s=0; s<4; s++ ){ for( int i=0; i<8; i++ ){ for( int j=0; j<16; j++ ){ infoNew.detail.tracks[s][i][j].no = tracks[s][i][j][0]; infoNew.detail.tracks[s][i][j].prog = tracks[s][i][j][1]; infoNew.detail.tracks[s][i][j].vol = tracks[s][i][j][2]; } } } err = f_DB_UpdateStyle( id, &infoNew ); if( 0==err ){ fseek( fp, 0, SEEK_SET ); fwrite( &infoNew, 1, sizeof(TSTYLEINFO), fp ); fwrite( pData, 1, nDataSize, fp ); // DebugPrint( "Style %d updating OK\n", infoNew.idStyle ); } } if( err!=0 ){ DebugPrint( "Style %d updating failed! err=%d\n", id, err ); } delete[] pData; fclose( fp ); } id++; } } */ void ModifyStyleDesc() { char strFileName[256]; char buf[20]; // int ids[3] = {404,418,422}; // char desc[3][120] = { "模仿周杰伦《东风破》的简单中国风,竖琴可换琵琶或古筝,鼓换电鼓", // "模仿王菲《闷》的摇滚风格,还原前间奏,乐器协调性是美中不足", // "麒麟谱,四不像,伪中国风。《红妆》编曲的收获,感谢花枝。" }; for( UINT i=g_iChkStyle; ; i++ ){ char strFileName[256]; char buf[20]; strcpy( strFileName, g_strStyleFileDir ); UINT nDir = (i-1) >> 13; sprintf( buf, "%08X\\", nDir ); strcat( strFileName, buf ); sprintf( buf, "%08X.YSI", i ); strcat( strFileName, buf ); FILE *fp = fopen( strFileName, "r+b" ); if( !fp ){ int err = GetLastError(); DebugPrint( "打开风格%d失败,err=%d\n", i, err ); return; } else{ short len = 0; fread( &len, 1, sizeof(short), fp ); if( len>0 ){ char* pData = new char[len]; fread( pData, 1, len, fp ); TSTYLEDETAIL detail; int ret = StyleTrans2Detail( detail, len, (char*)pData ); if( ret<0 ){ DebugPrint( "Style %d size error\n", i ); } else{ if( ret>0 ){ DebugPrint( "Trunc style %d %s\n", i, ret==1 ? "Author" : ret==2 ? "AtyleName" : "Description" ); // string ansiName; // // UTF8ToGBK( detail.strDescription, ansiName ); // GBKToUTF8( desc[i], ansiName); // strcpy( detail.strDescription, ansiName.c_str() ); int size; ret = StyleDetail2Trans( detail, size, pData ); if( ret>0 ) DebugPrint( "Trunc style %d %s\n", i, ret==1 ? "Author" : ret==2 ? "AtyleName" : "Description" ); len = size; fseek( fp, 0, SEEK_SET ); fwrite( &len, 1, sizeof(short), fp ); fwrite( pData, 1, len, fp ); } } } fclose( fp ); } } } void CreateLog() { SYSTEMTIME st; GetLocalTime(&st); char szBufPath[MAX_PATH] = ""; sprintf( szBufPath, "%slog\\", g_strServiceDir ); if( _chdir(szBufPath) == -1) { _mkdir(szBufPath); } sprintf( szBufPath, "%s%04d-%02d-%02d.log", szBufPath, st.wYear, st.wMonth, st.wDay); DebugModuleClose(); int iDebug = g_eDebug>0 ? g_eDebug : 1; DebugModuleInitialize( 0xFFFF, (EDPrintDest)iDebug, szBufPath ); } void GetStyleRecomList() { int tempList[MAX_STYLE_NUM+1]; memset( tempList, 0, sizeof(int)*(MAX_STYLE_NUM+1) ); int num = MAX_STYLE_NUM; int ret = f_DB_GetRecomStyleIDs( &num, tempList ); if( ret==0 ){ tempList[MAX_STYLE_NUM] = num; memcpy( g_aStyleRecomList, tempList, sizeof(int)*(MAX_STYLE_NUM+1) ); DebugPrint( "Recommand style num : %d\n", num ); } else{ DebugPrint( "DB_GetRecomStyleIDs return %d\n", ret ); } } void GetCommonQnAList() { int dtUpdate = 0; for( int i=0; i0 ){ char *tokenPtr=strtok( szBuf, "|" ); for( ; tokenPtr!=NULL; num++ ){ int iInner, iMaj, iMin, iMod, iBuil; sscanf( tokenPtr, "%d,%d.%d.%d", &iInner, &iMaj, &iMin, &iMod );//, &iBuil ); aVersion[num].iClientType = iInner; aVersion[num].version.majorVersion = iMaj; aVersion[num].version.minorVersion = iMin; aVersion[num].version.modifyVersion = iMod; // aVersion[num].version.buildVersion = iBuil; tokenPtr = strtok( NULL, "|" ); } } if( g_nClientTestNum>0 && g_nClientTestNum!=num ){ delete[] g_pVersionClientTest; g_pVersionClientTest = NULL; } g_nClientTestNum = num; if( num>0 ){ if( !g_pVersionClientTest ){ g_pVersionClientTest = new TTESTVERSION[num]; } for( int i=0; iversion.majorVersion, pVersion->version.minorVersion, pVersion->version.modifyVersion, //pVersion->version.buildVersion, //不设置构建版本 pVersion->iClientType ); } } else{ DebugPrint( "No test version.\n" ); } SetEvent( g_hEvClientCheck ); g_ftIniModify.dwLowDateTime = ftWrite.dwLowDateTime; g_ftIniModify.dwHighDateTime = ftWrite.dwHighDateTime; } else{ DebugPrint( "No config update.\n" ); } } void GetClientUpdateVersion() { if( WAIT_OBJECT_0!=WaitForSingleObject( g_hEvClientCheck, INFINITE ) ){ return; } int nOldTypeNum = g_nClientTypeNum; g_nClientTypeNum = f_DB_GetClientTypeNumber(); if( nOldTypeNum>0 && g_nClientTypeNum!=nOldTypeNum ){ delete[] g_pVersionClient; g_pVersionClient = NULL; } if( g_nClientTypeNum>0 ){ if( !g_pVersionClient ){ g_pVersionClient = new TCLIENTVERSION[g_nClientTypeNum]; } if( f_DB_GetClientVersion( g_pVersionClient, g_nClientTypeNum )>=0 ){ for( int i=0; iswInfo.strDescribe, ansiDescribe ); DebugPrint( "软件内部编号:%d\n最新客户端版本:%d.%d.%d.%04d\n 发布时间:%d-%d-%d\n 文件大小:%dK\n 文件描述:%s\n", pVersion->iClientType, pVersion->swInfo.version.majorVersion, pVersion->swInfo.version.minorVersion, pVersion->swInfo.version.modifyVersion, pVersion->swInfo.version.buildVersion, pVersion->swInfo.tIssueDate>>16, (pVersion->swInfo.tIssueDate&0xFF00)>>8, (pVersion->swInfo.tIssueDate&0xFF), pVersion->swInfo.nFileSize, ansiDescribe.c_str() ); } } else{ DebugPrint( "获取最新客户端版本信息失败!\n" ); } } else if( g_nClientTypeNum<0 ){ DebugPrint( "获取最新客户端类型数失败!\n" ); } SetEvent( g_hEvClientCheck ); } void OnTimerFunc( void *dummy ) { CreateLog(); // GetClientUpdateVersion(); GetStyleRecomList(); GetCommonQnAList(); // GetPublicNoticeList(); DebugPrint( "OnTimerFunc exit.\n" ); } bool ServiceInit() { g_hEvServiceThread = CreateEvent( NULL, // no security attributes TRUE, // manual reset event FALSE, // not-signalled NULL); // no name g_hEvClientCheck = CreateEvent( NULL, // no security attributes FALSE, // auto reset event TRUE, // signalled NULL); // no name if( !(g_hEvServiceThread && g_hEvClientCheck )){ return false; } WORD wVersionRequested; WSADATA wsaData; int err; /* //获取本地编码格式 char* locname = setlocale(LC_CTYPE, ""); char* code = strchr( locname, '.' ); //DebugPrint( "locale code: %s\n", code); if( !strcmp(code, ".936") || !strcmp(code, ".GBK") ){ g_locale_ctype = CTYPE_GBK; } */ wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { // Tell the user that we could not find a usable // WinSock DLL. _tprintf(TEXT("CreateService failed - can't startup wsock.\n")); if( g_hEvServiceThread ){ CloseHandle( g_hEvServiceThread ); g_hEvServiceThread = NULL; } return false; } //设置debug参数 HKEY hRootKey; DWORD nFlag=1, dwLength=4; if( ERROR_SUCCESS==RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\YHD\\ComposerService", 0, KEY_ALL_ACCESS, &hRootKey ) ){ if( RegQueryValueEx(hRootKey,"DebugFlag",NULL,NULL,(BYTE*)&nFlag,&dwLength)!=ERROR_SUCCESS ){ RegSetValueEx(hRootKey,"DebugFlag",0,REG_DWORD,(BYTE*)&nFlag,4 ); } RegCloseKey( hRootKey ); } char chTemp[2560]; GetModuleFileName( NULL, chTemp, 256 ); *(strrchr(chTemp, '\\')+1) = '\0'; strcpy( g_strServiceDir, chTemp ); //DebugModuleInitialize( 0xFFFF, (EDPrintDest)g_eDebug, NULL ); CreateLog(); //DebugPrint("DebugModuleInitialize success!\n"); //载入数据库访问模块 if( !LoadDB() ){ return FALSE; } // int ret = f_DB_InitDatabases("localhost", "root", "168soft.xyz"); f_DB_GetPath( g_strStyleFileDir, g_strWebFileDir, g_strMusicFileDir ); DebugPrint( "Style_dir: %s\nWeb_dir: %s\nMusic_dir: %s\n", g_strStyleFileDir, g_strWebFileDir, g_strMusicFileDir ); if( strlen(g_strMusicFileDir)>0 ){ char* pos = strstr( g_strMusicFileDir, "File" )+4; if( pos[0]!='/' && pos[0]!='\\' ){ int num; sscanf( pos, "%d", &num ); sprintf( g_strMusicLocation, "%d", num ); } } ///////////////////////////////////////////////////////////// //修改风格信息专用 //#ifdef _UPDATE if( g_iChkStyle>0 ){ // UpdateStyleInfo(); ModifyStyleDesc(); return FALSE; } //#endif ///////////////////////////////////////////////////////////// GetClientUpdateVersion(); memset( g_aStyleRecomList, 0, sizeof(int)*(MAX_STYLE_NUM+1) ); GetStyleRecomList(); g_ftIniModify.dwLowDateTime = 0; g_ftIniModify.dwHighDateTime = 0; ReadConfigParams(); GetCommonQnAList(); GetPublicNoticeList(); //创建数据接收 g_pDataBuffers = new CDataBufferManager; //创建消息响应管理 g_pResponses = new CResponseManager; //生成消息接收线程 CUDPSocket * pSocket = new CUDPSocket( 12071 ); if( pSocket && pSocket->IsOpen() ){ g_pMessageReceiveThread = new CUDPMessageReceiveThread( 3000, pSocket ); g_pMessageReceiveThread->Resume(); } //生成消息处理线程池 for( int i=0; i<20; i++ ){ pSocket = new CUDPSocket(); if( pSocket && pSocket->IsOpen() ){ CMessageHandleThread* pThread = new CMessageHandleThread( 3000, pSocket ); g_lstMessageHandleThreads.push_back( pThread ); } } //生成IOComplete线程 g_pIOCmpltThread = new CIOCmpltThread(3000); g_pIOCmpltThread->Resume(); _tprintf(TEXT("Composer Service is running...\n")); return true; } void ServiceDeInit() { _tprintf(TEXT("Composer Service is stopping...\n")); if( g_hEvClientCheck ){ CloseHandle( g_hEvClientCheck ); } if( g_pVersionClient ){ delete[] g_pVersionClient; g_pVersionClient = NULL; } if( g_pMessageReceiveThread ){ g_pMessageReceiveThread->Terminate(); delete g_pMessageReceiveThread; g_pMessageReceiveThread = NULL; } MHTHREADLIST::iterator iMT = g_lstMessageHandleThreads.begin(); while( iMT!=g_lstMessageHandleThreads.end() ){ (*iMT)->Terminate(); delete (*iMT); iMT = g_lstMessageHandleThreads.erase( iMT ); } if( g_pIOCmpltThread ){ g_pIOCmpltThread->Terminate(); delete g_pIOCmpltThread; g_pIOCmpltThread = NULL; } FreeDB(); if( g_pDataBuffers ){ delete g_pDataBuffers; g_pDataBuffers = NULL; } if( g_pResponses ){ delete g_pResponses; g_pResponses = NULL; } DebugModuleClose(); WSACleanup( ); DebugPrint( "System unloaded!" ); if( g_hEvServiceThread ){ SetEvent( g_hEvServiceThread ); } _tprintf(TEXT("Composer Service stopped.\n")); } /* #ifndef _DEBUG #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址 #endif */ DWORD WINAPI DBMain(void* pParam) { MSG msg; if( !ServiceInit() ){ // return 1; } SYSTEMTIME st; GetLocalTime(&st); DWORD timeCount = st.wHour * 60 * 60 + st.wMinute * 60 + st.wSecond; // timeCount = 0; //test UINT uTimer = SetTimer( NULL, 0, 1000, NULL ); while( GetMessage(&msg, NULL, 0, 0) && msg.message!=WM_CLOSE ){ if( msg.message==WM_TIMER && msg.wParam==uTimer ){ if( g_pIOCmpltThread ){ g_pIOCmpltThread->OnTimer(); } if( g_pDataBuffers ){ g_pDataBuffers->OnTimer(); } if( g_pResponses ){ g_pResponses->OnTimer(); } if( ++timeCount>=86400 ){ //00:00:00 // if( ++timeCount>=600 ){ //test 10 minutes // timeCount = 0; //test GetLocalTime(&st); timeCount = st.wHour * 60 * 60 + st.wMinute * 60 + st.wSecond; if( st.wHour==0 ){ // _beginthread( OnTimerFunc, 0, NULL ); CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)OnTimerFunc, 0, 0, 0 ); } } if( ( timeCount & 0x1FF )==0 ){ //512s~9m f_DB_CleanVipLog(); } if( ( timeCount & 0xFFF )==0 ){ //4095s~68m~1h 获取测试版本信息 ReadConfigParams(); } if( ( timeCount & 0x1FFF )==0 ){ //8191s~136m~2h 获取发布版本信息 GetClientUpdateVersion(); } continue; } try{ TranslateMessage (&msg); DispatchMessage (&msg); }catch (...){ _tprintf(TEXT("!!!!!!Unexpected exception in WMain()!!!!!!\n")); } } KillTimer( NULL, uTimer ); IF_DEBUG_SYSMANAGER(DebugPrint("%X:In %s Line %d WMain ExitThread!\n", TRACE_NUMBER(e_Trace_SysManager,e_Trace_Normal), __FILE__,__LINE__)) ServiceDeInit(); _tprintf(TEXT("WMain() ExitThread!\n")); ExitThread(0); return 0; } #endif