Check-in [76c2793cc8]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:add TWAPI upstream changes
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 76c2793cc8c3f3ee89258f651b99e790ff13efd0
User & Date: chw 2016-05-19 09:08:45
Context
2016-05-19
12:10
update SQLite to 3.13.0 check-in: c596548686 user: chw tags: trunk
09:08
add TWAPI upstream changes check-in: 76c2793cc8 user: chw tags: trunk
07:22
reviewed tkhtml for win64 check-in: ab56d64958 user: chw tags: trunk
Changes

Changes to undroid/twapi/configure.

1
2
3
4
5
6
7
8
9
10
...
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
....
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
....
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
....
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
....
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
.....
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
.....
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for twapi 4.2a5.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##
................................................................................
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Identity of this package.
PACKAGE_NAME='twapi'
PACKAGE_TARNAME='twapi'
PACKAGE_VERSION='4.2a5'
PACKAGE_STRING='twapi 4.2a5'
PACKAGE_BUGREPORT=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
................................................................................
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures twapi 4.2a5 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
................................................................................

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of twapi 4.2a5:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
twapi configure 4.2a5
generated by GNU Autoconf 2.63

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by twapi $as_me 4.2a5, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
................................................................................
    for i in $vars; do
	PKG_INCLUDES="$PKG_INCLUDES $i"
    done




    PKG_CFLAGS="$PKG_CFLAGS -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -DPSAPI_VERSION=1"




    vars="
	    twapi/base/adsi.c
	    twapi/base/async.c
................................................................................

exec 6>&1

# Save the log message, to keep $[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by twapi $as_me 4.2a5, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
................................................................................
$config_files

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
twapi config.status 4.2a5
configured by $0, generated by GNU Autoconf 2.63,
  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2008 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."



|







 







|
|







 







|







 







|







 







|













|







 







|







 







|







 







|







1
2
3
4
5
6
7
8
9
10
...
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
....
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
....
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
....
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
....
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
.....
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
.....
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for twapi 4.2a6.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization.  ##
................................................................................
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}

# Identity of this package.
PACKAGE_NAME='twapi'
PACKAGE_TARNAME='twapi'
PACKAGE_VERSION='4.2a6'
PACKAGE_STRING='twapi 4.2a6'
PACKAGE_BUGREPORT=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
................................................................................
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures twapi 4.2a6 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
................................................................................

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of twapi 4.2a6:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
twapi configure 4.2a6
generated by GNU Autoconf 2.63

Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by twapi $as_me 4.2a6, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
................................................................................
    for i in $vars; do
	PKG_INCLUDES="$PKG_INCLUDES $i"
    done




    PKG_CFLAGS="$PKG_CFLAGS -DUNICODE -D_UNICODE -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -DPSAPI_VERSION=1"




    vars="
	    twapi/base/adsi.c
	    twapi/base/async.c
................................................................................

exec 6>&1

# Save the log message, to keep $[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by twapi $as_me 4.2a6, which was
generated by GNU Autoconf 2.63.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
................................................................................
$config_files

Report bugs to <bug-autoconf@gnu.org>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
twapi config.status 4.2a6
configured by $0, generated by GNU Autoconf 2.63,
  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2008 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

Changes to undroid/twapi/configure.in.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_sample in
# this case) so that we create the export library with the dll.
#-----------------------------------------------------------------------

AC_INIT([twapi], [4.2a5])

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
# --------------------------------------------------------------------

................................................................................
#--------------------------------------------------------------------

CLEANFILES="$CLEANFILES twapi_entry.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then

    TEA_ADD_INCLUDES([-I. -I\"$(${CYGPATH} ${srcdir}/twapi/include)\"])

    TEA_ADD_CFLAGS([-DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -DPSAPI_VERSION=1])

    TEA_ADD_SOURCES([
	    twapi/base/adsi.c
	    twapi/base/async.c
	    twapi/base/calls.c
	    twapi/base/cstruct.c
	    twapi/base/errors.c







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_sample in
# this case) so that we create the export library with the dll.
#-----------------------------------------------------------------------

AC_INIT([twapi], [4.2a6])

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
# --------------------------------------------------------------------

................................................................................
#--------------------------------------------------------------------

CLEANFILES="$CLEANFILES twapi_entry.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then

    TEA_ADD_INCLUDES([-I. -I\"$(${CYGPATH} ${srcdir}/twapi/include)\"])

    TEA_ADD_CFLAGS([-DUNICODE -D_UNICODE -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 -DPSAPI_VERSION=1])

    TEA_ADD_SOURCES([
	    twapi/base/adsi.c
	    twapi/base/async.c
	    twapi/base/calls.c
	    twapi/base/cstruct.c
	    twapi/base/errors.c

Added undroid/twapi/tclconfig/ChangeLog.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
2010-09-09  Jan Nijtmans  <nijtmans@users.sf.net>

	* tcl.m4: [FREQ #3058486] TEA_LOAD_CONFIG doesn't set all BUILD_ vars
	Slightly related: defining BUILD_$1 on all platforms - not only win -
	allows the -fvisibility feature to be used in extensions as well, at
	least if you compile against tcl >= 8.5.

2010-08-26  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: ensure safe quoting for autoheader usage

2010-08-19  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: add TEA_ADD_CLEANFILES macro to make adding cleanfiles
	easier, and add *.exp to CLEANFILES Windows default.
	(TEA_MAKE_LIB): Enhanced to check for MSVC that requires manifests
	and auto-embed it into proj DLL via MAKE_SHARED_LIB.  Also define
	VC_MANIFEST_EMBED_DLL and VC_MANIFEST_EMBED_EXE that do the same
	magic in case it is needed for extended TEA projects.

2010-08-16  Jeff Hobbs  <jeffh@ActiveState.com>

	*** Bump to TEA_VERSION 3.9 ***
	If upgrading from TEA_VERSION 3.8, copy over tcl.m4, change
	TEA_INIT to use 3.9 and reconfigure (ac-2.59+).
	BUILD_${PACKAGE_NAME} will be auto-defined on Windows for
	correct setting of TCL_STORAGE_CLASS.
	TEA_LOAD_CONFIG users should remove the SHLIB_LD_LIBS setting done
	in configure.in (LIBS will be automagically populated by
	TEA_LOAD_CONFIG).
	TEA_EXPORT_CONFIG has been added for ${pkg}Config.sh creators
	SHLIB_LD_FLAGS was deprecated a while ago, remove it if it is
	still in your Makefile.in.

	* tcl.m4: add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
	Auto-define BUILD_$PACKAGE_NAME so users don't need to.  This
	needs to correspond with $pkg.h define magic for TCL_STORAGE_CLASS.
	Auto-define CLEANFILES.  Users can expand it.
	(SHLIB_LD_LIBS): define to '${LIBS}' default and change it only if
	necessary.  Platforms not using this may simply not work or have
	very funky linkers.
	(TEA_LOAD_CONFIG): When loading config for another extension,
	auto-add stub libraries found with TEA_ADD_LIBS.  Eases
	configure.in for modules like itk and img::*.
	(TEA_EXPORT_CONFIG): Add standardized function for exporting a
	${pkg}Config.sh.  See use by img::* and itcl.

2010-08-12  Jeff Hobbs  <jeffh@ActiveState.com>

	*** Bump to TEA_VERSION 3.8 ***
	If upgrading from TEA_VERSION 3.7, copy over tcl.m4, change
	TEA_INIT to use 3.8 and reconfigure (ac-2.59+).
	No other changes should be necessary.

	* tcl.m4: remove more vestigial bits from removed platforms.
	Add back SCO_SV-3.2*.
	Remove use of DL_LIBS and DL_OBJS and related baggage - these are
	only needed by the core to support 'load'.
	Allow for macosx in TEA_ADD_SOURCES.
	Correct check for found_xincludes=no in TEA_PATH_UNIX_X.

2010-08-11  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: remove the following old platform configurations:
	UNIX_SV*|UnixWare-5*, SunOS-4.*, SINIX*5.4*, SCO_SV-3.2*<readded>,
	OSF1-1.*, NEXTSTEP-*, NetBSD-1.*|FreeBSD-[[1-2]].*, MP-RAS-*,
	IRIX-5.*, HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*, dgux*,
	BSD/OS-2.1*|BSD/OS-3*
	(AIX): drop AIX-pre4 support and use of ldAix, use -bexpall/-brtl

2010-07-05  Jan Nijtmans  <nijtmans@users.sf.net>

	* tcl.m4: [Patch #1055668] removal of exported internals from
	tclInt.h (EXTERN macro)

2010-04-14  Jan Nijtmans  <nijtmans@users.sf.net>

	* tcl.m4    - Backport a lot of quoting fixes from tcl8.6/unix/tcl.m4
	            - Fix determination of CYGPATH for CYGWIN
	  With those fixes, itcl and tdbc compile fine with CYGWIN

2010-04-06  Jan Nijtmans  <nijtmans@users.sf.net>

	* install-sh         [Bug 2982540] configure and install* script files
	                     should always have LF

2010-02-19  Stuart Cassoff  <stwo@users.sourceforge.net>

	* tcl.m4: Correct compiler/linker flags for threaded builds on
	OpenBSD.

2010-01-19  Jan Nijtmans  <nijtmans@users.sf.net>

	* tcl.m4: Detect CYGWIN variant: win32 or unix

2010-01-03  Donal K. Fellows  <dkf@users.sf.net>

	* unix/tcl.m4 (TEA_CONFIG_CFLAGS): [Tcl Bug 1636685]: Use the
	configuration for modern FreeBSD suggested by the FreeBSD porter.

2009-10-22  Jan Nijtmans  <nijtmans@users.sf.net>

	* tcl.m4: [Tcl Patch #2883533] tcl.m4 support for Haiku OS

2009-04-27  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_CONFIG_CFLAGS): harden the check to add _r to CC on
	AIX with threads.

2009-04-10  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): check for 64-bit TkAqua.

2009-03-26  Jan Nijtmans  <nijtmans@users.sf.net>

	* tclconfig/tcl.m4: Adapt LDFLAGS and LD_SEARCH_FLAGS
	together with SHLIB_LD definition to unbreak building on HPUX.

2009-03-20  Andreas Kupries  <andreask@activestate.com>

	* tclconfig/tcl.m4: Changed SHLIB_LD definition to unbreak
	building on HPUX.

2009-03-16  Joe English  <jenglish@users.sourceforge.net>

	* tcl.m4(TEA_PUBLIC_TK_HEADERS): Look at ${TK_INCLUDE_SPEC}
	(found in tkConfig.sh) when trying to guess where tk.h might be
	[Patch 1960628].

2009-03-11  Joe English  <jenglish@users.sourceforge.net>

	* tcl.m4: Allow ${SHLIB_SUFFIX} to be overridden at
	configure-time [Patch 1960628].  Also fix some comment typos,
	and an uninitialized variable bug-waiting-to-happen.

2008-12-21  Jan Nijtmans  <nijtmans@users.sf.net>

	* tcl.m4: [Bug 2073255] Tcl_GetString(NULL) doesn't crash on HP-UX
	          (this bug report was for Tcl, but holds for TEA as well.)

2008-12-20  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: sync with tdbc tcl.m4 changes
	(SunOS-5.11): Sun cc SHLIB_LD: use LDFLAGS_DEFAULT instead of LDFLAGS

2008-12-02  Jeff Hobbs  <jeffh@ActiveState.com>

	*** Bump to TEA_VERSION 3.7 ***

	* tcl.m4: in private header check, check for <plat>Port.h instead
	of Int.h to ensure all private headers are available.

2008-11-04  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): sync TEA_PRIVATE_TK_HEADERS handling of
	Tk.framework PrivateHeaders with TEA_PRIVATE_TCL_HEADERS.

2008-11-04  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_PATH_TCLCONFIG, TEA_PATH_TKCONFIG): exit with error
	when tclConfig.sh cannot be found. [Bug #1997760]
	(TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): allow for
	finding the headers installed in the public areas, e.g. a result of
	make install-private-headers. [Bug #1631922]

2008-08-12  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): link shlib with current and compatiblity version
	flags; look for libX11.dylib when searching for X11 libraries.

2008-06-12  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.

2008-03-27  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]

2008-02-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* tcl.m4 (TEA_CONFIG_CFLAGS): Updated to work at least in part with
	more modern VC versions. Currently just made the linker flags more
	flexible; more work may be needed.

2007-10-26  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): add support for 64-bit X11.

2007-10-23  Jeff Hobbs  <jeffh@ActiveState.com>

	*** Tagged tea-3-branch to start TEA 4 development on HEAD ***

2007-09-17  Joe English  <jenglish@users.sourceforge.net>

	* tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable'
	to build shared libraries on current NetBSDs [Bug 1749251].

2007-09-15  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: 	replace all direct references to compiler by ${CC} to
			enable CC overriding at configure & make time.
	(SunOS-5.1x):	replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
			'cc' compiler driver.

2007-08-08  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: check Ttk dir for Tk private headers (8.5).
	Add some comments to other bits.

2007-06-25  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): move where / is added.

2007-06-13  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: fix --with-tkinclude alignment. [Bug 1506111]

2007-06-06  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): fix 64bit arch removal in fat 32&64bit builds.

2007-05-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* tcl.m4: Added quoting so that paths with spaces cause fewer
	problems.

2007-03-07  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in -mmacosx-version-min check.

2007-02-15  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: correct private header check to search in generic subdir

2007-02-09  Jeff Hobbs  <jeffh@ActiveState.com>

	*** Bump to TEA_VERSION 3.6 ***

	* tcl.m4: correct -d to -f
	(TEA_CONFIG_CFLAGS): SHLIB_SUFFIX is .so on HP ia64 [Bug 1615058]

2007-02-08  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): check
	that the dirs actually have private headers. [Bug 1631922]

2007-02-04  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: add caching to -pipe check.

2007-01-25  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
	move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to
	avoid errors about multiple -isysroot flags from some older gcc builds.

2006-01-19  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
	(Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
	present in CFLAGS to avoid discrepancies between what headers configure
	sees during preprocessing tests and compiling tests.

2006-12-19  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch flag
	succeeds before enabling 64bit build.

2006-12-16  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Linux): fix previous change to use makefile variable
	LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker
	flags in sampleextension Makefile are picked up.

2006-11-26  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Linux): --enable-64bit support. [Patch 1597389], [Bug 1230558]

2006-08-18  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
	universal builds including x86_64 and for use of -mmacosx-version-min
	instead of MACOSX_DEPLOYMENT_TARGET. For Tk extensions, remove 64-bit
	arch flags from CFLAGS like in the Tk configure, as neither TkAqua nor
	TkX11 can be built for 64-bit at present.

2006-03-28  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: []-quote AC_DEFUN functions.
	(TEA_PATH_TKCONFIG): Fixed Windows-specific check for tkConfig.sh.
	(TEA_MAKE_LIB): Prepend 'lib' for Windows-gcc configs.

2006-03-07  Joe English  <jenglish@users.sourceforge.net>

	* tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD,
	as per the other *BSD variants [Bug 1334613].

2006-01-25  Jeff Hobbs  <jeffh@ActiveState.com>

	*** Bump to TEA version 3.5 ***

	* tcl.m4: keep LD_SEARCH_FLAGS and CC_SEARCH_FLAGS synchronous
	with core tcl.m4 meaning.

2006-01-24  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): use makefile variable LDFLAGS_DEFAULT instead of
	LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile
	are picked up. [Bug 1403343]

2006-01-23  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: add C:/Tcl/lib and C:/Progra~1/Tcl/lib dirs to check for
	*Config.sh on Windows. [Bug 1407544]

2006-01-23  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): for Tk extensions, remove -arch ppc64 from CFLAGS
	like in the Tk configure, as neither TkAqua nor TkX11 can be built for
	64bit at present (no 64bit GUI libraries).

2006-01-22  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: restore system=windows on Windows.
	Remove error if 'ar' isn't found (it may not be on Windows).
	Do not add -lxnet or define _XOPEN_SOURCE on HP-UX by default.
	Ensure the C|LDFLAGS_DEFAULT gets the fully sub'd value at
	configure time.

2006-01-10  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: add caching, use AC_CACHE_CHECK instead of AC_CACHE_VAL
	where possible, consistent message quoting, sync relevant
	tcl/unix/tcl.m4 HEAD changes and gratuitous formatting differences
	(notably sunc removal of support for for ancient BSD's, IRIX 4,
	RISCos and Ultrix by kennykb), Darwin improvements to
	TEA_LOAD_*CONFIG to make linking work against Tcl/Tk frameworks
	installed in arbitrary location, change TEA_PROG_* search order
	(look in *_BIN_DIR parents before *_PREFIX).

2006-01-05  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: add dkf's system config refactor

2006-01-04  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: remove extraneous ' that causes bash 3.1 to choke

