예제 #1
0
static BOOL check_native_ie(void)
{
    static const WCHAR cszPath[] = {'b','r','o','w','s','e','u','i','.','d','l','l',0};
    DWORD handle,size;
    BOOL ret = TRUE;

    size = GetFileVersionInfoSizeW(cszPath,&handle);
    if (size)
    {
        LPVOID buf;
        LPWSTR lpFileDescription;
        UINT dwBytes;
        static const WCHAR cszFD[] = {'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o','\\','0','4','0','9','0','4','e','4','\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0};
        static const WCHAR cszWine[] = {'W','i','n','e',0};

        buf = HeapAlloc(GetProcessHeap(),0,size);
        GetFileVersionInfoW(cszPath,0,size,buf);

        if (VerQueryValueW(buf, cszFD, (LPVOID*)&lpFileDescription, &dwBytes) &&
            strstrW(lpFileDescription,cszWine))
                ret = FALSE;

        HeapFree(GetProcessHeap(), 0, buf);
    }

    return ret;
}
예제 #2
0
파일: help.c 프로젝트: YokoZar/wine
static void DoSync(HHInfo *info)
{
    WCHAR buf[INTERNET_MAX_URL_LENGTH];
    HRESULT hres;
    DWORD len;
    BSTR url;

    hres = IWebBrowser2_get_LocationURL(info->web_browser, &url);

    if (FAILED(hres))
    {
        WARN("get_LocationURL failed: %08x\n", hres);
        return;
    }

    /* If we're not currently viewing a page in the active .chm file, abort */
    if ((!AppendFullPathURL(info->pszFile, buf, NULL)) || (len = lstrlenW(buf) > lstrlenW(url)))
    {
        SysFreeString(url);
        return;
    }

    if (lstrcmpiW(buf, url) > 0)
    {
        static const WCHAR delimW[] = {':',':','/',0};
        const WCHAR *index;

        index = strstrW(url, delimW);

        if (index)
            ActivateContentTopic(info->tabs[TAB_CONTENTS].hwnd, index + 3, info->content); /* skip over ::/ */
    }

    SysFreeString(url);
}
예제 #3
0
파일: main.c 프로젝트: GYGit/reactos
static BOOL check_native_ie(void)
{
    DWORD handle, size;
    LPWSTR file_desc;
    UINT bytes;
    void* buf;
    BOOL ret;

    static const WCHAR browseui_dllW[] = {'b','r','o','w','s','e','u','i','.','d','l','l',0};
    static const WCHAR wineW[] = {'W','i','n','e',0};
    static const WCHAR file_desc_strW[] =
        {'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
#ifndef __REACTOS__
         '\\','0','4','0','9','0','4','e','4',
#else
         '\\','0','4','0','9','0','4','b','0',
#endif
         '\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n',0};

    size = GetFileVersionInfoSizeW(browseui_dllW, &handle);
    if(!size)
        return TRUE;

    buf = HeapAlloc(GetProcessHeap(), 0, size);
    GetFileVersionInfoW(browseui_dllW, 0, size,buf);

    ret = !VerQueryValueW(buf, file_desc_strW, (void**)&file_desc, &bytes) || !strstrW(file_desc, wineW);

    HeapFree(GetProcessHeap(), 0, buf);
    return ret;
}
예제 #4
0
파일: patch.c 프로젝트: Dietr1ch/wine
static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform )
{
    MSISUMMARYINFO *si = MSI_GetSummaryInformationW( transform, 0 );
    UINT valid_flags = 0, wanted_flags = 0;

    if (si) wanted_flags = msi_suminfo_get_int32( si, PID_CHARCOUNT );
    TRACE("validation flags %x\n", wanted_flags);

    if (wanted_flags & ~(MSITRANSFORM_VALIDATE_PRODUCT|MSITRANSFORM_VALIDATE_LANGUAGE))
        FIXME("unsupported validation flags %x\n", wanted_flags);

    if (wanted_flags & MSITRANSFORM_VALIDATE_PRODUCT)
    {
        WCHAR *package_product = msi_dup_property( package->db, szProductCode );
        WCHAR *transform_product = msi_get_suminfo_product( transform );

        TRACE("package = %s transform = %s\n", debugstr_w(package_product), debugstr_w(transform_product));

        if (!transform_product || strstrW( transform_product, package_product ))
        {
            valid_flags |= MSITRANSFORM_VALIDATE_PRODUCT;
        }
        msi_free( transform_product );
        msi_free( package_product );
    }
    if (wanted_flags & MSITRANSFORM_VALIDATE_LANGUAGE)
    {
        WCHAR *template;
예제 #5
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                              jsval_t *r)
{
    jsstr_t *search_jsstr, *jsstr;
    const WCHAR *search_str, *str;
    int length, pos = 0;
    INT ret = -1;
    HRESULT hres;

    TRACE("\n");

    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
    if(FAILED(hres))
        return hres;

    length = jsstr_length(jsstr);
    if(!argc) {
        if(r)
            *r = jsval_number(-1);
        jsstr_release(jsstr);
        return S_OK;
    }

    hres = to_flat_string(ctx, argv[0], &search_jsstr, &search_str);
    if(FAILED(hres)) {
        jsstr_release(jsstr);
        return hres;
    }

    if(argc >= 2) {
        double d;

        hres = to_integer(ctx, argv[1], &d);
        if(SUCCEEDED(hres) && d > 0.0)
            pos = is_int32(d) ? min(length, d) : length;
    }

    if(SUCCEEDED(hres)) {
        const WCHAR *ptr;

        ptr = strstrW(str+pos, search_str);
        if(ptr)
            ret = ptr - str;
        else
            ret = -1;
    }

    jsstr_release(search_jsstr);
    jsstr_release(jsstr);
    if(FAILED(hres))
        return hres;

    if(r)
        *r = jsval_number(ret);
    return S_OK;
}
예제 #6
0
파일: datainit.c 프로젝트: AlexSteel/wine
static WCHAR *strstriW(const WCHAR *str, const WCHAR *sub)
{
    LPWSTR strlower, sublower, r;
    strlower = CharLowerW(strdupW(str));
    sublower = CharLowerW(strdupW(sub));
    r = strstrW(strlower, sublower);
    if (r)
        r = (LPWSTR)str + (r - strlower);
    heap_free(strlower);
    heap_free(sublower);
    return r;
}
예제 #7
0
/******************************************************************
 *              macho_search_and_load_file
 *
 * Lookup a file in standard Mach-O locations, and if found, load it
 */
static BOOL macho_search_and_load_file(struct process* pcs, const WCHAR* filename,
                                       unsigned long load_addr,
                                       struct macho_info* macho_info)
{
    BOOL                ret = FALSE;
    struct module*      module;
    static WCHAR        S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
    const WCHAR*        p;

    TRACE("(%p/%p, %s, 0x%08lx, %p)\n", pcs, pcs->handle, debugstr_w(filename), load_addr,
            macho_info);

    if (filename == NULL || *filename == '\0') return FALSE;
    if ((module = module_is_already_loaded(pcs, filename)))
    {
        macho_info->module = module;
        module->format_info[DFI_MACHO]->u.macho_info->in_use = 1;
        return module->module.SymType;
    }

    if (strstrW(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */

    /* If has no directories, try LD_LIBRARY_PATH first. */
    if (!strchrW(filename, '/'))
    {
        ret = macho_load_file_from_path(pcs, filename, load_addr,
                                      getenv("PATH"), macho_info);
    }
    /* Try DYLD_LIBRARY_PATH, with just the filename (no directories). */
    if (!ret)
    {
        if ((p = strrchrW(filename, '/'))) p++;
        else p = filename;
        ret = macho_load_file_from_path(pcs, p, load_addr,
                                      getenv("DYLD_LIBRARY_PATH"), macho_info);
    }
    /* Try the path as given. */
    if (!ret)
        ret = macho_load_file(pcs, filename, load_addr, macho_info);
    /* Try DYLD_FALLBACK_LIBRARY_PATH, with just the filename (no directories). */
    if (!ret)
    {
        ret = macho_load_file_from_path(pcs, p, load_addr,
                                      getenv("DYLD_FALLBACK_LIBRARY_PATH"), macho_info);
    }
    if (!ret && !strchrW(filename, '/'))
        ret = macho_load_file_from_dll_path(pcs, filename, load_addr, macho_info);

    return ret;
}
예제 #8
0
static void update_result_text(HWND hdlg, const ps_struct_t *ps_struct)
{
    WCHAR resource_txt[200];
    UINT res_id;
    OLEUIPASTEENTRYW *pent;
    LONG cur_sel;
    static const WCHAR percent_s[] = {'%','s',0};
    WCHAR *result_txt, *ptr;

    cur_sel = SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETCURSEL, 0, 0);
    if(cur_sel == -1) return;
    pent = (OLEUIPASTEENTRYW*)SendMessageW(GetDlgItem(hdlg, IDC_PS_DISPLAYLIST), LB_GETITEMDATA, cur_sel, 0);

    if(ps_struct->flags & PSF_SELECTPASTE)
    {
        if(ps_struct->flags & PSF_CHECKDISPLAYASICON)
            res_id = IDS_PS_PASTE_OBJECT_AS_ICON;
        else
            res_id = IDS_PS_PASTE_DATA;
    }
    else
    {
        if(ps_struct->flags & PSF_CHECKDISPLAYASICON)
            res_id = IDS_PS_PASTE_LINK_OBJECT_AS_ICON;
        else
            res_id = IDS_PS_PASTE_LINK_DATA;
    }

    LoadStringW(OLEDLG_hInstance, res_id, resource_txt, sizeof(resource_txt)/sizeof(WCHAR));
    if((ptr = strstrW(resource_txt, percent_s)))
    {
        /* FIXME handle %s in ResultText. Sub appname if IDS_PS_PASTE_OBJECT{_AS_ICON}.  Else sub appropriate type name */
        size_t result_txt_len = strlenW(pent->lpstrResultText);
        ptrdiff_t offs = (char*)ptr - (char*)resource_txt;
        result_txt = HeapAlloc(GetProcessHeap(), 0, (strlenW(resource_txt) + result_txt_len - 1) * sizeof(WCHAR));
        memcpy(result_txt, resource_txt, offs);
        memcpy((char*)result_txt + offs, pent->lpstrResultText, result_txt_len * sizeof(WCHAR));
        memcpy((char*)result_txt + offs + result_txt_len * sizeof(WCHAR), ptr + 2, (strlenW(ptr + 2) + 1) * sizeof(WCHAR));
    }
    else
        result_txt = resource_txt;

    SetDlgItemTextW(hdlg, IDC_PS_RESULTTEXT, result_txt);

    if(result_txt != resource_txt)
        HeapFree(GetProcessHeap(), 0, result_txt);

}
예제 #9
0
파일: protocol.c 프로젝트: AlexSteel/wine
static HRESULT WINAPI ITSProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
        LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult,
        DWORD cchResult, DWORD* pcchResult, DWORD dwReserved)
{
    ITSProtocol *This = impl_from_IInternetProtocolInfo(iface);
    LPCWSTR base_end, ptr;
    DWORD rel_len;

    static const WCHAR separator[] = {':',':',0};

    TRACE("(%p)->(%s %s %08x %p %d %p %d)\n", This, debugstr_w(pwzBaseUrl),
            debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult,
            pcchResult, dwReserved);

    base_end = strstrW(pwzBaseUrl, separator);
    if(!base_end)
        return 0x80041001;
    base_end += 2;

    if(!skip_schema(pwzBaseUrl))
        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;

    if(strchrW(pwzRelativeUrl, ':'))
        return STG_E_INVALIDNAME;

    if(pwzRelativeUrl[0] == '#') {
        base_end += strlenW(base_end);
    }else if(pwzRelativeUrl[0] != '/') {
        ptr = strrchrW(base_end, '/');
        if(ptr)
            base_end = ptr+1;
        else
            base_end += strlenW(base_end);
    }

    rel_len = strlenW(pwzRelativeUrl)+1;

    *pcchResult = rel_len + (base_end-pwzBaseUrl);

    if(*pcchResult > cchResult)
        return E_OUTOFMEMORY;

    memcpy(pwzResult, pwzBaseUrl, (base_end-pwzBaseUrl)*sizeof(WCHAR));
    strcpyW(pwzResult + (base_end-pwzBaseUrl), pwzRelativeUrl);

    return S_OK;
}
예제 #10
0
static HRESULT WINAPI xmlwriter_WriteCData(IXmlWriter *iface, LPCWSTR data)
{
    xmlwriter *This = impl_from_IXmlWriter(iface);
    int len;

    TRACE("%p %s\n", This, debugstr_w(data));

    switch (This->state)
    {
    case XmlWriterState_Initial:
        return E_UNEXPECTED;
    case XmlWriterState_ElemStarted:
        writer_close_starttag(This);
        break;
    case XmlWriterState_Ready:
    case XmlWriterState_DocClosed:
        This->state = XmlWriterState_DocClosed;
        return WR_E_INVALIDACTION;
    default:
        ;
    }

    len = data ? strlenW(data) : 0;

    write_node_indent(This);
    if (!len)
        write_cdata_section(This->output, NULL, 0);
    else {
        static const WCHAR cdatacloseW[] = {']',']','>',0};
        while (len) {
            const WCHAR *str = strstrW(data, cdatacloseW);
            if (str) {
                str += 2;
                write_cdata_section(This->output, data, str - data);
                len -= str - data;
                data = str;
            }
            else {
                write_cdata_section(This->output, data, len);
                break;
            }
        }
    }

    return S_OK;
}
예제 #11
0
파일: search.c 프로젝트: RareHare/reactos
/* Search all children of a CHM storage object for the requested text and
 * return the last found search item.
 */
static SearchItem *SearchCHM_Storage(SearchItem *item, IStorage *pStorage,
                                     const char *needle)
{
    const WCHAR szHTMext[] = {'.','h','t','m',0};
    IEnumSTATSTG *elem = NULL;
    WCHAR *filename = NULL;
    STATSTG entries;
    HRESULT hres;
    ULONG retr;

    hres = IStorage_EnumElements(pStorage, 0, NULL, 0, &elem);
    if(hres != S_OK)
    {
        FIXME("Could not enumerate '/' storage elements: %08x\n", hres);
        return NULL;
    }
    while (IEnumSTATSTG_Next(elem, 1, &entries, &retr) == NOERROR)
    {
        switch(entries.type) {
        case STGTY_STORAGE:
            item = SearchCHM_Folder(item, pStorage, entries.pwcsName, needle);
            break;
        case STGTY_STREAM:
            filename = entries.pwcsName;
            while(strchrW(filename, '/'))
                filename = strchrW(filename, '/')+1;
            if(strstrW(filename, szHTMext))
            {
                WCHAR *title = SearchCHM_File(pStorage, filename, needle);

                if(title)
                {
                    item->next = alloc_search_item(title, entries.pwcsName);
                    item = item->next;
                }
            }
            break;
        default:
            FIXME("Unhandled IStorage stream element.\n");
        }
    }
    IEnumSTATSTG_Release(elem);
    return item;
}
예제 #12
0
static HRESULT WINAPI HTMLFrameBase_get_marginHeight(IHTMLFrameBase *iface, VARIANT *p)
{
    HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
    nsAString nsstr;
    nsresult nsres;
    HRESULT hres = S_OK;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&nsstr, NULL);
    if(This->nsframe)
        nsres = nsIDOMHTMLFrameElement_GetMarginHeight(This->nsframe, &nsstr);
    else
        nsres = nsIDOMHTMLIFrameElement_GetMarginHeight(This->nsiframe, &nsstr);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *str, *end;

        nsAString_GetData(&nsstr, &str);

        if(*str) {
            BSTR ret;

            end = strstrW(str, pxW);
            if(!end)
                end = str+strlenW(str);
            ret = SysAllocStringLen(str, end-str);
            if(ret) {
                V_VT(p) = VT_BSTR;
                V_BSTR(p) = ret;
            }else {
                hres = E_OUTOFMEMORY;
            }
        }else {
            V_VT(p) = VT_BSTR;
            V_BSTR(p) = NULL;
        }
    }else {
        ERR("SetMarginHeight failed: %08x\n", nsres);
        hres = E_FAIL;
    }

    nsAString_Finish(&nsstr);
    return hres;
}
예제 #13
0
파일: help.c 프로젝트: YokoZar/wine
BOOL NavigateToUrl(HHInfo *info, LPCWSTR surl)
{
    ChmPath chm_path;
    BOOL ret;
    HRESULT hres;

    static const WCHAR url_indicator[] = {':', '/', '/', 0};

    TRACE("%s\n", debugstr_w(surl));

    if (strstrW(surl, url_indicator)) {
        hres = navigate_url(info, surl);
        if(SUCCEEDED(hres))
            return TRUE;
    } /* look up in chm if it doesn't look like a full url */

    SetChmPath(&chm_path, info->pCHMInfo->szFile, surl);
    ret = NavigateToChm(info, chm_path.chm_file, chm_path.chm_index);

    heap_free(chm_path.chm_file);
    heap_free(chm_path.chm_index);

    return ret;
}
예제 #14
0
파일: main.c 프로젝트: GYGit/reactos
static void test_OleUIAddVerbMenu(void)
{
    static const WCHAR cadabraW[] = {'c','a','d','a','b','r','a',0};
    HMENU hMenu, verbmenu;
    MENUITEMINFOW info;
    WCHAR buffW[50];
    int count;
    BOOL ret;

    ret = OleUIAddVerbMenuW(NULL, NULL, NULL, 0, 0, 0, FALSE, 0, NULL);
    ok(!ret, "got %d\n", ret);

    verbmenu = (HMENU)0xdeadbeef;
    ret = OleUIAddVerbMenuW(NULL, NULL, NULL, 0, 0, 0, FALSE, 0, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, NULL, 0, 0, 0, FALSE, 0, NULL);
    ok(!ret, "got %d\n", ret);

    hMenu = CreatePopupMenu();

    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    ret = InsertMenuItemW(hMenu, 0, TRUE, &info);
    ok(ret, "got %d\n", ret);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 0, 0, 0, FALSE, 0, NULL);
    ok(!ret, "got %d\n", ret);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    ret = InsertMenuItemW(hMenu, 0, TRUE, &info);
    ok(ret, "got %d\n", ret);

    count = GetMenuItemCount(hMenu);
    ok(count == 2, "got %d\n", count);

    verbmenu = (HMENU)0xdeadbeef;
    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 1, 0, 0, FALSE, 0, &verbmenu);
    ok(ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 2, "got %d\n", count);

    /* object doesn't support EnumVerbs() */
    g_enumverbsfail = TRUE;
    g_enumpos = 0;
    verbmenu = (HMENU)0xdeadbeef;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 2, 0, 0, FALSE, 0, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);
    g_enumverbsfail = FALSE;

    /* added disabled item */
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STATE|MIIM_SUBMENU;
    ret = GetMenuItemInfoW(hMenu, 2, TRUE, &info);
    ok(ret, "got %d\n", ret);
    ok(info.fState & MFS_DISABLED, "got state 0x%08x\n", info.fState);
    ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 3, "got %d\n", count);

    /* now without object */
    verbmenu = (HMENU)0xdeadbeef;
    ret = OleUIAddVerbMenuW(NULL, testW, hMenu, 3, 42, 0, FALSE, 0, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STATE|MIIM_ID|MIIM_STRING|MIIM_SUBMENU;
    info.dwTypeData = buffW;
    info.cch = sizeof(buffW)/sizeof(WCHAR);
    ret = GetMenuItemInfoW(hMenu, 3, TRUE, &info);
    ok(ret, "got %d\n", ret);
    ok(info.fState == MF_GRAYED, "got state 0x%08x\n", info.fState);
    ok(info.wID == 42, "got id %d\n", info.wID);
    ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 4, "got %d\n", count);

    verbmenu = (HMENU)0xdeadbeef;
    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 4, 0, 0, FALSE, 0, &verbmenu);
    ok(ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    /* check newly added item */
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STRING|MIIM_STATE|MIIM_SUBMENU;
    info.dwTypeData = buffW;
    info.cch = sizeof(buffW)/sizeof(WCHAR);
    ret = GetMenuItemInfoW(hMenu, 4, TRUE, &info);
    ok(ret, "got %d\n", ret);
    /* Item string contains verb, usertype and localized string for 'Object' word,
       exact format depends on localization. */
    ok(strstrW(buffW, verbW) != NULL, "str %s\n", wine_dbgstr_w(buffW));
    ok(info.fState == 0, "got state 0x%08x\n", info.fState);
    ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 5, "got %d\n", count);

    DestroyMenu(hMenu);

    /* try to add verb menu repeatedly, with same id */
    hMenu = CreatePopupMenu();

    count = GetMenuItemCount(hMenu);
    ok(count == 0, "got %d\n", count);

    verbmenu = NULL;
    ret = OleUIAddVerbMenuW(NULL, NULL, hMenu, 0, 5, 10, TRUE, 3, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    verbmenu = NULL;
    ret = OleUIAddVerbMenuW(NULL, NULL, hMenu, 0, 5, 10, TRUE, 3, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    /* same position, different id */
    verbmenu = NULL;
    ret = OleUIAddVerbMenuW(NULL, NULL, hMenu, 0, 6, 10, TRUE, 3, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    /* change added item string and state */
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STRING|MIIM_STATE;
    info.fState = MFS_ENABLED;
    info.dwTypeData = buffW;
    lstrcpyW(buffW, cadabraW);
    ret = SetMenuItemInfoW(hMenu, 0, TRUE, &info);
    ok(ret, "got %d\n", ret);

    buffW[0] = 0;
    GetMenuStringW(hMenu, 0, buffW, sizeof(buffW)/sizeof(buffW[0]), MF_BYPOSITION);
    ok(!lstrcmpW(buffW, cadabraW), "got %s\n", wine_dbgstr_w(buffW));

    verbmenu = NULL;
    ret = OleUIAddVerbMenuW(NULL, NULL, hMenu, 0, 5, 10, TRUE, 3, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STRING|MIIM_STATE;
    buffW[0] = 0;
    info.dwTypeData = buffW;
    info.cch = sizeof(buffW)/sizeof(WCHAR);
    ret = GetMenuItemInfoW(hMenu, 0, TRUE, &info);
    ok(ret, "got %d\n", ret);
    ok(lstrcmpW(buffW, cadabraW), "got %s\n", wine_dbgstr_w(buffW));
    ok(info.fState == MF_GRAYED, "got state 0x%08x\n", info.fState);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    DestroyMenu(hMenu);
}
예제 #15
0
파일: protocol.c 프로젝트: AlexSteel/wine
static HRESULT WINAPI ITSProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
        IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
        DWORD grfPI, HANDLE_PTR dwReserved)
{
    ITSProtocol *This = impl_from_IInternetProtocol(iface);
    BINDINFO bindinfo;
    DWORD bindf = 0, len;
    LPWSTR file_name, mime, object_name, p;
    LPCWSTR ptr;
    struct chmFile *chm_file;
    struct chmUnitInfo chm_object;
    int res;
    HRESULT hres;

    static const WCHAR separator[] = {':',':',0};

    TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
            pOIBindInfo, grfPI, dwReserved);

    ptr = skip_schema(szUrl);
    if(!ptr)
        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;

    memset(&bindinfo, 0, sizeof(bindinfo));
    bindinfo.cbSize = sizeof(BINDINFO);
    hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
    if(FAILED(hres)) {
        WARN("GetBindInfo failed: %08x\n", hres);
        return hres;
    }

    ReleaseBindInfo(&bindinfo);

    len = strlenW(ptr)+3;
    file_name = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
    memcpy(file_name, ptr, len*sizeof(WCHAR));
    hres = UrlUnescapeW(file_name, NULL, &len, URL_UNESCAPE_INPLACE);
    if(FAILED(hres)) {
        WARN("UrlUnescape failed: %08x\n", hres);
        HeapFree(GetProcessHeap(), 0, file_name);
        return hres;
    }

    p = strstrW(file_name, separator);
    if(!p) {
        WARN("invalid url\n");
        HeapFree(GetProcessHeap(), 0, file_name);
        return report_result(pOIProtSink, STG_E_FILENOTFOUND);
    }

    *p = 0;
    chm_file = chm_openW(file_name);
    if(!chm_file) {
        WARN("Could not open chm file\n");
        HeapFree(GetProcessHeap(), 0, file_name);
        return report_result(pOIProtSink, STG_E_FILENOTFOUND);
    }

    object_name = p+2;
    len = strlenW(object_name);

    if(*object_name != '/' && *object_name != '\\') {
        memmove(object_name+1, object_name, (len+1)*sizeof(WCHAR));
        *object_name = '/';
        len++;
    }

    if(object_name[len-1] == '/')
        object_name[--len] = 0;

    for(p=object_name; *p; p++) {
        if(*p == '\\')
            *p = '/';
    }

    remove_dot_segments(object_name);

    TRACE("Resolving %s\n", debugstr_w(object_name));

    memset(&chm_object, 0, sizeof(chm_object));
    res = chm_resolve_object(chm_file, object_name, &chm_object);
    if(res != CHM_RESOLVE_SUCCESS) {
        WARN("Could not resolve chm object\n");
        HeapFree(GetProcessHeap(), 0, file_name);
        chm_close(chm_file);
        return report_result(pOIProtSink, STG_E_FILENOTFOUND);
    }

    IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST,
                                         strrchrW(object_name, '/')+1);

    /* FIXME: Native doesn't use FindMimeFromData */
    hres = FindMimeFromData(NULL, object_name, NULL, 0, NULL, 0, &mime, 0);
    HeapFree(GetProcessHeap(), 0, file_name);
    if(SUCCEEDED(hres)) {
        IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime);
        CoTaskMemFree(mime);
    }

    release_chm(This); /* Native leaks handle here */
    This->chm_file = chm_file;
    This->chm_object = chm_object;

    hres = IInternetProtocolSink_ReportData(pOIProtSink,
            BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE,
            chm_object.length, chm_object.length);
    if(FAILED(hres)) {
        WARN("ReportData failed: %08x\n", hres);
        release_chm(This);
        return report_result(pOIProtSink, hres);
    }

    hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);

    return report_result(pOIProtSink, hres);
}
예제 #16
0
/***********************************************************************
 *           MSACM_ReorderDriversByPriority()
 * Reorders all drivers based on the priority list indicated by the registry key:
 * HKCU\\Software\\Microsoft\\Multimedia\\Audio Compression Manager\\Priority v4.00
 */
static void MSACM_ReorderDriversByPriority(void)
{
    PWINE_ACMDRIVERID	padid;
    unsigned int iNumDrivers;
    PWINE_ACMDRIVERID * driverList = NULL;
    HKEY hPriorityKey = NULL;
    
    TRACE("\n");
    
    /* Count drivers && alloc corresponding memory for list */
    iNumDrivers = 0;
    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) iNumDrivers++;
    if (iNumDrivers > 1)
    {
        LONG lError;
        static const WCHAR basePriorityKey[] = {
            'S','o','f','t','w','a','r','e','\\',
            'M','i','c','r','o','s','o','f','t','\\',
            'M','u','l','t','i','m','e','d','i','a','\\',
            'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
            'P','r','i','o','r','i','t','y',' ','v','4','.','0','0','\0'
        };
        unsigned int i;
        LONG lBufferLength;
        WCHAR szBuffer[256];
        
        driverList = HeapAlloc(MSACM_hHeap, 0, iNumDrivers * sizeof(PWINE_ACMDRIVERID));
        if (!driverList)
        {
            ERR("out of memory\n");
            goto errCleanUp;
        }

        lError = RegOpenKeyW(HKEY_CURRENT_USER, basePriorityKey, &hPriorityKey);
        if (lError != ERROR_SUCCESS) {
            TRACE("RegOpenKeyW failed, possibly key does not exist yet\n");
            hPriorityKey = NULL;
            goto errCleanUp;
        } 
            
        /* Copy drivers into list to simplify linked list modification */
        for (i = 0, padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID, i++)
        {
            driverList[i] = padid;
        }

        /* Query each of the priorities in turn. Alias key is in lowercase. 
            The general form of the priority record is the following:
            "PriorityN" --> "1, msacm.driveralias"
            where N is an integer, and the value is a string of the driver
            alias, prefixed by "1, " for an enabled driver, or "0, " for a
            disabled driver.
            */
        for (i = 0; i < iNumDrivers; i++)
        {
            static const WCHAR priorityTmpl[] = {'P','r','i','o','r','i','t','y','%','l','d','\0'};
            WCHAR szSubKey[17];
            unsigned int iTargetPosition;
            unsigned int iCurrentPosition;
            WCHAR * pAlias;
            static const WCHAR sPrefix[] = {'m','s','a','c','m','.','\0'};
            
            /* Build expected entry name */
            snprintfW(szSubKey, 17, priorityTmpl, i + 1);
            lBufferLength = sizeof(szBuffer);
            lError = RegQueryValueExW(hPriorityKey, szSubKey, NULL, NULL, (LPBYTE)szBuffer, (LPDWORD)&lBufferLength);
            if (lError != ERROR_SUCCESS) continue;

            /* Recovered driver alias should be at this position */
            iTargetPosition = i;
            
            /* Locate driver alias in driver list */
            pAlias = strstrW(szBuffer, sPrefix);
            if (pAlias == NULL) continue;
            
            for (iCurrentPosition = 0; iCurrentPosition < iNumDrivers; iCurrentPosition++) {
                if (strcmpiW(driverList[iCurrentPosition]->pszDriverAlias, pAlias) == 0) 
                    break;
            }
            if (iCurrentPosition < iNumDrivers && iTargetPosition != iCurrentPosition) {
                padid = driverList[iTargetPosition];
                driverList[iTargetPosition] = driverList[iCurrentPosition];
                driverList[iCurrentPosition] = padid;

                /* Locate enabled status */
                if (szBuffer[0] == '1') {
                    driverList[iTargetPosition]->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
                } else if (szBuffer[0] == '0') {
                    driverList[iTargetPosition]->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
                }
            }
        }
        
        /* Re-assign pointers so that linked list traverses the ordered array */
        for (i = 0; i < iNumDrivers; i++) {
            driverList[i]->pPrevACMDriverID = (i > 0) ? driverList[i - 1] : NULL;
            driverList[i]->pNextACMDriverID = (i < iNumDrivers - 1) ? driverList[i + 1] : NULL;
        }
        MSACM_pFirstACMDriverID = driverList[0];
        MSACM_pLastACMDriverID = driverList[iNumDrivers - 1];
    }
    
errCleanUp:
    if (hPriorityKey != NULL) RegCloseKey(hPriorityKey);
    HeapFree(MSACM_hHeap, 0, driverList);
}
예제 #17
0
/*
  Window procedure for autocompletion
 */
static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    IAutoCompleteImpl *This = GetPropW(hwnd, autocomplete_propertyW);
    LPOLESTR strs;
    HRESULT hr;
    WCHAR hwndText[255];
    WCHAR *hwndQCText;
    RECT r;
    BOOL control, filled, displayall = FALSE;
    int cpt, height, sel;

    if (!This->enabled) return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);

    switch (uMsg)
    {
	case CB_SHOWDROPDOWN:
	    ShowWindow(This->hwndListBox, SW_HIDE);
	    break;
	case WM_KILLFOCUS:
            if ((This->options & ACO_AUTOSUGGEST) &&
		((HWND)wParam != This->hwndListBox))
	    {
		ShowWindow(This->hwndListBox, SW_HIDE);
	    }
	    return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
	case WM_KEYUP:
            GetWindowTextW( hwnd, hwndText, 255);

	    switch(wParam) {
		case VK_RETURN:
		    /* If quickComplete is set and control is pressed, replace the string */
		    control = GetKeyState(VK_CONTROL) & 0x8000;		    
		    if (control && This->quickComplete) {
			hwndQCText = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
						       (lstrlenW(This->quickComplete)+lstrlenW(hwndText))*sizeof(WCHAR));
			sel = sprintfW(hwndQCText, This->quickComplete, hwndText);
			SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)hwndQCText);
			SendMessageW(hwnd, EM_SETSEL, 0, sel);
			HeapFree(GetProcessHeap(), 0, hwndQCText);
		    }

		    ShowWindow(This->hwndListBox, SW_HIDE);
		    return 0;
		case VK_LEFT:
		case VK_RIGHT:
		    return 0;
		case VK_UP:	      
		case VK_DOWN:
		    /* Two cases here : 
		       - if the listbox is not visible, displays it 
		       with all the entries if the style ACO_UPDOWNKEYDROPSLIST
		       is present but does not select anything.
		       - if the listbox is visible, change the selection
		    */
		    if ( (This->options & (ACO_AUTOSUGGEST | ACO_UPDOWNKEYDROPSLIST)) 
			 && (!IsWindowVisible(This->hwndListBox) && (! *hwndText)) )
		    {
			 /* We must display all the entries */
			 displayall = TRUE;
		    } else {
			if (IsWindowVisible(This->hwndListBox)) {
			    int count;

			    count = SendMessageW(This->hwndListBox, LB_GETCOUNT, 0, 0);
			    /* Change the selection */
			    sel = SendMessageW(This->hwndListBox, LB_GETCURSEL, 0, 0);
			    if (wParam == VK_UP)
				sel = ((sel-1)<0)?count-1:sel-1;
			    else
				sel = ((sel+1)>= count)?-1:sel+1;
			    SendMessageW(This->hwndListBox, LB_SETCURSEL, sel, 0);
			    if (sel != -1) {
				WCHAR *msg;
				int len;
				
				len = SendMessageW(This->hwndListBox, LB_GETTEXTLEN, sel, 0);
				msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len+1)*sizeof(WCHAR));
				SendMessageW(This->hwndListBox, LB_GETTEXT, sel, (LPARAM)msg);
				SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)msg);
				SendMessageW(hwnd, EM_SETSEL, lstrlenW(msg), lstrlenW(msg));
				HeapFree(GetProcessHeap(), 0, msg);
			    } else {
				SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)This->txtbackup);
				SendMessageW(hwnd, EM_SETSEL, lstrlenW(This->txtbackup), lstrlenW(This->txtbackup));
			    }			
			} 		
			return 0;
		    }
		    break;
		case VK_BACK:
		case VK_DELETE:
		    if ((! *hwndText) && (This->options & ACO_AUTOSUGGEST)) {
			ShowWindow(This->hwndListBox, SW_HIDE);
			return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
		    }
		    if (This->options & ACO_AUTOAPPEND) {
			DWORD b;
                        SendMessageW(hwnd, EM_GETSEL, (WPARAM)&b, 0);
			if (b>1) {
			    hwndText[b-1] = '\0';
			} else {
			    hwndText[0] = '\0';
			    SetWindowTextW(hwnd, hwndText); 
			}			
		    }
		    break;
		default:		    
		    ;
	    }
      
	    SendMessageW(This->hwndListBox, LB_RESETCONTENT, 0, 0);

	    HeapFree(GetProcessHeap(), 0, This->txtbackup);
	    This->txtbackup = HeapAlloc(GetProcessHeap(),
						 HEAP_ZERO_MEMORY, (lstrlenW(hwndText)+1)*sizeof(WCHAR));							      
	    lstrcpyW(This->txtbackup, hwndText);

	    /* Returns if there is no text to search and we doesn't want to display all the entries */
	    if ((!displayall) && (! *hwndText) )
		break;
	    
	    IEnumString_Reset(This->enumstr);
	    filled = FALSE;
	    for(cpt = 0;;) {
	        ULONG fetched;
		hr = IEnumString_Next(This->enumstr, 1, &strs, &fetched);
		if (hr != S_OK)
		    break;

		if (strstrW(strs, hwndText) == strs) {
                    if (!filled && (This->options & ACO_AUTOAPPEND)) {
			SetWindowTextW(hwnd, strs);
			SendMessageW(hwnd, EM_SETSEL, lstrlenW(hwndText), lstrlenW(strs));
                        if (!(This->options & ACO_AUTOSUGGEST))
                            break;
		    }		

		    if (This->options & ACO_AUTOSUGGEST) {
			SendMessageW(This->hwndListBox, LB_ADDSTRING, 0, (LPARAM)strs);
			cpt++;
		    }

                    filled = TRUE;
		}		
	    }
	    
	    if (This->options & ACO_AUTOSUGGEST) {
		if (filled) {
		    height = SendMessageW(This->hwndListBox, LB_GETITEMHEIGHT, 0, 0);
		    SendMessageW(This->hwndListBox, LB_CARETOFF, 0, 0);
		    GetWindowRect(hwnd, &r);
		    SetParent(This->hwndListBox, HWND_DESKTOP);
		    /* It seems that Windows XP displays 7 lines at most 
		       and otherwise displays a vertical scroll bar */
		    SetWindowPos(This->hwndListBox, HWND_TOP, 
				 r.left, r.bottom + 1, r.right - r.left, min(height * 7, height*(cpt+1)), 
				 SWP_SHOWWINDOW );
		} else {
		    ShowWindow(This->hwndListBox, SW_HIDE);
		}
	    }
	    
	    break;
	case WM_DESTROY:
	{
	    WNDPROC proc = This->wpOrigEditProc;

	    RemovePropW(hwnd, autocomplete_propertyW);
	    SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)proc);
	    This->hwndEdit = NULL;
	    if (This->hwndListBox)
		    DestroyWindow(This->hwndListBox);
	    IAutoComplete2_Release((IAutoComplete2 *)This);
	    return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam);
	}
	default:
	    return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
	    
    }

    return 0;
}
예제 #18
0
파일: xmlview.c 프로젝트: RareHare/reactos
static inline HRESULT handle_xml_load(BindStatusCallback *This)
{
    static const WCHAR selectW[] = {'p','r','o','c','e','s','s','i','n','g','-',
        'i','n','s','t','r','u','c','t','i','o','n','(','\'','x','m','l',
        '-','s','t','y','l','e','s','h','e','e','t','\'',')',0};
    static const WCHAR hrefW[] = {'h','r','e','f','=',0};

    IXMLDOMDocument3 *xml = NULL, *xsl = NULL;
    IXMLDOMNode *stylesheet;
    IBindCtx *pbc;
    IMoniker *mon;
    LPOLESTR xsl_url;
    LARGE_INTEGER off;
    VARIANT_BOOL succ;
    VARIANT var;
    WCHAR *href = NULL, *p;
    BSTR bstr;
    HRESULT hres;

    off.QuadPart = 0;
    hres = IStream_Seek(This->stream, off, STREAM_SEEK_SET, NULL);
    if(FAILED(hres))
        return display_error_page(This);

    hres = DOMDocument_create(MSXML_DEFAULT, NULL, (void**)&xml);
    if(FAILED(hres))
        return display_error_page(This);

    V_VT(&var) = VT_UNKNOWN;
    V_UNKNOWN(&var) = (IUnknown*)This->stream;
    hres = IXMLDOMDocument3_load(xml, var, &succ);
    if(FAILED(hres) || !succ) {
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }
    V_VT(&var) = VT_EMPTY;

    bstr = SysAllocString(selectW);
    hres = IXMLDOMDocument3_selectSingleNode(xml, bstr, &stylesheet);
    SysFreeString(bstr);
    if(hres != S_OK) {
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    hres = IXMLDOMNode_get_nodeValue(stylesheet, &var);
    IXMLDOMNode_Release(stylesheet);
    if(SUCCEEDED(hres) && V_VT(&var)!=VT_BSTR) {
        FIXME("Variant type %d not supported\n", V_VT(&var));
        VariantClear(&var);
        hres = E_FAIL;
    }
    if(FAILED(hres)) {
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    /* TODO: fix parsing processing instruction value */
    if((p = strstrW(V_BSTR(&var), hrefW))) {
        p += sizeof(hrefW)/sizeof(WCHAR)-1;
        if(*p!='\'' && *p!='\"') p = NULL;
        else {
            href = p+1;
            p = strchrW(href, *p);
        }
    }
    if(p) {
        *p = 0;
    } else {
        VariantClear(&var);
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    hres = CreateURLMonikerEx(This->mon, href, &mon, 0);
    VariantClear(&var);
    if(FAILED(hres)) {
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    hres = CreateBindCtx(0, &pbc);
    if(SUCCEEDED(hres)) {
        hres = IMoniker_GetDisplayName(mon, pbc, NULL, &xsl_url);
        IMoniker_Release(mon);
        IBindCtx_Release(pbc);
    }
    if(FAILED(hres)) {
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    V_VT(&var) = VT_BSTR;
    V_BSTR(&var) = SysAllocString(xsl_url);
    CoTaskMemFree(xsl_url);
    if(!V_BSTR(&var)) {
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    hres = DOMDocument_create(MSXML_DEFAULT, NULL, (void**)&xsl);
    if(FAILED(hres)) {
        VariantClear(&var);
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    /* TODO: do the binding asynchronously */
    hres = IXMLDOMDocument3_load(xsl, var, &succ);
    VariantClear(&var);
    if(FAILED(hres) || !succ) {
        IXMLDOMDocument3_Release(xsl);
        IXMLDOMDocument3_Release(xml);
        return display_error_page(This);
    }

    hres = IXMLDOMDocument3_transformNode(xml, (IXMLDOMNode*)xsl, &bstr);
    IXMLDOMDocument3_Release(xsl);
    IXMLDOMDocument3_Release(xml);
    if(FAILED(hres))
        return display_error_page(This);

    hres = IStream_Seek(This->stream, off, STREAM_SEEK_SET, NULL);
    if(FAILED(hres)) {
        SysFreeString(bstr);
        return display_error_page(This);
    }

    hres = IStream_Write(This->stream, (BYTE*)bstr,
            SysStringLen(bstr)*sizeof(WCHAR), NULL);
    SysFreeString(bstr);
    if(FAILED(hres))
        return display_error_page(This);

    return report_data(This);
}
예제 #19
0
파일: string.c 프로젝트: jre-wine/wine
/* ECMA-262 3rd Edition    15.5.4.11 */
static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                              jsval_t *r)
{
    const WCHAR *str, *match_str = NULL, *rep_str = NULL;
    jsstr_t *rep_jsstr, *match_jsstr, *jsstr;
    jsdisp_t *rep_func = NULL, *regexp = NULL;
    match_state_t *match = NULL, last_match = {0};
    strbuf_t ret = {NULL,0,0};
    DWORD re_flags = REM_NO_CTX_UPDATE|REM_ALLOC_RESULT;
    DWORD rep_len=0;
    HRESULT hres = S_OK;

    TRACE("\n");

    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
    if(FAILED(hres))
        return hres;

    if(!argc) {
        if(r)
            *r = jsval_string(jsstr);
        else
            jsstr_release(jsstr);
        return S_OK;
    }

    if(is_object_instance(argv[0])) {
        regexp = iface_to_jsdisp(get_object(argv[0]));
        if(regexp && !is_class(regexp, JSCLASS_REGEXP)) {
            jsdisp_release(regexp);
            regexp = NULL;
        }
    }

    if(!regexp) {
        hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
        if(FAILED(hres)) {
            jsstr_release(jsstr);
            return hres;
        }
    }

    if(argc >= 2) {
        if(is_object_instance(argv[1])) {
            rep_func = iface_to_jsdisp(get_object(argv[1]));
            if(rep_func && !is_class(rep_func, JSCLASS_FUNCTION)) {
                jsdisp_release(rep_func);
                rep_func = NULL;
            }
        }

        if(!rep_func) {
            hres = to_flat_string(ctx, argv[1], &rep_jsstr, &rep_str);
            if(SUCCEEDED(hres))
                rep_len = jsstr_length(rep_jsstr);
        }
    }

    if(SUCCEEDED(hres)) {
        const WCHAR *ecp = str;

        while(1) {
            if(regexp) {
                hres = regexp_match_next(ctx, regexp, re_flags, jsstr, &match);
                re_flags = (re_flags | REM_CHECK_GLOBAL) & (~REM_ALLOC_RESULT);

                if(hres == S_FALSE) {
                    hres = S_OK;
                    break;
                }
                if(FAILED(hres))
                    break;

                last_match.cp = match->cp;
                last_match.match_len = match->match_len;
            } else {
                if(re_flags & REM_ALLOC_RESULT) {
                    re_flags &= ~REM_ALLOC_RESULT;
                    match = &last_match;
                    match->cp = str;
                }

                match->cp = strstrW(match->cp, match_str);
                if(!match->cp)
                    break;
                match->match_len = jsstr_length(match_jsstr);
                match->cp += match->match_len;
            }

            hres = strbuf_append(&ret, ecp, match->cp-ecp-match->match_len);
            ecp = match->cp;
            if(FAILED(hres))
                break;

            if(rep_func) {
                jsstr_t *cstr;

                hres = rep_call(ctx, rep_func, jsstr, str, match, &cstr);
                if(FAILED(hres))
                    break;

                hres = strbuf_append_jsstr(&ret, cstr);
                jsstr_release(cstr);
                if(FAILED(hres))
                    break;
            } else if(rep_str && regexp) {
                const WCHAR *ptr = rep_str, *ptr2;

                while((ptr2 = strchrW(ptr, '$'))) {
                    hres = strbuf_append(&ret, ptr, ptr2-ptr);
                    if(FAILED(hres))
                        break;

                    switch(ptr2[1]) {
                    case '$':
                        hres = strbuf_append(&ret, ptr2, 1);
                        ptr = ptr2+2;
                        break;
                    case '&':
                        hres = strbuf_append(&ret, match->cp-match->match_len, match->match_len);
                        ptr = ptr2+2;
                        break;
                    case '`':
                        hres = strbuf_append(&ret, str, match->cp-str-match->match_len);
                        ptr = ptr2+2;
                        break;
                    case '\'':
                        hres = strbuf_append(&ret, ecp, (str+jsstr_length(jsstr))-ecp);
                        ptr = ptr2+2;
                        break;
                    default: {
                        DWORD idx;

                        if(!isdigitW(ptr2[1])) {
                            hres = strbuf_append(&ret, ptr2, 1);
                            ptr = ptr2+1;
                            break;
                        }

                        idx = ptr2[1] - '0';
                        if(isdigitW(ptr2[2]) && idx*10 + (ptr2[2]-'0') <= match->paren_count) {
                            idx = idx*10 + (ptr[2]-'0');
                            ptr = ptr2+3;
                        } else if(idx && idx <= match->paren_count) {
                            ptr = ptr2+2;
                        } else {
                            hres = strbuf_append(&ret, ptr2, 1);
                            ptr = ptr2+1;
                            break;
                        }

                        if(match->parens[idx-1].index != -1)
                            hres = strbuf_append(&ret, str+match->parens[idx-1].index,
                                                 match->parens[idx-1].length);
                    }
                    }

                    if(FAILED(hres))
                        break;
                }

                if(SUCCEEDED(hres))
                    hres = strbuf_append(&ret, ptr, (rep_str+rep_len)-ptr);
                if(FAILED(hres))
                    break;
            } else if(rep_str) {
                hres = strbuf_append(&ret, rep_str, rep_len);
                if(FAILED(hres))
                    break;
            } else {
                static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d'};

                hres = strbuf_append(&ret, undefinedW, sizeof(undefinedW)/sizeof(WCHAR));
                if(FAILED(hres))
                    break;
            }

            if(!regexp)
                break;
            else if(!match->match_len)
                match->cp++;
        }

        if(SUCCEEDED(hres))
            hres = strbuf_append(&ret, ecp, str+jsstr_length(jsstr)-ecp);
    }

    if(rep_func)
        jsdisp_release(rep_func);
    if(rep_str)
        jsstr_release(rep_jsstr);
    if(match_str)
        jsstr_release(match_jsstr);
    if(regexp)
        heap_free(match);

    if(SUCCEEDED(hres) && last_match.cp && regexp) {
        jsstr_release(ctx->last_match);
        ctx->last_match = jsstr_addref(jsstr);
        ctx->last_match_index = last_match.cp-str-last_match.match_len;
        ctx->last_match_length = last_match.match_len;
    }

    if(regexp)
        jsdisp_release(regexp);
    jsstr_release(jsstr);

    if(SUCCEEDED(hres) && r) {
        jsstr_t *ret_str;

        ret_str = jsstr_alloc_len(ret.buf, ret.len);
        if(!ret_str)
            return E_OUTOFMEMORY;

        TRACE("= %s\n", debugstr_jsstr(ret_str));
        *r = jsval_string(ret_str);
    }

    heap_free(ret.buf);
    return hres;
}
예제 #20
0
파일: string.c 프로젝트: francissabado/wine
/**************************************************************************
 * StrStrW [COMCTL32.362]
 *
 * See StrStrA.
 */
LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
{
    if (!lpszStr || !lpszSearch) return NULL;
    return strstrW( lpszStr, lpszSearch );
}
예제 #21
0
/*** IDataInitialize methods ***/
static HRESULT WINAPI datainit_GetDataSource(IDataInitialize *iface, IUnknown *outer, DWORD clsctx,
                                LPWSTR initstring, REFIID riid, IUnknown **datasource)
{
    static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r','=',0};
    static const WCHAR msdasqlW[] = {'M','S','D','A','S','Q','L',0};
    datainit *This = impl_from_IDataInitialize(iface);
    IDBProperties *dbprops;
    DBPROPSET *propset;
    WCHAR *prov = NULL;
    CLSID provclsid;
    HRESULT hr;

    TRACE("(%p)->(%p 0x%x %s %s %p)\n", This, outer, clsctx, debugstr_w(initstring), debugstr_guid(riid), datasource);

    /* first get provider name */
    provclsid = IID_NULL;
    if (initstring && (prov = strstrW(initstring, providerW)))
    {
        WCHAR *start, *progid;
        int len;

        prov += sizeof(providerW)/sizeof(WCHAR)-1;
        start = prov;
        while (*prov && *prov != ';')
            ++prov;
        TRACE("got provider %s\n", debugstr_wn(start, prov-start));

        len = prov - start;
        progid = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
        if (!progid) return E_OUTOFMEMORY;

        memcpy(progid, start, len*sizeof(WCHAR));
        progid[len] = 0;

        hr = CLSIDFromProgID(progid, &provclsid);
        CoTaskMemFree(progid);
        if (FAILED(hr))
        {
            ERR("provider %s not registered\n", debugstr_wn(start, prov-start));
            return hr;
        }
    }
    else
    {
        hr = CLSIDFromProgID(msdasqlW, &provclsid);
        if (FAILED(hr))
            ERR("ODBC provider for OLE DB not registered\n");
    }

    /* check for provider mismatch if it was specified in init string */
    if (*datasource && prov)
    {
        DBPROPIDSET propidset;
        enum DBPROPENUM prop;
        CLSID initprov;
        ULONG count;

        hr = IUnknown_QueryInterface(*datasource, &IID_IDBProperties, (void**)&dbprops);
        if (FAILED(hr))
        {
            WARN("provider doesn't support IDBProperties\n");
            return hr;
        }

        prop = DBPROP_INIT_DATASOURCE;
        propidset.rgPropertyIDs = &prop;
        propidset.cPropertyIDs = 1;
        propidset.guidPropertySet = DBPROPSET_DBINIT;
        count = 0;
        propset = NULL;
        hr = IDBProperties_GetProperties(dbprops, 1, &propidset, &count, &propset);
        IDBProperties_Release(dbprops);
        if (FAILED(hr))
        {
            WARN("GetProperties failed for datasource, 0x%08x\n", hr);
            return hr;
        }

        TRACE("initial data source provider %s\n", debugstr_w(V_BSTR(&propset->rgProperties[0].vValue)));
        initprov = IID_NULL;
        CLSIDFromProgID(V_BSTR(&propset->rgProperties[0].vValue), &initprov);
        free_dbpropset(count, propset);

        if (!IsEqualIID(&provclsid, &initprov)) return DB_E_MISMATCHEDPROVIDER;
    }

    if (!*datasource)
    {
        if (!IsEqualIID(&provclsid, &IID_NULL))
            hr = CoCreateInstance(&provclsid, outer, clsctx, riid, (void**)datasource);

        if (FAILED(hr) && IsEqualIID(riid, &IID_IDBInitialize))
            hr = create_db_init((void**)datasource);
    }

    /* now set properties */
    if (initstring)
    {
        WCHAR *eq, *start;

        hr = IUnknown_QueryInterface(*datasource, &IID_IDBProperties, (void**)&dbprops);
        if (FAILED(hr))
        {
            WARN("provider doesn't support IDBProperties\n");
            return hr;
        }

        start = initstring;
        while (start && (eq = strchrW(start, '=')))
        {
            static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r',0};
            WCHAR *scol = strchrW(eq+1, ';');
            BSTR value, name;

            name = SysAllocStringLen(start, eq - start);
            /* skip equal sign to get value */
            eq++;
            value = SysAllocStringLen(eq, scol ? scol - eq : -1);

            /* skip semicolon if present */
            if (scol) scol++;
            start = scol;

            if (!strcmpW(name, providerW))
            {
                SysFreeString(name);
                SysFreeString(value);
                continue;
            }

            TRACE("property (name=%s, value=%s)\n", debugstr_w(name), debugstr_w(value));

            hr = set_dbpropset(name, value, &propset);
            SysFreeString(name);
            SysFreeString(value);
            if (FAILED(hr)) return hr;

            hr = IDBProperties_SetProperties(dbprops, 1, propset);
            free_dbpropset(1, propset);
            TRACE("provider ret 0x%08x\n", hr);
        }

        IDBProperties_Release(dbprops);
    }

    return hr;
}
예제 #22
0
파일: hhctrl.c 프로젝트: r6144/wine
/******************************************************************
 *		HtmlHelpW (HHCTRL.OCX.15)
 */
HWND WINAPI HtmlHelpW(HWND caller, LPCWSTR filename, UINT command, DWORD_PTR data)
{
    WCHAR fullname[MAX_PATH];

    TRACE("(%p, %s, command=%s, data=%lx)\n",
          caller, debugstr_w( filename ),
          command_to_string( command ), data);

    switch (command)
    {
    case HH_DISPLAY_TOPIC:
    case HH_DISPLAY_TOC:
    case HH_DISPLAY_SEARCH:{
        static const WCHAR delimW[] = {':',':',0};
        HHInfo *info;
        BOOL res;
        WCHAR chm_file[MAX_PATH];
        const WCHAR *index;

        FIXME("Not all HH cases handled correctly\n");

        if (!filename)
            return NULL;

        index = strstrW(filename, delimW);
        if (index)
        {
            memcpy(chm_file, filename, (index-filename)*sizeof(WCHAR));
            chm_file[index-filename] = 0;
            filename = chm_file;
            index += 2; /* advance beyond "::" for calling NavigateToChm() later */
        }

        if (!resolve_filename(filename, fullname, MAX_PATH))
        {
            WARN("can't find %s\n", debugstr_w(filename));
            return 0;
        }

        info = CreateHelpViewer(fullname);
        if(!info)
            return NULL;

        if(!index)
            index = info->WinType.pszFile;

        res = NavigateToChm(info, info->pCHMInfo->szFile, index);
        if(!res)
        {
            ReleaseHelpViewer(info);
            return NULL;
        }
        return info->WinType.hwndHelp;
    }
    case HH_HELP_CONTEXT: {
        HHInfo *info;
        LPWSTR url;

        if (!filename)
            return NULL;

        if (!resolve_filename(filename, fullname, MAX_PATH))
        {
            WARN("can't find %s\n", debugstr_w(filename));
            return 0;
        }

        info = CreateHelpViewer(fullname);
        if(!info)
            return NULL;

        url = FindContextAlias(info->pCHMInfo, data);
        if(!url)
        {
            ReleaseHelpViewer(info);
            return NULL;
        }

        NavigateToUrl(info, url);
        heap_free(url);
        return info->WinType.hwndHelp;
    }
    case HH_PRETRANSLATEMESSAGE: {
        static BOOL warned = FALSE;

        if (!warned)
        {
            FIXME("HH_PRETRANSLATEMESSAGE unimplemented\n");
            warned = TRUE;
        }
        return 0;
    }
    default:
        FIXME("HH case %s not handled.\n", command_to_string( command ));
    }

    return 0;
}
예제 #23
0
파일: wcstring.c 프로젝트: AmesianX/RosWine
/*********************************************************************
 *           wcsstr    (NTDLL.@)
 */
LPWSTR __cdecl NTDLL_wcsstr( LPCWSTR str, LPCWSTR sub )
{
    return strstrW( str, sub );
}
예제 #24
0
파일: main.c 프로젝트: Strongc/reactos
static void test_OleUIAddVerbMenu(void)
{
    HMENU hMenu, verbmenu;
    MENUITEMINFOW info;
    WCHAR buffW[50];
    int count;
    BOOL ret;

    ret = OleUIAddVerbMenuW(NULL, NULL, NULL, 0, 0, 0, FALSE, 0, NULL);
    ok(!ret, "got %d\n", ret);

    verbmenu = (HMENU)0xdeadbeef;
    ret = OleUIAddVerbMenuW(NULL, NULL, NULL, 0, 0, 0, FALSE, 0, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, NULL, 0, 0, 0, FALSE, 0, NULL);
    ok(!ret, "got %d\n", ret);

    hMenu = CreatePopupMenu();

    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    ret = InsertMenuItemW(hMenu, 0, TRUE, &info);
    ok(ret, "got %d\n", ret);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 0, 0, 0, FALSE, 0, NULL);
    ok(!ret, "got %d\n", ret);

    count = GetMenuItemCount(hMenu);
    ok(count == 1, "got %d\n", count);

    ret = InsertMenuItemW(hMenu, 0, TRUE, &info);
    ok(ret, "got %d\n", ret);

    count = GetMenuItemCount(hMenu);
    ok(count == 2, "got %d\n", count);

    verbmenu = (HMENU)0xdeadbeef;
    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 1, 0, 0, FALSE, 0, &verbmenu);
    ok(ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 2, "got %d\n", count);

    /* object doesn't support EnumVerbs() */
    g_enumverbsfail = TRUE;
    g_enumpos = 0;
    verbmenu = (HMENU)0xdeadbeef;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 2, 0, 0, FALSE, 0, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);
    g_enumverbsfail = FALSE;

    /* added disabled item */
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STATE|MIIM_SUBMENU;
    ret = GetMenuItemInfoW(hMenu, 2, TRUE, &info);
    ok(ret, "got %d\n", ret);
    ok(info.fState & MFS_DISABLED, "got state 0x%08x\n", info.fState);
    ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 3, "got %d\n", count);

    /* now without object */
    verbmenu = (HMENU)0xdeadbeef;
    ret = OleUIAddVerbMenuW(NULL, testW, hMenu, 3, 42, 0, FALSE, 0, &verbmenu);
    ok(!ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STATE|MIIM_ID|MIIM_STRING|MIIM_SUBMENU;
    info.dwTypeData = buffW;
    info.cch = sizeof(buffW)/sizeof(WCHAR);
    ret = GetMenuItemInfoW(hMenu, 3, TRUE, &info);
    ok(ret, "got %d\n", ret);
    ok(info.fState == MF_GRAYED, "got state 0x%08x\n", info.fState);
    ok(info.wID == 42, "got id %d\n", info.wID);
    ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 4, "got %d\n", count);

    verbmenu = (HMENU)0xdeadbeef;
    g_enumpos = 0;
    ret = OleUIAddVerbMenuW(&oleobject, NULL, hMenu, 4, 0, 0, FALSE, 0, &verbmenu);
    ok(ret, "got %d\n", ret);
    ok(verbmenu == NULL, "got %p\n", verbmenu);

    /* check newly added item */
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STRING|MIIM_STATE|MIIM_SUBMENU;
    info.dwTypeData = buffW;
    info.cch = sizeof(buffW)/sizeof(WCHAR);
    ret = GetMenuItemInfoW(hMenu, 4, TRUE, &info);
    ok(ret, "got %d\n", ret);
    /* Item string contains verb, usertype and localized string for 'Object' word,
       exact format depends on localization. */
    ok(strstrW(buffW, verbW) != NULL, "str %s\n", wine_dbgstr_w(buffW));
    ok(info.fState == 0, "got state 0x%08x\n", info.fState);
    ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);

    count = GetMenuItemCount(hMenu);
    ok(count == 5, "got %d\n", count);

    DestroyMenu(hMenu);
}
예제 #25
0
void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HANDLE pgmHandle) {

#define WCMD_BATCH_EXT_SIZE 5

  HANDLE h = INVALID_HANDLE_VALUE;
  WCHAR string[MAXSTRING];
  static const WCHAR extension_batch[][WCMD_BATCH_EXT_SIZE] = {{'.','b','a','t','\0'},
                                                               {'.','c','m','d','\0'}};
  static const WCHAR extension_exe[WCMD_BATCH_EXT_SIZE] = {'.','e','x','e','\0'};
  unsigned int  i;
  BATCH_CONTEXT *prev_context;

  if (startLabel == NULL) {
    for(i=0; (i<sizeof(extension_batch)/(WCMD_BATCH_EXT_SIZE * sizeof(WCHAR))) &&
             (h == INVALID_HANDLE_VALUE); i++) {
      strcpyW (string, file);
      CharLower (string);
      if (strstrW (string, extension_batch[i]) == NULL) strcatW (string, extension_batch[i]);
      h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ,
                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    }
    if (h == INVALID_HANDLE_VALUE) {
      strcpyW (string, file);
      CharLower (string);
      if (strstrW (string, extension_exe) == NULL) strcatW (string, extension_exe);
      if (GetFileAttributes (string) != INVALID_FILE_ATTRIBUTES) {
        WCMD_run_program (command, 0);
      } else {
        SetLastError (ERROR_FILE_NOT_FOUND);
        WCMD_print_error ();
      }
      return;
    }
  } else {
    DuplicateHandle(GetCurrentProcess(), pgmHandle,
                    GetCurrentProcess(), &h,
                    0, FALSE, DUPLICATE_SAME_ACCESS);
  }

/*
 *	Create a context structure for this batch file.
 */

  prev_context = context;
  context = (BATCH_CONTEXT *)LocalAlloc (LMEM_FIXED, sizeof (BATCH_CONTEXT));
  context -> h = h;
  context -> command = command;
  memset(context -> shift_count, 0x00, sizeof(context -> shift_count));
  context -> prev_context = prev_context;
  context -> skip_rest = FALSE;

  /* If processing a call :label, 'goto' the label in question */
  if (startLabel) {
    strcpyW(param1, startLabel);
    WCMD_goto(NULL);
  }

/*
 * 	Work through the file line by line. Specific batch commands are processed here,
 * 	the rest are handled by the main command processor.
 */

  while (context -> skip_rest == FALSE) {
      CMD_LIST *toExecute = NULL;         /* Commands left to be executed */
      if (WCMD_ReadAndParseLine(NULL, &toExecute, h) == NULL)
        break;
      WCMD_process_commands(toExecute, FALSE, NULL, NULL);
      WCMD_free_commands(toExecute);
      toExecute = NULL;
  }
  CloseHandle (h);

/*
 *	If invoked by a CALL, we return to the context of our caller. Otherwise return
 *	to the caller's caller.
 */

  LocalFree ((HANDLE)context);
  if ((prev_context != NULL) && (!called)) {
    prev_context -> skip_rest = TRUE;
    context = prev_context;
  }
  context = prev_context;
}
예제 #26
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                            jsval_t *r)
{
    match_state_t match_result, *match_ptr = &match_result;
    DWORD length, i, match_len = 0;
    const WCHAR *ptr, *ptr2, *str, *match_str = NULL;
    unsigned limit = ~0u;
    jsdisp_t *array, *regexp = NULL;
    jsstr_t *jsstr, *match_jsstr, *tmp_str;
    HRESULT hres;

    TRACE("\n");

    if(argc != 1 && argc != 2) {
        FIXME("unsupported argc %u\n", argc);
        return E_NOTIMPL;
    }

    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
    if(FAILED(hres))
        return hres;

    length = jsstr_length(jsstr);

    if(argc > 1 && !is_undefined(argv[1])) {
        hres = to_uint32(ctx, argv[1], &limit);
        if(FAILED(hres)) {
            jsstr_release(jsstr);
            return hres;
        }
    }

    if(is_object_instance(argv[0])) {
        regexp = iface_to_jsdisp(get_object(argv[0]));
        if(regexp) {
            if(!is_class(regexp, JSCLASS_REGEXP)) {
                jsdisp_release(regexp);
                regexp = NULL;
            }
        }
    }

    if(!regexp) {
        hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
        if(FAILED(hres)) {
            jsstr_release(jsstr);
            return hres;
        }

        match_len = jsstr_length(match_jsstr);
        if(!match_len) {
            jsstr_release(match_jsstr);
            match_str = NULL;
        }
    }

    hres = create_array(ctx, 0, &array);

    if(SUCCEEDED(hres)) {
        ptr = str;
        match_result.cp = str;
        for(i=0; i<limit; i++) {
            if(regexp) {
                hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, jsstr, &match_ptr);
                if(hres != S_OK)
                    break;
                ptr2 = match_result.cp - match_result.match_len;
            } else if(match_str) {
                ptr2 = strstrW(ptr, match_str);
                if(!ptr2)
                    break;
            } else {
                if(!*ptr)
                    break;
                ptr2 = ptr+1;
            }

            tmp_str = jsstr_alloc_len(ptr, ptr2-ptr);
            if(!tmp_str) {
                hres = E_OUTOFMEMORY;
                break;
            }

            hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str));
            jsstr_release(tmp_str);
            if(FAILED(hres))
                break;

            if(regexp)
                ptr = match_result.cp;
            else if(match_str)
                ptr = ptr2 + match_len;
            else
                ptr++;
        }
    }

    if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
        DWORD len = (str+length) - ptr;

        if(len || match_str) {
            tmp_str = jsstr_alloc_len(ptr, len);

            if(tmp_str) {
                hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str));
                jsstr_release(tmp_str);
            } else {
                hres = E_OUTOFMEMORY;
            }
        }
    }

    if(regexp)
        jsdisp_release(regexp);
    if(match_str)
        jsstr_release(match_jsstr);
    jsstr_release(jsstr);

    if(SUCCEEDED(hres) && r)
        *r = jsval_obj(array);
    else
        jsdisp_release(array);

    return hres;
}