int Process::process_packets(Thread *thread) { int flag; MPI_Status status; MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (flag) { bool net_changed = false; for(;;) { int msg_size; MPI_Get_count(&status, MPI_BYTE, &msg_size); char *buffer = (char*) malloc(msg_size); // FIXME: alloca for small packets MPI_Recv(buffer, msg_size, MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); /* Now we have to be sure that all thread messages are processed and we know about all nets */ thread->process_thread_messages(); net_changed |= process_packet(thread, status.MPI_SOURCE, status.MPI_TAG, buffer); MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status); if (!flag) break; } TraceLog *tracelog = thread->get_tracelog(); if (net_changed && tracelog) { tracelog->event_end(); } return 1; } return 0; }
//================================================================================================ // // LoadFile() // // - Called by Configuration::Load() // /// <summary> /// Attempts to load the specified config-file. Returns true if successful, false if not /// </summary> // bool Configuration::LoadFile(const TCHAR *file, HANDLE *fp, HANDLE *map, const void **view) { TCHAR chBuf[256]; _stprintf_s(chBuf, _countof(chBuf), _T("[Configuration] [LoadFile] loading file:[%s]"), file); g_tlog.LogMessage(chBuf, TRACELOG_LEVEL_INFO); *fp=CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(*fp==INVALID_HANDLE_VALUE) { TRACEERR("[Configuration] [LoadFile]", L"Can't open file", GetLastError()); return false; } // Attempting to access a 0-byte file causes "The volume for a file has been externally // altered so that the opened file is no longer valid." errors, both here and when trying // to save the .conf file later on. DWORD size=0; size=GetFileSize(*fp, NULL); if (size == 0) { TRACEW("[Configuration] [LoadFile] 0 byte conf file"); CloseHandle(*fp); *fp = 0; return false; } else if (size == INVALID_FILE_SIZE) { TRACEERR("[Configuration] [LoadFile]", L"Can't get file size", GetLastError()); CloseHandle(*fp); *fp = 0; return false; } else { tstring strBuf = boost::str(tformat(_T("[Configuration] [LoadFile] about to memory-map file - size: [%1%]")) % size ); TRACEBUFI(strBuf); } *map=CreateFileMapping(*fp, NULL, PAGE_READONLY, 0, 0, NULL); if(*map==NULL) { TRACEERR("[Configuration] [LoadFile]", L"Can't create file map", GetLastError()); return false; } *view=MapViewOfFile(*map, FILE_MAP_READ, 0, 0, 0); if(*view==NULL) { TRACEERR("[Configuration] [LoadFile]", L"Can't map view of file", GetLastError()); return false; } _stprintf_s(chBuf, _countof(chBuf), _T("[Configuration] [LoadFile] Successfully loaded file:[%s]"), file); g_tlog.LogMessage(chBuf, TRACELOG_LEVEL_SUCCESS); return true; }; // End of LoadFile()
void Process::process_service_message(Thread *thread, ServiceMessage *smsg) { switch (smsg->type) { case CA_SM_QUIT: CA_DLOG("SERVICE CA_SM_QUIT on process=%i thread=%i\n", get_process_id(), thread->get_id()); if(net == NULL) { CA_DLOG("Quitting not created net on process=%d\n", get_process_id()); net_is_quit = true; } too_early_message.clear(); quit(); break; case CA_SM_NET_CREATE: { CA_DLOG("SERVICE CA_SM_NET_CREATE on process=%i thread=%i\n", get_process_id(), thread->get_id()); ServiceMessageNetCreate *m = (ServiceMessageNetCreate*) smsg; if(net_is_quit) { CA_DLOG("Stop creating quit net on process=%i thread=%i\n", get_process_id(), thread->get_id()); too_early_message.clear(); net_is_quit = false; break; } spawn_net(m->def_index, false); if(too_early_message.size() > 0) { std::vector<EarlyMessage>::const_iterator i; for (i = too_early_message.begin(); i != too_early_message.end(); i++) { process_packet(thread, i->from_process, CA_TAG_TOKENS, i->data); } if (too_early_message.size() > 0) { TraceLog *tracelog = thread->get_tracelog(); if (tracelog) { tracelog->event_end(); } } too_early_message.clear(); } break; } case CA_SM_WAKE: { CA_DLOG("SERVICE CA_SM_WAKE on process=%i thread=%i\n", get_process_id(), thread->get_id()); start(false); clear(); #ifdef CA_MPI MPI_Barrier(MPI_COMM_WORLD); #endif break; } case CA_SM_EXIT: CA_DLOG("SERVICE CA_SM_EXIT on process=%i thread=%i\n", get_process_id(), thread->get_id()); too_early_message.clear(); free(smsg); exit(0); } }
void pbfilter_base::start_thread() { TRACEV("[pbfilter_base] [start_thread] > Entering routine."); m_runthread = true; m_exitevt = CreateEvent(0, TRUE, FALSE, 0); if(!m_exitevt) throw win32_error("CreateEvent", 0); TRACEI("[pbfilter_base] [start_thread] creating thread_thunk"); m_thread = CreateThread(0, 0, thread_thunk, this, 0, 0); if(!m_thread) { DWORD err = GetLastError(); CloseHandle(m_exitevt); TRACEE("[pbfilter_base] [start_thread] ERROR creating thread_thunk!!"); throw win32_error("CreateThread", err); } TCHAR chBuf[256]; _stprintf_s(chBuf, sizeof(chBuf)/2, _T("[pbfilter_base] [start_thread] thread_thunk created with handle:[%p]"), m_thread); g_tlog.LogMessage(chBuf, TRACELOG_LEVEL_VERBOSE); TRACEV("[pbfilter_base] [start_thread] < Leaving routine."); } // End of start_thread()
Net * Process::spawn_net(int def_index, bool globally) { TraceLog *tracelog = thread->get_tracelog(); if (tracelog) { tracelog->event_net_spawn(defs[def_index]->get_id()); } CA_DLOG("Spawning def_id=%i globally=%i\n", def_index, globally); if (globally) { ServiceMessageNetCreate *m = (ServiceMessageNetCreate *) malloc(sizeof(ServiceMessageNetCreate)); m->type = CA_SM_NET_CREATE; m->def_index = def_index; broadcast_packet(CA_TAG_SERVICE, m, sizeof(ServiceMessageNetCreate), process_id); } net = (Net *) defs[def_index]->spawn(thread); return net; }
bool Process::process_packet(Thread *thread, int from_process, int tag, void *data) { if (tag == CA_TAG_SERVICE) { process_service_message(thread, (ServiceMessage*) data); free(data); return false; } Tokens *tokens = (Tokens*) data; if(net == NULL) { CA_DLOG("Too early message on process=%d", get_process_id()); EarlyMessage msg; msg.from_process = from_process; msg.data = data; too_early_message.push_back(msg); return false; } Unpacker unpacker(tokens + 1); Net *n = net; TraceLog *tracelog = thread->get_tracelog(); if (tracelog) { tracelog->event_receive(from_process); } if (n == NULL) { CA_DLOG("Net not found process=%i thread=%i\n", get_process_id(), thread->get_id()); // Net is already stopped therefore we can throw tokens away return false; } int edge_id = tokens->edge_id; int tokens_count = tokens->tokens_count; CA_DLOG("RECV net=%i index=%i process=%i thread=%i\n", tokens->net_id, edge_id, get_process_id(), thread->get_id()); for (int t = 0; t < tokens_count; t++) { n->receive(thread, from_process, edge_id, unpacker); } CA_DLOG("EOR index=%i process=%i thread=%i\n", edge_id, get_process_id(), thread->get_id()); free(data); return true; }
//================================================================================================ // // CheckOS() // // - Called by _tWinMain at app start // /// <summary> /// Simply gets/logs the OS Version, doesn't actually do anything permanent with it. /// </summary> // static bool CheckOS() { OSVERSIONINFOEX osv = {0}; osv.dwOSVersionInfoSize = sizeof(osv); if(!GetVersionEx((OSVERSIONINFO *)&osv)) return false; SYSTEM_INFO si; GetSystemInfo(&si); //TODO: save version info tstring strOsName; if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 3 && osv.wProductType == VER_NT_WORKSTATION ) strOsName = _T("Windows 8.1"); else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 2 && osv.wProductType == VER_NT_WORKSTATION ) strOsName = _T("Windows 8"); else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 2 && osv.wProductType != VER_NT_WORKSTATION ) strOsName = _T("Windows 8 Server"); else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 1 && osv.wProductType == VER_NT_WORKSTATION ) strOsName = _T("Windows 7"); else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 1 && osv.wProductType != VER_NT_WORKSTATION ) strOsName = _T("Windows Server 2008 R2"); else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0 && osv.wProductType == VER_NT_WORKSTATION ) strOsName = _T("Windows Vista"); else if ( osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0 && osv.wProductType != VER_NT_WORKSTATION ) strOsName = _T("Windows Server 2008"); else if ( osv.dwMajorVersion == 5 && osv.dwMinorVersion == 2 && GetSystemMetrics(SM_SERVERR2) != 0 ) strOsName = _T("Windows Server 2003 R2"); else if ( osv.dwMajorVersion == 5 && osv.dwMinorVersion == 2 && osv.wSuiteMask == VER_SUITE_WH_SERVER ) strOsName = _T("Windows Home Server"); else if ( osv.dwMajorVersion == 5 && osv.dwMinorVersion == 2 && osv.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) strOsName = _T("Windows XP Professional 64-bit Edition"); else if ( osv.dwMajorVersion == 5 && osv.dwMinorVersion == 2 && GetSystemMetrics(SM_SERVERR2) == 0 ) strOsName = _T("Windows Server 2003"); else if ( osv.dwMajorVersion == 5 && osv.dwMinorVersion == 1 ) strOsName = _T("Windows XP"); else strOsName = boost::str(tformat(_T("UNKNOWN OS %1%.%2%")) % osv.dwMajorVersion % osv.dwMinorVersion ); // TODO: Check for Media Center / Starter / Tablet PC (as per OSVERSIONINFOEX docs) tstring strOsBitness; if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) strOsBitness = _T("64-bit"); else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) strOsBitness = _T("32-bit"); else strOsBitness = _T("??-bit"); tstring strOsString = boost::str(tformat(_T("%1% %5% - Build:[%2%], SP:[%3%.%4%]")) % strOsName % osv.dwBuildNumber % osv.wServicePackMajor % osv.wServicePackMinor % strOsBitness.c_str()); TCHAR chBuf[256]; _stprintf_s(chBuf, _countof(chBuf), _T("Running on OS: %s"), strOsString.c_str()); g_tlog.LogMessage(chBuf, TRACELOG_LEVEL_SUCCESS); return true; } // End of CheckOS()
//================================================================================================ // // _tWinMain() // // - Called by Windows when the app is first started // /// <summary> /// Initial starting point of the app. Performs some quick sanity-checking and then starts up /// a different thread (serviced by the Main_DlgProc() routine in mainproc.cpp) to handle all /// the "real" work. /// </summary> // int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow) { hPeerBlockInstance = hInstance; // If PeerBlock is already running, bring it to the forefront and exit this new instance. HANDLE pbmutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_pbmutex_name); if (pbmutex) { UINT msg = RegisterWindowMessage(_T("PeerBlockSetVisible")); if (msg) { SendNotifyMessage(HWND_BROADCAST, msg, 0, TRUE); } CloseHandle(pbmutex); return 0; } else CreateMutex(NULL, FALSE, g_pbmutex_name); path pathLog = path::base_dir()/L"peerblock.log"; // TODO: This should be a config-string! g_tlog.SetLogfile(pathLog.c_str()); TRACEC("PeerBlock Starting"); TCHAR buf[64]; swprintf_s(buf, _countof(buf), L"%S", PB_BLDSTR); TRACEBUFC(buf); g_tlog.ProcessMessages(); TRACES("Flushed tracelog"); if(!CheckOS()) { TRACEE("ERROR: Failed checking for OS rev!"); return -1; } // PeerBlock requires Admin Mode in order to load the pbfilter.sys driver if(!IsUserAnAdmin()) { TRACEE("ERROR: User not running as Admin!"); MessageBox(NULL, IDS_NEEDADMINTEXT, IDS_NEEDADMIN, MB_ICONERROR|MB_OK); return -1; } TRACES("User running as Admin"); // If PeerGuardian2 is already running, warn the user and then exit. HANDLE pgmutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_pgmutex_name); if (pgmutex) { TRACEW("PeerGuardian already running! Warning user and exiting."); MessageBox(NULL, IDS_PGALREADYRUNNINGTEXT, IDS_PGALREADYRUNNING, MB_ICONWARNING|MB_OK); CloseHandle(pgmutex); return 0; } else CreateMutex(NULL, FALSE, g_pgmutex_name); TRACES("Created program mutex"); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); { INITCOMMONCONTROLSEX icx={0}; icx.dwSize=sizeof(icx); icx.dwICC=ICC_DATE_CLASSES|ICC_INTERNET_CLASSES|ICC_LISTVIEW_CLASSES|ICC_PROGRESS_CLASS|ICC_TAB_CLASSES|ICC_UPDOWN_CLASS|ICC_USEREX_CLASSES|ICC_WIN95_CLASSES; InitCommonControlsEx(&icx); } TRACES("Initialized common controls"); RegisterColorPicker(hInstance); TRACES("Registered color picker"); { WSADATA data; WSAStartup(WINSOCK_VERSION, &data); } TRACES("Initialized winsock"); SetUnhandledExceptionFilter( PeerblockExceptionFilter ); BOOL bRet = PreventSetUnhandledExceptionFilter(); if (bRet) { TRACES("Successfully PreventSetUnhandledExceptionFilter()"); } else { TRACEW("Could NOT PreventSetUnhandledExceptionFilter()"); } try { // Spawn a new thread to handle the UI Dialog; this thread becomes the main workhorse of the program TRACEI("Creating main UI window"); HWND hwnd=CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAIN), NULL, Main_DlgProc); TRACES("Created main UI window"); // Save copy of peerblock.conf as "last known good" peerblock.conf.bak g_config.Save(_T("peerblock.conf.bak")); // Set main window caption to version-string from versioninfo.h TCHAR * chBuf; chBuf = (TCHAR *)malloc(256 * sizeof(*chBuf)); swprintf_s(chBuf, 256, L"%S", PB_BLDSTR); SetWindowText(hwnd, chBuf); free(chBuf); TRACES("Starting message-loop"); MSG msg; while(GetMessage(&msg, NULL, 0, 0)>0) { TranslateMessage(&msg); DispatchMessage(&msg); } TRACES("Message loop ended, shutting down PeerBlock"); } catch(exception &ex) { UncaughtExceptionBox(NULL, ex, __FILE__, __LINE__); } catch(...) { UncaughtExceptionBox(NULL, __FILE__, __LINE__); } Shutdown(); TRACES("PeerBlock is now exiting, due to user request. Have a nice day!"); return 0; } // End of _tWinMain()