tkWin32Dll.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tkWin32Dll.c --
  3.  *
  4.  * This file contains a stub dll entry point.
  5.  *
  6.  * Copyright (c) 1995 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * RCS: @(#) $Id: tkWin32Dll.c,v 1.6.2.3 2005/08/23 18:34:49 mdejong Exp $
  12.  */
  13. #include "tkWinInt.h"
  14. #ifndef STATIC_BUILD
  15. #ifdef HAVE_NO_SEH
  16. /*
  17.  * Unlike Borland and Microsoft, we don't register exception handlers by
  18.  * pushing registration records onto the runtime stack. Instead, we register
  19.  * them by creating an EXCEPTION_REGISTRATION within the activation record.
  20.  */
  21. typedef struct EXCEPTION_REGISTRATION {
  22.     struct EXCEPTION_REGISTRATION *link;
  23.     EXCEPTION_DISPOSITION (*handler)(
  24.     struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
  25.     void *ebp;
  26.     void *esp;
  27.     int status;
  28. } EXCEPTION_REGISTRATION;
  29. /* Need to add noinline flag to DllMain declaration so that gcc -O3
  30.  * does not inline asm code into DllEntryPoint and cause a
  31.  * compile time error because of redefined local labels.
  32.  */
  33. BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, 
  34. LPVOID reserved)
  35.                         __attribute__ ((noinline));
  36. #else
  37. /*
  38.  * The following declaration is for the VC++ DLL entry point.
  39.  */
  40. BOOL WINAPI DllMain _ANSI_ARGS_((HINSTANCE hInst,
  41.     DWORD reason, LPVOID reserved));
  42. #endif /* HAVE_NO_SEH */
  43. /*
  44.  *----------------------------------------------------------------------
  45.  *
  46.  * DllEntryPoint --
  47.  *
  48.  * This wrapper function is used by Borland to invoke the
  49.  * initialization code for Tk.  It simply calls the DllMain
  50.  * routine.
  51.  *
  52.  * Results:
  53.  * See DllMain.
  54.  *
  55.  * Side effects:
  56.  * See DllMain.
  57.  *
  58.  *----------------------------------------------------------------------
  59.  */
  60. BOOL WINAPI
  61. DllEntryPoint(hInst, reason, reserved)
  62.     HINSTANCE hInst; /* Library instance handle. */
  63.     DWORD reason; /* Reason this function is being called. */
  64.     LPVOID reserved; /* Not used. */
  65. {
  66.     return DllMain(hInst, reason, reserved);
  67. }
  68. /*
  69.  *----------------------------------------------------------------------
  70.  *
  71.  * DllMain --
  72.  *
  73.  * DLL entry point.  It is only necessary to specify our dll here so
  74.  * that resources are found correctly.  Otherwise Tk will initialize
  75.  * and clean up after itself through other methods, in order to be
  76.  * consistent whether the build is static or dynamic.
  77.  *
  78.  * Results:
  79.  * Always TRUE.
  80.  *
  81.  * Side effects:
  82.  * This might call some sycronization functions, but MSDN
  83.  * documentation states: "Waiting on synchronization objects in
  84.  * DllMain can cause a deadlock."
  85.  *
  86.  *----------------------------------------------------------------------
  87.  */
  88. BOOL WINAPI
  89. DllMain(hInstance, reason, reserved)
  90.     HINSTANCE hInstance;
  91.     DWORD reason;
  92.     LPVOID reserved;
  93. {
  94. #ifdef HAVE_NO_SEH
  95.     EXCEPTION_REGISTRATION registration;
  96. #endif
  97.     /*
  98.      * If we are attaching to the DLL from a new process, tell Tk about
  99.      * the hInstance to use.
  100.      */
  101.     switch (reason) {
  102.     case DLL_PROCESS_ATTACH:
  103. DisableThreadLibraryCalls(hInstance);
  104. TkWinSetHINSTANCE(hInstance);
  105. break;
  106.     case DLL_PROCESS_DETACH:
  107. /*
  108.  * Protect the call to TkFinalize in an SEH block.  We can't
  109.  * be guarenteed Tk is always being unloaded from a stable
  110.  * condition.
  111.  */
  112. #ifdef HAVE_NO_SEH
  113. __asm__ __volatile__ (
  114.     /*
  115.      * Construct an EXCEPTION_REGISTRATION to protect the call to
  116.      * TkFinalize
  117.      */
  118.     "leal %[registration], %%edx" "nt"
  119.     "movl %%fs:0, %%eax" "nt"
  120.     "movl %%eax, 0x0(%%edx)" "nt" /* link */
  121.     "leal 1f, %%eax" "nt"
  122.     "movl %%eax, 0x4(%%edx)" "nt" /* handler */
  123.     "movl %%ebp, 0x8(%%edx)" "nt" /* ebp */
  124.     "movl %%esp, 0xc(%%edx)" "nt" /* esp */
  125.     "movl %[error], 0x10(%%edx)" "nt" /* status */
  126.     /*
  127.      * Link the EXCEPTION_REGISTRATION on the chain
  128.      */
  129.     "movl %%edx, %%fs:0" "nt"
  130.     /*
  131.      * Call TkFinalize
  132.      */
  133.     "movl $0x0, 0x0(%%esp)" "nt"
  134.     "call _TkFinalize" "nt"
  135.     /*
  136.      * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION
  137.      * and store a TCL_OK status
  138.      */
  139.     "movl %%fs:0, %%edx" "nt"
  140.     "movl %[ok], %%eax" "nt"
  141.     "movl %%eax, 0x10(%%edx)" "nt"
  142.     "jmp 2f" "n"
  143.     /*
  144.      * Come here on an exception. Get the EXCEPTION_REGISTRATION that
  145.      * we previously put on the chain.
  146.      */
  147.     "1:" "t"
  148.     "movl %%fs:0, %%edx" "nt"
  149.     "movl 0x8(%%edx), %%edx" "n"
  150.     /* 
  151.      * Come here however we exited. Restore context from the
  152.      * EXCEPTION_REGISTRATION in case the stack is unbalanced.
  153.      */
  154.     "2:" "t"
  155.     "movl 0xc(%%edx), %%esp" "nt"
  156.     "movl 0x8(%%edx), %%ebp" "nt"
  157.     "movl 0x0(%%edx), %%eax" "nt"
  158.     "movl %%eax, %%fs:0" "nt"
  159.     :
  160.     /* No outputs */
  161.     :
  162.     [registration] "m" (registration),
  163.     [ok] "i" (TCL_OK),
  164.     [error] "i" (TCL_ERROR)
  165.     :
  166.     "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
  167.     );
  168. #else /* HAVE_NO_SEH */
  169. __try {
  170.     /*
  171.      * Run and remove our exit handlers, if they haven't already
  172.      * been run.  Just in case we are being unloaded prior to
  173.      * Tcl (it can happen), we won't leave any dangling pointers
  174.      * hanging around for when Tcl gets unloaded later.
  175.      */
  176.     TkFinalize(NULL);
  177. } __except (EXCEPTION_EXECUTE_HANDLER) {
  178.     /* empty handler body. */
  179. }
  180. #endif
  181. break;
  182.     }
  183.     return TRUE;
  184. }
  185. #endif /* !STATIC_BUILD */