dso_win32.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:16k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
  2. /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
  3.  * project 2000.
  4.  */
  5. /* ====================================================================
  6.  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  *
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer. 
  14.  *
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in
  17.  *    the documentation and/or other materials provided with the
  18.  *    distribution.
  19.  *
  20.  * 3. All advertising materials mentioning features or use of this
  21.  *    software must display the following acknowledgment:
  22.  *    "This product includes software developed by the OpenSSL Project
  23.  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24.  *
  25.  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26.  *    endorse or promote products derived from this software without
  27.  *    prior written permission. For written permission, please contact
  28.  *    licensing@OpenSSL.org.
  29.  *
  30.  * 5. Products derived from this software may not be called "OpenSSL"
  31.  *    nor may "OpenSSL" appear in their names without prior written
  32.  *    permission of the OpenSSL Project.
  33.  *
  34.  * 6. Redistributions of any form whatsoever must retain the following
  35.  *    acknowledgment:
  36.  *    "This product includes software developed by the OpenSSL Project
  37.  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38.  *
  39.  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  51.  * ====================================================================
  52.  *
  53.  * This product includes cryptographic software written by Eric Young
  54.  * (eay@cryptsoft.com).  This product includes software written by Tim
  55.  * Hudson (tjh@cryptsoft.com).
  56.  *
  57.  */
  58. #include <stdio.h>
  59. #include <string.h>
  60. #include "cryptlib.h"
  61. #include <openssl/dso.h>
  62. #if !defined(DSO_WIN32)
  63. DSO_METHOD *DSO_METHOD_win32(void)
  64. {
  65. return NULL;
  66. }
  67. #else
  68. #ifdef _WIN32_WCE
  69. # if _WIN32_WCE < 300
  70. static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
  71. {
  72. WCHAR lpProcNameW[64];
  73. int i;
  74. for (i=0;lpProcName[i] && i<64;i++)
  75. lpProcNameW[i] = (WCHAR)lpProcName[i];
  76. if (i==64) return NULL;
  77. lpProcNameW[i] = 0;
  78. return GetProcAddressW(hModule,lpProcNameW);
  79. }
  80. # endif
  81. # undef GetProcAddress
  82. # define GetProcAddress GetProcAddressA
  83. static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
  84. {
  85. WCHAR *fnamw;
  86. size_t len_0=strlen(lpLibFileName)+1,i;
  87. #ifdef _MSC_VER
  88. fnamw = (WCHAR *)_alloca (len_0*sizeof(WCHAR));
  89. #else
  90. fnamw = (WCHAR *)alloca (len_0*sizeof(WCHAR));
  91. #endif
  92. if (fnamw == NULL) return NULL;
  93. #if defined(_WIN32_WCE) && _WIN32_WCE>=101
  94. if (!MultiByteToWideChar(CP_ACP,0,lpLibFileName,len_0,fnamw,len_0))
  95. #endif
  96. for (i=0;i<len_0;i++) fnamw[i]=(WCHAR)lpLibFileName[i];
  97. return LoadLibraryW(fnamw);
  98. }
  99. #endif
  100. /* Part of the hack in "win32_load" ... */
  101. #define DSO_MAX_TRANSLATED_SIZE 256
  102. static int win32_load(DSO *dso);
  103. static int win32_unload(DSO *dso);
  104. static void *win32_bind_var(DSO *dso, const char *symname);
  105. static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
  106. #if 0
  107. static int win32_unbind_var(DSO *dso, char *symname, void *symptr);
  108. static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
  109. static int win32_init(DSO *dso);
  110. static int win32_finish(DSO *dso);
  111. static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
  112. #endif
  113. static char *win32_name_converter(DSO *dso, const char *filename);
  114. static char *win32_merger(DSO *dso, const char *filespec1,
  115. const char *filespec2);
  116. static const char *openssl_strnchr(const char *string, int c, size_t len);
  117. static DSO_METHOD dso_meth_win32 = {
  118. "OpenSSL 'win32' shared library method",
  119. win32_load,
  120. win32_unload,
  121. win32_bind_var,
  122. win32_bind_func,
  123. /* For now, "unbind" doesn't exist */
  124. #if 0
  125. NULL, /* unbind_var */
  126. NULL, /* unbind_func */
  127. #endif
  128. NULL, /* ctrl */
  129. win32_name_converter,
  130. win32_merger,
  131. NULL, /* init */
  132. NULL  /* finish */
  133. };
  134. DSO_METHOD *DSO_METHOD_win32(void)
  135. {
  136. return(&dso_meth_win32);
  137. }
  138. /* For this DSO_METHOD, our meth_data STACK will contain;
  139.  * (i) a pointer to the handle (HINSTANCE) returned from
  140.  *     LoadLibrary(), and copied.
  141.  */
  142. static int win32_load(DSO *dso)
  143. {
  144. HINSTANCE h = NULL, *p = NULL;
  145. /* See applicable comments from dso_dl.c */
  146. char *filename = DSO_convert_filename(dso, NULL);
  147. if(filename == NULL)
  148. {
  149. DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
  150. goto err;
  151. }
  152. h = LoadLibraryA(filename);
  153. if(h == NULL)
  154. {
  155. DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
  156. ERR_add_error_data(3, "filename(", filename, ")");
  157. goto err;
  158. }
  159. p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE));
  160. if(p == NULL)
  161. {
  162. DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE);
  163. goto err;
  164. }
  165. *p = h;
  166. if(!sk_push(dso->meth_data, (char *)p))
  167. {
  168. DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR);
  169. goto err;
  170. }
  171. /* Success */
  172. dso->loaded_filename = filename;
  173. return(1);
  174. err:
  175. /* Cleanup !*/
  176. if(filename != NULL)
  177. OPENSSL_free(filename);
  178. if(p != NULL)
  179. OPENSSL_free(p);
  180. if(h != NULL)
  181. FreeLibrary(h);
  182. return(0);
  183. }
  184. static int win32_unload(DSO *dso)
  185. {
  186. HINSTANCE *p;
  187. if(dso == NULL)
  188. {
  189. DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
  190. return(0);
  191. }
  192. if(sk_num(dso->meth_data) < 1)
  193. return(1);
  194. p = (HINSTANCE *)sk_pop(dso->meth_data);
  195. if(p == NULL)
  196. {
  197. DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE);
  198. return(0);
  199. }
  200. if(!FreeLibrary(*p))
  201. {
  202. DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED);
  203. /* We should push the value back onto the stack in
  204.  * case of a retry. */
  205. sk_push(dso->meth_data, (char *)p);
  206. return(0);
  207. }
  208. /* Cleanup */
  209. OPENSSL_free(p);
  210. return(1);
  211. }
  212. /* Using GetProcAddress for variables? TODO: Check this out in
  213.  * the Win32 API docs, there's probably a variant for variables. */
  214. static void *win32_bind_var(DSO *dso, const char *symname)
  215. {
  216. HINSTANCE *ptr;
  217. void *sym;
  218. if((dso == NULL) || (symname == NULL))
  219. {
  220. DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
  221. return(NULL);
  222. }
  223. if(sk_num(dso->meth_data) < 1)
  224. {
  225. DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR);
  226. return(NULL);
  227. }
  228. ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
  229. if(ptr == NULL)
  230. {
  231. DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE);
  232. return(NULL);
  233. }
  234. sym = GetProcAddress(*ptr, symname);
  235. if(sym == NULL)
  236. {
  237. DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE);
  238. ERR_add_error_data(3, "symname(", symname, ")");
  239. return(NULL);
  240. }
  241. return(sym);
  242. }
  243. static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
  244. {
  245. HINSTANCE *ptr;
  246. void *sym;
  247. if((dso == NULL) || (symname == NULL))
  248. {
  249. DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
  250. return(NULL);
  251. }
  252. if(sk_num(dso->meth_data) < 1)
  253. {
  254. DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR);
  255. return(NULL);
  256. }
  257. ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
  258. if(ptr == NULL)
  259. {
  260. DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE);
  261. return(NULL);
  262. }
  263. sym = GetProcAddress(*ptr, symname);
  264. if(sym == NULL)
  265. {
  266. DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE);
  267. ERR_add_error_data(3, "symname(", symname, ")");
  268. return(NULL);
  269. }
  270. return((DSO_FUNC_TYPE)sym);
  271. }
  272. struct file_st
  273. {
  274. const char *node; int nodelen;
  275. const char *device; int devicelen;
  276. const char *predir; int predirlen;
  277. const char *dir; int dirlen;
  278. const char *file; int filelen;
  279. };
  280. static struct file_st *win32_splitter(DSO *dso, const char *filename,
  281. int assume_last_is_dir)
  282. {
  283. struct file_st *result = NULL;
  284. enum { IN_NODE, IN_DEVICE, IN_FILE } position;
  285. const char *start = filename;
  286. char last;
  287. if (!filename)
  288. {
  289. DSOerr(DSO_F_WIN32_SPLITTER,DSO_R_NO_FILENAME);
  290. /*goto err;*/
  291. return(NULL);
  292. }
  293. result = OPENSSL_malloc(sizeof(struct file_st));
  294. if(result == NULL)
  295. {
  296. DSOerr(DSO_F_WIN32_SPLITTER,
  297. ERR_R_MALLOC_FAILURE);
  298. return(NULL);
  299. }
  300. memset(result, 0, sizeof(struct file_st));
  301. position = IN_DEVICE;
  302. if(filename[0] == '\' && filename[1] == '\'
  303. || filename[0] == '/' && filename[1] == '/')
  304. {
  305. position = IN_NODE;
  306. filename += 2;
  307. start = filename;
  308. result->node = start;
  309. }
  310. do
  311. {
  312. last = filename[0];
  313. switch(last)
  314. {
  315. case ':':
  316. if(position != IN_DEVICE)
  317. {
  318. DSOerr(DSO_F_WIN32_SPLITTER,
  319. DSO_R_INCORRECT_FILE_SYNTAX);
  320. /*goto err;*/
  321. return(NULL);
  322. }
  323. result->device = start;
  324. result->devicelen = filename - start;
  325. position = IN_FILE;
  326. start = ++filename;
  327. result->dir = start;
  328. break;
  329. case '\':
  330. case '/':
  331. if(position == IN_NODE)
  332. {
  333. result->nodelen = filename - start;
  334. position = IN_FILE;
  335. start = ++filename;
  336. result->dir = start;
  337. }
  338. else if(position == IN_DEVICE)
  339. {
  340. position = IN_FILE;
  341. filename++;
  342. result->dir = start;
  343. result->dirlen = filename - start;
  344. start = filename;
  345. }
  346. else
  347. {
  348. filename++;
  349. result->dirlen += filename - start;
  350. start = filename;
  351. }
  352. break;
  353. case '':
  354. if(position == IN_NODE)
  355. {
  356. result->nodelen = filename - start;
  357. }
  358. else
  359. {
  360. if(filename - start > 0)
  361. {
  362. if (assume_last_is_dir)
  363. {
  364. if (position == IN_DEVICE)
  365. {
  366. result->dir = start;
  367. result->dirlen = 0;
  368. }
  369. result->dirlen +=
  370. filename - start;
  371. }
  372. else
  373. {
  374. result->file = start;
  375. result->filelen =
  376. filename - start;
  377. }
  378. }
  379. }
  380. break;
  381. default:
  382. filename++;
  383. break;
  384. }
  385. }
  386. while(last);
  387. if(!result->nodelen) result->node = NULL;
  388. if(!result->devicelen) result->device = NULL;
  389. if(!result->dirlen) result->dir = NULL;
  390. if(!result->filelen) result->file = NULL;
  391. return(result);
  392. }
  393. static char *win32_joiner(DSO *dso, const struct file_st *file_split)
  394. {
  395. int len = 0, offset = 0;
  396. char *result = NULL;
  397. const char *start;
  398. if(!file_split)
  399. {
  400. DSOerr(DSO_F_WIN32_JOINER,
  401. ERR_R_PASSED_NULL_PARAMETER);
  402. return(NULL);
  403. }
  404. if(file_split->node)
  405. {
  406. len += 2 + file_split->nodelen; /* 2 for starting \ */
  407. if(file_split->predir || file_split->dir || file_split->file)
  408. len++; /* 1 for ending  */
  409. }
  410. else if(file_split->device)
  411. {
  412. len += file_split->devicelen + 1; /* 1 for ending : */
  413. }
  414. len += file_split->predirlen;
  415. if(file_split->predir && (file_split->dir || file_split->file))
  416. {
  417. len++; /* 1 for ending  */
  418. }
  419. len += file_split->dirlen;
  420. if(file_split->dir && file_split->file)
  421. {
  422. len++; /* 1 for ending  */
  423. }
  424. len += file_split->filelen;
  425. if(!len)
  426. {
  427. DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
  428. return(NULL);
  429. }
  430. result = OPENSSL_malloc(len + 1);
  431. if (!result)
  432. {
  433. DSOerr(DSO_F_WIN32_JOINER,
  434. ERR_R_MALLOC_FAILURE);
  435. return(NULL);
  436. }
  437. if(file_split->node)
  438. {
  439. strcpy(&result[offset], "\\"); offset += 2;
  440. strncpy(&result[offset], file_split->node,
  441. file_split->nodelen); offset += file_split->nodelen;
  442. if(file_split->predir || file_split->dir || file_split->file)
  443. {
  444. result[offset] = '\'; offset++;
  445. }
  446. }
  447. else if(file_split->device)
  448. {
  449. strncpy(&result[offset], file_split->device,
  450. file_split->devicelen); offset += file_split->devicelen;
  451. result[offset] = ':'; offset++;
  452. }
  453. start = file_split->predir;
  454. while(file_split->predirlen > (start - file_split->predir))
  455. {
  456. const char *end = openssl_strnchr(start, '/',
  457. file_split->predirlen - (start - file_split->predir));
  458. if(!end)
  459. end = start
  460. + file_split->predirlen
  461. - (start - file_split->predir);
  462. strncpy(&result[offset], start,
  463. end - start); offset += end - start;
  464. result[offset] = '\'; offset++;
  465. start = end + 1;
  466. }
  467. #if 0 /* Not needed, since the directory converter above already appeneded
  468.  a backslash */
  469. if(file_split->predir && (file_split->dir || file_split->file))
  470. {
  471. result[offset] = '\'; offset++;
  472. }
  473. #endif
  474. start = file_split->dir;
  475. while(file_split->dirlen > (start - file_split->dir))
  476. {
  477. const char *end = openssl_strnchr(start, '/',
  478. file_split->dirlen - (start - file_split->dir));
  479. if(!end)
  480. end = start
  481. + file_split->dirlen
  482. - (start - file_split->dir);
  483. strncpy(&result[offset], start,
  484. end - start); offset += end - start;
  485. result[offset] = '\'; offset++;
  486. start = end + 1;
  487. }
  488. #if 0 /* Not needed, since the directory converter above already appeneded
  489.  a backslash */
  490. if(file_split->dir && file_split->file)
  491. {
  492. result[offset] = '\'; offset++;
  493. }
  494. #endif
  495. strncpy(&result[offset], file_split->file,
  496. file_split->filelen); offset += file_split->filelen;
  497. result[offset] = '';
  498. return(result);
  499. }
  500. static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
  501. {
  502. char *merged = NULL;
  503. struct file_st *filespec1_split = NULL;
  504. struct file_st *filespec2_split = NULL;
  505. if(!filespec1 && !filespec2)
  506. {
  507. DSOerr(DSO_F_WIN32_MERGER,
  508. ERR_R_PASSED_NULL_PARAMETER);
  509. return(NULL);
  510. }
  511. if (!filespec2)
  512. {
  513. merged = OPENSSL_malloc(strlen(filespec1) + 1);
  514. if(!merged)
  515. {
  516. DSOerr(DSO_F_WIN32_MERGER,
  517. ERR_R_MALLOC_FAILURE);
  518. return(NULL);
  519. }
  520. strcpy(merged, filespec1);
  521. }
  522. else if (!filespec1)
  523. {
  524. merged = OPENSSL_malloc(strlen(filespec2) + 1);
  525. if(!merged)
  526. {
  527. DSOerr(DSO_F_WIN32_MERGER,
  528. ERR_R_MALLOC_FAILURE);
  529. return(NULL);
  530. }
  531. strcpy(merged, filespec2);
  532. }
  533. else
  534. {
  535. filespec1_split = win32_splitter(dso, filespec1, 0);
  536. if (!filespec1_split)
  537. {
  538. DSOerr(DSO_F_WIN32_MERGER,
  539. ERR_R_MALLOC_FAILURE);
  540. return(NULL);
  541. }
  542. filespec2_split = win32_splitter(dso, filespec2, 1);
  543. if (!filespec2_split)
  544. {
  545. DSOerr(DSO_F_WIN32_MERGER,
  546. ERR_R_MALLOC_FAILURE);
  547. OPENSSL_free(filespec1_split);
  548. return(NULL);
  549. }
  550. /* Fill in into filespec1_split */
  551. if (!filespec1_split->node && !filespec1_split->device)
  552. {
  553. filespec1_split->node = filespec2_split->node;
  554. filespec1_split->nodelen = filespec2_split->nodelen;
  555. filespec1_split->device = filespec2_split->device;
  556. filespec1_split->devicelen = filespec2_split->devicelen;
  557. }
  558. if (!filespec1_split->dir)
  559. {
  560. filespec1_split->dir = filespec2_split->dir;
  561. filespec1_split->dirlen = filespec2_split->dirlen;
  562. }
  563. else if (filespec1_split->dir[0] != '\'
  564. && filespec1_split->dir[0] != '/')
  565. {
  566. filespec1_split->predir = filespec2_split->dir;
  567. filespec1_split->predirlen = filespec2_split->dirlen;
  568. }
  569. if (!filespec1_split->file)
  570. {
  571. filespec1_split->file = filespec2_split->file;
  572. filespec1_split->filelen = filespec2_split->filelen;
  573. }
  574. merged = win32_joiner(dso, filespec1_split);
  575. }
  576. return(merged);
  577. }
  578. static char *win32_name_converter(DSO *dso, const char *filename)
  579. {
  580. char *translated;
  581. int len, transform;
  582. len = strlen(filename);
  583. transform = ((strstr(filename, "/") == NULL) &&
  584. (strstr(filename, "\") == NULL) &&
  585. (strstr(filename, ":") == NULL));
  586. if(transform)
  587. /* We will convert this to "%s.dll" */
  588. translated = OPENSSL_malloc(len + 5);
  589. else
  590. /* We will simply duplicate filename */
  591. translated = OPENSSL_malloc(len + 1);
  592. if(translated == NULL)
  593. {
  594. DSOerr(DSO_F_WIN32_NAME_CONVERTER,
  595. DSO_R_NAME_TRANSLATION_FAILED); 
  596. return(NULL);   
  597. }
  598. if(transform)
  599. sprintf(translated, "%s.dll", filename);
  600. else
  601. sprintf(translated, "%s", filename);
  602. return(translated);
  603. }
  604. static const char *openssl_strnchr(const char *string, int c, size_t len)
  605. {
  606. size_t i;
  607. const char *p;
  608. for (i = 0, p = string; i < len && *p; i++, p++)
  609. {
  610. if (*p == c)
  611. return p;
  612. }
  613. return NULL;
  614. }
  615. #endif /* OPENSSL_SYS_WIN32 */