/*
 *  call-seq:
 *     WIN32OLE.connect( ole ) --> aWIN32OLE
 * 
 *  Returns running OLE Automation object or WIN32OLE object from moniker.
 *  1st argument should be OLE program id or class id or moniker.
 *     
 *     WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.
 */
static VALUE
fole_s_connect(argc, argv, self)
    int argc;
    VALUE *argv;
    VALUE self;
{
    VALUE svr_name;
    VALUE others;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    IDispatch *pDispatch;
    IUnknown *pUnknown;
    rb_secure(4);
    /* initialize to use OLE */
    ole_initialize();
    rb_scan_args(argc, argv, "1*", &svr_name, &others);
    if (ruby_safe_level > 0 && OBJ_TAINTED(svr_name)) {
        rb_raise(rb_eSecurityError, "Insecure Object Connection - %s",
                 StringValuePtr(svr_name));
    }
    /* get CLSID from OLE server name */
    pBuf  = ole_mb2wc(StringValuePtr(svr_name), -1);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        return ole_bind_obj(svr_name, argc, argv, self);
    }
    hr = GetActiveObject(&clsid, 0, &pUnknown);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, 
                  "OLE server `%s' not running", StringValuePtr(svr_name));
    }
    hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch,
                                             (void **)&pDispatch);
    if(FAILED(hr)) {
        OLE_RELEASE(pUnknown);
        ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, 
                  "failed to create WIN32OLE server `%s'", 
                  StringValuePtr(svr_name));
    }
    OLE_RELEASE(pUnknown);
    return create_win32ole_object(self, pDispatch, argc, argv);
}