Project

General

Profile

Feature #14348 ยป 0001-win32ole-Enable-COM-classes-with-multiple-IDispatch.patch

graywolf (Gray Wolf), 01/10/2018 11:31 AM

View differences:

ext/win32ole/win32ole.c
2392 2392
    return Qnil;
2393 2393
}
2394 2394

  
2395
static HRESULT str_to_clsid(VALUE str, CLSID * clsid)
2396
{
2397
    OLECHAR *pBuf;
2398
    HRESULT hr;
2399

  
2400
    pBuf  = ole_vstr2wc(str);
2401
    hr = CLSIDFromProgID(pBuf, clsid);
2402
    if(FAILED(hr)) {
2403
        hr = CLSIDFromString(pBuf, clsid);
2404
    }
2405
    SysFreeString(pBuf);
2406
    return hr;
2407
}
2408

  
2395 2409
/*
2396 2410
 * Document-class: WIN32OLE
2397 2411
 *
......
2443 2457
 *  call-seq:
2444 2458
 *     WIN32OLE.new(server, [host]) -> WIN32OLE object
2445 2459
 *     WIN32OLE.new(server, license: 'key') -> WIN32OLE object
2460
 *     WIN32OLE.new(server, iface: '{00000000-0000-0000-0000-000000000000}') -> WIN32OLE object
2446 2461
 *
2447 2462
 *  Returns a new WIN32OLE object(OLE Automation object).
2448 2463
 *  The first argument server specifies OLE Automation server.
......
2452 2467
 *  If :license keyword argument is provided,
2453 2468
 *  IClassFactory2::CreateInstanceLic is used to create instance of
2454 2469
 *  licensed server.
2470
 *  If :iface keyword argument (GUID) is provided,
2471
 *  that interface is retrieved instead of IDispatch. But it must
2472
 *  also inherit from IDispatch. In 99.999% cases you don't need this.
2455 2473
 *
2456 2474
 *      WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
2457 2475
 *      WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.
......
2464 2482
    VALUE others;
2465 2483
    VALUE opts;
2466 2484
    HRESULT hr;
2467
    CLSID   clsid;
2468
    OLECHAR *pBuf;
2485
    CLSID clsid;
2486
    CLSID iface;
2469 2487
    OLECHAR *key_buf;
2470 2488
    IDispatch *pDispatch;
2471 2489
    IClassFactory2 * pIClassFactory2;
2472 2490
    void *p;
2473
    static ID keyword_ids[1];
2474
    VALUE kwargs[1];
2491
    static ID keyword_ids[2];
2492
    VALUE kwargs[2];
2475 2493

  
2476 2494
    rb_call_super(0, 0);
2477 2495
    rb_scan_args(argc, argv, "11*:", &svr_name, &host, &others, &opts);
......
2491 2509
    }
2492 2510

  
2493 2511
    /* get CLSID from OLE server name */
2494
    pBuf  = ole_vstr2wc(svr_name);
2495
    hr = CLSIDFromProgID(pBuf, &clsid);
2496
    if(FAILED(hr)) {
2497
        hr = CLSIDFromString(pBuf, &clsid);
2498
    }
2499
    SysFreeString(pBuf);
2512
    hr = str_to_clsid(svr_name, &clsid);
2500 2513
    if(FAILED(hr)) {
2501 2514
        ole_raise(hr, eWIN32OLERuntimeError,
2502 2515
                  "unknown OLE server: `%s'",
......
2505 2518

  
2506 2519
    if (!keyword_ids[0]) {
2507 2520
        keyword_ids[0] = rb_intern_const("license");
2521
        keyword_ids[1] = rb_intern_const("iface");
2522
    }
2523
    rb_get_kwargs(opts, keyword_ids, 0, 2, kwargs);
2524

  
2525
    if (kwargs[1] == Qundef) {
2526
	iface = IID_IDispatch;
2527
    } else {
2528
	hr = str_to_clsid(kwargs[1], &iface);
2529
	if (FAILED(hr)) {
2530
	    ole_raise(
2531
		hr,
2532
		eWIN32OLERuntimeError,
2533
		"unknown interface: `%s'",
2534
		StringValuePtr(kwargs[1])
2535
	    );
2536
	}
2508 2537
    }
2509
    rb_get_kwargs(opts, keyword_ids, 0, 1, kwargs);
2510 2538

  
2511 2539
    if (kwargs[0] == Qundef) {
2512 2540
        /* get IDispatch interface */
......
2514 2542
            &clsid,
2515 2543
            NULL,
2516 2544
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
2517
            &IID_IDispatch,
2545
            &iface,
2518 2546
            &p
2519 2547
        );
2520 2548
    } else {
......
2527 2555
        );
2528 2556
        if (hr == S_OK) {
2529 2557
            key_buf = ole_vstr2wc(kwargs[0]);
2530
            hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2, NULL, NULL, &IID_IDispatch, key_buf, &p);
2558
            hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2, NULL, NULL, &iface, key_buf, &p);
2531 2559
            SysFreeString(key_buf);
2532 2560
            OLE_RELEASE(pIClassFactory2);
2533 2561
        }
......
4149 4177

  
4150 4178
    ole_init_cp();
4151 4179
}
4180

  
4181
/* vim: set ts=8 sw=4 noexpandtab: */
4152
-