2005-12-19  Joe English  <jenglish@users.sourceforge.net>

	* tcl.m4 (TEA_PATH_TCLCONFIG &c): Look for tclConfig.sh &c
	in ${libdir}, where they are installed by default [Patch #1377407].

2005-12-05  Don Porter  <dgp@users.sf.net>

	* tcl.m4 (TEA_PUBLIC_*_HEADERS):	Better support for finding
	header files for uninstalled Tcl and Tk.

2005-12-02  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: correctly bump TEA_VERSION var to 3.4

2005-12-01  Daniel Steffen  <das@users.sourceforge.net>

	* unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset

2005-11-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4:  *** Bump to TEA version 3.4 ***
	Add Windows x64 build support.
	Remove TEA_PATH_NOSPACE and handle the problem with ""s where
	necessary - the macro relied on TCLSH_PROG which didn't work for
	cross-compiles.

2005-11-27  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to
	support passing -isysroot in env(CFLAGS) to configure (flag can't
	be present twice, so can't be in both CFLAGS and LDFLAGS during
	configure), don't use -prebind when deploying on 10.4.
	(TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching.

2005-10-30  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that
	should have been for `uname -s` = "Darwin" instead; added some
	missing quoting.
	(TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that
	install location of tclConfig.sh/tkConfig.sh allows to determine
	the tclsh/wish install dir via ../bin. Indeed tcl/tk can be
	configured with arbitrary --libdir and --bindir (independent of
	prefix) and such a configuration is in fact standard with Darwin
	framework builds. At least now also check ${TCL_PREFIX}/bin
	resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk
	have been configured with arbitrary --bindir, this will still not
	find them, for a general solution *Config.sh would need to contain
	the values of bindir/libdir/includedir passed to configure).

2005-10-07  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds.

2005-10-04  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro
	(TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func

2005-09-13  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: *** Update to TEA version 3.3 ***
	define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG.
	Make --enable-threads the default (users can --disable-threads).
	Improve AIX ${CC}_r fix to better check existing ${CC} value.
	Do the appropriate evals to not require the *TOP_DIR_NATIVE vars
	be set for extensions that use private headers.
	Make aqua check for Xlib compat headers the same as win32.

2005-07-26  Mo DeJong  <mdejong@users.sourceforge.net>

	* tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
	TEA_PROG_WISH, TEA_BUILD_WISH): Remove
	TEA_BUILD_TCLSH and TEA_BUILD_WISH because
	of complaints that it broke the build when
	only an installed version of Tcl was available
	at extension build time. The TEA_PROG_TCLSH and
	TEA_PROG_WISH macros will no longer search the
	path at all. The build tclsh or installed
	tclsh shell will now be found by TEA_PROG_TCLSH.

2005-07-24  Mo DeJong  <mdejong@users.sourceforge.net>

	* tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
	TEA_PROG_WISH, TEA_BUILD_WISH):
	Split confused search for tclsh on PATH and
	build and install locations into two macros.
	TEA_PROG_TCLSH and TEA_PROG_WISH search the
	system PATH for an installed tclsh or wish.
	The TEA_BUILD_TCLSH and TEA_BUILD_WISH
	macros determine the name of tclsh or
	wish in the Tcl or Tk build directory even
	if tclsh or wish has not yet been built.
	[Tcl bug 1160114]
	[Tcl patch 1244153]

2005-06-23  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to
	TK_INCLUDES when building against TkAqua.

	* tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE

	* tcl.m4: changes to better support framework builds of Tcl and Tk out
	of the box: search framework install locations for *Config.sh, and if in
	presence of a framework build, use the framework's Headers and
	PrivateHeaders directories for public and private includes. [FR 947735]

2005-06-18  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
	ensure we can always relocate binaries with install_name_tool.

2005-06-04  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib
	compat headers are available in tkheaders location, otherwise add xlib
	sourcedir to TK_XINCLUDES.

2005-04-25  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow
	use with autoheader.
	(Darwin): added configure checks for recently added linker flags
	-single_module and -search_paths_first to allow building with older
	tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD.
	(TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check.
	(TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4).

2005-03-24  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide
	int type only on Windows when __int64 is detected as valid.

2005-03-24  Don Porter  <dgp@users.sf.net>

	* README.txt:	Update reference to "SC_* macros" to "TEA_* macros".
	* tcl.m4:	Incorporated recent improvements in SC_PATH_TCLCONFIG
	and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG.
	Corrected search path in TEA_PATH_CONFIG and added
	AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load
	the configuration of another package can know where they loaded
	it from.

2005-03-18  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have
	variant LD_SEARCH_FLAGS for gcc and cc builds.

	* tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check.

2005-03-17  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: Correct gcc build and HP-UX-11.

2005-02-08  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -.
	(TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build.
	(TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed).

2005-02-01  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: redo of 2005-01-27 changes to correctly handle paths
	with spaces.  Win/CE and Win/64 builds now require a prebuilt
	tclsh to handle conversion to short pathnames.  This is done in
	the new TEA_PATH_NOSPACE macro.  For Win/CE|64, make CC just the
	compiler and move the necessary includes to CFLAGS.
	(TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support.
	(TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to
	be set in the env and prevent resetting.
	(TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib
	args to -lfoo, for use with mingw.
		*** POTENTIAL INCOMPATABILITY ***
	(TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box.
	Bumped TEA to 3.2.

2005-01-27  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: remove cygpath calls to support msys.
	Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003".
	Make STLIB_LD use $LINKBIN -lib.

2005-01-25  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (Darwin): fixed bug with static build linking to dynamic
	library in /usr/lib etc instead of linking to static library earlier
	in search path. [Tcl Bug 956908]
	Removed obsolete references to Rhapsody.

2004-12-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS
	options, using better default -O levels. [Bug 1092952, 1091967]

2004-12-29  Joe English  <jenglish@users.sourceforge.net>

	* tcl.m4: Do not use ${DBGX} suffix when building
	shared libraries [patch #1081595, TIP #34]

2004-09-07  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds

2004-08-10  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to
	work around subdir configures since autoconf only propagates the
	prefix (not exec_prefix).

2004-07-23  Daniel Steffen  <das@users.sourceforge.net>

	* tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with
	Tcl 8.5 HEAD config, removed core specific & obsolete settings.

2004-07-22  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if
	we are compiling on Aqua.  Add TEA_WINDOWINGSYSTEM var that
	reflects 'tk windowingsystem' value.

2004-07-16  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when
	building against a threaded core.
	(CFLAGS_WARNING): Remove -Wconversion for gcc builds
	(TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build
	configuration, replacing EXTRA_CFLAGS with CFLAGS.  [Bug #874058]
	Update to latest Tcl 8.5 head config settings.
	Call this TEA version 3.1.

2004-04-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with
	AC_TRY_COMPILE for the long vs. long long check. (kenny)

2004-04-26  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to
	define TCL_WIDE_INT_IS_LONG if 'using long'.

2004-03-19  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB

2004-02-11  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: correct TCL_INCLUDES for private headers on Windows - it
	doesn't need the eval.

2004-02-10  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the
	DIR_NATIVE vars defined when using private headers on unix.
	Allow $... to TEA_ADD_SOURCES for constructs like
	TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to
	place more in the Makefile.in.
	tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
	CHECK on limits.h

2003-12-10  Jeff Hobbs  <jeffh@ActiveState.com>

	* Makefile.in:      added TEA_ADD_LIBS, TEA_ADD_INCLUDES and
	* configure:        TEA_ADD_CFLAGS to configurable parameters with
	* configure.in:     PKG_* equivs in the Makefile.  This allows the
	* tclconfig/tcl.m4: user to worry less about actual magic VAR names.
	Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires
	exact file names.

2003-12-09  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff)

2003-12-05  Jeff Hobbs  <jeffh@ActiveState.com>

	* configure:
	* configure.in:
	* Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the
	first part of VPATH can get chopped off.
	Change .c.$(OBJEXT) rule to .c.@OBJEXT@ to support more makes.
	* tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub
	generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as
	the way the user specifies library files.

2003-12-03  Jeff Hobbs  <jeffh@ActiveState.com>

	* configure:           Update of TEA spec to (hopefully) simplify
	* configure.in:        some aspects of TEA by making use of more
	* Makefile.in:         AC 2.5x features.  Use PACKAGE_NAME (instead
	* generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of
	* tclconfig/tcl.m4:    VERSION) arguments to AC_INIT as the TEA
	package name and version.
	Provide a version argument to TEA_INIT - starting with 3.0.
	Drop all use of interior shell substs that older makefiles didn't
	like.  Use PKG_* naming convention instead.
	Move specification of source files and public headers into
	configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS.  These will
	be munged during ./configure into the right obj file names (no
	$(SOURCES:.c=.obj) needed).
	There is almost nothing that should be touched in Makefile.in now
	for the developer.  May want to add a TEA_ADD_TCL_SOURCES for the
	RUNTIME_SOURCES that remains.
	Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does.
	Only specify the user requested LDFLAGS/CFLAGS in the Makefile,
	don't mention the _OPTIMIZE/_DEBUG variants.

2003-10-15  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the
	TEA_SETUP_COMPILER macro.  They are split so the check for CC
	occurs before any use of CC.  Also add AC_PROG_CPP to the compiler
	checks.

2003-10-06  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: Updated for autoconf 2.5x prereq.
	Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks
	in tcl.h, which also handles TCL_LL_MODIFIER* properly.

2003-04-22  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: correct default setting of ARCH for WinCE builds.
	Correct \ escaping for CE sed macros.

2003-04-10  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: replace $(syscal) construct with older `syscall` for
	systems where sh != bash.

2003-04-09  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib
	options for Windows/CE compilation support.  Requires the
	Microsoft eMbedded SDK and Keuchel's celib emulation layer.

2003-02-18  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on
	the link line when checking for the pthread_attr_setstacksize
	symbol. (dejong)

	* tcl.m4 (TEA_SETUP_COMPILER): added default calls to
	TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS,
	TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD.

2003-02-14  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: correct HP-UX ia64 --enable-64bit build flags

2003-01-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: check $prefix/lib as well as $exec_prefix/lib when
	looking for tcl|tkConfig.sh, as this check is done before we would
	set exec_prefix when the user does not define it.

2003-01-21  Mo DeJong  <mdejong@users.sourceforge.net>

	* tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support
	for mingw, the previous implementation would
	use VC++ when compiling with mingw gcc. Don't
	pass -fPIC since gcc always compiles pic code
	under win32. Change some hard coded cases
	of gcc to ${CC}.

2002-10-15  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to
	TEA_MAKE_LIB because setting too early confuses other AC_* macros.
	Correct the HP-11 SHLIB_LD_LIBS setting.

	* tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and
	make it pick up the env CFLAGS at configure time.

2002-10-09  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG.
	Improved AIX 64-bit build support, allow it on AIX-4 as well.
	Enable 64-bit HP-11 compilation with gcc.
	Enable 64-bit IRIX64-6 cc build support.
	Correct FreeBSD thread library linkage.
	Add OSF1 static build support.
	Improve SunOS-5 shared build SHLIB_LD macro.

2002-07-20  Zoran Vasiljevic  <zoran@archiware.com>

	* tcl.m4: Added MINGW32 to list of systems checked for Windows build.
	Also, fixes some indentation issues with "--with-XXX" options.

2002-04-23  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to
	use new threaded allocatory by default on Unix for Tcl 8.4.
	(TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+.

2002-04-22  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that
	we can use autoconf 2.5x as well as 2.13.  This prevents us from
	being able to warn against the use of cygwin gcc at configure
	time, but allows autoconf 2.5x, which is what is shipped with most
	newer systems.

2002-04-11  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: Enabled COFF as well as CV style debug info with
	--enable-symbols to allow Dr. Watson users to see function info.
	More info on debugging levels can be obtained at:
	http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp

2002-04-03  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: change all SC_* macros to TEA_*.  The SC_ was for
	Scriptics, which is no more.  TEA represents a better, independent
	prefix that won't need changing.
	Added preliminary mingw gcc support. [Patch #538772]
	Added TEA_PREFIX macro that handles defaulting the prefix and
	exec_prefix vars to those used by Tcl if none were specified.
	Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC
	check and several other basic AC_PROG checks needed for making
	executables.  This greatly simplifies user's configure.in files.
	Collapsed AIX-5 defines into AIX-* with extra checks for doing the
	ELF stuff on AIX-5-ia64.
	Updated TEA_ENABLE_THREADS to take an optional arg to allow
	switching it on by default (for Thread) and add sanity checking to
	warn the user if configuring threads incompatibly.

2002-03-29  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT.
	Removed --enable-64bit support for AIX-4 because it wasn't correct.
	Added -MT or -MD Windows linker switches to properly support
	symbols-enabled builds.

2002-03-28  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first
	instead of calling it as that inlines it each time in shell code.
	Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti.
	Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds.
	A few changes to support itcl (and perhaps others):
	Added support for making your own stub libraries to SC_MAKE_LIB.
	New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg
	and find that ${pkg}Config.sh file.  itk uses this for itcl.

2002-03-27  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk
	build dir setup.
	Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS.
	Added XLIBSW onto LIBS when it is defined.
	Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS
	instead to not rely as much on tclConfig.sh cached info.
	Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH.
	These move towards making TEA much more independent of *Config.sh.

2002-03-19  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and
	SHLIB_SUFFIX defines for Win.
	(SC_PATH_X): made this only do the check on unix platforms.

2002-03-12  Jeff Hobbs  <jeffh@ActiveState.com>

	* README.txt: updated to reflect fewer files

2002-03-06  Jeff Hobbs  <jeffh@ActiveState.com>

	* config.guess (removed):
	* config.sub (removed): removed unnecessary files

	* installFile.tcl (removed):
	* mkinstalldirs (removed): these aren't really necessary for
	making TEA work

	* tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't
	check /usr(/local)/include for includes on Windows when not using
	gcc

2002-03-05  Jeff Hobbs  <jeffh@ActiveState.com>

	* tcl.m4: added warnings on Windows, removed RELPATH define and
	added TCL_LIBS to MAKE_LIB macro.

	This import represents 2.0.0, or a new start at attempting to
	make TEA much easier for C extension developers.

	**** moved from tclpro project to core tcl project, ****
	**** renamed to 'tclconfig'                         ****

2001-03-15    Karl Lehenbauer <karl@procplace.com>

	* installFile.tcl: Added updating of the modification time of
	  the target file whether we overwrote it or decided that it
	  hadn't changed.  This was necessary for us to be able to
	  determine whether or not a module install touched the file.

2001-03-08    Karl Lehenbauer <karl@procplace.com>

	* installFile.tcl: Added support for converting new-style (1.1+)
	  Cygnus drive paths to Tcl-style.

2001-01-15    <brent.welch@interwoven.com>

	* tcl.m4: Added FreeBSD clause.

2001-01-03    <brent.welch@interwoven.com>

	* tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking
	for exec-prefix.

2000-12-01    <brent.welch@interwoven.com>

	* tcl.m4: Concatenated most of the Ajuba acsite.m4 file
	so we don't need to modify the autoconf installation.
	* config.guess:
	* config.sub:
	* installFile.tcl:
	Added files from the itcl config subdirectory,
	which should go away.

2000-7-29    <welch@ajubasolutions.com>

	* Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within
	TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent
	change from $(srcdir) to $(srcdir)/..

Changes to undroid/twapi/twapi/base/cstruct.c.

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
    char type;                  /* The type of the field */
} TwapiCStructField;
#define CSTRUCT_REP(o_)    ((TwapiCStructRep *)((o_)->internalRep.twoPtrValue.ptr1))
#define CSTRUCT_REP_SET(o_)    (o_)->internalRep.twoPtrValue.ptr1

typedef struct TwapiCStructRep_s {
    int nrefs;                  /* Reference count for this structure */
    unsigned int nfields;                /* Number of elements in fields[] */
    unsigned int size;                   /* Size of the defined structure */
    unsigned int alignment;              /* Alignment required (calculated based
                                   on contained fields) */
    TwapiCStructField fields[1];
} TwapiCStructRep;

static void CStructRepDecrRefs(TwapiCStructRep *csP)
................................................................................
    return TCL_ERROR;
}


static TCL_RESULT ObjFromCStructHelper(Tcl_Interp *interp, void *pv, unsigned int nbytes, TwapiCStructRep *csP, DWORD flags, Tcl_Obj **objPP)
{
    Tcl_Obj *objs[2*32]; /* Assume no more than 32 fields in a struct */
    unsigned int i, objindex, max_fields, include_key;


    TWAPI_ASSERT(csP->nrefs > 0);
    csP->nrefs += 1;            /* So it is not shimmered away underneath us */

    if (nbytes != 0 && nbytes != csP->size) {
        TwapiReturnErrorMsg(interp, TWAPI_INVALID_DATA, "Size mismatch with cstruct definition");
        goto error_return;







|







 







|
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
    char type;                  /* The type of the field */
} TwapiCStructField;
#define CSTRUCT_REP(o_)    ((TwapiCStructRep *)((o_)->internalRep.twoPtrValue.ptr1))
#define CSTRUCT_REP_SET(o_)    (o_)->internalRep.twoPtrValue.ptr1

typedef struct TwapiCStructRep_s {
    int nrefs;                  /* Reference count for this structure */
    int nfields;                /* Number of elements in fields[] */
    unsigned int size;                   /* Size of the defined structure */
    unsigned int alignment;              /* Alignment required (calculated based
                                   on contained fields) */
    TwapiCStructField fields[1];
} TwapiCStructRep;

static void CStructRepDecrRefs(TwapiCStructRep *csP)
................................................................................
    return TCL_ERROR;
}


static TCL_RESULT ObjFromCStructHelper(Tcl_Interp *interp, void *pv, unsigned int nbytes, TwapiCStructRep *csP, DWORD flags, Tcl_Obj **objPP)
{
    Tcl_Obj *objs[2*32]; /* Assume no more than 32 fields in a struct */
    unsigned int objindex, include_key;
    int i, max_fields;

    TWAPI_ASSERT(csP->nrefs > 0);
    csP->nrefs += 1;            /* So it is not shimmered away underneath us */

    if (nbytes != 0 && nbytes != csP->size) {
        TwapiReturnErrorMsg(interp, TWAPI_INVALID_DATA, "Size mismatch with cstruct definition");
        goto error_return;

Changes to undroid/twapi/twapi/base/errors.c.

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
496
497
498
499
500
501
502





            objP = Twapi_FormatMsgFromModule(error, hNetmsg);
        if (objP)
            return objP;
    }

    /* Try as NTSTATUS code */
    if (hNtdll == NULL)
        hNtdll = GetModuleHandle("ntdll.dll");
    if (hNtdll)
        objP = Twapi_FormatMsgFromModule(error, hNtdll);
    if (objP)
        return objP;

    /* How about WMI ? */
    if (hWmi == NULL)
................................................................................
    HANDLE hevl;
    hevl = RegisterEventSourceA(NULL, TWAPI_TCL_NAMESPACE);
    if (hevl) {
        (void) ReportEventA(hevl, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, &msg, NULL);
        DeregisterEventSource(hevl);
    }
}












|







 







>
>
>
>
>
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
496
497
498
499
500
501
502
503
504
505
506
507
            objP = Twapi_FormatMsgFromModule(error, hNetmsg);
        if (objP)
            return objP;
    }

    /* Try as NTSTATUS code */
    if (hNtdll == NULL)
        hNtdll = GetModuleHandleW(L"ntdll.dll");
    if (hNtdll)
        objP = Twapi_FormatMsgFromModule(error, hNtdll);
    if (objP)
        return objP;

    /* How about WMI ? */
    if (hWmi == NULL)
................................................................................
    HANDLE hevl;
    hevl = RegisterEventSourceA(NULL, TWAPI_TCL_NAMESPACE);
    if (hevl) {
        (void) ReportEventA(hevl, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, &msg, NULL);
        DeregisterEventSource(hevl);
    }
}

TWAPI_EXTERN void TwapiUnreachablePanic()
{
    Tcl_Panic("Unreachable code executed.");
}

Changes to undroid/twapi/twapi/base/recordarray.c.

587
588
589
590
591
592
593
594


595



596
597
598
599
600
601
602
603
    if (len == 0) {
        ObjSetStaticResult(interp, "empty record definition");
        return TCL_ERROR;
    }

    nsP = Tcl_GetCurrentNamespace(interp);
    sep = nsP->parentPtr == NULL ? "" : "::";
    if (objc < 3) 


        nameObj = Tcl_ObjPrintf("%s%srecord%u", nsP->fullName, sep, Twapi_NewId());



    else {
        char *nameP = ObjToString(objv[1]);
        if (nameP[0] == ':' && nameP[1] == ':')
            nameObj = objv[1];
        else
            nameObj = Tcl_ObjPrintf("%s%s%s", nsP->fullName, sep, nameP);
    }








|
>
>
|
>
>
>
|







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
    if (len == 0) {
        ObjSetStaticResult(interp, "empty record definition");
        return TCL_ERROR;
    }

    nsP = Tcl_GetCurrentNamespace(interp);
    sep = nsP->parentPtr == NULL ? "" : "::";
    if (objc < 3)  {
#ifdef _WIN64
        /* Note: even MingW gcc needs %I64, NOT %llu, as it uses the MSVC runtime */
        nameObj = Tcl_ObjPrintf("%s%srecord%I64u", nsP->fullName, sep, Twapi_NewId());
#else
        nameObj = Tcl_ObjPrintf("%s%srecord%lu", nsP->fullName, sep, Twapi_NewId());
#endif
    } else {
        char *nameP = ObjToString(objv[1]);
        if (nameP[0] == ':' && nameP[1] == ':')
            nameObj = objv[1];
        else
            nameObj = Tcl_ObjPrintf("%s%s%s", nsP->fullName, sep, nameP);
    }

Changes to undroid/twapi/twapi/base/tclobjs.c.

1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
....
4240
4241
4242
4243
4244
4245
4246


























4247
4248
4249
4250
4251
4252
4253
....
4757
4758
4759
4760
4761
4762
4763






4764
4765
4766
4767
4768
4769
4770
4771
4772
4773






4774
4775
4776
4777
4778
4779
4780
    Tcl_Obj       *objP;
    if (UuidToStringA(uuidP, &uuidStr) != RPC_S_OK)
        return NULL;

    /* NOTE UUID and GUID have same binary format but are formatted
       differently based on the component. */
    objP = ObjFromString((char *)uuidStr);
    RpcStringFree(&uuidStr);
    return objP;
}

TWAPI_EXTERN int ObjToUUID(Tcl_Interp *interp, Tcl_Obj *objP, UUID *uuidP)
{
    /* NOTE UUID and GUID have same binary format but are formatted
       differently based on the component.  We accept both forms here */
................................................................................
    return Tcl_GetBooleanFromObj(interp, objP, valP);
}

TWAPI_EXTERN TCL_RESULT ObjToWideInt(Tcl_Interp *interp, Tcl_Obj *objP, Tcl_WideInt *wideP)
{
    return Tcl_GetWideIntFromObj(interp, objP, wideP);
}



























TWAPI_EXTERN TCL_RESULT ObjToDouble(Tcl_Interp *interp, Tcl_Obj *objP, double *dblP)
{
    return Tcl_GetDoubleFromObj(interp, objP, dblP);
}

TWAPI_EXTERN Tcl_Obj *ObjNewList(int objc, Tcl_Obj * const objv[])
................................................................................
}

static void UpdateEnumTypeString(Tcl_Obj *objP)
{
    Tcl_Obj *obj2P;
    char *p;
    int len;






    TCL_RESULT res;

    TWAPI_ASSERT(objP->bytes == NULL);
    TWAPI_ASSERT(objP->typePtr == &gEnumType);
    TWAPI_ASSERT(objP->internalRep.ptrAndLongRep.ptr);
    
    res = ObjListIndex(NULL, objP->internalRep.ptrAndLongRep.ptr, objP->internalRep.ptrAndLongRep.value, &obj2P);
    TWAPI_ASSERT(res == TCL_OK);
    TWAPI_ASSERT(obj2P);







    p = ObjToStringN(obj2P, &len);
    objP->bytes = ckalloc(len+1);
    objP->length = len;
    CopyMemory(objP->bytes, p, len+1);
}

TWAPI_EXTERN TCL_RESULT ObjToEnum(Tcl_Interp *interp, Tcl_Obj *enumsObj, Tcl_Obj *nameObj,







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>










>
>
>
>
>
>







1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
....
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
....
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
    Tcl_Obj       *objP;
    if (UuidToStringA(uuidP, &uuidStr) != RPC_S_OK)
        return NULL;

    /* NOTE UUID and GUID have same binary format but are formatted
       differently based on the component. */
    objP = ObjFromString((char *)uuidStr);
    RpcStringFreeA(&uuidStr);
    return objP;
}

TWAPI_EXTERN int ObjToUUID(Tcl_Interp *interp, Tcl_Obj *objP, UUID *uuidP)
{
    /* NOTE UUID and GUID have same binary format but are formatted
       differently based on the component.  We accept both forms here */
................................................................................
    return Tcl_GetBooleanFromObj(interp, objP, valP);
}

TWAPI_EXTERN TCL_RESULT ObjToWideInt(Tcl_Interp *interp, Tcl_Obj *objP, Tcl_WideInt *wideP)
{
    return Tcl_GetWideIntFromObj(interp, objP, wideP);
}

TWAPI_EXTERN TCL_RESULT ObjToDWORD(Tcl_Interp *interp, Tcl_Obj *objP, DWORD *dwP) {
    long l;
    /* TBD - should we convert to Tcl_WideInt and check the range?
       How much code depends on silent long<->unsigned long conversions? */
    /* TBD - Test that full 32 bit unsigned is returned correctly */
    TCL_RESULT res = Tcl_GetLongFromObj(interp, objP, &l);
    if (res == TCL_OK)
        *dwP = (DWORD) l;
    return res;
}

/* Define as a function to avoid gcc squawking about signed pointers */
TWAPI_EXTERN TCL_RESULT ObjToDWORD_PTR(Tcl_Interp *interp, Tcl_Obj *objP, DWORD_PTR *dwP)
{
#if defined(_WIN64)
    Tcl_WideInt val;
    TCL_RESULT res = Tcl_GetWideIntFromObj(interp, objP, &val);
#else
    long val;
    TCL_RESULT res = Tcl_GetLongFromObj(interp, objP, &val);
#endif
    if (res == TCL_OK)
        *dwP = (DWORD_PTR) val;
    return res;
}

TWAPI_EXTERN TCL_RESULT ObjToDouble(Tcl_Interp *interp, Tcl_Obj *objP, double *dblP)
{
    return Tcl_GetDoubleFromObj(interp, objP, dblP);
}

TWAPI_EXTERN Tcl_Obj *ObjNewList(int objc, Tcl_Obj * const objv[])
................................................................................
}

static void UpdateEnumTypeString(Tcl_Obj *objP)
{
    Tcl_Obj *obj2P;
    char *p;
    int len;

    /*
     * Separate out the assert version because otherwise gcc squawks about
     * unused variable res
     */
#if TWAPI_ENABLE_ASSERT
    TCL_RESULT res;

    TWAPI_ASSERT(objP->bytes == NULL);
    TWAPI_ASSERT(objP->typePtr == &gEnumType);
    TWAPI_ASSERT(objP->internalRep.ptrAndLongRep.ptr);
    
    res = ObjListIndex(NULL, objP->internalRep.ptrAndLongRep.ptr, objP->internalRep.ptrAndLongRep.value, &obj2P);
    TWAPI_ASSERT(res == TCL_OK);
    TWAPI_ASSERT(obj2P);

#else
    
    (void) ObjListIndex(NULL, objP->internalRep.ptrAndLongRep.ptr, objP->internalRep.ptrAndLongRep.value, &obj2P);

#endif
    
    p = ObjToStringN(obj2P, &len);
    objP->bytes = ckalloc(len+1);
    objP->length = len;
    CopyMemory(objP->bytes, p, len+1);
}

TWAPI_EXTERN TCL_RESULT ObjToEnum(Tcl_Interp *interp, Tcl_Obj *enumsObj, Tcl_Obj *nameObj,

Changes to undroid/twapi/twapi/base/winchars.c.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
                   Always >=0 (i.e. -1 not used to indicate null termination)*/
    WCHAR chars[1]; /* Variable length array holding the string */
} WinChars;

static void DupWinCharsType(Tcl_Obj *srcP, Tcl_Obj *dstP);
static void FreeWinCharsType(Tcl_Obj *objP);
static void UpdateWinCharsTypeString(Tcl_Obj *objP);
static struct Tcl_ObjType gWinCharsType = {
    "TwapiWinChars",
    FreeWinCharsType,
    DupWinCharsType,
    UpdateWinCharsTypeString,
    NULL,     /* jenglish says keep this NULL */
};

................................................................................
    
    if (objP->typePtr == &gWinCharsType)
        return WinCharsGet(objP)->chars;

    utf8 = ObjToStringN(objP, &nbytes);
    Tcl_WinUtfToTChar(utf8, nbytes, &ds);
    len = Tcl_DStringLength(&ds) / sizeof(WCHAR);
    rep = WinCharsNew(Tcl_DStringValue(&ds), len);
    Tcl_DStringFree(&ds);
    
    /* Convert the passed object's internal rep */
    if (objP->typePtr && objP->typePtr->freeIntRepProc)
        objP->typePtr->freeIntRepProc(objP);
    WinCharsSet(objP, rep);
    return rep->chars;







|







 







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
                   Always >=0 (i.e. -1 not used to indicate null termination)*/
    WCHAR chars[1]; /* Variable length array holding the string */
} WinChars;

static void DupWinCharsType(Tcl_Obj *srcP, Tcl_Obj *dstP);
static void FreeWinCharsType(Tcl_Obj *objP);
static void UpdateWinCharsTypeString(Tcl_Obj *objP);
struct Tcl_ObjType gWinCharsType = {
    "TwapiWinChars",
    FreeWinCharsType,
    DupWinCharsType,
    UpdateWinCharsTypeString,
    NULL,     /* jenglish says keep this NULL */
};

................................................................................
    
    if (objP->typePtr == &gWinCharsType)
        return WinCharsGet(objP)->chars;

    utf8 = ObjToStringN(objP, &nbytes);
    Tcl_WinUtfToTChar(utf8, nbytes, &ds);
    len = Tcl_DStringLength(&ds) / sizeof(WCHAR);
    rep = WinCharsNew((WCHAR *) Tcl_DStringValue(&ds), len);
    Tcl_DStringFree(&ds);
    
    /* Convert the passed object's internal rep */
    if (objP->typePtr && objP->typePtr->freeIntRepProc)
        objP->typePtr->freeIntRepProc(objP);
    WinCharsSet(objP, rep);
    return rep->chars;

Changes to undroid/twapi/twapi/com/com.c.

1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844

        hr = CoInitializeSecurity(secdP, -1, NULL, NULL,
                                  authn_level, impersonation_level,
                                  sole_auth_listP, capabilities, NULL);

        /* Zero out passwords in memory */
        if (sole_auth_listP && sole_auth_listP->aAuthInfo) {
            int i;
            SOLE_AUTHENTICATION_INFO *saiP = sole_auth_listP->aAuthInfo;
            for (i = 0; i < sole_auth_listP->cAuthInfo;  ++i) {
                if (saiP[i].dwAuthnSvc == RPC_C_AUTHN_WINNT ||
                    saiP[i].dwAuthnSvc == RPC_C_AUTHN_GSS_KERBEROS ||
                    saiP[i].dwAuthnSvc == RPC_C_AUTHN_GSS_NEGOTIATE) {
                    SecureZeroSEC_WINNT_AUTH_IDENTITY(saiP[i].pAuthInfo);
                }







|







1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844

        hr = CoInitializeSecurity(secdP, -1, NULL, NULL,
                                  authn_level, impersonation_level,
                                  sole_auth_listP, capabilities, NULL);

        /* Zero out passwords in memory */
        if (sole_auth_listP && sole_auth_listP->aAuthInfo) {
            DWORD i;
            SOLE_AUTHENTICATION_INFO *saiP = sole_auth_listP->aAuthInfo;
            for (i = 0; i < sole_auth_listP->cAuthInfo;  ++i) {
                if (saiP[i].dwAuthnSvc == RPC_C_AUTHN_WINNT ||
                    saiP[i].dwAuthnSvc == RPC_C_AUTHN_GSS_KERBEROS ||
                    saiP[i].dwAuthnSvc == RPC_C_AUTHN_GSS_NEGOTIATE) {
                    SecureZeroSEC_WINNT_AUTH_IDENTITY(saiP[i].pAuthInfo);
                }

Changes to undroid/twapi/twapi/console/console.c.

11
12
13
14
15
16
17



18
19

20
21
22
23
24
25
26
...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
static HMODULE gModuleHandle;     /* DLL handle to ourselves */
#endif

#ifndef MODULENAME
#define MODULENAME "twapi_console"
#endif




static TwapiInterpContext * volatile console_control_ticP;


static int ObjToCHAR_INFO(Tcl_Interp *interp, Tcl_Obj *obj, CHAR_INFO *ciP)
{
    Tcl_Obj **objv;
    int       objc;
    int i;

    if (ObjGetElements(interp, obj, &objc, &objv) != TCL_OK ||
................................................................................
}

static int Twapi_StartConsoleEventNotifier(TwapiInterpContext *ticP)
{
    void *pv;

    ERROR_IF_UNTHREADED(ticP->interp);
    pv = InterlockedCompareExchangePointer((void * volatile *) &console_control_ticP,
                                           ticP, NULL);
    if (pv) {
        ObjSetStaticResult(ticP->interp, "Console control handler is already set.");
        return TCL_ERROR;
    }

    if (SetConsoleCtrlHandler(TwapiConsoleCtrlHandler, TRUE)) {
        ticP->module.data.ival = 1; /* Indicates console is hooked in this interp */
        TwapiInterpContextRef(ticP, 1);
        return TCL_OK;
    }
    else {
        InterlockedExchangePointer((void * volatile *)&console_control_ticP, NULL);
        return TwapiReturnSystemError(ticP->interp);
    }
}

    
static int Twapi_StopConsoleEventNotifier(TwapiInterpContext *ticP)
{
    void *pv;
    pv = InterlockedCompareExchangePointer((void * volatile *) &console_control_ticP,
                                           NULL, ticP);
    if (pv != (void*) ticP) {
        ObjSetStaticResult(ticP->interp, "Console control handler not set by this interpreter.");
        return TCL_ERROR;
    }
    SetConsoleCtrlHandler(TwapiConsoleCtrlHandler, FALSE);
    ticP->module.data.ival = 0; /* Indicates console is not hooked in this interp */







>
>
>

<
>







 







|












|








|







11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
static HMODULE gModuleHandle;     /* DLL handle to ourselves */
#endif

#ifndef MODULENAME
#define MODULENAME "twapi_console"
#endif

#ifdef __GNUC__
static void * volatile console_control_ticP;
#else
static TwapiInterpContext * volatile console_control_ticP;

#endif
static int ObjToCHAR_INFO(Tcl_Interp *interp, Tcl_Obj *obj, CHAR_INFO *ciP)
{
    Tcl_Obj **objv;
    int       objc;
    int i;

    if (ObjGetElements(interp, obj, &objc, &objv) != TCL_OK ||
................................................................................
}

static int Twapi_StartConsoleEventNotifier(TwapiInterpContext *ticP)
{
    void *pv;

    ERROR_IF_UNTHREADED(ticP->interp);
    pv = InterlockedCompareExchangePointer(&console_control_ticP,
                                           ticP, NULL);
    if (pv) {
        ObjSetStaticResult(ticP->interp, "Console control handler is already set.");
        return TCL_ERROR;
    }

    if (SetConsoleCtrlHandler(TwapiConsoleCtrlHandler, TRUE)) {
        ticP->module.data.ival = 1; /* Indicates console is hooked in this interp */
        TwapiInterpContextRef(ticP, 1);
        return TCL_OK;
    }
    else {
        InterlockedExchangePointer(&console_control_ticP, NULL);
        return TwapiReturnSystemError(ticP->interp);
    }
}

    
static int Twapi_StopConsoleEventNotifier(TwapiInterpContext *ticP)
{
    void *pv;
    pv = InterlockedCompareExchangePointer(&console_control_ticP,
                                           NULL, ticP);
    if (pv != (void*) ticP) {
        ObjSetStaticResult(ticP->interp, "Console control handler not set by this interpreter.");
        return TCL_ERROR;
    }
    SetConsoleCtrlHandler(TwapiConsoleCtrlHandler, FALSE);
    ticP->module.data.ival = 0; /* Indicates console is not hooked in this interp */

Changes to undroid/twapi/twapi/crypto/crypto.c.

3012
3013
3014
3015
3016
3017
3018


3019
3020
3021
3022
3023
3024
3025
            ObjToDWORD(NULL, objs[0], (DWORD *) &algids[0]) != TCL_OK ||
            ObjToDWORD(NULL, objs[1], (DWORD *) &algids[1]) != TCL_OK) {
            TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Invalid CRYPT_OID_INFO_SIGN_KEY format");
            return TCL_ERROR;
        }
        pv = algids;
        break;


    }

    /* NOTE: coiP must NOT be freed */
    coiP = CryptFindOIDInfo(keytype, pv, group);
    if (coiP)
        ObjSetResult(interp, ObjFromCRYPT_OID_INFO(coiP));
    /* Else empty result */







>
>







3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
            ObjToDWORD(NULL, objs[0], (DWORD *) &algids[0]) != TCL_OK ||
            ObjToDWORD(NULL, objs[1], (DWORD *) &algids[1]) != TCL_OK) {
            TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Invalid CRYPT_OID_INFO_SIGN_KEY format");
            return TCL_ERROR;
        }
        pv = algids;
        break;
    default:
        return TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Invalid OID info flags.");
    }

    /* NOTE: coiP must NOT be freed */
    coiP = CryptFindOIDInfo(keytype, pv, group);
    if (coiP)
        ObjSetResult(interp, ObjFromCRYPT_OID_INFO(coiP));
    /* Else empty result */

Changes to undroid/twapi/twapi/crypto/sspi.c.

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112

    if (n != 0) {
        if (WSTREQ(packageP, UNISP_NAME_W) ||
            WSTREQ(packageP, SCHANNEL_NAME_W)) {
            if (ParseSCHANNEL_CRED(ticP, authObj, (SCHANNEL_CRED **)&pv) != TCL_OK)
                goto vamoose;
            is_unisp = 1;
#ifdef WDIGEST_SP_NAME_W
        } else if (WSTREQ(packageP, WDIGEST_SP_NAME_W) ||
                   WSTREQ(packageP, NTLMSP_NAME) ||
                   WSTREQ(packageP, NEGOSSP_NAME_W) ||
                   WSTREQ(packageP, MICROSOFT_KERBEROS_NAME_W)) {
            /* TBD - SDK has the comment that for RPC this memory
               must be valid for the lifetime of the binding handle. Is
               that true for SSPI also. Test */
            if (ParsePSEC_WINNT_AUTH_IDENTITY(ticP, authObj, (SEC_WINNT_AUTH_IDENTITY_W **)&pv) != TCL_OK)
                goto vamoose;
            is_unisp = 0;
#endif
        } else {
            TwapiReturnErrorEx(interp, TWAPI_UNSUPPORTED_TYPE,
                               Tcl_ObjPrintf("Non-default authentication is not supported for SSPI package %s.", ObjToString(objv[2])));
            goto vamoose;
        }
    }








<










<







1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110

    if (n != 0) {
        if (WSTREQ(packageP, UNISP_NAME_W) ||
            WSTREQ(packageP, SCHANNEL_NAME_W)) {
            if (ParseSCHANNEL_CRED(ticP, authObj, (SCHANNEL_CRED **)&pv) != TCL_OK)
                goto vamoose;
            is_unisp = 1;

        } else if (WSTREQ(packageP, WDIGEST_SP_NAME_W) ||
                   WSTREQ(packageP, NTLMSP_NAME) ||
                   WSTREQ(packageP, NEGOSSP_NAME_W) ||
                   WSTREQ(packageP, MICROSOFT_KERBEROS_NAME_W)) {
            /* TBD - SDK has the comment that for RPC this memory
               must be valid for the lifetime of the binding handle. Is
               that true for SSPI also. Test */
            if (ParsePSEC_WINNT_AUTH_IDENTITY(ticP, authObj, (SEC_WINNT_AUTH_IDENTITY_W **)&pv) != TCL_OK)
                goto vamoose;
            is_unisp = 0;

        } else {
            TwapiReturnErrorEx(interp, TWAPI_UNSUPPORTED_TYPE,
                               Tcl_ObjPrintf("Non-default authentication is not supported for SSPI package %s.", ObjToString(objv[2])));
            goto vamoose;
        }
    }

Changes to undroid/twapi/twapi/crypto/twapi_crypto.h.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define TWAPI_CRYPTO_H


int TwapiSspiInitCalls(Tcl_Interp *interp, TwapiInterpContext *ticP);
#ifndef UNISP_NAME_W
#include <schannel.h>            /* For VC6 */
#endif
#if !defined(WDIGEST_SP_NAME_W) && !defined(__GNUC__)
#include <wdigest.h>            /* For VC6 */
#endif
#include <softpub.h>            /* WinVerifyTrust */

#ifndef X509_ALGORITHM_IDENTIFIER
# define X509_ALGORITHM_IDENTIFIER           ((LPCSTR) 74)
#endif








|
|







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define TWAPI_CRYPTO_H


int TwapiSspiInitCalls(Tcl_Interp *interp, TwapiInterpContext *ticP);
#ifndef UNISP_NAME_W
#include <schannel.h>            /* For VC6 */
#endif
#ifndef WDIGEST_SP_NAME_W  /* Needed for MingW and VC6 */
#define WDIGEST_SP_NAME_W             L"WDigest"
#endif
#include <softpub.h>            /* WinVerifyTrust */

#ifndef X509_ALGORITHM_IDENTIFIER
# define X509_ALGORITHM_IDENTIFIER           ((LPCSTR) 74)
#endif

Changes to undroid/twapi/twapi/etw/etw.c.

2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
        Tcl_ResetResult(interp); /* For any holdover from callbacks */

    return TCL_OK;
}

TCL_RESULT Twapi_ParseEventMofData(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    int       i, eaten;
    Tcl_Obj **types;            /* Field types */
    int       ntypes;           /* Number of fields/types */
    BYTE     *bytesP;
    int       nbytes;
    ULONG     remain;
    Tcl_Obj  *resultObj = NULL;
    WCHAR     wc;
    GUID      guid;
    int       pointer_size;     /* Of target system, NOT us */
    union {
        SID sid;                /* For alignment */
        char buf[SECURITY_MAX_SID_SIZE];







|




<







2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434

2435
2436
2437
2438
2439
2440
2441
        Tcl_ResetResult(interp); /* For any holdover from callbacks */

    return TCL_OK;
}

TCL_RESULT Twapi_ParseEventMofData(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    int       i, eaten, remain;
    Tcl_Obj **types;            /* Field types */
    int       ntypes;           /* Number of fields/types */
    BYTE     *bytesP;
    int       nbytes;

    Tcl_Obj  *resultObj = NULL;
    WCHAR     wc;
    GUID      guid;
    int       pointer_size;     /* Of target system, NOT us */
    union {
        SID sid;                /* For alignment */
        char buf[SECURITY_MAX_SID_SIZE];

Changes to undroid/twapi/twapi/eventlog/eventlog.c.

242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
    TwapiDefineFncodeCmds(interp, ARRAYSIZE(EvlogCallDispatch), EvlogCallDispatch, Twapi_EventlogCallObjCmd);

    Tcl_CreateObjCommand(interp, "twapi::ReadEventLog", Twapi_ReadEventLogObjCmd, ticP, NULL);

    return Twapi_EvtInitCalls(interp, ticP);
}

static int TwapiEventlogOneTimeInit(Tcl_Interp *interp)
{

    TwapiInitEvtStubs(interp);
    return TCL_OK;
}

#ifndef TWAPI_SINGLE_MODULE
BOOL WINAPI DllMain(HINSTANCE hmod, DWORD reason, PVOID unused)
{







|

>







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    TwapiDefineFncodeCmds(interp, ARRAYSIZE(EvlogCallDispatch), EvlogCallDispatch, Twapi_EventlogCallObjCmd);

    Tcl_CreateObjCommand(interp, "twapi::ReadEventLog", Twapi_ReadEventLogObjCmd, ticP, NULL);

    return Twapi_EvtInitCalls(interp, ticP);
}

static int TwapiEventlogOneTimeInit(void *arg)
{
    Tcl_Interp *interp = arg;
    TwapiInitEvtStubs(interp);
    return TCL_OK;
}

#ifndef TWAPI_SINGLE_MODULE
BOOL WINAPI DllMain(HINSTANCE hmod, DWORD reason, PVOID unused)
{

Changes to undroid/twapi/twapi/eventlog/evt.c.

1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
            var.Type = EvtVarTypeBoolean;
            break;
        case EvtChannelConfigIsolation:
        case EvtChannelConfigType:
        case EvtChannelPublishingConfigLevel:
        case EvtChannelPublishingConfigClockType:
        case EvtChannelPublishingConfigFileMax:
            if (ObjToDWORD(interp, objv[3], &var.UInt32Val) != TCL_OK)
                return TCL_ERROR;
            var.Type = EvtVarTypeUInt32;
            break;
        case EvtChannelConfigOwningPublisher:
        case EvtChannelConfigAccess:
        case EvtChannelLoggingConfigLogFilePath:
        case EvtChannelPublisherList:







|







1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
            var.Type = EvtVarTypeBoolean;
            break;
        case EvtChannelConfigIsolation:
        case EvtChannelConfigType:
        case EvtChannelPublishingConfigLevel:
        case EvtChannelPublishingConfigClockType:
        case EvtChannelPublishingConfigFileMax:
            if (ObjToDWORD(interp, objv[3], (DWORD *)&var.UInt32Val) != TCL_OK)
                return TCL_ERROR;
            var.Type = EvtVarTypeUInt32;
            break;
        case EvtChannelConfigOwningPublisher:
        case EvtChannelConfigAccess:
        case EvtChannelLoggingConfigLogFilePath:
        case EvtChannelPublisherList:

Changes to undroid/twapi/twapi/include/common.inc.

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
CINCLUDES     = $(SRCROOT)\include\twapi.h \
		$(SRCROOT)\include\twapi_wm.h \
		$(SRCROOT)\include\twapi_ddkdefs.h \
		$(SRCROOT)\include\twapi_sdkdefs.h \
		$(SRCROOT)\include\zlist.h \
		$(SRCROOT)\include\memlifo.h

CFLAGS    = $(CDEBUG) /c /nologo /DWIN32 /D_WIN32 /D_WINDOWS -DTCL_THREADS=1 -D_WIN32_WINNT=$(TWAPI_WIN_HEADER_VERSION) -DPSAPI_VERSION=1 $(INCFLAGS) -DMODULENAME=\"$(MODULENAME)\" -D$(MODULENAME)_BUILD -DMODULEVERSION=\"$(MODULEVERSION)\" -DHGID=\"$(HGID)\"

!if "$(MACHINE)" == "AMD64" && $(VCVER) < 9
CFLAGS = $(CFLAGS) /Wp64
!endif

# What version of shell32.dll to use. XP or later -> IE 6
!if $(TWAPI_WIN_HEADER_VERSION) >= 0x0501







|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
CINCLUDES     = $(SRCROOT)\include\twapi.h \
		$(SRCROOT)\include\twapi_wm.h \
		$(SRCROOT)\include\twapi_ddkdefs.h \
		$(SRCROOT)\include\twapi_sdkdefs.h \
		$(SRCROOT)\include\zlist.h \
		$(SRCROOT)\include\memlifo.h

CFLAGS    = $(CDEBUG) /c /nologo /DWIN32 /D_WIN32 /D_WINDOWS /D_UNICODE /DUNICODE -DTCL_THREADS=1 -D_WIN32_WINNT=$(TWAPI_WIN_HEADER_VERSION) -DPSAPI_VERSION=1 $(INCFLAGS) -DMODULENAME=\"$(MODULENAME)\" -D$(MODULENAME)_BUILD -DMODULEVERSION=\"$(MODULEVERSION)\" -DHGID=\"$(HGID)\"

!if "$(MACHINE)" == "AMD64" && $(VCVER) < 9
CFLAGS = $(CFLAGS) /Wp64
!endif

# What version of shell32.dll to use. XP or later -> IE 6
!if $(TWAPI_WIN_HEADER_VERSION) >= 0x0501

Changes to undroid/twapi/twapi/include/twapi.h.

8
9
10
11
12
13
14



15
16
17
18
19
20
21
..
71
72
73
74
75
76
77





78
79
80

81
82

83
84

85
86

87
88
89
90
91
92
93
...
175
176
177
178
179
180
181





182
183
184
185
186
187
188
...
209
210
211
212
213
214
215





216
217
218
219
220
221
222
....
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
....
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440

1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
 * See the file LICENSE for license
 */

#if _WIN32_WINNT < 0x0501
#error _WIN32_WINNT too low
#endif
        




/* Enable prototype-less extern functions warnings even at warning level 1 */
#ifdef _MSC_VER
#pragma warning (1 : 13)
#endif

/*
................................................................................
#   ifdef __GNUC__
#       define TWAPI_EXTERN_VA extern __cdecl
#   else
#       define TWAPI_EXTERN_VA extern TWAPI_STORAGE_CLASS
#   endif
#endif






#ifndef TWAPI_INLINE
# ifdef _MSC_VER
#  define TWAPI_INLINE __inline  /* Because VC++ 6 only accepts "inline" in C++  */

# elif __GNUC__ && !__GNUC_STDC_INLINE__
#  define TWAPI_INLINE static inline

# else
#  define TWAPI_INLINE inline

# endif
#endif


/* Define macros that affect structure sizes before any includes */
#define CRYPT_DECRYPT_MESSAGE_PARA_HAS_EXTRA_FIELDS
#define CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS

#include <stddef.h>
#include <stdlib.h>
................................................................................
#define TWAPI_LOG_VAR TWAPI_TCL_NAMESPACE "::log_messages"
#define TWAPI_LOG_CONFIG_VAR TWAPI_TCL_NAMESPACE "::log_config"

#ifdef TWAPI_SINGLE_MODULE
/* Note:
 * when calling that pkg_ must be title-ized as documented in Tcl_StaticPackage
 */





#ifdef USE_TCL_STUBS
#define TWAPI_INIT_STATIC_PACKAGE(pkg_, init_, safe_init_)                   \
    do  {                                                                    \
        /* Note first param NULL else init proc is assumed already called */ \
        (tclStubsPtr->tcl_StaticPackage)(NULL, #pkg_, init_, safe_init_);    \
    } while (0)
#else
................................................................................
#    define TWAPI_ASSERT(bool_) do { if (! (bool_)) { __asm int 3 } } while (0)
#  else
#    error Invalid value for TWAPI_ENABLE_ASSERT
#  endif
#else
#define TWAPI_ASSERT(bool_) ((void) 0)
#endif






#if TWAPI_ENABLE_LOG
#define TWAPI_OBJ_LOG_IF(cond_, interp_, objp_) if (cond_) TWAPI_OBJ_LOG(interp_, objp_)
#define TWAPI_OBJ_LOG(interp_, objp_) Twapi_AppendObjLog(interp, objp_)
#define TWAPI_LOG(interp_, s_) Twapi_AppendLog(interp, L ## s_)
#define TWAPI_LOG_IF(cond_, interp_, s_) if (cond_) TWAPI_LOG(interp_, s_)
#define TWAPI_LOG_BLOCK(cond_) if (cond_)
................................................................................



/*****************************************************************
 * Prototypes and globals
 *****************************************************************/

typedef int TwapiTclObjCmd(
    ClientData dummy,           /* Not used. */
    Tcl_Interp *interp,         /* Current interpreter. */
    int objc,                   /* Number of arguments. */
    Tcl_Obj *CONST objv[]);     /* Argument objects. */

#ifdef __cplusplus
extern "C" {
................................................................................
TWAPI_EXTERN TCL_RESULT ObjToInt(Tcl_Interp *interp, Tcl_Obj *objP, int *);

TWAPI_EXTERN Tcl_Obj *ObjFromWideInt(Tcl_WideInt val);
/* Unsigneds need to be promoted to wide ints when converting to Tcl_Obj*/
TWAPI_INLINE Tcl_Obj *ObjFromDWORD(DWORD dw) {
    return ObjFromWideInt(dw);
}
TWAPI_INLINE TCL_RESULT ObjToDWORD(Tcl_Interp *interp, Tcl_Obj *objP, DWORD *dwP) {
    long l;
    /* TBD - should we convert to Tcl_WideInt and check the range?
       How much code depends on silent long<->unsigned long conversions? */
    TCL_RESULT res = ObjToLong(interp, objP, &l);
    if (res == TCL_OK)
        *dwP = (DWORD) l;
    return res;
}
#define ObjFromULONG      ObjFromDWORD

TWAPI_EXTERN TCL_RESULT ObjToWideInt(Tcl_Interp *interp, Tcl_Obj *objP, Tcl_WideInt *wideP);
TWAPI_EXTERN Tcl_Obj *ObjFromDouble(double val);
TWAPI_EXTERN TCL_RESULT ObjToDouble(Tcl_Interp *interp, Tcl_Obj *objP, double *);


#ifdef _WIN64
/* Define as a function to avoid gcc squawking about signed pointers */
TWAPI_INLINE TCL_RESULT ObjToDWORD_PTR(Tcl_Interp *interp, Tcl_Obj *objP, DWORD_PTR *dwP) {
    Tcl_WideInt wide;
    TCL_RESULT res = ObjToWideInt(interp, objP, &wide);
    if (res == TCL_OK)
        *dwP = (DWORD_PTR) wide;
    return res;
}
#define ObjFromDWORD_PTR(p_)  ObjFromULONGLONG((ULONGLONG)(p_))
#define ObjToLONG_PTR         ObjToWideInt
#define ObjFromLONG_PTR       ObjFromWideInt
#else  // ! _WIN64
/* Define as a function to avoid gcc squawking about signed pointers */
TWAPI_INLINE TCL_RESULT ObjToDWORD_PTR(Tcl_Interp *interp, Tcl_Obj *objP, DWORD_PTR *dwP) {
    DWORD dw;
    TCL_RESULT res = ObjToDWORD(interp, objP, &dw);
    if (res == TCL_OK)
        *dwP = (DWORD_PTR) dw;
    return res;
}
#define ObjFromDWORD_PTR(p_)  ObjFromDWORD((DWORD_PTR)(p_))
#define ObjToLONG_PTR         ObjToLong
#define ObjFromLONG_PTR       ObjFromLong
#endif // _WIN64
#define ObjToULONG_PTR    ObjToDWORD_PTR
#define ObjFromULONG_PTR  ObjFromDWORD_PTR
#define ObjFromSIZE_T     ObjFromDWORD_PTR







>
>
>







 







>
>
>
>
>



>

|
>


>


>







 







>
>
>
>
>







 







>
>
>
>
>







 







|







 







|
|
|
|
<
<
<
<

<




<
>

<
<
<
<
<
<
<
<




<
<
<
<
<
<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
....
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
....
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451




1452

1453
1454
1455
1456

1457
1458








1459
1460
1461
1462








1463
1464
1465
1466
1467
1468
1469
 * See the file LICENSE for license
 */

#if _WIN32_WINNT < 0x0501
#error _WIN32_WINNT too low
#endif
        
#ifndef _UNICODE
#error -D_UNICODE is not defined on compile command.
#endif

/* Enable prototype-less extern functions warnings even at warning level 1 */
#ifdef _MSC_VER
#pragma warning (1 : 13)
#endif

/*
................................................................................
#   ifdef __GNUC__
#       define TWAPI_EXTERN_VA extern __cdecl
#   else
#       define TWAPI_EXTERN_VA extern TWAPI_STORAGE_CLASS
#   endif
#endif

/*
 * TWAPI_INLINE should be used for defining inline functions that are
 * used across multiple files. TWAPI_STATIC_INLINE should be used for
 * functions that are intended to be used within a single file.
 */
#ifndef TWAPI_INLINE
# ifdef _MSC_VER
#  define TWAPI_INLINE __inline  /* Because VC++ 6 only accepts "inline" in C++  */
#  define TWAPI_STATIC_INLINE static __inline
# elif __GNUC__ && !__GNUC_STDC_INLINE__
#  define TWAPI_INLINE extern inline
#  define TWAPI_STATIC_INLINE static inline
# else
#  define TWAPI_INLINE inline
#  define TWAPI_STATIC_INLINE static inline
# endif
#endif


/* Define macros that affect structure sizes before any includes */
#define CRYPT_DECRYPT_MESSAGE_PARA_HAS_EXTRA_FIELDS
#define CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS

#include <stddef.h>
#include <stdlib.h>
................................................................................
#define TWAPI_LOG_VAR TWAPI_TCL_NAMESPACE "::log_messages"
#define TWAPI_LOG_CONFIG_VAR TWAPI_TCL_NAMESPACE "::log_config"

#ifdef TWAPI_SINGLE_MODULE
/* Note:
 * when calling that pkg_ must be title-ized as documented in Tcl_StaticPackage
 */
/* TBD - in 8.6 Tcl_StaticPackage is no longer defined so we call it
   through the stubs structure. Is this the right thing to do ?
   TBD - if twapi gets loaded into multiple interps, is it ok to pass
   NULL to the function the second time it is called?
*/
#ifdef USE_TCL_STUBS
#define TWAPI_INIT_STATIC_PACKAGE(pkg_, init_, safe_init_)                   \
    do  {                                                                    \
        /* Note first param NULL else init proc is assumed already called */ \
        (tclStubsPtr->tcl_StaticPackage)(NULL, #pkg_, init_, safe_init_);    \
    } while (0)
#else
................................................................................
#    define TWAPI_ASSERT(bool_) do { if (! (bool_)) { __asm int 3 } } while (0)
#  else
#    error Invalid value for TWAPI_ENABLE_ASSERT
#  endif
#else
#define TWAPI_ASSERT(bool_) ((void) 0)
#endif

TWAPI_EXTERN void TwapiUnreachablePanic(void);
#define UNREACHABLE do { \
        TwapiUnreachablePanic(); \
    } while (0)

#if TWAPI_ENABLE_LOG
#define TWAPI_OBJ_LOG_IF(cond_, interp_, objp_) if (cond_) TWAPI_OBJ_LOG(interp_, objp_)
#define TWAPI_OBJ_LOG(interp_, objp_) Twapi_AppendObjLog(interp, objp_)
#define TWAPI_LOG(interp_, s_) Twapi_AppendLog(interp, L ## s_)
#define TWAPI_LOG_IF(cond_, interp_, s_) if (cond_) TWAPI_LOG(interp_, s_)
#define TWAPI_LOG_BLOCK(cond_) if (cond_)
................................................................................



/*****************************************************************
 * Prototypes and globals
 *****************************************************************/

typedef TCL_RESULT TwapiTclObjCmd(
    ClientData dummy,           /* Not used. */
    Tcl_Interp *interp,         /* Current interpreter. */
    int objc,                   /* Number of arguments. */
    Tcl_Obj *CONST objv[]);     /* Argument objects. */

#ifdef __cplusplus
extern "C" {
................................................................................
TWAPI_EXTERN TCL_RESULT ObjToInt(Tcl_Interp *interp, Tcl_Obj *objP, int *);

TWAPI_EXTERN Tcl_Obj *ObjFromWideInt(Tcl_WideInt val);
/* Unsigneds need to be promoted to wide ints when converting to Tcl_Obj*/
TWAPI_INLINE Tcl_Obj *ObjFromDWORD(DWORD dw) {
    return ObjFromWideInt(dw);
}
TWAPI_EXTERN TCL_RESULT ObjToDWORD(Tcl_Interp *interp, Tcl_Obj *objP, DWORD *dwP);
#define ObjFromULONG      ObjFromDWORD
TWAPI_INLINE TCL_RESULT ObjToUINT(Tcl_Interp *ip, Tcl_Obj *objP, UINT *uiP) {
    return ObjToDWORD(ip, objP, (DWORD *)uiP);




}


TWAPI_EXTERN TCL_RESULT ObjToWideInt(Tcl_Interp *interp, Tcl_Obj *objP, Tcl_WideInt *wideP);
TWAPI_EXTERN Tcl_Obj *ObjFromDouble(double val);
TWAPI_EXTERN TCL_RESULT ObjToDouble(Tcl_Interp *interp, Tcl_Obj *objP, double *);

TWAPI_EXTERN TCL_RESULT ObjToDWORD_PTR(Tcl_Interp *interp, Tcl_Obj *objP, DWORD_PTR *dwP);
#ifdef _WIN64








#define ObjFromDWORD_PTR(p_)  ObjFromULONGLONG((ULONGLONG)(p_))
#define ObjToLONG_PTR         ObjToWideInt
#define ObjFromLONG_PTR       ObjFromWideInt
#else  // ! _WIN64








#define ObjFromDWORD_PTR(p_)  ObjFromDWORD((DWORD_PTR)(p_))
#define ObjToLONG_PTR         ObjToLong
#define ObjFromLONG_PTR       ObjFromLong
#endif // _WIN64
#define ObjToULONG_PTR    ObjToDWORD_PTR
#define ObjFromULONG_PTR  ObjFromDWORD_PTR
#define ObjFromSIZE_T     ObjFromDWORD_PTR

Changes to undroid/twapi/twapi/include/version.inc.

1
2
3
4
5
6
7
TWAPI_MAJOR=4
TWAPI_MINOR=2
TWAPI_BUILD=5
# RELEASETYPE: a is alpha, b is beta, . is release
TWAPI_RELEASETYPE = a

TWAPI_VERSION = $(TWAPI_MAJOR).$(TWAPI_MINOR)$(TWAPI_RELEASETYPE)$(TWAPI_BUILD)


|




1
2
3
4
5
6
7
TWAPI_MAJOR=4
TWAPI_MINOR=2
TWAPI_BUILD=6
# RELEASETYPE: a is alpha, b is beta, . is release
TWAPI_RELEASETYPE = a

TWAPI_VERSION = $(TWAPI_MAJOR).$(TWAPI_MINOR)$(TWAPI_RELEASETYPE)$(TWAPI_BUILD)

Changes to undroid/twapi/twapi/mstask/mstask.c.

635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
...
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
                ifc.scheduledworkitem, &result.value.systime);
            break;
        case 5214: // GetStatus
            if (objc != 1)
                goto badargs;
            result.type = TRT_LONG;
            hr = ifc.scheduledworkitem->lpVtbl->GetStatus(
                ifc.scheduledworkitem, &result.value.uval);
            break;
        case 5215: // GetTrigger
            if (objc != 2)
                goto badargs;
            if (ObjToWord(interp, objv[1], &w) != TCL_OK)
                return TCL_ERROR;
            result.type = TRT_INTERFACE;
................................................................................
        case 5226: // Terminate
            result.type = TRT_EMPTY;
            hr = ifc.scheduledworkitem->lpVtbl->Terminate(ifc.scheduledworkitem);
            break;
        case 5227: // SetWorkItemData
            if (objc != 2)
                goto badargs;
            pv = ObjToByteArray(objv[1], &dw1);
            if (dw1 > MAXWORD) {
                ObjSetStaticResult(interp, "Binary data exceeds MAXWORD");
                return TCL_ERROR;
            }
            result.type = TRT_EMPTY;
            hr = ifc.scheduledworkitem->lpVtbl->SetWorkItemData(
                ifc.scheduledworkitem, (WORD) dw1, pv);
................................................................................
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetWorkingDirectory(
                ifc.task, ObjToWinChars(objv[1]));
            break;
        case 5310: // SetMaxRunTime
            if (objc != 2)
                goto badargs;
            CHECK_INTEGER_OBJ(interp, dw1, objv[1]);
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetMaxRunTime(ifc.task, dw1);
            break;
        case 5311: // SetPriority
            if (objc != 2)
                goto badargs;
            CHECK_INTEGER_OBJ(interp, dw1, objv[1]);
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetPriority(ifc.task, dw1);
            break;
        case 5312: // SetTaskFlags
            if (objc != 2)
                goto badargs;
            CHECK_INTEGER_OBJ(interp, dw1, objv[1]);
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetTaskFlags(ifc.task, dw1);
            break;
        }
    } else if (func < 5500) {
        /* ITaskTrigger */
        if (ObjToOpaque(interp, objv[0], (void **)&ifc.tasktrigger,







|







 







|







 







|






|






|







635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
...
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
                ifc.scheduledworkitem, &result.value.systime);
            break;
        case 5214: // GetStatus
            if (objc != 1)
                goto badargs;
            result.type = TRT_LONG;
            hr = ifc.scheduledworkitem->lpVtbl->GetStatus(
                ifc.scheduledworkitem, &result.value.lval);
            break;
        case 5215: // GetTrigger
            if (objc != 2)
                goto badargs;
            if (ObjToWord(interp, objv[1], &w) != TCL_OK)
                return TCL_ERROR;
            result.type = TRT_INTERFACE;
................................................................................
        case 5226: // Terminate
            result.type = TRT_EMPTY;
            hr = ifc.scheduledworkitem->lpVtbl->Terminate(ifc.scheduledworkitem);
            break;
        case 5227: // SetWorkItemData
            if (objc != 2)
                goto badargs;
            pv = ObjToByteArrayDW(objv[1], &dw1);
            if (dw1 > MAXWORD) {
                ObjSetStaticResult(interp, "Binary data exceeds MAXWORD");
                return TCL_ERROR;
            }
            result.type = TRT_EMPTY;
            hr = ifc.scheduledworkitem->lpVtbl->SetWorkItemData(
                ifc.scheduledworkitem, (WORD) dw1, pv);
................................................................................
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetWorkingDirectory(
                ifc.task, ObjToWinChars(objv[1]));
            break;
        case 5310: // SetMaxRunTime
            if (objc != 2)
                goto badargs;
            CHECK_DWORD_OBJ(interp, dw1, objv[1]);
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetMaxRunTime(ifc.task, dw1);
            break;
        case 5311: // SetPriority
            if (objc != 2)
                goto badargs;
            CHECK_DWORD_OBJ(interp, dw1, objv[1]);
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetPriority(ifc.task, dw1);
            break;
        case 5312: // SetTaskFlags
            if (objc != 2)
                goto badargs;
            CHECK_DWORD_OBJ(interp, dw1, objv[1]);
            result.type = TRT_EMPTY;
            hr = ifc.task->lpVtbl->SetTaskFlags(ifc.task, dw1);
            break;
        }
    } else if (func < 5500) {
        /* ITaskTrigger */
        if (ObjToOpaque(interp, objv[0], (void **)&ifc.tasktrigger,

Changes to undroid/twapi/twapi/namedpipe/namedpipe.c.

62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
...
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
....
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
....
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
....
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
....
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
....
1341
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
....
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
....
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
....
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
#define NPIPE_F_WATCHREAD       1 /* Generate event when data available */
#define NPIPE_F_WATCHWRITE      2 /* Generate event when output possible */
#define NPIPE_F_NONBLOCKING     4 /* Channel is async */
#define NPIPE_F_CONNECTED       8 /* Client has successfully connected */
#define NPIPE_F_EVENT_QUEUED   16 /* A TCL event has been queued */ 
#define NPIPE_F_EOF_NOTIFIED   32 /* Have already notified EOF */

    ULONG volatile nrefs;              /* Ref count */
    WIN32_ERROR winerr;


#define SET_NPIPE_ERROR(ctxP_, err_) \
    ((ctxP_)->winerr == ERROR_SUCCESS ? ((ctxP_)->winerr = (err_)) : (ctxP_)->winerr)
};

#define NPIPE_CONNECTED(pcP_) ((pcP_)->flags & NPIPE_F_CONNECTED)

/*
 * EOF errors - note 0xc000014b is defined as STATUS_PIPE_BROKEN in
 * ntstatus.h. However that duplicates some defs from winnt.h and
 * hence cannot be included without generating compiler warnings.
 */
................................................................................
 */
static int NPipeSetTclErrnoFromWin32Error(WIN32_ERROR winerr)
{
    TWAPI_TCL85_INT_PLAT_STUB(tclWinConvertError) (winerr);
    return Tcl_GetErrno();
}

static int NPipeModuleInit(Tcl_Interp *interp)
{

    gNPipeTlsSlot = Twapi_AssignTlsSubSlot();
    if (gNPipeTlsSlot < 0) {
        ObjSetStaticResult(interp, "Could not assign private TLS slot");
        return TCL_ERROR;
    }

    return TCL_OK;
................................................................................
void NPipeThreadFinalize(void)
{
    if (gNPipeTlsSlot > 0) {
        TwapiTls *tlsP;
        /* Do not use GET_NPIPE_TLS directly here since TLS may be gone */
        tlsP = Twapi_GetTls();
        if (tlsP) {
            NPipeTls *pipetlsP = GET_NPIPE_TLS();
            //TBD - release all channels, events etc.
            // TBD - Tcl_DeleteEventSource(NPipeSetupProc, NPipeCheckProc, NULL);
        }
    }
        
    return;
}

................................................................................
    ClientData clientdata,
    char *bufP,
    int buf_sz,
    int *errnoP)
{
    NPipeChannel *pcP = (NPipeChannel *)clientdata;
    struct _NPipeIO *ioP;
    int nread;

    TWAPI_ASSERT(pcP->thread == Tcl_GetCurrentThread());

    if (! NPIPE_CONNECTED(pcP)) {
        /* Note we do not set pcP->winerr here */
        *errnoP = NPipeSetTclErrnoFromWin32Error(ERROR_PIPE_NOT_CONNECTED);
        return -1;
................................................................................
            WIN32_ERROR winerr = GetLastError();
            if (winerr != ERROR_IO_PENDING) {
                /* Genuine error */
                pcP->winerr = winerr;
                goto error_return;
            }
            /* Wait for I/O to complete */
            if (!GetOverlappedResult(pcP->hpipe, &ovl, &count, TRUE)) {
                pcP->winerr = GetLastError();
                goto error_return;
            }
        }
        /*
         * Sync I/O completed. Change state only if previous state was
         * IDLE. If previous state was PENDING from a previous non-blocking
................................................................................
 */
static void NPipeConfigureChannelDefaults(Tcl_Interp *interp, NPipeChannel *pcP)
{
    Tcl_SetChannelOption(interp, pcP->channel, "-translation", "auto crlf");
    Tcl_SetChannelOption(NULL, pcP->channel, "-eofchar", "");
}

int Twapi_NPipeServerObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    DWORD open_mode, pipe_mode, max_instances;
    DWORD inbuf_sz, outbuf_sz, timeout;
    SECURITY_ATTRIBUTES *secattrP = NULL;
    NPipeChannel *pcP;
    DWORD winerr = ERROR_SUCCESS;
    NPipeTls *tlsP;
    Tcl_Obj *nameObj, *secattrObj;
    SWSMark mark = NULL;
    TCL_RESULT res;
    
    res = TwapiGetArgs(interp, objc-1, objv+1,
                       GETOBJ(nameObj), GETINT(open_mode), GETINT(pipe_mode),
                       GETINT(max_instances), GETINT(outbuf_sz),
................................................................................

    /*
     * Note: Use GetNPipeTls, not GET_NPIPE_TLS here as tls
     * might not have been initialized. Also do this as the first thing
     * as various callbacks when registering channels will call functions
     * which expect the tls to have been initialized.
     */
    tlsP = GetNPipeTls();

    if (pipe_mode & 0x7) {
        /* Currently, must be byte mode pipe and must not have NOWAIT flag */
        ObjSetStaticResult(interp,  "Pipe mode must be byte mode and not specify the NPIPE_NOWAIT flag.");
        return Twapi_AppendSystemError(interp, TWAPI_INVALID_ARGS);
    }

................................................................................
             */
            pcP->io[READER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (pcP->io[READER].hevent) {
                pcP->io[WRITER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
                if (pcP->io[WRITER].hevent) {
                    int channel_mask = 0;
                    char instance_name[30];
                    wsprintf(instance_name, "np%u", TWAPI_NEWID(ticP));
                    if (open_mode & PIPE_ACCESS_INBOUND)
                        channel_mask |= TCL_READABLE;
                    if (open_mode & PIPE_ACCESS_OUTBOUND)
                        channel_mask |= TCL_WRITABLE;
                    NPipeChannelRef(pcP, 1); /* Adding to Tcl channels */
                    pcP->channel = Tcl_CreateChannel(&gNPipeChannelDispatch,
                                                     instance_name, pcP,
................................................................................

    pcP->winerr = winerr;
    NPipeShutdown(ticP->interp, pcP, 0);    /* pcP might be gone */
    return Twapi_AppendSystemError(ticP->interp, winerr);
}


int Twapi_NPipeClientObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    DWORD desired_access, share_mode, creation_disposition;
    DWORD flags_attr;
    SECURITY_ATTRIBUTES *secattrP = NULL;
    NPipeChannel *pcP;
    DWORD winerr;
    NPipeTls *tlsP;
    HANDLE hpipe;
    Tcl_Obj *nameObj, *secattrObj;
    SWSMark mark = NULL;

    if (TwapiGetArgs(interp, objc-1, objv+1,
                     GETOBJ(nameObj),
                     GETINT(desired_access),
................................................................................

    /*
     * Note: Use GetNPipeTls, not GET_NPIPE_TLS here as tls
     * might not have been initialized. Also do this as the first thing
     * as various callbacks when registering channels will call functions
     * which expect the tls to have been initialized.
     */
    tlsP = GetNPipeTls();
    flags_attr |= FILE_FLAG_OVERLAPPED;
    
    mark = SWSPushMark();
    if (ObjToPSECURITY_ATTRIBUTESSWS(interp, secattrObj, &secattrP) != TCL_OK) {
        SWSPopMark(mark);
        return TCL_ERROR;
    }
................................................................................
         */
        pcP->io[READER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (pcP->io[READER].hevent) {
            pcP->io[WRITER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (pcP->io[WRITER].hevent) {
                int channel_mask = 0;
                char instance_name[30];
                wsprintf(instance_name, "np%u", TWAPI_NEWID(ticP));
                if (desired_access & (GENERIC_READ |FILE_READ_DATA))
                    channel_mask |= TCL_READABLE;
                if (desired_access & (GENERIC_WRITE|FILE_WRITE_DATA))
                    channel_mask |= TCL_WRITABLE;
                NPipeChannelRef(pcP, 1); /* Adding to Tcl channels */
                pcP->channel = Tcl_CreateChannel(&gNPipeChannelDispatch,
                                                 instance_name, pcP,
................................................................................
    winerr = GetLastError();
    pcP->winerr = winerr;
    NPipeShutdown(ticP->interp, pcP, 0);    /* pcP might be gone */
    return Twapi_AppendSystemError(ticP->interp, winerr);
}


int Twapi_NPipeImpersonateObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    HANDLE h;

    if (objc != 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

    if (ObjToHANDLE(interp, objv[1], &h) != TCL_OK)







|

>



<
<







 







|

>







 







|
|







 







|







 







|







 







|

>





<







 







|







 







|







 







|

>





<







 







|







 







|







 







|







62
63
64
65
66
67
68
69
70
71
72
73
74


75
76
77
78
79
80
81
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
....
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
....
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
....
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
....
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
....
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
....
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
....
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
....
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
#define NPIPE_F_WATCHREAD       1 /* Generate event when data available */
#define NPIPE_F_WATCHWRITE      2 /* Generate event when output possible */
#define NPIPE_F_NONBLOCKING     4 /* Channel is async */
#define NPIPE_F_CONNECTED       8 /* Client has successfully connected */
#define NPIPE_F_EVENT_QUEUED   16 /* A TCL event has been queued */ 
#define NPIPE_F_EOF_NOTIFIED   32 /* Have already notified EOF */

    long volatile nrefs;              /* Ref count */
    WIN32_ERROR winerr;
} NPipeChannel;

#define SET_NPIPE_ERROR(ctxP_, err_) \
    ((ctxP_)->winerr == ERROR_SUCCESS ? ((ctxP_)->winerr = (err_)) : (ctxP_)->winerr)


#define NPIPE_CONNECTED(pcP_) ((pcP_)->flags & NPIPE_F_CONNECTED)

/*
 * EOF errors - note 0xc000014b is defined as STATUS_PIPE_BROKEN in
 * ntstatus.h. However that duplicates some defs from winnt.h and
 * hence cannot be included without generating compiler warnings.
 */
................................................................................
 */
static int NPipeSetTclErrnoFromWin32Error(WIN32_ERROR winerr)
{
    TWAPI_TCL85_INT_PLAT_STUB(tclWinConvertError) (winerr);
    return Tcl_GetErrno();
}

static int NPipeModuleInit(void *arg)
{
    Tcl_Interp *interp = arg;
    gNPipeTlsSlot = Twapi_AssignTlsSubSlot();
    if (gNPipeTlsSlot < 0) {
        ObjSetStaticResult(interp, "Could not assign private TLS slot");
        return TCL_ERROR;
    }

    return TCL_OK;
................................................................................
void NPipeThreadFinalize(void)
{
    if (gNPipeTlsSlot > 0) {
        TwapiTls *tlsP;
        /* Do not use GET_NPIPE_TLS directly here since TLS may be gone */
        tlsP = Twapi_GetTls();
        if (tlsP) {
            // NPipeTls *pipetlsP = GET_NPIPE_TLS();
            // TBD - release all channels, events etc.
            // TBD - Tcl_DeleteEventSource(NPipeSetupProc, NPipeCheckProc, NULL);
        }
    }
        
    return;
}

................................................................................
    ClientData clientdata,
    char *bufP,
    int buf_sz,
    int *errnoP)
{
    NPipeChannel *pcP = (NPipeChannel *)clientdata;
    struct _NPipeIO *ioP;
    DWORD nread;

    TWAPI_ASSERT(pcP->thread == Tcl_GetCurrentThread());

    if (! NPIPE_CONNECTED(pcP)) {
        /* Note we do not set pcP->winerr here */
        *errnoP = NPipeSetTclErrnoFromWin32Error(ERROR_PIPE_NOT_CONNECTED);
        return -1;
................................................................................
            WIN32_ERROR winerr = GetLastError();
            if (winerr != ERROR_IO_PENDING) {
                /* Genuine error */
                pcP->winerr = winerr;
                goto error_return;
            }
            /* Wait for I/O to complete */
            if (!GetOverlappedResult(pcP->hpipe, &ovl, (DWORD *)&count, TRUE)) {
                pcP->winerr = GetLastError();
                goto error_return;
            }
        }
        /*
         * Sync I/O completed. Change state only if previous state was
         * IDLE. If previous state was PENDING from a previous non-blocking
................................................................................
 */
static void NPipeConfigureChannelDefaults(Tcl_Interp *interp, NPipeChannel *pcP)
{
    Tcl_SetChannelOption(interp, pcP->channel, "-translation", "auto crlf");
    Tcl_SetChannelOption(NULL, pcP->channel, "-eofchar", "");
}

static int Twapi_NPipeServerObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    DWORD open_mode, pipe_mode, max_instances;
    DWORD inbuf_sz, outbuf_sz, timeout;
    SECURITY_ATTRIBUTES *secattrP = NULL;
    NPipeChannel *pcP;
    DWORD winerr = ERROR_SUCCESS;

    Tcl_Obj *nameObj, *secattrObj;
    SWSMark mark = NULL;
    TCL_RESULT res;
    
    res = TwapiGetArgs(interp, objc-1, objv+1,
                       GETOBJ(nameObj), GETINT(open_mode), GETINT(pipe_mode),
                       GETINT(max_instances), GETINT(outbuf_sz),
................................................................................

    /*
     * Note: Use GetNPipeTls, not GET_NPIPE_TLS here as tls
     * might not have been initialized. Also do this as the first thing
     * as various callbacks when registering channels will call functions
     * which expect the tls to have been initialized.
     */
    (void) GetNPipeTls(); /* Just to init it */

    if (pipe_mode & 0x7) {
        /* Currently, must be byte mode pipe and must not have NOWAIT flag */
        ObjSetStaticResult(interp,  "Pipe mode must be byte mode and not specify the NPIPE_NOWAIT flag.");
        return Twapi_AppendSystemError(interp, TWAPI_INVALID_ARGS);
    }

................................................................................
             */
            pcP->io[READER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (pcP->io[READER].hevent) {
                pcP->io[WRITER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
                if (pcP->io[WRITER].hevent) {
                    int channel_mask = 0;
                    char instance_name[30];
                    wsprintfA(instance_name, "np%u", TWAPI_NEWID(ticP));
                    if (open_mode & PIPE_ACCESS_INBOUND)
                        channel_mask |= TCL_READABLE;
                    if (open_mode & PIPE_ACCESS_OUTBOUND)
                        channel_mask |= TCL_WRITABLE;
                    NPipeChannelRef(pcP, 1); /* Adding to Tcl channels */
                    pcP->channel = Tcl_CreateChannel(&gNPipeChannelDispatch,
                                                     instance_name, pcP,
................................................................................

    pcP->winerr = winerr;
    NPipeShutdown(ticP->interp, pcP, 0);    /* pcP might be gone */
    return Twapi_AppendSystemError(ticP->interp, winerr);
}


int Twapi_NPipeClientObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    DWORD desired_access, share_mode, creation_disposition;
    DWORD flags_attr;
    SECURITY_ATTRIBUTES *secattrP = NULL;
    NPipeChannel *pcP;
    DWORD winerr;

    HANDLE hpipe;
    Tcl_Obj *nameObj, *secattrObj;
    SWSMark mark = NULL;

    if (TwapiGetArgs(interp, objc-1, objv+1,
                     GETOBJ(nameObj),
                     GETINT(desired_access),
................................................................................

    /*
     * Note: Use GetNPipeTls, not GET_NPIPE_TLS here as tls
     * might not have been initialized. Also do this as the first thing
     * as various callbacks when registering channels will call functions
     * which expect the tls to have been initialized.
     */
    (void) GetNPipeTls(); /* Just to initialize it */
    flags_attr |= FILE_FLAG_OVERLAPPED;
    
    mark = SWSPushMark();
    if (ObjToPSECURITY_ATTRIBUTESSWS(interp, secattrObj, &secattrP) != TCL_OK) {
        SWSPopMark(mark);
        return TCL_ERROR;
    }
................................................................................
         */
        pcP->io[READER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (pcP->io[READER].hevent) {
            pcP->io[WRITER].hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (pcP->io[WRITER].hevent) {
                int channel_mask = 0;
                char instance_name[30];
                wsprintfA(instance_name, "np%u", TWAPI_NEWID(ticP));
                if (desired_access & (GENERIC_READ |FILE_READ_DATA))
                    channel_mask |= TCL_READABLE;
                if (desired_access & (GENERIC_WRITE|FILE_WRITE_DATA))
                    channel_mask |= TCL_WRITABLE;
                NPipeChannelRef(pcP, 1); /* Adding to Tcl channels */
                pcP->channel = Tcl_CreateChannel(&gNPipeChannelDispatch,
                                                 instance_name, pcP,
................................................................................
    winerr = GetLastError();
    pcP->winerr = winerr;
    NPipeShutdown(ticP->interp, pcP, 0);    /* pcP might be gone */
    return Twapi_AppendSystemError(ticP->interp, winerr);
}


int Twapi_NPipeImpersonateObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    HANDLE h;

    if (objc != 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

    if (ObjToHANDLE(interp, objv[1], &h) != TCL_OK)

Changes to undroid/twapi/twapi/network/network.c.

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
....
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
....
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
....
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
....
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
....
1660
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673
1674
1675
....
1682
1683
1684
1685
1686
1687
1688
1689
1690

1691
1692
1693
1694
1695
1696
1697
....
1767
1768
1769
1770
1771
1772
1773
1774
1775

1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789

1790
1791
1792
1793
1794
1795
1796
....
1872
1873
1874
1875
1876
1877
1878
1879
1880

1881
1882
1883
1884
1885
1886
1887
....
1905
1906
1907
1908
1909
1910
1911
1912
1913

1914
1915
1916
1917
1918
1919
1920
....
1953
1954
1955
1956
1957
1958
1959
1960
1961

1962
1963

1964
1965
1966
1967
1968
1969
1970
....
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
....
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
....
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
....
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
int ObjToSOCKADDR_STORAGE(Tcl_Interp *interp, Tcl_Obj *objP, SOCKADDR_STORAGE *ssP)
{
    Tcl_Obj **objv;
    int       objc;
    Tcl_Obj **addrv;
    int       addrc;
    int       family;
    int       sz = sizeof(*ssP);
    WORD      port;

    if (ObjGetElements(interp, objP, &objc, &objv) != TCL_OK)
        return TCL_ERROR;

    if (objc > 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
................................................................................
        if (interp)
            Tcl_AppendResult(interp, "Invalid TCP connection format: ",
                             ObjToString(listObj),
                             NULL);
        return TCL_ERROR;
    }

    if ((ObjToInt(interp, objv[0], &row->dwState) != TCL_OK) ||
        (IPAddrObjToDWORD(interp, objv[1], &row->dwLocalAddr) != TCL_OK) ||
        (ObjToInt(interp, objv[2], &row->dwLocalPort) != TCL_OK) ||
        (IPAddrObjToDWORD(interp, objv[3], &row->dwRemoteAddr) != TCL_OK) ||
        (ObjToInt(interp, objv[4], &row->dwRemotePort) != TCL_OK)) {
        /* interp already has error */
        return TCL_ERROR;
    }

    /* COnvert ports to network format */
    row->dwLocalPort = htons((short)row->dwLocalPort);
    row->dwRemotePort = htons((short)row->dwRemotePort);
................................................................................
    }

    return resultObj;
}


/* Helper function - common to all table retrieval functions */
static int TwapiIpConfigTableHelper(TwapiInterpContext *ticP, DWORD (FAR WINAPI *fn)(), Tcl_Obj *(*objbuilder)(Tcl_Interp *, ...), BOOL sortable, BOOL sort)
{
    int error;
    void *bufP;
    ULONG bufsz;
    int  tries;

    if (fn == NULL) {
................................................................................

    MemLifoPopFrame(ticP->memlifoP);

    return error == ERROR_SUCCESS ? TCL_OK : TCL_ERROR;
}


/* TBD - obsoleted by GetAdaptersAddresses ? */
int Twapi_GetAdaptersInfo(TwapiInterpContext *ticP)
{
    return TwapiIpConfigTableHelper(
        ticP,
        GetAdaptersInfo,
        ObjFromIP_ADAPTER_INFO_table,
        0,
        0
        );
}


int Twapi_GetAdaptersAddresses(TwapiInterpContext *ticP, ULONG family,
                               ULONG flags, void *reserved)
{
    IP_ADAPTER_ADDRESSES *iaaP;
    ULONG bufsz;
    DWORD error;
................................................................................
        if (tab)
            TwapiFree(tab);
        return error == ERROR_SUCCESS ? TCL_OK : TCL_ERROR;
    }
}


static int Twapi_GetNameInfoObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    int status;
    SOCKADDR_STORAGE ss;
    char hostname[NI_MAXHOST];
    char portname[NI_MAXSERV];
    Tcl_Obj *objs[2];
    int flags;
................................................................................
            }
        }
        addrP = addrP->ai_next;
    }
    return resultObj;
}

static int Twapi_GetAddrInfoObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    const char *hostname;
    const char *svcname;
    int status;
    struct addrinfo hints;
    struct addrinfo *addrP;

................................................................................
    ObjSetResult(interp, TwapiCollectAddrInfo(addrP, hints.ai_family));
    if (addrP)
        freeaddrinfo(addrP);

    return TCL_OK;
}

static int Twapi_GetBestRouteObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    MIB_IPFORWARDROW route;
    int error;
    DWORD dest, src;

    if (TwapiGetArgs(ticP->interp, objc-1, objv+1,
                     GETVAR(dest, IPAddrObjToDWORD),
                     GETVAR(src, IPAddrObjToDWORD),
................................................................................
        ObjSetResult(ticP->interp, ObjFromMIB_IPFORWARDROW(ticP->interp, &route));
        return TCL_OK;
    } else {
        return Twapi_AppendSystemError(ticP->interp, error);
    }
}

static int Twapi_GetBestInterfaceObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    GetBestInterfaceEx_t fn;
    int result;
    DWORD ifindex;
    DWORD ipaddr;
    Tcl_Obj *objP;

    if (objc != 2)
................................................................................
        freeaddrinfo(theP->addrinfolist);

    return 1;                   /* So Tcl removes from queue */
}


/* Called from the Win2000 thread pool */
static DWORD WINAPI TwapiHostnameHandler(TwapiHostnameEvent *theP)
{

    struct addrinfo hints;

    TwapiZeroMemory(&hints, sizeof(hints));
    hints.ai_family = theP->family;
    hints.ai_flags = theP->ai_flags;
    theP->tcl_ev.proc = TwapiHostnameEventProc;
    theP->status = getaddrinfo(theP->name, "0", &hints, &theP->addrinfolist);
    TwapiEnqueueTclEvent(theP->ticP, &theP->tcl_ev);
    return 0;               /* Return value does not matter */
}


static int Twapi_ResolveHostnameAsyncObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    TwapiId id;
    char *name;
    int   len;
    TwapiHostnameEvent *theP;
    DWORD winerr;
    int family;
    int hint_flags;
................................................................................
        TwapiFree(theP->hostname);
    
    return 1;                   /* So Tcl removes from queue */
}


/* Called from the Win2000 thread pool */
static DWORD WINAPI TwapiAddressHandler(TwapiHostnameEvent *theP)
{

    SOCKADDR_STORAGE ss;
    char hostname[NI_MAXHOST];
    char portname[NI_MAXSERV];
    int family;

    theP->tcl_ev.proc = TwapiAddressEventProc;
    family = TwapiStringToSOCKADDR_STORAGE(theP->name, &ss, theP->family);
................................................................................
        }
    }

    TwapiEnqueueTclEvent(theP->ticP, &theP->tcl_ev);
    return 0;                   /* Return value ignored anyways */
}

static int Twapi_ResolveAddressAsyncObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    TwapiId id;
    char *addrstr;
    int   len;
    TwapiHostnameEvent *theP;
    DWORD winerr;
    int family;

................................................................................

    TwapiInterpContextUnref(ticP, 1); /* Undo above ref */
    Tcl_Free((char*) theP);
    return Twapi_AppendSystemError(ticP->interp, winerr);
}


static int Twapi_NetworkCallObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    TwapiResult result;
    int func;

    union {
        MIB_TCPROW tcprow;
        SOCKADDR_STORAGE ss;
    } u;
    DWORD dw, dw2, dw3, dw4;
    LPWSTR s;
    LPVOID pv;
................................................................................
        /* Functions taking no arguments */
        if (objc != 2)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

        switch (func) {
        case 1:
            return Twapi_GetNetworkParams(ticP);
        case 2:
            return Twapi_GetAdaptersInfo(ticP);
        }
    } else if (func < 300) {
        if (objc != 3)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        if (func == 101) {
            if (ObjToMIB_TCPROW(interp, objv[2], &u.tcprow) != TCL_OK)
                return TCL_ERROR;
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = SetTcpEntry(&u.tcprow);
        } else if (func < 250) {
            CHECK_INTEGER_OBJ(interp, dw, objv[2]);
            switch (func) {
            case 201:
                return Twapi_GetPerAdapterInfo(ticP, dw);
            case 202: // UNUSED
                // return Twapi_GetIfEntry(interp, dw);
                break;
            case 203: // UNUSED
................................................................................
                result.type = GetAdapterIndex((LPWSTR)s, &result.value.uval)
                    ? TRT_GETLASTERROR
                    : TRT_DWORD;
                break;
            case 252: // Twapi_IPAddressFamily - TBD - optimizable?
                result.value.ival = 0;
                result.type = TRT_DWORD;
                dw = sizeof(u.ss);
                dw2 = sizeof(u.ss); /* Since first call might change dw */
                if (WSAStringToAddressW(s, AF_INET, NULL, (struct sockaddr *)&u.ss, &dw) == 0 ||
                    WSAStringToAddressW(s, AF_INET6, NULL, (struct sockaddr *)&u.ss, &dw2) == 0) {
                    result.value.uval = u.ss.ss_family;
                }
                break;

            case 253: // Twapi_NormalizeIPAddress
                dw = sizeof(u.ss);
                dw2 = sizeof(u.ss); /* Since first call might change dw */
                if (WSAStringToAddressW(s, AF_INET, NULL, (struct sockaddr *)&u.ss, &dw) == 0 ||
                    WSAStringToAddressW(s, AF_INET6, NULL, (struct sockaddr *)&u.ss, &dw2) == 0) {
                    result.type = TRT_OBJ;
                    if (u.ss.ss_family == AF_INET6) {
                        /* Do not want scope id in normalized form */
                        ((SOCKADDR_IN6 *)&u.ss)->sin6_scope_id = 0;
                    }
                    result.value.obj = ObjFromSOCKADDR_address((struct sockaddr *)&u.ss);
                } else {
................................................................................
                }
                break;
            }
        }
    } else if (func < 400) {
        if (objc != 4)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_INTEGER_OBJ(interp, dw, objv[2]);
        CHECK_INTEGER_OBJ(interp, dw2, objv[3]);
        switch (func) {
        case 301:
            return Twapi_GetAdaptersAddresses(ticP, dw, dw2, NULL);
        case 302:
            return Twapi_AllocateAndGetTcpExTableFromStack(ticP, dw, dw2);
        case 303:
            return Twapi_AllocateAndGetUdpExTableFromStack(ticP, dw, dw2);
................................................................................
        DEFINE_TCL_CMD(getnameinfo,  Twapi_GetNameInfoObjCmd),
        DEFINE_TCL_CMD(GetBestRoute, Twapi_GetBestRouteObjCmd),
        DEFINE_TCL_CMD(GetBestInterfaceEx, Twapi_GetBestInterfaceObjCmd),
    };

    static struct alias_dispatch_s NetDispatch[] = {
        DEFINE_ALIAS_CMD(GetNetworkParams, 1),
        DEFINE_ALIAS_CMD(GetAdaptersInfo,  2),
        DEFINE_ALIAS_CMD(SetTcpEntry,  101),
        DEFINE_ALIAS_CMD(GetPerAdapterInfo,  201),
        DEFINE_ALIAS_CMD(GetIfEntry,  202),
        DEFINE_ALIAS_CMD(GetIfTable,  203),
        DEFINE_ALIAS_CMD(GetIpNetTable,  205),
        DEFINE_ALIAS_CMD(GetIpForwardTable,  206),
        DEFINE_ALIAS_CMD(FlushIpNetTable,  207),







<







 







|

|

|







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







|







 







|

>







 







|

>







 







|

>












|

>







 







|

>







 







|

>







 







|

>

<
>







 







<
<










|







 







|
|
|
|





|
|
|
|







 







|
|







 







<







243
244
245
246
247
248
249

250
251
252
253
254
255
256
...
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
....
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
....
1233
1234
1235
1236
1237
1238
1239












1240
1241
1242
1243
1244
1245
1246
....
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
....
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
....
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
....
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
....
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
....
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
....
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
....
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
1960
1961
1962
1963
1964
....
1973
1974
1975
1976
1977
1978
1979


1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
....
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
....
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
....
2104
2105
2106
2107
2108
2109
2110

2111
2112
2113
2114
2115
2116
2117
int ObjToSOCKADDR_STORAGE(Tcl_Interp *interp, Tcl_Obj *objP, SOCKADDR_STORAGE *ssP)
{
    Tcl_Obj **objv;
    int       objc;
    Tcl_Obj **addrv;
    int       addrc;
    int       family;

    WORD      port;

    if (ObjGetElements(interp, objP, &objc, &objv) != TCL_OK)
        return TCL_ERROR;

    if (objc > 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
................................................................................
        if (interp)
            Tcl_AppendResult(interp, "Invalid TCP connection format: ",
                             ObjToString(listObj),
                             NULL);
        return TCL_ERROR;
    }

    if ((ObjToDWORD(interp, objv[0], &row->dwState) != TCL_OK) ||
        (IPAddrObjToDWORD(interp, objv[1], &row->dwLocalAddr) != TCL_OK) ||
        (ObjToDWORD(interp, objv[2], &row->dwLocalPort) != TCL_OK) ||
        (IPAddrObjToDWORD(interp, objv[3], &row->dwRemoteAddr) != TCL_OK) ||
        (ObjToDWORD(interp, objv[4], &row->dwRemotePort) != TCL_OK)) {
        /* interp already has error */
        return TCL_ERROR;
    }

    /* COnvert ports to network format */
    row->dwLocalPort = htons((short)row->dwLocalPort);
    row->dwRemotePort = htons((short)row->dwRemotePort);
................................................................................
    }

    return resultObj;
}


/* Helper function - common to all table retrieval functions */
static int TwapiIpConfigTableHelper(TwapiInterpContext *ticP, DWORD (FAR WINAPI *fn)(), Tcl_Obj *(*objbuilder)(), BOOL sortable, BOOL sort)
{
    int error;
    void *bufP;
    ULONG bufsz;
    int  tries;

    if (fn == NULL) {
................................................................................

    MemLifoPopFrame(ticP->memlifoP);

    return error == ERROR_SUCCESS ? TCL_OK : TCL_ERROR;
}















int Twapi_GetAdaptersAddresses(TwapiInterpContext *ticP, ULONG family,
                               ULONG flags, void *reserved)
{
    IP_ADAPTER_ADDRESSES *iaaP;
    ULONG bufsz;
    DWORD error;
................................................................................
        if (tab)
            TwapiFree(tab);
        return error == ERROR_SUCCESS ? TCL_OK : TCL_ERROR;
    }
}


static int Twapi_GetNameInfoObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    int status;
    SOCKADDR_STORAGE ss;
    char hostname[NI_MAXHOST];
    char portname[NI_MAXSERV];
    Tcl_Obj *objs[2];
    int flags;
................................................................................
            }
        }
        addrP = addrP->ai_next;
    }
    return resultObj;
}

static int Twapi_GetAddrInfoObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    const char *hostname;
    const char *svcname;
    int status;
    struct addrinfo hints;
    struct addrinfo *addrP;

................................................................................
    ObjSetResult(interp, TwapiCollectAddrInfo(addrP, hints.ai_family));
    if (addrP)
        freeaddrinfo(addrP);

    return TCL_OK;
}

static int Twapi_GetBestRouteObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    MIB_IPFORWARDROW route;
    int error;
    DWORD dest, src;

    if (TwapiGetArgs(ticP->interp, objc-1, objv+1,
                     GETVAR(dest, IPAddrObjToDWORD),
                     GETVAR(src, IPAddrObjToDWORD),
................................................................................
        ObjSetResult(ticP->interp, ObjFromMIB_IPFORWARDROW(ticP->interp, &route));
        return TCL_OK;
    } else {
        return Twapi_AppendSystemError(ticP->interp, error);
    }
}

static int Twapi_GetBestInterfaceObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    GetBestInterfaceEx_t fn;
    int result;
    DWORD ifindex;
    DWORD ipaddr;
    Tcl_Obj *objP;

    if (objc != 2)
................................................................................
        freeaddrinfo(theP->addrinfolist);

    return 1;                   /* So Tcl removes from queue */
}


/* Called from the Win2000 thread pool */
static DWORD WINAPI TwapiHostnameHandler(void *arg)
{
    TwapiHostnameEvent *theP = arg;
    struct addrinfo hints;

    TwapiZeroMemory(&hints, sizeof(hints));
    hints.ai_family = theP->family;
    hints.ai_flags = theP->ai_flags;
    theP->tcl_ev.proc = TwapiHostnameEventProc;
    theP->status = getaddrinfo(theP->name, "0", &hints, &theP->addrinfolist);
    TwapiEnqueueTclEvent(theP->ticP, &theP->tcl_ev);
    return 0;               /* Return value does not matter */
}


static int Twapi_ResolveHostnameAsyncObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    TwapiId id;
    char *name;
    int   len;
    TwapiHostnameEvent *theP;
    DWORD winerr;
    int family;
    int hint_flags;
................................................................................
        TwapiFree(theP->hostname);
    
    return 1;                   /* So Tcl removes from queue */
}


/* Called from the Win2000 thread pool */
static DWORD WINAPI TwapiAddressHandler(void *arg)
{
    TwapiHostnameEvent *theP = arg;
    SOCKADDR_STORAGE ss;
    char hostname[NI_MAXHOST];
    char portname[NI_MAXSERV];
    int family;

    theP->tcl_ev.proc = TwapiAddressEventProc;
    family = TwapiStringToSOCKADDR_STORAGE(theP->name, &ss, theP->family);
................................................................................
        }
    }

    TwapiEnqueueTclEvent(theP->ticP, &theP->tcl_ev);
    return 0;                   /* Return value ignored anyways */
}

static int Twapi_ResolveAddressAsyncObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    TwapiId id;
    char *addrstr;
    int   len;
    TwapiHostnameEvent *theP;
    DWORD winerr;
    int family;

................................................................................

    TwapiInterpContextUnref(ticP, 1); /* Undo above ref */
    Tcl_Free((char*) theP);
    return Twapi_AppendSystemError(ticP->interp, winerr);
}


static int Twapi_NetworkCallObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    TwapiResult result;

    int i, j, func;
    union {
        MIB_TCPROW tcprow;
        SOCKADDR_STORAGE ss;
    } u;
    DWORD dw, dw2, dw3, dw4;
    LPWSTR s;
    LPVOID pv;
................................................................................
        /* Functions taking no arguments */
        if (objc != 2)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

        switch (func) {
        case 1:
            return Twapi_GetNetworkParams(ticP);


        }
    } else if (func < 300) {
        if (objc != 3)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        if (func == 101) {
            if (ObjToMIB_TCPROW(interp, objv[2], &u.tcprow) != TCL_OK)
                return TCL_ERROR;
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = SetTcpEntry(&u.tcprow);
        } else if (func < 250) {
            CHECK_DWORD_OBJ(interp, dw, objv[2]);
            switch (func) {
            case 201:
                return Twapi_GetPerAdapterInfo(ticP, dw);
            case 202: // UNUSED
                // return Twapi_GetIfEntry(interp, dw);
                break;
            case 203: // UNUSED
................................................................................
                result.type = GetAdapterIndex((LPWSTR)s, &result.value.uval)
                    ? TRT_GETLASTERROR
                    : TRT_DWORD;
                break;
            case 252: // Twapi_IPAddressFamily - TBD - optimizable?
                result.value.ival = 0;
                result.type = TRT_DWORD;
                i = sizeof(u.ss);
                j = sizeof(u.ss); /* Since first call might change i */
                if (WSAStringToAddressW(s, AF_INET, NULL, (struct sockaddr *)&u.ss, &i) == 0 ||
                    WSAStringToAddressW(s, AF_INET6, NULL, (struct sockaddr *)&u.ss, &j) == 0) {
                    result.value.uval = u.ss.ss_family;
                }
                break;

            case 253: // Twapi_NormalizeIPAddress
                i = sizeof(u.ss);
                j = sizeof(u.ss); /* Since first call might change i */
                if (WSAStringToAddressW(s, AF_INET, NULL, (struct sockaddr *)&u.ss, &i) == 0 ||
                    WSAStringToAddressW(s, AF_INET6, NULL, (struct sockaddr *)&u.ss, &j) == 0) {
                    result.type = TRT_OBJ;
                    if (u.ss.ss_family == AF_INET6) {
                        /* Do not want scope id in normalized form */
                        ((SOCKADDR_IN6 *)&u.ss)->sin6_scope_id = 0;
                    }
                    result.value.obj = ObjFromSOCKADDR_address((struct sockaddr *)&u.ss);
                } else {
................................................................................
                }
                break;
            }
        }
    } else if (func < 400) {
        if (objc != 4)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_DWORD_OBJ(interp, dw, objv[2]);
        CHECK_DWORD_OBJ(interp, dw2, objv[3]);
        switch (func) {
        case 301:
            return Twapi_GetAdaptersAddresses(ticP, dw, dw2, NULL);
        case 302:
            return Twapi_AllocateAndGetTcpExTableFromStack(ticP, dw, dw2);
        case 303:
            return Twapi_AllocateAndGetUdpExTableFromStack(ticP, dw, dw2);
................................................................................
        DEFINE_TCL_CMD(getnameinfo,  Twapi_GetNameInfoObjCmd),
        DEFINE_TCL_CMD(GetBestRoute, Twapi_GetBestRouteObjCmd),
        DEFINE_TCL_CMD(GetBestInterfaceEx, Twapi_GetBestInterfaceObjCmd),
    };

    static struct alias_dispatch_s NetDispatch[] = {
        DEFINE_ALIAS_CMD(GetNetworkParams, 1),

        DEFINE_ALIAS_CMD(SetTcpEntry,  101),
        DEFINE_ALIAS_CMD(GetPerAdapterInfo,  201),
        DEFINE_ALIAS_CMD(GetIfEntry,  202),
        DEFINE_ALIAS_CMD(GetIfTable,  203),
        DEFINE_ALIAS_CMD(GetIpNetTable,  205),
        DEFINE_ALIAS_CMD(GetIpForwardTable,  206),
        DEFINE_ALIAS_CMD(FlushIpNetTable,  207),

Changes to undroid/twapi/twapi/nls/nls.c.

136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215




216

217
218
219
220
221
222
223
        ObjSetResult(ticP->interp, ObjFromWinCharsN(buf, numchars-1));

    MemLifoPopFrame(ticP->memlifoP);

    return numchars ? TCL_OK : TCL_ERROR;
}

static int Twapi_NlsCallObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    int func;
    DWORD dw, dw2;
    TwapiResult result;
    WCHAR buf[MAX_PATH+1];

    if (objc < 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
................................................................................
    case 32:
        return Twapi_GetNumberFormat(ticP, objc-2, objv+2);
    case 33:
        return Twapi_GetCurrencyFormat(ticP, objc-2, objv+2);
    case 34:
        if (objc != 3)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_INTEGER_OBJ(interp, dw, objv[2]);
        result.value.unicode.len = VerLanguageNameW(dw, buf, sizeof(buf)/sizeof(buf[0]));
        result.value.unicode.str = buf;
        result.type = result.value.unicode.len ? TRT_UNICODE : TRT_GETLASTERROR;
        break;
    case 35: //GetLocaleInfo
        if (objc != 4)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_INTEGER_OBJ(interp, dw, objv[2]);
        CHECK_INTEGER_OBJ(interp, dw2, objv[3]);
        result.value.unicode.len = GetLocaleInfoW(dw, dw2, buf,
                                                  ARRAYSIZE(buf));
        if (result.value.unicode.len == 0) {
            result.type = TRT_GETLASTERROR;
        } else {
            if (dw2 & LOCALE_RETURN_NUMBER) {
                // buf actually contains a number




                result.value.ival = *(int *)buf;

                result.type = TRT_LONG;
            } else {
                result.value.unicode.len -= 1;
                result.value.unicode.str = buf;
                result.type = TRT_UNICODE;
            }
        }







|

>







 







|







|
|







>
>
>
>
|
>







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
        ObjSetResult(ticP->interp, ObjFromWinCharsN(buf, numchars-1));

    MemLifoPopFrame(ticP->memlifoP);

    return numchars ? TCL_OK : TCL_ERROR;
}

static int Twapi_NlsCallObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    int func;
    DWORD dw, dw2;
    TwapiResult result;
    WCHAR buf[MAX_PATH+1];

    if (objc < 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
................................................................................
    case 32:
        return Twapi_GetNumberFormat(ticP, objc-2, objv+2);
    case 33:
        return Twapi_GetCurrencyFormat(ticP, objc-2, objv+2);
    case 34:
        if (objc != 3)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_DWORD_OBJ(interp, dw, objv[2]);
        result.value.unicode.len = VerLanguageNameW(dw, buf, sizeof(buf)/sizeof(buf[0]));
        result.value.unicode.str = buf;
        result.type = result.value.unicode.len ? TRT_UNICODE : TRT_GETLASTERROR;
        break;
    case 35: //GetLocaleInfo
        if (objc != 4)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_DWORD_OBJ(interp, dw, objv[2]);
        CHECK_DWORD_OBJ(interp, dw2, objv[3]);
        result.value.unicode.len = GetLocaleInfoW(dw, dw2, buf,
                                                  ARRAYSIZE(buf));
        if (result.value.unicode.len == 0) {
            result.type = TRT_GETLASTERROR;
        } else {
            if (dw2 & LOCALE_RETURN_NUMBER) {
                // buf actually contains a number
#ifdef __GNUC__
                /* gcc complains about type punning so we have to do this. */
                memcpy(&result.value.lval, buf, sizeof(result.value.lval));
#else
                result.value.lval = *(long *)buf;
#endif
                result.type = TRT_LONG;
            } else {
                result.value.unicode.len -= 1;
                result.value.unicode.str = buf;
                result.type = TRT_UNICODE;
            }
        }

Changes to undroid/twapi/twapi/os/os.c.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
...
194
195
196
197
198
199
200


201
202
203
204
205
206
207
...
226
227
228
229
230
231
232

233

234
235
236
237
238
239
240
...
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
...
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
...
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

typedef enum _TWAPI_LOGICAL_PROCESSOR_RELATIONSHIP {
    TwapiRelationProcessorCore,
    TwapiRelationNumaNode,
    TwapiRelationCache,
    TwapiRelationProcessorPackage,
    TwapiRelationGroup,
    TwapiRelationAll = 0xffff
} TWAPI_LOGICAL_PROCESSOR_RELATIONSHIP;

#ifndef LTP_PC_SMT
#define LTP_PC_SMT 0x1
#endif

typedef enum _TWAPI_PROCESSOR_CACHE_TYPE {
................................................................................
    case TwapiRelationProcessorPackage:
        elems[0] = ObjFromLong(slpiexP->Processor.Flags);
        elems[1] = ObjNewList(slpiexP->Processor.GroupCount, NULL);
        for (i = 0; i < slpiexP->Processor.GroupCount; ++i)
            ObjAppendElement(NULL, elems[1], ObjFromGROUP_AFFINITY(&slpiexP->Processor.GroupMask[i]));
        nelems = 2;
        break;


    }

    objs[1] = ObjNewList(nelems, elems);
    return ObjNewList(2, objs);

}

................................................................................
        break;
    case TwapiRelationNumaNode:
        objs[2] = ObjFromLong(slpiP->NumaNode.NodeNumber);
        break;
    case TwapiRelationProcessorCore:
        objs[2] = ObjFromLong(slpiP->ProcessorCore.Flags);
        break;

    case TwapiRelationProcessorPackage:

        objs[2] = ObjFromEmptyString();
        break;
    }

    return ObjNewList(3, objs);
}

................................................................................

        ObjSetResult(interp, ObjNewList(26, objv));
        return TCL_OK;
    } else
        return TwapiReturnSystemError(interp);
}

static TCL_RESULT Twapi_SystemProcessorTimesObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    SYSTEM_INFO sysinfo;
    void  *bufP;
    int    bufsz;
    ULONG  dummy;
    NTSTATUS status;
    DWORD    i;
    NtQuerySystemInformation_t NtQuerySystemInformationPtr = Twapi_GetProc_NtQuerySystemInformation();
................................................................................
        if (objc != 0)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        switch (func) {
        case 32:
            return Twapi_GetLogicalProcessorInformation(interp);
        case 33:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetComputerNameW(u.buf, &result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 34:
            return Twapi_GetSystemInfo(interp);
................................................................................
                break;
            }
            break;
        }
    } else if (func < 300) {
        if (objc != 1)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_INTEGER_OBJ(interp, dw, objv[0]);
        switch (func) {
        case 201:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetComputerNameExW(dw, u.buf, &result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 202:
            result.type = TRT_LONG;







<







 







>
>







 







>

>







 







|

>







 







|







 







|



|







51
52
53
54
55
56
57

58
59
60
61
62
63
64
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
...
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

typedef enum _TWAPI_LOGICAL_PROCESSOR_RELATIONSHIP {
    TwapiRelationProcessorCore,
    TwapiRelationNumaNode,
    TwapiRelationCache,
    TwapiRelationProcessorPackage,
    TwapiRelationGroup,

} TWAPI_LOGICAL_PROCESSOR_RELATIONSHIP;

#ifndef LTP_PC_SMT
#define LTP_PC_SMT 0x1
#endif

typedef enum _TWAPI_PROCESSOR_CACHE_TYPE {
................................................................................
    case TwapiRelationProcessorPackage:
        elems[0] = ObjFromLong(slpiexP->Processor.Flags);
        elems[1] = ObjNewList(slpiexP->Processor.GroupCount, NULL);
        for (i = 0; i < slpiexP->Processor.GroupCount; ++i)
            ObjAppendElement(NULL, elems[1], ObjFromGROUP_AFFINITY(&slpiexP->Processor.GroupMask[i]));
        nelems = 2;
        break;
    default:
        return ObjNewList(0, NULL);
    }

    objs[1] = ObjNewList(nelems, elems);
    return ObjNewList(2, objs);

}

................................................................................
        break;
    case TwapiRelationNumaNode:
        objs[2] = ObjFromLong(slpiP->NumaNode.NodeNumber);
        break;
    case TwapiRelationProcessorCore:
        objs[2] = ObjFromLong(slpiP->ProcessorCore.Flags);
        break;
    case TwapiRelationGroup: /* TBD - add support */
    case TwapiRelationProcessorPackage:
    default:
        objs[2] = ObjFromEmptyString();
        break;
    }

    return ObjNewList(3, objs);
}

................................................................................

        ObjSetResult(interp, ObjNewList(26, objv));
        return TCL_OK;
    } else
        return TwapiReturnSystemError(interp);
}

static TCL_RESULT Twapi_SystemProcessorTimesObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    SYSTEM_INFO sysinfo;
    void  *bufP;
    int    bufsz;
    ULONG  dummy;
    NTSTATUS status;
    DWORD    i;
    NtQuerySystemInformation_t NtQuerySystemInformationPtr = Twapi_GetProc_NtQuerySystemInformation();
................................................................................
        if (objc != 0)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        switch (func) {
        case 32:
            return Twapi_GetLogicalProcessorInformation(interp);
        case 33:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetComputerNameW(u.buf, (DWORD *) &result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 34:
            return Twapi_GetSystemInfo(interp);
................................................................................
                break;
            }
            break;
        }
    } else if (func < 300) {
        if (objc != 1)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        CHECK_DWORD_OBJ(interp, dw, objv[0]);
        switch (func) {
        case 201:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetComputerNameExW(dw, u.buf, (DWORD*)&result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 202:
            result.type = TRT_LONG;

Changes to undroid/twapi/twapi/pdh/pdh.c.

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
...
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
    if (valP->CStatus == ERROR_SUCCESS) {
        switch (dwFormat & (PDH_FMT_LARGE | PDH_FMT_DOUBLE | PDH_FMT_LONG)) {
        case PDH_FMT_LONG:   return ObjFromLong(valP->longValue);
        case PDH_FMT_LARGE:  return ObjFromWideInt(valP->largeValue);
        case PDH_FMT_DOUBLE: return Tcl_NewDoubleObj(valP->doubleValue);
        default:
            ObjSetResult(interp,
                         Tcl_ObjPrintf("Invalid PDH counter format value 0x%x",
                                       dwFormat));
            return NULL;
        }
    }
    Twapi_AppendSystemErrorEx(interp, valP->CStatus, Tcl_ObjPrintf("Counter value status failure %d", valP->CStatus));
    return NULL;
}

static TCL_RESULT ObjFromPDH_COUNTER_VALUE_ITEM(Tcl_Interp *interp, PDH_FMT_COUNTERVALUE_ITEM_W *itemP, DWORD dwFormat, Tcl_Obj **nameObjP, Tcl_Obj **valObjP)
{
    Tcl_Obj *valObj;

................................................................................
    Tcl_Interp *interp,
    HANDLE hCounter,
    DWORD dwFormat
    )
{
    PDH_STATUS pdh_status;
    DWORD sz, nitems;
    PDH_FMT_COUNTERVALUE_ITEM_W *itemP;
    TCL_RESULT res;
    DWORD i;
    SWSMark mark = SWSPushMark();

    /* Always get required size first since docs say do not rely on
     * returned size for allocation if it was not passed in as 0.
     */
................................................................................
    
    pdh_status = PdhGetFormattedCounterValue(hCounter, dwFormat,
                                             &counter_type, &counter_value);

    if ((pdh_status != ERROR_SUCCESS)
        || (counter_value.CStatus != ERROR_SUCCESS)) {
        ObjSetResult(interp,
                         Tcl_ObjPrintf("Error (0x%x/0x%x) retrieving counter value: ", pdh_status, counter_value.CStatus));
        if (pdh_status == ERROR_SUCCESS)
            pdh_status = counter_value.CStatus;
        return Twapi_AppendSystemError(interp, pdh_status);
    }

    switch (dwFormat & (PDH_FMT_LARGE | PDH_FMT_DOUBLE | PDH_FMT_LONG)) {
    case PDH_FMT_LONG:
................................................................................

    case PDH_FMT_DOUBLE:
        objP = Tcl_NewDoubleObj(counter_value.doubleValue);
        break;

    default:
        ObjSetResult(interp,
                         Tcl_ObjPrintf("Invalid PDH counter format value 0x%x",
                                       dwFormat));
        return  TCL_ERROR;
    }
    
    ObjSetResult(interp, objP);
    return TCL_OK;
}
................................................................................
#if 0
PdhExpandCounterPath has a bug on Win2K. So we do not wrap it; TBD
#endif


/* Call PDH API. This is special-cased because we have to do a restore
   locale after every PDH call on some platforms */
int Twapi_CallPdhObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    int func;
    LPWSTR s;
    DWORD   dw, dw2;
    HANDLE h;
    TwapiResult result;

    if (TwapiGetArgs(interp, objc-1, objv+1,
................................................................................
        }
    } else if (func < 200) {
        /* Single argument */
        CHECK_NARGS(interp, objc, 3);

        switch (func) {
        case 101:
            if (ObjToLong(interp, objv[2], &dw) != TCL_OK)
                return TwapiReturnError(interp, TWAPI_INVALID_ARGS);
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = PdhSetDefaultRealTimeDataSource(dw);
            break;
        case 102:
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = PdhConnectMachineW(ObjToLPWSTR_NULL_IF_EMPTY(objv[2]));
................................................................................
            result.value.ival = PdhValidatePathW(ObjToWinChars(objv[2]));
            break;
        }
    } else if (func < 300) {
        /* Single string with integer arg. */
        CHECK_NARGS(interp, objc, 4);
        /* To prevent shimmering issues, get int arg first */
        CHECK_INTEGER_OBJ(interp, dw, objv[3]);
        s = ObjToWinChars(objv[2]);
        switch (func) {
        case 201: 
            return Twapi_PdhParseCounterPath(ticP, s, dw);
        case 202: 
            NULLIFY_EMPTY(s);
            return Twapi_PdhLookupPerfNameByIndex(interp, s, dw);







|




|







 







|







 







|







 







|







 







|

>







 







|







 







|







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
...
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
    if (valP->CStatus == ERROR_SUCCESS) {
        switch (dwFormat & (PDH_FMT_LARGE | PDH_FMT_DOUBLE | PDH_FMT_LONG)) {
        case PDH_FMT_LONG:   return ObjFromLong(valP->longValue);
        case PDH_FMT_LARGE:  return ObjFromWideInt(valP->largeValue);
        case PDH_FMT_DOUBLE: return Tcl_NewDoubleObj(valP->doubleValue);
        default:
            ObjSetResult(interp,
                         Tcl_ObjPrintf("Invalid PDH counter format value 0x%lx",
                                       dwFormat));
            return NULL;
        }
    }
    Twapi_AppendSystemErrorEx(interp, valP->CStatus, Tcl_ObjPrintf("Counter value status failure %lu", valP->CStatus));
    return NULL;
}

static TCL_RESULT ObjFromPDH_COUNTER_VALUE_ITEM(Tcl_Interp *interp, PDH_FMT_COUNTERVALUE_ITEM_W *itemP, DWORD dwFormat, Tcl_Obj **nameObjP, Tcl_Obj **valObjP)
{
    Tcl_Obj *valObj;

................................................................................
    Tcl_Interp *interp,
    HANDLE hCounter,
    DWORD dwFormat
    )
{
    PDH_STATUS pdh_status;
    DWORD sz, nitems;
    PDH_FMT_COUNTERVALUE_ITEM_W *itemP = NULL;
    TCL_RESULT res;
    DWORD i;
    SWSMark mark = SWSPushMark();

    /* Always get required size first since docs say do not rely on
     * returned size for allocation if it was not passed in as 0.
     */
................................................................................
    
    pdh_status = PdhGetFormattedCounterValue(hCounter, dwFormat,
                                             &counter_type, &counter_value);

    if ((pdh_status != ERROR_SUCCESS)
        || (counter_value.CStatus != ERROR_SUCCESS)) {
        ObjSetResult(interp,
                         Tcl_ObjPrintf("Error (0x%lx/0x%lx) retrieving counter value: ", pdh_status, counter_value.CStatus));
        if (pdh_status == ERROR_SUCCESS)
            pdh_status = counter_value.CStatus;
        return Twapi_AppendSystemError(interp, pdh_status);
    }

    switch (dwFormat & (PDH_FMT_LARGE | PDH_FMT_DOUBLE | PDH_FMT_LONG)) {
    case PDH_FMT_LONG:
................................................................................

    case PDH_FMT_DOUBLE:
        objP = Tcl_NewDoubleObj(counter_value.doubleValue);
        break;

    default:
        ObjSetResult(interp,
                         Tcl_ObjPrintf("Invalid PDH counter format value 0x%lx",
                                       dwFormat));
        return  TCL_ERROR;
    }
    
    ObjSetResult(interp, objP);
    return TCL_OK;
}
................................................................................
#if 0
PdhExpandCounterPath has a bug on Win2K. So we do not wrap it; TBD
#endif


/* Call PDH API. This is special-cased because we have to do a restore
   locale after every PDH call on some platforms */
int Twapi_CallPdhObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    int func;
    LPWSTR s;
    DWORD   dw, dw2;
    HANDLE h;
    TwapiResult result;

    if (TwapiGetArgs(interp, objc-1, objv+1,
................................................................................
        }
    } else if (func < 200) {
        /* Single argument */
        CHECK_NARGS(interp, objc, 3);

        switch (func) {
        case 101:
            if (ObjToDWORD(interp, objv[2], &dw) != TCL_OK)
                return TwapiReturnError(interp, TWAPI_INVALID_ARGS);
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = PdhSetDefaultRealTimeDataSource(dw);
            break;
        case 102:
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = PdhConnectMachineW(ObjToLPWSTR_NULL_IF_EMPTY(objv[2]));
................................................................................
            result.value.ival = PdhValidatePathW(ObjToWinChars(objv[2]));
            break;
        }
    } else if (func < 300) {
        /* Single string with integer arg. */
        CHECK_NARGS(interp, objc, 4);
        /* To prevent shimmering issues, get int arg first */
        CHECK_DWORD_OBJ(interp, dw, objv[3]);
        s = ObjToWinChars(objv[2]);
        switch (func) {
        case 201: 
            return Twapi_PdhParseCounterPath(ticP, s, dw);
        case 202: 
            NULLIFY_EMPTY(s);
            return Twapi_PdhLookupPerfNameByIndex(interp, s, dw);

Changes to undroid/twapi/twapi/process/process.c.

310
311
312
313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361




362
363
364
365
366
367
368
...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
...
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
...
863
864
865
866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
882
883

884
885
886
887
888
889
890
891
892

893
894
895
896
897
898
899
900
901

902
903
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918

/*
 * Helper to enumerate processes, or modules for a
 * process with a given pid
 * type = 0 for process, 1 for modules, 2 for drivers
 */
static int Twapi_EnumProcessesModulesObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    void  *bufP;
    DWORD  buf_filled;
    DWORD  buf_size;
    int    result;
    BOOL   status;
    int type;
    HANDLE phandle;
................................................................................
    result = TCL_ERROR;
    do {
        switch (type) {
        case 0:
            /* Looking for processes */
            status = EnumProcesses(bufP, buf_size, &buf_filled);
            break;

        case 1:
            /* Looking for modules for a process */
            status = EnumProcessModules(phandle, bufP, buf_size, &buf_filled);
            break;

        case 2:
            /* Looking for drivers */
            status = EnumDeviceDrivers(bufP, buf_size, &buf_filled);
            break;




        }

        if (! status) {
            TwapiReturnSystemError(ticP->interp);
            break;
        }

................................................................................
                       GETINT(inherit), GETINT(flags),
                       GETOBJ(envObj),   GETEMPTYASNULL(curdir),
                       GETOBJ(startinfoObj), ARGEND) != TCL_OK)
        goto vamoose;           /* So any allocs/marks can be freed */

    envP = ObjToLPWSTR_WITH_NULL(envObj);
    if (envP) {
        if (ObjToMultiSzEx(interp, envObj, (LPWSTR*) &envP, ticP->memlifoP) == TCL_ERROR)
            goto vamoose;
        /* Note envP is allocated from ticP->memlifo */
    }
    
    if (ListObjToSTARTUPINFO(ticP, startinfoObj, &startinfo) != TCL_OK)
        goto vamoose;

................................................................................
        if (ParsePSEC_WINNT_AUTH_IDENTITY(ticP, authObj, &swaiP) != TCL_OK)
            goto vamoose;
        NULLIFY_EMPTY(swaiP->Domain);
    }

    envP = ObjToLPWSTR_WITH_NULL(envObj);
    if (envP) {
        if (ObjToMultiSzEx(interp, envObj, (LPWSTR*) &envP, ticP->memlifoP) == TCL_ERROR)
            goto vamoose;
        /* Note envP is allocated from ticP->memlifo */
    }
    
    if (ListObjToSTARTUPINFO(ticP, startinfoObj, &startinfo) != TCL_OK)
        goto vamoose;

................................................................................

    MemLifoPopMark(mark);
    return status ? TCL_OK : TCL_ERROR;
}


static TCL_RESULT Twapi_CreateProcessObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    return TwapiCreateProcessHelper(ticP, 0, objc, objv);
}

static TCL_RESULT Twapi_CreateProcessAsUserObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    return TwapiCreateProcessHelper(ticP, 1, objc, objv);
}

static TCL_RESULT Twapi_CreateProcessWithLogonWObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    return TwapiCreateProcessHelper2(ticP, 0, objc, objv);
}

static TCL_RESULT Twapi_CreateProcessWithTokenWObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    return TwapiCreateProcessHelper2(ticP, 1, objc, objv);
}


static TCL_RESULT Twapi_LoadUserProfileObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    HANDLE  hToken;
    PROFILEINFOW profileinfo;
    int nobjs;
    Tcl_Obj **objs;

    CHECK_NARGS(interp, objc, 2);
    if (ObjGetElements(interp, objv[1], &nobjs, &objs) != TCL_OK)







|




>







 







|









>
>
>
>







 







|







 







|







 







|




>




|




>




|




>




|




>





|




>







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928

/*
 * Helper to enumerate processes, or modules for a
 * process with a given pid
 * type = 0 for process, 1 for modules, 2 for drivers
 */
static int Twapi_EnumProcessesModulesObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    void  *bufP;
    DWORD  buf_filled;
    DWORD  buf_size;
    int    result;
    BOOL   status;
    int type;
    HANDLE phandle;
................................................................................
    result = TCL_ERROR;
    do {
        switch (type) {
        case 0:
            /* Looking for processes */
            status = EnumProcesses(bufP, buf_size, &buf_filled);
            break;
 
        case 1:
            /* Looking for modules for a process */
            status = EnumProcessModules(phandle, bufP, buf_size, &buf_filled);
            break;

        case 2:
            /* Looking for drivers */
            status = EnumDeviceDrivers(bufP, buf_size, &buf_filled);
            break;

        default:
            MemLifoPopFrame(ticP->memlifoP);
            return TwapiReturnError(ticP->interp, TWAPI_INVALID_ARGS);
        }

        if (! status) {
            TwapiReturnSystemError(ticP->interp);
            break;
        }

................................................................................
                       GETINT(inherit), GETINT(flags),
                       GETOBJ(envObj),   GETEMPTYASNULL(curdir),
                       GETOBJ(startinfoObj), ARGEND) != TCL_OK)
        goto vamoose;           /* So any allocs/marks can be freed */

    envP = ObjToLPWSTR_WITH_NULL(envObj);
    if (envP) {
        if (ObjToMultiSzEx(interp, envObj, (const WCHAR **) &envP, ticP->memlifoP) == TCL_ERROR)
            goto vamoose;
        /* Note envP is allocated from ticP->memlifo */
    }
    
    if (ListObjToSTARTUPINFO(ticP, startinfoObj, &startinfo) != TCL_OK)
        goto vamoose;

................................................................................
        if (ParsePSEC_WINNT_AUTH_IDENTITY(ticP, authObj, &swaiP) != TCL_OK)
            goto vamoose;
        NULLIFY_EMPTY(swaiP->Domain);
    }

    envP = ObjToLPWSTR_WITH_NULL(envObj);
    if (envP) {
        if (ObjToMultiSzEx(interp, envObj, (const WCHAR **) &envP, ticP->memlifoP) == TCL_ERROR)
            goto vamoose;
        /* Note envP is allocated from ticP->memlifo */
    }
    
    if (ListObjToSTARTUPINFO(ticP, startinfoObj, &startinfo) != TCL_OK)
        goto vamoose;

................................................................................

    MemLifoPopMark(mark);
    return status ? TCL_OK : TCL_ERROR;
}


static TCL_RESULT Twapi_CreateProcessObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    return TwapiCreateProcessHelper(ticP, 0, objc, objv);
}

