static void test_BuildPath(void) { struct buildpath_test *ptr = buildpath_data; BSTR ret, path; HRESULT hr; int i = 0; hr = IFileSystem3_BuildPath(fs3, NULL, NULL, NULL); ok(hr == E_POINTER, "got 0x%08x\n", hr); ret = (BSTR)0xdeadbeef; hr = IFileSystem3_BuildPath(fs3, NULL, NULL, &ret); ok(hr == S_OK, "got 0x%08x\n", hr); ok(*ret == 0, "got %p\n", ret); SysFreeString(ret); ret = (BSTR)0xdeadbeef; path = bstr_from_str("path"); hr = IFileSystem3_BuildPath(fs3, path, NULL, &ret); ok(hr == S_OK, "got 0x%08x\n", hr); ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret)); SysFreeString(ret); SysFreeString(path); ret = (BSTR)0xdeadbeef; path = bstr_from_str("path"); hr = IFileSystem3_BuildPath(fs3, NULL, path, &ret); ok(hr == S_OK, "got 0x%08x\n", hr); ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret)); SysFreeString(ret); SysFreeString(path); while (ptr->path) { BSTR name, result; ret = NULL; path = bstr_from_str(ptr->path); name = bstr_from_str(ptr->name); result = bstr_from_str(ptr->result); hr = IFileSystem3_BuildPath(fs3, path, name, &ret); ok(hr == S_OK, "%d: got 0x%08x\n", i, hr); if (hr == S_OK) { ok(!lstrcmpW(ret, result), "%d: got wrong path %s, expected %s\n", i, wine_dbgstr_w(ret), wine_dbgstr_w(result)); SysFreeString(ret); } SysFreeString(path); SysFreeString(name); SysFreeString(result); i++; ptr++; } }
/****************************************************************************** * SysFreeString [OLEAUT32.6] * * Free a BSTR. * * PARAMS * str [I] BSTR to free. * * RETURNS * Nothing. * * NOTES * See BSTR. * str may be NULL, in which case this function does nothing. */ void WINAPI SysFreeString(BSTR str) { bstr_cache_entry_t *cache_entry; bstr_t *bstr; if(!str) return; bstr = bstr_from_str(str); cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR)); if(cache_entry) { EnterCriticalSection(&cs_bstr_cache); if(cache_entry->cnt < sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) { cache_entry->buf[(cache_entry->head+cache_entry->cnt)%((sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)))] = bstr; cache_entry->cnt++; if(WARN_ON(heap)) { unsigned i, n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1; bstr->size = ARENA_FREE_FILLER; for(i=0; i<n; i++) bstr->u.dwptr[i] = ARENA_FREE_FILLER; } LeaveCriticalSection(&cs_bstr_cache); return; } LeaveCriticalSection(&cs_bstr_cache); } HeapFree(GetProcessHeap(), 0, bstr); }
/****************************************************************************** * SysFreeString [OLEAUT32.6] * * Free a BSTR. * * PARAMS * str [I] BSTR to free. * * RETURNS * Nothing. * * NOTES * See BSTR. * str may be NULL, in which case this function does nothing. */ void WINAPI SysFreeString(BSTR str) { bstr_cache_entry_t *cache_entry; bstr_t *bstr; if(!str) return; bstr = bstr_from_str(str); cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR)); if(cache_entry) { unsigned i; EnterCriticalSection(&cs_bstr_cache); /* According to tests, freeing a string that's already in cache doesn't corrupt anything. * For that to work we need to search the cache. */ for(i=0; i < cache_entry->cnt; i++) { if(cache_entry->buf[(cache_entry->head+i) % BUCKET_BUFFER_SIZE] == bstr) { WARN_(heap)("String already is in cache!\n"); LeaveCriticalSection(&cs_bstr_cache); return; } } if(cache_entry->cnt < sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) { cache_entry->buf[(cache_entry->head+cache_entry->cnt) % BUCKET_BUFFER_SIZE] = bstr; cache_entry->cnt++; if(WARN_ON(heap)) { unsigned n = bstr_alloc_size(bstr->size) / sizeof(DWORD) - 1; bstr->size = ARENA_FREE_FILLER; for(i=0; i<n; i++) bstr->u.dwptr[i] = ARENA_FREE_FILLER; } LeaveCriticalSection(&cs_bstr_cache); return; } LeaveCriticalSection(&cs_bstr_cache); } HeapFree(GetProcessHeap(), 0, bstr); }
/****************************************************************************** * SysStringByteLen [OLEAUT32.149] * * Get the allocated length of a BSTR in bytes. * * PARAMS * str [I] BSTR to find the length of * * RETURNS * The allocated length of str, or 0 if str is NULL. * * NOTES * See SysStringLen(), BSTR(). */ UINT WINAPI SysStringByteLen(BSTR str) { return str ? bstr_from_str(str)->size : 0; }
/****************************************************************************** * SysStringLen [OLEAUT32.7] * * Get the allocated length of a BSTR in wide characters. * * PARAMS * str [I] BSTR to find the length of * * RETURNS * The allocated length of str, or 0 if str is NULL. * * NOTES * See BSTR. * The returned length may be different from the length of the string as * calculated by lstrlenW(), since it returns the length that was used to * allocate the string by SysAllocStringLen(). */ UINT WINAPI SysStringLen(BSTR str) { return str ? bstr_from_str(str)->size/sizeof(WCHAR) : 0; }