Annotation of OpenXM_contrib2/asir2018/builtin/ctrl.c, Revision 1.4
1.1 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.4 ! ohara 48: * $OpenXM: OpenXM_contrib2/asir2018/builtin/ctrl.c,v 1.3 2019/03/06 10:43:25 noro Exp $
1.1 noro 49: */
50: #include "ca.h"
51: #include "parse.h"
52: #include <string.h>
53: #if defined(VISUAL) || defined(__MINGW32__)
54: #include <windows.h>
55: #include <winnls.h>
56: #else
57: #include <locale.h>
58: #include <unistd.h>
59: #include <sys/types.h>
60: #include <sys/socket.h>
61: #include <sys/wait.h>
62: #include <sys/utsname.h>
63: #endif
64:
65: static struct {
66: char *type;
67: char *kernel;
68: char *name;
69: char *arch;
70: char *release;
71: char *full;
72: char *lang;
1.4 ! ohara 73: #if defined(VISUAL)
! 74: int ver_major;
! 75: int ver_minor;
! 76: int ver_build;
! 77: #endif
1.1 noro 78: } sysinfo;
79:
80: void Pctrl();
81: void Psysinfo(LIST *rp);
82: static void get_sysinfo();
83:
84: struct ftab ctrl_tab[] = {
85: {"ctrl",Pctrl,-2},
86: {"asir_env",Pctrl,-2},
87: {"sysinfo", Psysinfo, 0},
88: {0,0,0},
89: };
90:
91: extern int error_in_timer;
92: extern int prtime,nez,echoback,bigfloat,evalef;
93: extern int debug_up;
94: extern int GC_max_heap_size,Verbose,hideargs,hex_output,do_server_in_X11;
95: extern int do_message,do_terse;
96: extern int ox_batch,ox_check,ox_exchange_mathcap;
97: extern int f4_nocheck;
98: extern int StrassenSize;
99: extern int outputstyle;
100: extern int fortran_output;
101: extern int real_digit;
102: extern int real_binary;
103: extern int allow_laurent;
104: #if defined(INTERVAL)
105: extern int zerorewrite;
106: extern int Itvplot;
107: #endif
108: extern int double_output;
109: extern int use_new_hensel;
110: extern int print_quote;
111: extern int show_crossref;
112: extern Obj user_defined_prompt;
113: extern int asir_setenv;
114: extern int show_orderspec;
115: extern int no_debug_on_error;
116: extern int diag_period;
117: extern int weight_check;
118: extern char **ASIRLOADPATH;
119: extern int ASIRLOADPATH_LEN;
120: extern int No_ox_reset;
121: extern int plot_by_bigfloat;
122: extern int debug_plot;
123:
124: static struct keyval {
125: char *key;
126: int *val;
127: char *desc;
128: } ctrls[] = {
129: {"StrassenSize",&StrassenSize,"Determines the parameter in Strassen-Winograd matrix multiplication algorithm."},
130: {"allow_laurent",&allow_laurent,"If set to 1, negative exponents are allowed in monomials."},
131: {"asir_setenv",&asir_setenv,"Not used."},
132: {"bigfloat",&bigfloat,"If set to 1, MPFR bigfloat functions are used for floating point evaluation." },
133: {"cputime",&prtime,"If set to 1, the CPU time at the toplevel is shown." },
134: {"debug_up",&debug_up,"If set to 1, some debug messages are printed in special functions for univariate polynomials."},
135: {"debug_window",&do_server_in_X11,"If set to 1, an input window for debugging remote server are shown."},
136: {"diag_period",&diag_period,"Determines the frequency of the intermediate inter-reduction in nd_gr()."},
137: {"double_output",&double_output,"If set to 1, floating point numbers are printed in the style ddd.ddd."},
138: {"echo",&echoback,"If set to 1, characters read by the input function are printed." },
139: {"error_in_timer",&error_in_timer,"If set to 1, the usual error handler is executed when the timer is expired."},
140: {"evalef",&evalef,"If set to 1, elementary functions are evaluated immediately."},
141: {"f4_nocheck",&f4_nocheck,"If set to 1, correctness check of the result of modular computation are omitted in nd_f4()."},
142: {"fake_ox_reset",&No_ox_reset,"Determines the treatment of OX reset request for a server which does not implement the reset protocol."},
143: {"fortran_output",&fortran_output,"If set to 1, ** is used instead of ^ for representing the power."},
144: {"hex",&hex_output,"If set to 1, integers are printed by the hexadecimal notation."},
145: {"hideargs",&hideargs,"If set to 1, the arguments of a function call are not printed."},
146: {"message",&do_message,"If set to 1, an opening message is printed in ox_asir and ox_plot."},
147: {"new_hensel",&use_new_hensel,"If set to 1, a function hensel2() is used in the univariate factorizer over Q."},
148: {"nez",&nez,"If set to 1, a new version of EZGCD implementation is used." },
149: {"no_debug_on_error",&no_debug_on_error,"If set to 1, the debug mode is not used."},
150: {"no_ox_reset",&No_ox_reset,"Determines the treatment of OX reset request for a server which does not implement the reset protocol."},
151: {"no_prompt",&do_quiet,"If set to 1, prompts are not shown."},
152: {"outputstyle",&outputstyle,"If set to 1, structured data such as matrices and vectors are printed in the style mat(...), vect(...)."},
153: {"ox_batch",&ox_batch,"If set to 1, the OX stream are not flushed at each sending of an OX data."},
154: {"ox_check",&ox_check,"If set to 1, mathcap check is done for OpenXM date communication."},
155: {"ox_exchange_mathcap",&ox_exchange_mathcap,"If set to 1, mathcaps are exchanged."},
156: {"print_quote",&print_quote,"Determines the behavior of the printed form of a quote."},
157: {"quiet_mode",&do_quiet,"If set to 1, the copyright notices are not printed at the beginning of the session."},
158: {"real_binary",&real_binary,"If set to 1, a floating point number is printed by the binary notation."},
159: {"real_digit",&real_digit,"Determines the number of digits to appear after the decimal point."},
160: {"show_crossref",&show_crossref,"If set to 1, cross-references are shown when a program file is loaded."},
161: {"show_orderspec",&show_orderspec,"If set to 1, the specification of a composite term order is printed upon its creation."},
162: {"terse",&do_terse,"If set to 1, messages are not printed when user-defined callbacks are executed."},
163: {"verbose",&Verbose,"If set to 1, a warning is printed if a function is redefined."},
164: {"weight_check",&weight_check,"If set to 1, an overflow check for the given weight vector is done before starting the Groebner basis computation."},
165: #if defined(DO_PLOT)
166: {"plot_by_bigfloat",&plot_by_bigfloat,"If set to 1, computation is done by using MPFR bigfloat functions in ox_plot."},
167: {"debug_plot",&debug_plot,"If set to 1, ox_plot is executed with the message window."},
168: #endif
169: #if defined(INTERVAL)
170: {"zerorewrite",&zerorewrite,""},
171: {"itvplotsize",&Itvplot,""},
172: #endif
173: {0,0},
174: };
175:
176: LIST create_control_value(char *keystr,Obj value,char *descstr,int withdesc)
177: {
178: STRING key,desc;
179: NODE nd;
180: LIST list;
181:
182: MKSTR(key,keystr);
183: if ( withdesc ) {
184: MKSTR(desc,descstr);
185: nd = mknode(3,key,value,desc);
186: } else nd = mknode(2,key,value);
187: MKLIST(list,nd);
188: return list;
189: }
190:
191: extern Z ox_pari_stream;
192: extern int ox_pari_stream_initialized;
193: extern P ox_pari_starting_function;
194:
195: LIST create_control_values(int withdesc)
196: {
197: int n,i;
198: NODE top,top1,nd,node,p;
199: LIST list,l;
200: STRING s;
201: char *descstr;
202: Z val;
203: Q adj;
204: int nm,dv;
205: Z num,den;
206:
207: n = sizeof(ctrls)/sizeof(struct keyval)-1;
208: top = 0;
209: for ( i = n-1; i >= 0; i-- ) {
1.2 noro 210: STOZ(*(ctrls[i].val),val);
1.1 noro 211: list = create_control_value(ctrls[i].key,(Obj)val,ctrls[i].desc,withdesc);
212: MKNODE(top1,list,top); top = top1;
213: }
214: /* adj */
1.2 noro 215: Risa_GC_get_adj(&nm,&dv); UTOZ(nm,num); UTOZ(dv,den); divq((Q)num,(Q)den,&adj);
1.1 noro 216: descstr = "Determines the parameter for Boehm's GC.";
217: list = create_control_value("adj",(Obj)adj,descstr,withdesc);
218: MKNODE(top1,list,top); top = top1;
219:
220: /* prompt */
221: descstr = "Determines the user-defined prompt.";
222: list = create_control_value("prompt",(Obj)user_defined_prompt,descstr,withdesc);
223: MKNODE(top1,list,top); top = top1;
224:
225: /* loadpath */
226: node = 0;
227: if( ASIRLOADPATH[0] ) {
228: for(i=0; ASIRLOADPATH[i]; i++);
229: for(i--,p=NULL; i>=0; i--,p=node) {
230: MKSTR(s,ASIRLOADPATH[i]);
231: MKNODE(node,s,p);
232: }
233: }
234: MKLIST(l,node);
1.3 noro 235: descstr = "List of paths in ASIRLOADPATH.";
1.1 noro 236: list = create_control_value("loadpath",(Obj)l,descstr,withdesc);
237: MKNODE(top1,list,top); top = top1;
238:
239: /* oxpari_id */
240: if(!ox_pari_stream_initialized) {
1.2 noro 241: STOZ(-1,val);
1.1 noro 242: } else val = ox_pari_stream;
243: descstr = "Id of ox_pari.";
244: list = create_control_value("oxpari_id",(Obj)val,descstr,withdesc);
245: MKNODE(top1,list,top); top = top1;
246:
247: /* oxpari_start */
248: val = (Z)ox_pari_starting_function;
249: descstr = "oxpari starting function.";
250: list = create_control_value("oxpari_start",(Obj)val,descstr,withdesc);
251: MKNODE(top1,list,top); top = top1;
252:
253: MKLIST(list,top);
254: return list;
255: }
256:
257: void Pctrl(NODE arg,Obj *rp)
258: {
259: int t,i,n,desc=0;
260: int nm,dv;
261: Z num,den,z;
262: Q c;
263: char *key;
264: char buf[BUFSIZ];
265: char *str;
266: STRING s;
267: NODE node,p,opt;
268: LIST list;
269: P f;
270: Obj value;
271:
272: if ( !arg ) {
273: if ( current_option ) {
274: for ( opt = current_option; opt; opt = NEXT(opt) ) {
275: p = BDY((LIST)BDY(opt));
276: key = BDY((STRING)BDY(p));
277: value = (Obj)BDY(NEXT(p));
278: if ( !strcmp(key,"desc") && value ) {
279: desc = value ? 1 : 0;
280: break;
281: }
282: }
283: }
284: *rp = (Obj)create_control_values(desc);
285: return;
286: }
287: key = BDY((STRING)ARG0(arg));
288: if ( !strcmp(key,"adj") ) {
289: /* special treatment is necessary for "adj" */
290: if ( argc(arg) == 1 ) {
291: Risa_GC_get_adj(&nm,&dv);
1.2 noro 292: UTOZ(dv,num);
293: UTOZ(nm,den);
1.1 noro 294: divq((Q)num,(Q)den,(Q *)rp);
295: } else {
296: absq((Q)ARG1(arg),&c);
297: if ( !c )
298: error("ctrl : adj : invalid argument");
299: nmq(c,&num);
300: dnq(c,&den);
1.2 noro 301: Risa_GC_set_adj(ZTOS(den),ZTOS(num));
1.1 noro 302: *rp = (Obj)c;
303: }
304: return;
305: } else if ( !strcmp(key,"prompt") ) {
306: /* special treatment is necessary for "prompt" */
307: if ( argc(arg) == 1 ) {
308: if ((!do_quiet) && (user_defined_prompt == (Obj)0)) *rp=(Obj)ONE;
309: else *rp = (Obj)user_defined_prompt;
310: } else {
311: c = (Q)ARG1(arg);
312: if ( !c ) {
313: do_quiet = 1;
314: user_defined_prompt = 0;
315: *rp = 0;
316: } else if ( OID(c) == O_STR ) {
317: str = BDY((STRING)c);
318: for ( i = 0, n = 0; str[i]; i++ )
319: if ( str[i] == '%' )
320: n++;
321: if ( n >= 2 )
322: error("ctrl : prompt : invalid prompt specification");
323: do_quiet = 1;
324: user_defined_prompt = (Obj)c;
325: *rp = (Obj)c;
326: } else if ( NUM(c) && RATN(c) && UNIQ(c) ) {
327: user_defined_prompt = 0;
328: do_quiet = 0;
329: } else {
330: error("ctrl : prompt : invalid argument");
331: }
332: }
333: return;
334: } else if ( !strcmp(key,"loadpath") ) {
335: *rp = 0;
336: if ( argc(arg) == 1 ) {
337: if( ASIRLOADPATH[0] ) {
338: for(i=0; ASIRLOADPATH[i]; i++) {
339: }
340: for(i--,p=NULL; i>=0; i--,p=node) {
341: MKSTR(s,ASIRLOADPATH[i]);
342: MKNODE(node,s,p);
343: }
344: MKLIST(list,node);
345: *rp = (Obj)list;
346: }
347: } else {
348: list = (LIST)ARG1(arg);
349: if ( OID(list) == O_LIST ) {
350: for(i=0,p=BDY(list); p; i++,p=NEXT(p)) {
351: s=(STRING)BDY(p);
352: if(!s || OID(s)!=O_STR) {
353: error("ctrl : loadpath : invalid argument");
354: }
355: }
356: if(i >= ASIRLOADPATH_LEN) {
357: ASIRLOADPATH_LEN = i+1;
358: ASIRLOADPATH = (char **)MALLOC(sizeof(char *)*ASIRLOADPATH_LEN);
359: }
360: for(i=0,p=BDY(list); p; i++,p=NEXT(p)) {
361: ASIRLOADPATH[i] = (char *)BDY((STRING)BDY(p));
362: }
363: ASIRLOADPATH[i] = NULL;
364: }else {
365: error("ctrl : loadpath : invalid argument");
366: }
367: }
368: return;
369: } else if ( !strcmp(key,"oxpari_id") ) {
370: if ( argc(arg) == 1 ) {
371: if(!ox_pari_stream_initialized) {
1.2 noro 372: STOZ(-1,z);
1.1 noro 373: *rp = (Obj)z;
374: }else {
375: *rp = (Obj)ox_pari_stream;
376: }
377: }else {
378: c = (Q)ARG1(arg);
379: if ( !c || ( NUM(c) && INT(c) && sgnq(c)>0 ) ) {
380: ox_pari_stream_initialized = 1;
381: ox_pari_stream = (Z)c;
382: *rp = (Obj)c;
383: }else {
1.2 noro 384: STOZ(-1,z);
1.1 noro 385: *rp = (Obj)z;
386: }
387: }
388: return;
389: } else if ( !strcmp(key,"oxpari_start") ) {
390: if ( argc(arg) == 1 ) {
391: *rp = (Obj)ox_pari_starting_function;
392: } else {
393: f = (P)ARG1(arg);
394: if ( !f || OID(f) == O_P) {
395: ox_pari_starting_function = f;
396: *rp = (Obj)f;
397: }else {
398: *rp = 0;
399: }
400: }
401: return;
402: }
403: for ( i = 0; ctrls[i].key; i++ )
404: if ( !strcmp(key,ctrls[i].key) )
405: break;
406: if ( ctrls[i].key ) {
407: if ( argc(arg) == 1 )
408: t = *ctrls[i].val;
409: else
1.2 noro 410: *ctrls[i].val = t = ZTOS((Q)ARG1(arg));
411: STOZ(t,z);
1.1 noro 412: *rp = (Obj)z;
413: } else {
414: sprintf(buf,"ctrl : %s : no such key",key);
415: error(buf);
416: }
417: }
418:
419: void Psysinfo(LIST *rp)
420: {
421: int i;
422: NODE n,p;
423: STRING s[7];
424:
425: get_sysinfo();
426: MKSTR(s[0],sysinfo.type); MKSTR(s[1],sysinfo.kernel); MKSTR(s[2],sysinfo.name);
427: MKSTR(s[3],sysinfo.arch); MKSTR(s[4],sysinfo.release); MKSTR(s[5],sysinfo.full);
428: MKSTR(s[6],sysinfo.lang);
429: for(i=6,p=NULL; i>=0; i--,p=n) {
430: MKNODE(n,s[i],p);
431: }
432: MKLIST(*rp,n);
433: }
434:
435: #if !defined(VISUAL) && !defined(__MINGW32__)
436:
437: static char *get_lang()
438: {
439: char *c, *p, *q;
440: c = setlocale(LC_ALL, NULL); /* saving current locale */
441: p = setlocale(LC_ALL, "");
442: q = (char *)MALLOC(strlen(p)+1);
443: strcpy(q,p);
444: setlocale(LC_ALL, c); /* restoring current locale */
445: return q;
446: }
447:
448: static char *myuname(char *option)
449: {
450: char buf[BUFSIZ];
451: char *s;
452: int fd[2], status, pid;
453: *buf = 0;
454: if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) {
455: *buf = 0; return NULL;
456: }
457: pid = fork();
458: if (pid < 0) {
459: return NULL;
460: }else if (pid == 0) {
461: dup2(fd[1], 1);
462: close(2);
463: execlp("uname", "uname", option, NULL);
464: }
465: waitpid(pid, &status, 0);
466: if (status) { /* error */
467: return NULL;
468: }
469: s = buf;
470: if( !read(fd[0], s, BUFSIZ-1) || (s = strchr(s, '\n')) ) {
471: *s = 0;
472: }
473: close(fd[0]);
474: close(fd[1]);
475: s = (char *)MALLOC(strlen(buf)+1);
476: strcpy(s, buf);
477: return s;
478: }
479:
480: static void get_sysinfo()
481: {
482: static struct utsname u;
483: static int initialized = 0;
484: if (initialized) {
485: return;
486: }
487: initialized = 1;
488: uname(&u);
489: sysinfo.kernel = u.sysname;
490: #if defined(__DARWIN__)
491: sysinfo.type = "macosx";
492: sysinfo.name = sysinfo.kernel;
493: #else
494: sysinfo.type = "unix";
495: sysinfo.name = myuname("-o"); // not work on Darwin
496: if (!sysinfo.name) {
497: sysinfo.name = sysinfo.kernel;
498: }
499: #endif
500: sysinfo.arch = u.machine;
501: sysinfo.release= u.release;
502: sysinfo.full = myuname("-a");
503: sysinfo.lang = get_lang();
504: }
505:
506: #else
507:
508: /* http://msdn.microsoft.com/ja-jp/library/windows/desktop/ms724834%28v=vs.85%29.aspx */
509: static char *osnameNT(int major, int minor)
510: {
511: if ((major == 3 && minor == 51) || (major == 4 && minor == 0)) {
512: return "WindowsNT";
513: }else if (major == 5 && minor == 0) {
514: return "Windows2000";
515: }else if (major == 5 && minor == 1) {
516: return "WindowsXP";
517: }else if (major == 5 && minor == 2) {
518: return "Windows2003 Server";
519: }else if (major == 6 && minor == 0) {
520: return "WindowsVista";
521: }else if (major == 6 && minor == 1) {
522: return "Windows7";
523: }else if (major == 6 && minor == 2) {
524: return "Windows8";
525: }else if (major == 6 && minor == 3) {
526: return "Windows8.1";
1.4 ! ohara 527: }else if (major == 10 && minor == 0) {
! 528: return "Windows10";
1.1 noro 529: }
530: return "unknown";
531: }
532:
533: static char *osname95(int major, int minor)
534: {
535: if (major == 4 && minor == 0) {
536: return "Windows95";
537: }else if (major == 4 && minor == 10) {
538: return "Windows98";
539: }else if (major == 4 && minor == 90) {
540: return "WindowsMe";
541: }
542: return "unknown";
543: }
544:
545: static char *get_lang()
546: {
547: char lang[BUFSIZ];
548: char *s;
549: if(GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SISO639LANGNAME, lang, BUFSIZ)) {
550: s = (char *)MALLOC(strlen(lang)+1);
551: strcpy(s,lang);
552: return s;
553: }
554: return "en"; // English
555: }
556:
1.4 ! ohara 557: void get_version_win8(int *major,int *minor,int *build)
! 558: {
! 559: char *res;
! 560: char fname[4096]; /* fullpath of kernel32.dll (_MAX_PATH==260)*/
! 561: char cmd[4096];
! 562: int size;
! 563: char *version_string;
! 564: struct LANGANDCODEPAGE {
! 565: WORD language;
! 566: WORD codepage;
! 567: }* lang;
! 568: sprintf(fname,"%s\\system32\\kernel32.dll", getenv("SYSTEMROOT"));
! 569: size=GetFileVersionInfoSize(fname,0);
! 570: res = (char *)MALLOC(size+1);
! 571: if(GetFileVersionInfo(fname,0,size+1,res)) {
! 572: VerQueryValue(res,"\\VarFileInfo\\Translation",&lang,&size);
! 573: sprintf(cmd,"\\StringFileInfo\\%04x%04x\\ProductVersion",lang->language,lang->codepage);
! 574: VerQueryValue(res,cmd,&version_string,&size);
! 575: sscanf(version_string,"%d.%d.%d.",major,minor,build);
! 576: }
! 577: }
! 578:
1.1 noro 579: static void get_sysinfo()
580: {
581: int arch64 = 0;
582: char buf[BUFSIZ];
583: OSVERSIONINFO v;
584: char *s;
585: static int initialized = 0;
586:
587: if (initialized) {
588: return;
589: }
590: initialized = 1;
591:
592: v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
593: GetVersionEx(&v);
1.4 ! ohara 594: /* Windows8 == version 6.2 */
! 595: if (v.dwPlatformId == VER_PLATFORM_WIN32_NT
! 596: && v.dwMajorVersion == 6 && v.dwMinorVersion >= 2) {
! 597: get_version_win8(&v.dwMajorVersion, &v.dwMinorVersion, &v.dwBuildNumber);
! 598: }
! 599: sysinfo.ver_major=v.dwMajorVersion;
! 600: sysinfo.ver_minor=v.dwMinorVersion;
! 601: sysinfo.ver_build=v.dwBuildNumber;
1.1 noro 602:
603: sysinfo.type = "windows";
604: sysinfo.arch = "x86";
605: sprintf(buf, "%d.%d.%d", v.dwMajorVersion, v.dwMinorVersion, v.dwBuildNumber);
606: s = (char *)MALLOC(strlen(buf)+1);
607: strcpy(s, buf);
608: sysinfo.release = s;
609:
610: if (v.dwPlatformId == VER_PLATFORM_WIN32_NT) {
611: sysinfo.kernel = "WindowsNT";
612: sysinfo.name = osnameNT(v.dwMajorVersion, v.dwMinorVersion);
613:
614: #if defined(_WIN64)
615: sysinfo.arch = "x86_64";
616: #else
617: // IsWow64Process exists on WindowsXP SP2 or later
618: if(GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process")) {
619: IsWow64Process(GetCurrentProcess(),&arch64);
620: if(arch64) {
621: sysinfo.arch = "x86_64";
622: }
623: }
624: #endif
625: }else { /* v.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS */
626: sysinfo.kernel = "Windows95";
627: sysinfo.name = osname95(v.dwMajorVersion, v.dwMinorVersion);
628: }
629: sprintf(buf, "%s %s %s %s %s", sysinfo.kernel, sysinfo.release, sysinfo.name, v.szCSDVersion, sysinfo.arch);
630: s = (char *)MALLOC(strlen(buf)+1);
631: strcpy(s, buf);
632: sysinfo.full = s;
633: sysinfo.lang = get_lang();
634: }
635:
636: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>