static TCL_RESULT Twapi_CreateProcessAsUserObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    return TwapiCreateProcessHelper(ticP, 1, objc, objv);
}

static TCL_RESULT Twapi_CreateProcessWithLogonWObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    return TwapiCreateProcessHelper2(ticP, 0, objc, objv);
}

static TCL_RESULT Twapi_CreateProcessWithTokenWObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    return TwapiCreateProcessHelper2(ticP, 1, objc, objv);
}


static TCL_RESULT Twapi_LoadUserProfileObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = (TwapiInterpContext*) clientdata;
    HANDLE  hToken;
    PROFILEINFOW profileinfo;
    int nobjs;
    Tcl_Obj **objs;

    CHECK_NARGS(interp, objc, 2);
    if (ObjGetElements(interp, objv[1], &nobjs, &objs) != TCL_OK)

Changes to undroid/twapi/twapi/resource/resource.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
...
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
{
    int i;

    /*
     * Resource type and name can be integers or strings. If integer,
     * they must pass the IS_INTRESOURCE test as not all integers are valid.
     */
    if (ObjToLong(NULL, objP, &i) == TCL_OK &&
        IS_INTRESOURCE(i))
        *wsP = MAKEINTRESOURCEW(i);
    else
        *wsP = ObjToWinChars(objP);

    return TCL_OK;
}
................................................................................
    TWAPI_FILEVERINFO* verP
    )
{
    Tcl_Obj           *resultObj;
    VS_FIXEDFILEINFO *ffiP;
    UINT              ffi_sz;

    if (! VerQueryValue(verP, "\\", (LPVOID) &ffiP, &ffi_sz)) {
        /* Return empty list, not error */
        return TCL_OK;
    }

    resultObj = ObjEmptyList();
    Twapi_APPEND_DWORD_FIELD_TO_LIST(interp, resultObj, ffiP, dwSignature);
    Twapi_APPEND_DWORD_FIELD_TO_LIST(interp, resultObj, ffiP, dwStrucVersion);
................................................................................
    )
{
    Tcl_Obj  *resultObj;
    DWORD    *bufP;
    DWORD    *dwP;
    UINT      len;

    if (! VerQueryValue(verP, "\\VarFileInfo\\Translation", (LPVOID) &bufP, &len)) {
        /* Return empty list, not error */
        return TCL_OK;
    }

    resultObj = ObjEmptyList();
    for (dwP = bufP; ((char *)dwP) <= (len - sizeof(*dwP) + (char *)bufP) ; ++dwP) {
        WORD *wP = (WORD *) dwP;
................................................................................
       them AFTER scalars are extracted above to prevent shimmering bugs */
    if (ObjToResourceIntOrString(interp, restypeObj, &restype) != TCL_OK ||
        ObjToResourceIntOrString(interp, resnameObj, &resname) != TCL_OK)
        return TCL_ERROR;

    /* Note resP / reslen might be NULL/0 -> delete resource */
    if (resObj)
        resP = ObjToByteArray(resObj, &reslen);
    else {
        resP = NULL;
        reslen = 0;
    }

    if (UpdateResourceW(h, restype, resname, langid, resP, reslen))
        return TCL_OK;
................................................................................
        ObjDecrRefs(ctx.objP);
        return TCL_ERROR;
    }
}

