~ubuntu-branches/ubuntu/intrepid/ruby1.9/intrepid-updates

« back to all changes in this revision

Viewing changes to ext/win32ole/win32ole.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-09-04 16:01:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20070904160117-i15zckg2nhxe9fyw
Tags: 1.9.0+20070830-2ubuntu1
* Sync from Debian; remaining changes:
  - Add -g to CFLAGS.
* Fixes build failure on ia64.
* Fixes build failure with gcc-4.2 on lpia.
* Robustify check for target_os, fixing build failure on lpia.
* Set Ubuntu maintainer address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 */
13
13
 
14
14
/*
15
 
  $Date: 2007-03-16 22:24:06 +0900 (金, 16  3月 2007) $
 
15
  $Date: 2007-08-28 19:23:31 +0900 (火, 28  8月 2007) $
16
16
  modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp>
17
17
 */
18
18
 
19
 
#include "ruby.h"
20
 
#include "st.h"
 
19
#include "ruby/ruby.h"
 
20
#include "ruby/st.h"
21
21
#include <ctype.h>
22
22
#include <windows.h>
23
23
#include <ocidl.h>
116
116
 
117
117
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
118
118
 
119
 
#define WIN32OLE_VERSION "1.0.2"
 
119
#define WIN32OLE_VERSION "1.0.7"
120
120
 
121
121
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
122
122
    (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
173
173
    DWORD m_dwCookie;
174
174
    IConnectionPoint *pConnectionPoint;
175
175
    ITypeInfo *pTypeInfo;
176
 
    int *ptr_freed;
177
176
}IEVENTSINKOBJ, *PIEVENTSINKOBJ;
178
177
 
179
178
VALUE cWIN32OLE;
230
229
};
231
230
 
232
231
struct oleeventdata {
233
 
    IEVENTSINKOBJ *pEvent;
234
232
    int freed;
235
233
};
236
234
 
770
768
    LPSTR pm;
771
769
    size = WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, NULL, 0, NULL, NULL);
772
770
    if (size) {
773
 
        pm = ALLOC_N(char, size);    
 
771
        pm = ALLOC_N(char, size + 1);    
774
772
        WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, pm, size, NULL, NULL);
 
773
        pm[size] = '\0';
775
774
    }
