source: trunk/src/msvcrt/data.c@ 10005

Last change on this file since 10005 was 10005, checked in by sandervl, 22 years ago

PF: MSVCRT update

File size: 13.0 KB
Line 
1/*
2 * msvcrt.dll dll data items
3 *
4 * Copyright 2000 Jon Griffiths
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __WIN32OS2__
21#include "config.h"
22#else
23#include <emxheader.h>
24#include <math.h>
25#include <string.h>
26#endif
27
28#include "wine/port.h"
29
30#include "msvcrt.h"
31
32#include "msvcrt/stdlib.h"
33#include "msvcrt/string.h"
34
35#ifndef __WIN32OS2__
36#include "wine/library.h"
37#endif
38#include "wine/unicode.h"
39#include "wine/debug.h"
40
41WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
42
43unsigned int MSVCRT___argc;
44unsigned int MSVCRT_basemajor;/* FIXME: */
45unsigned int MSVCRT_baseminor;/* FIXME: */
46unsigned int MSVCRT_baseversion; /* FIXME: */
47unsigned int MSVCRT__commode;
48unsigned int MSVCRT__fmode;
49unsigned int MSVCRT_osmajor;/* FIXME: */
50unsigned int MSVCRT_osminor;/* FIXME: */
51unsigned int MSVCRT_osmode;/* FIXME: */
52unsigned int MSVCRT__osver;
53unsigned int MSVCRT_osversion; /* FIXME: */
54unsigned int MSVCRT__winmajor;
55unsigned int MSVCRT__winminor;
56unsigned int MSVCRT__winver;
57unsigned int MSVCRT__sys_nerr; /* FIXME: not accessible from Winelib apps */
58char** MSVCRT__sys_errlist; /* FIXME: not accessible from Winelib apps */
59unsigned int MSVCRT___setlc_active;
60unsigned int MSVCRT___unguarded_readlc_active;
61double MSVCRT__HUGE;
62char **MSVCRT___argv;
63MSVCRT_wchar_t **MSVCRT___wargv;
64char *MSVCRT__acmdln;
65MSVCRT_wchar_t *MSVCRT__wcmdln;
66char **MSVCRT__environ = 0;
67MSVCRT_wchar_t **MSVCRT__wenviron = 0;
68char **MSVCRT___initenv = 0;
69MSVCRT_wchar_t **MSVCRT___winitenv = 0;
70int MSVCRT_timezone;
71int MSVCRT_app_type;
72char MSVCRT_pgm[MAX_PATH];
73char* MSVCRT__pgmptr = 0;
74
75/* Get a snapshot of the current environment
76 * and construct the __p__environ array
77 *
78 * The pointer returned from GetEnvironmentStrings may get invalid when
79 * some other module cause a reallocation of the env-variable block
80 *
81 * blk is an array of pointers to environment strings, ending with a NULL
82 * and after that the actual copy of the environment strings, ending in a \0
83 */
84char ** msvcrt_SnapshotOfEnvironmentA(char **blk)
85{
86 char* environ_strings = GetEnvironmentStringsA();
87 int count = 1, len = 1, i = 0; /* keep space for the trailing NULLS */
88 char *ptr;
89
90 for (ptr = environ_strings; *ptr; ptr += strlen(ptr) + 1)
91 {
92 count++;
93 len += strlen(ptr) + 1;
94 }
95 if (blk)
96 blk = HeapReAlloc( GetProcessHeap(), 0, blk, count* sizeof(char*) + len );
97 else
98 blk = HeapAlloc(GetProcessHeap(), 0, count* sizeof(char*) + len );
99
100 if (blk)
101 {
102 if (count)
103 {
104 memcpy(&blk[count],environ_strings,len);
105 for (ptr = (char*) &blk[count]; *ptr; ptr += strlen(ptr) + 1)
106 {
107 blk[i++] = ptr;
108 }
109 }
110 blk[i] = NULL;
111 }
112 FreeEnvironmentStringsA(environ_strings);
113 return blk;
114}
115
116MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **wblk)
117{
118 MSVCRT_wchar_t* wenviron_strings = GetEnvironmentStringsW();
119 int count = 1, len = 1, i = 0; /* keep space for the trailing NULLS */
120 MSVCRT_wchar_t *wptr;
121
122 for (wptr = wenviron_strings; *wptr; wptr += strlenW(wptr) + 1)
123 {
124 count++;
125 len += strlenW(wptr) + 1;
126 }
127 if (wblk)
128 wblk = HeapReAlloc( GetProcessHeap(), 0, wblk, count* sizeof(MSVCRT_wchar_t*) + len * sizeof(MSVCRT_wchar_t));
129 else
130 wblk = HeapAlloc(GetProcessHeap(), 0, count* sizeof(MSVCRT_wchar_t*) + len * sizeof(MSVCRT_wchar_t));
131 if (wblk)
132 {
133 if (count)
134 {
135 memcpy(&wblk[count],wenviron_strings,len * sizeof(MSVCRT_wchar_t));
136 for (wptr = (MSVCRT_wchar_t*)&wblk[count]; *wptr; wptr += strlenW(wptr) + 1)
137 {
138 wblk[i++] = wptr;
139 }
140 }
141 wblk[i] = NULL;
142 }
143 FreeEnvironmentStringsW(wenviron_strings);
144 return wblk;
145}
146
147typedef void (*_INITTERMFUN)(void);
148
149/***********************************************************************
150 * __p___argc (MSVCRT.@)
151 */
152int* __p___argc(void) { dprintf(("MSVCRT: Query of p__argc")); return &MSVCRT___argc; }
153
154/***********************************************************************
155 * __p__commode (MSVCRT.@)
156 */
157unsigned int* __p__commode(void) { dprintf(("MSVCRT: Query of p__commode")); return &MSVCRT__commode; }
158
159/***********************************************************************
160 * __p__pgmptr (MSVCRT.@)
161 */
162char** __p__pgmptr(void) { return &MSVCRT__pgmptr; }
163
164/***********************************************************************
165 * __p__fmode (MSVCRT.@)
166 */
167unsigned int* __p__fmode(void) { dprintf(("MSVCRT: Query of p__fmode")); return &MSVCRT__fmode; }
168
169/***********************************************************************
170 * __p__osver (MSVCRT.@)
171 */
172unsigned int* __p__osver(void) { dprintf(("MSVCRT: Query of p__osver")); return &MSVCRT__osver; }
173
174/***********************************************************************
175 * __p__winmajor (MSVCRT.@)
176 */
177unsigned int* __p__winmajor(void) { dprintf(("MSVCRT: Query of p__winmajor")); return &MSVCRT__winmajor; }
178
179/***********************************************************************
180 * __p__winminor (MSVCRT.@)
181 */
182unsigned int* __p__winminor(void) { dprintf(("MSVCRT: Query of p__winminor")); return &MSVCRT__winminor; }
183
184/***********************************************************************
185 * __p__winver (MSVCRT.@)
186 */
187unsigned int* __p__winver(void) { dprintf(("MSVCRT: Query of p__winver")); return &MSVCRT__winver; }
188
189/*********************************************************************
190 * __p__acmdln (MSVCRT.@)
191 */
192char** __p__acmdln(void) { dprintf(("MSVCRT: Query of p__acmdln")); return &MSVCRT__acmdln; }
193
194/*********************************************************************
195 * __p__wcmdln (MSVCRT.@)
196 */
197MSVCRT_wchar_t** __p__wcmdln(void) { dprintf(("MSVCRT: Query of p__wcmdln")); return &MSVCRT__wcmdln; }
198
199/*********************************************************************
200 * __p___argv (MSVCRT.@)
201 */
202char*** __p___argv(void) { dprintf(("MSVCRT: Query of p__argv")); return &MSVCRT___argv; }
203
204/*********************************************************************
205 * __p___wargv (MSVCRT.@)
206 */
207MSVCRT_wchar_t*** __p___wargv(void) { dprintf(("MSVCRT: Query of p__wargv")); return &MSVCRT___wargv; }
208
209/*********************************************************************
210 * __p__environ (MSVCRT.@)
211 */
212char*** __p__environ(void)
213{
214 dprintf(("MSVCRT: Query of p__environ"));
215 if (!MSVCRT__environ)
216 MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(NULL);
217 return &MSVCRT__environ;
218}
219
220/*********************************************************************
221 * __p__wenviron (MSVCRT.@)
222 */
223MSVCRT_wchar_t*** __p__wenviron(void)
224{
225 dprintf(("MSVCRT: Query of p__wenviron"));
226 if (!MSVCRT__wenviron)
227 MSVCRT__wenviron = msvcrt_SnapshotOfEnvironmentW(NULL);
228 return &MSVCRT__wenviron;
229}
230
231/*********************************************************************
232 * __p___initenv (MSVCRT.@)
233 */
234char*** __p___initenv(void) { dprintf(("MSVCRT: Query of p__initenv")); return &MSVCRT___initenv; }
235
236/*********************************************************************
237 * __p___winitenv (MSVCRT.@)
238 */
239MSVCRT_wchar_t*** __p___winitenv(void) { dprintf(("MSVCRT: Query of p__winitenv")); return &MSVCRT___winitenv; }
240
241/*********************************************************************
242 * __p__timezone (MSVCRT.@)
243 */
244int* __p__timezone(void) { dprintf(("MSVCRT: Query of p__timezone")); return &MSVCRT_timezone; }
245
246/* INTERNAL: Create a wide string from an ascii string */
247static MSVCRT_wchar_t *wstrdupa(const char *str)
248{
249 const size_t len = strlen(str) + 1 ;
250 dprintf(("MSVCRT: wstrdupa %s",str));
251 MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t));
252 if (!wstr)
253 return NULL;
254 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,str,len,wstr,len);
255 return wstr;
256}
257
258
259#ifdef __WIN32OS2__
260
261static int __wine_main_argc = 0;
262static char **__wine_main_argv = NULL;
263static WCHAR **__wine_main_wargv = NULL;
264char *argv[255];
265
266static void set_library_argv( char **incargv)
267{
268 int argc = 0;
269 WCHAR *p;
270 WCHAR **wargv;
271 char *token2 = NULL;
272 DWORD total = 0;
273
274 char argvbuf[255];
275
276 strcpy(argvbuf,incargv[0]);
277
278 if (argvbuf[0] == '\"')
279 token2 = strtok(argvbuf, "\"");
280 else
281 token2 = strtok(argvbuf, " ");
282
283 if (token2)
284 do
285 {
286 argv[argc] = HeapAlloc( GetProcessHeap(), 0, strlen(token2)+1);
287 strcpy(argv[argc++],token2);
288 }
289 while (token2 = strtok(NULL, " "));
290
291 argv[argc] = NULL;
292 for (argc = 0; argv[argc]; argc++)
293 total += MultiByteToWideChar( CP_ACP, 0, argv[argc], -1, NULL, 0 );
294
295 wargv = HeapAlloc( GetProcessHeap(), 0,
296 total * sizeof(WCHAR) + (argc + 1) * sizeof(*wargv) );
297 p = (WCHAR *)(wargv + argc + 1);
298 for (argc = 0; argv[argc]; argc++)
299 {
300 DWORD len = MultiByteToWideChar( CP_ACP, 0, argv[argc], -1, p, total );
301 wargv[argc] = p;
302 p += len;
303 total -= len;
304 }
305 wargv[argc] = NULL;
306
307 dprintf(("Num of args is %d",argc));
308
309 __wine_main_argc = argc;
310 __wine_main_argv = argv;
311 __wine_main_wargv = wargv;
312}
313#endif
314
315/* INTERNAL: Since we can't rely on Winelib startup code calling w/getmainargs,
316 * we initialise data values during DLL loading. When called by a native
317 * program we simply return the data we've already initialised. This also means
318 * you can call multiple times without leaking
319 */
320void msvcrt_init_args(void)
321{
322 DWORD version;
323
324 MSVCRT__acmdln = MSVCRT__strdup( GetCommandLineA() );
325 MSVCRT__wcmdln = wstrdupa(MSVCRT__acmdln);
326#ifdef __WIN32OS2__
327 set_library_argv(&MSVCRT__acmdln);
328#endif
329 MSVCRT___argc = __wine_main_argc;
330 MSVCRT___argv = __wine_main_argv;
331 MSVCRT___wargv = __wine_main_wargv;
332
333 TRACE("got '%s', wide = %s argc=%d\n", MSVCRT__acmdln,
334 debugstr_w(MSVCRT__wcmdln),MSVCRT___argc);
335
336 version = GetVersion();
337 MSVCRT__osver = version >> 16;
338 MSVCRT__winminor = version & 0xFF;
339 MSVCRT__winmajor = (version>>8) & 0xFF;
340 MSVCRT_baseversion = version >> 16;
341 MSVCRT__winver = ((version >> 8) & 0xFF) + ((version & 0xFF) << 8);
342 MSVCRT_baseminor = (version >> 16) & 0xFF;
343 MSVCRT_basemajor = (version >> 24) & 0xFF;
344 MSVCRT_osversion = version & 0xFFFF;
345 MSVCRT_osminor = version & 0xFF;
346 MSVCRT_osmajor = (version>>8) & 0xFF;
347 MSVCRT__sys_nerr = 43;
348 MSVCRT__HUGE = HUGE_VAL;
349 MSVCRT___setlc_active = 0;
350 MSVCRT___unguarded_readlc_active = 0;
351 MSVCRT_timezone = 0;
352
353 MSVCRT___initenv= msvcrt_SnapshotOfEnvironmentA(NULL);
354 MSVCRT___winitenv= msvcrt_SnapshotOfEnvironmentW(NULL);
355
356 MSVCRT_pgm[0] = '\0';
357 GetModuleFileNameA(0, MSVCRT_pgm, sizeof(MSVCRT_pgm)/sizeof(MSVCRT_pgm[0]));
358 MSVCRT__pgmptr = MSVCRT_pgm;
359}
360
361
362/* INTERNAL: free memory used by args */
363void msvcrt_free_args(void)
364{
365 /* FIXME: more things to free */
366 if (MSVCRT___initenv) HeapFree(GetProcessHeap(), 0,MSVCRT___initenv);
367 if (MSVCRT___winitenv) HeapFree(GetProcessHeap(), 0,MSVCRT___winitenv);
368 if (MSVCRT__environ) HeapFree(GetProcessHeap(), 0,MSVCRT__environ);
369 if (MSVCRT__wenviron) HeapFree(GetProcessHeap(), 0,MSVCRT__wenviron);
370}
371
372/*********************************************************************
373 * __getmainargs (MSVCRT.@)
374 */
375void __getmainargs(int *argc, char** *argv, char** *envp,
376 int expand_wildcards, int *new_mode)
377{
378 TRACE("(%p,%p,%p,%d,%p).\n", argc, argv, envp, expand_wildcards, new_mode);
379 *argc = MSVCRT___argc;
380 *argv = MSVCRT___argv;
381 *envp = MSVCRT___initenv;
382 if (new_mode)
383 MSVCRT__set_new_mode( *new_mode );
384}
385
386/*********************************************************************
387 * __wgetmainargs (MSVCRT.@)
388 */
389void __wgetmainargs(int *argc, MSVCRT_wchar_t** *wargv, MSVCRT_wchar_t** *wenvp,
390 int expand_wildcards, int *new_mode)
391{
392 TRACE("(%p,%p,%p,%d,%p).\n", argc, wargv, wenvp, expand_wildcards, new_mode);
393 *argc = MSVCRT___argc;
394 *wargv = MSVCRT___wargv;
395 *wenvp = MSVCRT___winitenv;
396 if (new_mode)
397 MSVCRT__set_new_mode( *new_mode );
398}
399
400/*********************************************************************
401 * _initterm (MSVCRT.@)
402 */
403unsigned int _initterm(_INITTERMFUN *start,_INITTERMFUN *end)
404{
405 _INITTERMFUN* current = start;
406
407 TRACE("(%p,%p)\n",start,end);
408 while (current<end)
409 {
410 if (*current)
411 {
412 TRACE("Call init function %p\n",*current);
413 (**current)();
414 TRACE("returned\n");
415 }
416 current++;
417 }
418 return 0;
419}
420
421/*********************************************************************
422 * __set_app_type (MSVCRT.@)
423 */
424void MSVCRT___set_app_type(int app_type)
425{
426 TRACE("(%d) %s application\n", app_type, app_type == 2 ? "Gui" : "Console");
427 MSVCRT_app_type = app_type;
428}
Note: See TracBrowser for help on using the repository browser.