static BOOL CALLBACK EnumResourceTypesProc(
    HMODULE hModule,
    LPCWSTR lpszType,
    LONG_PTR lParam
)
{
    TwapiEnumCtx *ctxP = (TwapiEnumCtx *) lParam;

    ObjAppendElement(ctxP->interp, ctxP->objP,
                             ObjFromResourceIntOrString(lpszType));
................................................................................
        if (TwapiGetArgs(interp, objc, objv, GETHANDLE(h), GETBOOL(dw), ARGEND) != TCL_OK)
            return TCL_ERROR;
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival = EndUpdateResourceW(h, dw);
        break;
    case 19:
        CHECK_NARGS(interp, objc, 4);
        CHECK_INTEGER_OBJ(interp, dw, objv[0]);
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival =
            CreateScalableFontResourceW(dw,
                                        ObjToWinChars(objv[1]),
                                        ObjToWinChars(objv[2]),
                                        ObjToWinChars(objv[3]));
        break;
    case 20:
        CHECK_NARGS(interp, objc, 2);
        CHECK_INTEGER_OBJ(interp, dw, objv[1]);
        result.type = TRT_BOOL;
        result.value.bval = RemoveFontResourceExW(ObjToWinChars(objv[0]), dw, NULL);
        break;
    }

    return TwapiSetResult(interp, &result);
}