776
775
    else {
777
776
        pm = ALLOC_N(char, 1);
1076
1075
        val1 = ole_ary_m_entry(val, pid);
1077
1076
        p = val2variant_ptr(val1, &var, vt);
1078
1077
        if (is_all_index_under(pid, pub, dim) == Qtrue) {
1079
 
            if (V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL ||
1080
 
                V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL) {
 
1078
          if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
 
1079
              (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
1081
1080
                rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
1082
1081
            }
1083
1082
            hr = SafeArrayPutElement(psa, pid, p);
1915
1914
static VALUE
1916
1915
reg_enum_key(HKEY hkey, DWORD i)
1917
1916
{
1918
 
    char buf[BUFSIZ];
 
1917
    char buf[BUFSIZ + 1];
1919
1918
    DWORD size_buf = sizeof(buf);
1920
1919
    FILETIME ft;
1921
1920
    LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,
1922
1921
                            NULL, NULL, NULL, &ft);
1923
1922
    if(err == ERROR_SUCCESS) {
 
1923
        buf[BUFSIZ] = '\0';
1924
1924
        return rb_str_new2(buf);
1925
1925
    }
1926
1926
    return Qnil;
1929
1929
static VALUE
1930
1930
reg_get_val(HKEY hkey, const char *subkey)
1931
1931
{
1932
 
    char buf[BUFSIZ];
1933
 
    LONG size_buf = sizeof(buf);
1934
 
    LONG err = RegQueryValue(hkey, subkey, buf, &size_buf);
1935
 
    if (err == ERROR_SUCCESS) {
1936
 
        return rb_str_new2(buf);
1937
 
    }
1938
 
    return Qnil;
 
1932
    char *pbuf;
 
1933
    DWORD dwtype = 0;
 
1934
    LONG size = 0;
 
1935
    VALUE val = Qnil;
 
1936
    LONG err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, NULL, &size); 
 
1937
 
 
1938
    if (err == ERROR_SUCCESS) {
 
1939
        pbuf = ALLOC_N(char, size + 1);
 
1940
        err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, pbuf, &size);
 
1941
        if (err == ERROR_SUCCESS) {
 
1942
            pbuf[size] = '\0';
 
1943
            val = rb_str_new2(pbuf);
 
1944
        }
 
1945
        free(pbuf);
 
1946
    }
 
1947
    return val;
 
1948
}
 
1949
 
 
1950
static VALUE
 
1951
reg_get_val2(HKEY hkey, const char *subkey)
 
1952
{
 
1953
    HKEY hsubkey;
 
1954
    LONG err;
 
1955
    VALUE val = Qnil;
 
1956
    err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
 
1957
    if (err == ERROR_SUCCESS) {
 
1958
        val = reg_get_val(hsubkey, NULL);
 
1959
        RegCloseKey(hsubkey);
 
1960
    }
 
1961
    if (val == Qnil) {
 
1962
        val = reg_get_val(hkey, subkey);
 
1963
    }
 
1964
    return val;
1939
1965
}
1940
1966
 
1941
1967
static VALUE
1942
1968
reg_get_typelib_file_path(HKEY hkey)
1943
1969
{
1944
1970
    VALUE path = Qnil;
1945
 
    path = reg_get_val(hkey, "win32");
 
1971
    path = reg_get_val2(hkey, "win32");
1946
1972
    if (path == Qnil) {
1947
 
        path = reg_get_val(hkey, "win16");
 
1973
        path = reg_get_val2(hkey, "win16");
1948
1974
    }
1949
1975
    return path;
1950
1976
}
1952
1978
static VALUE
1953
1979
typelib_file_from_clsid(VALUE ole)
1954
1980
{
1955
 
    OLECHAR *pbuf;
1956
 
    CLSID clsid;
1957
 
    HRESULT hr;
1958
1981
    HKEY hroot, hclsid;
1959
1982
    LONG err;
1960
1983
    VALUE typelib;
1961
 
    VALUE vclsid;
 
1984
    char path[MAX_PATH + 1];
1962
1985
 
1963
 
    pbuf  = ole_mb2wc(StringValuePtr(ole), -1);
1964
 
    hr = CLSIDFromProgID(pbuf, &clsid);
1965
 
    SysFreeString(pbuf);
1966
 
    if (FAILED(hr)) {
1967
 
        return Qnil;
1968
 
    }
1969
 
    StringFromCLSID(&clsid, &pbuf);
1970
 
    vclsid = WC2VSTR(pbuf);
1971
1986
    err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
1972
1987
    if (err != ERROR_SUCCESS) {
1973
1988
        return Qnil;
1974
1989
    }
1975
 
    err = reg_open_key(hroot, StringValuePtr(vclsid), &hclsid);
 
1990
    err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
1976
1991
    if (err != ERROR_SUCCESS) {
1977
1992
        RegCloseKey(hroot);
1978
1993
        return Qnil;
1979
1994
    }
1980
 
    typelib = reg_get_val(hclsid, "InprocServer32");
 
1995
    typelib = reg_get_val2(hclsid, "InprocServer32");
1981
1996
    RegCloseKey(hroot);
1982
1997
    RegCloseKey(hclsid);
 
1998
    if (typelib != Qnil) {
 
1999
        ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
 
2000
        path[MAX_PATH] = '\0';
 
2001
        typelib = rb_str_new2(path);
 
2002
    }
1983
2003
    return typelib;
1984
2004
}
1985
2005
 
2014
2034
            if (ver == Qnil)
2015
2035
                break;
2016
2036
            err = reg_open_vkey(hclsid, ver, &hversion);
2017
 
            if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
 
2037
                        if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
2018
2038
                continue;
2019
2039
            fver = atof(StringValuePtr(ver));
2020
2040
            typelib = reg_get_val(hversion, NULL);
2641
2661
lcid_installed(LCID lcid)
2642
2662
{
2643
2663
    g_lcid_installed = FALSE;
2644
 
    snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08x", lcid);
 
2664
    snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08lx", lcid);
2645
2665
    EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED);
2646
2666
    return g_lcid_installed;
2647
2667
}
2669
2689
            cWIN32OLE_lcid = lcid;
2670
2690
            break;
2671
2691
        default:
2672
 
            rb_raise(eWIN32OLERuntimeError, "not installed locale: %d", lcid);
 
2692
            rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
2673
2693
        }
2674
2694
    }
2675
2695
    return Qnil;
4428
4448
        err = reg_open_vkey(hclsids, clsid, &hclsid);
4429
4449
        if (err != ERROR_SUCCESS)
4430
4450
            continue;
4431
 
        if ((v = reg_get_val(hclsid, "ProgID")) != Qnil) 
 
4451
        if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil) 
4432
4452
            rb_ary_push(progids, v);
4433
 
        if ((v = reg_get_val(hclsid, "VersionIndependentProgID")) != Qnil)
 
4453
        if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
4434
4454
            rb_ary_push(progids, v);
4435
4455
        RegCloseKey(hclsid);
4436
4456
    }
4545
4565
            version = reg_enum_key(hguid, j);
4546
4566
            if (version == Qnil)
