void GatherInfoThread::doRun() { auto wildc = gcRefPtr<WildcardManager>::create(); wildc->onNeedSpecialEvent += delegate(&onNeedWCEvent); uint32 prog = 0; onProgUpdateEvent(prog); getUserCore()->getItemManager()->retrieveItemInfo(getItemId(), 0, wildc, MCFBranch::BranchFromInt(getMcfBranch()), MCFBuild::BuildFromInt(getMcfBuild())); if (isStopped()) return; auto item = getItemInfo(); if (!item) throw gcException(ERR_INVALIDDATA, "The item handle was null (gather info failed)"); uint32 itemId = item->getId().getItem(); onCompleteEvent(itemId); }
ScriptCoreI* newInstance() { bool loaded = false; m_ScriptLock.lock(); if (m_uiInstanceCount == 0) loaded = loadDll(); else loaded = true; bool didLoad = (loaded && m_pFactory); if (didLoad) m_uiInstanceCount++; m_ScriptLock.unlock(); if (didLoad == false) throw gcException(ERR_LIBRARY_LOADFAILED, "Failed to load script engine"); return (ScriptCoreI*)m_pFactory(SCRIPT_CORE); }
CourgetteI* newInstance() { bool loaded = false; m_ScriptLock.lock(); if (m_uiInstanceCount == 0) loaded = loadDll(); else loaded = true; bool didLoad = (loaded && m_pFactory); if (didLoad) m_uiInstanceCount++; m_ScriptLock.unlock(); if (didLoad == false) throw gcException(ERR_LIBRARY_LOADFAILED, "Failed to load courgette"); return (CourgetteI*)m_pFactory(COURGETTE); }
void MCF::dlFilesFromHttp(const char* url, const char* installDir) { gcTrace("Url: {0}, Dir: {1}", url, installDir); gcAssert(!m_pTHandle); if (m_bStopped) return; if (!url) throw gcException(ERR_BADURL); //save the header first incase we fail saveMCF_Header(); MCFCore::Thread::HGTController *temp = new MCFCore::Thread::HGTController(url, this, installDir); temp->onProgressEvent +=delegate(&onProgressEvent); temp->onErrorEvent += delegate(&onErrorEvent); runThread(temp); saveMCF_Header(); }
gcString WebCoreClass::getCDKey(DesuraId id, MCFBranch branch) { TiXmlDocument doc; PostMap post; post["siteareaid"] = id.getItem(); post["sitearea"] = id.getTypeString(); post["branch"] = (size_t)branch; #ifdef WIN32 post["token"] = UTIL::WIN::getRegValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\MachineGuid", true); #else post["token"] = "todo"; #endif TiXmlNode* root = postToServer(getCDKeyUrl(), "cdkey", post, doc); TiXmlElement* key = root->FirstChildElement("key"); if (!key) throw gcException(ERR_BADXML); return key->GetText(); }
void ItemHandle::doLaunch(Helper::ItemLaunchHelperI* helper) { preLaunchCheck(); bool needElevation = false; size_t x=0; while (g_ElevatedGames[x].isOk()) { if (getItemInfo()->getId() == g_ElevatedGames[x] || getItemInfo()->getParentId() == g_ElevatedGames[x]) { needElevation = true; break; } x++; } UserCore::Item::Misc::ExeInfoI* ei = getItemInfo()->getActiveExe(); gcString args; gcString ea(ei->getExeArgs()); gcString ua(ei->getUserArgs()); if (ea.size() > 0) args += " " + ea; if (ua.size() > 0) args += " " + ua; m_pUserCore->getItemManager()->setRecent(getItemInfo()->getId()); bool res = UTIL::WIN::launchExe(ei->getExe(), args.c_str(), needElevation, m_pUserCore->getMainWindowHandle()); if (!res) throw gcException(ERR_LAUNCH, GetLastError(), gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), GetLastError(), ei->getExe())); }
void MCF::parseXml(char* buff, uint32 buffLen) { if (m_bStopped) return; TiXmlDocument doc; doc.SetCondenseWhiteSpace(false); doc.LoadBuffer(buff, buffLen); TiXmlNode *fNode = doc.FirstChild("files"); if (!fNode) throw gcException(ERR_XML_NOPRIMENODE); TiXmlElement* pChild = fNode->FirstChildElement(); while (pChild) { if (m_bStopped) return; MCFCore::MCFFile* temp = new MCFCore::MCFFile(); try { temp->loadXmlData(pChild); m_pFileList.push_back( temp ); } catch (gcException &) { safe_delete(temp); } pChild = pChild->NextSiblingElement(); } }
void AppUpdateInstall::startService() { gcTrace(""); uint32 res = UTIL::WIN::queryService(SERVICE_NAME); if (res != SERVICE_STATUS_STOPPED) { try { UTIL::WIN::stopService(SERVICE_NAME); gcSleep(500); } catch (gcException &) { } } std::vector<std::string> args; args.push_back("-wdir"); args.push_back(gcString(UTIL::OS::getCurrentDir())); UTIL::WIN::startService(SERVICE_NAME, args); uint32 count = 0; while (UTIL::WIN::queryService(SERVICE_NAME) != SERVICE_STATUS_RUNNING) { //wait 10 seconds if (count > 40) throw gcException(ERR_SERVICE, "Failed to start desura Service (PipeManager)."); gcSleep(250); count++; } }
void CDKeyTask::doTask() { if (!getItemInfo() || !getWebCore()) { CDKeyEventInfo<gcException> cdei; cdei.task = this; cdei.t = gcException(ERR_NULLHANDLE, "Item info or web core are null"); cdei.id = getItemId(); onErrorEvent(cdei); return; } MCFBranch branch = getItemInfo()->getInstalledBranch(); try { gcString key = getWebCore()->getCDKey(getItemId(), branch); CDKeyEventInfo<gcString> cdei; cdei.task = this; cdei.t = key; cdei.id = getItemId(); onCompleteEvent(cdei); } catch (gcException &e) { CDKeyEventInfo<gcException> cdei; cdei.task = this; cdei.t = e; cdei.id = getItemId(); onErrorEvent(cdei); } }
void User::logIn(const char* user, const char* pass) { gcString appDataPath = UTIL::OS::getAppDataPath(); m_pThreadPool->unBlockTasks(); if (!m_pWebCore) throw gcException(ERR_NULLWEBCORE); tinyxml2::XMLDocument doc; m_pWebCore->logIn(user, pass, doc); tinyxml2::XMLElement *uNode = doc.FirstChildElement("memberlogin"); uint32 version = 0; XML::GetAtt("version", version, uNode); if (version == 0) version = 1; m_bDelayLoading = (version >= 3); if (!uNode) { logOut(); throw gcException(ERR_BADXML); } tinyxml2::XMLElement *memNode = uNode->FirstChildElement("member"); if (memNode) { const char* idStr = memNode->Attribute("siteareaid"); if (idStr) { m_iUserId = atoi(idStr); if ((int)m_iUserId <= 0) { logOut(); throw gcException(ERR_BAD_PORU); } } else { logOut(); throw gcException(ERR_BAD_PORU); } } XML::GetChild("admin", m_bAdmin, memNode); XML::GetChild("name", m_szUserName, memNode); XML::GetChild("nameid", m_szUserNameId, memNode); XML::GetChild("url", m_szProfileUrl, memNode); XML::GetChild("urledit", m_szProfileEditUrl, memNode); initPipe(); #ifdef WIN32 if (getServiceMain()) getServiceMain()->fixFolderPermissions(appDataPath.c_str()); try { testMcfCache(); } catch (...) { if (getServiceMain()) getServiceMain()->fixFolderPermissions(m_szMcfCachePath.c_str()); try { testMcfCache(); } catch (gcException &e) { Warning(gcString("Failed to set mcf cache path to be writeable: {0}", e)); } } #endif gcString szAvatar; XML::GetChild("avatar", szAvatar, memNode); m_pThreadPool->queueTask(new UserCore::Task::DownloadAvatarTask(this, szAvatar.c_str(), m_iUserId) ); tinyxml2::XMLElement *msgNode = memNode->FirstChildElement("messages"); if (msgNode) { XML::GetChild("updates", m_iUpdates, msgNode); XML::GetChild("privatemessages", m_iPms, msgNode); XML::GetChild("cart", m_iCartItems, msgNode); XML::GetChild("threadwatch", m_iThreads, msgNode); } m_pToolManager->loadItems(); m_pItemManager->loadItems(); try { if (m_bDelayLoading) { //do nothing as the update thread will grab it } else if (version == 2) { m_pItemManager->parseLoginXml2(memNode->FirstChildElement("games"), memNode->FirstChildElement("platforms")); } else { m_pItemManager->parseLoginXml(memNode->FirstChildElement("games"), memNode->FirstChildElement("developer")); } } catch (gcException &) { logOut(); throw; } tinyxml2::XMLElement *newsNode = memNode->FirstChildElement("news"); if (newsNode) parseNews(newsNode); tinyxml2::XMLElement *giftsNode = memNode->FirstChildElement("gifts"); if (giftsNode) parseGifts(giftsNode); m_pUThread = m_pThreadManager->newUpdateThread(&onForcePollEvent, m_bDelayLoading); m_pUThread->start(); #ifdef WIN32 m_pGameExplorerManager->loadItems(); #endif if (getServiceMain()) getServiceMain()->updateShortCuts(); if (!m_bDelayLoading) m_pItemManager->enableSave(); #ifdef WIN32 #ifdef DEBUG gcString val("\"{0}\"", UTIL::OS::getCurrentDir(L"desura-d.exe")); #else gcString val("\"{0}\"", UTIL::OS::getCurrentDir(L"desura.exe")); #endif val += " \"%1\" -urllink"; updateRegKey("HKEY_CLASSES_ROOT\\Desura\\shell\\open\\command\\", val.c_str()); #endif }
void MCF::dlHeaderFromHttp(const char* url) { if (m_bStopped) return; if (!url) throw gcException(ERR_BADURL); //FIXME: Needs error checking on getweb HttpHandle wc(url); wc->setDownloadRange(0, MCFCore::MCFHeader::getSizeS()); wc->getWeb(); if (wc->getDataSize() != MCFCore::MCFHeader::getSizeS()) throw gcException(ERR_BADHEADER); MCFCore::MCFHeader webHeader((uint8*)wc->getData()); setHeader(&webHeader); if (!webHeader.isValid()) throw gcException(ERR_BADHEADER); wc->cleanUp(); wc->setDownloadRange(webHeader.getXmlStart(), webHeader.getXmlSize()); wc->getWeb(); if (wc->getDataSize() == 0 || wc->getDataSize() != webHeader.getXmlSize()) throw gcException(ERR_WEBDL_FAILED, "Failed to download MCF xml from web (size is ether zero or didnt match header size)"); uint32 bz2BuffLen = webHeader.getXmlSize()*25; char* bz2Buff = NULL; if ( isCompressed() ) { bz2Buff = new char[bz2BuffLen]; UTIL::STRING::zeroBuffer(bz2Buff, bz2BuffLen); try { UTIL::BZIP::BZ2DBuff((char*)bz2Buff, &bz2BuffLen, const_cast<char*>(wc->getData()), wc->getDataSize()); parseXml(bz2Buff, bz2BuffLen); safe_delete(bz2Buff); } catch (gcException &) { safe_delete(bz2Buff); throw; } } else { parseXml(const_cast<char*>(wc->getData()), wc->getDataSize()); } //we remove the complete flag due to the files not existing in the MCF for (size_t x=0; x< m_pFileList.size(); x++) { m_pFileList[x]->delFlag(MCFCore::MCFFileI::FLAG_COMPLETE); } }
void MCF::getDownloadProviders(const char* url, MCFCore::Misc::UserCookies *pCookies, bool *unauthed, bool local) { if (!pCookies) throw gcException(ERR_INVALID, "Cookies are null (getDownloadProviders)"); HttpHandle wc(url); pCookies->set(wc); DesuraId id = m_sHeader->getDesuraId(); gcString type = id.getTypeString(); wc->addPostText("siteareaid", id.getItem()); wc->addPostText("sitearea", type.c_str()); wc->addPostText("branch", m_sHeader->getBranch()); MCFBuild build = m_sHeader->getBuild(); if (build != 0) wc->addPostText("build", build); if (local) wc->addPostText("local", "yes"); wc->postWeb(); if (wc->getDataSize() == 0) throw gcException(ERR_BADRESPONSE); TiXmlDocument doc; doc.SetCondenseWhiteSpace(false); XML::loadBuffer(doc, const_cast<char*>(wc->getData()), wc->getDataSize()); TiXmlNode *uNode = doc.FirstChild("itemdownloadurl"); if (!uNode) throw gcException(ERR_BADXML); TiXmlNode* sNode = uNode->FirstChild("status"); if (!sNode) throw gcException(ERR_BADXML); uint32 status = 0; TiXmlElement* sEl = sNode->ToElement(); if (sEl) { const char* statStr = sEl->Attribute("code"); if (statStr) status = atoi(statStr); else throw gcException(ERR_BADXML); } else { throw gcException(ERR_BADXML); } if (status != 0) throw gcException(ERR_BADSTATUS, status, gcString("Status: {0}", sEl->GetText())); TiXmlNode* iNode = uNode->FirstChild("item"); if (!iNode) { throw gcException(ERR_BADXML); } TiXmlNode* mNode = iNode->FirstChild("mcf"); if (!mNode) { throw gcException(ERR_BADXML); } TiXmlElement *melNode = mNode->ToElement(); if (melNode) { const char* build = melNode->Attribute("build"); const char* branch = melNode->Attribute("branch"); //Debug(gcString("MCF: R: {0}.{1} G: {2}.{3}\n", m_sHeader->getBranch(), m_sHeader->getBuild(), build, branch)); if (build) m_sHeader->setBuild(MCFBuild::BuildFromInt(atoi(build))); if (branch) m_sHeader->setBranch(MCFBranch::BranchFromInt(atoi(branch))); } safe_delete(m_pFileAuth); char *szAuthCode = NULL; XML::GetChild("authhash", szAuthCode, mNode); if (!szAuthCode) throw gcException(ERR_BADXML); m_pFileAuth = new Misc::GetFile_s; memset(m_pFileAuth, 0, sizeof(Misc::GetFile_s)); Safe::strncpy(m_pFileAuth->authhash, 33, szAuthCode, 33); char buff[10]; Safe::snprintf(buff, 10, "%d", pCookies->getUserId()); size_t size = Safe::strlen(buff, 10); memcpy(m_pFileAuth->authkey, buff, size); safe_delete(szAuthCode); TiXmlNode* urlNode = mNode->FirstChild("urls"); if (!urlNode) throw gcException(ERR_BADXML); char * szAuthed = NULL; XML::GetChild("authed", szAuthed, mNode); if (unauthed && szAuthed) { *unauthed = (atoi(szAuthed) == 0); } safe_delete(szAuthed); #ifdef DEBUG #if 0 m_vProviderList.clear(); m_vProviderList.push_back(new MCFCore::Misc::DownloadProvider("localhost", "mcf://10.0.0.121:62001", "", "")); return; #endif #endif TiXmlElement* pChild = urlNode->FirstChildElement("url"); while (pChild) { MCFCore::Misc::DownloadProvider* temp = new MCFCore::Misc::DownloadProvider(pChild); m_vProviderList.push_back(temp); pChild = pChild->NextSiblingElement(); } if (m_vProviderList.size() == 0) throw gcException(ERR_ZEROSIZE); }
void WGTWorker::doDownload() { assert(m_pMcfCon); if (!m_pCurBlock) { uint32 status; m_pCurBlock = m_pCT->newTask(m_uiId, status); if (!m_pCurBlock) { if (status != MCFCore::Thread::BaseMCFThread::SF_STATUS_STOP) Warning(gcString("The block was NULL for Mcf Download thread {0}\n", m_uiId)); return; } } try { if (m_szUrl.size() == 0 || m_szUrl == "NULL") throw gcException(ERR_MCFSERVER, "No more download servers to use."); if (!m_pMcfCon->isConnected()) m_pMcfCon->connect(m_szUrl.c_str(), m_pFileAuth); m_pMcfCon->downloadRange(m_pCurBlock->offset, m_pCurBlock->size, this); } catch (gcException &excep) { if (excep.getErrId() == ERR_MCFSERVER && excep.getSecErrId() == ERR_USERCANCELED) { //do nothing. Block errored out before or client paused. } else if (!isStopped()) { Warning(gcString("Mcf Server error: {0} [{1}]\n", excep, m_szUrl)); if (excep.getErrId() == ERR_LIBCURL) { //dont do any thing, just retry unless this is our third time if (isGoodSocketError(excep.getSecErrId()) && m_iAttempt < 3) m_iAttempt++; else requestNewUrl(excep); } else if (excep.getErrId() == ERR_MCFSERVER) { requestNewUrl(excep); } else { m_pCT->reportError(m_uiId, excep); } } takeProgressOff(); return; } m_pCT->workerFinishedSuperBlock(m_uiId); m_pCurBlock = NULL; }
void WildcardManager::constructPath(const char* path, char **res, uint8 *depth) { if (!path) throw gcException(ERR_BADPATH); (*depth)++; if (*depth > 25) throw gcException(ERR_WILDCARD, "Hit max recursion while constructing path (posible loop)."); size_t len = strlen(path); int32 start = -1; int32 stop = 0; std::vector<char*> list; AutoDeleteV<std::vector<char*>> lad(list); //split the string up into section based on %% and then add to vector for (size_t x=0; x<len; x++) { if (path[x] == '%') { if (x==0) { start = 0; } else if (start == -1) { start = (int32)x; char* temp = new char[start-stop+1]; for (int32 y=stop; y<=start; y++) temp[y-stop] = path[y]; temp[start-stop] = '\0'; list.push_back(temp); } else { stop = (int32)x; char *temp = new char[stop-start+1]; for (int32 y = start; y<=stop; y++) temp[y-start] = path[y]; temp[stop-start] = '\0'; list.push_back(temp); start = -1; stop++; } } else if (x>=len-1) { char* temp = new char[len-stop+1]; for (int32 y=stop; y<(int32)len; y++) temp[y-stop] = path[y]; temp[len-stop] = '\0'; list.push_back(temp); } } //all those starting with % are wildcards so resolve them for (size_t x=0; x<list.size(); x++) { if (list[x][0] == '%') { size_t len = strlen(list[x]); char *temp = new char[len]; for (size_t y=1; y<len; y++) temp[y-1] = list[x][y]; temp[len-1]='\0'; if (strlen(temp)==0) { delete [] temp; throw gcException(ERR_WILDCARD, gcString("Failed to find wildcard [{0}] Current node is null", path)); } AutoDelete<char> tad(temp); AutoDelete<WildcardInfo> wad; WildcardInfo* wcInfo = nullptr; if (Safe::stricmp(temp, "TEMP") == 0) { WCSpecialInfo info; info.name = "temp"; onNeedInstallSpecialEvent(info); if (info.handled) { wcInfo = new WildcardInfo("temp", info.result.c_str(), "temp", true); AutoDelete<WildcardInfo> ad(wcInfo); wad = ad; } } else { wcInfo = findItem(temp); } if (!wcInfo) throw gcException(ERR_WILDCARD, gcString("Failed to find wildcard [{0}]", temp)); resolveWildCard(wcInfo); if (!wcInfo->m_bResolved) throw gcException(ERR_WILDCARD, gcString("Failed to resolve wildcard [{0}]", temp)); if (wcInfo->m_szPath == temp) { //dont do any thing, dont have enough info yet. size_t len = strlen(temp)+3; char* newPath = new char[len]; Safe::snprintf(newPath, len, "%%%s%%", temp); safe_delete(list[x]); list[x] = newPath; } else if (wcInfo->m_szPath != "") { char* newPath = nullptr; constructPath(wcInfo->m_szPath.c_str(), &newPath, depth); safe_delete(list[x]); list[x] = newPath; if (Safe::stricmp(temp, "TEMP") != 0) { //this means we dont have to resolve this path next time wcInfo->m_szPath = newPath; } } else { throw gcException(ERR_WILDCARD, gcString("Failed to find wildcard [{0}]", temp)); } } } size_t totalLen = 0; size_t listSize = list.size(); for (size_t x=0; x<listSize; x++) totalLen += strlen(list[x]); safe_delete(*res); *res = new char[totalLen+1]; char* cur = *res; //put list back into one stting; for (size_t x=0; x<listSize; x++) { size_t itemLen = strlen(list[x]); strncpy(cur, list[x], itemLen); cur += itemLen; } (*res)[totalLen] = '\0'; (*depth)--; }
void ItemHandle::doLaunch(bool useXdgOpen, const char* globalExe, const char* globalArgs) { preLaunchCheck(); UserCore::Item::Misc::ExeInfoI* ei = getItemInfo()->getActiveExe(); gcString e(globalExe); gcString args; gcString ea(ei->getExeArgs()); gcString ua(ei->getUserArgs()); gcString ga(globalArgs); gcString wdp(ei->getExe()); if (!useXdgOpen) { //if we have a valid global exe need to append the local exe as the first arg if (e.size() > 0) args += gcString(ei->getExe()); else globalExe = ei->getExe(); } auto AppendArgs = [&args](const std::string& a) { if (a.size() == 0) return; if (args.size() > 0) args += " "; args += a; }; AppendArgs(ea); AppendArgs(ua); if (!useXdgOpen) AppendArgs(ga); bool res = false; if (useXdgOpen && args.size() != 0) Warning(gcString("Arguments '{1}' are not being passed to non-executable file '{0}'.", ei->getExe(), args)); UserCore::Item::BranchInfoI* branch = getItemInfo()->getCurrentBranch(); #ifdef NIX64 if (!useXdgOpen && branch && branch->is32Bit()) { #ifdef USE_BITTEST int testRet = system("desura_bittest"); if (testRet != 0) throw gcException(ERR_NO32LIBS); #else throw gcException(ERR_NOBITTEST); #endif } #endif gcString libPathA; gcString libPathB; gcString libPath; if (branch) { libPathA = gcString("{0}/{1}/{2}/lib", UTIL::OS::getAppDataPath(), branch->getItemId().getFolderPathExtension(), (uint32)branch->getBranchId()); libPathB = gcString("{0}/lib{1}", getItemInfo()->getPath(), branch->is32Bit()?"32":"64"); libPath = libPathA; if (UTIL::FS::isValidFolder(libPathB.c_str())) { libPath += ":"; libPath += libPathB; } } if (useXdgOpen) { res = UTIL::LIN::launchProcessXDG(ei->getExe(), libPath.c_str()); } else { if (libPathA.size() > 0) { std::vector<DesuraId> toolList; branch->getToolList(toolList); getUserCore()->getToolManager()->symLinkTools(toolList, libPathA.c_str()); } std::map<std::string, std::string> info; info["cla"] = args; info["lp"] = libPath; info["wd"] = UTIL::FS::PathWithFile(wdp.c_str()).getFolderPath(); res = UTIL::LIN::launchProcess(globalExe, info); } if (!res) { ERROR_OUTPUT(gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), errno, ei->getExe()).c_str()); throw gcException(ERR_LAUNCH, errno, gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), errno, ei->getExe())); } }
void CreateMCFThread::doRun() { UserCore::Item::ItemInfo *item = getItemInfo(); if (!item && !getUserCore()->isAdmin()) throw gcException(ERR_BADITEM); if (!item) { waitForItemInfo(); item = getItemInfo(); } if (isStopped()) return; if (!item) throw gcException(ERR_BADITEM); const char* val = getUserCore()->getCVarValue("gc_corecount"); if (val && atoi(val) != 0) m_hMCFile->setWorkerCount(atoi(val)); m_hMCFile->parseFolder(m_szPath.c_str(), true); if (m_hMCFile->getFileCount() == 0) throw gcException(ERR_ZEROFILECOUNT, gcString("There are no files in the folder {0}. \nPlease check to see if you have the correct folder and try again.", m_szPath)); if (item->getBranchCount() == 0) { m_hMCFile->setHeader(getItemId(), MCFBranch(), MCFBuild()); m_hMCFile->getHeader()->setParent(0); } else { std::vector<UserCore::Item::BranchInfo*> vBranchList; try { retrieveBranchList(vBranchList); if (vBranchList.size() != 0) compareBranches(vBranchList); } catch (...) { } safe_delete(vBranchList); } if (isStopped()) return; createMcf(); if (isStopped()) return; m_bComplete = true; onCompleteStrEvent(m_szFilePath); }
DesuraId WebCoreClass::nameToId(const char* name, const char* type) { if (!name) throw gcException(ERR_BADITEM, "The name is NULL"); gcString key("{0}-{1}", name, type); uint32 hash = UTIL::MISC::RSHash_CSTR(key.c_str()); try { sqlite3x::sqlite3_connection db(getWebCoreDb(m_szAppDataPath.c_str()).c_str()); gcString q("select internalid from namecache where nameid='{0}' and ttl > DATETIME('NOW');", hash); DesuraId id(db.executeint64(q.c_str())); if (id.isOk()) return id; } catch(std::exception &) { } TiXmlDocument doc; PostMap post; post["nameid"] = name; post["sitearea"] = type; TiXmlNode *uNode = postToServer(getNameLookUpUrl(), "iteminfo", post, doc); TiXmlNode* cNode = uNode->FirstChild("item"); if (cNode) { TiXmlElement* cEl = cNode->ToElement(); if (cEl) { const char* idStr = cEl->Attribute("siteareaid"); const char* typeS = cEl->Attribute("sitearea"); DesuraId id(idStr, typeS); if (!id.isOk() || DesuraId::getTypeString(id.getType()) != type) { throw gcException(ERR_BADXML); } else { try { sqlite3x::sqlite3_connection db(getWebCoreDb(m_szAppDataPath.c_str()).c_str()); gcString q("replace into namecache (internalid, nameid, ttl) values ('{0}','{1}', DATETIME('NOW', '+5 day'));", id.toInt64(), hash); db.executenonquery(q.c_str()); } catch(std::exception &ex) { Warning(gcString("Failed to update namecache in webcore: {0}\n", ex.what())); } return id; } } } throw gcException(ERR_BADXML); }
gcException IPCToolMain::installTool(gcRefPtr<UserCore::ToolInfo> info) { gcString exe(info->getExe()); gcString args(info->getArgs()); if (!UTIL::FS::isValidFile(exe.c_str())) return gcException(ERR_INVALIDFILE); if (exe.size() > 0 && args == "GAME_LIBRARY") { size_t pos = exe.find_last_of(".bz2"); if (pos == (exe.size()-1)) { UTIL::FS::Path pd(exe.c_str(), "", true); pd += UTIL::FS::File(info->getName()); gcString dest = pd.getFullPath(); uint64 size = UTIL::FS::getFileSize(exe.c_str()); try { UTIL::FS::FileHandle srcFh(exe.c_str(), UTIL::FS::FILE_READ); UTIL::FS::FileHandle destFh(dest.c_str(), UTIL::FS::FILE_WRITE); UTIL::MISC::BZ2Worker bz2(UTIL::MISC::BZ2_DECOMPRESS); srcFh.read(size, [&bz2, &destFh](const unsigned char* buff, uint32 size) -> bool { UTIL::FS::FileHandle *pDest = &destFh; bz2.write((const char*)buff, size, [&pDest](const unsigned char* buff, uint32 size) -> bool { pDest->write((const char*)buff, size); return false; }); return false; }); } catch (gcException &e) { return e; } info->overridePath(dest.c_str()); UTIL::FS::delFile(exe.c_str()); } else { info->overridePath(exe.c_str()); } } else if (args.find("PRECHECK_") == 0) { info->setInstalled(); } else { return gcException(ERR_TOOLINSTALL, gcString("Un-supported tool install [{0}]", info->getName())); } return gcException(ERR_COMPLETED); }
void UMcf::install(const wchar_t* path) { m_bCanceled = false; FileHandle fh(m_szFile.c_str(), m_uiOffset); if (!fh.isValid()) throw gcException(ERR_INVALIDFILE, GetLastError(), gcString("Failed to open update file {0}.", m_szFile)); #ifdef WIN32 if (m_bShouldMoveOldFiles) removeOldFiles(path); #endif //sort by offset so we are not seeking all over the place std::sort(m_pFileList.begin(), m_pFileList.end(), &SortMcfFiles); m_uiTotProgress = 0; m_uiCurProgress = 0; for (size_t x=0; x<m_pFileList.size(); x++) { if (m_pFileList[x]->isCompressed()) m_uiTotProgress += m_pFileList[x]->getCSize(); else m_uiTotProgress += m_pFileList[x]->getSize(); } for(size_t x=0; x<m_pFileList.size(); x++) { if (m_bCanceled) throw gcException(ERR_USERCANCELED); if (!m_pFileList[x] || !m_pFileList[x]->isSaved()) continue; #ifdef WIN32 if (m_bShouldMoveOldFiles) moveOldFiles(path, m_pFileList[x]->getName()); #else m_pFileList[x]->remove(path); #endif uint8 res = m_pFileList[x]->readMCFAndSave(fh.hFileSrc, path?path:L".\\", m_uiOffset, delegate(this, &UMcf::onFileProgress)); if (m_bCanceled) throw gcException(ERR_USERCANCELED); if (res == MCFF_ERR_BADHASH) throw gcException(ERR_CSUM_FAILED, gcString("Check sum failed on file {0}\\{1}", m_pFileList[x]->getPath(), m_pFileList[x]->getName())); if (res == MCFF_ERR_INVALIDHANDLE) throw gcException(ERR_INVALID, gcString("Could not open file {0}\\{1} for updating. Sys Code: {2}", m_pFileList[x]->getPath(), m_pFileList[x]->getName(), GetLastError())); if ( res != 0 && res != MCF_NOTCOMPRESSED && res != MCFF_ERR_PARTREAD ) throw gcException(ERR_INVALID, gcString("Failed to update file {0}\\{1}: {2}.", m_pFileList[x]->getPath(), m_pFileList[x]->getName(), (uint32)res)); if (m_pFileList[x]->isCompressed()) m_uiCurProgress += m_pFileList[x]->getCSize(); else m_uiCurProgress += m_pFileList[x]->getSize(); } }
void bz2CompressFile(const char* src, const char* dest) { if (!g_hBZ2 && !initFactory()) return; UTIL::FS::FileHandle srcFH(src, UTIL::FS::FILE_READ); UTIL::FS::FileHandle destFH(dest, UTIL::FS::FILE_WRITE); uint64 tot = 0; uint64 fileSize = UTIL::FS::getFileSize(UTIL::FS::PathWithFile(src)); bz_stream* bzs = new bz_stream; bzs->bzalloc = NULL; bzs->bzfree = NULL; bzs->opaque = NULL; int32 res = pBZ2_bzCompressInit(bzs, 9, 0, 0); if (res != BZ_OK) throw gcException(ERR_BZ2DFAIL); size_t buffSize = 512*1024; char *inBuff = new char[buffSize]; char *outBuff = new char[buffSize]; bool endFile = false; do { uint32 readSize = buffSize; if (fileSize - tot < buffSize) { readSize = fileSize - tot; endFile = true; } if (readSize == 0) break; bzs->next_in = inBuff; bzs->avail_in = readSize; srcFH.read(inBuff, readSize); tot += readSize; int32 res = BZ_OK; do { bzs->next_out = outBuff; bzs->avail_out = buffSize; if (endFile) res = pBZ2_bzCompress(bzs, BZ_FINISH); else res = pBZ2_bzCompress(bzs, BZ_RUN); uint32 done = buffSize - bzs->avail_out; if (done > 0) destFH.write(outBuff, done); } while (endFile && res != BZ_STREAM_END || bzs->avail_in > 0); } while (res != BZ_STREAM_END); pBZ2_bzCompressEnd(bzs); safe_delete(bzs); }
void MCF::dlHeaderFromWeb() { if (m_bStopped) return; if (m_vProviderList.size() == 0) throw gcException(ERR_ZEROFILE); gcException lastE; bool successful = false; OutBuffer out(MCF_HEADERSIZE_V2); MCFCore::Misc::MCFServerCon msc; for (size_t x=0; x<m_vProviderList.size(); x++) { try { msc.disconnect(); msc.connect(m_vProviderList[x]->getUrl(), m_pFileAuth); msc.downloadRange(0, 5, &out); //4 id bytes and 1 version byte if (out.m_uiTotalSize != 5) throw gcException(ERR_BADHEADER, "Did not get any data from mcf server."); const char* data = out.m_szBuffer; if ( !(data[0] == 'L' && data[1] == 'M' && data[2] == 'C' && data[3] == 'F') ) throw gcException(ERR_BADHEADER, "Failed magic check."); size_t headerSize = MCF_HEADERSIZE_V1; if (data[4] == 0x01) headerSize = MCF_HEADERSIZE_V1; else if (data[4] == 0x02) headerSize = MCF_HEADERSIZE_V2; else throw gcException(ERR_BADHEADER, "Bad version number"); out.reset(); msc.downloadRange(0, headerSize, &out); if (out.m_uiTotalSize != headerSize) throw gcException(ERR_BADHEADER, "Did not get correct ammount of data from server."); MCFCore::MCFHeader webHeader((uint8*)out.m_szBuffer); if (!webHeader.isValid()) throw gcException(ERR_BADHEADER, "Mcf header was not valid."); uint32 ths = webHeader.getXmlSize(); out = ths; msc.downloadRange(webHeader.getXmlStart(), webHeader.getXmlSize(), &out); if (out.m_uiTotalSize == 0 || out.m_uiTotalSize != webHeader.getXmlSize()) throw gcException(ERR_WEBDL_FAILED, "Failed to download MCF xml from web (size is ether zero or didnt match header size)"); data = out.m_szBuffer; if (data[0] == 'L' && data[1] == 'M' && data[2] == 'C' && data[3] == 'F') throw gcException(ERR_WEBDL_FAILED, "Server failed 4gb seek."); setHeader(&webHeader); successful = true; break; } catch (gcException &e) { lastE = e; Warning(gcString("Failed to download MCF Header from {1}: {0}\n", e, m_vProviderList[x]->getUrl())); } } if (!successful) throw lastE; uint32 bz2BuffLen = getHeader()->getXmlSize()*25; char* bz2Buff = NULL; if ( isCompressed() ) { bz2Buff = new char[bz2BuffLen]; UTIL::STRING::zeroBuffer(bz2Buff, bz2BuffLen); try { UTIL::BZIP::BZ2DBuff((char*)bz2Buff, &bz2BuffLen, out.m_szBuffer, out.m_uiTotalSize); parseXml(bz2Buff, bz2BuffLen); safe_delete(bz2Buff); } catch (gcException &) { safe_delete(bz2Buff); throw; } } else { parseXml(out.m_szBuffer, out.m_uiTotalSize); } //we remove the complete flag due to the files not existing in the MCF for (size_t x=0; x< m_pFileList.size(); x++) { m_pFileList[x]->delFlag(MCFCore::MCFFileI::FLAG_COMPLETE); } if (m_szFile != "") saveMCF_Header(); }
void startService(const char* szName, std::vector<std::string> &args) { gcAssert(szName); gcWString wName(szName); SC_HANDLE scm, Service; SERVICE_STATUS ssStatus; DWORD dwWaitTime; //open connection to SCM scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); if (!scm) throw gcException(ERR_NULLSCMANAGER, GetLastError(), "Failed to open the Service Control Manager"); //open service Service = OpenService(scm, wName.c_str(), SERVICE_START|SERVICE_QUERY_STATUS); if (!Service) { CloseServiceHandle(scm); throw gcException(ERR_NULLSERVICE, GetLastError(), gcString("Failed to open service: {0}", szName)); } // Check the status until the service is no longer start pending. if (!QueryServiceStatus( Service, &ssStatus) ) { CloseServiceHandle(Service); CloseServiceHandle(scm); throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to Query service: {0}", szName)); } while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) { gcSleep(1000); } if (ssStatus.dwCurrentState != SERVICE_STOPPED) { CloseServiceHandle(Service); CloseServiceHandle(scm); throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to start service: Service {0} is not stopped [{1}]", szName, ssStatus.dwCurrentState)); } BOOL res = doStartService(Service, szName, args); if (res == 0) { if (GetLastError() == 1058) throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to start service {0} as the service is disabled. Please use msconfig and renable service.", szName)); throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to start service: {0}", szName)); } // Check the status until the service is no longer start pending. if (!QueryServiceStatus( Service, &ssStatus) ) { CloseServiceHandle(Service); CloseServiceHandle(scm); throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to Query service: {0}", szName)); } DWORD totalTime = 0; while (ssStatus.dwCurrentState != SERVICE_RUNNING) { if (ssStatus.dwCurrentState == SERVICE_STOPPED) { //start service BOOL res = doStartService(Service, szName, args); if (res == 0) throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to start service: {0}", szName)); } dwWaitTime = 1000; totalTime += dwWaitTime; gcSleep( dwWaitTime ); // Check the status again. if (!QueryServiceStatus( Service, &ssStatus) ) { CloseServiceHandle(Service); CloseServiceHandle(scm); throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to Query service: {0}", szName)); } if (totalTime > 30000) { CloseServiceHandle(Service); CloseServiceHandle(scm); throw gcException(ERR_SERVICE, gcString("Service {0} Startup timed out after 30 seconds.", szName)); } } // Check the status again. if (!QueryServiceStatus( Service, &ssStatus) ) { CloseServiceHandle(Service); CloseServiceHandle(scm); throw gcException(ERR_SERVICE, GetLastError(), gcString("Failed to Query service: {0}", szName)); } CloseServiceHandle(scm); CloseServiceHandle(Service); if (ssStatus.dwCurrentState != SERVICE_RUNNING) throw gcException(ERR_SERVICE, gcString("Failed to start service: {0} [{1}]", szName, ssStatus.dwCurrentState)); }
//this is a feature of webcore but we need it here in case we need to shutdown during a download void DownloadUpdateTask::downloadUpdate() { #ifdef DEBUG return; #endif uint32 appver = m_uiAppVer; uint32 appbuild = m_uiAppBuild; HttpHandle wc(PRIMUPDATE); getWebCore()->setWCCookies(wc); wc->addPostText("appid", appver); wc->postWeb(); if (wc->getDataSize() == 0) throw gcException(ERR_INVALIDDATA); XML::gcXMLDocument doc(const_cast<char*>(wc->getData()), wc->getDataSize()); doc.ProcessStatus("appupdate"); auto mNode = doc.GetRoot("appupdate").FirstChildElement("mcf"); if (!mNode.IsValid()) throw gcException(ERR_BADXML); uint32 version = 0; uint32 build = 0; mNode.GetAtt("appid", version); mNode.GetAtt("build", build); if (version == 0 || build == 0) throw gcException(ERR_BADXML); //check to see if its newer than last if (appbuild != 0 && build <= appbuild && appver == version) return; gcString url = mNode.GetChild("url"); if (url.size() == 0) throw gcException(ERR_BADXML); #ifdef WIN32 const char *comAppPath = getUserCore()->getAppDataPath(); m_szPath = gcString("{0}{1}{2}", comAppPath, DIRS_STR, UPDATEFILE); #else m_szPath = gcString("{0}", UPDATEFILE); #endif m_hMcfHandle->setFile(m_szPath.c_str()); m_hMcfHandle->setWorkerCount(1); try { m_hMcfHandle->dlHeaderFromHttp(url.c_str()); #ifdef WIN32 const char* dir = ".\\"; #else const char* dir = "./"; #endif //Dont use courgette for non admins for now bool useCourgette = false; #ifdef WIN32 if (getUserCore()->isAdmin()) useCourgette = true; #endif bool res = m_hMcfHandle->verifyInstall(dir, true, useCourgette); m_hMcfHandle->getProgEvent() += delegate(this, &DownloadUpdateTask::onDownloadProgress); UserCore::Misc::update_s info; info.build = build; if (!res) { Msg(gcString("Downloading " PRODUCT_NAME " update: Ver {0} build {1}\n", appver, build)); info.alert = true; onDownloadStartEvent(info); if (useCourgette) m_hMcfHandle->dlFilesFromHttp(url.c_str(), dir); else m_hMcfHandle->dlFilesFromHttp(url.c_str()); if (!isStopped()) onDownloadCompleteEvent(info); } else { //sometimes this gets called after shutdown and causes major problems if (!getUserCore() || !getUserCore()->getServiceMain()) return; gcString av("{0}", appver); gcString ab("{0}", build); info.alert = false; try { getUserCore()->getServiceMain()->updateRegKey(APPID, av.c_str()); getUserCore()->getServiceMain()->updateRegKey(APPBUILD, ab.c_str()); } catch (gcException &e) { Warning(gcString("Failed to update reg key: {0}\n", e)); } onDownloadCompleteEvent(info); } } catch (gcException &e) { Warning(gcString("Download update failed: {0}\n", e)); } }
void MCF::parseFolder(const char *filePath, const char *oPath) { if (m_bStopped) return; if (!oPath) throw gcException(ERR_BADPATH); UTIL::FS::Path path(oPath, "", false); if (filePath) path += filePath; std::vector<UTIL::FS::Path> fileList; std::vector<UTIL::FS::Path> dirList; if (!UTIL::FS::isValidFolder(path)) throw gcException(ERR_BADPATH, gcString("The file path was invalid [{0}]", path.getFullPath())); UTIL::FS::getAllFiles(path, fileList, NULL); UTIL::FS::getAllFolders(path, dirList); if (fileList.size() == 0 && dirList.size() == 0) { MCFCore::MCFFile *temp = new MCFCore::MCFFile(); if (filePath) temp->setPath(filePath); temp->setName("%%EMPTYFOLDER%%"); temp->setDir(oPath); temp->setSize(0); m_pFileList.push_back(temp); return; } for (size_t x=0; x<fileList.size(); x++) { std::string file = fileList[x].getFile().getFile(); if (UTIL::MISC::matchList(file.c_str(), MCFCore::g_vExcludeFileList)) continue; if (file.size() > 0 && file[file.size()-1] == ' ') throw gcException(ERR_BADPATH, gcString("File [{0}] has a space at the end of its name. This is not valid for MCF archives.", fileList[x].getFullPath())); MCFCore::MCFFile *temp = new MCFCore::MCFFile(); if (filePath) temp->setPath(filePath); else temp->setPath(DIRS_STR); temp->setName(file.c_str()); temp->setDir(oPath); temp->setSize((uint32)UTIL::FS::getFileSize(fileList[x])); time_t lastWrite = UTIL::FS::lastWriteTime(fileList[x]); std::string timeStr = bpt::to_iso_string(bpt::from_time_t(lastWrite)); temp->setTimeStamp(UTIL::MISC::atoll(timeStr.c_str())); #ifdef NIX std::string fullpath = fileList[x].getFullPath(); struct stat s; if ((stat(fullpath.c_str(), &s) == 0) && s.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) temp->addFlag(MCFFileI::FLAG_XECUTABLE); #endif m_pFileList.push_back( temp ); } for (size_t x=0; x<dirList.size(); x++) { if (UTIL::MISC::matchList(dirList[x].getLastFolder().c_str(), MCFCore::g_vExcludeDirList)) continue; gcString newPath(dirList[x].getLastFolder().c_str()); if (filePath) newPath = gcString("{0}{1}{2}", filePath, DIRS_STR, dirList[x].getLastFolder()); parseFolder(newPath.c_str(), oPath); } };
void MCF::optimiseAndSaveMcf(MCFI* prevMcf, const char* path) { printf("Optimising mcf!!\n"); if (m_bStopped) return; if (!path) throw gcException(ERR_INVALID, "Path is null"); MCF* mcf = dynamic_cast<MCF*>(prevMcf); if (!mcf) return; std::vector<mcfDif_s> vDiff; std::vector<mcfDif_s> vNew; std::vector<mcfDif_s> vSame; this->findChanges(mcf, &vSame, &vDiff, NULL, &vNew); MCF dest; dest.setFile(path); dest.setHeader(this->getHeader()); dest.getHeader()->updateFileVersion(); //allways start after the header. uint64 lastOffset = dest.getHeader()->getSize(); UTIL::FS::FileHandle hFileSrc(getFile(), UTIL::FS::FILE_READ); UTIL::FS::FileHandle hFileDest(path, UTIL::FS::FILE_WRITE); hFileDest.seek(lastOffset); for (size_t x=0; x<vNew.size(); x++) { MCFFile* file = m_pFileList[vNew[x].thisMcf]; if (file->isSaved()) { printf("Copying New File %s\n", file->getName()); dest.copyFile(file, lastOffset, hFileSrc, hFileDest); } } for (size_t x=0; x<vDiff.size(); x++) { MCFFile* file = m_pFileList[vDiff[x].thisMcf]; if (file->isSaved()) { printf("Copying Diff File %s\n", file->getName()); dest.copyFile(file, lastOffset, hFileSrc, hFileDest); } } for (size_t x=0; x<vSame.size(); x++) { MCFFile* file = m_pFileList[vSame[x].thisMcf]; if (file->isSaved()) { printf("Copying Same File %s\n", file->getName()); dest.copyFile(file, lastOffset, hFileSrc, hFileDest); } } printf("Doing crc!\n"); hFileSrc.close(); hFileDest.close(); dest.saveMCF_Header(); dest.makeCRC(); }
void changeServiceAccess(const char* szName) { gcAssert(szName); SC_HANDLE scm = nullptr; SC_HANDLE Service = nullptr; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; DWORD dwSize = 0; EXPLICIT_ACCESS ea; PACL pacl = nullptr; PACL pNewAcl = nullptr; PSECURITY_DESCRIPTOR psd = nullptr; SECURITY_DESCRIPTOR sd; //open connection to SCM scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT); if (!scm) throw gcException(ERR_NULLSCMANAGER, GetLastError(), "Failed to open the Service Control Manager"); gcWString wName(szName); try { //open service Service = OpenService(scm, wName.c_str(), READ_CONTROL|WRITE_DAC); if (!Service) throw gcException(ERR_NULLSERVICE, GetLastError(), gcString("Failed to open service: {0}", szName)); // Get the current security descriptor. if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, 0, &dwSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); if (!psd) throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName)); //get securtty info if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize)) throw gcException(ERR_SERVICE, GetLastError(), gcString("QueryServiceObjectSecurity failed for service: {0}", szName)); } } if (!psd) throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName)); // Get the DACL. if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted)) throw gcException(ERR_SERVICE, GetLastError(), gcString("GetSecurityDescriptorDacl failed for service: {0}", szName)); DWORD SidSize; PSID TheSID; SidSize = SECURITY_MAX_SID_SIZE; // Allocate enough memory for the largest possible SID. if(!(TheSID = LocalAlloc(LMEM_FIXED, SidSize))) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("LocalAlloc failed for service: {0}", szName)); } if(!CreateWellKnownSid(WinWorldSid, nullptr, TheSID, &SidSize)) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("CreateWellKnownSid failed for service: {0}", szName)); } wchar_t everyone[255]; wchar_t domain[255]; DWORD eSize = 255; DWORD dSize = 255; SID_NAME_USE rSidNameUse; if (!LookupAccountSid(nullptr, TheSID, everyone, &eSize, domain, &dSize, &rSidNameUse)) { LocalFree(TheSID); throw gcException(ERR_SERVICE, GetLastError(), gcString("LookupAccountSid failed for service: {0}", szName)); } LocalFree(TheSID); // Build the ACE. BuildExplicitAccessWithName(&ea, everyone, SERVICE_START|SERVICE_STOP|READ_CONTROL|SERVICE_QUERY_STATUS|PROCESS_QUERY_INFORMATION, SET_ACCESS, NO_INHERITANCE); if (SetEntriesInAcl(1, &ea, pacl, &pNewAcl) != ERROR_SUCCESS) { throw gcException(ERR_SERVICE, GetLastError(), gcString("SetEntriesInAcl failed for service: {0}", szName)); } // Initialize a NEW Security Descriptor. if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) throw gcException(ERR_SERVICE, GetLastError(), gcString("InitializeSecurityDescriptor failed for service: {0}", szName)); // Set the new DACL in the Security Descriptor. if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) throw gcException(ERR_SERVICE, GetLastError(), gcString("SetSecurityDescriptorDacl failed for service: {0}", szName)); // Set the new DACL for the service object. if (!SetServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, &sd)) throw gcException(ERR_SERVICE, GetLastError(), gcString("SetServiceObjectSecurity failed for service: {0}", szName)); } catch (gcException &e) { if (Service) CloseServiceHandle(Service); if (scm) CloseServiceHandle(scm); // Free buffers. LocalFree((HLOCAL)pNewAcl); HeapFree(GetProcessHeap(), 0, (LPVOID)psd); throw e; } CloseServiceHandle(scm); CloseServiceHandle(Service); // Free buffers. LocalFree((HLOCAL)pNewAcl); HeapFree(GetProcessHeap(), 0, (LPVOID)psd); }
void PipeBase::processEvents() { DWORD dwWait = WaitForMultipleObjects(getNumEvents(), m_hEventsArr, FALSE, 500); if (isStopped()) return; if (dwWait == WAIT_TIMEOUT) return; if (dwWait == WAIT_FAILED) { DWORD lErr = GetLastError(); return; } // dwWait shows which pipe completed the operation. size_t i = dwWait - WAIT_OBJECT_0; // determines which pipe if (i < 0 || i > (getNumEvents() - 1)) { printf("Index out of range.\n"); return; } PipeData* data = getData(i); DWORD cbRet = 0; #ifdef IPC_DEBUG if (fh) { fprintf(fh, "Triggered event %d\n", i); fflush(fh); } #endif //printf("Event %d, P: %d\n", i, data->fPendingIO); // Get the result if the operation was pending. if (data->fPendingIO) { BOOL fSuccess = GetOverlappedResult(data->hPipe, &data->oOverlap, &cbRet, FALSE); //printf("Pending S: %d A: %d P: %d\n", fSuccess, cbRet, data->pendingConnection); if (data->pendingConnection) { if (!fSuccess) throw gcException(ERR_PIPE, GetLastError(), gcString("Error {0}.\n", GetLastError())); data->pendingConnection = false; data->fPendingIO = FALSE; } else { DWORD err = GetLastError(); //Buffer is full. Wait for space if (err == ERROR_IO_INCOMPLETE) fSuccess = GetOverlappedResult(data->hPipe, &data->oOverlap, &cbRet, TRUE); if (!fSuccess || (cbRet == 0 && data->sender == false)) // || (cbRet != data->size && data->sender == true) { disconnectAndReconnect(i); ResetEvent(m_hEventsArr[i]); printf("Disconnect pending!\n"); return; } if (!data->sender) { data->size = cbRet; finishRead(data, getManager(i)); } } } bool res = false; // The pipe state determines which operation to do next. if (data->sender) res = performWrite(data, getManager(i)); else res = performRead(data, getManager(i)); if (res) ResetEvent(m_hEventsArr[i]); }