~ubuntu-branches/ubuntu/precise/nspr/precise-proposed

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/src/linking/prlink.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2009-08-10 11:34:26 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090810113426-3uv4diflrkcbdimm
Tags: 4.8-0ubuntu1
* New upstream release: 4.8 (LP: #387812)
* adjust patches to changed upstreanm codebase
  - update debian/patches/99_configure.patch
* update shlibs symbols to include new API elements
  - update debian/libnspr4-0d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
 
89
89
#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY
90
90
 
91
 
#ifdef VMS
92
 
/* These are all require for the PR_GetLibraryFilePathname implementation */
93
 
#include <descrip.h>
94
 
#include <dvidef.h>
95
 
#include <fibdef.h>
96
 
#include <iodef.h>
97
 
#include <lib$routines.h>
98
 
#include <ssdef.h>
99
 
#include <starlet.h>
100
 
#include <stsdef.h>
101
 
#include <unixlib.h>
102
 
 
103
 
#pragma __nostandard 
104
 
#pragma __member_alignment __save
105
 
#pragma __nomember_alignment
106
 
#ifdef __INITIAL_POINTER_SIZE
107
 
#pragma __required_pointer_size __save 
108
 
#pragma __required_pointer_size __short
109
 
#endif
110
 
 
111
 
typedef struct _imcb {
112
 
    struct _imcb *imcb$l_flink;         
113
 
    struct _imcb *imcb$l_blink;         
114
 
    unsigned short int imcb$w_size;     
115
 
    unsigned char imcb$b_type;          
116
 
    char imcb$b_resv_1;                 
117
 
    unsigned char imcb$b_access_mode;   
118
 
    unsigned char imcb$b_act_code;      
119
 
    unsigned short int imcb$w_chan;     
120
 
    unsigned int imcb$l_flags;          
121
 
    char imcb$t_image_name [40];        
122
 
    unsigned int imcb$l_symvec_size; 
123
 
    unsigned __int64 imcb$q_ident;
124
 
    void *imcb$l_starting_address;
125
 
    void *imcb$l_end_address;
126
 
} IMCB;
127
 
 
128
 
#pragma __member_alignment __restore
129
 
#ifdef __INITIAL_POINTER_SIZE 
130
 
#pragma __required_pointer_size __restore
131
 
#endif
132
 
#pragma __standard
133
 
 
134
 
typedef struct {
135
 
    short   buflen;
136
 
    short   itmcode;
137
 
    void    *buffer;
138
 
    void    *retlen;
139
 
} ITMLST;
140
 
 
141
 
typedef struct {
142
 
    short cond;
143
 
    short count;
144
 
    int   rest;
145
 
} IOSB;
146
 
 
147
 
typedef unsigned long int ulong_t;
148
 
 
149
 
struct _imcb *IAC$GL_IMAGE_LIST = NULL;
150
 
 
151
 
#define MAX_DEVNAM 64
152
 
#define MAX_FILNAM 255
153
 
#endif  /* VMS */
154
 
 
155
91
/*
156
92
 * On these platforms, symbols have a leading '_'.
157
93
 */
158
94
#if defined(SUNOS4) || (defined(DARWIN) && defined(USE_MACH_DYLD)) \
159
 
    || defined(NEXTSTEP) || defined(WIN16) || defined(XP_OS2) \
 
95
    || defined(NEXTSTEP) || defined(XP_OS2) \
160
96
    || ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__))
161
97
#define NEED_LEADING_UNDERSCORE
162
98
#endif
210
146
 
211
147
static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags);
212
148
 
213
 
#ifdef WIN95
214
 
typedef HMODULE (WINAPI *LoadLibraryWFn)(LPCWSTR);
215
 
static HMODULE WINAPI EmulateLoadLibraryW(LPCWSTR);
216
 
static LoadLibraryWFn loadLibraryW = LoadLibraryW;
217
 
#endif
218
 
 
219
 
#ifdef WIN32
220
 
static int pr_ConvertUTF16toUTF8(LPCWSTR wname, LPSTR name, int len);
221
 
#endif
222
 
 
223
149
/************************************************************************/
224
150
 