4547
4567
                break;
4548
 
            if ( (name = reg_get_val(hguid, StringValuePtr(version))) != Qnil ) {
 
4568
            if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
4549
4569
                typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
4550
4570
                oletypelib_set_member(typelib, name, guid, version);
4551
4571
                rb_ary_push(typelibs, typelib);
5172
5192
    if (FAILED(hr)) 
5173
5193
        return progid;
5174
5194
    hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
5175
 
    if (SUCCEEDED(hr)) 
5176
 
        progid = WC2VSTR(pbuf);
 
5195
    if (SUCCEEDED(hr)) {
 
5196
        progid = ole_wc2vstr(pbuf, FALSE);
 
5197
        CoTaskMemFree(pbuf);
 
5198
    }
5177
5199
    OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5178
5200
    return progid;
5179
5201
}
7119
7141
    pEv->m_dwCookie = 0;
7120
7142
    pEv->pConnectionPoint = NULL;
7121
7143
    pEv->pTypeInfo = NULL;
7122
 
    pEv->ptr_freed = NULL;
7123
7144
    return pEv;
7124
7145
}
7125
7146
 
7127
7148
    PIEVENTSINKOBJ pEVObj
7128
7149
    ) {
7129
7150
    if(pEVObj != NULL) {
7130
 
        *(pEVObj->ptr_freed) = 1;
7131
7151
        free(pEVObj);
7132
7152
        pEVObj = NULL;
7133
7153
    }
7341
7361
{
7342
7362
    ITypeInfo *pti = NULL;
7343
7363
    IConnectionPoint *pcp = NULL;
7344
 
 
7345
 
    if (poleev->freed == 1) {
7346
 
        /* 
7347
 
         * this return create memory leak.
7348
 
         * but poleev->pEvent->pConnectionPoint shoul'd not be freed
7349
 
         * until poleev->freed == 0.
7350
 
         */
7351
 
        return; 
7352
 
    }
7353
 
    if(poleev->pEvent) {
7354
 
        pti = poleev->pEvent->pTypeInfo;
7355
 
        if(pti) OLE_RELEASE(pti);
7356
 
        pcp = poleev->pEvent->pConnectionPoint;
7357
 
        if(pcp) {
7358
 
            pcp->lpVtbl->Unadvise(pcp, poleev->pEvent->m_dwCookie);
7359
 
            OLE_RELEASE(pcp);
7360
 
        }
7361
 
        free(poleev);
7362
 
    }
 
7364
    free(poleev);
7363
7365
}
7364
7366
 
7365
7367
static VALUE
7368
7370
    VALUE obj;
7369
7371
    struct oleeventdata *poleev;
7370
7372
    obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);
 
7373
/*
7371
7374
    poleev->pEvent = NULL;
 
7375
*/
7372
7376
    return obj;
7373
7377
}
7374
7378
 
7451
7455
    }
7452
7456
 
7453
7457
    Data_Get_Struct(self, struct oleeventdata, poleev);
7454
 
    poleev->pEvent = pIEV;
7455
 
    poleev->pEvent->m_event_id
 
7458
    pIEV->m_event_id
7456
7459
        = NUM2INT(rb_funcall(ary_ole_event, rb_intern("length"), 0));
7457
 
    poleev->pEvent->pConnectionPoint = pConnectionPoint;
7458
 
    poleev->pEvent->pTypeInfo = pTypeInfo;
7459
 
    poleev->pEvent->m_dwCookie = dwCookie;
7460
 
    poleev->freed = 0;
7461
 
    poleev->pEvent->ptr_freed = &(poleev->freed);
 
7460
    pIEV->pConnectionPoint = pConnectionPoint;
 
7461
    pIEV->pTypeInfo = pTypeInfo;
 
7462
    pIEV->m_dwCookie = dwCookie;
 
7463
 
7462
7464
    rb_ary_push(ary_ole_event, self);
7463
7465
 
7464
7466
    events = rb_ary_new();
7827
7829
{
7828
7830
    struct olevariantdata *pvar;
7829
7831
    SAFEARRAY *psa;
7830
 
    VALUE val = Qnil;
7831
7832
    VARIANT var;
7832
7833
    VARTYPE vt;
7833
7834
    long *pid;
7849
7850
    VariantInit(&var);
7850
7851
    vt = (V_VT(&(pvar->var)) & ~VT_ARRAY);
7851
7852
    p = val2variant_ptr(argv[argc-1], &var, vt);
7852
 
    if (V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL ||
7853
 
        V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL) {
 
7853
    if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
 
7854
        (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
7854
7855
        rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
7855
7856
    }
7856
7857
    hr = SafeArrayPutElement(psa, pid, p);