|







 







|







 







|







 







|







 







|







 







|









|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
...
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
{
    int i;

    /*
     * Resource type and name can be integers or strings. If integer,
     * they must pass the IS_INTRESOURCE test as not all integers are valid.
     */
    if (ObjToInt(NULL, objP, &i) == TCL_OK &&
        IS_INTRESOURCE(i))
        *wsP = MAKEINTRESOURCEW(i);
    else
        *wsP = ObjToWinChars(objP);

    return TCL_OK;
}
................................................................................
    TWAPI_FILEVERINFO* verP
    )
{
    Tcl_Obj           *resultObj;
    VS_FIXEDFILEINFO *ffiP;
    UINT              ffi_sz;

    if (! VerQueryValueW(verP, L"\\", (LPVOID) &ffiP, &ffi_sz)) {
        /* Return empty list, not error */
        return TCL_OK;
    }

    resultObj = ObjEmptyList();
    Twapi_APPEND_DWORD_FIELD_TO_LIST(interp, resultObj, ffiP, dwSignature);
    Twapi_APPEND_DWORD_FIELD_TO_LIST(interp, resultObj, ffiP, dwStrucVersion);
................................................................................
    )
{
    Tcl_Obj  *resultObj;
    DWORD    *bufP;
    DWORD    *dwP;
    UINT      len;

    if (! VerQueryValueW(verP, L"\\VarFileInfo\\Translation", (LPVOID) &bufP, &len)) {
        /* Return empty list, not error */
        return TCL_OK;
    }

    resultObj = ObjEmptyList();
    for (dwP = bufP; ((char *)dwP) <= (len - sizeof(*dwP) + (char *)bufP) ; ++dwP) {
        WORD *wP = (WORD *) dwP;
................................................................................
       them AFTER scalars are extracted above to prevent shimmering bugs */
    if (ObjToResourceIntOrString(interp, restypeObj, &restype) != TCL_OK ||
        ObjToResourceIntOrString(interp, resnameObj, &resname) != TCL_OK)
        return TCL_ERROR;

    /* Note resP / reslen might be NULL/0 -> delete resource */
    if (resObj)
        resP = ObjToByteArrayDW(resObj, &reslen);
    else {
        resP = NULL;
        reslen = 0;
    }

    if (UpdateResourceW(h, restype, resname, langid, resP, reslen))
        return TCL_OK;
................................................................................
        ObjDecrRefs(ctx.objP);
        return TCL_ERROR;
    }
}