225
151
#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR)
254
180
    void *h;
255
181
#endif
256
182
 
257
 
#ifdef WIN95
258
 
    if (!_pr_useUnicode) {
259
 
        loadLibraryW = EmulateLoadLibraryW;
260
 
    }
261
 
#endif
262
 
 
263
183
    if (!pr_linker_lock) {
264
184
        pr_linker_lock = PR_NewNamedMonitor("linker-lock");
265
185
    }
330
250
    PR_ExitMonitor(pr_linker_lock);
331
251
}
332
252
 
333
 
#if defined(WIN16)
334
 
/*
335
 
 * _PR_ShutdownLinker unloads all dlls loaded by the application via
336
 
 * calls to PR_LoadLibrary
337
 
 */
338
 
void _PR_ShutdownLinker(void)
339
 
{
340
 
    PR_EnterMonitor(pr_linker_lock);
341
 
 
342
 
    while (pr_loadmap) {
343
 
    if (pr_loadmap->refCount > 1) {
344
 
#ifdef DEBUG
345
 
        fprintf(stderr, "# Forcing library to unload: %s (%d outstanding references)\n",
346
 
            pr_loadmap->name, pr_loadmap->refCount);
347
 
#endif
348
 
        pr_loadmap->refCount = 1;
349
 
    }
350
 
    PR_UnloadLibrary(pr_loadmap);
351
 
    }
352
 
    
353
 
    PR_ExitMonitor(pr_linker_lock);
354
 
 
355
 
    PR_DestroyMonitor(pr_linker_lock);
356
 
    pr_linker_lock = NULL;
357
 
}
358
 
#else
359
 
/*
360
 
 * _PR_ShutdownLinker was originally only used on WIN16 (see above),
361
 
 * but I think it should also be used on other platforms.  However,
362
 
 * I disagree with the original implementation's unloading the dlls
363
 
 * for the application.  Any dlls that still remain on the pr_loadmap
364
 
 * list when NSPR shuts down are application programming errors.  The
365
 
 * only exception is pr_exe_loadmap, which was added to the list by
 
253
/*
 
254
 * _PR_ShutdownLinker does not unload the dlls loaded by the application
 
255
 * via calls to PR_LoadLibrary.  Any dlls that still remain on the
 
256
 * pr_loadmap list when NSPR shuts down are application programming errors.
 
257
 * The only exception is pr_exe_loadmap, which was added to the list by
366
258
 * NSPR and hence should be cleaned up by NSPR.
367
259
 */
368
260
void _PR_ShutdownLinker(void)
377
269
        _pr_currentLibPath = NULL;
378
270
    }
379
271
}
380
 
#endif
381
272
 
382
273
/******************************************************************************/
383
274
 
780
671
 
781
672
#endif /* XP_MACOSX && USE_MACH_DYLD */
782
673
 
783
 
#ifdef WIN95
784
 
static HMODULE WINAPI
785
 
EmulateLoadLibraryW(LPCWSTR lpLibFileName)
786
 
{
787
 
    HMODULE h;
788
 
    char nameA[MAX_PATH];
789
 
 
790
 
    if (!WideCharToMultiByte(CP_ACP, 0, lpLibFileName, -1,
791
 
                             nameA, sizeof nameA, NULL, NULL)) {
792
 
        return NULL;
793
 
    }
794
 
    /* Perhaps it's better to add a check for characters 
795
 
     * not representable in CP_ACP.
796
 
     */
797
 
    h = LoadLibraryA(nameA);
798
 
    return h;
799
 
}
800
 
#endif /* WIN95 */
801
 
 
802
674
/*
803
675
** Dynamically load a library. Only load libraries once, so scan the load
804
676
** map first.
838
710
            goto unlock;
839
711
        }
840
712
    }
841
 
    len = pr_ConvertUTF16toUTF8(wname, NULL, 0);
 
713
    len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL);
842
714
    if (len > MAX_PATH)
843
715
        utf8name = utf8name_malloc = PR_Malloc(len);
844
716
    if (utf8name == NULL ||
845
 
        !pr_ConvertUTF16toUTF8(wname, utf8name, len)) {
 
717
        !WideCharToMultiByte(CP_UTF8, 0, wname, -1,
 
718
                             utf8name, len, NULL, NULL)) {
846
719
        oserr = _MD_ERRNO();
847
720
        goto unlock;
848
721
    }
881
754
    }
882
755
#endif /* XP_OS2 */
883
756
 
