Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | dgp-refactor |
Files: | files | file ages | folders |
SHA3-256: |
910dbafdea05a18e810d1ce625750b65 |
User & Date: | dgp 2019-09-20 13:21:33.539 |
Context
2019-09-25
| ||
14:56 | merge trunk check-in: 491a418fae user: dgp tags: dgp-refactor | |
2019-09-20
| ||
13:21 | merge trunk check-in: 910dbafdea user: dgp tags: dgp-refactor | |
2019-09-19
| ||
15:36 | Merge 8.7 check-in: 8c85c9ded5 user: jan.nijtmans tags: trunk | |
2019-09-18
| ||
15:55 | merge trunk check-in: 2900aeb10b user: dgp tags: dgp-refactor | |
Changes
Changes to generic/tclExecute.c.
︙ | ︙ | |||
2018 2019 2020 2021 2022 2023 2024 | /* * Locals - variables that are used within opcodes or bounded sections of * the file (jumps between opcodes within a family). * NOTE: These are now mostly defined locally where needed. */ Tcl_Obj *objPtr, *valuePtr, *value2Ptr, *part1Ptr, *part2Ptr, *tmpPtr; | | | 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 | /* * Locals - variables that are used within opcodes or bounded sections of * the file (jumps between opcodes within a family). * NOTE: These are now mostly defined locally where needed. */ Tcl_Obj *objPtr, *valuePtr, *value2Ptr, *part1Ptr, *part2Ptr, *tmpPtr; Tcl_Obj **objv = NULL; int objc = 0; int opnd, length, pcAdjustment; Var *varPtr, *arrayPtr; #ifdef TCL_COMPILE_DEBUG char cmdNameBuf[21]; #endif |
︙ | ︙ |
Changes to generic/tclPlatDecls.h.
︙ | ︙ | |||
95 96 97 98 99 100 101 | #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT | | < < < < | < | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #if defined(USE_TCL_STUBS) && defined(_WIN32) #define Tcl_WinUtfToTChar(string, len, dsPtr) (Tcl_DStringInit(dsPtr), \ (TCHAR *)Tcl_UtfToChar16DString((string), (len), (dsPtr))) #define Tcl_WinTCharToUtf(string, len, dsPtr) (Tcl_DStringInit(dsPtr), \ (char *)Tcl_Char16ToUtfDString((const unsigned short *)(string), ((((len) + 2) >> 1) - 1), (dsPtr))) #endif #endif /* _TCLPLATDECLS */ |
Changes to tests/all.tcl.
︙ | ︙ | |||
21 22 23 24 25 26 27 | if {[singleProcess]} { interp debug {} -frame 1 } set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)] unset -nocomplain env(ERROR_ON_FAILURES) if {[runAllTests] && $ErrorOnFailures} {exit 1} | > > > > | > | 21 22 23 24 25 26 27 28 29 30 31 32 33 | if {[singleProcess]} { interp debug {} -frame 1 } set ErrorOnFailures [info exists env(ERROR_ON_FAILURES)] unset -nocomplain env(ERROR_ON_FAILURES) if {[runAllTests] && $ErrorOnFailures} {exit 1} # if calling direct only (avoid rewrite exit if inlined or interactive): if { [info exists ::argv0] && [file tail $::argv0] eq [file tail [info script]] && !([info exists ::tcl_interactive] && $::tcl_interactive) } { proc exit args {} } |
Changes to unix/tclSelectNotfy.c.
︙ | ︙ | |||
227 228 229 230 231 232 233 | int cbWndExtra; void *hInstance; void *hIcon; void *hCursor; void *hbrBackground; void *lpszMenuName; const void *lpszClassName; | | | | 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 | int cbWndExtra; void *hInstance; void *hIcon; void *hCursor; void *hbrBackground; void *lpszMenuName; const void *lpszClassName; } WNDCLASSW; extern void __stdcall CloseHandle(void *); extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *); extern void *__stdcall CreateWindowExW(void *, const void *, const void *, DWORD, int, int, int, int, void *, void *, void *, void *); extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *); extern unsigned char __stdcall DestroyWindow(void *); extern int __stdcall DispatchMessageW(const MSG *); extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int); extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *, unsigned char, DWORD, DWORD); extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int); extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *, void *); extern void __stdcall PostQuitMessage(int); extern void *__stdcall RegisterClassW(const WNDCLASSW *); extern unsigned char __stdcall ResetEvent(void *); extern unsigned char __stdcall TranslateMessage(const MSG *); /* * Threaded-cygwin specific constants and functions in this file: */ |
︙ | ︙ | |||
293 294 295 296 297 298 299 | tsdPtr->eventReady = 0; /* * Initialize thread specific condition variable for this thread. */ if (tsdPtr->waitCVinitialized == 0) { #ifdef __CYGWIN__ | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | tsdPtr->eventReady = 0; /* * Initialize thread specific condition variable for this thread. */ if (tsdPtr->waitCVinitialized == 0) { #ifdef __CYGWIN__ WNDCLASSW class; class.style = 0; class.cbClsExtra = 0; class.cbWndExtra = 0; class.hInstance = TclWinGetTclInstance(); class.hbrBackground = NULL; class.lpszMenuName = NULL; |
︙ | ︙ |
Changes to win/tclWin32Dll.c.
︙ | ︙ | |||
310 311 312 313 314 315 316 | drive[0] = (WCHAR) dlIter->driveLetter; /* * Try to read the volume mount point and see where it points. */ | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | drive[0] = (WCHAR) dlIter->driveLetter; /* * Try to read the volume mount point and see where it points. */ if (GetVolumeNameForVolumeMountPointW(drive, Target, 55) != 0) { if (wcscmp(dlIter->volumeName, Target) == 0) { /* * Nothing has changed. */ Tcl_MutexUnlock(&mountPointMap); |
︙ | ︙ | |||
369 370 371 372 373 374 375 | */ for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++) { /* * Try to read the volume mount point and see where it points. */ | | | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | */ for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++) { /* * Try to read the volume mount point and see where it points. */ if (GetVolumeNameForVolumeMountPointW(drive, Target, 55) != 0) { int alreadyStored = 0; for (dlIter = driveLetterLookup; dlIter != NULL; dlIter = dlIter->nextPtr) { if (wcscmp(dlIter->volumeName, Target) == 0) { alreadyStored = 1; |
︙ | ︙ |
Changes to win/tclWinChan.c.
︙ | ︙ | |||
942 943 944 945 946 947 948 | if (TEST_FLAG(mode, O_CREAT)) { if (TEST_FLAG(permissions, S_IWRITE)) { flags = FILE_ATTRIBUTE_NORMAL; } else { flags = FILE_ATTRIBUTE_READONLY; } } else { | | | | 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | if (TEST_FLAG(mode, O_CREAT)) { if (TEST_FLAG(permissions, S_IWRITE)) { flags = FILE_ATTRIBUTE_NORMAL; } else { flags = FILE_ATTRIBUTE_READONLY; } } else { flags = GetFileAttributesW(nativeName); if (flags == 0xFFFFFFFF) { flags = 0; } } /* * Set up the file sharing mode. We want to allow simultaneous access. */ shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; /* * Now we get to create the file. */ handle = CreateFileW(nativeName, accessMode, shareMode, NULL, createMode, flags, (HANDLE) NULL); if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if ((err & 0xffffL) == ERROR_OPEN_FAILED) { err = TEST_FLAG(mode, O_CREAT) ? ERROR_FILE_EXISTS |
︙ | ︙ |
Changes to win/tclWinConsole.c.
︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 | * If the console has hit EOF, it is always readable. */ if (infoPtr->readFlags & CONSOLE_EOF) { return 1; } | | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | * If the console has hit EOF, it is always readable. */ if (infoPtr->readFlags & CONSOLE_EOF) { return 1; } if (PeekConsoleInputW(handle, &input, 1, &count) == FALSE) { /* * Check to see if the peek failed because of EOF. */ TclWinConvertError(GetLastError()); if (errno == EOF) { |
︙ | ︙ | |||
1353 1354 1355 1356 1357 1358 1359 | infoPtr->flags |= CONSOLE_READ_OPS; GetConsoleMode(infoPtr->handle, &infoPtr->initMode); modes = infoPtr->initMode; modes &= ~(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); modes |= ENABLE_LINE_INPUT; SetConsoleMode(infoPtr->handle, modes); | | | | 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | infoPtr->flags |= CONSOLE_READ_OPS; GetConsoleMode(infoPtr->handle, &infoPtr->initMode); modes = infoPtr->initMode; modes &= ~(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); modes |= ENABLE_LINE_INPUT; SetConsoleMode(infoPtr->handle, modes); infoPtr->reader.readyEvent = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->reader.thread = CreateThread(NULL, 256, ConsoleReaderThread, TclPipeThreadCreateTI(&infoPtr->reader.TI, infoPtr, infoPtr->reader.readyEvent), 0, NULL); SetThreadPriority(infoPtr->reader.thread, THREAD_PRIORITY_HIGHEST); } if (permissions & TCL_WRITABLE) { infoPtr->writer.readyEvent = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->writer.thread = CreateThread(NULL, 256, ConsoleWriterThread, TclPipeThreadCreateTI(&infoPtr->writer.TI, infoPtr, infoPtr->writer.readyEvent), 0, NULL); SetThreadPriority(infoPtr->writer.thread, THREAD_PRIORITY_HIGHEST); } /* |
︙ | ︙ |
Changes to win/tclWinFCmd.c.
︙ | ︙ | |||
210 211 212 213 214 215 216 | /* * Link the TCLEXCEPTION_REGISTRATION on the chain. */ "movl %%edx, %%fs:0" "\n\t" /* | | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | /* * Link the TCLEXCEPTION_REGISTRATION on the chain. */ "movl %%edx, %%fs:0" "\n\t" /* * Call MoveFileW(nativeSrc, nativeDst) */ "pushl %%ebx" "\n\t" "pushl %%ecx" "\n\t" "movl %[moveFileW], %%eax" "\n\t" "call *%%eax" "\n\t" /* * Come here on normal exit. Recover the TCLEXCEPTION_REGISTRATION and * put the status return from MoveFile into it. */ |
︙ | ︙ | |||
252 253 254 255 256 257 258 | : /* No outputs */ : [registration] "m" (registration), [nativeDst] "m" (nativeDst), [nativeSrc] "m" (nativeSrc), | | | | | | | | 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 | : /* No outputs */ : [registration] "m" (registration), [nativeDst] "m" (nativeDst), [nativeSrc] "m" (nativeSrc), [moveFileW] "r" (MoveFileW) : "%eax", "%ebx", "%ecx", "%edx", "memory" ); if (registration.status != FALSE) { retval = TCL_OK; } #else #ifndef HAVE_NO_SEH __try { #endif if ((*MoveFileW)(nativeSrc, nativeDst) != FALSE) { retval = TCL_OK; } #ifndef HAVE_NO_SEH } __except (EXCEPTION_EXECUTE_HANDLER) {} #endif #endif if (retval != -1) { return retval; } TclWinConvertError(GetLastError()); srcAttr = GetFileAttributesW(nativeSrc); dstAttr = GetFileAttributesW(nativeDst); if (srcAttr == 0xffffffff) { if (GetFullPathNameW(nativeSrc, 0, NULL, NULL) >= MAX_PATH) { errno = ENAMETOOLONG; return TCL_ERROR; } srcAttr = 0; } if (dstAttr == 0xffffffff) { if (GetFullPathNameW(nativeDst, 0, NULL, NULL) >= MAX_PATH) { errno = ENAMETOOLONG; return TCL_ERROR; } dstAttr = 0; } |
︙ | ︙ | |||
311 312 313 314 315 316 317 | const char **srcArgv, **dstArgv; int size, srcArgc, dstArgc; WCHAR nativeSrcPath[MAX_PATH]; WCHAR nativeDstPath[MAX_PATH]; Tcl_DString srcString, dstString; const char *src, *dst; | | | | | | 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 | const char **srcArgv, **dstArgv; int size, srcArgc, dstArgc; WCHAR nativeSrcPath[MAX_PATH]; WCHAR nativeDstPath[MAX_PATH]; Tcl_DString srcString, dstString; const char *src, *dst; size = GetFullPathNameW(nativeSrc, MAX_PATH, nativeSrcPath, &nativeSrcRest); if ((size == 0) || (size > MAX_PATH)) { return TCL_ERROR; } size = GetFullPathNameW(nativeDst, MAX_PATH, nativeDstPath, &nativeDstRest); if ((size == 0) || (size > MAX_PATH)) { return TCL_ERROR; } CharLowerW(nativeSrcPath); CharLowerW(nativeDstPath); Tcl_DStringInit(&srcString); Tcl_DStringInit(&dstString); src = Tcl_WCharToUtfDString(nativeSrcPath, -1, &srcString); dst = Tcl_WCharToUtfDString(nativeDstPath, -1, &dstString); /* |
︙ | ︙ | |||
406 407 408 409 410 411 412 | if (DoRemoveJustDirectory(nativeDst, 0, NULL) == TCL_OK) { /* * Now that that empty directory is gone, we can try * renaming again. If that fails, we'll put this empty * directory back, for completeness. */ | | | | | 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 | if (DoRemoveJustDirectory(nativeDst, 0, NULL) == TCL_OK) { /* * Now that that empty directory is gone, we can try * renaming again. If that fails, we'll put this empty * directory back, for completeness. */ if (MoveFileW(nativeSrc, nativeDst) != FALSE) { return TCL_OK; } /* * Some new error has occurred. Don't know what it could * be, but report this one. */ TclWinConvertError(GetLastError()); CreateDirectoryW(nativeDst, NULL); SetFileAttributesW(nativeDst, dstAttr); if (Tcl_GetErrno() == EACCES) { /* * Decode the EACCES to a more meaningful error. */ goto decode; } |
︙ | ︙ | |||
447 448 449 450 451 452 453 | * back to old name. */ WCHAR *nativeRest, *nativeTmp, *nativePrefix; int result, size; WCHAR tempBuf[MAX_PATH]; | | | | | | | | | | | | 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 | * back to old name. */ WCHAR *nativeRest, *nativeTmp, *nativePrefix; int result, size; WCHAR tempBuf[MAX_PATH]; size = GetFullPathNameW(nativeDst, MAX_PATH, tempBuf, &nativeRest); if ((size == 0) || (size > MAX_PATH) || (nativeRest == NULL)) { return TCL_ERROR; } nativeTmp = (WCHAR *) tempBuf; nativeRest[0] = '\0'; result = TCL_ERROR; nativePrefix = (WCHAR *)L"tclr"; if (GetTempFileNameW(nativeTmp, nativePrefix, 0, tempBuf) != 0) { /* * Strictly speaking, need the following DeleteFile and * MoveFile to be joined as an atomic operation so no * other app comes along in the meantime and creates the * same temp file. */ nativeTmp = tempBuf; DeleteFileW(nativeTmp); if (MoveFileW(nativeDst, nativeTmp) != FALSE) { if (MoveFileW(nativeSrc, nativeDst) != FALSE) { SetFileAttributesW(nativeTmp, FILE_ATTRIBUTE_NORMAL); DeleteFileW(nativeTmp); return TCL_OK; } else { DeleteFileW(nativeDst); MoveFileW(nativeTmp, nativeDst); } } /* * Can't backup dst file or move src file. Return that * error. Could happen if an open file refers to dst. */ |
︙ | ︙ | |||
599 600 601 602 603 604 605 | /* * Link the TCLEXCEPTION_REGISTRATION on the chain. */ "movl %%edx, %%fs:0" "\n\t" /* | | | | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | /* * Link the TCLEXCEPTION_REGISTRATION on the chain. */ "movl %%edx, %%fs:0" "\n\t" /* * Call CopyFileW(nativeSrc, nativeDst, 0) */ "movl %[copyFileW], %%eax" "\n\t" "pushl $0" "\n\t" "pushl %%ebx" "\n\t" "pushl %%ecx" "\n\t" "call *%%eax" "\n\t" /* * Come here on normal exit. Recover the TCLEXCEPTION_REGISTRATION and |
︙ | ︙ | |||
642 643 644 645 646 647 648 | : /* No outputs */ : [registration] "m" (registration), [nativeDst] "m" (nativeDst), [nativeSrc] "m" (nativeSrc), | | | | | | | | | 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 | : /* No outputs */ : [registration] "m" (registration), [nativeDst] "m" (nativeDst), [nativeSrc] "m" (nativeSrc), [copyFileW] "r" (CopyFileW) : "%eax", "%ebx", "%ecx", "%edx", "memory" ); if (registration.status != FALSE) { retval = TCL_OK; } #else #ifndef HAVE_NO_SEH __try { #endif if (CopyFileW(nativeSrc, nativeDst, 0) != FALSE) { retval = TCL_OK; } #ifndef HAVE_NO_SEH } __except (EXCEPTION_EXECUTE_HANDLER) {} #endif #endif if (retval != -1) { return retval; } TclWinConvertError(GetLastError()); if (Tcl_GetErrno() == EBADF) { Tcl_SetErrno(EACCES); return TCL_ERROR; } if (Tcl_GetErrno() == EACCES) { DWORD srcAttr, dstAttr; srcAttr = GetFileAttributesW(nativeSrc); dstAttr = GetFileAttributesW(nativeDst); if (srcAttr != 0xffffffff) { if (dstAttr == 0xffffffff) { dstAttr = 0; } if ((srcAttr & FILE_ATTRIBUTE_DIRECTORY) || (dstAttr & FILE_ATTRIBUTE_DIRECTORY)) { if (srcAttr & FILE_ATTRIBUTE_REPARSE_POINT) { /* Source is a symbolic link -- copy it */ if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst)==0) { return TCL_OK; } } Tcl_SetErrno(EISDIR); } if (dstAttr & FILE_ATTRIBUTE_READONLY) { SetFileAttributesW(nativeDst, dstAttr & ~((DWORD)FILE_ATTRIBUTE_READONLY)); if (CopyFileW(nativeSrc, nativeDst, 0) != FALSE) { return TCL_OK; } /* * Still can't copy onto dst. Return that error, and restore * attributes of dst. */ TclWinConvertError(GetLastError()); SetFileAttributesW(nativeDst, dstAttr); } } } return TCL_ERROR; } /* |
︙ | ︙ | |||
759 760 761 762 763 764 765 | */ if (path == NULL || path[0] == '\0') { Tcl_SetErrno(ENOENT); return TCL_ERROR; } | | | | | | | | 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 | */ if (path == NULL || path[0] == '\0') { Tcl_SetErrno(ENOENT); return TCL_ERROR; } if (DeleteFileW(path) != FALSE) { return TCL_OK; } TclWinConvertError(GetLastError()); if (Tcl_GetErrno() == EACCES) { attr = GetFileAttributesW(path); if (attr != 0xffffffff) { if (attr & FILE_ATTRIBUTE_DIRECTORY) { if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { /* * It is a symbolic link - remove it. */ if (TclWinSymLinkDelete(path, 0) == 0) { return TCL_OK; } } /* * If we fall through here, it is a directory. * * Windows NT reports removing a directory as EACCES instead * of EISDIR. */ Tcl_SetErrno(EISDIR); } else if (attr & FILE_ATTRIBUTE_READONLY) { int res = SetFileAttributesW(path, attr & ~((DWORD) FILE_ATTRIBUTE_READONLY)); if ((res != 0) && (DeleteFileW(path) != FALSE)) { return TCL_OK; } TclWinConvertError(GetLastError()); if (res != 0) { SetFileAttributesW(path, attr); } } } } else if (Tcl_GetErrno() == ENOENT) { attr = GetFileAttributesW(path); if (attr != 0xffffffff) { if (attr & FILE_ATTRIBUTE_DIRECTORY) { /* * Windows 95 reports removing a directory as ENOENT instead * of EISDIR. */ |
︙ | ︙ | |||
859 860 861 862 863 864 865 | return DoCreateDirectory(Tcl_FSGetNativePath(pathPtr)); } static int DoCreateDirectory( const WCHAR *nativePath) /* Pathname of directory to create (native). */ { | | | 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 | return DoCreateDirectory(Tcl_FSGetNativePath(pathPtr)); } static int DoCreateDirectory( const WCHAR *nativePath) /* Pathname of directory to create (native). */ { if (CreateDirectoryW(nativePath, NULL) == 0) { DWORD error = GetLastError(); TclWinConvertError(error); return TCL_ERROR; } return TCL_OK; } |
︙ | ︙ | |||
1031 1032 1033 1034 1035 1036 1037 | if (nativePath == NULL || nativePath[0] == '\0') { Tcl_SetErrno(ENOENT); Tcl_DStringInit(errorPtr); return TCL_ERROR; } | | | | | 1031 1032 1033 1034 1035 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 1063 1064 1065 1066 1067 | if (nativePath == NULL || nativePath[0] == '\0') { Tcl_SetErrno(ENOENT); Tcl_DStringInit(errorPtr); return TCL_ERROR; } attr = GetFileAttributesW(nativePath); if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { /* * It is a symbolic link - remove it. */ if (TclWinSymLinkDelete(nativePath, 0) == 0) { return TCL_OK; } } else { /* * Ordinary directory. */ if (RemoveDirectoryW(nativePath) != FALSE) { return TCL_OK; } } TclWinConvertError(GetLastError()); if (Tcl_GetErrno() == EACCES) { attr = GetFileAttributesW(nativePath); if (attr != 0xffffffff) { if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { /* * Windows 95 reports calling RemoveDirectory on a file as an * EACCES, not an ENOTDIR. */ |
︙ | ︙ | |||
1077 1078 1079 1080 1081 1082 1083 | if (TclWinSymLinkDelete(nativePath, 1) != 0) { goto end; } } if (attr & FILE_ATTRIBUTE_READONLY) { attr &= ~FILE_ATTRIBUTE_READONLY; | | | | | 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | if (TclWinSymLinkDelete(nativePath, 1) != 0) { goto end; } } if (attr & FILE_ATTRIBUTE_READONLY) { attr &= ~FILE_ATTRIBUTE_READONLY; if (SetFileAttributesW(nativePath, attr) == FALSE) { goto end; } if (RemoveDirectoryW(nativePath) != FALSE) { return TCL_OK; } TclWinConvertError(GetLastError()); SetFileAttributesW(nativePath, attr | FILE_ATTRIBUTE_READONLY); } } } if (Tcl_GetErrno() == ENOTEMPTY) { /* |
︙ | ︙ | |||
1187 1188 1189 1190 1191 1192 1193 | * filled with UTF-8 name of file causing * error. */ { DWORD sourceAttr; WCHAR *nativeSource, *nativeTarget, *nativeErrfile; int result, found, sourceLen, targetLen = 0, oldSourceLen, oldTargetLen; HANDLE handle; | | | | 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 | * filled with UTF-8 name of file causing * error. */ { DWORD sourceAttr; WCHAR *nativeSource, *nativeTarget, *nativeErrfile; int result, found, sourceLen, targetLen = 0, oldSourceLen, oldTargetLen; HANDLE handle; WIN32_FIND_DATAW data; nativeErrfile = NULL; result = TCL_OK; oldTargetLen = 0; /* lint. */ nativeSource = (WCHAR *) Tcl_DStringValue(sourcePtr); nativeTarget = (WCHAR *) (targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)); oldSourceLen = Tcl_DStringLength(sourcePtr); sourceAttr = GetFileAttributesW(nativeSource); if (sourceAttr == 0xffffffff) { nativeErrfile = nativeSource; goto end; } if (sourceAttr & FILE_ATTRIBUTE_REPARSE_POINT) { /* |
︙ | ︙ | |||
1225 1226 1227 1228 1229 1230 1231 | return traverseProc(nativeSource, nativeTarget, DOTREE_F, errorPtr); } Tcl_DStringAppend(sourcePtr, (char *) L"\\*.*", 4 * sizeof(WCHAR) + 1); Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1); nativeSource = (WCHAR *) Tcl_DStringValue(sourcePtr); | | | 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 | return traverseProc(nativeSource, nativeTarget, DOTREE_F, errorPtr); } Tcl_DStringAppend(sourcePtr, (char *) L"\\*.*", 4 * sizeof(WCHAR) + 1); Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1); nativeSource = (WCHAR *) Tcl_DStringValue(sourcePtr); handle = FindFirstFileW(nativeSource, &data); if (handle == INVALID_HANDLE_VALUE) { /* * Can't read directory. */ TclWinConvertError(GetLastError()); nativeErrfile = nativeSource; |
︙ | ︙ | |||
1258 1259 1260 1261 1262 1263 1264 | targetLen = oldTargetLen; targetLen += sizeof(WCHAR); Tcl_DStringAppend(targetPtr, (char *) L"\\", sizeof(WCHAR) + 1); Tcl_DStringSetLength(targetPtr, targetLen); } found = 1; | | | 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 | targetLen = oldTargetLen; targetLen += sizeof(WCHAR); Tcl_DStringAppend(targetPtr, (char *) L"\\", sizeof(WCHAR) + 1); Tcl_DStringSetLength(targetPtr, targetLen); } found = 1; for (; found; found = FindNextFileW(handle, &data)) { WCHAR *nativeName; int len; WCHAR *wp = data.cFileName; if (*wp == '.') { wp++; if (*wp == '.') { |
︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 | case DOTREE_LINK: if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst) == TCL_OK) { return TCL_OK; } break; case DOTREE_PRED: if (DoCreateDirectory(nativeDst) == TCL_OK) { | | | | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 | case DOTREE_LINK: if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst) == TCL_OK) { return TCL_OK; } break; case DOTREE_PRED: if (DoCreateDirectory(nativeDst) == TCL_OK) { DWORD attr = GetFileAttributesW(nativeSrc); if (SetFileAttributesW(nativeDst, attr) != FALSE) { return TCL_OK; } TclWinConvertError(GetLastError()); } break; case DOTREE_POSTD: |
︙ | ︙ | |||
1514 1515 1516 1517 1518 1519 1520 | Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { DWORD result; const WCHAR *nativeName; int attr; nativeName = Tcl_FSGetNativePath(fileName); | | | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 | Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ { DWORD result; const WCHAR *nativeName; int attr; nativeName = Tcl_FSGetNativePath(fileName); result = GetFileAttributesW(nativeName); if (result == 0xffffffff) { StatError(interp, fileName); return TCL_ERROR; } attr = (int)(result & attributeArray[objIndex]); |
︙ | ︙ | |||
1645 1646 1647 1648 1649 1650 1651 | pathv[0] = (char) Tcl_UniCharToUpper(UCHAR(pathv[0])); } else { Tcl_Obj *tempPath; Tcl_DString ds; Tcl_DString dsTemp; const WCHAR *nativeName; const char *tempString; | | | | | | 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 | pathv[0] = (char) Tcl_UniCharToUpper(UCHAR(pathv[0])); } else { Tcl_Obj *tempPath; Tcl_DString ds; Tcl_DString dsTemp; const WCHAR *nativeName; const char *tempString; WIN32_FIND_DATAW data; HANDLE handle; DWORD attr; tempPath = Tcl_FSJoinPath(splitPath, i+1); Tcl_IncrRefCount(tempPath); /* * We'd like to call Tcl_FSGetNativePath(tempPath) but that is * likely to lead to infinite loops. */ tempString = TclGetStringFromObj(tempPath, &length); Tcl_DStringInit(&ds); nativeName = Tcl_UtfToWCharDString(tempString, length, &ds); Tcl_DecrRefCount(tempPath); handle = FindFirstFileW(nativeName, &data); if (handle == INVALID_HANDLE_VALUE) { /* * FindFirstFileW() doesn't like root directories. We would * only get a root directory here if the caller specified "c:" * or "c:." and the current directory on the drive was the * root directory */ attr = GetFileAttributesW(nativeName); if ((attr!=0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY)) { Tcl_DStringFree(&ds); goto simple; } } if (handle == INVALID_HANDLE_VALUE) { |
︙ | ︙ | |||
1840 1841 1842 1843 1844 1845 1846 | Tcl_Obj *attributePtr) /* The new value of the attribute. */ { DWORD fileAttributes, old; int yesNo, result; const WCHAR *nativeName; nativeName = Tcl_FSGetNativePath(fileName); | | | | 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 | Tcl_Obj *attributePtr) /* The new value of the attribute. */ { DWORD fileAttributes, old; int yesNo, result; const WCHAR *nativeName; nativeName = Tcl_FSGetNativePath(fileName); fileAttributes = old = GetFileAttributesW(nativeName); if (fileAttributes == 0xffffffff) { StatError(interp, fileName); return TCL_ERROR; } result = Tcl_GetBooleanFromObj(interp, attributePtr, &yesNo); if (result != TCL_OK) { return result; } if (yesNo) { fileAttributes |= (attributeArray[objIndex]); } else { fileAttributes &= ~(attributeArray[objIndex]); } if ((fileAttributes != old) && !SetFileAttributesW(nativeName, fileAttributes)) { StatError(interp, fileName); return TCL_ERROR; } return result; } |
︙ | ︙ | |||
1932 1933 1934 1935 1936 1937 1938 | * On Win32s: * GetLogicalDriveStrings() isn't implemented. * GetLogicalDrives() returns incorrect information. */ if (GetLogicalDriveStringsA(sizeof(buf), buf) == 0) { /* | | | | 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 | * On Win32s: * GetLogicalDriveStrings() isn't implemented. * GetLogicalDrives() returns incorrect information. */ if (GetLogicalDriveStringsA(sizeof(buf), buf) == 0) { /* * GetVolumeInformationW() will detects all drives, but causes * chattering on empty floppy drives. We only do this if * GetLogicalDriveStrings() didn't work. It has also been reported * that on some laptops it takes a while for GetVolumeInformationW() to * return when pinging an empty floppy drive, another reason to try to * avoid calling it. */ buf[1] = ':'; buf[2] = '/'; buf[3] = '\0'; |
︙ | ︙ |
Changes to win/tclWinFile.c.
︙ | ︙ | |||
199 200 201 202 203 204 205 | WCHAR *tempFilePart; DWORD attr; /* * Get the full path referenced by the target. */ | | | | | | | 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 | WCHAR *tempFilePart; DWORD attr; /* * Get the full path referenced by the target. */ if (!GetFullPathNameW(linkTargetPath, MAX_PATH, tempFileName, &tempFilePart)) { /* * Invalid file. */ TclWinConvertError(GetLastError()); return -1; } /* * Make sure source file doesn't exist. */ attr = GetFileAttributesW(linkSourcePath); if (attr != INVALID_FILE_ATTRIBUTES) { Tcl_SetErrno(EEXIST); return -1; } /* * Get the full path referenced by the source file/directory. */ if (!GetFullPathNameW(linkSourcePath, MAX_PATH, tempFileName, &tempFilePart)) { /* * Invalid file. */ TclWinConvertError(GetLastError()); return -1; } /* * Check the target. */ attr = GetFileAttributesW(linkTargetPath); if (attr == INVALID_FILE_ATTRIBUTES) { /* * The target doesn't exist. */ TclWinConvertError(GetLastError()); } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { /* * It is a file. */ if (linkAction & TCL_CREATE_HARD_LINK) { if (CreateHardLinkW(linkSourcePath, linkTargetPath, NULL)) { /* * Success! */ return 0; } |
︙ | ︙ | |||
312 313 314 315 316 317 318 | WCHAR *tempFilePart; DWORD attr; /* * Get the full path referenced by the target. */ | | | | 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 | WCHAR *tempFilePart; DWORD attr; /* * Get the full path referenced by the target. */ if (!GetFullPathNameW(linkSourcePath, MAX_PATH, tempFileName, &tempFilePart)) { /* * Invalid file. */ TclWinConvertError(GetLastError()); return NULL; } /* * Make sure source file does exist. */ attr = GetFileAttributesW(linkSourcePath); if (attr == INVALID_FILE_ATTRIBUTES) { /* * The source doesn't exist. */ TclWinConvertError(GetLastError()); return NULL; |
︙ | ︙ | |||
483 484 485 486 487 488 489 | DUMMY_REPARSE_BUFFER dummy; REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy; HANDLE hFile; DWORD returnedLength; memset(reparseBuffer, 0, sizeof(DUMMY_REPARSE_BUFFER)); reparseBuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; | | | | 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 | DUMMY_REPARSE_BUFFER dummy; REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy; HANDLE hFile; DWORD returnedLength; memset(reparseBuffer, 0, sizeof(DUMMY_REPARSE_BUFFER)); reparseBuffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; hFile = CreateFileW(linkOrigPath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile != INVALID_HANDLE_VALUE) { if (!DeviceIoControl(hFile, FSCTL_DELETE_REPARSE_POINT, reparseBuffer, REPARSE_MOUNTPOINT_HEADER_SIZE,NULL,0,&returnedLength,NULL)) { /* * Error setting junction. */ TclWinConvertError(GetLastError()); CloseHandle(hFile); } else { CloseHandle(hFile); if (!linkOnly) { RemoveDirectoryW(linkOrigPath); } return 0; } } return -1; } |
︙ | ︙ | |||
543 544 545 546 547 548 549 | int attr, len, offset; DUMMY_REPARSE_BUFFER dummy; REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy; Tcl_Obj *retVal; Tcl_DString ds; const char *copy; | | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | int attr, len, offset; DUMMY_REPARSE_BUFFER dummy; REPARSE_DATA_BUFFER *reparseBuffer = (REPARSE_DATA_BUFFER *) &dummy; Tcl_Obj *retVal; Tcl_DString ds; const char *copy; attr = GetFileAttributesW(linkDirPath); if (!(attr & FILE_ATTRIBUTE_REPARSE_POINT)) { goto invalidError; } if (NativeReadReparse(linkDirPath, reparseBuffer, 0)) { return NULL; } |
︙ | ︙ | |||
677 678 679 680 681 682 683 | const WCHAR *linkDirPath, /* The junction to read */ REPARSE_DATA_BUFFER *buffer,/* Pointer to buffer. Cannot be NULL */ DWORD desiredAccess) { HANDLE hFile; DWORD returnedLength; | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | const WCHAR *linkDirPath, /* The junction to read */ REPARSE_DATA_BUFFER *buffer,/* Pointer to buffer. Cannot be NULL */ DWORD desiredAccess) { HANDLE hFile; DWORD returnedLength; hFile = CreateFileW(linkDirPath, desiredAccess, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { /* * Error creating directory. */ |
︙ | ︙ | |||
737 738 739 740 741 742 743 | HANDLE hFile; DWORD returnedLength; /* * Create the directory - it must not already exist. */ | | | | 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | HANDLE hFile; DWORD returnedLength; /* * Create the directory - it must not already exist. */ if (CreateDirectoryW(linkDirPath, NULL) == 0) { /* * Error creating directory. */ TclWinConvertError(GetLastError()); return -1; } hFile = CreateFileW(linkDirPath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { /* * Error creating directory. */ |
︙ | ︙ | |||
770 771 772 773 774 775 776 | NULL, 0, &returnedLength, NULL)) { /* * Error setting junction. */ TclWinConvertError(GetLastError()); CloseHandle(hFile); | | | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | NULL, 0, &returnedLength, NULL)) { /* * Error setting junction. */ TclWinConvertError(GetLastError()); CloseHandle(hFile); RemoveDirectoryW(linkDirPath); return -1; } CloseHandle(hFile); /* * We succeeded. */ |
︙ | ︙ | |||
916 917 918 919 920 921 922 | DWORD attr; WIN32_FILE_ATTRIBUTE_DATA data; size_t length = 0; const char *str = TclGetStringFromObj(norm, &length); native = Tcl_FSGetNativePath(pathPtr); | | | | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | DWORD attr; WIN32_FILE_ATTRIBUTE_DATA data; size_t length = 0; const char *str = TclGetStringFromObj(norm, &length); native = Tcl_FSGetNativePath(pathPtr); if (GetFileAttributesExW(native, GetFileExInfoStandard, &data) != TRUE) { return TCL_OK; } attr = data.dwFileAttributes; if (NativeMatchType(WinIsDrive(str, length), attr, native, types)) { Tcl_ListObjAppendElement(interp, resultPtr, pathPtr); } } return TCL_OK; } else { DWORD attr; HANDLE handle; WIN32_FIND_DATAW data; const char *dirName; /* UTF-8 dir name, later with pattern * appended. */ size_t dirLength; int matchSpecialDots; Tcl_DString ds; /* Native encoding of dir, also used * temporarily for other things. */ Tcl_DString dsOrig; /* UTF-8 encoding of dir. */ |
︙ | ︙ | |||
959 960 961 962 963 964 965 | * Verify that the specified path exists and is actually a directory. */ native = Tcl_FSGetNativePath(pathPtr); if (native == NULL) { return TCL_OK; } | | | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 | * Verify that the specified path exists and is actually a directory. */ native = Tcl_FSGetNativePath(pathPtr); if (native == NULL) { return TCL_OK; } attr = GetFileAttributesW(native); if ((attr == INVALID_FILE_ATTRIBUTES) || ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)) { return TCL_OK; } /* |
︙ | ︙ | |||
1003 1004 1005 1006 1007 1008 1009 | } else { dirName = TclDStringAppendLiteral(&dsOrig, "*.*"); } Tcl_DStringInit(&ds); native = Tcl_UtfToWCharDString(dirName, -1, &ds); if ((types == NULL) || (types->type != TCL_GLOB_TYPE_DIR)) { | | | | 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 | } else { dirName = TclDStringAppendLiteral(&dsOrig, "*.*"); } Tcl_DStringInit(&ds); native = Tcl_UtfToWCharDString(dirName, -1, &ds); if ((types == NULL) || (types->type != TCL_GLOB_TYPE_DIR)) { handle = FindFirstFileW(native, &data); } else { /* * We can be more efficient, for pure directory requests. */ handle = FindFirstFileExW(native, FindExInfoStandard, &data, FindExSearchLimitToDirectories, NULL, 0); } if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); |
︙ | ︙ | |||
1135 1136 1137 1138 1139 1140 1141 | } /* * Free ds here to ensure that native is valid above. */ Tcl_DStringFree(&ds); | | | 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 | } /* * Free ds here to ensure that native is valid above. */ Tcl_DStringFree(&ds); } while (FindNextFileW(handle, &data) == TRUE); FindClose(handle); Tcl_DStringFree(&dsOrig); return TCL_OK; } } |
︙ | ︙ | |||
1569 1570 1571 1572 1573 1574 1575 | static int NativeAccess( const WCHAR *nativePath, /* Path of file to access, native encoding. */ int mode) /* Permission setting. */ { DWORD attr; | | | 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 | static int NativeAccess( const WCHAR *nativePath, /* Path of file to access, native encoding. */ int mode) /* Permission setting. */ { DWORD attr; attr = GetFileAttributesW(nativePath); if (attr == INVALID_FILE_ATTRIBUTES) { /* * File might not exist. */ DWORD lasterror = GetLastError(); |
︙ | ︙ | |||
1638 1639 1640 1641 1642 1643 1644 | if (mode & W_OK) { mask |= GENERIC_WRITE; } if (mode & X_OK) { mask |= GENERIC_EXECUTE; } | | | 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 | if (mode & W_OK) { mask |= GENERIC_WRITE; } if (mode & X_OK) { mask |= GENERIC_EXECUTE; } hFile = CreateFileW(nativePath, mask, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL); if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); return 0; } |
︙ | ︙ | |||
1688 1689 1690 1691 1692 1693 1694 | int error; /* * First find out how big the buffer needs to be. */ size = 0; | | | 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 | int error; /* * First find out how big the buffer needs to be. */ size = 0; GetFileSecurityW(nativePath, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, 0, 0, &size); /* * Should have failed with ERROR_INSUFFICIENT_BUFFER */ |
︙ | ︙ | |||
1719 1720 1721 1722 1723 1724 1725 | sdPtr = (SECURITY_DESCRIPTOR *) HeapAlloc(GetProcessHeap(), 0, size); if (sdPtr == NULL) { goto accessError; } /* | | | | 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 | sdPtr = (SECURITY_DESCRIPTOR *) HeapAlloc(GetProcessHeap(), 0, size); if (sdPtr == NULL) { goto accessError; } /* * Call GetFileSecurityW() for real. */ if (!GetFileSecurityW(nativePath, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, sdPtr, size, &size)) { /* * Error getting owner SD */ |
︙ | ︙ | |||
1901 1902 1903 1904 1905 1906 1907 | const WCHAR *nativePath; nativePath = Tcl_FSGetNativePath(pathPtr); if (!nativePath) { return -1; } | | | 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 | const WCHAR *nativePath; nativePath = Tcl_FSGetNativePath(pathPtr); if (!nativePath) { return -1; } result = SetCurrentDirectoryW(nativePath); if (result == 0) { TclWinConvertError(GetLastError()); return -1; } return 0; } |
︙ | ︙ | |||
1942 1943 1944 1945 1946 1947 1948 | Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with * name of current directory. */ { WCHAR buffer[MAX_PATH]; char *p; WCHAR *native; | | | 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 | Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with * name of current directory. */ { WCHAR buffer[MAX_PATH]; char *p; WCHAR *native; if (GetCurrentDirectoryW(MAX_PATH, buffer) == 0) { TclWinConvertError(GetLastError()); if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error getting working directory name: %s", Tcl_PosixError(interp))); } return NULL; |
︙ | ︙ | |||
2043 2044 2045 2046 2047 2048 2049 | * CON, NULL, COM1, LPT1 etc. For these, we still need to do the * CreateFile as some may not exist (e.g. there is no CON in wish by * default). However the subsequent GetFileInformationByHandle will * fail. We do a WinIsReserved to see if it is one of the special names, * and if successful, mock up a BY_HANDLE_FILE_INFORMATION structure. */ | | | 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 | * CON, NULL, COM1, LPT1 etc. For these, we still need to do the * CreateFile as some may not exist (e.g. there is no CON in wish by * default). However the subsequent GetFileInformationByHandle will * fail. We do a WinIsReserved to see if it is one of the special names, * and if successful, mock up a BY_HANDLE_FILE_INFORMATION structure. */ fileHandle = CreateFileW(nativePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (fileHandle != INVALID_HANDLE_VALUE) { BY_HANDLE_FILE_INFORMATION data; |
︙ | ︙ | |||
2101 2102 2103 2104 2105 2106 2107 | } else { /* * Fall back on the less capable routines. This means no nlink or ino. */ WIN32_FILE_ATTRIBUTE_DATA data; | | | | | 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 | } else { /* * Fall back on the less capable routines. This means no nlink or ino. */ WIN32_FILE_ATTRIBUTE_DATA data; if (GetFileAttributesExW(nativePath, GetFileExInfoStandard, &data) != TRUE) { HANDLE hFind; WIN32_FIND_DATAW ffd; DWORD lasterror = GetLastError(); if (lasterror != ERROR_SHARING_VIOLATION) { TclWinConvertError(lasterror); return -1; } hFind = FindFirstFileW(nativePath, &ffd); if (hFind == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); return -1; } memcpy(&data, &ffd, sizeof(data)); FindClose(hFind); } |
︙ | ︙ | |||
2169 2170 2171 2172 2173 2174 2175 | { int dev; Tcl_DString ds; WCHAR nativeFullPath[MAX_PATH]; WCHAR *nativePart; const char *fullPath; | | | 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 | { int dev; Tcl_DString ds; WCHAR nativeFullPath[MAX_PATH]; WCHAR *nativePart; const char *fullPath; GetFullPathNameW(nativePath, MAX_PATH, nativeFullPath, &nativePart); Tcl_DStringInit(&ds); fullPath = Tcl_WCharToUtfDString(nativeFullPath, -1, &ds); if ((fullPath[0] == '\\') && (fullPath[1] == '\\')) { const char *p; DWORD dw; const WCHAR *nativeVol; |
︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 | p = fullPath + Tcl_DStringLength(&ds); } else { p++; } Tcl_DStringInit(&volString); nativeVol = Tcl_UtfToWCharDString(fullPath, p - fullPath, &volString); dw = (DWORD) -1; | | | | | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 | p = fullPath + Tcl_DStringLength(&ds); } else { p++; } Tcl_DStringInit(&volString); nativeVol = Tcl_UtfToWCharDString(fullPath, p - fullPath, &volString); dw = (DWORD) -1; GetVolumeInformationW(nativeVol, NULL, 0, &dw, NULL, NULL, NULL, 0); /* * GetFullPathNameW() turns special devices like "NUL" into "\\.\NUL", * but GetVolumeInformationW() returns failure for "\\.\NUL". This will * cause "NUL" to get a drive number of -1, which makes about as much * sense as anything since the special devices don't live on any * drive. */ dev = dw; Tcl_DStringFree(&volString); |
︙ | ︙ | |||
2341 2342 2343 2344 2345 2346 2347 | ClientData TclpGetNativeCwd( ClientData clientData) { WCHAR buffer[MAX_PATH]; | | | 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 | ClientData TclpGetNativeCwd( ClientData clientData) { WCHAR buffer[MAX_PATH]; if (GetCurrentDirectoryW(MAX_PATH, buffer) == 0) { TclWinConvertError(GetLastError()); return NULL; } if (clientData != NULL) { if (wcscmp((const WCHAR *) clientData, buffer) == 0) { return clientData; |
︙ | ︙ | |||
2457 2458 2459 2460 2461 2462 2463 | path = TclGetString(normPath); if (path == NULL) { return NULL; } firstSeparator = strchr(path, '/'); if (firstSeparator == NULL) { | | | | 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 | path = TclGetString(normPath); if (path == NULL) { return NULL; } firstSeparator = strchr(path, '/'); if (firstSeparator == NULL) { found = GetVolumeInformationW(Tcl_FSGetNativePath(pathPtr), NULL, 0, NULL, NULL, NULL, volType, VOL_BUF_SIZE); } else { Tcl_Obj *driveName = Tcl_NewStringObj(path, firstSeparator - path+1); Tcl_IncrRefCount(driveName); found = GetVolumeInformationW(Tcl_FSGetNativePath(driveName), NULL, 0, NULL, NULL, NULL, volType, VOL_BUF_SIZE); Tcl_DecrRefCount(driveName); } if (found == 0) { return NULL; } else { |
︙ | ︙ | |||
2550 2551 2552 2553 2554 2555 2556 | WIN32_FILE_ATTRIBUTE_DATA data; const WCHAR *nativePath; Tcl_DStringInit(&ds); nativePath = Tcl_UtfToWCharDString(path, currentPathEndPosition - path, &ds); | | | 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 | WIN32_FILE_ATTRIBUTE_DATA data; const WCHAR *nativePath; Tcl_DStringInit(&ds); nativePath = Tcl_UtfToWCharDString(path, currentPathEndPosition - path, &ds); if (GetFileAttributesExW(nativePath, GetFileExInfoStandard, &data) != TRUE) { /* * File doesn't exist. */ if (isDrive) { int len = WinIsReserved(path); |
︙ | ︙ | |||
3225 3226 3227 3228 3229 3230 3231 | FILETIME lastAccessTime, lastModTime; FromCTime(tval->actime, &lastAccessTime); FromCTime(tval->modtime, &lastModTime); native = Tcl_FSGetNativePath(pathPtr); | | | | 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 | FILETIME lastAccessTime, lastModTime; FromCTime(tval->actime, &lastAccessTime); FromCTime(tval->modtime, &lastModTime); native = Tcl_FSGetNativePath(pathPtr); attr = GetFileAttributesW(native); if (attr != INVALID_FILE_ATTRIBUTES && attr & FILE_ATTRIBUTE_DIRECTORY) { flags = FILE_FLAG_BACKUP_SEMANTICS; } /* * We use the native APIs (not 'utime') because there are some daylight * savings complications that utime gets wrong. */ fileHandle = CreateFileW(native, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, flags, NULL); if (fileHandle == INVALID_HANDLE_VALUE || !SetFileTime(fileHandle, NULL, &lastAccessTime, &lastModTime)) { TclWinConvertError(GetLastError()); res = -1; } |
︙ | ︙ | |||
3276 3277 3278 3279 3280 3281 3282 | HANDLE token; LPBYTE buf = NULL; DWORD bufsz; int owned = 0; native = Tcl_FSGetNativePath(pathPtr); | | | 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 | HANDLE token; LPBYTE buf = NULL; DWORD bufsz; int owned = 0; native = Tcl_FSGetNativePath(pathPtr); if (GetNamedSecurityInfoW((LPWSTR) native, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &ownerSid, NULL, NULL, NULL, &secd) != ERROR_SUCCESS) { /* * Either not a file, or we do not have access to it in which case we * are in all likelihood not the owner. */ |
︙ | ︙ |
Changes to win/tclWinInit.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | #include "tclWinInt.h" #include <winnt.h> #include <winbase.h> #include <lmcons.h> /* | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include "tclWinInt.h" #include <winnt.h> #include <winbase.h> #include <lmcons.h> /* * GetUserNameW() is found in advapi32.dll */ #ifdef _MSC_VER # pragma comment(lib, "advapi32.lib") #endif /* * The following declaration is a workaround for some Microsoft brain damage. |
︙ | ︙ | |||
145 146 147 148 149 150 151 | #ifdef STATIC_BUILD /* * If we are in a statically linked executable, then we need to explicitly * initialize the Windows function tables here since DllMain() will not be * invoked. */ | | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | #ifdef STATIC_BUILD /* * If we are in a statically linked executable, then we need to explicitly * initialize the Windows function tables here since DllMain() will not be * invoked. */ TclWinInit(GetModuleHandleW(NULL)); #endif /* * Fill available functions depending on windows version */ handle = GetModuleHandleW(L"KERNEL32"); tclWinProcs.cancelSynchronousIo = (BOOL (WINAPI *)(HANDLE)) GetProcAddress(handle, "CancelSynchronousIo"); } /* *------------------------------------------------------------------------- |
︙ | ︙ | |||
293 294 295 296 297 298 299 | objPtr = Tcl_NewStringObj(buf, -1); Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); TclWinNoBackslash(buf); Tcl_SplitPath(buf, &pathc, &pathv); /* | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | objPtr = Tcl_NewStringObj(buf, -1); Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); TclWinNoBackslash(buf); Tcl_SplitPath(buf, &pathc, &pathv); /* * The lstrcmpiA() will work even if pathv[pathc-1] is random UTF-8 * chars because I know shortlib is ascii. */ if ((pathc > 0) && (lstrcmpiA(shortlib, pathv[pathc - 1]) != 0)) { /* * TCL_LIBRARY is set but refers to a different tcl installation * than the current version. Try fiddling with the specified |
︙ | ︙ | |||
468 469 470 471 472 473 474 | { Tcl_DStringInit(bufferPtr); if (TclGetEnv("USERNAME", bufferPtr) == NULL) { WCHAR szUserName[UNLEN+1]; DWORD cchUserNameLen = UNLEN; | | | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | { Tcl_DStringInit(bufferPtr); if (TclGetEnv("USERNAME", bufferPtr) == NULL) { WCHAR szUserName[UNLEN+1]; DWORD cchUserNameLen = UNLEN; if (!GetUserNameW(szUserName, &cchUserNameLen)) { return NULL; } cchUserNameLen--; Tcl_DStringInit(bufferPtr); Tcl_WCharToUtfDString(szUserName, cchUserNameLen, bufferPtr); } return Tcl_DStringValue(bufferPtr); |
︙ | ︙ | |||
513 514 515 516 517 518 519 | static int osInfoInitialized = 0; Tcl_DString ds; Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL, TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY); if (!osInfoInitialized) { | | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | static int osInfoInitialized = 0; Tcl_DString ds; Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL, TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY); if (!osInfoInitialized) { HMODULE handle = GetModuleHandleW(L"NTDLL"); int(__stdcall *getversion)(void *) = (int(__stdcall *)(void *)) GetProcAddress(handle, "RtlGetVersion"); osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); if (!getversion || getversion(&osInfo)) { GetVersionExW(&osInfo); } osInfoInitialized = 1; |
︙ | ︙ |
Changes to win/tclWinLoad.c.
︙ | ︙ | |||
72 73 74 75 76 77 78 | * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ nativeName = Tcl_FSGetNativePath(pathPtr); if (nativeName != NULL) { | | | | 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 | * First try the full path the user gave us. This is particularly * important if the cwd is inside a vfs, and we are trying to load using a * relative path. */ nativeName = Tcl_FSGetNativePath(pathPtr); if (nativeName != NULL) { hInstance = LoadLibraryExW(nativeName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); } if (hInstance == NULL) { /* * Let the OS loader examine the binary search path for whatever * string the user gave us which hopefully refers to a file on the * binary path. */ Tcl_DString ds; /* * Remember the first error on load attempt to be used if the * second load attempt below also fails. */ firstError = (nativeName == NULL) ? ERROR_MOD_NOT_FOUND : GetLastError(); Tcl_DStringInit(&ds); nativeName = Tcl_UtfToWCharDString(TclGetString(pathPtr), -1, &ds); hInstance = LoadLibraryExW(nativeName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); Tcl_DStringFree(&ds); } if (hInstance == NULL) { DWORD lastError; Tcl_Obj *errMsg; |
︙ | ︙ |
Changes to win/tclWinNotify.c.
︙ | ︙ | |||
94 95 96 97 98 99 100 | /* * Register Notifier window class if this is the first thread to use * this module. */ EnterCriticalSection(¬ifierMutex); if (notifierCount == 0) { | | | | | 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 | /* * Register Notifier window class if this is the first thread to use * this module. */ EnterCriticalSection(¬ifierMutex); if (notifierCount == 0) { WNDCLASSW clazz; clazz.style = 0; clazz.cbClsExtra = 0; clazz.cbWndExtra = 0; clazz.hInstance = TclWinGetTclInstance(); clazz.hbrBackground = NULL; clazz.lpszMenuName = NULL; clazz.lpszClassName = className; clazz.lpfnWndProc = NotifierProc; clazz.hIcon = NULL; clazz.hCursor = NULL; if (!RegisterClassW(&clazz)) { Tcl_Panic("Unable to register TclNotifier window class"); } } notifierCount++; LeaveCriticalSection(¬ifierMutex); tsdPtr->pending = 0; tsdPtr->timerActive = 0; InitializeCriticalSection(&tsdPtr->crit); tsdPtr->hwnd = NULL; tsdPtr->thread = GetCurrentThreadId(); tsdPtr->event = CreateEventW(NULL, TRUE /* manual */, FALSE /* !signaled */, NULL); return tsdPtr; } } /* |
︙ | ︙ | |||
191 192 193 194 195 196 197 | * notifier window class. */ EnterCriticalSection(¬ifierMutex); if (notifierCount) { notifierCount--; if (notifierCount == 0) { | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | * notifier window class. */ EnterCriticalSection(¬ifierMutex); if (notifierCount) { notifierCount--; if (notifierCount == 0) { UnregisterClassW(className, TclWinGetTclInstance()); } } LeaveCriticalSection(¬ifierMutex); } } /* |
︙ | ︙ | |||
243 244 245 246 247 248 249 | if (tsdPtr->hwnd) { /* * We do need to lock around access to the pending flag. */ EnterCriticalSection(&tsdPtr->crit); if (!tsdPtr->pending) { | | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | if (tsdPtr->hwnd) { /* * We do need to lock around access to the pending flag. */ EnterCriticalSection(&tsdPtr->crit); if (!tsdPtr->pending) { PostMessageW(tsdPtr->hwnd, WM_WAKEUP, 0, 0); } tsdPtr->pending = 1; LeaveCriticalSection(&tsdPtr->crit); } else { SetEvent(tsdPtr->event); } } |
︙ | ︙ | |||
355 356 357 358 359 360 361 | * or Windows will hang waiting for the window to respond to * synchronous system messages. At some point, we may want to consider * destroying the window if we leave the modal loop, but for now we'll * leave it around. */ if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) { | | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | * or Windows will hang waiting for the window to respond to * synchronous system messages. At some point, we may want to consider * destroying the window if we leave the modal loop, but for now we'll * leave it around. */ if (mode == TCL_SERVICE_ALL && !tsdPtr->hwnd) { tsdPtr->hwnd = CreateWindowW(className, className, WS_TILED, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); /* * Send an initial message to the window to ensure that we wake up * the notifier once we get into the modal loop. This will force * the notifier to recompute the timeout value and schedule a timer |
︙ | ︙ | |||
403 404 405 406 407 408 409 | ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (message == WM_WAKEUP) { EnterCriticalSection(&tsdPtr->crit); tsdPtr->pending = 0; LeaveCriticalSection(&tsdPtr->crit); } else if (message != WM_TIMER) { | | | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (message == WM_WAKEUP) { EnterCriticalSection(&tsdPtr->crit); tsdPtr->pending = 0; LeaveCriticalSection(&tsdPtr->crit); } else if (message != WM_TIMER) { return DefWindowProcW(hwnd, message, wParam, lParam); } /* * Process all of the runnable events. */ Tcl_ServiceAll(); |
︙ | ︙ | |||
475 476 477 478 479 480 481 | /* * Check to see if there are any messages in the queue before waiting * because MsgWaitForMultipleObjects will not wake up if there are * events currently sitting in the queue. */ | | | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | /* * Check to see if there are any messages in the queue before waiting * because MsgWaitForMultipleObjects will not wake up if there are * events currently sitting in the queue. */ if (!PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) { /* * Wait for something to happen (a signal from another thread, a * message, or timeout) or loop servicing asynchronous procedure * calls queued to this thread. */ again: |
︙ | ︙ | |||
497 498 499 500 501 502 503 | } } /* * Check to see if there are any messages to process. */ | | | | | 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 | } } /* * Check to see if there are any messages to process. */ if (PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE)) { /* * Retrieve and dispatch the first message. */ result = GetMessageW(&msg, NULL, 0, 0); if (result == 0) { /* * We received a request to exit this thread (WM_QUIT), so * propagate the quit message and start unwinding. */ PostQuitMessage((int) msg.wParam); status = -1; } else if (result == (DWORD)-1) { /* * We got an error from the system. I have no idea why this * would happen, so we'll just unwind. */ status = -1; } else { TranslateMessage(&msg); DispatchMessageW(&msg); status = 1; } } else { status = 0; } end: |
︙ | ︙ |
Changes to win/tclWinPipe.c.
︙ | ︙ | |||
462 463 464 465 466 467 468 | static int TempFileName( WCHAR name[MAX_PATH]) /* Buffer in which name for temporary file * gets stored. */ { const WCHAR *prefix = L"TCL"; | | | | | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | static int TempFileName( WCHAR name[MAX_PATH]) /* Buffer in which name for temporary file * gets stored. */ { const WCHAR *prefix = L"TCL"; if (GetTempPathW(MAX_PATH, name) != 0) { if (GetTempFileNameW(name, prefix, 0, name) != 0) { return 1; } } name[0] = '.'; name[1] = '\0'; return GetTempFileNameW(name, prefix, 0, name); } /* *---------------------------------------------------------------------- * * TclpMakeFile -- * |
︙ | ︙ | |||
582 583 584 585 586 587 588 | /* * If the file is not being created, use the existing file attributes. */ flags = 0; if (!(mode & O_CREAT)) { | | | | 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 | /* * If the file is not being created, use the existing file attributes. */ flags = 0; if (!(mode & O_CREAT)) { flags = GetFileAttributesW(nativePath); if (flags == 0xFFFFFFFF) { flags = 0; } } /* * Set up the file sharing mode. We want to allow simultaneous access. */ shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; /* * Now we get to create the file. */ handle = CreateFileW(nativePath, accessMode, shareMode, NULL, createMode, flags, NULL); Tcl_DStringFree(&ds); if (handle == INVALID_HANDLE_VALUE) { DWORD err; err = GetLastError(); |
︙ | ︙ | |||
655 656 657 658 659 660 661 | Tcl_DString dstring; HANDLE handle; if (TempFileName(name) == 0) { return NULL; } | | | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | Tcl_DString dstring; HANDLE handle; if (TempFileName(name) == 0) { return NULL; } handle = CreateFileW(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL); if (handle == INVALID_HANDLE_VALUE) { goto error; } /* |
︙ | ︙ | |||
717 718 719 720 721 722 723 | if (contents != NULL) { Tcl_DStringFree(&dstring); } TclWinConvertError(GetLastError()); CloseHandle(handle); | | | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | if (contents != NULL) { Tcl_DStringFree(&dstring); } TclWinConvertError(GetLastError()); CloseHandle(handle); DeleteFileW(name); return NULL; } /* *---------------------------------------------------------------------- * * TclpTempFileName -- |
︙ | ︙ | |||
933 934 935 936 937 938 939 | * may be the same as outputFile. */ Tcl_Pid *pidPtr) /* If this function is successful, pidPtr is * filled with the process id of the child * process. */ { int result, applType, createFlags; Tcl_DString cmdLine; /* Complete command line (WCHAR). */ | | | 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 | * may be the same as outputFile. */ Tcl_Pid *pidPtr) /* If this function is successful, pidPtr is * filled with the process id of the child * process. */ { int result, applType, createFlags; Tcl_DString cmdLine; /* Complete command line (WCHAR). */ STARTUPINFOW startInfo; PROCESS_INFORMATION procInfo; SECURITY_ATTRIBUTES secAtts; HANDLE hProcess, h, inputHandle, outputHandle, errorHandle; char execPath[MAX_PATH * 3]; WinFile *filePtr; PipeInit(); |
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | * the child process would hang forever waiting for input from the * unmapped console window used by the helper application. * * Fortunately, the helper application will detect a closed pipe as a * sink. */ | | | | 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 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 | * the child process would hang forever waiting for input from the * unmapped console window used by the helper application. * * Fortunately, the helper application will detect a closed pipe as a * sink. */ startInfo.hStdOutput = CreateFileW(L"NUL:", GENERIC_WRITE, 0, &secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } else { DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't duplicate output handle: %s", Tcl_PosixError(interp))); goto end; } if (errorHandle == INVALID_HANDLE_VALUE) { /* * If handle was not set, errors should be sent to an infinitely deep * sink. */ startInfo.hStdError = CreateFileW(L"NUL:", GENERIC_WRITE, 0, &secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); } if (startInfo.hStdError == INVALID_HANDLE_VALUE) { TclWinConvertError(GetLastError()); |
︙ | ︙ | |||
1130 1131 1132 1133 1134 1135 1136 | * Additionally, when calling a 16-bit dos or windows application, all * path names must use the short, cryptic, path format (e.g., using * ab~1.def instead of "a b.default"). */ BuildCommandLine(execPath, argc, argv, &cmdLine); | | | 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 | * Additionally, when calling a 16-bit dos or windows application, all * path names must use the short, cryptic, path format (e.g., using * ab~1.def instead of "a b.default"). */ BuildCommandLine(execPath, argc, argv, &cmdLine); if (CreateProcessW(NULL, (WCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) { TclWinConvertError(GetLastError()); Tcl_SetObjResult(interp, Tcl_ObjPrintf("couldn't execute \"%s\": %s", argv[0], Tcl_PosixError(interp))); goto end; } |
︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | } /* * "When an application spawns a process repeatedly, a new thread instance * will be created for each process but the previous instances may not be * cleaned up. This results in a significant virtual memory loss each time * the process is spawned. If there is a WaitForInputIdle() call between | | | 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 | } /* * "When an application spawns a process repeatedly, a new thread instance * will be created for each process but the previous instances may not be * cleaned up. This results in a significant virtual memory loss each time * the process is spawned. If there is a WaitForInputIdle() call between * CreateProcessW() and CloseHandle(), the problem does not occur." PSS ID * Number: Q124121 */ WaitForInputIdle(procInfo.hProcess, 5000); CloseHandle(procInfo.hThread); *pidPtr = (Tcl_Pid) (size_t) procInfo.dwProcessId; |
︙ | ︙ | |||
1271 1272 1273 1274 1275 1276 1277 | static const char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; /* * Look for the program as an external program. First try the name as it * is, then try adding .com, .exe, .bat and .cmd, in that order, to the name, * looking for an executable. * | | | | | | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 | static const char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; /* * Look for the program as an external program. First try the name as it * is, then try adding .com, .exe, .bat and .cmd, in that order, to the name, * looking for an executable. * * Using the raw SearchPathW() function doesn't do quite what is necessary. * If the name of the executable already contains a '.' character, it will * not try appending the specified extension when searching (in other * words, SearchPath will not find the program "a.b.exe" if the arguments * specified "a.b" and ".exe"). So, first look for the file as it is * named. Then manually append the extensions, looking for a match. */ applType = APPL_NONE; Tcl_DStringInit(&nameBuf); Tcl_DStringAppend(&nameBuf, originalName, -1); nameLen = Tcl_DStringLength(&nameBuf); for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { Tcl_DStringSetLength(&nameBuf, nameLen); Tcl_DStringAppend(&nameBuf, extensions[i], -1); Tcl_DStringInit(&ds); nativeName = Tcl_UtfToWCharDString(Tcl_DStringValue(&nameBuf), Tcl_DStringLength(&nameBuf), &ds); found = SearchPathW(NULL, nativeName, NULL, MAX_PATH, nativeFullPath, &rest); Tcl_DStringFree(&ds); if (found == 0) { continue; } /* * Ignore matches on directories or data files, return if identified a * known type. */ attr = GetFileAttributesW(nativeFullPath); if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { continue; } Tcl_DStringInit(&ds); strcpy(fullName, Tcl_WCharToUtfDString(nativeFullPath, -1, &ds)); Tcl_DStringFree(&ds); ext = strrchr(fullName, '.'); if ((ext != NULL) && (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) { applType = APPL_DOS; break; } hFile = CreateFileW(nativeFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { continue; } header.e_magic = 0; |
︙ | ︙ | |||
1397 1398 1399 1400 1401 1402 1403 | /* * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able to * correctly parse its own command line to separate off the * application name from the arguments. */ | | | | 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 | /* * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able to * correctly parse its own command line to separate off the * application name from the arguments. */ GetShortPathNameW(nativeFullPath, nativeFullPath, MAX_PATH); Tcl_DStringInit(&ds); strcpy(fullName, Tcl_WCharToUtfDString(nativeFullPath, -1, &ds)); Tcl_DStringFree(&ds); } return applType; } /* *---------------------------------------------------------------------- * * BuildCommandLine -- * * The command line arguments are stored in linePtr separated by spaces, * in a form that CreateProcessW() understands. Special characters in * individual arguments from argv[] must be quoted when being stored in * cmdLine. * * Results: * None. * * Side effects: |
︙ | ︙ | |||
1785 1786 1787 1788 1789 1790 1791 | infoPtr->threadId = Tcl_GetCurrentThread(); if (readFile != NULL) { /* * Start the background reader thread. */ | | | | 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 | infoPtr->threadId = Tcl_GetCurrentThread(); if (readFile != NULL) { /* * Start the background reader thread. */ infoPtr->readable = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->readThread = CreateThread(NULL, 256, PipeReaderThread, TclPipeThreadCreateTI(&infoPtr->readTI, infoPtr, infoPtr->readable), 0, NULL); SetThreadPriority(infoPtr->readThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_READABLE; } else { infoPtr->readTI = NULL; infoPtr->readThread = 0; } if (writeFile != NULL) { /* * Start the background writer thread. */ infoPtr->writable = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, PipeWriterThread, TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, infoPtr->writable), 0, NULL); SetThreadPriority(infoPtr->writeThread, THREAD_PRIORITY_HIGHEST); infoPtr->validMask |= TCL_WRITABLE; } else { infoPtr->writeTI = NULL; |
︙ | ︙ | |||
3203 3204 3205 3206 3207 3208 3209 | Tcl_DString buf; if (!resultingNameObj) { flags |= FILE_FLAG_DELETE_ON_CLOSE; } namePtr = (char *) name; | | | 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 | Tcl_DString buf; if (!resultingNameObj) { flags |= FILE_FLAG_DELETE_ON_CLOSE; } namePtr = (char *) name; length = GetTempPathW(MAX_PATH, name); if (length == 0) { goto gotError; } namePtr += length * sizeof(WCHAR); if (basenameObj) { const char *string = TclGetStringFromObj(basenameObj, &length); |
︙ | ︙ | |||
3238 3239 3240 3241 3242 3243 3244 | counter = (unsigned short) (counter + 1); Tcl_DStringInit(&buf); Tcl_UtfToWCharDString(number, strlen(number), &buf); Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf) + 1); memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf) + 1); Tcl_DStringFree(&buf); | | | 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 | counter = (unsigned short) (counter + 1); Tcl_DStringInit(&buf); Tcl_UtfToWCharDString(number, strlen(number), &buf); Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf) + 1); memcpy(namePtr, Tcl_DStringValue(&buf), Tcl_DStringLength(&buf) + 1); Tcl_DStringFree(&buf); handle = CreateFileW(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, flags, NULL); } while (handle == INVALID_HANDLE_VALUE && --counter2 > 0 && GetLastError() == ERROR_FILE_EXISTS); if (handle == INVALID_HANDLE_VALUE) { goto gotError; } |
︙ | ︙ | |||
3287 3288 3289 3290 3291 3292 3293 | { TclPipeThreadInfo *pipeTI; #ifndef _PTI_USE_CKALLOC pipeTI = malloc(sizeof(TclPipeThreadInfo)); #else pipeTI = Tcl_Alloc(sizeof(TclPipeThreadInfo)); #endif /* !_PTI_USE_CKALLOC */ | | | 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 | { TclPipeThreadInfo *pipeTI; #ifndef _PTI_USE_CKALLOC pipeTI = malloc(sizeof(TclPipeThreadInfo)); #else pipeTI = Tcl_Alloc(sizeof(TclPipeThreadInfo)); #endif /* !_PTI_USE_CKALLOC */ pipeTI->evControl = CreateEventW(NULL, FALSE, FALSE, NULL); pipeTI->state = PTI_STATE_IDLE; pipeTI->clientData = clientData; pipeTI->evWakeUp = wakeEvent; return (*pipeTIPtr = pipeTI); } /* |
︙ | ︙ |
Changes to win/tclWinSerial.c.
︙ | ︙ | |||
1287 1288 1289 1290 1291 1292 1293 | break; } infoPtr = (SerialInfo *) pipeTI->clientData; buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; | | | 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 | break; } infoPtr = (SerialInfo *) pipeTI->clientData; buf = infoPtr->writeBuf; toWrite = infoPtr->toWrite; myWrite.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); /* * Loop until all of the bytes are written or an error occurs. */ while (toWrite > 0) { /* |
︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 | { SerialInit(); /* * If an open channel is specified, close it */ | | | | 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | { SerialInit(); /* * If an open channel is specified, close it */ if (handle != INVALID_HANDLE_VALUE && CloseHandle(handle) == FALSE) { return INVALID_HANDLE_VALUE; } /* * Multithreaded I/O needs the overlapped flag set otherwise * ClearCommError blocks under Windows NT/2000 until serial output is * finished */ handle = CreateFileW(name, access, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); return handle; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1482 1483 1484 1485 1486 1487 1488 | * Default is blocking. */ SetCommTimeouts(handle, &no_timeout); InitializeCriticalSection(&infoPtr->csWrite); if (permissions & TCL_READABLE) { | | | | | 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 | * Default is blocking. */ SetCommTimeouts(handle, &no_timeout); InitializeCriticalSection(&infoPtr->csWrite); if (permissions & TCL_READABLE) { infoPtr->osRead.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); } if (permissions & TCL_WRITABLE) { /* * Initially the channel is writable and the writeThread is idle. */ infoPtr->osWrite.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); infoPtr->evWritable = CreateEventW(NULL, TRUE, TRUE, NULL); infoPtr->writeThread = CreateThread(NULL, 256, SerialWriterThread, TclPipeThreadCreateTI(&infoPtr->writeTI, infoPtr, infoPtr->evWritable), 0, NULL); } /* * Files have default translation of AUTO and ^Z eof char, which means |
︙ | ︙ | |||
1667 1668 1669 1670 1671 1672 1673 | if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) { if (!GetCommState(infoPtr->handle, &dcb)) { goto getStateFailed; } Tcl_DStringInit(&ds); native = Tcl_UtfToWCharDString(value, -1, &ds); | | | 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 | if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) { if (!GetCommState(infoPtr->handle, &dcb)) { goto getStateFailed; } Tcl_DStringInit(&ds); native = Tcl_UtfToWCharDString(value, -1, &ds); result = BuildCommDCBW(native, &dcb); Tcl_DStringFree(&ds); if (result == FALSE) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad value \"%s\" for -mode: should be baud,parity,data,stop", value)); |
︙ | ︙ |
Changes to win/tclWinSock.c.
︙ | ︙ | |||
231 232 233 234 235 236 237 | * list. This value is also checked by * the event structure. */ TcpState *socketList; /* Every open socket in this thread has an * entry on this list. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | * list. This value is also checked by * the event structure. */ TcpState *socketList; /* Every open socket in this thread has an * entry on this list. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; static WNDCLASSW windowClass; /* * Static routines for this file: */ static int TcpConnect(Tcl_Interp *interp, TcpState *state); |
︙ | ︙ | |||
359 360 361 362 363 364 365 | void InitializeHostName( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) { | | | | | 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 | void InitializeHostName( char **valuePtr, size_t *lengthPtr, Tcl_Encoding *encodingPtr) { WCHAR wbuf[MAX_COMPUTERNAME_LENGTH + 1]; DWORD length = MAX_COMPUTERNAME_LENGTH + 1; Tcl_DString ds; Tcl_DStringInit(&ds); if (GetComputerNameW(wbuf, &length) != 0) { /* * Convert string from native to UTF then change to lowercase. */ Tcl_UtfToLower(Tcl_WCharToUtfDString(wbuf, -1, &ds)); } else { if (TclpHasSockets(NULL) == TCL_OK) { /* * The buffer size of 256 is recommended by the MSDN page that * documents gethostname() as being always adequate. */ |
︙ | ︙ | |||
2500 2501 2502 2503 2504 2505 2506 | windowClass.hbrBackground = NULL; windowClass.lpszMenuName = NULL; windowClass.lpszClassName = className; windowClass.lpfnWndProc = SocketProc; windowClass.hIcon = NULL; windowClass.hCursor = NULL; | | | 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 | windowClass.hbrBackground = NULL; windowClass.lpszMenuName = NULL; windowClass.lpszClassName = className; windowClass.lpfnWndProc = SocketProc; windowClass.hIcon = NULL; windowClass.hCursor = NULL; if (!RegisterClassW(&windowClass)) { TclWinConvertError(GetLastError()); goto initFailure; } } /* * Check for per-thread initialization. |
︙ | ︙ | |||
2625 2626 2627 2628 2629 2630 2631 | /* * Make sure the socket event handling window is cleaned-up for, at * most, this thread. */ TclpFinalizeSockets(); | | | 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 | /* * Make sure the socket event handling window is cleaned-up for, at * most, this thread. */ TclpFinalizeSockets(); UnregisterClassW(className, TclWinGetTclInstance()); initialized = 0; Tcl_MutexUnlock(&socketMutex); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
3172 3173 3174 3175 3176 3177 3178 | MSG msg; ThreadSpecificData *tsdPtr = arg; /* * Create a dummy window receiving socket events. */ | | | 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 | MSG msg; ThreadSpecificData *tsdPtr = arg; /* * Create a dummy window receiving socket events. */ tsdPtr->hwnd = CreateWindowW(className, className, WS_TILED, 0, 0, 0, 0, NULL, NULL, windowClass.hInstance, arg); /* * Signalize thread creator that we are done creating the window. */ SetEvent(tsdPtr->readyEvent); |
︙ | ︙ | |||
3195 3196 3197 3198 3199 3200 3201 | /* * Process all messages on the socket window until WM_QUIT. This threads * exits only when instructed to do so by the call to * PostMessage(SOCKET_TERMINATE) in TclpFinalizeSockets(). */ | | | | 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 | /* * Process all messages on the socket window until WM_QUIT. This threads * exits only when instructed to do so by the call to * PostMessage(SOCKET_TERMINATE) in TclpFinalizeSockets(). */ while (GetMessageW(&msg, NULL, 0, 0) > 0) { DispatchMessageW(&msg); } /* * This releases waiters on thread exit in TclpFinalizeSockets() */ SetEvent(tsdPtr->readyEvent); |
︙ | ︙ | |||
3241 3242 3243 3244 3245 3246 3247 | int event, error; SOCKET socket; TcpState *statePtr; int info_found = 0; TcpFdList *fds = NULL; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) #ifdef _WIN64 | | | | 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 | int event, error; SOCKET socket; TcpState *statePtr; int info_found = 0; TcpFdList *fds = NULL; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) #ifdef _WIN64 GetWindowLongPtrW(hwnd, GWLP_USERDATA); #else GetWindowLong(hwnd, GWL_USERDATA); #endif switch (message) { default: return DefWindowProcW(hwnd, message, wParam, lParam); break; case WM_CREATE: /* * Store the initial tsdPtr, it's from a different thread, so it's not * directly accessible, but needed. */ |
︙ | ︙ |
Changes to win/tclWinTest.c.
︙ | ︙ | |||
132 133 134 135 136 137 138 | * that we do not explicitly call Tcl_ServiceEvent(). */ done = 0; while (!done) { MSG msg; | | | | 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 | * that we do not explicitly call Tcl_ServiceEvent(). */ done = 0; while (!done) { MSG msg; if (!GetMessageW(&msg, NULL, 0, 0)) { /* * The application is exiting, so repost the quit message and * start unwinding. */ PostQuitMessage((int) msg.wParam); break; } TranslateMessage(&msg); DispatchMessageW(&msg); } (void) Tcl_SetServiceMode(oldMode); framePtr = oldFramePtr; } else { Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be done or wait", NULL); return TCL_ERROR; |
︙ | ︙ |
Changes to win/tclWinThrd.c.
︙ | ︙ | |||
678 679 680 681 682 683 684 | TclpMasterLock(); /* * Create the per-thread event and queue pointers. */ if (tsdPtr->flags == WIN_THREAD_UNINIT) { | | | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 | TclpMasterLock(); /* * Create the per-thread event and queue pointers. */ if (tsdPtr->flags == WIN_THREAD_UNINIT) { tsdPtr->condEvent = CreateEventW(NULL, TRUE /* manual reset */, FALSE /* non signaled */, NULL); tsdPtr->nextPtr = NULL; tsdPtr->prevPtr = NULL; tsdPtr->flags = WIN_THREAD_RUNNING; doExit = 1; } TclpMasterUnlock(); |
︙ | ︙ |
Changes to win/tclWinTime.c.
︙ | ︙ | |||
516 517 518 519 520 521 522 | * calibrate it. */ if (timeInfo.perfCounterAvailable) { DWORD id; InitializeCriticalSection(&timeInfo.cs); | | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | * calibrate it. */ if (timeInfo.perfCounterAvailable) { DWORD id; InitializeCriticalSection(&timeInfo.cs); timeInfo.readyEvent = CreateEventW(NULL, FALSE, FALSE, NULL); timeInfo.exitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); timeInfo.calibrationThread = CreateThread(NULL, 256, CalibrationThread, (LPVOID) NULL, 0, &id); SetThreadPriority(timeInfo.calibrationThread, THREAD_PRIORITY_HIGHEST); /* * Wait for the thread just launched to start running, and |
︙ | ︙ |