1*2139Sjp161948 /* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
20Sstevel@tonic-gate /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
30Sstevel@tonic-gate * project 2000.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate * are met:
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate * the documentation and/or other materials provided with the
180Sstevel@tonic-gate * distribution.
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate * software must display the following acknowledgment:
220Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate * endorse or promote products derived from this software without
270Sstevel@tonic-gate * prior written permission. For written permission, please contact
280Sstevel@tonic-gate * licensing@OpenSSL.org.
290Sstevel@tonic-gate *
300Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate * permission of the OpenSSL Project.
330Sstevel@tonic-gate *
340Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate * acknowledgment:
360Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate * ====================================================================
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
550Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate *
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate #include <stdio.h>
600Sstevel@tonic-gate #include <string.h>
610Sstevel@tonic-gate #include "cryptlib.h"
620Sstevel@tonic-gate #include <openssl/dso.h>
630Sstevel@tonic-gate
64*2139Sjp161948 #if !defined(DSO_WIN32)
DSO_METHOD_win32(void)650Sstevel@tonic-gate DSO_METHOD *DSO_METHOD_win32(void)
660Sstevel@tonic-gate {
670Sstevel@tonic-gate return NULL;
680Sstevel@tonic-gate }
690Sstevel@tonic-gate #else
700Sstevel@tonic-gate
71*2139Sjp161948 #ifdef _WIN32_WCE
72*2139Sjp161948 # if _WIN32_WCE < 300
GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)73*2139Sjp161948 static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
74*2139Sjp161948 {
75*2139Sjp161948 WCHAR lpProcNameW[64];
76*2139Sjp161948 int i;
77*2139Sjp161948
78*2139Sjp161948 for (i=0;lpProcName[i] && i<64;i++)
79*2139Sjp161948 lpProcNameW[i] = (WCHAR)lpProcName[i];
80*2139Sjp161948 if (i==64) return NULL;
81*2139Sjp161948 lpProcNameW[i] = 0;
82*2139Sjp161948
83*2139Sjp161948 return GetProcAddressW(hModule,lpProcNameW);
84*2139Sjp161948 }
85*2139Sjp161948 # endif
86*2139Sjp161948 # undef GetProcAddress
87*2139Sjp161948 # define GetProcAddress GetProcAddressA
88*2139Sjp161948
LoadLibraryA(LPCSTR lpLibFileName)89*2139Sjp161948 static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
90*2139Sjp161948 {
91*2139Sjp161948 WCHAR *fnamw;
92*2139Sjp161948 size_t len_0=strlen(lpLibFileName)+1,i;
93*2139Sjp161948
94*2139Sjp161948 #ifdef _MSC_VER
95*2139Sjp161948 fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
96*2139Sjp161948 #else
97*2139Sjp161948 fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
98*2139Sjp161948 #endif
99*2139Sjp161948 if (fnamw == NULL) return NULL;
100*2139Sjp161948
101*2139Sjp161948 #if defined(_WIN32_WCE) && _WIN32_WCE>=101
102*2139Sjp161948 if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
103*2139Sjp161948 #endif
104*2139Sjp161948 for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i];
105*2139Sjp161948
106*2139Sjp161948 return LoadLibraryW(fnamw);
107*2139Sjp161948 }
108*2139Sjp161948 #endif
109*2139Sjp161948
1100Sstevel@tonic-gate /* Part of the hack in "win32_load" ... */
1110Sstevel@tonic-gate #define DSO_MAX_TRANSLATED_SIZE 256
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate static int win32_load(DSO *dso);
1140Sstevel@tonic-gate static int win32_unload(DSO *dso);
1150Sstevel@tonic-gate static void *win32_bind_var(DSO *dso, const char *symname);
1160Sstevel@tonic-gate static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
1170Sstevel@tonic-gate #if 0
1180Sstevel@tonic-gate static int win32_unbind_var(DSO *dso, char *symname, void *symptr);
1190Sstevel@tonic-gate static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
1200Sstevel@tonic-gate static int win32_init(DSO *dso);
1210Sstevel@tonic-gate static int win32_finish(DSO *dso);
1220Sstevel@tonic-gate static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
1230Sstevel@tonic-gate #endif
1240Sstevel@tonic-gate static char *win32_name_converter(DSO *dso, const char *filename);
125*2139Sjp161948 static char *win32_merger(DSO *dso, const char *filespec1,
126*2139Sjp161948 const char *filespec2);
127*2139Sjp161948
128*2139Sjp161948 static const char *openssl_strnchr(const char *string, int c, size_t len);
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate static DSO_METHOD dso_meth_win32 = {
1310Sstevel@tonic-gate "OpenSSL 'win32' shared library method",
1320Sstevel@tonic-gate win32_load,
1330Sstevel@tonic-gate win32_unload,
1340Sstevel@tonic-gate win32_bind_var,
1350Sstevel@tonic-gate win32_bind_func,
1360Sstevel@tonic-gate /* For now, "unbind" doesn't exist */
1370Sstevel@tonic-gate #if 0
1380Sstevel@tonic-gate NULL, /* unbind_var */
1390Sstevel@tonic-gate NULL, /* unbind_func */
1400Sstevel@tonic-gate #endif
1410Sstevel@tonic-gate NULL, /* ctrl */
1420Sstevel@tonic-gate win32_name_converter,
143*2139Sjp161948 win32_merger,
1440Sstevel@tonic-gate NULL, /* init */
1450Sstevel@tonic-gate NULL /* finish */
1460Sstevel@tonic-gate };
1470Sstevel@tonic-gate
DSO_METHOD_win32(void)1480Sstevel@tonic-gate DSO_METHOD *DSO_METHOD_win32(void)
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate return(&dso_meth_win32);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate /* For this DSO_METHOD, our meth_data STACK will contain;
1540Sstevel@tonic-gate * (i) a pointer to the handle (HINSTANCE) returned from
1550Sstevel@tonic-gate * LoadLibrary(), and copied.
1560Sstevel@tonic-gate */
1570Sstevel@tonic-gate
win32_load(DSO * dso)1580Sstevel@tonic-gate static int win32_load(DSO *dso)
1590Sstevel@tonic-gate {
1600Sstevel@tonic-gate HINSTANCE h = NULL, *p = NULL;
1610Sstevel@tonic-gate /* See applicable comments from dso_dl.c */
1620Sstevel@tonic-gate char *filename = DSO_convert_filename(dso, NULL);
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate if(filename == NULL)
1650Sstevel@tonic-gate {
1660Sstevel@tonic-gate DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
1670Sstevel@tonic-gate goto err;
1680Sstevel@tonic-gate }
169*2139Sjp161948 h = LoadLibraryA(filename);
1700Sstevel@tonic-gate if(h == NULL)
1710Sstevel@tonic-gate {
1720Sstevel@tonic-gate DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
1730Sstevel@tonic-gate ERR_add_error_data(3, "filename(", filename, ")");
1740Sstevel@tonic-gate goto err;
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
1770Sstevel@tonic-gate if(p == NULL)
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
1800Sstevel@tonic-gate goto err;
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate *p = h;
1830Sstevel@tonic-gate if(!sk_push(dso->meth_data, (char *)p))
1840Sstevel@tonic-gate {
1850Sstevel@tonic-gate DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
1860Sstevel@tonic-gate goto err;
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate /* Success */
1890Sstevel@tonic-gate dso->loaded_filename = filename;
1900Sstevel@tonic-gate return(1);
1910Sstevel@tonic-gate err:
1920Sstevel@tonic-gate /* Cleanup !*/
1930Sstevel@tonic-gate if(filename != NULL)
1940Sstevel@tonic-gate OPENSSL_free(filename);
1950Sstevel@tonic-gate if(p != NULL)
1960Sstevel@tonic-gate OPENSSL_free(p);
1970Sstevel@tonic-gate if(h != NULL)
1980Sstevel@tonic-gate FreeLibrary(h);
1990Sstevel@tonic-gate return(0);
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate
win32_unload(DSO * dso)2020Sstevel@tonic-gate static int win32_unload(DSO *dso)
2030Sstevel@tonic-gate {
2040Sstevel@tonic-gate HINSTANCE *p;
2050Sstevel@tonic-gate if(dso == NULL)
2060Sstevel@tonic-gate {
2070Sstevel@tonic-gate DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
2080Sstevel@tonic-gate return(0);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate if(sk_num(dso->meth_data) < 1)
2110Sstevel@tonic-gate return(1);
2120Sstevel@tonic-gate p = (HINSTANCE *)sk_pop(dso->meth_data);
2130Sstevel@tonic-gate if(p == NULL)
2140Sstevel@tonic-gate {
2150Sstevel@tonic-gate DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE);
2160Sstevel@tonic-gate return(0);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate if(!FreeLibrary(*p))
2190Sstevel@tonic-gate {
2200Sstevel@tonic-gate DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED);
2210Sstevel@tonic-gate /* We should push the value back onto the stack in
2220Sstevel@tonic-gate * case of a retry. */
2230Sstevel@tonic-gate sk_push(dso->meth_data, (char *)p);
2240Sstevel@tonic-gate return(0);
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate /* Cleanup */
2270Sstevel@tonic-gate OPENSSL_free(p);
2280Sstevel@tonic-gate return(1);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate /* Using GetProcAddress for variables? TODO: Check this out in
2320Sstevel@tonic-gate * the Win32 API docs, there's probably a variant for variables. */
win32_bind_var(DSO * dso,const char * symname)2330Sstevel@tonic-gate static void *win32_bind_var(DSO *dso, const char *symname)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate HINSTANCE *ptr;
2360Sstevel@tonic-gate void *sym;
2370Sstevel@tonic-gate
2380Sstevel@tonic-gate if((dso == NULL) || (symname == NULL))
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
2410Sstevel@tonic-gate return(NULL);
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate if(sk_num(dso->meth_data) < 1)
2440Sstevel@tonic-gate {
2450Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
2460Sstevel@tonic-gate return(NULL);
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
2490Sstevel@tonic-gate if(ptr == NULL)
2500Sstevel@tonic-gate {
2510Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE);
2520Sstevel@tonic-gate return(NULL);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate sym = GetProcAddress(*ptr, symname);
2550Sstevel@tonic-gate if(sym == NULL)
2560Sstevel@tonic-gate {
2570Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE);
2580Sstevel@tonic-gate ERR_add_error_data(3, "symname(", symname, ")");
2590Sstevel@tonic-gate return(NULL);
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate return(sym);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate
win32_bind_func(DSO * dso,const char * symname)2640Sstevel@tonic-gate static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
2650Sstevel@tonic-gate {
2660Sstevel@tonic-gate HINSTANCE *ptr;
2670Sstevel@tonic-gate void *sym;
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate if((dso == NULL) || (symname == NULL))
2700Sstevel@tonic-gate {
2710Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
2720Sstevel@tonic-gate return(NULL);
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate if(sk_num(dso->meth_data) < 1)
2750Sstevel@tonic-gate {
2760Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
2770Sstevel@tonic-gate return(NULL);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
2800Sstevel@tonic-gate if(ptr == NULL)
2810Sstevel@tonic-gate {
2820Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE);
2830Sstevel@tonic-gate return(NULL);
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate sym = GetProcAddress(*ptr, symname);
2860Sstevel@tonic-gate if(sym == NULL)
2870Sstevel@tonic-gate {
2880Sstevel@tonic-gate DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE);
2890Sstevel@tonic-gate ERR_add_error_data(3, "symname(", symname, ")");
2900Sstevel@tonic-gate return(NULL);
2910Sstevel@tonic-gate }
2920Sstevel@tonic-gate return((DSO_FUNC_TYPE)sym);
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate
295*2139Sjp161948 struct file_st
296*2139Sjp161948 {
297*2139Sjp161948 const char *node; int nodelen;
298*2139Sjp161948 const char *device; int devicelen;
299*2139Sjp161948 const char *predir; int predirlen;
300*2139Sjp161948 const char *dir; int dirlen;
301*2139Sjp161948 const char *file; int filelen;
302*2139Sjp161948 };
303*2139Sjp161948
win32_splitter(DSO * dso,const char * filename,int assume_last_is_dir)304*2139Sjp161948 static struct file_st *win32_splitter(DSO *dso, const char *filename,
305*2139Sjp161948 int assume_last_is_dir)
306*2139Sjp161948 {
307*2139Sjp161948 struct file_st *result = NULL;
308*2139Sjp161948 enum { IN_NODE, IN_DEVICE, IN_FILE } position;
309*2139Sjp161948 const char *start = filename;
310*2139Sjp161948
311*2139Sjp161948 if (!filename)
312*2139Sjp161948 {
313*2139Sjp161948 DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME);
314*2139Sjp161948 /*goto err;*/
315*2139Sjp161948 return(NULL);
316*2139Sjp161948 }
317*2139Sjp161948
318*2139Sjp161948 result = OPENSSL_malloc(sizeof(struct file_st));
319*2139Sjp161948 if(result == NULL)
320*2139Sjp161948 {
321*2139Sjp161948 DSOerr(DSO_F_WIN32_SPLITTER,
322*2139Sjp161948 ERR_R_MALLOC_FAILURE);
323*2139Sjp161948 return(NULL);
324*2139Sjp161948 }
325*2139Sjp161948
326*2139Sjp161948 memset(result, 0, sizeof(struct file_st));
327*2139Sjp161948 position = IN_DEVICE;
328*2139Sjp161948
329*2139Sjp161948 if(filename[0] == '\\' && filename[1] == '\\'
330*2139Sjp161948 || filename[0] == '/' && filename[1] == '/')
331*2139Sjp161948 {
332*2139Sjp161948 position = IN_NODE;
333*2139Sjp161948 filename += 2;
334*2139Sjp161948 start = filename;
335*2139Sjp161948 result->node = start;
336*2139Sjp161948 }
337*2139Sjp161948
338*2139Sjp161948 do
339*2139Sjp161948 {
340*2139Sjp161948 switch(filename[0])
341*2139Sjp161948 {
342*2139Sjp161948 case ':':
343*2139Sjp161948 if(position != IN_DEVICE)
344*2139Sjp161948 {
345*2139Sjp161948 DSOerr(DSO_F_WIN32_SPLITTER,
346*2139Sjp161948 DSO_R_INCORRECT_FILE_SYNTAX);
347*2139Sjp161948 /*goto err;*/
348*2139Sjp161948 return(NULL);
349*2139Sjp161948 }
350*2139Sjp161948 result->device = start;
351*2139Sjp161948 result->devicelen = filename - start;
352*2139Sjp161948 position = IN_FILE;
353*2139Sjp161948 start = ++filename;
354*2139Sjp161948 result->dir = start;
355*2139Sjp161948 break;
356*2139Sjp161948 case '\\':
357*2139Sjp161948 case '/':
358*2139Sjp161948 if(position == IN_NODE)
359*2139Sjp161948 {
360*2139Sjp161948 result->nodelen = filename - start;
361*2139Sjp161948 position = IN_FILE;
362*2139Sjp161948 start = ++filename;
363*2139Sjp161948 result->dir = start;
364*2139Sjp161948 }
365*2139Sjp161948 else
366*2139Sjp161948 {
367*2139Sjp161948 filename++;
368*2139Sjp161948 result->dirlen += filename - start;
369*2139Sjp161948 }
370*2139Sjp161948 break;
371*2139Sjp161948 case '\0':
372*2139Sjp161948 if(position == IN_NODE)
373*2139Sjp161948 {
374*2139Sjp161948 result->nodelen = filename - start;
375*2139Sjp161948 }
376*2139Sjp161948 else
377*2139Sjp161948 {
378*2139Sjp161948 if(filename - start > 0)
379*2139Sjp161948 {
380*2139Sjp161948 if (assume_last_is_dir)
381*2139Sjp161948 {
382*2139Sjp161948 result->devicelen += filename - start;
383*2139Sjp161948 }
384*2139Sjp161948 else
385*2139Sjp161948 {
386*2139Sjp161948 result->file = start;
387*2139Sjp161948 result->filelen = filename - start;
388*2139Sjp161948 }
389*2139Sjp161948 }
390*2139Sjp161948 }
391*2139Sjp161948 break;
392*2139Sjp161948 default:
393*2139Sjp161948 filename++;
394*2139Sjp161948 break;
395*2139Sjp161948 }
396*2139Sjp161948 }
397*2139Sjp161948 while(*filename);
398*2139Sjp161948
399*2139Sjp161948 if(!result->nodelen) result->node = NULL;
400*2139Sjp161948 if(!result->devicelen) result->device = NULL;
401*2139Sjp161948 if(!result->dirlen) result->dir = NULL;
402*2139Sjp161948 if(!result->filelen) result->file = NULL;
403*2139Sjp161948
404*2139Sjp161948 return(result);
405*2139Sjp161948 }
406*2139Sjp161948
win32_joiner(DSO * dso,const struct file_st * file_split)407*2139Sjp161948 static char *win32_joiner(DSO *dso, const struct file_st *file_split)
408*2139Sjp161948 {
409*2139Sjp161948 int len = 0, offset = 0;
410*2139Sjp161948 char *result = NULL;
411*2139Sjp161948 const char *start;
412*2139Sjp161948
413*2139Sjp161948 if(!file_split)
414*2139Sjp161948 {
415*2139Sjp161948 DSOerr(DSO_F_WIN32_JOINER,
416*2139Sjp161948 ERR_R_PASSED_NULL_PARAMETER);
417*2139Sjp161948 return(NULL);
418*2139Sjp161948 }
419*2139Sjp161948 if(file_split->node)
420*2139Sjp161948 {
421*2139Sjp161948 len += 2 + file_split->nodelen; /* 2 for starting \\ */
422*2139Sjp161948 if(file_split->predir || file_split->dir || file_split->file)
423*2139Sjp161948 len++; /* 1 for ending \ */
424*2139Sjp161948 }
425*2139Sjp161948 else if(file_split->device)
426*2139Sjp161948 {
427*2139Sjp161948 len += file_split->devicelen + 1; /* 1 for ending : */
428*2139Sjp161948 }
429*2139Sjp161948 len += file_split->predirlen;
430*2139Sjp161948 if(file_split->predir && (file_split->dir || file_split->file))
431*2139Sjp161948 {
432*2139Sjp161948 len++; /* 1 for ending \ */
433*2139Sjp161948 }
434*2139Sjp161948 len += file_split->dirlen;
435*2139Sjp161948 if(file_split->dir && file_split->file)
436*2139Sjp161948 {
437*2139Sjp161948 len++; /* 1 for ending \ */
438*2139Sjp161948 }
439*2139Sjp161948 len += file_split->filelen;
440*2139Sjp161948
441*2139Sjp161948 if(!len)
442*2139Sjp161948 {
443*2139Sjp161948 DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
444*2139Sjp161948 return(NULL);
445*2139Sjp161948 }
446*2139Sjp161948
447*2139Sjp161948 result = OPENSSL_malloc(len + 1);
448*2139Sjp161948 if (!result)
449*2139Sjp161948 {
450*2139Sjp161948 DSOerr(DSO_F_WIN32_JOINER,
451*2139Sjp161948 ERR_R_MALLOC_FAILURE);
452*2139Sjp161948 return(NULL);
453*2139Sjp161948 }
454*2139Sjp161948
455*2139Sjp161948 if(file_split->node)
456*2139Sjp161948 {
457*2139Sjp161948 strcpy(&result[offset], "\\\\"); offset += 2;
458*2139Sjp161948 strncpy(&result[offset], file_split->node,
459*2139Sjp161948 file_split->nodelen); offset += file_split->nodelen;
460*2139Sjp161948 if(file_split->predir || file_split->dir || file_split->file)
461*2139Sjp161948 {
462*2139Sjp161948 result[offset] = '\\'; offset++;
463*2139Sjp161948 }
464*2139Sjp161948 }
465*2139Sjp161948 else if(file_split->device)
466*2139Sjp161948 {
467*2139Sjp161948 strncpy(&result[offset], file_split->device,
468*2139Sjp161948 file_split->devicelen); offset += file_split->devicelen;
469*2139Sjp161948 result[offset] = ':'; offset++;
470*2139Sjp161948 }
471*2139Sjp161948 start = file_split->predir;
472*2139Sjp161948 while(file_split->predirlen > (start - file_split->predir))
473*2139Sjp161948 {
474*2139Sjp161948 const char *end = openssl_strnchr(start, '/',
475*2139Sjp161948 file_split->predirlen - (start - file_split->predir));
476*2139Sjp161948 if(!end)
477*2139Sjp161948 end = start
478*2139Sjp161948 + file_split->predirlen
479*2139Sjp161948 - (start - file_split->predir);
480*2139Sjp161948 strncpy(&result[offset], start,
481*2139Sjp161948 end - start); offset += end - start;
482*2139Sjp161948 result[offset] = '\\'; offset++;
483*2139Sjp161948 start = end + 1;
484*2139Sjp161948 }
485*2139Sjp161948 if(file_split->predir && (file_split->dir || file_split->file))
486*2139Sjp161948 {
487*2139Sjp161948 result[offset] = '\\'; offset++;
488*2139Sjp161948 }
489*2139Sjp161948 start = file_split->dir;
490*2139Sjp161948 while(file_split->dirlen > (start - file_split->dir))
491*2139Sjp161948 {
492*2139Sjp161948 const char *end = openssl_strnchr(start, '/',
493*2139Sjp161948 file_split->dirlen - (start - file_split->dir));
494*2139Sjp161948 if(!end)
495*2139Sjp161948 end = start
496*2139Sjp161948 + file_split->dirlen
497*2139Sjp161948 - (start - file_split->dir);
498*2139Sjp161948 strncpy(&result[offset], start,
499*2139Sjp161948 end - start); offset += end - start;
500*2139Sjp161948 result[offset] = '\\'; offset++;
501*2139Sjp161948 start = end + 1;
502*2139Sjp161948 }
503*2139Sjp161948 if(file_split->dir && file_split->file)
504*2139Sjp161948 {
505*2139Sjp161948 result[offset] = '\\'; offset++;
506*2139Sjp161948 }
507*2139Sjp161948 strncpy(&result[offset], file_split->file,
508*2139Sjp161948 file_split->filelen); offset += file_split->filelen;
509*2139Sjp161948 result[offset] = '\0';
510*2139Sjp161948 return(result);
511*2139Sjp161948 }
512*2139Sjp161948
win32_merger(DSO * dso,const char * filespec1,const char * filespec2)513*2139Sjp161948 static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
514*2139Sjp161948 {
515*2139Sjp161948 char *merged = NULL;
516*2139Sjp161948 struct file_st *filespec1_split = NULL;
517*2139Sjp161948 struct file_st *filespec2_split = NULL;
518*2139Sjp161948
519*2139Sjp161948 if(!filespec1 && !filespec2)
520*2139Sjp161948 {
521*2139Sjp161948 DSOerr(DSO_F_WIN32_MERGER,
522*2139Sjp161948 ERR_R_PASSED_NULL_PARAMETER);
523*2139Sjp161948 return(NULL);
524*2139Sjp161948 }
525*2139Sjp161948 if (!filespec2)
526*2139Sjp161948 {
527*2139Sjp161948 merged = OPENSSL_malloc(strlen(filespec1) + 1);
528*2139Sjp161948 if(!merged)
529*2139Sjp161948 {
530*2139Sjp161948 DSOerr(DSO_F_WIN32_MERGER,
531*2139Sjp161948 ERR_R_MALLOC_FAILURE);
532*2139Sjp161948 return(NULL);
533*2139Sjp161948 }
534*2139Sjp161948 strcpy(merged, filespec1);
535*2139Sjp161948 }
536*2139Sjp161948 else if (!filespec1)
537*2139Sjp161948 {
538*2139Sjp161948 merged = OPENSSL_malloc(strlen(filespec2) + 1);
539*2139Sjp161948 if(!merged)
540*2139Sjp161948 {
541*2139Sjp161948 DSOerr(DSO_F_WIN32_MERGER,
542*2139Sjp161948 ERR_R_MALLOC_FAILURE);
543*2139Sjp161948 return(NULL);
544*2139Sjp161948 }
545*2139Sjp161948 strcpy(merged, filespec2);
546*2139Sjp161948 }
547*2139Sjp161948 else
548*2139Sjp161948 {
549*2139Sjp161948 filespec1_split = win32_splitter(dso, filespec1, 1);
550*2139Sjp161948 if (!filespec1_split)
551*2139Sjp161948 {
552*2139Sjp161948 DSOerr(DSO_F_WIN32_MERGER,
553*2139Sjp161948 ERR_R_MALLOC_FAILURE);
554*2139Sjp161948 return(NULL);
555*2139Sjp161948 }
556*2139Sjp161948 filespec2_split = win32_splitter(dso, filespec2, 0);
557*2139Sjp161948 if (!filespec1_split)
558*2139Sjp161948 {
559*2139Sjp161948 DSOerr(DSO_F_WIN32_MERGER,
560*2139Sjp161948 ERR_R_MALLOC_FAILURE);
561*2139Sjp161948 OPENSSL_free(filespec1_split);
562*2139Sjp161948 return(NULL);
563*2139Sjp161948 }
564*2139Sjp161948
565*2139Sjp161948 /* Fill in into filespec1_split */
566*2139Sjp161948 if (!filespec1_split->node && !filespec1_split->device)
567*2139Sjp161948 {
568*2139Sjp161948 filespec1_split->node = filespec2_split->node;
569*2139Sjp161948 filespec1_split->nodelen = filespec2_split->nodelen;
570*2139Sjp161948 filespec1_split->device = filespec2_split->device;
571*2139Sjp161948 filespec1_split->devicelen = filespec2_split->devicelen;
572*2139Sjp161948 }
573*2139Sjp161948 if (!filespec1_split->dir)
574*2139Sjp161948 {
575*2139Sjp161948 filespec1_split->dir = filespec2_split->dir;
576*2139Sjp161948 filespec1_split->dirlen = filespec2_split->dirlen;
577*2139Sjp161948 }
578*2139Sjp161948 else if (filespec1_split->dir[0] != '\\'
579*2139Sjp161948 && filespec1_split->dir[0] != '/')
580*2139Sjp161948 {
581*2139Sjp161948 filespec1_split->predir = filespec2_split->dir;
582*2139Sjp161948 filespec1_split->predirlen = filespec2_split->dirlen;
583*2139Sjp161948 }
584*2139Sjp161948 if (!filespec1_split->file)
585*2139Sjp161948 {
586*2139Sjp161948 filespec1_split->file = filespec2_split->file;
587*2139Sjp161948 filespec1_split->filelen = filespec2_split->filelen;
588*2139Sjp161948 }
589*2139Sjp161948
590*2139Sjp161948 merged = win32_joiner(dso, filespec1_split);
591*2139Sjp161948 }
592*2139Sjp161948 return(merged);
593*2139Sjp161948 }
594*2139Sjp161948
win32_name_converter(DSO * dso,const char * filename)5950Sstevel@tonic-gate static char *win32_name_converter(DSO *dso, const char *filename)
5960Sstevel@tonic-gate {
5970Sstevel@tonic-gate char *translated;
5980Sstevel@tonic-gate int len, transform;
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate len = strlen(filename);
6010Sstevel@tonic-gate transform = ((strstr(filename, "/") == NULL) &&
6020Sstevel@tonic-gate (strstr(filename, "\\") == NULL) &&
6030Sstevel@tonic-gate (strstr(filename, ":") == NULL));
6040Sstevel@tonic-gate if(transform)
6050Sstevel@tonic-gate /* We will convert this to "%s.dll" */
6060Sstevel@tonic-gate translated = OPENSSL_malloc(len + 5);
6070Sstevel@tonic-gate else
6080Sstevel@tonic-gate /* We will simply duplicate filename */
6090Sstevel@tonic-gate translated = OPENSSL_malloc(len + 1);
6100Sstevel@tonic-gate if(translated == NULL)
6110Sstevel@tonic-gate {
6120Sstevel@tonic-gate DSOerr(DSO_F_WIN32_NAME_CONVERTER,
6130Sstevel@tonic-gate DSO_R_NAME_TRANSLATION_FAILED);
6140Sstevel@tonic-gate return(NULL);
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate if(transform)
6170Sstevel@tonic-gate sprintf(translated, "%s.dll", filename);
6180Sstevel@tonic-gate else
6190Sstevel@tonic-gate sprintf(translated, "%s", filename);
6200Sstevel@tonic-gate return(translated);
6210Sstevel@tonic-gate }
6220Sstevel@tonic-gate
openssl_strnchr(const char * string,int c,size_t len)623*2139Sjp161948 static const char *openssl_strnchr(const char *string, int c, size_t len)
624*2139Sjp161948 {
625*2139Sjp161948 size_t i;
626*2139Sjp161948 const char *p;
627*2139Sjp161948 for (i = 0, p = string; i < len && *p; i++, p++)
628*2139Sjp161948 {
629*2139Sjp161948 if (*p == c)
630*2139Sjp161948 return p;
631*2139Sjp161948 }
632*2139Sjp161948 return NULL;
633*2139Sjp161948 }
634*2139Sjp161948
635*2139Sjp161948
6360Sstevel@tonic-gate #endif /* OPENSSL_SYS_WIN32 */
637