OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [win/] [tclWin32Dll.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclWin32Dll.c --
3
 *
4
 *      This file contains the DLL entry point which sets up the 32-to-16-bit
5
 *      thunking code for SynchSpawn if the library is running under Win32s.
6
 *
7
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tclWin32Dll.c,v 1.1.1.1 2002-01-16 10:25:38 markom Exp $
13
 */
14
 
15
#include "tclWinInt.h"
16
 
17
typedef DWORD (WINAPI * UT32PROC)(LPVOID lpBuff, DWORD dwUserDefined,
18
        LPVOID *lpTranslationList);
19
 
20
typedef BOOL (WINAPI * PUTREGISTER)(HANDLE hModule, LPCSTR SixteenBitDLL,
21
        LPCSTR InitName, LPCSTR ProcName, UT32PROC* ThirtyTwoBitThunk,
22
        FARPROC UT32Callback, LPVOID Buff);
23
 
24
typedef VOID (WINAPI * PUTUNREGISTER)(HANDLE hModule);
25
 
26
static PUTUNREGISTER UTUnRegister = NULL;
27
static int           tclProcessesAttached = 0;
28
 
29
/*
30
 * The following data structure is used to keep track of all of the DLL's
31
 * opened by Tcl so that they can be freed with the Tcl.dll is unloaded.
32
 */
33
 
34
typedef struct LibraryList {
35
    HINSTANCE handle;
36
    struct LibraryList *nextPtr;
37
} LibraryList;
38
 
39
static LibraryList *libraryList = NULL; /* List of currently loaded DLL's.  */
40
 
41
static HINSTANCE tclInstance;   /* Global library instance handle. */
42
static int tclPlatformId;       /* Running under NT, 95, or Win32s? */
43
 
44
/*
45
 * Declarations for functions that are only used in this file.
46
 */
47
 
48
static void             UnloadLibraries _ANSI_ARGS_((void));
49
 
50
/*
51
 * The following declaration is for the VC++ DLL entry point.
52
 */
53
 
54
BOOL APIENTRY           DllMain _ANSI_ARGS_((HINSTANCE hInst,
55
                            DWORD reason, LPVOID reserved));
56
 
57
#ifdef __WIN32__
58
#ifndef STATIC_BUILD
59
 
60
/* CYGNUS LOCAL */
61
#ifdef __CYGWIN__0
62
/* CYGWIN requires an impure pointer variable, which must be
63
   explicitly initialized when the DLL starts up.  */
64
struct _reent *_impure_ptr;
65
extern struct _reent *_imp__reent_data;
66
#endif
67
/* END CYGNUS LOCAL */
68
 
69
/*
70
 *----------------------------------------------------------------------
71
 *
72
 * DllEntryPoint --
73
 *
74
 *      This wrapper function is used by Borland to invoke the
75
 *      initialization code for Tcl.  It simply calls the DllMain
76
 *      routine.
77
 *
78
 * Results:
79
 *      See DllMain.
80
 *
81
 * Side effects:
82
 *      See DllMain.
83
 *
84
 *----------------------------------------------------------------------
85
 */
86
 
87
BOOL APIENTRY
88
DllEntryPoint(hInst, reason, reserved)
89
    HINSTANCE hInst;            /* Library instance handle. */
90
    DWORD reason;               /* Reason this function is being called. */
91
    LPVOID reserved;            /* Not used. */
92
{
93
    return DllMain(hInst, reason, reserved);
94
}
95
 
96
/*
97
 *----------------------------------------------------------------------
98
 *
99
 * DllMain --
100
 *
101
 *      This routine is called by the VC++ C run time library init
102
 *      code, or the DllEntryPoint routine.  It is responsible for
103
 *      initializing various dynamically loaded libraries.
104
 *
105
 * Results:
106
 *      TRUE on sucess, FALSE on failure.
107
 *
108
 * Side effects:
109
 *      Establishes 32-to-16 bit thunk and initializes sockets library.
110
 *
111
 *----------------------------------------------------------------------
112
 */
113
BOOL APIENTRY
114
DllMain(hInst, reason, reserved)
115
    HINSTANCE hInst;            /* Library instance handle. */
116
    DWORD reason;               /* Reason this function is being called. */
117
    LPVOID reserved;            /* Not used. */
118
{
119
    OSVERSIONINFO os;
120
 
121
    /* CYGNUS LOCAL */
122
#ifdef __CYGWIN__0
123
    /* Cygwin requires the impure data pointer to be initialized
124
       when the DLL starts up.  */
125
    _impure_ptr = _imp__reent_data;
126
#endif
127
    /* END CYGNUS LOCAL */
128
 
129
    switch (reason) {
130
    case DLL_PROCESS_ATTACH:
131
        if (tclProcessesAttached++) {
132
            return FALSE;         /* Not the first initialization. */
133
        }
134
 
135
        TclWinInit(hInst);
136
        return TRUE;
137
 
138
    case DLL_PROCESS_DETACH:
139
 
140
        tclProcessesAttached--;
141
        if (tclProcessesAttached == 0) {
142
            Tcl_Finalize();
143
        }
144
        break;
145
    }
146
 
147
    return TRUE;
148
}
149
 
150
#endif /* !STATIC_BUILD */
151
#endif /* __WIN32__ */
152
 
153
/*
154
 *----------------------------------------------------------------------
155
 *
156
 * TclWinInit --
157
 *
158
 *      This function initializes the internal state of the tcl library.
159
 *
160
 * Results:
161
 *      None.
162
 *
163
 * Side effects:
164
 *      Initializes the 16-bit thunking library, and the tclPlatformId
165
 *      variable.
166
 *
167
 *----------------------------------------------------------------------
168
 */
169
 
170
void
171
TclWinInit(hInst)
172
    HINSTANCE hInst;            /* Library instance handle. */
173
{
174
    OSVERSIONINFO os;
175
 
176
    tclInstance = hInst;
177
    os.dwOSVersionInfoSize = sizeof(os);
178
    GetVersionEx(&os);
179
    tclPlatformId = os.dwPlatformId;
180
 
181
    /*
182
     * The following code stops Windows 3.x from automatically putting
183
     * up Sharing Violation dialogs, e.g, when someone tries to
184
     * access a file that is locked or a drive with no disk in it.
185
     * Tcl already returns the appropriate error to the caller, and they
186
     * can decide to put up their own dialog in response to that failure.
187
     *
188
     * Under 95 and NT, the system doesn't automatically put up dialogs
189
     * when the above operations fail.
190
     */
191
 
192
    if (tclPlatformId == VER_PLATFORM_WIN32s) {
193
        SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);
194
    }
195
}
196
 