884
 
#if defined(WIN32) || defined(WIN16)
 
757
#ifdef WIN32
885
758
    {
886
759
    HINSTANCE h;
887
760
 
888
 
#ifdef WIN32
889
 
#ifdef WIN95
890
 
    if (flags & PR_LD_PATHW)
891
 
        h = loadLibraryW(wname);
892
 
    else
893
 
        h = LoadLibraryA(name);
894
 
#else
895
 
    if (flags & PR_LD_PATHW)
896
 
        h = LoadLibraryW(wname);
897
 
    else
898
 
        h = LoadLibraryA(name);
899
 
#endif /* WIN95 */
900
 
#else 
901
 
    h = LoadLibrary(name);
902
 
#endif
903
 
    if (h < (HINSTANCE)HINSTANCE_ERROR) {
 
761
    h = LoadLibraryW(wname);
 
762
    if (h == NULL) {
904
763
        oserr = _MD_ERRNO();
905
764
        PR_DELETE(lm);
906
765
        goto unlock;
907
766
    }
908
 
#ifdef WIN32
909
767
    lm->name = strdup(utf8name);
910
 
#else
911
 
    lm->name = strdup(name);
912
 
#endif
913
768
    lm->dlh = h;
914
769
    lm->next = pr_loadmap;
915
770
    pr_loadmap = lm;
916
771
    }
917
 
#endif /* WIN32 || WIN16 */
 
772
#endif /* WIN32 */
918
773
 
919
774
#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
920
775
    {
957
812
#else
958
813
    int dl_flags = 0;
959
814
#endif
960
 
    void *h;
 
815
    void *h = NULL;
961
816
 
962
817
    if (flags & PR_LD_LAZY) {
963
818
        dl_flags |= RTLD_LAZY;
971
826
    if (flags & PR_LD_LOCAL) {
972
827
        dl_flags |= RTLD_LOCAL;
973
828
    }
 
829
#if defined(DARWIN)
 
830
    /* ensure the file exists if it contains a slash character i.e. path */
 
831
    /* DARWIN's dlopen ignores the provided path and checks for the */
 
832
    /* plain filename in DYLD_LIBRARY_PATH */
 
833
    if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL ||
 
834
        PR_Access(name, PR_ACCESS_EXISTS) == PR_SUCCESS) {
 
835
            h = dlopen(name, dl_flags);
 
836
        }
 
837
#else
974
838
    h = dlopen(name, dl_flags);
 
839
#endif
975
840
#elif defined(USE_HPSHL)
976
841
    int shl_flags = 0;
977
842
    shl_t h;
1120
985
    return result;
1121
986
}
1122
987
 
1123
 
#ifdef WIN32
1124
 
#ifdef WIN95
1125
 
/*
1126
 
 * CP_UTF8 is not supported by WideCharToMultiByte on Windows 95 so that 
1127
 
 * we have to emulate it
1128
 
 */
1129
 
static PRStatus 
1130
 
pr_ConvertSingleCharToUTF8(PRUint32 usv, PRUint16 offset, int bufLen,
1131
 
                           int *utf8Len, char * *buf)
1132
 
{
1133
 
    char* p = *buf;
1134
 
    PR_ASSERT(!bufLen || *buf);
1135
 
    if (!bufLen) {
1136
 
        *utf8Len += offset;
1137
 
        return PR_SUCCESS;
1138
 
    }
1139
 
 
1140
 
    if (*utf8Len + offset >= bufLen)
1141
 
        return PR_FAILURE;
1142
 
 
1143
 
    *utf8Len += offset;
1144
 
    if (offset == 1) {
1145
 
        *p++ = (char) usv;
1146
 
    } else if (offset == 2) {
1147
 
        *p++ = (char)0xc0 | (usv >> 6);
1148
 
        *p++ = (char)0x80 | (usv & 0x003f);
1149
 
    } else if (offset == 3) {
1150
 
        *p++ = (char)0xe0 | (usv >> 12);
1151
 
        *p++ = (char)0x80 | ((usv >> 6) & 0x003f);
1152
 
        *p++ = (char)0x80 | (usv & 0x003f);
1153
 
    } else { /* offset = 4 */
1154
 
        *p++ = (char)0xf0 | (usv >> 18);
1155
 
        *p++ = (char)0x80 | ((usv >> 12) & 0x003f);
1156
 
        *p++ = (char)0x80 | ((usv >> 6) & 0x003f);
1157
 
        *p++ = (char)0x80 | (usv & 0x003f);
1158
 
    }
1159
 
 
1160
 
    *buf = p;
1161
 
    return PR_SUCCESS;
1162
 
}
1163
 
 
1164
 
static int pr_ConvertUTF16toUTF8(LPCWSTR wname, LPSTR name, int len)
1165
 
{
1166
 
    LPCWSTR pw = wname;
1167
 
    LPSTR p = name;
1168
 
    int utf8Len = 0;
1169
 
    PRBool highSurrogate = PR_FALSE;
1170
 
 
1171
 
    utf8Len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, name, len, 
1172
 
                                  NULL, NULL);
1173
 
    /*
1174
 
     * Windows 95 and NT 3.51 don't support CP_UTF8.
1175
 
     * WideCharToMultiByte(CP_UTF8, ...) fails with the error code
1176
 
     * ERROR_INVALID_PARAMETER on Windows 95 and NT 3.51.
1177
 
     */
1178
 
    if (utf8Len || GetLastError() != ERROR_INVALID_PARAMETER)
1179
 
        return utf8Len;
1180
 
 
1181
 
    if (!wname || len < 0 || (len > 0 && !name)) {
1182
 
        SetLastError(ERROR_INVALID_PARAMETER);
1183
 
        return 0;
1184
 
    }
1185
 
 
1186
 
    while (*pw) {
1187
 
        PRStatus status = PR_SUCCESS;
1188
 
        if (highSurrogate) {
1189
 
            if (*pw >= (PRUnichar) 0xDC00 && *pw < (PRUnichar) 0xE000) {
1190
 
                /* found a matching low surrogate */
1191
 
                /* convert a surrogate pair to UCS4 */
1192
 
                PRUint32 usv = ((*(pw-1) - (PRUnichar)0xD800) << 10) + 
1193
 
                               (*pw - (PRUnichar)0xDC00) + (PRUint32)0x10000;
1194
 
                if (pr_ConvertSingleCharToUTF8(usv, 4, len, &utf8Len, &p) ==
1195
 
                    PR_FAILURE)
1196
 
                    return 0;
1197
 
                highSurrogate = PR_FALSE;
1198
 
                ++pw;
1199
 
                continue;
1200
 
            } else {
1201
 
                /*
1202
 
                 * silently ignore a lone high surrogate
1203
 
                 * as is done by WideCharToMultiByte by default
1204
 
                 */
1205
 
                highSurrogate = PR_FALSE;
1206
 
            }
1207
 
        }
1208
 
        if (*pw <= 0x7f) 
1209
 
            status = pr_ConvertSingleCharToUTF8(*pw, 1, len, &utf8Len, &p);
1210
 
        else if (*pw <= 0x07ff)
1211
 
            status = pr_ConvertSingleCharToUTF8(*pw, 2, len, &utf8Len, &p);
1212
 
        else if (*pw < (PRUnichar) 0xD800 || *pw >= (PRUnichar) 0xE000)
1213
 
            status = pr_ConvertSingleCharToUTF8(*pw, 3, len, &utf8Len, &p);
1214
 
        else if (*pw < (PRUnichar) 0xDC00)
1215
 
            highSurrogate = PR_TRUE;
1216
 
        /* else */
1217
 
        /* silently ignore a lone low surrogate as is done by 
1218
 
         * WideCharToMultiByte by default */
1219
 
 
1220
 
        if (status == PR_FAILURE) {
1221
 
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
1222
 
            return 0;
1223
 
        }
1224
 
        ++pw;
1225
 
    }
1226
 
 
1227
 
    /* if we're concerned with a lone high surrogate,
1228
 
     * we have to take care of it here, but we just drop it 
1229
 
     */
1230
 
    if (len > 0)
1231
 
        *p = '\0';
1232
 
    return utf8Len + 1;
1233
 
}
1234
 
