size_t os_wcs_to_utf8_ptr(const wchar_t *str, size_t len, char **pstr) { size_t out_len = os_wcs_to_utf8(str, len, NULL); *pstr = bmalloc((out_len+1) * sizeof(char)); return os_wcs_to_utf8(str, out_len, *pstr); }
static inline void EnumD3DAdapters( bool (*callback)(void*, const char*, uint32_t), void *param) { ComPtr<IDXGIFactory1> factory; ComPtr<IDXGIAdapter1> adapter; HRESULT hr; UINT i = 0; IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 : __uuidof(IDXGIFactory1); hr = CreateDXGIFactory1(factoryIID, (void**)factory.Assign()); if (FAILED(hr)) throw HRError("Failed to create DXGIFactory", hr); while (factory->EnumAdapters1(i++, adapter.Assign()) == S_OK) { DXGI_ADAPTER_DESC desc; char name[512] = ""; hr = adapter->GetDesc(&desc); if (FAILED(hr)) continue; /* ignore microsoft's 'basic' renderer' */ if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) continue; os_wcs_to_utf8(desc.Description, 0, name, sizeof(name)); if (!callback(param, name, i - 1)) break; } }
static bool get_device_info(obs_enum_audio_device_cb cb, void *data, IMMDeviceCollection *collection, UINT idx) { IPropertyStore *store = NULL; IMMDevice *device = NULL; PROPVARIANT name_var; char utf8_name[512]; WCHAR *w_id = NULL; char utf8_id[512]; bool cont = true; HRESULT hr; hr = collection->lpVtbl->Item(collection, idx, &device); if (FAILED(hr)) { goto fail; } hr = device->lpVtbl->GetId(device, &w_id); if (FAILED(hr)) { goto fail; } hr = device->lpVtbl->OpenPropertyStore(device, STGM_READ, &store); if (FAILED(hr)) { goto fail; } PropVariantInit(&name_var); hr = store->lpVtbl->GetValue(store, &PKEY_Device_FriendlyName, &name_var); if (FAILED(hr)) { goto fail; } os_wcs_to_utf8(w_id, 0, utf8_id, 512); os_wcs_to_utf8(name_var.pwszVal, 0, utf8_name, 512); cont = cb(data, utf8_name, utf8_id); fail: safe_release(store); safe_release(device); if (w_id) CoTaskMemFree(w_id); return cont; }
void mssapi_captions::main_thread() try { HRESULT hr; os_set_thread_name(__FUNCTION__); hr = grammar->SetDictationState(SPRS_ACTIVE); if (FAILED(hr)) throw HRError("SetDictationState failed", hr); hr = recognizer->SetRecoState(SPRST_ACTIVE); if (FAILED(hr)) throw HRError("SetRecoState(SPRST_ACTIVE) failed", hr); HANDLE events[] = {notify, stop}; started = true; for (;;) { DWORD ret = WaitForMultipleObjects(2, events, false, INFINITE); if (ret != WAIT_OBJECT_0) break; CSpEvent event; bool exit = false; while (event.GetFrom(context) == S_OK) { if (event.eEventId == SPEI_RECOGNITION) { ISpRecoResult *result = event.RecoResult(); CoTaskMemPtr<wchar_t> text; hr = result->GetText((ULONG)-1, (ULONG)-1, true, &text, nullptr); if (FAILED(hr)) continue; char text_utf8[512]; os_wcs_to_utf8(text, 0, text_utf8, 512); callback(text_utf8); blog(LOG_DEBUG, "\"%s\"", text_utf8); } else if (event.eEventId == SPEI_END_SR_STREAM) { exit = true; break; } } if (exit) break; } audio->Stop(); } catch (HRError err) { blog(LOG_WARNING, "%s failed: %s (%lX)", __FUNCTION__, err.str, err.hr); }
/* returns %appdata% on windows */ char *os_get_home_path(void) { char *out; wchar_t path_utf16[MAX_PATH]; SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path_utf16); os_wcs_to_utf8(path_utf16, 0, &out); return out; }
size_t os_mbs_to_utf8(const char *str, size_t len, char **pstr) { wchar_t *wstr = NULL; char *dst = NULL; size_t wlen = os_mbs_to_wcs(str, len, &wstr); size_t out_len = os_wcs_to_utf8(wstr, wlen, &dst); bfree(wstr); *pstr = dst; return out_len; }
static BOOL CALLBACK enum_module(PCTSTR module_name, DWORD64 module_base, ULONG module_size, struct module_info *info) { if (info->addr >= module_base && info->addr < module_base + module_size) { os_wcs_to_utf8(module_name, 0, info->name_utf8, MAX_PATH); strlwr(info->name_utf8); return false; } return true; }
char *os_getcwd(char *path, size_t size) { wchar_t *path_w; DWORD len; len = GetCurrentDirectoryW(0, NULL); if (!len) return NULL; path_w = bmalloc((len + 1) * sizeof(wchar_t)); GetCurrentDirectoryW(len + 1, path_w); os_wcs_to_utf8(path_w, (size_t)len, path, size); bfree(path_w); return path; }
FILE *os_wfopen(const wchar_t *path, const char *mode) { FILE *file; #ifdef _MSC_VER wchar_t *wcs_mode; os_utf8_to_wcs(mode, 0, &wcs_mode); file = _wfopen(path, wcs_mode); bfree(wcs_mode); #else char *mbs_path; os_wcs_to_utf8(path, 0, &mbs_path); file = fopen(mbs_path, mode); bfree(mbs_path); #endif return file; }
size_t os_get_abs_path(const char *path, char *abspath, size_t size) { wchar_t wpath[512]; wchar_t wabspath[512]; size_t out_len = 0; size_t len; if (!abspath) return 0; len = os_utf8_to_wcs(path, 0, wpath, 512); if (!len) return 0; if (_wfullpath(wabspath, wpath, 512) != NULL) out_len = os_wcs_to_utf8(wabspath, 0, abspath, size); return out_len; }
bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info) { VS_FIXEDFILEINFO *info = NULL; UINT len = 0; BOOL success; LPVOID data; DWORD size; char utf8_lib[512]; if (!ver_initialized && !initialize_version_functions()) return false; if (!ver_initialize_success) return false; os_wcs_to_utf8(lib, 0, utf8_lib, sizeof(utf8_lib)); size = get_file_version_info_size(lib, NULL); if (!size) { blog(LOG_ERROR, "Failed to get %s version info size", utf8_lib); return false; } data = bmalloc(size); if (!get_file_version_info(lib, 0, size, data)) { blog(LOG_ERROR, "Failed to get %s version info", utf8_lib); bfree(data); return false; } success = ver_query_value(data, L"\\", (LPVOID*)&info, &len); if (!success || !info || !len) { blog(LOG_ERROR, "Failed to get %s version info value", utf8_lib); bfree(data); return false; } ver_info->major = (int)HIWORD(info->dwFileVersionMS); ver_info->minor = (int)LOWORD(info->dwFileVersionMS); ver_info->build = (int)HIWORD(info->dwFileVersionLS); ver_info->revis = (int)LOWORD(info->dwFileVersionLS); bfree(data); return true; }
struct os_dirent *os_readdir(os_dir_t dir) { if (!dir) return NULL; if (dir->first) { dir->first = false; } else { if (!FindNextFileW(dir->handle, &dir->wfd)) return NULL; } os_wcs_to_utf8(dir->wfd.cFileName, 0, dir->out.d_name, sizeof(dir->out.d_name)); dir->out.directory = is_dir(&dir->wfd); return &dir->out; }
void gs_device::InitDevice(gs_init_data *data, IDXGIAdapter *adapter) { wstring adapterName; DXGI_SWAP_CHAIN_DESC swapDesc; DXGI_ADAPTER_DESC desc; D3D_FEATURE_LEVEL levelUsed; HRESULT hr; make_swap_desc(swapDesc, data); uint32_t createFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG createFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif adapterName = (adapter->GetDesc(&desc) == S_OK) ? desc.Description : L"<unknown>"; char *adapterNameUTF8; os_wcs_to_utf8(adapterName.c_str(), 0, &adapterNameUTF8); blog(LOG_INFO, "Loading up D3D11 on adapter %s", adapterNameUTF8); bfree(adapterNameUTF8); hr = D3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createFlags, featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL), D3D11_SDK_VERSION, &swapDesc, defaultSwap.swap.Assign(), device.Assign(), &levelUsed, context.Assign()); if (FAILED(hr)) throw HRError("Failed to create device and swap chain", hr); blog(LOG_INFO, "D3D11 loaded sucessfully, feature level used: %u", (uint32_t)levelUsed); defaultSwap.device = this; defaultSwap.hwnd = (HWND)data->hwnd; defaultSwap.numBuffers = data->num_backbuffers; defaultSwap.Init(data); }
/* returns [folder]\[name] on windows */ static int os_get_path_internal(char *dst, size_t size, const char *name, int folder) { wchar_t path_utf16[MAX_PATH]; SHGetFolderPathW(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path_utf16); if (os_wcs_to_utf8(path_utf16, 0, dst, size) != 0) { if (!name || !*name) { return (int)strlen(dst); } if (strcat_s(dst, size, "\\") == 0) { if (strcat_s(dst, size, name) == 0) { return (int)strlen(dst); } } } return -1; }
static BOOL CALLBACK enum_all_modules(PCTSTR module_name, DWORD64 module_base, ULONG module_size, struct exception_handler_data *data) { char name_utf8[MAX_PATH]; os_wcs_to_utf8(module_name, 0, name_utf8, MAX_PATH); if (data->main_trace.instruction_ptr >= module_base && data->main_trace.instruction_ptr < module_base + module_size) { dstr_copy(&data->module_name, name_utf8); strlwr(data->module_name.array); } #ifdef _WIN64 dstr_catf(&data->module_list, "%016"PRIX64"-%016"PRIX64" %s\r\n", module_base, module_base + module_size, name_utf8); #else dstr_catf(&data->module_list, "%08"PRIX64"-%08"PRIX64" %s\r\n", module_base, module_base + module_size, name_utf8); #endif return true; }
static inline bool walk_stack(struct exception_handler_data *data, HANDLE thread, struct stack_trace *trace) { struct module_info module_info = {0}; DWORD64 func_offset; char sym_name[256]; char *p; bool success = data->stack_walk64(trace->image_type, data->process, thread, &trace->frame, &trace->context, NULL, data->sym_function_table_access64, data->sym_get_module_base64, NULL); if (!success) return false; module_info.addr = trace->frame.AddrPC.Offset; get_module_name(data, &module_info); if (!!module_info.name_utf8[0]) { p = strrchr(module_info.name_utf8, '\\'); p = p ? (p + 1) : module_info.name_utf8; } else { strcpy(module_info.name_utf8, "<unknown>"); p = module_info.name_utf8; } success = !!data->sym_from_addr(data->process, trace->frame.AddrPC.Offset, &func_offset, data->sym_info); if (success) os_wcs_to_utf8(data->sym_info->Name, 0, sym_name, 256); #ifdef _WIN64 #define SUCCESS_FORMAT \ "%016I64X %016I64X %016I64X %016I64X " \ "%016I64X %016I64X %s!%s+0x%I64x\r\n" #define FAIL_FORMAT \ "%016I64X %016I64X %016I64X %016I64X " \ "%016I64X %016I64X %s!0x%I64x\r\n" #else #define SUCCESS_FORMAT \ "%08.8I64X %08.8I64X %08.8I64X %08.8I64X " \ "%08.8I64X %08.8I64X %s!%s+0x%I64x\r\n" #define FAIL_FORMAT \ "%08.8I64X %08.8I64X %08.8I64X %08.8I64X " \ "%08.8I64X %08.8I64X %s!0x%I64x\r\n" trace->frame.AddrStack.Offset &= 0xFFFFFFFFF; trace->frame.AddrPC.Offset &= 0xFFFFFFFFF; trace->frame.Params[0] &= 0xFFFFFFFF; trace->frame.Params[1] &= 0xFFFFFFFF; trace->frame.Params[2] &= 0xFFFFFFFF; trace->frame.Params[3] &= 0xFFFFFFFF; #endif if (success && (data->sym_info->Flags & SYMFLAG_EXPORT) == 0) { dstr_catf(&data->str, SUCCESS_FORMAT, trace->frame.AddrStack.Offset, trace->frame.AddrPC.Offset, trace->frame.Params[0], trace->frame.Params[1], trace->frame.Params[2], trace->frame.Params[3], p, sym_name, func_offset); } else { dstr_catf(&data->str, FAIL_FORMAT, trace->frame.AddrStack.Offset, trace->frame.AddrPC.Offset, trace->frame.Params[0], trace->frame.Params[1], trace->frame.Params[2], trace->frame.Params[3], p, trace->frame.AddrPC.Offset); } return true; }