197
/*
198
 *----------------------------------------------------------------------
199
 *
200
 * TclpFinalize --
201
 *
202
 *      Clean up the Windows specific library state.
203
 *
204
 * Results:
205
 *      None.
206
 *
207
 * Side effects:
208
 *      Unloads any DLLs and cleans up the thunking library, if
209
 *      necessary.
210
 *
211
 *----------------------------------------------------------------------
212
 */
213
 
214
void
215
TclpFinalize()
216
{
217
    /*
218
     * Unregister the Tcl thunk.
219
     */
220
 
221
    if (UTUnRegister != NULL) {
222
        UTUnRegister(tclInstance);
223
        UTUnRegister = NULL;
224
    }
225
 
226
    /*
227
     * Cleanup any dynamically loaded libraries.
228
     */
229
 
230
    UnloadLibraries();
231
}
232
 
233
/*
234
 *----------------------------------------------------------------------
235
 *
236
 * TclWinLoadLibrary --
237
 *
238
 *      This function is a wrapper for the system LoadLibrary.  It is
239
 *      responsible for adding library handles to the library list so
240
 *      the libraries can be freed when tcl.dll is unloaded.
241
 *
242
 * Results:
243
 *      Returns the handle of the newly loaded library, or NULL on
244
 *      failure.
245
 *
246
 * Side effects:
247
 *      Loads the specified library into the process.
248
 *
249
 *----------------------------------------------------------------------
250
 */
251
 
252
HINSTANCE
253
TclWinLoadLibrary(name)
254
    char *name;                 /* Library file to load. */
255
{
256
    HINSTANCE handle;
257
    LibraryList *ptr;
258
 
259
    handle = LoadLibrary(name);
260
    if (handle != NULL) {
261
        ptr = (LibraryList*) ckalloc(sizeof(LibraryList));
262
        ptr->handle = handle;
263
        ptr->nextPtr = libraryList;
264
        libraryList = ptr;
265
    } else {
266
        TclWinConvertError(GetLastError());
267
    }
268
    return handle;
269
}
270
 