#else
1235
 
static int pr_ConvertUTF16toUTF8(LPCWSTR wname, LPSTR name, int len)
1236
 
{
1237
 
    return WideCharToMultiByte(CP_UTF8, 0, wname, -1, name, len, NULL, NULL);
1238
 
}
1239
 
#endif /* WIN95 */
1240
 
#endif /* WIN32 */
1241
 
 
1242
988
/*
1243
989
** Unload a shared library which was loaded via PR_LoadLibrary
1244
990
*/
1384
1130
#endif
1385
1131
#endif  /* XP_OS2 */
1386
1132
 
1387
 
#if defined(WIN32) || defined(WIN16)
 
1133
#ifdef WIN32
1388
1134
    f = GetProcAddress(lm->dlh, name);
1389
 
#endif  /* WIN32 || WIN16 */
 
1135
#endif  /* WIN32 */
1390
1136
 
1391
1137
#if defined(XP_MACOSX) && defined(USE_MACH_DYLD)
1392
1138
/* add this offset to skip the leading underscore in name */
1777
1523
    }
1778
1524
    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
1779
1525
    return NULL;
1780
 
#elif defined(VMS)
1781
 
    /* Contributed by Colin Blake of HP */
1782
 
    struct _imcb        *icb;
1783
 
    ulong_t             status;
1784
 
    char                device_name[MAX_DEVNAM];
1785
 
    int                 device_name_len;
1786
 
    $DESCRIPTOR         (device_name_desc, device_name);
1787
 
    struct fibdef       fib;
1788
 
    struct dsc$descriptor_s fib_desc = 
1789
 
        { sizeof(struct fibdef), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *)&fib } ;
1790
 
    IOSB                iosb;
1791
 
    ITMLST              devlst[2] = {
1792
 
                        {MAX_DEVNAM, DVI$_ALLDEVNAM, device_name, &device_name_len},
1793
 
                        {0,0,0,0}};
1794
 
    short               file_name_len;
1795
 
    char                file_name[MAX_FILNAM+1];
1796
 
    char                *result = NULL;
1797
 
    struct dsc$descriptor_s file_name_desc = 
1798
 
        { MAX_FILNAM, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &file_name[0] } ;
1799
 
 
1800
 
    /*
1801
 
    ** The address for the process image list could change in future versions
1802
 
    ** of the operating system. 7FFD0688 is valid for V7.2 and V7.3 releases,
1803
 
    ** so we use that for the default, but allow an environment variable
1804
 
    ** (logical name) to override.
1805
 
    */
1806
 
    if (IAC$GL_IMAGE_LIST == NULL) {
1807
 
        char *p = getenv("MOZILLA_IAC_GL_IMAGE_LIST");
1808
 
        if (p)
1809
 
            IAC$GL_IMAGE_LIST = (struct _imcb *) strtol(p,NULL,0);
1810
 
        else
1811
 
            IAC$GL_IMAGE_LIST = (struct _imcb *) 0x7FFD0688;
1812
 
    }