static BOOL CALLBACK EnumResourceTypesProc(
    HMODULE hModule,
    LPWSTR lpszType,
    LONG_PTR lParam
)
{
    TwapiEnumCtx *ctxP = (TwapiEnumCtx *) lParam;

    ObjAppendElement(ctxP->interp, ctxP->objP,
                             ObjFromResourceIntOrString(lpszType));
................................................................................
        if (TwapiGetArgs(interp, objc, objv, GETHANDLE(h), GETBOOL(dw), ARGEND) != TCL_OK)
            return TCL_ERROR;
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival = EndUpdateResourceW(h, dw);
        break;
    case 19:
        CHECK_NARGS(interp, objc, 4);
        CHECK_DWORD_OBJ(interp, dw, objv[0]);
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival =
            CreateScalableFontResourceW(dw,
                                        ObjToWinChars(objv[1]),
                                        ObjToWinChars(objv[2]),
                                        ObjToWinChars(objv[3]));
        break;
    case 20:
        CHECK_NARGS(interp, objc, 2);
        CHECK_DWORD_OBJ(interp, dw, objv[1]);
        result.type = TRT_BOOL;
        result.value.bval = RemoveFontResourceExW(ObjToWinChars(objv[0]), dw, NULL);
        break;
    }

    return TwapiSetResult(interp, &result);
}

Changes to undroid/twapi/twapi/security/security.c.

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
...
322
323
324
325
326
327
328



329
330
331
332
333
334
335
...
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
...
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
...
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
...
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
....
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
....
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
int ObjToSID_AND_ATTRIBUTESSWS(Tcl_Interp *interp, Tcl_Obj *obj, SID_AND_ATTRIBUTES *sidattrP)
{
    Tcl_Obj **objv;
    int       objc;

    if (ObjGetElements(interp, obj, &objc, &objv) == TCL_OK &&
        objc == 2 &&
        ObjToLong(interp, objv[1], &sidattrP->Attributes) == TCL_OK &&
        ObjToPSIDSWS(interp, objv[0], &sidattrP->Sid) == TCL_OK) {

        return TCL_OK;
    } else
        return TCL_ERROR;
}

................................................................................
    int       objc;
    Tcl_Obj **objv;

    if (ObjGetElements(interp, listobj, &objc, &objv) != TCL_OK)
        return TCL_ERROR;

    if ((objc != 2) ||
        (ObjToLong(interp,objv[1],&luidattrP->Attributes) != TCL_OK) ||
        (ObjToLUID(interp, objv[0], &luidattrP->Luid) != TCL_OK)) {
        if (interp) {
            Tcl_AppendResult(interp,
                             "\nInvalid LUID_AND_ATTRIBUTES: ",
                             ObjToString(listobj),
                             NULL);
        }
................................................................................
 * Generic routine to retrieve token information. Returns pointer to memory\
 * allocated on SWS. Caller responsible for memory management
 */
static void *AllocateAndGetTokenInformation(HANDLE tokenH,
                                            TOKEN_INFORMATION_CLASS class)
{
    void *infoP = NULL;
    int   info_buf_sz = 0;
    DWORD error = 0;

    /* Keep looping since required buffer size may keep changing */
    do {
        if (GetTokenInformation(tokenH, (TOKEN_INFORMATION_CLASS) class,
                                infoP, info_buf_sz, &info_buf_sz)) {
            /* Got what we wanted */
................................................................................
                break;
                
            case TokenType:
                resultObj = ObjFromInt(value.type);
                result = TCL_OK;
                break;




            }

            /*
             * At this point, if result is TCL_OK, resultObj should contain
             * the result to be returned. Else interp->result should
             * contain the error message. In this
             * case, resultObj will be freed if non-NULL
................................................................................
    LsaFreeReturnBuffer(sessionP);
    return TCL_OK;
}

static TCL_RESULT Twapi_SecCallObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    LPWSTR s, s2;
    DWORD dw, dw2, dw3;
    SECURITY_ATTRIBUTES *secattrP;
    HANDLE h, h2;
    SECURITY_DESCRIPTOR *secdP;
    LUID luid;
    ACL *daclP, *saclP;
    PSID osidP, gsidP;
    union {
................................................................................
    LSA_HANDLE lsah;
    ULONG  lsa_count;
    LSA_UNICODE_STRING *lsa_strings;
    TwapiResult result;
    int func = PtrToInt(clientdata);
    WCHAR *passwordP;
    Tcl_Obj **objPP;
    DWORD nobjs;
    int *iP;
    Tcl_Obj *objP;
    SWSMark mark = NULL;
    TCL_RESULT res;

    daclP = saclP = NULL;
    osidP = gsidP = NULL;
    secdP = NULL;
................................................................................
            if (res != TCL_OK)
                goto vamoose;
            // Note aclP may me NULL even on TCL_OK
            result.type = TRT_BOOL;
            result.value.bval = daclP ? IsValidAcl(daclP) : 0;
            break;
        case 103:
            res = ObjToInt(interp, objv[0], &dw);
            if (res != TCL_OK)
                goto vamoose;
            result.value.ival = ImpersonateSelf(dw);
            result.type = TRT_EXCEPTION_ON_FALSE;
            break;
        case 104:
            res = ObjToHANDLE(interp, objv[0], &h);
................................................................................
            goto vamoose;
        }
        s = ObjToWinChars(objv[0]);
        s2 = ObjToWinChars(objv[1]);
        switch (func) {
        case 401:
            result.value.unicode.len = ARRAYSIZE(u.buf);
            if (LookupPrivilegeDisplayNameW(s,s2,u.buf,&result.value.unicode.len,&dw)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 402:
            if (LookupPrivilegeValueW(s,s2,&result.value.luid))
................................................................................
                           GETINT(dw2), ARGEND);
        if (res != TCL_OK)
            goto vamoose;
        s = ObjToWinChars(objv[0]);
        switch (func) {
        case 501:
            if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
                    s, dw, &secdP, NULL)) {
                result.value.obj = ObjFromSECURITY_DESCRIPTOR(interp, secdP);
                if (secdP)
                    LocalFree(secdP);
                if (result.value.obj)
                    result.type = TRT_OBJ;
                else {
                    res = TCL_ERROR;
................................................................................
                result.type = TRT_GETLASTERROR;
            break;

        case 10012:
            if (objc != 3)
                goto badargcount;
            if (ObjToOpaque(interp, objv[0], (void **) &lsah, "LSA_HANDLE") != TCL_OK ||
                ObjToBoolean(interp, objv[1], &dw2) != TCL_OK ||
                ObjGetElements(interp, objv[2], &nobjs, &objPP) != TCL_OK) {
                res = TCL_ERROR;
                goto vamoose;
            }
            iP = SWSAlloc(sizeof(int) * nobjs, NULL);
            for (dw = 0; dw < nobjs; ++dw) {
                if (ObjToInt(interp, objPP[dw], &iP[dw]) != TCL_OK)
                    break;
            }
            if (dw < nobjs) {
                /* Failed to convert to int */
                res = TCL_ERROR;
                goto vamoose;
            } else {
                POLICY_AUDIT_EVENTS_INFO paei;
                paei.AuditingMode = dw2 ? TRUE : FALSE;
                paei.EventAuditingOptions = iP;
                paei.MaximumAuditEventCount = nobjs;
                result.type = TRT_NTSTATUS;
                result.value.ival = LsaSetInformationPolicy(lsah,
                                                            PolicyAuditEventsInformation,
                                                            &paei);
            }

            break;

        case 10013: // Unused
            break;
        case 10014:
            res = TwapiGetArgs(interp, objc, objv,
                               ARGSKIP, ARGSKIP, ARGSKIP,
                               GETINT(dw), GETINT(dw2), ARGEND);
            if (res != TCL_OK)
                goto vamoose;
            passwordP = ObjDecryptPasswordSWS(objv[2], &dw3);
            if (LogonUserW(
                    ObjToWinChars(objv[0]),
                    ObjToLPWSTR_NULL_IF_EMPTY(objv[1]),
                    passwordP, dw, dw2, &result.value.hval))
                result.type = TRT_HANDLE;
            else
                result.type = TRT_GETLASTERROR;
            SecureZeroMemory(passwordP, dw3);
            break;
            
        case 10015:
            res = TwapiGetArgs(interp, objc, objv,
                               GETHANDLE(h), GETVAR(osidP, ObjToPSIDSWS),
                               ARGSKIP, ARGEND);
            if (res != TCL_OK)
................................................................................
            res = TwapiGetArgs(interp, objc, objv,
                               ARGSKIP, GETVAR(luid, ObjToLUID),
                               ARGEND);
            if (res != TCL_OK)
                goto vamoose;
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (LookupPrivilegeNameW(ObjToWinChars(objv[0]), &luid,
                                     u.buf, &result.value.unicode.len)) {
                result.type = TRT_UNICODE;
                result.value.unicode.str = u.buf;
                result.value.unicode.len = -1;
            } else
                result.type = TRT_GETLASTERROR;
            break;








|







 







|







 







|







 







>
>
>







 







|







 







|
|







 







|







 







|







 







|







 







|




|
|
|


|





|
|






<










|







|







 







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
...
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
...
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
...
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
...
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
....
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
....
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
int ObjToSID_AND_ATTRIBUTESSWS(Tcl_Interp *interp, Tcl_Obj *obj, SID_AND_ATTRIBUTES *sidattrP)
{
    Tcl_Obj **objv;
    int       objc;

    if (ObjGetElements(interp, obj, &objc, &objv) == TCL_OK &&
        objc == 2 &&
        ObjToDWORD(interp, objv[1], &sidattrP->Attributes) == TCL_OK &&
        ObjToPSIDSWS(interp, objv[0], &sidattrP->Sid) == TCL_OK) {

        return TCL_OK;
    } else
        return TCL_ERROR;
}

................................................................................
    int       objc;
    Tcl_Obj **objv;

    if (ObjGetElements(interp, listobj, &objc, &objv) != TCL_OK)
        return TCL_ERROR;

    if ((objc != 2) ||
        (ObjToDWORD(interp,objv[1],&luidattrP->Attributes) != TCL_OK) ||
        (ObjToLUID(interp, objv[0], &luidattrP->Luid) != TCL_OK)) {
        if (interp) {
            Tcl_AppendResult(interp,
                             "\nInvalid LUID_AND_ATTRIBUTES: ",
                             ObjToString(listobj),
                             NULL);
        }
................................................................................
 * Generic routine to retrieve token information. Returns pointer to memory\
 * allocated on SWS. Caller responsible for memory management
 */
static void *AllocateAndGetTokenInformation(HANDLE tokenH,
                                            TOKEN_INFORMATION_CLASS class)
{
    void *infoP = NULL;
    DWORD   info_buf_sz = 0;
    DWORD error = 0;

    /* Keep looping since required buffer size may keep changing */
    do {
        if (GetTokenInformation(tokenH, (TOKEN_INFORMATION_CLASS) class,
                                infoP, info_buf_sz, &info_buf_sz)) {
            /* Got what we wanted */
................................................................................
                break;
                
            case TokenType:
                resultObj = ObjFromInt(value.type);
                result = TCL_OK;
                break;

            default:
                UNREACHABLE;
                break;
            }

            /*
             * At this point, if result is TCL_OK, resultObj should contain
             * the result to be returned. Else interp->result should
             * contain the error message. In this
             * case, resultObj will be freed if non-NULL
................................................................................
    LsaFreeReturnBuffer(sessionP);
    return TCL_OK;
}

static TCL_RESULT Twapi_SecCallObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    LPWSTR s, s2;
    DWORD dw, dw2, dw3, *dwP;
    SECURITY_ATTRIBUTES *secattrP;
    HANDLE h, h2;
    SECURITY_DESCRIPTOR *secdP;
    LUID luid;
    ACL *daclP, *saclP;
    PSID osidP, gsidP;
    union {
................................................................................
    LSA_HANDLE lsah;
    ULONG  lsa_count;
    LSA_UNICODE_STRING *lsa_strings;
    TwapiResult result;
    int func = PtrToInt(clientdata);
    WCHAR *passwordP;
    Tcl_Obj **objPP;
    int nobjs;
    int i, ival;
    Tcl_Obj *objP;
    SWSMark mark = NULL;
    TCL_RESULT res;

    daclP = saclP = NULL;
    osidP = gsidP = NULL;
    secdP = NULL;
................................................................................
            if (res != TCL_OK)
                goto vamoose;
            // Note aclP may me NULL even on TCL_OK
            result.type = TRT_BOOL;
            result.value.bval = daclP ? IsValidAcl(daclP) : 0;
            break;
        case 103:
            res = ObjToDWORD(interp, objv[0], &dw);
            if (res != TCL_OK)
                goto vamoose;
            result.value.ival = ImpersonateSelf(dw);
            result.type = TRT_EXCEPTION_ON_FALSE;
            break;
        case 104:
            res = ObjToHANDLE(interp, objv[0], &h);
................................................................................
            goto vamoose;
        }
        s = ObjToWinChars(objv[0]);
        s2 = ObjToWinChars(objv[1]);
        switch (func) {
        case 401:
            result.value.unicode.len = ARRAYSIZE(u.buf);
            if (LookupPrivilegeDisplayNameW(s,s2,u.buf,(DWORD *) &result.value.unicode.len,&dw)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 402:
            if (LookupPrivilegeValueW(s,s2,&result.value.luid))
................................................................................
                           GETINT(dw2), ARGEND);
        if (res != TCL_OK)
            goto vamoose;
        s = ObjToWinChars(objv[0]);
        switch (func) {
        case 501:
            if (ConvertStringSecurityDescriptorToSecurityDescriptorW(
                    s, dw, (void **) &secdP, NULL)) {
                result.value.obj = ObjFromSECURITY_DESCRIPTOR(interp, secdP);
                if (secdP)
                    LocalFree(secdP);
                if (result.value.obj)
                    result.type = TRT_OBJ;
                else {
                    res = TCL_ERROR;
................................................................................
                result.type = TRT_GETLASTERROR;
            break;

        case 10012:
            if (objc != 3)
                goto badargcount;
            if (ObjToOpaque(interp, objv[0], (void **) &lsah, "LSA_HANDLE") != TCL_OK ||
                ObjToBoolean(interp, objv[1], &ival) != TCL_OK ||
                ObjGetElements(interp, objv[2], &nobjs, &objPP) != TCL_OK) {
                res = TCL_ERROR;
                goto vamoose;
            }
            dwP = SWSAlloc(sizeof(DWORD) * nobjs, NULL);
            for (i = 0; i < nobjs; ++i) {
                if (ObjToDWORD(interp, objPP[i], &dwP[i]) != TCL_OK)
                    break;
            }
            if (i < nobjs) {
                /* Failed to convert to int */
                res = TCL_ERROR;
                goto vamoose;
            } else {
                POLICY_AUDIT_EVENTS_INFO paei;
                paei.AuditingMode = ival ? TRUE : FALSE;
                paei.EventAuditingOptions = dwP;
                paei.MaximumAuditEventCount = nobjs;
                result.type = TRT_NTSTATUS;
                result.value.ival = LsaSetInformationPolicy(lsah,
                                                            PolicyAuditEventsInformation,
                                                            &paei);
            }

            break;

        case 10013: // Unused
            break;
        case 10014:
            res = TwapiGetArgs(interp, objc, objv,
                               ARGSKIP, ARGSKIP, ARGSKIP,
                               GETINT(dw), GETINT(dw2), ARGEND);
            if (res != TCL_OK)
                goto vamoose;
            passwordP = ObjDecryptPasswordSWS(objv[2], &ival);
            if (LogonUserW(
                    ObjToWinChars(objv[0]),
                    ObjToLPWSTR_NULL_IF_EMPTY(objv[1]),
                    passwordP, dw, dw2, &result.value.hval))
                result.type = TRT_HANDLE;
            else
                result.type = TRT_GETLASTERROR;
            SecureZeroMemory(passwordP, ival);
            break;
            
        case 10015:
            res = TwapiGetArgs(interp, objc, objv,
                               GETHANDLE(h), GETVAR(osidP, ObjToPSIDSWS),
                               ARGSKIP, ARGEND);
            if (res != TCL_OK)
................................................................................
            res = TwapiGetArgs(interp, objc, objv,
                               ARGSKIP, GETVAR(luid, ObjToLUID),
                               ARGEND);
            if (res != TCL_OK)
                goto vamoose;
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (LookupPrivilegeNameW(ObjToWinChars(objv[0]), &luid,
                                     u.buf, (DWORD *) &result.value.unicode.len)) {
                result.type = TRT_UNICODE;
                result.value.unicode.str = u.buf;
                result.value.unicode.len = -1;
            } else
                result.type = TRT_GETLASTERROR;
            break;

Changes to undroid/twapi/twapi/service/scm.c.

12
13
14
15
16
17
18










19
20
21
22
23
24
25
...
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
...
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
...
810
811
812
813
814
815
816
817
818

819
820
821
822
823
824
825
...
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
...
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
#ifndef TWAPI_SINGLE_MODULE
static HMODULE gModuleHandle;
#endif

#ifndef MODULENAME
#define MODULENAME "twapi_service"
#endif











/* Map service state int to string */
static char *ServiceStateString(DWORD state)
{
    switch (state) {
    case 0: return "0";
    case 1: return "stopped";
................................................................................

        res = ObjGetElements(interp, objs[i], &nfields, &fields);
        if (res != TCL_OK)
            return res;
        if (nfields != 2)
            return TwapiReturnError(interp, TWAPI_INVALID_DATA);
        if (ObjToInt(interp, fields[0], &sc_type) != TCL_OK ||
            ObjToInt(interp, fields[1], &sfaP->lpsaActions[i].Delay) != TCL_OK)
            return TCL_ERROR;
        sfaP->lpsaActions[i].Type = (SC_ACTION_TYPE) sc_type;
    }        

    return TCL_OK;
}

................................................................................
                         GETTOKENNULL(logrp), GETOBJ(tagObj), GETOBJ(depObj),
                         GETTOKENNULL(start_name),
                         GETOBJ(passwordObj), GETTOKENNULL(display_name),
                         ARGEND);
    if (res != TCL_OK)
        goto vamoose;

    if (ObjToLong(interp, tagObj, &tag_id) == TCL_OK)
        tag_idP = &tag_id;
    else {
        /* An empty string means value is not to be changed. Else error */
        if (Tcl_GetCharLength(tagObj) != 0) {
            res = TCL_ERROR;
            goto vamoose;   /* interp already holds error fom ObjToLong */
        }
................................................................................
                         GETOBJ(tagObj), GETOBJ(depObj),
                         GETEMPTYASNULL(service_start_name),
                         GETOBJ(passwordObj),
                         ARGEND);
    if (res != TCL_OK)
        goto vamoose;

    if (ObjToLong(NULL, tagObj, &tag_id) == TCL_OK)
        tag_idP = &tag_id;
    else {
        /* An empty string means value is not to be changed. Else error */
        if (Tcl_GetCharLength(tagObj) != 0)
            return TCL_ERROR;   /* interp already holds error */
        tag_idP = NULL;         /* Tag is not to be changed */
    }
................................................................................
    Tcl_Obj **argObjs;
    int     i, nargs;
    
    if (objc != 2) {
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
    }

    if (ObjToHANDLE(interp, objv[0], &svcH) != TCL_OK)
        return TCL_ERROR;

    if (ObjGetElements(interp, objv[1], &nargs, &argObjs) == TCL_ERROR)
        return TCL_ERROR;

    if (nargs > ARRAYSIZE(args)) {
        ObjSetStaticResult(interp, "Exceeded limit on number of service arguments.");
................................................................................
    if (reason == DLL_PROCESS_ATTACH)
        gModuleHandle = hmod;
    return TRUE;
}
#endif


static int Twapi_ServiceCallObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    TwapiResult result;
    int func;
    union {
        SERVICE_STATUS svcstatus;
        WCHAR buf[MAX_PATH+1];
    } u;
    DWORD dw;
................................................................................
                         GETHANDLE(h), GETOBJ(sObj), ARGUSEDEFAULT,
                         GETINT(dw), ARGEND) != TCL_OK)
            return TCL_ERROR;
        s = ObjToWinChars(sObj);
        switch (func) {
        case 201:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetServiceKeyNameW(h, s, u.buf, &result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 202:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetServiceDisplayNameW(h, s, u.buf, &result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 203:
            /* If access type not specified, use SERVICE_ALL_ACCESS */
................................................................................
            return Twapi_StartService(interp, objc-2, objv+2);
        case 10005:
            return Twapi_SetServiceStatus(ticP, objc-2, objv+2);
        case 10006:
            return Twapi_BecomeAService(ticP, objc-2, objv+2);
        case 10007:
            CHECK_NARGS(interp, objc, 5);
            CHECK_INTEGER_OBJ(interp, dw, objv[4]);
            result.type = TRT_SC_HANDLE;
            result.value.hval = OpenSCManagerW(
                ObjToLPWSTR_NULL_IF_EMPTY(objv[2]),
                ObjToLPWSTR_NULL_IF_EMPTY(objv[3]),
                dw);
            break;
        case 10008:







>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







|







 







|







 







|

>







 







|







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
...
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
...
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
...
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
...
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
#ifndef TWAPI_SINGLE_MODULE
static HMODULE gModuleHandle;
#endif

#ifndef MODULENAME
#define MODULENAME "twapi_service"
#endif

TWAPI_STATIC_INLINE TCL_RESULT ObjToSC_HANDLE(Tcl_Interp *interp, Tcl_Obj *objP, SC_HANDLE *schP) {
    HANDLE sch;
    TCL_RESULT res;
    /* Use of the intermediary is to keep gcc happy */
    res = ObjToHANDLE(interp, objP, &sch);
    if (res == TCL_OK)
        *schP = sch;
    return res;
}

/* Map service state int to string */
static char *ServiceStateString(DWORD state)
{
    switch (state) {
    case 0: return "0";
    case 1: return "stopped";
................................................................................

        res = ObjGetElements(interp, objs[i], &nfields, &fields);
        if (res != TCL_OK)
            return res;
        if (nfields != 2)
            return TwapiReturnError(interp, TWAPI_INVALID_DATA);
        if (ObjToInt(interp, fields[0], &sc_type) != TCL_OK ||
            ObjToDWORD(interp, fields[1], &sfaP->lpsaActions[i].Delay) != TCL_OK)
            return TCL_ERROR;
        sfaP->lpsaActions[i].Type = (SC_ACTION_TYPE) sc_type;
    }        

    return TCL_OK;
}

................................................................................
                         GETTOKENNULL(logrp), GETOBJ(tagObj), GETOBJ(depObj),
                         GETTOKENNULL(start_name),
                         GETOBJ(passwordObj), GETTOKENNULL(display_name),
                         ARGEND);
    if (res != TCL_OK)
        goto vamoose;

    if (ObjToDWORD(interp, tagObj, &tag_id) == TCL_OK)
        tag_idP = &tag_id;
    else {
        /* An empty string means value is not to be changed. Else error */
        if (Tcl_GetCharLength(tagObj) != 0) {
            res = TCL_ERROR;
            goto vamoose;   /* interp already holds error fom ObjToLong */
        }
................................................................................
                         GETOBJ(tagObj), GETOBJ(depObj),
                         GETEMPTYASNULL(service_start_name),
                         GETOBJ(passwordObj),
                         ARGEND);
    if (res != TCL_OK)
        goto vamoose;

    if (ObjToDWORD(NULL, tagObj, &tag_id) == TCL_OK)
        tag_idP = &tag_id;
    else {
        /* An empty string means value is not to be changed. Else error */
        if (Tcl_GetCharLength(tagObj) != 0)
            return TCL_ERROR;   /* interp already holds error */
        tag_idP = NULL;         /* Tag is not to be changed */
    }
................................................................................
    Tcl_Obj **argObjs;
    int     i, nargs;
    
    if (objc != 2) {
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
    }

    if (ObjToSC_HANDLE(interp, objv[0], &svcH) != TCL_OK)
        return TCL_ERROR;

    if (ObjGetElements(interp, objv[1], &nargs, &argObjs) == TCL_ERROR)
        return TCL_ERROR;

    if (nargs > ARRAYSIZE(args)) {
        ObjSetStaticResult(interp, "Exceeded limit on number of service arguments.");
................................................................................
    if (reason == DLL_PROCESS_ATTACH)
        gModuleHandle = hmod;
    return TRUE;
}
#endif


static int Twapi_ServiceCallObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    TwapiResult result;
    int func;
    union {
        SERVICE_STATUS svcstatus;
        WCHAR buf[MAX_PATH+1];
    } u;
    DWORD dw;
................................................................................
                         GETHANDLE(h), GETOBJ(sObj), ARGUSEDEFAULT,
                         GETINT(dw), ARGEND) != TCL_OK)
            return TCL_ERROR;
        s = ObjToWinChars(sObj);
        switch (func) {
        case 201:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetServiceKeyNameW(h, s, u.buf, (DWORD *)&result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 202:
            result.value.unicode.len = sizeof(u.buf)/sizeof(u.buf[0]);
            if (GetServiceDisplayNameW(h, s, u.buf, (DWORD *)&result.value.unicode.len)) {
                result.value.unicode.str = u.buf;
                result.type = TRT_UNICODE;
            } else
                result.type = TRT_GETLASTERROR;
            break;
        case 203:
            /* If access type not specified, use SERVICE_ALL_ACCESS */
................................................................................
            return Twapi_StartService(interp, objc-2, objv+2);
        case 10005:
            return Twapi_SetServiceStatus(ticP, objc-2, objv+2);
        case 10006:
            return Twapi_BecomeAService(ticP, objc-2, objv+2);
        case 10007:
            CHECK_NARGS(interp, objc, 5);
            CHECK_DWORD_OBJ(interp, dw, objv[4]);
            result.type = TRT_SC_HANDLE;
            result.value.hval = OpenSCManagerW(
                ObjToLPWSTR_NULL_IF_EMPTY(objv[2]),
                ObjToLPWSTR_NULL_IF_EMPTY(objv[3]),
                dw);
            break;
        case 10008:

Changes to undroid/twapi/twapi/service/service.c.

11
12
13
14
15
16
17



18

19
20
21
22
23
24
25
..
54
55
56
57
58
59
60


61




62
63
64
65
66
67
68
69
70
71
72
73
74
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
449
450
451
452
453
454
455




456
457
458
459
460
461
462
...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
...
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# include <process.h>
#endif
#include <dbt.h>                /* For DBT_* decls */

#include "twapi_service.h"

/* There can be only one....*/



static TwapiInterpContext *gServiceInterpContextP;


/* Structure to keep track of a particular service state */
typedef struct _TwapiServiceContext {
    SERVICE_STATUS_HANDLE service_status_handle; /* Must NEVER be closed! */
    DWORD   controls_accepted;   /* Controls accepted by the service */
    WCHAR   name[1];               /* Variable size, name of service */
} TwapiServiceContext;
................................................................................
 * Each individual element of gServiceContexts[] is only modified by
 * the specific thread running that service.
 * Hence no locks are required for this data.
 */
static TwapiServiceContext **gServiceContexts;
static int gNumServiceContexts;
DWORD  gServiceType;        /* own process or shared and whether interactive */


DWORD  gServiceMasterThreadId;   /* Thread of service main program */




HANDLE gServiceMasterThreadHandle;


static void TwapiFreeServiceContexts(void);
static BOOL ConsoleCtrlHandler( DWORD ctrl);
static DWORD WINAPI TwapiServiceMasterThread(LPVOID unused);
static int TwapiFindServiceIndex(const WCHAR *nameP);

int Twapi_SetServiceStatus(
    TwapiInterpContext *ticP,
    int objc,
    Tcl_Obj *CONST objv[])
{
................................................................................

    interp = ticP->interp;
    ERROR_IF_UNTHREADED(interp);

    if (objc < 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

    if (ObjToLong(interp, objv[0], &service_type) != TCL_OK)
        return TCL_ERROR;

    if (InterlockedCompareExchangePointer(&gServiceInterpContextP, ticP, NULL)
        != NULL) {
        ObjSetStaticResult(interp, "Twapi_BecomeAService multiple invocations.");
        return TCL_ERROR;
    }
................................................................................
    for (i = 0; i < gNumServiceContexts; ++i) {
        Tcl_Obj **objs;
        int       n;
        int       ctrls;
        WCHAR    *nameP;
        if (ObjGetElements(interp, objv[i+1], &n, &objs) != TCL_OK ||
            n != 2 ||
            ObjToLong(interp, objs[1], &ctrls) != TCL_OK) {
            ObjSetStaticResult(interp, "Invalid service specification.");
            goto error_handler;
        }
        /* Allocate a single block for the context and name */
        nameP = ObjToWinCharsN(objs[0], &n);
        gServiceContexts[i] = TwapiAlloc(SIZE_TwapiServiceContext(n));
        CopyMemory(gServiceContexts[i]->name, nameP, sizeof(WCHAR)*(n+1));
................................................................................
            // User defined
            ctrl_str = "userdefined";
            break;
        }
    }

    if (ctrl_str) {
        Tcl_Obj *objs[6];
        int nobjs = 0;
        objs[0] = STRING_LITERAL_OBJ(TWAPI_TCL_NAMESPACE "::_service_handler");
        objs[1] = ObjFromWinChars(gServiceContexts[cbP->service_index]->name);
        objs[2] = ObjFromOpaque(gServiceContexts[cbP->service_index]->service_status_handle, "SERVICE_STATUS_HANDLE");
        objs[3] = Tcl_NewStringObj(ctrl_str, -1);
        objs[4] = Tcl_NewLongObj(cbP->ctrl);
        nobjs = 5;
................................................................................
    }

    cbP = (TwapiServiceControlCallback *)
        TwapiCallbackNew(gServiceInterpContextP,
                                TwapiServiceControlCallbackFn,
                                sizeof(*cbP));





    cbP->service_index = service_index;
    cbP->ctrl = ctrl;
    cbP->event = event;
    cbP->additional_info = additional_info;
    if (need_response) {
        if (TwapiEnqueueCallback(gServiceInterpContextP,
                                 &cbP->cb,
................................................................................
                                 30*1000, /* TBD - Timeout (ms) */
                                 (TwapiCallback **)&cbP)
            == ERROR_SUCCESS) {
            if (cbP
                && (cbP->cb.response.type == TRT_DWORD ||
                    cbP->cb.response.type == TRT_LONG))
                status = cbP->cb.response.value.ival;
        } else {
            status = NO_ERROR;          /* Do not want to block queries that ask
                                           for permission */
        }
        if (cbP)
            TwapiCallbackUnref(&cbP->cb, 1);
    } else {

        /* TBD - in call below, on error, do we send an error notification ? */
        TwapiEnqueueCallback(gServiceInterpContextP, &cbP->cb,
                             TWAPI_ENQUEUE_DIRECT,
                             0, /* No response wanted */
                             NULL);
        status = NO_ERROR;
    }
    return status;
}

/*
 * Called by the SCM to start a particular service. It does the intitialization
 * and exits since the actual service work is done by the interp thread.
................................................................................

/*
 * This is the master thread for services. In a normal Windows service
 * application, this would be the main thread. Here, it gets started by
 * some interpreter thread. It calls the SCM which calls back into the
 * handlers.
 */
static DWORD WINAPI TwapiServiceMasterThread(LPVOID unused)
{
    SERVICE_TABLE_ENTRYW *steP;
    int i;

    /*
     * Construct the service descriptors to pass to the SCM. Note
     * the strings within the descriptors point to dynamically allocated







>
>
>
|
>







 







>
>

>
>
>
>





|







 







|







 







|







 







|







 







>
>
>
>







 







<
<
<




<





<







 







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
...
478
479
480
481
482
483
484



485
486
487
488

489
490
491
492
493

494
495
496
497
498
499
500
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
# include <process.h>
#endif
#include <dbt.h>                /* For DBT_* decls */

#include "twapi_service.h"

/* There can be only one....*/
#ifdef __GNUC__
static void * volatile gServiceInterpContextP;
#else
static TwapiInterpContext * volatile gServiceInterpContextP;
#endif

/* Structure to keep track of a particular service state */
typedef struct _TwapiServiceContext {
    SERVICE_STATUS_HANDLE service_status_handle; /* Must NEVER be closed! */
    DWORD   controls_accepted;   /* Controls accepted by the service */
    WCHAR   name[1];               /* Variable size, name of service */
} TwapiServiceContext;
................................................................................
 * Each individual element of gServiceContexts[] is only modified by
 * the specific thread running that service.
 * Hence no locks are required for this data.
 */
static TwapiServiceContext **gServiceContexts;
static int gNumServiceContexts;
DWORD  gServiceType;        /* own process or shared and whether interactive */
#if defined(TWAPI_REPLACE_CRT) || defined(TWAPI_MINIMIZE_CRT)
/* Using CreateThread */
DWORD  gServiceMasterThreadId;   /* Thread of service main program */
#else
/* Using _beginthreadex */
unsigned int gServiceMasterThreadId;   /* Thread of service main program */
#endif
HANDLE gServiceMasterThreadHandle;


static void TwapiFreeServiceContexts(void);
static BOOL ConsoleCtrlHandler( DWORD ctrl);
static unsigned int WINAPI TwapiServiceMasterThread(LPVOID unused);
static int TwapiFindServiceIndex(const WCHAR *nameP);

int Twapi_SetServiceStatus(
    TwapiInterpContext *ticP,
    int objc,
    Tcl_Obj *CONST objv[])
{
................................................................................

    interp = ticP->interp;
    ERROR_IF_UNTHREADED(interp);

    if (objc < 2)
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

    if (ObjToDWORD(interp, objv[0], &service_type) != TCL_OK)
        return TCL_ERROR;

    if (InterlockedCompareExchangePointer(&gServiceInterpContextP, ticP, NULL)
        != NULL) {
        ObjSetStaticResult(interp, "Twapi_BecomeAService multiple invocations.");
        return TCL_ERROR;
    }
................................................................................
    for (i = 0; i < gNumServiceContexts; ++i) {
        Tcl_Obj **objs;
        int       n;
        int       ctrls;
        WCHAR    *nameP;
        if (ObjGetElements(interp, objv[i+1], &n, &objs) != TCL_OK ||
            n != 2 ||
            ObjToInt(interp, objs[1], &ctrls) != TCL_OK) {
            ObjSetStaticResult(interp, "Invalid service specification.");
            goto error_handler;
        }
        /* Allocate a single block for the context and name */
        nameP = ObjToWinCharsN(objs[0], &n);
        gServiceContexts[i] = TwapiAlloc(SIZE_TwapiServiceContext(n));
        CopyMemory(gServiceContexts[i]->name, nameP, sizeof(WCHAR)*(n+1));
................................................................................
            // User defined
            ctrl_str = "userdefined";
            break;
        }
    }

    if (ctrl_str) {
        Tcl_Obj *objs[7];
        int nobjs = 0;
        objs[0] = STRING_LITERAL_OBJ(TWAPI_TCL_NAMESPACE "::_service_handler");
        objs[1] = ObjFromWinChars(gServiceContexts[cbP->service_index]->name);
        objs[2] = ObjFromOpaque(gServiceContexts[cbP->service_index]->service_status_handle, "SERVICE_STATUS_HANDLE");
        objs[3] = Tcl_NewStringObj(ctrl_str, -1);
        objs[4] = Tcl_NewLongObj(cbP->ctrl);
        nobjs = 5;
................................................................................
    }

    cbP = (TwapiServiceControlCallback *)
        TwapiCallbackNew(gServiceInterpContextP,
                                TwapiServiceControlCallbackFn,
                                sizeof(*cbP));

    /* Note unless the interp thread successfully responds with
       an status code, we assume status is NO_ERROR so as to not block
       notifications that need a response */
    status = NO_ERROR;
    cbP->service_index = service_index;
    cbP->ctrl = ctrl;
    cbP->event = event;
    cbP->additional_info = additional_info;
    if (need_response) {
        if (TwapiEnqueueCallback(gServiceInterpContextP,
                                 &cbP->cb,
................................................................................
                                 30*1000, /* TBD - Timeout (ms) */
                                 (TwapiCallback **)&cbP)
            == ERROR_SUCCESS) {
            if (cbP
                && (cbP->cb.response.type == TRT_DWORD ||
                    cbP->cb.response.type == TRT_LONG))
                status = cbP->cb.response.value.ival;



        }
        if (cbP)
            TwapiCallbackUnref(&cbP->cb, 1);
    } else {

        /* TBD - in call below, on error, do we send an error notification ? */
        TwapiEnqueueCallback(gServiceInterpContextP, &cbP->cb,
                             TWAPI_ENQUEUE_DIRECT,
                             0, /* No response wanted */
                             NULL);

    }
    return status;
}

/*
 * Called by the SCM to start a particular service. It does the intitialization
 * and exits since the actual service work is done by the interp thread.
................................................................................

/*
 * This is the master thread for services. In a normal Windows service
 * application, this would be the main thread. Here, it gets started by
 * some interpreter thread. It calls the SCM which calls back into the
 * handlers.
 */
static unsigned int WINAPI TwapiServiceMasterThread(LPVOID unused)
{
    SERVICE_TABLE_ENTRYW *steP;
    int i;

    /*
     * Construct the service descriptors to pass to the SCM. Note
     * the strings within the descriptors point to dynamically allocated

Changes to undroid/twapi/twapi/share/share.c.

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
...
523
524
525
526
527
528
529
530
531

532
533
534
535
536
537
538
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
...
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
...
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
...
895
896
897
898
899
900
901




902
903
904
905
906
907
908
...
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
....
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
....
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
....
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
    DWORD          parm_err;
    NET_API_STATUS status;
    SWSMark mark;

    CHECK_NARGS(interp, objc, 7);

    /* Extract integer args before WSTRs to avoid shimmering issues */
    CHECK_INTEGER_OBJ(interp, share_info.shi502_type, objv[2]);
    CHECK_INTEGER_OBJ(interp, share_info.shi502_max_uses, objv[4]);

    mark = SWSPushMark();
    if (ObjToPSECURITY_DESCRIPTORSWS(interp, objv[6], &secdP) != TCL_OK) {
        SWSPopMark(mark);
        return TCL_ERROR;
    }
    server_name = ObjToLPWSTR_NULL_IF_EMPTY(objv[0]);
................................................................................
}


int Twapi_WNetUseConnection(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    HWND          winH;
    LPWSTR  usernameP;
    int                   ignore_password;
    LPWSTR  passwordP, decrypted_password;
    int     password_len;
    DWORD   flags;
    WCHAR accessname[MAX_PATH];
    DWORD accessname_size;
    NETRESOURCEW netresource;
    DWORD       outflags;       /* Not really used */
    int         error;
    SWSMark mark = NULL;

    CHECK_NARGS(interp, objc, 9);
    /* TBD - what is the type of HWD ? SHould it not use ObjToHWND ? */
    if (ObjToHWND(interp, objv[0], &winH) != TCL_OK)
        return TCL_ERROR;
    CHECK_INTEGER_OBJ(interp, netresource.dwType, objv[1]);
    CHECK_INTEGER_OBJ(interp, ignore_password, objv[6]);
    CHECK_INTEGER_OBJ(interp, flags, objv[8]);
    netresource.lpLocalName = ObjToLPWSTR_NULL_IF_EMPTY(objv[2]);
    netresource.lpRemoteName = ObjToWinChars(objv[3]);
    netresource.lpProvider = ObjToLPWSTR_NULL_IF_EMPTY(objv[4]);
    usernameP = ObjToLPWSTR_NULL_IF_EMPTY(objv[5]);

    mark = SWSPushMark();
    decrypted_password = ObjDecryptPasswordSWS(objv[7], &password_len);
................................................................................
        return TCL_OK;
    }
    else {
        return Twapi_AppendWNetError(interp, error);
    }
}

static TCL_RESULT Twapi_WNetGetUniversalNameObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    int result;
    DWORD error;
    DWORD buf_sz;
    void *buf;
    LPCWSTR      localpathP;

    if (objc != 2)
................................................................................
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

    localpathP = ObjToWinChars(objv[1]);

    buf = MemLifoPushFrame(ticP->memlifoP, MAX_PATH+1, &buf_sz);
    error = WNetGetUniversalNameW(localpathP, REMOTE_NAME_INFO_LEVEL,
                                  buf, &buf_sz);
    if (error = ERROR_MORE_DATA) {
        /* Retry with larger buffer */
        buf = MemLifoAlloc(ticP->memlifoP, buf_sz, NULL);
        error = WNetGetUniversalNameW(localpathP, REMOTE_NAME_INFO_LEVEL,
                                      buf, &buf_sz);
    }
    if (error == NO_ERROR) {
        ObjSetResult(ticP->interp,
................................................................................
    }

    MemLifoPopFrame(ticP->memlifoP);

    return result;
}

static TCL_RESULT Twapi_WNetGetResourceInformationObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    NETRESOURCEW in;
    NETRESOURCEW *outP;
    DWORD       outsz;
    int         error;
    LPWSTR      systempart;
    Tcl_Obj    *objs[2];
    MemLifoMarkHandle mark;
................................................................................
    }

    MemLifoPopMark(mark);
    return res;
}