271
/*
272
 *----------------------------------------------------------------------
273
 *
274
 * UnloadLibraries --
275
 *
276
 *      Frees any dynamically allocated libraries loaded by Tcl.
277
 *
278
 * Results:
279
 *      None.
280
 *
281
 * Side effects:
282
 *      Frees the libraries on the library list as well as the list.
283
 *
284
 *----------------------------------------------------------------------
285
 */
286
 
287
static void
288
UnloadLibraries()
289
{
290
    LibraryList *ptr;
291
 
292
    while (libraryList != NULL) {
293
        FreeLibrary(libraryList->handle);
294
        ptr = libraryList->nextPtr;
295
        ckfree((char*)libraryList);
296
        libraryList = ptr;
297
    }
298
}
299
 
300
/*
301
 *----------------------------------------------------------------------
302
 *
303
 * TclWinSynchSpawn --
304
 *
305
 *      32-bit entry point to the 16-bit SynchSpawn code.
306
 *
307
 * Results:
308
 *      1 on success, 0 on failure.
309
 *
310
 * Side effects:
311
 *      Spawns a command and waits for it to complete.
312
 *
313
 *----------------------------------------------------------------------
314
 */
315
int
316
TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
317
{
318
    static UT32PROC UTProc = NULL;
319
    static int utErrorCode;
320
 
321
    if (UTUnRegister == NULL) {
322
        /*
323
         * Load the Universal Thunking routines from kernel32.dll.
324
         */
325
 
326
        HINSTANCE hKernel;
327
        PUTREGISTER UTRegister;
328
        char buffer[] = "TCL16xx.DLL";
329
 
330
        hKernel = TclWinLoadLibrary("Kernel32.Dll");
331
        if (hKernel == NULL) {
332
            return 0;
333
        }
334
 
335
        UTRegister = (PUTREGISTER) GetProcAddress(hKernel, "UTRegister");
336
        UTUnRegister = (PUTUNREGISTER) GetProcAddress(hKernel, "UTUnRegister");
337
        if (!UTRegister || !UTUnRegister) {
338
            UnloadLibraries();
339
            return 0;
340
        }
341
 
342
        /*
343
         * Construct the complete name of tcl16xx.dll.
344
         */
345
 
346
        buffer[5] = '0' + TCL_MAJOR_VERSION;
347
        buffer[6] = '0' + TCL_MINOR_VERSION;
348
 
349
        /*
350
         * Register the Tcl thunk.
351
         */
352
 
353
        if (UTRegister(tclInstance, buffer, NULL, "UTProc", &UTProc, NULL,
354
                NULL) == FALSE) {
355
            utErrorCode = GetLastError();
356
        }
357
    }
358
 
359
    if (UTProc == NULL) {
360
        /*
361
         * The 16-bit thunking DLL wasn't found.  Return error code that
362
         * indicates this problem.
363
         */
364
 
365
        SetLastError(utErrorCode);
366
        return 0;
367
    }
368
 
369
    UTProc(args, type, trans);
370
    *pidPtr = 0;
371
    return 1;
372
}
373
 
374
/*
375
 *----------------------------------------------------------------------
376
 *
377
 * TclWinGetTclInstance --
378
 *
379
 *      Retrieves the global library instance handle.
380
 *
381
 * Results:
382
 *      Returns the global library instance handle.
383
 *
384
 * Side effects:
385
 *      None.
386
 *
387
 *----------------------------------------------------------------------
388
 */
389
 
390
HINSTANCE
391
TclWinGetTclInstance()
392
{
393
    return tclInstance;
394
}
395
 
396
/*
397
 *----------------------------------------------------------------------
398
 *
399
 * TclWinGetPlatformId --
400
 *
401
 *      Determines whether running under NT, 95, or Win32s, to allow
402
 *      runtime conditional code.
403
 *
404
 * Results:
405
 *      The return value is one of:
406
 *          VER_PLATFORM_WIN32s         Win32s on Windows 3.1.
407
 *          VER_PLATFORM_WIN32_WINDOWS  Win32 on Windows 95.
408
 *          VER_PLATFORM_WIN32_NT       Win32 on Windows NT
409
 *
410
 * Side effects:
411
 *      None.
412
 *
413
 *----------------------------------------------------------------------
414
 */
415
 
416
int
417
TclWinGetPlatformId()
418
{
419
    return tclPlatformId;
420
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.