📄 w32g_syn.c
字号:
int ok = 0; for ( i = 0; i < 10; i++ ) { if ( WaitForSingleObject ( w32g_syn.syn_hThread, 200 ) == WAIT_TIMEOUT ) { w32g_message_set ( W32G_SYN_QUIT ); } else { ok = 1; break; } } return ok;}#else // !TWSYNSRV// Windows service version here// To debug output (Require attached debugger)static void OutputString(char *format, ...){ char temp[256]; va_list va; va_start(va, format); vsnprintf(temp, sizeof(temp), format, va); OutputDebugString(temp); va_end(va);}void PutsConsoleWnd(char *str){ OutputString("%s", str);}// To MessageBox Window (Require grant access windowstation)static void OutputWindow(char *format, ...){ char temp[256]; va_list va; va_start(va, format); vsnprintf(temp, sizeof(temp), format, va); MessageBox(NULL, temp, serviceName, MB_OK | MB_ICONEXCLAMATION); va_end(va);}static void OutputLastError(char *message){ LPVOID buffer; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer, 0, NULL); OutputDebugString(message); OutputDebugString(" : "); OutputDebugString(buffer); OutputDebugString("\n"); LocalFree(buffer);}static void OutputWindowLastError(char *message){ LPVOID buffer; char *temp; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer, 0, NULL); temp = (char *)malloc(strlen((const char *)buffer) + strlen(message) + 10); sprintf(temp, "%s : %s\n", message, buffer); MessageBox(NULL, temp, serviceName, MB_OK | MB_ICONEXCLAMATION); free(temp); LocalFree(buffer);}// Report service status to service control managerstatic BOOL ReportStatusToSCM(DWORD newServiceStatus, DWORD checkPoint, DWORD waitHint, DWORD win32ExitCode, DWORD serviceSpecificExitCode){ BOOL result; SERVICE_STATUS serviceStatus; serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; currentServiceStatus = newServiceStatus; serviceStatus.dwCurrentState = newServiceStatus; serviceStatus.dwCheckPoint = checkPoint; serviceStatus.dwWaitHint = waitHint; serviceStatus.dwWin32ExitCode = win32ExitCode; serviceStatus.dwServiceSpecificExitCode = serviceSpecificExitCode; if (newServiceStatus == SERVICE_START_PENDING) { serviceStatus.dwControlsAccepted = 0; } else { serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_PARAMCHANGE; } result = SetServiceStatus(serviceStatusHandle, &serviceStatus); if (result == FALSE) { OutputLastError("ReportStatusToSCM() == FALSE"); } return result;}// Report service status to service control manager (Alternate version)static BOOL PingStatusToSCM(DWORD checkPoint, DWORD waitHint){ return ReportStatusToSCM(currentServiceStatus, checkPoint, waitHint, NO_ERROR, NO_ERROR);}// Service control message from management interface (Callback from SCM)static void WINAPI ServiceCtrlHandler(DWORD state){ switch (state) { case SERVICE_CONTROL_STOP: ReportStatusToSCM(SERVICE_STOP_PENDING, 1, 0, NO_ERROR, NO_ERROR); w32g_message_set(W32G_SYN_QUIT); break; case SERVICE_CONTROL_PAUSE: ReportStatusToSCM(SERVICE_PAUSE_PENDING, 1, 0, NO_ERROR, NO_ERROR); w32g_message_set(W32G_SYN_STOP); ReportStatusToSCM(SERVICE_PAUSED, 1, 0, NO_ERROR, NO_ERROR); break; case SERVICE_CONTROL_CONTINUE: ReportStatusToSCM(SERVICE_CONTINUE_PENDING, 1, 0, NO_ERROR, NO_ERROR); w32g_message_set(W32G_SYN_START); ReportStatusToSCM(SERVICE_RUNNING, 1, 0, NO_ERROR, NO_ERROR); break; case SERVICE_CONTROL_INTERROGATE: OutputString("ServiceCtrlHandler(), SERVICE_CONTROL_INTERROGATE : oops.\n"); break; case SERVICE_CONTROL_SHUTDOWN: OutputString("ServiceCtrlHandler(), SERVICE_CONTROL_SHUTDOWN : oops.\n"); break; default: OutputString("ServiceCtrlHandler(), default handler (%d) : oops.\n", state); break; } PingStatusToSCM(0, 0);}// Register service control handlerstatic SERVICE_STATUS_HANDLE RegisterCtrlHandler(){ SERVICE_STATUS_HANDLE ssh = RegisterServiceCtrlHandler( serviceName, ServiceCtrlHandler); if (ssh == 0) { OutputLastError("RegisterServiceCtrlHandler() == 0"); return NULL; } return ssh;}// Service entry function (Callback from SCM)static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv){ serviceStatusHandle = RegisterCtrlHandler(); ReportStatusToSCM(SERVICE_RUNNING, 1, 0, NO_ERROR, NO_ERROR); w32g_syn.syn_hThread = GetCurrentThread(); win_main(w32g_syn.argc, w32g_syn.argv); ReportStatusToSCM(SERVICE_STOPPED, 1, 0, NO_ERROR, NO_ERROR);}// return// 0 : OK// -1 : FATAL ERRORstatic int w32g_syn_main ( void ){ int i; BOOL result; SERVICE_TABLE_ENTRY ServiceTable[2]; w32g_syn.nid_uID = W32G_SYN_NID_UID; processPriority = NORMAL_PRIORITY_CLASS; syn_ThreadPriority = THREAD_PRIORITY_NORMAL; for ( i = 0; i <= MAX_PORT; i ++ ) { w32g_syn_id_port[i] = i + 1; } ServiceTable[0].lpServiceName = (LPSTR)serviceName; ServiceTable[0].lpServiceProc = ServiceMain; ServiceTable[1].lpServiceName = 0; ServiceTable[1].lpServiceProc = 0; result = StartServiceCtrlDispatcher(ServiceTable); if (result == FALSE) {#if 0// OutputLastError("StartServiceCtrlDispatcher() == FALSE"); OutputWindowLastError("StartServiceCtrlDispatcher() == FALSE");#else ServiceMain(0, 0);#endif return -1; } return 0;}// Service installerstatic BOOL InstallService(){ char twSynSrvPath[_MAX_PATH], serviceLongName[40]; SC_HANDLE scm, sv; HKEY srvKey; GetModuleFileName(NULL, twSynSrvPath, _MAX_PATH); scm = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE); if (scm == NULL) { OutputWindowLastError("OpenSCManager() == NULL"); return FALSE; } strcpy(serviceLongName, serviceName); strcat(serviceLongName, (strcmp(timidity_version, "current")) ? " version " : " "); strcat(serviceLongName, timidity_version); sv = CreateService(scm, serviceName, serviceLongName, 0, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, twSynSrvPath, NULL, NULL, NULL, NULL, NULL); if (sv == NULL) { OutputWindowLastError("CreateService() == NULL"); CloseServiceHandle(scm); return FALSE; } CloseServiceHandle(sv); CloseServiceHandle(scm); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKeyTwSynSrv, 0, KEY_WRITE | KEY_READ, &srvKey) == ERROR_SUCCESS) { if (RegSetValueEx(srvKey, "Description", NULL, REG_SZ, (const BYTE *)serviceDescription, strlen(serviceDescription)) != ERROR_SUCCESS) { OutputWindowLastError("RegSetValueEx() != ERROR_SUCCESS"); RegCloseKey(srvKey); return FALSE; } RegCloseKey(srvKey); } OutputWindow("%s : Service install successful.", serviceLongName); return TRUE;}// Service uninstallerstatic BOOL UninstallService(){ char serviceLongName[40]; SC_HANDLE scm, sv; scm = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); if (scm == NULL) { OutputWindowLastError("OpenSCManager() == NULL"); return FALSE; } sv = OpenService(scm, serviceName, DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); if (sv == NULL) { OutputWindowLastError("OpenService() == NULL"); CloseServiceHandle(scm); return FALSE; } if (DeleteService(sv) == FALSE) { OutputWindowLastError("DeleteService() == FALSE"); CloseServiceHandle(sv); CloseServiceHandle(scm); return FALSE; } CloseServiceHandle(sv); CloseServiceHandle(scm); strcpy(serviceLongName, serviceName); strcat(serviceLongName, (strcmp(timidity_version, "current")) ? " version " : " "); strcat(serviceLongName, timidity_version); OutputWindow("%s : Service uninstall successful.", serviceLongName); return TRUE;}#endif // !TWSYNSRV// 壜曄挿堷悢偵偡傞梊掕乧乧// 0: 惉岟丄1: 捛壛偱偒側偐偭偨int w32g_message_set ( int cmd ){ int res = 0; if ( msg_loopbuf_hMutex == NULL ) { msg_loopbuf_hMutex = CreateMutex ( NULL, TRUE, NULL ); } else { WaitForSingleObject ( msg_loopbuf_hMutex, INFINITE ); } if ( cmd == W32G_SYN_QUIT || cmd == W32G_SYN_START || cmd == W32G_SYN_STOP ) { // 桪愭偡傞儊僢僙乕僕丅 msg_loopbuf_start = 0; msg_loopbuf_end = 0; msg_loopbuf[msg_loopbuf_end].cmd = cmd; ReleaseMutex ( msg_loopbuf_hMutex ); return res; } else if ( cmd != W32G_SYN_NONE ) { if ( msg_loopbuf_end < 0 ) { msg_loopbuf_start = 0; msg_loopbuf_end = 0; } else if ( msg_loopbuf_start <= msg_loopbuf_end ) { if ( msg_loopbuf_end < W32G_SYN_MESSAGE_MAX - 1) msg_loopbuf_end ++; else res = 1; } else if ( msg_loopbuf_end < msg_loopbuf_start - 1 ) { msg_loopbuf_end ++; } else { res = 1; } if ( res == 0 ) { msg_loopbuf[msg_loopbuf_end].cmd = cmd; } } ReleaseMutex ( msg_loopbuf_hMutex ); Sleep ( 100 ); return res;}int w32g_message_get ( w32g_syn_message_t *msg ){ int have_msg = 0; if ( msg_loopbuf_hMutex == NULL ) { msg_loopbuf_hMutex = CreateMutex ( NULL, TRUE, NULL ); } else { WaitForSingleObject ( msg_loopbuf_hMutex, INFINITE ); } if ( msg_loopbuf_start >= 0 ) { memcpy ( msg, &msg_loopbuf[msg_loopbuf_start], sizeof ( w32g_syn_message_t ) ); have_msg = 1; msg_loopbuf_start ++; if ( msg_loopbuf_end < msg_loopbuf_start ) { msg_loopbuf_start = msg_loopbuf_end = -1; } else if ( msg_loopbuf_start >= W32G_SYN_MESSAGE_MAX ) { msg_loopbuf_start = 0; } } ReleaseMutex ( msg_loopbuf_hMutex ); return have_msg;}extern int seq_quit;extern void rtsyn_play_event(MidiEvent *);void w32g_syn_doit(void){ w32g_syn_message_t msg; MidiEvent ev; DWORD sleep_time; while(seq_quit==0) { int have_msg = 0; sleep_time = 0; have_msg = w32g_message_get ( &msg ); if ( have_msg ) { switch ( msg.cmd ) { case W32G_SYN_QUIT: seq_quit=~0; w32g_syn_status = quit; sleep_time = 100; break; case W32G_SYN_START: seq_quit=~0; w32g_syn_status = run; sleep_time = 100; break; case W32G_SYN_STOP: seq_quit=~0; w32g_syn_status = stop; sleep_time = 100; break; case W32G_SYN_GM_SYSTEM_RESET: rtsyn_server_reset(); ev.type=ME_RESET; ev.a=GM_SYSTEM_MODE; rtsyn_play_event(&ev); sleep_time = 100; break; case W32G_SYN_GS_SYSTEM_RESET: rtsyn_server_reset(); ev.type=ME_RESET; ev.a=GS_SYSTEM_MODE; rtsyn_play_event(&ev); sleep_time = 100; break; case W32G_SYN_XG_SYSTEM_RESET: rtsyn_server_reset(); ev.type=ME_RESET; ev.a=XG_SYSTEM_MODE; rtsyn_play_event(&ev); sleep_time = 100; break; case W32G_SYN_SYSTEM_RESET: rtsyn_server_reset(); ev.type=ME_RESET; ev.a=rtsyn_system_mode; rtsyn_play_event(&ev); sleep_time = 100; break; case W32G_SYN_CHANGE_GM_SYSTEM: rtsyn_system_mode=GM_SYSTEM_MODE; rtsyn_server_reset(); ev.type=ME_RESET; ev.a=GM_SYSTEM_MODE; rtsyn_play_event(&ev); change_system_mode(rtsyn_system_mode); sleep_time = 100; break; case W32G_SYN_CHANGE_GS_SYSTEM: rtsyn_system_mode=GS_SYSTEM_MODE; rtsyn_server_reset(); ev.type=ME_RESET; ev.a=GS_SYSTEM_MODE; rtsyn_play_event(&ev); change_system_mode(rtsyn_system_mode); sleep_time = 100; break; case W32G_SYN_CHANGE_XG_SYSTEM: rtsyn_system_mode=XG_SYSTEM_MODE; rtsyn_server_reset(); ev.type=ME_RESET; ev.a=XG_SYSTEM_MODE; rtsyn_play_event(&ev); change_system_mode(rtsyn_system_mode); sleep_time = 100; break; case W32G_SYN_CHANGE_DEFAULT_SYSTEM: rtsyn_system_mode=DEFAULT_SYSTEM_MODE; rtsyn_server_reset(); ev.type=ME_RESET; ev.a=GS_SYSTEM_MODE; rtsyn_play_event(&ev); change_system_mode(rtsyn_system_mode); sleep_time = 100; break; default: break; } } winplaymidi();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -