void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player, std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& count, uint32& totalcount) { int loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); int locdbc_idx = player->GetSession()->GetSessionDbcLocale(); for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) { AuctionEntry* Aentry = itr->second; Item* item = sAuctionMgr->GetAItem(Aentry->itemGUIDLow); if (!item) continue; ItemTemplate const* proto = item->GetTemplate(); if (itemClass != 0xffffffff && proto->Class != itemClass) continue; if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass) continue; if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType) continue; if (quality != 0xffffffff && proto->Quality != quality) continue; if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax))) continue; if (usable != 0x00 && player->CanUseItem(item) != EQUIP_ERR_OK) continue; // Allow search by suffix (ie: of the Monkey) or partial name (ie: Monkey) // No need to do any of this if no search term was entered if (!wsearchedname.empty()) { std::string name = proto->Name1; if (name.empty()) continue; // local name if (loc_idx >= 0) if (ItemLocale const* il = sObjectMgr->GetItemLocale(proto->ItemId)) ObjectMgr::GetLocaleString(il->Name, loc_idx, name); // DO NOT use GetItemEnchantMod(proto->RandomProperty) as it may return a result // that matches the search but it may not equal item->GetItemRandomPropertyId() // used in BuildAuctionInfo() which then causes wrong items to be listed int32 propRefID = item->GetItemRandomPropertyId(); if (propRefID) { // Append the suffix to the name (ie: of the Monkey) if one exists // These are found in ItemRandomProperties.dbc, not ItemRandomSuffix.dbc // even though the DBC names seem misleading const ItemRandomPropertiesEntry* itemRandProp = sItemRandomPropertiesStore.LookupEntry(propRefID); if (itemRandProp) { char* const* temp = itemRandProp->nameSuffix; // dbc local name if (temp) { // Append the suffix (ie: of the Monkey) to the name using localization // or default enUS if localization is invalid name += ' '; name += temp[locdbc_idx >= 0 ? locdbc_idx : LOCALE_enUS]; } } } // Perform the search (with or without suffix) if (!Utf8FitTo(name, wsearchedname)) continue; } // Add the item if no search term or if entered search term was found if (count < 50 && totalcount >= listfrom) { ++count; Aentry->BuildAuctionInfo(data); } ++totalcount; } }
/* ** Sets the system wallpapar. ** */ void CSystem::SetWallpaper(const std::wstring& wallpaper, const std::wstring& style) { if (!wallpaper.empty()) { if (_waccess(wallpaper.c_str(), 0) == -1) { LogWithArgs(LOG_ERROR, L"!SetWallpaper: Unable to read file: %s", wallpaper.c_str()); return; } Bitmap* bitmap = Bitmap::FromFile(wallpaper.c_str()); if (bitmap && bitmap->GetLastStatus() == Ok) { std::wstring file = Rainmeter->GetSettingsPath(); file += L"Wallpaper.bmp"; const CLSID bmpClsid = { 0x557cf400, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } }; if (bitmap->Save(file.c_str(), &bmpClsid) == Ok) { if (!style.empty()) { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { const WCHAR* wallStyle = NULL; const WCHAR* wallTile = L"0"; const WCHAR* option = style.c_str(); if (_wcsicmp(option, L"CENTER") == 0) { wallStyle = L"0"; } else if (_wcsicmp(option, L"TILE") == 0) { wallStyle = L"0"; wallTile = L"1"; } else if (_wcsicmp(option, L"STRETCH") == 0) { wallStyle = L"2"; } else if (GetOSPlatform() >= OSPLATFORM_7) { if (_wcsicmp(option, L"FIT") == 0) { wallStyle = L"6"; } else if (_wcsicmp(option, L"FILL") == 0) { wallStyle = L"10"; } } if (wallStyle) { RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_SZ, (const BYTE*)wallStyle, sizeof(WCHAR) * 2); RegSetValueEx(hKey, L"TileWallpaper", 0, REG_SZ, (const BYTE*)wallTile, sizeof(WCHAR) * 2); } else { Log(LOG_ERROR, L"!SetWallpaper: Invalid style"); } RegCloseKey(hKey); } } SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)file.c_str(), SPIF_UPDATEINIFILE); } } } }
const bool File::isValid(const std::wstring& filename) const { if (filename.empty()) return true; return NSFile::CFileBinary::Exists(filename); }
D3D12GSRender::D3D12GSRender() : GSRender() , m_d3d12_lib() , m_current_pso({}) { if (g_cfg.video.debug_output) { Microsoft::WRL::ComPtr<ID3D12Debug> debugInterface; wrapD3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)); debugInterface->EnableDebugLayer(); } Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory; CHECK_HRESULT(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory))); // Create adapter ComPtr<IDXGIAdapter> adapter; const std::wstring adapter_name = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().from_bytes(g_cfg.video.d3d12.adapter); for (UINT id = 0; dxgi_factory->EnumAdapters(id, adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND; id++) { DXGI_ADAPTER_DESC desc; adapter->GetDesc(&desc); // Adapter with specified name if (adapter_name == desc.Description) { break; } // Default adapter if (id == 1 && adapter_name.empty()) { break; } } if (FAILED(wrapD3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)))) { LOG_ERROR(RSX, "Failed to initialize D3D device on adapter '%s', falling back to first available GPU", g_cfg.video.d3d12.adapter.get()); //Try to create a device on the first available device if (FAILED(wrapD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)))) { LOG_FATAL(RSX, "Unable to create D3D12 device. Your GPU(s) may not have D3D12 support."); return; } } g_d3d12_device = m_device.Get(); // Queues D3D12_COMMAND_QUEUE_DESC graphic_queue_desc = { D3D12_COMMAND_LIST_TYPE_DIRECT }; CHECK_HRESULT(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_command_queue.GetAddressOf()))); m_descriptor_stride_srv_cbv_uav = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); m_descriptor_stride_dsv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); m_descriptor_stride_rtv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); m_descriptor_stride_samplers = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); // Create swap chain and put them in a descriptor heap as rendertarget DXGI_SWAP_CHAIN_DESC swap_chain = {}; swap_chain.BufferCount = 2; swap_chain.Windowed = true; swap_chain.OutputWindow = (HWND)m_frame->handle(); swap_chain.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swap_chain.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain.SampleDesc.Count = 1; swap_chain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; swap_chain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; CHECK_HRESULT(dxgi_factory->CreateSwapChain(m_command_queue.Get(), &swap_chain, (IDXGISwapChain**)m_swap_chain.GetAddressOf())); m_swap_chain->GetBuffer(0, IID_PPV_ARGS(&m_backbuffer[0])); m_swap_chain->GetBuffer(1, IID_PPV_ARGS(&m_backbuffer[1])); D3D12_DESCRIPTOR_HEAP_DESC render_target_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1}; D3D12_RENDER_TARGET_VIEW_DESC renter_target_view_desc = {}; renter_target_view_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; renter_target_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbuffer_descriptor_heap[0])); m_device->CreateRenderTargetView(m_backbuffer[0].Get(), &renter_target_view_desc, m_backbuffer_descriptor_heap[0]->GetCPUDescriptorHandleForHeapStart()); m_device->CreateDescriptorHeap(&render_target_descriptor_heap_desc, IID_PPV_ARGS(&m_backbuffer_descriptor_heap[1])); m_device->CreateRenderTargetView(m_backbuffer[1].Get(), &renter_target_view_desc, m_backbuffer_descriptor_heap[1]->GetCPUDescriptorHandleForHeapStart()); D3D12_DESCRIPTOR_HEAP_DESC current_texture_descriptors_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 16 }; CHECK_HRESULT(m_device->CreateDescriptorHeap(¤t_texture_descriptors_desc, IID_PPV_ARGS(m_current_texture_descriptors.GetAddressOf()))); D3D12_DESCRIPTOR_HEAP_DESC current_sampler_descriptors_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, 16 }; CHECK_HRESULT(m_device->CreateDescriptorHeap(¤t_sampler_descriptors_desc, IID_PPV_ARGS(m_current_sampler_descriptors.GetAddressOf()))); ComPtr<ID3DBlob> root_signature_blob = get_shared_root_signature_blob(); m_device->CreateRootSignature(0, root_signature_blob->GetBufferPointer(), root_signature_blob->GetBufferSize(), IID_PPV_ARGS(m_shared_root_signature.GetAddressOf())); m_per_frame_storage[0].init(m_device.Get()); m_per_frame_storage[0].reset(); m_per_frame_storage[1].init(m_device.Get()); m_per_frame_storage[1].reset(); m_output_scaling_pass.init(m_device.Get(), m_command_queue.Get()); CHECK_HRESULT( m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, 2, 2, 1, 1), D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_dummy_texture)) ); m_rtts.init(m_device.Get()); m_readback_resources.init(m_device.Get(), 1024 * 1024 * 128, D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST); m_buffer_data.init(m_device.Get(), 1024 * 1024 * 896, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ); CHECK_HRESULT( m_device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_NONE, &CD3DX12_RESOURCE_DESC::Buffer(1024 * 1024 * 16), D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, nullptr, IID_PPV_ARGS(m_vertex_buffer_data.GetAddressOf()) ) ); if (g_cfg.video.overlay) init_d2d_structures(); }
void WorldSession::BuildListAuctionItems(std::vector<AuctionEntry*> const& auctions, WorldPacket& data, std::wstring const& wsearchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& count, uint32& totalcount, bool isFull) { int loc_idx = _player->GetSession()->GetSessionDbLocaleIndex(); for (std::vector<AuctionEntry*>::const_iterator itr = auctions.begin(); itr != auctions.end(); ++itr) { AuctionEntry* Aentry = *itr; if (!Aentry || Aentry->moneyDeliveryTime) continue; Item* item = sAuctionMgr.GetAItem(Aentry->itemGuidLow); if (!item) continue; if (isFull) { ++count; Aentry->BuildAuctionInfo(data); } else { ItemPrototype const* proto = item->GetProto(); if (itemClass != 0xffffffff && proto->Class != itemClass) continue; if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass) continue; if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType) continue; if (quality != 0xffffffff && proto->Quality < quality) continue; if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax))) continue; if (usable != 0x00) { if (_player->CanUseItem(item) != EQUIP_ERR_OK) continue; if (proto->Class == ITEM_CLASS_RECIPE) { if (SpellEntry const* spell = sSpellStore.LookupEntry(proto->Spells[0].SpellId)) { if(SpellEffectEntry const* spellEffect = spell->GetSpellEffect(EFFECT_INDEX_0)) { if (_player->HasSpell(spellEffect->EffectTriggerSpell)) continue; } } } } std::string name = proto->Name1; sObjectMgr.GetItemLocaleStrings(proto->ItemId, loc_idx, &name); if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname)) continue; if (count < 50 && totalcount >= listfrom) { ++count; Aentry->BuildAuctionInfo(data); } } ++totalcount; } }
//-------------------------------------------------------------------------------------- // Name: HttpRequest::Open() // Desc: Set up and kickstart an asynchronous HTTP request on a URL given specific headers // Params: // verb - HTTP verb as a wchar_t string // url - URI for the HTTP request // headers - Array of HTTPHeaderInfo objects to include with the request // iHeaderCount - How many headers are in the array // data - Optional, Data payload for the request as void pointer //-------------------------------------------------------------------------------------- HRESULT HttpRequest::Open(const std::wstring& verb, const std::wstring& url, const std::vector<HttpHeaderInfo>& headers, const uint8_t* data, const size_t datalength) { if (verb.empty()) { return E_INVALIDARG; } if (url.empty()) { return E_INVALIDARG; } if (headers.size() == 0) { return E_INVALIDARG; } HRESULT hr = E_FAIL; // Open a connection for an HTTP GET request. // NOTE: This is where the IXMLHTTPRequest2 object gets given a // pointer to the IXMLHTTPRequest2Callback object. hr = m_pXHR->Open(verb.c_str(), // HTTP method url.c_str(), // URL string as wchar* m_pXHRCallback.Get(), // callback object from a ComPtr<> NULL, // username NULL, // password NULL, // proxy username NULL); // proxy password if (FAILED(hr)) { return hr; } //Add code to not have Durango OS add authorization header hr = m_pXHR->SetRequestHeader(L"xbl-authz-optout-10", L"1\r\n"); if (FAILED(hr)) { return hr; } // // Add the provided headers to the request from the caller, if one is // a required header for the signature, add it to the SigningHeaders // string following the standard header format "Header: value\r\n" to // be used with the token and signature retrieval API // for (INT i = 0; i < headers.size(); i++) { std::wstring wstrHeaderName = headers[i].wstrHeaderName; std::wstring wstrHeaderValue = headers[i].wstrHeaderValue; hr = m_pXHR->SetRequestHeader(wstrHeaderName.c_str(), wstrHeaderValue.c_str()); if (FAILED(hr)) { m_pXHR->Abort(); return hr; } } if (data != nullptr && datalength != 0) { // Create and open a new runtime class m_requestStream = Make<RequestStream>(); m_requestStream->Open(reinterpret_cast<const char*>(data), datalength); hr = m_pXHR->Send(m_requestStream.Get(), // body message as an ISequentialStream* m_requestStream->Size()); // count of bytes in the stream. } else { hr = m_pXHR->Send(NULL, 0); } if (FAILED(hr)) { m_pXHR->Abort(); return hr; } return hr; }
bool CRealTextParser::ParseRealText(std::wstring p_szFile) { std::vector<int> vStartTimecodes; std::vector<int> vEndTimecodes; bool bPrevEndTimeMissing = false; std::list<Tag> listTags; std::list<Tag> listPreviousOpenTags; while (!p_szFile.empty()) { if (p_szFile.at(0) == '<') { Tag oTag; if (!ExtractTag(p_szFile, oTag)) { return false; } if (oTag.m_bComment) { continue; } if (oTag.m_szName == L"time") { int iStartTimecode = GetTimecode(oTag.m_mapAttributes[L"begin"]); int iEndTimecode = GetTimecode(oTag.m_mapAttributes[L"end"]); //FilterReduntantTags(listTags); std::wstring szLine = RenderTags(listTags); if (bPrevEndTimeMissing) { std::pair<int, int> pairTimecodes(vStartTimecodes.back(), iStartTimecode); // Fix issues where the next time code isn't valid end time code for the previous subtitle if (pairTimecodes.first >= pairTimecodes.second) { pairTimecodes.second = pairTimecodes.first + m_iDefaultSubtitleDurationInMillisecs; } if (!szLine.empty()) { m_RealText.m_mapLines[pairTimecodes] = szLine; } bPrevEndTimeMissing = false; } else if (!vStartTimecodes.empty() && !vEndTimecodes.empty()) { std::pair<int, int> pairTimecodes(vStartTimecodes.back(), vEndTimecodes.back()); if (!szLine.empty()) { m_RealText.m_mapLines[pairTimecodes] = szLine; } } vStartTimecodes.push_back(iStartTimecode); if (iEndTimecode <= 0) { bPrevEndTimeMissing = true; } else { vEndTimecodes.push_back(iEndTimecode); } } else if (oTag.m_szName == L"b" || oTag.m_szName == L"i" || oTag.m_szName == L"font") { if (oTag.m_bOpen) { listPreviousOpenTags.push_back(oTag); } if (oTag.m_bClose) { PopTag(listPreviousOpenTags, oTag.m_szName); } listTags.push_back(oTag); } else if (oTag.m_szName == L"clear") { listTags.clear(); // set existing tags listTags.insert(listTags.end(), listPreviousOpenTags.begin(), listPreviousOpenTags.end()); } else if (oTag.m_szName == L"window") { if (oTag.m_bOpen) { m_RealText.m_WindowTag = oTag; } // Ignore close } else if (oTag.m_szName == L"center") { m_RealText.m_bCenter = true; } else if (oTag.m_szName == L"required") { // Ignore } else if (oTag.m_szName.empty()) { // Ignore } else { // assume formating tag (handled later) listTags.push_back(oTag); } } else { Tag oTextTag; if (!ExtractTextTag(p_szFile, oTextTag)) { return false; } listTags.push_back(oTextTag); } } // Handle final line //FilterReduntantTags(listTags); std::wstring szLine = RenderTags(listTags); if (bPrevEndTimeMissing) { std::pair<int, int> pairTimecodes(vStartTimecodes.back(), vStartTimecodes.back() + m_iDefaultSubtitleDurationInMillisecs); if (!szLine.empty()) { m_RealText.m_mapLines[pairTimecodes] = szLine; } bPrevEndTimeMissing = false; } else if (!vStartTimecodes.empty() && !vEndTimecodes.empty()) { std::pair<int, int> pairTimecodes(vStartTimecodes.back(), vEndTimecodes.back()); if (!szLine.empty()) { m_RealText.m_mapLines[pairTimecodes] = szLine; } } return true; }
std::wstring EncryptPassword(bool bEncrypt, const std::wstring& passwordIn) { if(passwordIn.empty()) return L""; if(!bEncrypt && PASSWORD_ENCRYPTED_ESCAPE != passwordIn[0] && PASSWORD_ENCRYPTED_ESCAPE != passwordIn[1]) return passwordIn; std::vector<wchar_t> vMessItUpArray; vMessItUpArray.push_back(2); vMessItUpArray.push_back(5); vMessItUpArray.push_back(7); vMessItUpArray.push_back(9); vMessItUpArray.push_back(3); vMessItUpArray.push_back(16); vMessItUpArray.push_back(14); vMessItUpArray.push_back(8); vMessItUpArray.push_back(9); vMessItUpArray.push_back(12); std::vector<wchar_t>::iterator it = vMessItUpArray.begin(); if(bEncrypt) { std::ostrstream passwordOut; passwordOut << PASSWORD_ENCRYPTED_ESCAPE << PASSWORD_ENCRYPTED_ESCAPE << std::hex; passwordOut.fill('0'); passwordOut.width(2); for(int i = 0; i < (int)passwordIn.size(); i++) { if(it == vMessItUpArray.end()) it = vMessItUpArray.begin(); wchar_t bOut = passwordIn[i] - *it; passwordOut << bOut; it++; } passwordOut << std::ends; return _bstr_t(passwordOut.str()).copy(); } else { std::wstring passwordOut; passwordOut.resize(passwordIn.size() / 2 - 1); for(int i = 0; i < (int)passwordOut.size(); i++) { if(it == vMessItUpArray.end()) it = vMessItUpArray.begin(); wchar_t bOut = towupper(passwordIn[(i+1)*2]) - '0'; if(9 < bOut) bOut -= 7; passwordOut[i] = bOut * 0x10; bOut = towupper(passwordIn[(i+1)*2+1]) - '0'; if(9 < bOut) bOut -= 7; passwordOut[i] += bOut + *it; it++; } return passwordOut; } }
void HOSTFXR_UTILITY::GetHostFxrParameters( const fs::path &processPath, const fs::path &applicationPhysicalPath, const std::wstring &applicationArguments, fs::path &hostFxrDllPath, fs::path &dotnetExePath, std::vector<std::wstring> &arguments ) { LOG_INFOF(L"Resolving hostfxr parameters for application: '%ls' arguments: '%ls' path: '%ls'", processPath.c_str(), applicationArguments.c_str(), applicationPhysicalPath.c_str()); arguments = std::vector<std::wstring>(); fs::path expandedProcessPath = Environment::ExpandEnvironmentVariables(processPath); const auto expandedApplicationArguments = Environment::ExpandEnvironmentVariables(applicationArguments); LOG_INFOF(L"Known dotnet.exe location: '%ls'", dotnetExePath.c_str()); if (!expandedProcessPath.has_extension()) { // The only executable extension inprocess supports expandedProcessPath.replace_extension(".exe"); } else if (!ends_with(expandedProcessPath, L".exe", true)) { throw InvalidOperationException(format(L"Process path '%s' doesn't have '.exe' extension.", expandedProcessPath.c_str())); } // Check if the absolute path is to dotnet or not. if (IsDotnetExecutable(expandedProcessPath)) { LOG_INFOF(L"Process path '%ls' is dotnet, treating application as portable", expandedProcessPath.c_str()); if (applicationArguments.empty()) { throw InvalidOperationException(L"Application arguments are empty."); } if (dotnetExePath.empty()) { dotnetExePath = GetAbsolutePathToDotnet(applicationPhysicalPath, expandedProcessPath); } hostFxrDllPath = GetAbsolutePathToHostFxr(dotnetExePath); arguments.push_back(dotnetExePath); AppendArguments( expandedApplicationArguments, applicationPhysicalPath, arguments, true); } else { LOG_INFOF(L"Process path '%ls' is not dotnet, treating application as standalone or portable with bootstrapper", expandedProcessPath.c_str()); auto executablePath = expandedProcessPath; if (executablePath.is_relative()) { executablePath = applicationPhysicalPath / expandedProcessPath; } // // The processPath is a path to the application executable // like: C:\test\MyApp.Exe or MyApp.Exe // Check if the file exists, and if it does, get the parameters for a standalone application // if (is_regular_file(executablePath)) { auto applicationDllPath = executablePath; applicationDllPath.replace_extension(".dll"); LOG_INFOF(L"Checking application.dll at '%ls'", applicationDllPath.c_str()); if (!is_regular_file(applicationDllPath)) { throw InvalidOperationException(format(L"Application .dll was not found at %s", applicationDllPath.c_str())); } hostFxrDllPath = executablePath.parent_path() / "hostfxr.dll"; LOG_INFOF(L"Checking hostfxr.dll at '%ls'", hostFxrDllPath.c_str()); if (is_regular_file(hostFxrDllPath)) { LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as standalone", hostFxrDllPath.c_str()); // For standalone apps we need .exe to be argv[0], dll would be discovered next to it arguments.push_back(executablePath); } else { LOG_INFOF(L"hostfxr.dll found app local at '%ls', treating application as portable with launcher", hostFxrDllPath.c_str()); // passing "dotnet" here because we don't know where dotnet.exe should come from // so trying all fallbacks is appropriate if (dotnetExePath.empty()) { dotnetExePath = GetAbsolutePathToDotnet(applicationPhysicalPath, L"dotnet"); } hostFxrDllPath = GetAbsolutePathToHostFxr(dotnetExePath); // For portable with launcher apps we need dotnet.exe to be argv[0] and .dll be argv[1] arguments.push_back(dotnetExePath); arguments.push_back(applicationDllPath); } AppendArguments( expandedApplicationArguments, applicationPhysicalPath, arguments); } else { // // If the processPath file does not exist and it doesn't include dotnet.exe or dotnet // then it is an invalid argument. // throw InvalidOperationException(format(L"Executable was not found at '%s'", executablePath.c_str())); } } }
void HOSTFXR_UTILITY::AppendArguments( const std::wstring &applicationArguments, const fs::path &applicationPhysicalPath, std::vector<std::wstring> &arguments, bool expandDllPaths ) { if (applicationArguments.empty()) { return; } // don't throw while trying to expand arguments std::error_code ec; // Try to treat entire arguments section as a single path if (expandDllPaths) { fs::path argumentAsPath = applicationArguments; if (is_regular_file(argumentAsPath, ec)) { LOG_INFOF(L"Treating '%ls' as a single path argument", applicationArguments.c_str()); arguments.push_back(argumentAsPath); return; } if (argumentAsPath.is_relative()) { argumentAsPath = applicationPhysicalPath / argumentAsPath; if (is_regular_file(argumentAsPath, ec)) { LOG_INFOF(L"Converted argument '%ls' to '%ls'", applicationArguments.c_str(), argumentAsPath.c_str()); arguments.push_back(argumentAsPath); return; } } } int argc = 0; auto pwzArgs = std::unique_ptr<LPWSTR[], LocalFreeDeleter>(CommandLineToArgvW(applicationArguments.c_str(), &argc)); if (!pwzArgs) { throw InvalidOperationException(format(L"Unable parse command line arguments '%s'", applicationArguments.c_str())); } for (int intArgsProcessed = 0; intArgsProcessed < argc; intArgsProcessed++) { std::wstring argument = pwzArgs[intArgsProcessed]; // Try expanding arguments ending in .dll to a full paths if (expandDllPaths && ends_with(argument, L".dll", true)) { fs::path argumentAsPath = argument; if (argumentAsPath.is_relative()) { argumentAsPath = applicationPhysicalPath / argumentAsPath; if (is_regular_file(argumentAsPath, ec)) { LOG_INFOF(L"Converted argument '%ls' to '%ls'", argument.c_str(), argumentAsPath.c_str()); argument = argumentAsPath; } } } arguments.push_back(argument); } }
bool CLocalPath::SetPath(std::wstring const& path, std::wstring* file) { // This function ensures that the path is in canonical form on success. if (path.empty()) { m_path.clear(); return false; } #ifdef FZ_WINDOWS if (path == L"\\") { m_path.get() = path; if (file) { file->clear(); } return true; } #endif std::deque<wchar_t*> segments; // List to store the beginnings of segments wchar_t const* in = path.c_str(); { std::wstring & path_out = m_path.get(); path_out.resize(path.size() + 1); wchar_t * const start = &(path_out[0]); wchar_t * out = start; #ifdef FZ_WINDOWS if (*in == '\\') { // possibly UNC in++; if (*in++ != '\\') { path_out.clear(); return false; } if (*in == '?') { // Could be \\?\c:\foo\bar // or \\?\UNC\server\share // or something else we do not support. if (*(++in) != '\\') { path_out.clear(); return false; } in++; if (((*in >= 'a' && *in <= 'z') || (*in >= 'A' || *in <= 'Z')) && *(in+1) == ':') { // It's \\?\c:\foo\bar goto parse_regular; } wchar_t const* in_end = in + path.size(); if (in_end - in < 5 || fz::stricmp(std::wstring(in, in_end), L"UNC\\")) { path_out.clear(); return false; } in += 4; // It's \\?\UNC\server\share // ^we are here } *out++ = '\\'; *out++ = '\\'; // UNC path while (*in) { if (*in == '/' || *in == '\\') break; *out++ = *in++; } *out++ = path_separator; if (out - start <= 3) { // not a valid UNC path path_out.clear(); return false; } segments.push_back(out); } else if ((*in >= 'a' && *in <= 'z') || (*in >= 'A' || *in <= 'Z')) { parse_regular: // Regular path *out++ = *in++; if (*in++ != ':') { path_out.clear(); return false; } *out++ = ':'; if (*in != '/' && *in != '\\' && *in) { path_out.clear(); return false; } *out++ = path_separator; segments.push_back(out); } else { path_out.clear(); return false; } #else if (*in++ != '/') { // SetPath only accepts absolute paths path_out.clear(); return false; } *out++ = '/'; segments.push_back(out); #endif enum _last { separator, dot, dotdot, segment }; _last last = separator; while (*in) { if (*in == '/' #ifdef FZ_WINDOWS || *in == '\\' #endif ) { in++; if (last == separator) { // /foo//bar is equal to /foo/bar continue; } else if (last == dot) { // /foo/./bar is equal to /foo/bar last = separator; out = segments.back(); continue; } else if (last == dotdot) { last = separator; // Go two segments back if possible if (segments.size() > 1) { segments.pop_back(); } out = segments.back(); continue; } // Ordinary segment just ended. *out++ = path_separator; segments.push_back(out); last = separator; continue; } else if (*in == '.') { if (last == separator) { last = dot; } else if (last == dot) { last = dotdot; } else if (last == dotdot) { last = segment; } } else { last = segment; } *out++ = *in++; } if (last == dot) { out = segments.back(); } else if (last == dotdot) { if (segments.size() > 1) { segments.pop_back(); } out = segments.back(); } else if (last == segment) { if (file) { *file = std::wstring(segments.back(), out); out = segments.back(); } else { *out++ = path_separator; } } path_out.resize(out - start); } return true; }
bool ServiceController::installService( const std::wstring& serviceName, const std::wstring& displayName, const std::wstring& serviceDesc, const std::wstring& serviceUser, const std::wstring& servicePassword, const std::string dbpath, int argc, char* argv[] ) { assert(argc >= 1); stringstream commandLine; char exePath[1024]; GetModuleFileNameA( NULL, exePath, sizeof exePath ); commandLine << '"' << exePath << "\" "; for ( int i = 1; i < argc; i++ ) { std::string arg( argv[ i ] ); // replace install command to indicate process is being started as a service if ( arg == "--install" || arg == "--reinstall" ) { arg = "--service"; } else if ( arg == "--dbpath" && i + 1 < argc ) { commandLine << arg << " \"" << dbpath << "\" "; i++; continue; } else if ( arg == "--logpath" && i + 1 < argc ) { commandLine << arg << " \"" << argv[i+1] << "\" "; i++; continue; } else if ( arg == "-f" && i + 1 < argc ) { commandLine << arg << " \"" << argv[i+1] << "\" "; i++; continue; } else if ( arg == "--config" && i + 1 < argc ) { commandLine << arg << " \"" << argv[i+1] << "\" "; i++; continue; } else if ( arg == "--pidfilepath" && i + 1 < argc ) { commandLine << arg << " \"" << argv[i+1] << "\" "; i++; continue; } else if ( arg == "--repairpath" && i + 1 < argc ) { commandLine << arg << " \"" << argv[i+1] << "\" "; i++; continue; } else if ( arg == "--keyfile" && i + 1 < argc ) { commandLine << arg << " \"" << argv[i+1] << "\" "; i++; continue; } else if ( arg.length() > 9 && arg.substr(0, 9) == "--service" ) { // Strip off --service(Name|User|Password) arguments i++; continue; } commandLine << arg << " "; } SC_HANDLE schSCManager = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if ( schSCManager == NULL ) { DWORD err = ::GetLastError(); cerr << "Error connecting to the Service Control Manager: " << GetWinErrMsg(err) << endl; return false; } // Make sure servise doesn't already exist. // TODO: Check to see if service is in "Deleting" status, suggest the user close down Services MMC snap-ins. SC_HANDLE schService = ::OpenService( schSCManager, serviceName.c_str(), SERVICE_ALL_ACCESS ); if ( schService != NULL ) { cerr << "There is already a service named " << toUtf8String(serviceName) << ". Aborting" << endl; ::CloseServiceHandle( schService ); ::CloseServiceHandle( schSCManager ); return false; } std::basic_ostringstream< TCHAR > commandLineWide; commandLineWide << commandLine.str().c_str(); cerr << "Creating service " << toUtf8String(serviceName) << "." << endl; // create new service schService = ::CreateService( schSCManager, serviceName.c_str(), displayName.c_str(), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, commandLineWide.str().c_str(), NULL, NULL, L"\0\0", NULL, NULL ); if ( schService == NULL ) { DWORD err = ::GetLastError(); cerr << "Error creating service: " << GetWinErrMsg(err) << endl; ::CloseServiceHandle( schSCManager ); return false; } cerr << "Service creation successful." << endl; cerr << "Service can be started from the command line via 'net start \"" << toUtf8String(serviceName) << "\"'." << endl; bool serviceInstalled; // TODO: If neccessary grant user "Login as a Service" permission. if ( !serviceUser.empty() ) { std::wstring actualServiceUser; if ( serviceUser.find(L"\\") == string::npos ) { actualServiceUser = L".\\" + serviceUser; } else { actualServiceUser = serviceUser; } cerr << "Setting service login credentials. User: "******"Setting service login failed. Service has 'LocalService' permissions." << endl; } } // set the service description SERVICE_DESCRIPTION serviceDescription; serviceDescription.lpDescription = (LPTSTR)serviceDesc.c_str(); serviceInstalled = ::ChangeServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, &serviceDescription ); #if 1 if ( ! serviceInstalled ) { #else // This code sets the mongod service to auto-restart, forever. // This might be a fine thing to do except that when mongod or Windows has a crash, the mongo.lock // file is still around, so any attempt at a restart will immediately fail. With auto-restart, we // go into a loop, crashing and restarting, crashing and restarting, until someone comes in and // disables the service or deletes the mongod.lock file. // // I'm leaving the old code here for now in case we solve this and are able to turn SC_ACTION_RESTART // back on. // if ( serviceInstalled ) { SC_ACTION aActions[ 3 ] = { { SC_ACTION_RESTART, 0 }, { SC_ACTION_RESTART, 0 }, { SC_ACTION_RESTART, 0 } }; SERVICE_FAILURE_ACTIONS serviceFailure; ZeroMemory( &serviceFailure, sizeof( SERVICE_FAILURE_ACTIONS ) ); serviceFailure.cActions = 3; serviceFailure.lpsaActions = aActions; // set service recovery options serviceInstalled = ::ChangeServiceConfig2( schService, SERVICE_CONFIG_FAILURE_ACTIONS, &serviceFailure ); } else { #endif cerr << "Could not set service description. Check the event log for more details." << endl; } ::CloseServiceHandle( schService ); ::CloseServiceHandle( schSCManager ); return serviceInstalled; } bool ServiceController::removeService( const std::wstring& serviceName ) { SC_HANDLE schSCManager = ::OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if ( schSCManager == NULL ) { DWORD err = ::GetLastError(); cerr << "Error connecting to the Service Control Manager: " << GetWinErrMsg(err) << endl; return false; } SC_HANDLE schService = ::OpenService( schSCManager, serviceName.c_str(), SERVICE_ALL_ACCESS ); if ( schService == NULL ) { cerr << "Could not find a service named " << toUtf8String(serviceName) << " to uninstall." << endl; ::CloseServiceHandle( schSCManager ); return false; } SERVICE_STATUS serviceStatus; // stop service if its running if ( ::ControlService( schService, SERVICE_CONTROL_STOP, &serviceStatus ) ) { cerr << "Service " << toUtf8String(serviceName) << " is currently running. Stopping service." << endl; while ( ::QueryServiceStatus( schService, &serviceStatus ) ) { if ( serviceStatus.dwCurrentState == SERVICE_STOP_PENDING ) { Sleep( 1000 ); } else { break; } } cerr << "Service stopped." << endl; } cerr << "Deleting service " << toUtf8String(serviceName) << "." << endl; bool serviceRemoved = ::DeleteService( schService ); ::CloseServiceHandle( schService ); ::CloseServiceHandle( schSCManager ); if (serviceRemoved) { cerr << "Service deleted successfully." << endl; } else { cerr << "Failed to delete service." << endl; } return serviceRemoved; }