1813
 
 
1814
 
    for (icb = IAC$GL_IMAGE_LIST->imcb$l_flink;
1815
 
         icb != IAC$GL_IMAGE_LIST;
1816
 
         icb = icb->imcb$l_flink) {
1817
 
        if (((void *)addr >= icb->imcb$l_starting_address) && 
1818
 
            ((void *)addr <= icb->imcb$l_end_address)) {
1819
 
            /*
1820
 
            ** This is the correct image.
1821
 
            ** Get the device name.
1822
 
            */
1823
 
            status = sys$getdviw(0,icb->imcb$w_chan,0,&devlst,0,0,0,0);
1824
 
            if ($VMS_STATUS_SUCCESS(status))
1825
 
                device_name_desc.dsc$w_length = device_name_len;
1826
 
 
1827
 
            /*
1828
 
            ** Get the FID.
1829
 
            */
1830
 
            memset(&fib,0,sizeof(struct fibdef));
1831
 
            status = sys$qiow(0,icb->imcb$w_chan,IO$_ACCESS,&iosb,
1832
 
                                0,0,&fib_desc,0,0,0,0,0);
1833
 
 
1834
 
            /*
1835
 
            ** If we got the FID, now look up its name (if for some reason
1836
 
            ** we didn't get the device name, this call will fail).
1837
 
            */
1838
 
            if (($VMS_STATUS_SUCCESS(status)) && ($VMS_STATUS_SUCCESS(iosb.cond))) {
1839
 
                status = lib$fid_to_name (
1840
 
                    &device_name_desc,
1841
 
                    &fib.fib$w_fid,
1842
 
                    &file_name_desc,
1843
 
                    &file_name_len,
1844
 
                    0, 0);
1845
 
 
1846
 
                /*
1847
 
                ** If we succeeded then remove the version number and
1848
 
                ** return a copy of the UNIX format version of the file name.
1849
 
                */
1850
 
                if ($VMS_STATUS_SUCCESS(status)) {
1851
 
                    char *p, *result;
1852
 
                    file_name[file_name_len] = 0;
1853
 
                    p = strrchr(file_name,';');
1854
 
                    if (p) *p = 0;
1855
 
                    p = decc$translate_vms(&file_name[0]);
1856
 
                    result = PR_Malloc(strlen(p)+1);
1857
 
                    if (result != NULL) {
1858
 
                        strcpy(result, p);
1859
 
                    }
1860
 
                    return result;
1861
 
                }
1862
 
            }
1863
 
        }
1864
 
    }
1865
 
 
1866
 
    /* Didn't find it */
1867
 
    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
1868
 
    return NULL;
1869
 
 
1870
1526
#elif defined(HPUX) && defined(USE_HPSHL)
1871
1527
    int index;
1872
1528
    struct shl_descriptor desc;
1923
1579
    }
1924
1580
    return result;
1925
1581
#elif defined(WIN32)
1926
 
    HMODULE handle;
1927
 
    char module_name[MAX_PATH];
 
1582
    PRUnichar wname[MAX_PATH];
 
1583
    HMODULE handle = NULL;
 
1584
    PRUnichar module_name[MAX_PATH];
 
1585
    int len;
1928
1586
    char *result;
1929
1587
 
1930
 
    handle = GetModuleHandle(name);
 
1588
    if (MultiByteToWideChar(CP_ACP, 0, name, -1, wname, MAX_PATH)) {
 
1589
        handle = GetModuleHandleW(wname);
 
1590
    }
1931
1591
    if (handle == NULL) {
1932
1592
        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
1933
1593
        DLLErrorInternal(_MD_ERRNO());
1934
1594
        return NULL;
1935
1595
    }
1936
 
    if (GetModuleFileName(handle, module_name, sizeof module_name) == 0) {
 
1596
    if (GetModuleFileNameW(handle, module_name, MAX_PATH) == 0) {
1937
1597
        /* should not happen */
1938
1598
        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
1939
1599
        return NULL;
1940
1600
    }
1941
 
    result = PR_Malloc(strlen(module_name)+1);
 
1601
    len = WideCharToMultiByte(CP_ACP, 0, module_name, -1,
 
1602
                              NULL, 0, NULL, NULL);
 
1603
    if (len == 0) {
 
1604
        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
 
1605
        return NULL;
 
1606
    }
 
1607
    result = PR_Malloc(len * sizeof(PRUnichar));
1942
1608
    if (result != NULL) {
1943
 
        strcpy(result, module_name);
 
1609
        WideCharToMultiByte(CP_ACP, 0, module_name, -1,
 
1610
                            result, len, NULL, NULL);
1944
1611
    }
1945
1612
    return result;
1946
1613
#elif defined(XP_OS2)