static TCL_RESULT Twapi_WNetAddConnection3ObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    TCL_RESULT res;
    DWORD       flags, wnet_status, sz;
    MemLifoMarkHandle mark;
    LPCWSTR     username;
    HWND hwnd;
    WCHAR         *decryptedP;
    int            decrypted_len;
................................................................................
                         ARGSKIP,
                         ARGSKIP,
                         GETWSTR(username),
                         GETINT(flags),
                         ARGEND);
    if (res == TCL_OK) {
        res = TwapiCStructParse(interp, ticP->memlifoP, objv[2],
                                0, &sz, &netresP);
        if (res == TCL_OK) {
            if (sz != sizeof(NETRESOURCEW))
                res = TwapiReturnError(interp, TWAPI_INVALID_ARGS);
            else {
                TWAPI_ASSERT(ticP->memlifoP == SWS());
                decryptedP = ObjDecryptPasswordSWS(objv[3], &decrypted_len);
                wnet_status = WNetAddConnection3W(hwnd, netresP,
................................................................................
            &netenum.netbufP,
            MAX_PREFERRED_LENGTH,
            &netenum.entriesread,
            &netenum.totalentries,
            &dwresume);
        netenum.hresume = dwresume;
        break;




    }

    if (netenum.status != NERR_Success && netenum.status != ERROR_MORE_DATA) {
        Twapi_AppendSystemError(interp, netenum.status);
        goto error_return;
    }

................................................................................
    case 2:
        return Twapi_NetShareAdd(interp, objc, objv);
    case 3:
        CHECK_NARGS(interp, objc, 1);
        return Twapi_WNetGetUser(interp, ObjToWinChars(objv[0]));
    case 4: // NetFileClose
        CHECK_NARGS(interp, objc, 2);
        CHECK_INTEGER_OBJ(interp, dw, objv[1]);
        result.type = TRT_EXCEPTION_ON_ERROR;
        result.value.ival = NetFileClose(ObjToLPWSTR_NULL_IF_EMPTY(objv[0]), dw);
        break;
    case 5:
    case 6:
        if (TwapiGetArgs(interp, objc-1, objv+1, GETINT(dw), GETINT(dw2),
                         ARGEND) != TCL_OK)
................................................................................
        } else {
            NULLIFY_EMPTY(s);
            return Twapi_NetFileGetInfo(interp, s, dw, dw2);
        }
        break;
    case 7: // NetShareSetInfo
        CHECK_NARGS(interp, objc, 5);
        CHECK_INTEGER_OBJ(interp, dw, objv[3]);
        mark = SWSPushMark();
        res = ObjToPSECURITY_DESCRIPTORSWS(interp, objv[4], &secdP);
        /* Note secdP may be NULL even on success */
        if (res == TCL_OK) {
            res = Twapi_NetShareSetInfo(interp,
                                        ObjToWinChars(objv[0]),
                                        ObjToWinChars(objv[1]),
................................................................................
    case 9:
    case 10:
    case 11:
        CHECK_NARGS_RANGE(interp, objc, 2, 3);
        if (objc == 2)
            dw = 0;
        else {
            CHECK_INTEGER_OBJ(interp, dw, objv[2]);
        }
        s = ObjToLPWSTR_NULL_IF_EMPTY(objv[0]);
        s2 = ObjToWinChars(objv[1]);
        switch (func) {
        case 8:
            return Twapi_NetUseGetInfo(interp, s, s2, dw);
        case 9:
................................................................................
        result.value.ival = NetSessionDel(
            ObjToLPWSTR_NULL_IF_EMPTY(objv[0]),
            ObjToLPWSTR_NULL_IF_EMPTY(objv[1]),
            ObjToLPWSTR_NULL_IF_EMPTY(objv[2]));
        break;
    case 13:
        CHECK_NARGS(interp, objc, 4);
        CHECK_INTEGER_OBJ(interp, dw, objv[3]);
        return Twapi_NetSessionGetInfo(interp,
                                       ObjToLPWSTR_NULL_IF_EMPTY(objv[0]),
                                       ObjToWinChars(objv[1]),
                                       ObjToWinChars(objv[2]),
                                       dw);
    case 14: // WNetOpenEnum
        if (TwapiGetArgs(interp, objc, objv,
                         GETINT(dw), GETINT(dw2), GETINT(dw3),
                         ARGSKIP, ARGEND) != TCL_OK)
            return TCL_ERROR;
        mark = SWSPushMark();
        res = TwapiCStructParse(interp, SWS(), objv[3], CSTRUCT_ALLOW_NULL, &dw4, &netresP);
        if (res == TCL_OK) {
            if (netresP && dw4 != sizeof(NETRESOURCEW))
                res = TwapiReturnError(interp, TWAPI_INVALID_ARGS);
            else {
                result.value.ival = WNetOpenEnumW(dw, dw2, dw3, netresP, &h);
                if (result.value.ival != NO_ERROR) {
                    /* Don't change res. Error will be set by TwapiSetResult */
................................................................................
        } else
            result.type = TRT_EXCEPTION_ON_WNET_ERROR;

        break;

    case 18: // WNetGetProviderName
        CHECK_NARGS(interp, objc, 1);
        CHECK_INTEGER_OBJ(interp, dw, objv[0]);
        mark = SWSPushMark();
        dw2 = MAX_PATH;
        s = SWSAlloc(sizeof(WCHAR)*dw2, NULL);
        result.value.ival = WNetGetProviderNameW(dw, s, &dw2);
        if (result.value.ival == NO_ERROR) {
            result.type = TRT_UNICODE;
            result.value.unicode.str = s;







|
|







 







<


|











|
|
|







 







|

>







 







|







 







|

>







 







|

>







 







|







 







>
>
>
>







 







|







 







|







 







|







 







|











|







 







|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
474
475
476
477
478
479
480

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
...
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
...
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
...
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
...
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
....
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
....
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
....
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
    DWORD          parm_err;
    NET_API_STATUS status;
    SWSMark mark;

    CHECK_NARGS(interp, objc, 7);

    /* Extract integer args before WSTRs to avoid shimmering issues */
    CHECK_DWORD_OBJ(interp, share_info.shi502_type, objv[2]);
    CHECK_DWORD_OBJ(interp, share_info.shi502_max_uses, objv[4]);

    mark = SWSPushMark();
    if (ObjToPSECURITY_DESCRIPTORSWS(interp, objv[6], &secdP) != TCL_OK) {
        SWSPopMark(mark);
        return TCL_ERROR;
    }
    server_name = ObjToLPWSTR_NULL_IF_EMPTY(objv[0]);
................................................................................
}


int Twapi_WNetUseConnection(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    HWND          winH;
    LPWSTR  usernameP;

    LPWSTR  passwordP, decrypted_password;
    int     password_len;
    DWORD   ignore_password, flags;
    WCHAR accessname[MAX_PATH];
    DWORD accessname_size;
    NETRESOURCEW netresource;
    DWORD       outflags;       /* Not really used */
    int         error;
    SWSMark mark = NULL;

    CHECK_NARGS(interp, objc, 9);
    /* TBD - what is the type of HWD ? SHould it not use ObjToHWND ? */
    if (ObjToHWND(interp, objv[0], &winH) != TCL_OK)
        return TCL_ERROR;
    CHECK_DWORD_OBJ(interp, netresource.dwType, objv[1]);
    CHECK_DWORD_OBJ(interp, ignore_password, objv[6]);
    CHECK_DWORD_OBJ(interp, flags, objv[8]);
    netresource.lpLocalName = ObjToLPWSTR_NULL_IF_EMPTY(objv[2]);
    netresource.lpRemoteName = ObjToWinChars(objv[3]);
    netresource.lpProvider = ObjToLPWSTR_NULL_IF_EMPTY(objv[4]);
    usernameP = ObjToLPWSTR_NULL_IF_EMPTY(objv[5]);

    mark = SWSPushMark();
    decrypted_password = ObjDecryptPasswordSWS(objv[7], &password_len);
................................................................................
        return TCL_OK;
    }
    else {
        return Twapi_AppendWNetError(interp, error);
    }
}

static TCL_RESULT Twapi_WNetGetUniversalNameObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    int result;
    DWORD error;
    DWORD buf_sz;
    void *buf;
    LPCWSTR      localpathP;

    if (objc != 2)
................................................................................
        return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

    localpathP = ObjToWinChars(objv[1]);

    buf = MemLifoPushFrame(ticP->memlifoP, MAX_PATH+1, &buf_sz);
    error = WNetGetUniversalNameW(localpathP, REMOTE_NAME_INFO_LEVEL,
                                  buf, &buf_sz);
    if (error == ERROR_MORE_DATA) {
        /* Retry with larger buffer */
        buf = MemLifoAlloc(ticP->memlifoP, buf_sz, NULL);
        error = WNetGetUniversalNameW(localpathP, REMOTE_NAME_INFO_LEVEL,
                                      buf, &buf_sz);
    }
    if (error == NO_ERROR) {
        ObjSetResult(ticP->interp,
................................................................................
    }

    MemLifoPopFrame(ticP->memlifoP);

    return result;
}

static TCL_RESULT Twapi_WNetGetResourceInformationObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    NETRESOURCEW in;
    NETRESOURCEW *outP;
    DWORD       outsz;
    int         error;
    LPWSTR      systempart;
    Tcl_Obj    *objs[2];
    MemLifoMarkHandle mark;
................................................................................
    }

    MemLifoPopMark(mark);
    return res;
}


static TCL_RESULT Twapi_WNetAddConnection3ObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    TCL_RESULT res;
    DWORD       flags, wnet_status, sz;
    MemLifoMarkHandle mark;
    LPCWSTR     username;
    HWND hwnd;
    WCHAR         *decryptedP;
    int            decrypted_len;
................................................................................
                         ARGSKIP,
                         ARGSKIP,
                         GETWSTR(username),
                         GETINT(flags),
                         ARGEND);
    if (res == TCL_OK) {
        res = TwapiCStructParse(interp, ticP->memlifoP, objv[2],
                                0, &sz, (void **) &netresP);
        if (res == TCL_OK) {
            if (sz != sizeof(NETRESOURCEW))
                res = TwapiReturnError(interp, TWAPI_INVALID_ARGS);
            else {
                TWAPI_ASSERT(ticP->memlifoP == SWS());
                decryptedP = ObjDecryptPasswordSWS(objv[3], &decrypted_len);
                wnet_status = WNetAddConnection3W(hwnd, netresP,
................................................................................
            &netenum.netbufP,
            MAX_PREFERRED_LENGTH,
            &netenum.entriesread,
            &netenum.totalentries,
            &dwresume);
        netenum.hresume = dwresume;
        break;

    default:
        TwapiReturnError(interp, TWAPI_INVALID_ARGS);
        goto error_return;
    }

    if (netenum.status != NERR_Success && netenum.status != ERROR_MORE_DATA) {
        Twapi_AppendSystemError(interp, netenum.status);
        goto error_return;
    }

................................................................................
    case 2:
        return Twapi_NetShareAdd(interp, objc, objv);
    case 3:
        CHECK_NARGS(interp, objc, 1);
        return Twapi_WNetGetUser(interp, ObjToWinChars(objv[0]));
    case 4: // NetFileClose
        CHECK_NARGS(interp, objc, 2);
        CHECK_DWORD_OBJ(interp, dw, objv[1]);
        result.type = TRT_EXCEPTION_ON_ERROR;
        result.value.ival = NetFileClose(ObjToLPWSTR_NULL_IF_EMPTY(objv[0]), dw);
        break;
    case 5:
    case 6:
        if (TwapiGetArgs(interp, objc-1, objv+1, GETINT(dw), GETINT(dw2),
                         ARGEND) != TCL_OK)
................................................................................
        } else {
            NULLIFY_EMPTY(s);
            return Twapi_NetFileGetInfo(interp, s, dw, dw2);
        }
        break;
    case 7: // NetShareSetInfo
        CHECK_NARGS(interp, objc, 5);
        CHECK_DWORD_OBJ(interp, dw, objv[3]);
        mark = SWSPushMark();
        res = ObjToPSECURITY_DESCRIPTORSWS(interp, objv[4], &secdP);
        /* Note secdP may be NULL even on success */
        if (res == TCL_OK) {
            res = Twapi_NetShareSetInfo(interp,
                                        ObjToWinChars(objv[0]),
                                        ObjToWinChars(objv[1]),
................................................................................
    case 9:
    case 10:
    case 11:
        CHECK_NARGS_RANGE(interp, objc, 2, 3);
        if (objc == 2)
            dw = 0;
        else {
            CHECK_DWORD_OBJ(interp, dw, objv[2]);
        }
        s = ObjToLPWSTR_NULL_IF_EMPTY(objv[0]);
        s2 = ObjToWinChars(objv[1]);
        switch (func) {
        case 8:
            return Twapi_NetUseGetInfo(interp, s, s2, dw);
        case 9:
................................................................................
        result.value.ival = NetSessionDel(
            ObjToLPWSTR_NULL_IF_EMPTY(objv[0]),
            ObjToLPWSTR_NULL_IF_EMPTY(objv[1]),
            ObjToLPWSTR_NULL_IF_EMPTY(objv[2]));
        break;
    case 13:
        CHECK_NARGS(interp, objc, 4);
        CHECK_DWORD_OBJ(interp, dw, objv[3]);
        return Twapi_NetSessionGetInfo(interp,
                                       ObjToLPWSTR_NULL_IF_EMPTY(objv[0]),
                                       ObjToWinChars(objv[1]),
                                       ObjToWinChars(objv[2]),
                                       dw);
    case 14: // WNetOpenEnum
        if (TwapiGetArgs(interp, objc, objv,
                         GETINT(dw), GETINT(dw2), GETINT(dw3),
                         ARGSKIP, ARGEND) != TCL_OK)
            return TCL_ERROR;
        mark = SWSPushMark();
        res = TwapiCStructParse(interp, SWS(), objv[3], CSTRUCT_ALLOW_NULL, &dw4, (void **) &netresP);
        if (res == TCL_OK) {
            if (netresP && dw4 != sizeof(NETRESOURCEW))
                res = TwapiReturnError(interp, TWAPI_INVALID_ARGS);
            else {
                result.value.ival = WNetOpenEnumW(dw, dw2, dw3, netresP, &h);
                if (result.value.ival != NO_ERROR) {
                    /* Don't change res. Error will be set by TwapiSetResult */
................................................................................
        } else
            result.type = TRT_EXCEPTION_ON_WNET_ERROR;

        break;

    case 18: // WNetGetProviderName
        CHECK_NARGS(interp, objc, 1);
        CHECK_DWORD_OBJ(interp, dw, objv[0]);
        mark = SWSPushMark();
        dw2 = MAX_PATH;
        s = SWSAlloc(sizeof(WCHAR)*dw2, NULL);
        result.value.ival = WNetGetProviderNameW(dw, s, &dw2);
        if (result.value.ival == NO_ERROR) {
            result.type = TRT_UNICODE;
            result.value.unicode.str = s;

Changes to undroid/twapi/twapi/shell/shell.c.

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
...
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
...
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
...
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
    return &shellver;
}

int Twapi_GetShellVersion(Tcl_Interp *interp)
{
    DLLVERSIONINFO *ver = TwapiShellVersion();
    ObjSetResult(interp,
                     Tcl_ObjPrintf("%u.%u.%u",
                                   ver->dwMajorVersion,
                                   ver->dwMinorVersion,
                                   ver->dwBuildNumber));
    return TCL_OK;
}


................................................................................
    }

    return (*fnSHObjectProperties)(hwnd, dwType, szObject, szPage);
}

// Create a shell link
static TCL_RESULT Twapi_WriteShortcutObjCmd(
    TwapiInterpContext *ticP,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{

    LPCWSTR linkPath;
    LPCWSTR objPath;
    LPITEMIDLIST itemIds;
    LPCWSTR commandArgs;
    LPCWSTR desc;
    WORD    hotkey;
    LPCWSTR iconPath;
................................................................................
vamoose:
    if (mark)
        SWSPopMark(mark);

    return res;
}

static TCL_RESULT Twapi_ShellExecuteExObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    LPCWSTR lpClass;
    HKEY hkeyClass;
    DWORD dwHotKey;
    HANDLE hIconOrMonitor;
    TCL_RESULT res;
    SHELLEXECUTEINFOW sei;
    MemLifoMarkHandle mark;
................................................................................
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = dw;
        }
        break;

    case 10: // Shell_NotifyIcon
        CHECK_NARGS(interp, objc, 2);
        CHECK_INTEGER_OBJ(interp, dw, objv[0]);
        u.niP = (NOTIFYICONDATAW *) ObjToByteArray(objv[1], &dw2);
        if (dw2 != sizeof(NOTIFYICONDATAW) || dw2 != u.niP->cbSize) {
            return TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Inconsistent size of NOTIFYICONDATAW structure.");
        }
        result.type = TRT_EMPTY;
        if (Shell_NotifyIconW(dw, u.niP) == FALSE) {
            result.type = TRT_GETLASTERROR;
        }







|







 







|




>







 







|

>







 







|
|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
...
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
    return &shellver;
}

int Twapi_GetShellVersion(Tcl_Interp *interp)
{
    DLLVERSIONINFO *ver = TwapiShellVersion();
    ObjSetResult(interp,
                     Tcl_ObjPrintf("%lu.%lu.%lu",
                                   ver->dwMajorVersion,
                                   ver->dwMinorVersion,
                                   ver->dwBuildNumber));
    return TCL_OK;
}


................................................................................
    }

    return (*fnSHObjectProperties)(hwnd, dwType, szObject, szPage);
}

// Create a shell link
static TCL_RESULT Twapi_WriteShortcutObjCmd(
    ClientData clientdata,
    Tcl_Interp *interp,
    int  objc,
    Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    LPCWSTR linkPath;
    LPCWSTR objPath;
    LPITEMIDLIST itemIds;
    LPCWSTR commandArgs;
    LPCWSTR desc;
    WORD    hotkey;
    LPCWSTR iconPath;
................................................................................
vamoose:
    if (mark)
        SWSPopMark(mark);

    return res;
}

static TCL_RESULT Twapi_ShellExecuteExObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    LPCWSTR lpClass;
    HKEY hkeyClass;
    DWORD dwHotKey;
    HANDLE hIconOrMonitor;
    TCL_RESULT res;
    SHELLEXECUTEINFOW sei;
    MemLifoMarkHandle mark;
................................................................................
            result.type = TRT_EXCEPTION_ON_ERROR;
            result.value.ival = dw;
        }
        break;

    case 10: // Shell_NotifyIcon
        CHECK_NARGS(interp, objc, 2);
        CHECK_DWORD_OBJ(interp, dw, objv[0]);
        u.niP = (NOTIFYICONDATAW *) ObjToByteArrayDW(objv[1], &dw2);
        if (dw2 != sizeof(NOTIFYICONDATAW) || dw2 != u.niP->cbSize) {
            return TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Inconsistent size of NOTIFYICONDATAW structure.");
        }
        result.type = TRT_EMPTY;
        if (Shell_NotifyIconW(dw, u.niP) == FALSE) {
            result.type = TRT_GETLASTERROR;
        }

Changes to undroid/twapi/twapi/storage/dirmonitor.c.

26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
...
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
...
510
511
512
513
514
515
516

517
518
519
520
521

522





523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
static void CALLBACK TwapiDirectoryMonitorThreadPoolFn(
    PVOID lpParameter,
    BOOLEAN TimerOrWaitFired
);
static int TwapiDirectoryMonitorCallbackFn(TwapiCallback *p);
static int TwapiDirectoryMonitorPatternMatch(WCHAR *path, WCHAR *pattern);

TCL_RESULT Twapi_RegisterDirectoryMonitorObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    TwapiDirectoryMonitorContext *dmcP;
    LPWSTR pathP;
    int    path_len;
    int    include_subtree;
    int    npatterns;
    WCHAR  **patterns;
    DWORD  winerr;
................................................................................
system_error:
    /* winerr should contain system error, waits should not registered */
    TwapiShutdownDirectoryMonitor(dmcP);
    return Twapi_AppendSystemError(interp, winerr);
}


TCL_RESULT Twapi_UnregisterDirectoryMonitorObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    HANDLE dirhandle;
    TwapiDirectoryMonitorContext *dmcP;

    if (TwapiGetArgs(interp, objc-1, objv+1, GETHANDLE(dirhandle),
                     ARGEND) != TCL_OK)
        return TCL_ERROR;

................................................................................
                ObjDecrRefs(fnObj[1]);
            fnObj[1] = ObjFromWinCharsN(fniP->FileName, fniP->FileNameLength/2);
            if (dmcP->npatterns == 0)
                pattern_matched = 1; /* No pattern so match everything */
            else {
                /* Need to match on pattern */
                int i;

                for (i = 0; i < dmcP->npatterns; ++i) {
                    int matched = TwapiDirectoryMonitorPatternMatch(
                        ObjToWinChars(fnObj[1]),
                        dmcP->patterns[i]);
                    if (matched) {

                        /* Matches can be inclusive or exclusive */





                        pattern_matched = (matched > 0);
                        break;
                    }
                }
                if (i == dmcP->npatterns) {
                    /*
                     * No match. Try next name. Note fnObj will be released

                     * later if necessary or reused in next iteration
                     */
                    pattern_matched = 0;
                }
            }

            if (pattern_matched) {
                /*
                 * We reuse the action names instead of allocating new ones. Much
                 * more efficient in space and time when many notifications.
                 */







|

>







 







|

>







 







>





>
|
>
>
>
>
>




<
|
<
>
|
|
<
<







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535

536

537
538
539


540
541
542
543
544
545
546
static void CALLBACK TwapiDirectoryMonitorThreadPoolFn(
    PVOID lpParameter,
    BOOLEAN TimerOrWaitFired
);
static int TwapiDirectoryMonitorCallbackFn(TwapiCallback *p);
static int TwapiDirectoryMonitorPatternMatch(WCHAR *path, WCHAR *pattern);

TCL_RESULT Twapi_RegisterDirectoryMonitorObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    TwapiDirectoryMonitorContext *dmcP;
    LPWSTR pathP;
    int    path_len;
    int    include_subtree;
    int    npatterns;
    WCHAR  **patterns;
    DWORD  winerr;
................................................................................
system_error:
    /* winerr should contain system error, waits should not registered */
    TwapiShutdownDirectoryMonitor(dmcP);
    return Twapi_AppendSystemError(interp, winerr);
}


TCL_RESULT Twapi_UnregisterDirectoryMonitorObjCmd(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    HANDLE dirhandle;
    TwapiDirectoryMonitorContext *dmcP;

    if (TwapiGetArgs(interp, objc-1, objv+1, GETHANDLE(dirhandle),
                     ARGEND) != TCL_OK)
        return TCL_ERROR;

................................................................................
                ObjDecrRefs(fnObj[1]);
            fnObj[1] = ObjFromWinCharsN(fniP->FileName, fniP->FileNameLength/2);
            if (dmcP->npatterns == 0)
                pattern_matched = 1; /* No pattern so match everything */
            else {
                /* Need to match on pattern */
                int i;
                pattern_matched = 0;
                for (i = 0; i < dmcP->npatterns; ++i) {
                    int matched = TwapiDirectoryMonitorPatternMatch(
                        ObjToWinChars(fnObj[1]),
                        dmcP->patterns[i]);
                    if (matched) {
                        /* 
                         * Matches can be inclusive or exclusive. If 
                         * inclusive (matched > 0), the pattern matches
                         * and no need to check additional patterns.
                         * If exclusive, it does not match AND we should not
                         * check additional patterns.
                         */
                        pattern_matched = (matched > 0);
                        break;
                    }
                }

                /*

                 * Note if no match we will try next name. fnObj[1] will
                 * be released later if necessary or reused in next iteration
                 */


            }

            if (pattern_matched) {
                /*
                 * We reuse the action names instead of allocating new ones. Much
                 * more efficient in space and time when many notifications.
                 */

Changes to undroid/twapi/twapi/storage/storage.c.

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
            NULLIFY_EMPTY(s);
            return Twapi_GetVolumeInformation(interp, s);
        case 9:
            return TwapiFirstVolume(interp, s);
        case 10:
            return Twapi_GetDiskFreeSpaceEx(interp, s);
        case 11: // GetCompressedFileSize
            largeint.u.LowPart = GetCompressedFileSizeW(s, &largeint.u.HighPart);
            if (largeint.u.LowPart == INVALID_FILE_SIZE) {
                /* Does not mean failure, have to actually check */
                dw = GetLastError();
                if (dw != NO_ERROR) {
                    result.value.ival = dw;
                    result.type = TRT_EXCEPTION_ON_ERROR;
                    break;
................................................................................
    case 19:
    case 20:
    case 21:
        CHECK_NARGS_RANGE(interp, objc, 2, 3);
        if (objc == 2)
            dw = 0;
        else {
            CHECK_INTEGER_OBJ(interp, dw, objv[2]);
        }
        s = ObjToWinChars(objv[0]);
        s2 = ObjToWinChars(objv[1]);
        switch (func) {
        case 19:
            NULLIFY_EMPTY(s2);
            result.type = TRT_EXCEPTION_ON_FALSE;
................................................................................
            }
        }
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival = SetFileTime(h, ftP[0], ftP[1], ftP[2]);
        break;
    case 23:
        CHECK_NARGS(interp, objc, 3);
        CHECK_INTEGER_OBJ(interp, dw, objv[0]);
        if (TwapiGetArgs(interp, objc, objv,
                         GETINT(dw), ARGSKIP, ARGSKIP, ARGEND) != TCL_OK)
            return TCL_ERROR;
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival =
            DefineDosDeviceW(dw, ObjToWinChars(objv[1]),
                             ObjToLPWSTR_NULL_IF_EMPTY(objv[2]));







|







 







|







 







|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
            NULLIFY_EMPTY(s);
            return Twapi_GetVolumeInformation(interp, s);
        case 9:
            return TwapiFirstVolume(interp, s);
        case 10:
            return Twapi_GetDiskFreeSpaceEx(interp, s);
        case 11: // GetCompressedFileSize
            largeint.u.LowPart = GetCompressedFileSizeW(s, (LPDWORD) &largeint.u.HighPart);
            if (largeint.u.LowPart == INVALID_FILE_SIZE) {
                /* Does not mean failure, have to actually check */
                dw = GetLastError();
                if (dw != NO_ERROR) {
                    result.value.ival = dw;
                    result.type = TRT_EXCEPTION_ON_ERROR;
                    break;
................................................................................
    case 19:
    case 20:
    case 21:
        CHECK_NARGS_RANGE(interp, objc, 2, 3);
        if (objc == 2)
            dw = 0;
        else {
            CHECK_DWORD_OBJ(interp, dw, objv[2]);
        }
        s = ObjToWinChars(objv[0]);
        s2 = ObjToWinChars(objv[1]);
        switch (func) {
        case 19:
            NULLIFY_EMPTY(s2);
            result.type = TRT_EXCEPTION_ON_FALSE;
................................................................................
            }
        }
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival = SetFileTime(h, ftP[0], ftP[1], ftP[2]);
        break;
    case 23:
        CHECK_NARGS(interp, objc, 3);
        CHECK_DWORD_OBJ(interp, dw, objv[0]);
        if (TwapiGetArgs(interp, objc, objv,
                         GETINT(dw), ARGSKIP, ARGSKIP, ARGEND) != TCL_OK)
            return TCL_ERROR;
        result.type = TRT_EXCEPTION_ON_FALSE;
        result.value.ival =
            DefineDosDeviceW(dw, ObjToWinChars(objv[1]),
                             ObjToLPWSTR_NULL_IF_EMPTY(objv[2]));

Changes to undroid/twapi/twapi/storage/twapi_storage.h.

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
..
89
90
91
92
93
94
95
96
97
98
99
100
 */
typedef struct _TwapiDirectoryMonitorContext {
    TwapiInterpContext *ticP;
    HANDLE  directory_handle;   /* Handle to dir we are monitoring */
    HANDLE  thread_pool_registry_handle; /* Handle returned by thread pool */
    HANDLE  completion_event;            /* Used for i/o signaling */
    ZLINK_DECL(TwapiDirectoryMonitorContext);
    ULONG volatile nrefs;              /* Ref count */
    TwapiDirectoryMonitorBuffer *iobP; /* Used for actual reads. IMPORTANT -
                                          if not NULL, and iobP->ovl.hEvent
                                          is not NULL, READ is in progress
                                          and even when closing handle
                                          we have to wait for event to be
                                          signalled.
                                       */
................................................................................
    int     include_subtree;
    int     npatterns;
    WCHAR  *patterns[1];
    /* VARIABLE SIZE AREA FOLLOWS */
} TwapiDirectoryMonitorContext;


TCL_RESULT Twapi_RegisterDirectoryMonitorObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
TCL_RESULT Twapi_UnregisterDirectoryMonitorObjCmd(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
int TwapiShutdownDirectoryMonitor(TwapiDirectoryMonitorContext *);

#endif







|







 







|
|



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
..
89
90
91
92
93
94
95
96
97
98
99
100
 */
typedef struct _TwapiDirectoryMonitorContext {
    TwapiInterpContext *ticP;
    HANDLE  directory_handle;   /* Handle to dir we are monitoring */
    HANDLE  thread_pool_registry_handle; /* Handle returned by thread pool */
    HANDLE  completion_event;            /* Used for i/o signaling */
    ZLINK_DECL(TwapiDirectoryMonitorContext);
    long volatile nrefs;              /* Ref count */
    TwapiDirectoryMonitorBuffer *iobP; /* Used for actual reads. IMPORTANT -
                                          if not NULL, and iobP->ovl.hEvent
                                          is not NULL, READ is in progress
                                          and even when closing handle
                                          we have to wait for event to be
                                          signalled.
                                       */
................................................................................
    int     include_subtree;
    int     npatterns;
    WCHAR  *patterns[1];
    /* VARIABLE SIZE AREA FOLLOWS */
} TwapiDirectoryMonitorContext;


TwapiTclObjCmd Twapi_RegisterDirectoryMonitorObjCmd;
TwapiTclObjCmd Twapi_UnregisterDirectoryMonitorObjCmd;
int TwapiShutdownDirectoryMonitor(TwapiDirectoryMonitorContext *);

#endif

Changes to undroid/twapi/twapi/ui/gdi.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    int      objc;

    objc = 3;
    objv[0] = ObjFromRECT(&miP->rcMonitor);
    objv[1] = ObjFromRECT(&miP->rcWork);
    objv[2] = Tcl_NewLongObj(miP->dwFlags);
    /* miP could be either a MONITORINFO or MONITORINFOEX or MONITORINFOEXW */
    if (miP->cbSize == sizeof(MONITORINFOEX)) {
        objv[3] = Tcl_NewStringObj(((MONITORINFOEX *)miP)->szDevice, -1);
        objc = 4;
    }
    else if (miP->cbSize == sizeof(MONITORINFOEXW)) {
        objv[3] = ObjFromWinChars(((MONITORINFOEXW *)miP)->szDevice);
        objc = 4;
    }








|
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    int      objc;

    objc = 3;
    objv[0] = ObjFromRECT(&miP->rcMonitor);
    objv[1] = ObjFromRECT(&miP->rcWork);
    objv[2] = Tcl_NewLongObj(miP->dwFlags);
    /* miP could be either a MONITORINFO or MONITORINFOEX or MONITORINFOEXW */
    if (miP->cbSize == sizeof(MONITORINFOEXA)) {
        objv[3] = Tcl_NewStringObj(((MONITORINFOEXA *)miP)->szDevice, -1);
        objc = 4;
    }
    else if (miP->cbSize == sizeof(MONITORINFOEXW)) {
        objv[3] = ObjFromWinChars(((MONITORINFOEXW *)miP)->szDevice);
        objc = 4;
    }

Changes to undroid/twapi/twapi/ui/ui.c.

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364



365
366
367
368
369
370
371
...
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
...
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
    if (ObjGetElements(interp, obj, &objc, &objv) == TCL_ERROR) {
        return TCL_ERROR;
    }

    fwP->cbSize = sizeof(*fwP);
    if (objc == 4 &&
        (ObjToHWND(interp, objv[0], &hwnd) == TCL_OK) &&
        (ObjToLong(interp, objv[1], &fwP->dwFlags) == TCL_OK) &&
        (ObjToLong(interp, objv[2], &fwP->uCount) == TCL_OK) &&
        (ObjToLong(interp, objv[3], &fwP->dwTimeout) == TCL_OK)) {
        fwP->hwnd = (HWND) hwnd;
        return TCL_OK;
    }

    ObjSetStaticResult(interp, "Invalid FLASHWINFO structure. Need 4 elements - window handle, flags, count and timeout.");
    return TCL_ERROR;
}
................................................................................

    if (ObjGetElements(interp, objP, &objc, &objv) != TCL_OK)
        return TCL_ERROR;

    if (objc != 5)
        return TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Incorrect format of WINDOWPLACEMENT argument.");

    if (ObjToLong(interp, objv[0], &wpP->flags) != TCL_OK ||
        ObjToLong(interp, objv[1], &wpP->showCmd) != TCL_OK ||
        ObjToPOINT(interp, objv[2], &wpP->ptMinPosition) != TCL_OK ||
        ObjToPOINT(interp, objv[3], &wpP->ptMaxPosition) != TCL_OK ||
        ObjToRECT(interp, objv[4], &wpP->rcNormalPosition) != TCL_OK) {
        return TCL_ERROR;
    }

    wpP->length = sizeof(*wpP);
................................................................................
    --objc;
    ++objv;

    result.type = TRT_BADFUNCTIONCODE;
    if (func < 1000) {
        /* Functions taking no arguments */

        HWND (WINAPI *hfn)(void) = NULL;
        DWORD (WINAPI *dfn)() = NULL;

        if (objc != 0)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        switch (func) {
        case 1:
        case 2:
            result.type = (func == 1 ? GetCursorPos : GetCaretPos) (&result.value.point) ? TRT_POINT : TRT_GETLASTERROR;
            break;
        case 3: dfn = GetCaretBlinkTime; break;
        case 4: hfn = GetFocus; break;
        case 5: hfn = GetDesktopWindow; break;
        case 6: hfn = GetShellWindow; break;
        case 7: hfn = GetForegroundWindow; break;
        case 8: hfn = GetActiveWindow; break;
        case 9: dfn = IsThemeActive; break;
        case 10: dfn = IsAppThemed; break;
        case 11:
            return Twapi_GetCurrentThemeName(interp);
        }
        if (hfn) {
            result.type = TRT_HWND;
            result.value.hwin = hfn();
        } else if (dfn) {
            result.type = TRT_DWORD;
            result.value.uval = dfn();



        }
    } else if (func < 2000) {
        /* Exactly one arg */
        if (objc != 1)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

        switch (func) {
................................................................................
        return TCL_ERROR;

    objc -= 2;
    objv += 2;
    result.type = TRT_BADFUNCTIONCODE;
    if (func < 500) {
        BOOL (WINAPI *bfn)(HWND) = NULL;
        DWORD (WINAPI *dfn)(HWND) = NULL;

        if (objc != 0)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

        switch (func) {
        case 1: bfn = IsIconic; break;
        case 2: bfn = IsZoomed; break;
        case 3: bfn = IsWindowVisible; break;
        case 4: bfn = IsWindow; break;
        case 5: bfn = IsWindowUnicode; break;
        case 6: bfn = IsWindowEnabled; break;
        case 7: bfn = ArrangeIconicWindows; break;
        case 8: bfn = SetForegroundWindow; break;
        case 9: dfn = OpenIcon; break;
        case 10: dfn = CloseWindow; break;
        case 11: dfn = DestroyWindow; break;
        case 12: dfn = UpdateWindow; break;
        case 13: dfn = HideCaret; break;
        case 14: dfn = ShowCaret; break;
        case 15:
            result.type = TRT_HWND;
            result.value.hwin = GetParent(hwnd);
            break;
        case 16:
            if (GetWindowInfo(hwnd, &u.wininfo)) {
                result.type = TRT_OBJ;
................................................................................
            else
                result.type = TRT_GETLASTERROR;
            break;
        }
        if (bfn) {
            result.type = TRT_BOOL;
            result.value.bval = bfn(hwnd);
        } else if (dfn) {
            result.type = TRT_EXCEPTION_ON_FALSE;
            result.value.ival = dfn(hwnd);
        }
    } else if (func < 1000) {
        /* Exactly one additional int arg */
        if (TwapiGetArgs(interp, objc, objv, GETINT(dw), ARGEND) != TCL_OK)
            return TCL_ERROR;
        switch (func) {
        case 501:







|
|
|







 







|
|







 







|
|
>







|





|
|






|

|
>
>
>







 







|
<










|

|
|
|
|
|
|







 







|

|







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
...
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
...
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
...
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
    if (ObjGetElements(interp, obj, &objc, &objv) == TCL_ERROR) {
        return TCL_ERROR;
    }

    fwP->cbSize = sizeof(*fwP);
    if (objc == 4 &&
        (ObjToHWND(interp, objv[0], &hwnd) == TCL_OK) &&
        (ObjToDWORD(interp, objv[1], &fwP->dwFlags) == TCL_OK) &&
        (ObjToUINT(interp, objv[2], &fwP->uCount) == TCL_OK) &&
        (ObjToDWORD(interp, objv[3], &fwP->dwTimeout) == TCL_OK)) {
        fwP->hwnd = (HWND) hwnd;
        return TCL_OK;
    }

    ObjSetStaticResult(interp, "Invalid FLASHWINFO structure. Need 4 elements - window handle, flags, count and timeout.");
    return TCL_ERROR;
}
................................................................................

    if (ObjGetElements(interp, objP, &objc, &objv) != TCL_OK)
        return TCL_ERROR;

    if (objc != 5)
        return TwapiReturnErrorMsg(interp, TWAPI_INVALID_ARGS, "Incorrect format of WINDOWPLACEMENT argument.");

    if (ObjToUINT(interp, objv[0], &wpP->flags) != TCL_OK ||
        ObjToUINT(interp, objv[1], &wpP->showCmd) != TCL_OK ||
        ObjToPOINT(interp, objv[2], &wpP->ptMinPosition) != TCL_OK ||
        ObjToPOINT(interp, objv[3], &wpP->ptMaxPosition) != TCL_OK ||
        ObjToRECT(interp, objv[4], &wpP->rcNormalPosition) != TCL_OK) {
        return TCL_ERROR;
    }

    wpP->length = sizeof(*wpP);
................................................................................
    --objc;
    ++objv;

    result.type = TRT_BADFUNCTIONCODE;
    if (func < 1000) {
        /* Functions taking no arguments */

        HWND (WINAPI *hfn)() = NULL;
        BOOL (WINAPI *bfn)() = NULL;
        UINT (WINAPI *ufn)() = NULL;
        if (objc != 0)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);
        switch (func) {
        case 1:
        case 2:
            result.type = (func == 1 ? GetCursorPos : GetCaretPos) (&result.value.point) ? TRT_POINT : TRT_GETLASTERROR;
            break;
        case 3: ufn = GetCaretBlinkTime; break;
        case 4: hfn = GetFocus; break;
        case 5: hfn = GetDesktopWindow; break;
        case 6: hfn = GetShellWindow; break;
        case 7: hfn = GetForegroundWindow; break;
        case 8: hfn = GetActiveWindow; break;
        case 9: bfn = IsThemeActive; break;
        case 10: bfn = IsAppThemed; break;
        case 11:
            return Twapi_GetCurrentThemeName(interp);
        }
        if (hfn) {
            result.type = TRT_HWND;
            result.value.hwin = hfn();
        } else if (ufn) {
            result.type = TRT_DWORD;
            result.value.uval = ufn();
        } else if (bfn) {
            result.type = TRT_BOOL;
            result.value.bval = bfn();
        }
    } else if (func < 2000) {
        /* Exactly one arg */
        if (objc != 1)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

        switch (func) {
................................................................................
        return TCL_ERROR;

    objc -= 2;
    objv += 2;
    result.type = TRT_BADFUNCTIONCODE;
    if (func < 500) {
        BOOL (WINAPI *bfn)(HWND) = NULL;
        UINT (WINAPI *ufn)(HWND) = NULL;

        if (objc != 0)
            return TwapiReturnError(interp, TWAPI_BAD_ARG_COUNT);

        switch (func) {
        case 1: bfn = IsIconic; break;
        case 2: bfn = IsZoomed; break;
        case 3: bfn = IsWindowVisible; break;
        case 4: bfn = IsWindow; break;
        case 5: bfn = IsWindowUnicode; break;
        case 6: bfn = IsWindowEnabled; break;
        case 7: ufn = ArrangeIconicWindows; break;
        case 8: bfn = SetForegroundWindow; break;
        case 9: bfn = OpenIcon; break;
        case 10: bfn = CloseWindow; break;
        case 11: bfn = DestroyWindow; break;
        case 12: bfn = UpdateWindow; break;
        case 13: bfn = HideCaret; break;
        case 14: bfn = ShowCaret; break;
        case 15:
            result.type = TRT_HWND;
            result.value.hwin = GetParent(hwnd);
            break;
        case 16:
            if (GetWindowInfo(hwnd, &u.wininfo)) {
                result.type = TRT_OBJ;
................................................................................
            else
                result.type = TRT_GETLASTERROR;
            break;
        }
        if (bfn) {
            result.type = TRT_BOOL;
            result.value.bval = bfn(hwnd);
        } else if (ufn) {
            result.type = TRT_EXCEPTION_ON_FALSE;
            result.value.ival = ufn(hwnd);
        }
    } else if (func < 1000) {
        /* Exactly one additional int arg */
        if (TwapiGetArgs(interp, objc, objv, GETINT(dw), ARGEND) != TCL_OK)
            return TCL_ERROR;
        switch (func) {
        case 501:

Changes to undroid/twapi/twapi/winsta/winsta.c.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
...
114
115
116
117
118
119
120



121
122
123
124
125
126
127
#endif

#ifndef MODULENAME
#define MODULENAME "twapi_winsta"
#endif

/* Window station enumeration callback */
BOOL CALLBACK Twapi_EnumWindowStationsOrDesktopsCallback(LPCWSTR p_winsta, LPARAM p_ctx) {
    TwapiEnumCtx *p_enum_ctx =
        (TwapiEnumCtx *) p_ctx;

    ObjAppendElement(p_enum_ctx->interp,
                             p_enum_ctx->objP,
                             ObjFromWinChars(p_winsta));
    return 1;
................................................................................
/* Window station enumeration */
int Twapi_EnumWindowStations(Tcl_Interp *interp)
{
    TwapiEnumCtx enum_ctx;

    enum_ctx.interp = interp;
    enum_ctx.objP = ObjEmptyList();

    
    if (EnumWindowStationsW(Twapi_EnumWindowStationsOrDesktopsCallback, (LPARAM)&enum_ctx) == 0) {
        TwapiReturnSystemError(interp);
        Twapi_FreeNewTclObj(enum_ctx.objP);
        return TCL_ERROR;
    }

................................................................................
        return TCL_ERROR;
    }

    ObjSetResult(interp, enum_ctx.objP);
    return TCL_OK;
}

static int Twapi_GetUserObjectInformation(TwapiInterpContext *ticP, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    HANDLE h;
    int idx;
    void *pv;
    DWORD len;
    TCL_RESULT res;
    USEROBJECTFLAGS *flagsP;
    Tcl_Obj *objs[3];
................................................................................
            break;
        case UOI_USER_SID:
            /* If len is 0, no SID is associated and we just return empty result */
            if (len == 0)
                objP = NULL;
            else
                objP = ObjFromSIDNoFail(pv);



        }
        if (objP)
            ObjSetResult(interp, objP);
        res = TCL_OK;
    }

    if (pv)







|







 







<







 







|

>







 







>
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
33
34
35
36
37
38
39

40
41
42
43
44
45
46
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#endif

#ifndef MODULENAME
#define MODULENAME "twapi_winsta"
#endif

/* Window station enumeration callback */
BOOL CALLBACK Twapi_EnumWindowStationsOrDesktopsCallback(LPWSTR p_winsta, LPARAM p_ctx) {
    TwapiEnumCtx *p_enum_ctx =
        (TwapiEnumCtx *) p_ctx;

    ObjAppendElement(p_enum_ctx->interp,
                             p_enum_ctx->objP,
                             ObjFromWinChars(p_winsta));
    return 1;
................................................................................
/* Window station enumeration */
int Twapi_EnumWindowStations(Tcl_Interp *interp)
{
    TwapiEnumCtx enum_ctx;

    enum_ctx.interp = interp;
    enum_ctx.objP = ObjEmptyList();

    
    if (EnumWindowStationsW(Twapi_EnumWindowStationsOrDesktopsCallback, (LPARAM)&enum_ctx) == 0) {
        TwapiReturnSystemError(interp);
        Twapi_FreeNewTclObj(enum_ctx.objP);
        return TCL_ERROR;
    }

................................................................................
        return TCL_ERROR;
    }

    ObjSetResult(interp, enum_ctx.objP);
    return TCL_OK;
}

static int Twapi_GetUserObjectInformation(ClientData clientdata, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    TwapiInterpContext *ticP = clientdata;
    HANDLE h;
    int idx;
    void *pv;
    DWORD len;
    TCL_RESULT res;
    USEROBJECTFLAGS *flagsP;
    Tcl_Obj *objs[3];
................................................................................
            break;
        case UOI_USER_SID:
            /* If len is 0, no SID is associated and we just return empty result */
            if (len == 0)
                objP = NULL;
            else
                objP = ObjFromSIDNoFail(pv);
        default:
            objP = ObjFromByteArray(pv, len);
            break;
        }
        if (objP)
            ObjSetResult(interp, objP);
        res = TCL_OK;
    }

    if (pv)

Changes to undroid/twapi/twapi/wmi/wmi.c.

34
35
36
37
38
39
40



41
42
43
44
45
46
47
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
        if (TwapiGetArgs(interp, objc, objv,
                         GETPTR(ifc, IMofCompiler), ARGSKIP, ARGSKIP,
                         ARGUSEDEFAULT,
                         GETOBJ(server_namespaceObj),
                         GETINT(optflags), GETINT(classflags),
                         GETINT(instflags), ARGEND) != TCL_OK)
            return TCL_ERROR;



    } else {
        if (TwapiGetArgs(interp, objc, objv,
                         GETPTR(ifc, IMofCompiler), ARGSKIP, ARGUSEDEFAULT,
                         GETOBJ(server_namespaceObj),
                         GETOBJ(userObj),
                         GETOBJ(authorityObj), GETOBJ(passwordObj),
                         GETINT(optflags), GETINT(classflags),
................................................................................

    server_namespace = server_namespaceObj ? ObjToLPWSTR_NULL_IF_EMPTY(server_namespaceObj) : NULL;

    ZeroMemory(&wcsi, sizeof(wcsi));

    switch (type) {
    case 0:
        buf = ObjToStringN(objv[1], &buflen);
        hr = ifc->lpVtbl->CompileBuffer(ifc, buflen, buf, server_namespace,
                                         user, authority, password,
                                         optflags, classflags, instflags,
                                         &wcsi);
        break;
    case 1:
        hr = ifc->lpVtbl->CompileFile(ifc, ObjToWinChars(objv[1]),
................................................................................
    case 2: /* Warning if autorecover pragma is not present. Not an error */
    case WBEM_S_NO_ERROR:
        return TCL_OK;

    case WBEM_S_FALSE: /* Fall thru */
    default:
        ObjSetResult(interp,
                         Tcl_ObjPrintf("IMofCompiler error: phase: %d, object number: %d, first line: %d, last line: %d.",
                                       wcsi.lPhaseError,
                                       wcsi.ObjectNum,
                                       wcsi.FirstLine,
                                       wcsi.LastLine));
        return Twapi_AppendSystemError(interp, wcsi.hRes ? wcsi.hRes : hr);
    }
}                     







>
>
>







 







|







 







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        if (TwapiGetArgs(interp, objc, objv,
                         GETPTR(ifc, IMofCompiler), ARGSKIP, ARGSKIP,
                         ARGUSEDEFAULT,
                         GETOBJ(server_namespaceObj),
                         GETINT(optflags), GETINT(classflags),
                         GETINT(instflags), ARGEND) != TCL_OK)
            return TCL_ERROR;
        password = NULL;   /* Keep gcc happy though unused below for type 2 */
        authority = NULL;  /* Ditto */
        user = NULL; /* Ditto again */
    } else {
        if (TwapiGetArgs(interp, objc, objv,
                         GETPTR(ifc, IMofCompiler), ARGSKIP, ARGUSEDEFAULT,
                         GETOBJ(server_namespaceObj),
                         GETOBJ(userObj),
                         GETOBJ(authorityObj), GETOBJ(passwordObj),
                         GETINT(optflags), GETINT(classflags),
................................................................................

    server_namespace = server_namespaceObj ? ObjToLPWSTR_NULL_IF_EMPTY(server_namespaceObj) : NULL;

    ZeroMemory(&wcsi, sizeof(wcsi));

    switch (type) {
    case 0:
        buf = (BYTE *) ObjToStringN(objv[1], &buflen);
        hr = ifc->lpVtbl->CompileBuffer(ifc, buflen, buf, server_namespace,
                                         user, authority, password,
                                         optflags, classflags, instflags,
                                         &wcsi);
        break;
    case 1:
        hr = ifc->lpVtbl->CompileFile(ifc, ObjToWinChars(objv[1]),
................................................................................
    case 2: /* Warning if autorecover pragma is not present. Not an error */
    case WBEM_S_NO_ERROR:
        return TCL_OK;

    case WBEM_S_FALSE: /* Fall thru */
    default:
        ObjSetResult(interp,
                         Tcl_ObjPrintf("IMofCompiler error: phase: %ld, object number: %ld, first line: %ld, last line: %ld.",
                                       wcsi.lPhaseError,
                                       wcsi.ObjectNum,
                                       wcsi.FirstLine,
                                       wcsi.LastLine));
        return Twapi_AppendSystemError(interp, wcsi.hRes ? wcsi.hRes : hr);
    }
}