diff options
Diffstat (limited to 'win/tclWinFCmd.c')
| -rw-r--r-- | win/tclWinFCmd.c | 443 | 
1 files changed, 170 insertions, 273 deletions
| diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c index aa80297..52ea8c6 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -8,8 +8,6 @@   *   * See the file "license.terms" for information on usage and redistribution of   * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclWinFCmd.c,v 1.52.8.1 2010/09/08 15:42:13 dgp Exp $   */  #include "tclWinInt.h" @@ -52,16 +50,16 @@ enum {      WIN_SYSTEM_ATTRIBUTE  }; -static int attributeArray[] = {FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN, +static const int attributeArray[] = {FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN,  	0, FILE_ATTRIBUTE_READONLY, 0, FILE_ATTRIBUTE_SYSTEM}; -CONST char *tclpFileAttrStrings[] = { +const char *const tclpFileAttrStrings[] = {  	"-archive", "-hidden", "-longname", "-readonly",  	"-shortname", "-system", (char *) NULL  }; -CONST TclFileAttrProcs tclpFileAttrProcs[] = { +const TclFileAttrProcs tclpFileAttrProcs[] = {  	{GetWinFileAttributes, SetWinFileAttributes},  	{GetWinFileAttributes, SetWinFileAttributes},  	{GetWinFileLongName, CannotSetAttribute}, @@ -69,30 +67,11 @@ CONST TclFileAttrProcs tclpFileAttrProcs[] = {  	{GetWinFileShortName, CannotSetAttribute},  	{GetWinFileAttributes, SetWinFileAttributes}}; -#ifdef HAVE_NO_SEH - -/* - * Unlike Borland and Microsoft, we don't register exception handlers by - * pushing registration records onto the runtime stack. Instead, we register - * them by creating an EXCEPTION_REGISTRATION within the activation record. - */ - -typedef struct EXCEPTION_REGISTRATION { -    struct EXCEPTION_REGISTRATION *link; -    EXCEPTION_DISPOSITION (*handler)( -	    struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); -    void *ebp; -    void *esp; -    int status; -} EXCEPTION_REGISTRATION; - -#endif -  /*   * Prototype for the TraverseWinTree callback function.   */ -typedef int (TraversalProc)(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr, +typedef int (TraversalProc)(const TCHAR *srcPtr, const TCHAR *dstPtr,  	int type, Tcl_DString *errorPtr);  /* @@ -103,18 +82,18 @@ static void		StatError(Tcl_Interp *interp, Tcl_Obj *fileName);  static int		ConvertFileNameFormat(Tcl_Interp *interp,  			    int objIndex, Tcl_Obj *fileName, int longShort,  			    Tcl_Obj **attributePtrPtr); -static int		DoCopyFile(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr); -static int		DoCreateDirectory(CONST TCHAR *pathPtr); -static int		DoRemoveJustDirectory(CONST TCHAR *nativeSrc, +static int		DoCopyFile(const TCHAR *srcPtr, const TCHAR *dstPtr); +static int		DoCreateDirectory(const TCHAR *pathPtr); +static int		DoRemoveJustDirectory(const TCHAR *nativeSrc,  			    int ignoreError, Tcl_DString *errorPtr);  static int		DoRemoveDirectory(Tcl_DString *pathPtr, int recursive,  			    Tcl_DString *errorPtr); -static int		DoRenameFile(CONST TCHAR *nativeSrc, -			    CONST TCHAR *dstPtr); -static int		TraversalCopy(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr, +static int		DoRenameFile(const TCHAR *nativeSrc, +			    const TCHAR *dstPtr); +static int		TraversalCopy(const TCHAR *srcPtr, const TCHAR *dstPtr,  			    int type, Tcl_DString *errorPtr); -static int		TraversalDelete(CONST TCHAR *srcPtr, -			    CONST TCHAR *dstPtr, int type, +static int		TraversalDelete(const TCHAR *srcPtr, +			    const TCHAR *dstPtr, int type,  			    Tcl_DString *errorPtr);  static int		TraverseWinTree(TraversalProc *traverseProc,  			    Tcl_DString *sourcePtr, Tcl_DString *dstPtr, @@ -172,13 +151,13 @@ TclpObjRenameFile(  static int  DoRenameFile( -    CONST TCHAR *nativeSrc,	/* Pathname of file or dir to be renamed +    const TCHAR *nativeSrc,	/* Pathname of file or dir to be renamed  				 * (native). */ -    CONST TCHAR *nativeDst)	/* New pathname for file or directory +    const TCHAR *nativeDst)	/* New pathname for file or directory  				 * (native). */  { -#ifdef HAVE_NO_SEH -    EXCEPTION_REGISTRATION registration; +#if defined(HAVE_NO_SEH) && !defined(_WIN64) +    TCLEXCEPTION_REGISTRATION registration;  #endif      DWORD srcAttr, dstAttr;      int retval = -1; @@ -215,7 +194,7 @@ DoRenameFile(  	"movl	    %[nativeSrc],   %%ecx"	    "\n\t"  	/* -	 * Construct an EXCEPTION_REGISTRATION to protect the call to +	 * Construct an TCLEXCEPTION_REGISTRATION to protect the call to  	 * MoveFile.  	 */ @@ -229,7 +208,7 @@ DoRenameFile(  	"movl	    $0,		    0x10(%%edx)"    "\n\t" /* status */  	/* -	 * Link the EXCEPTION_REGISTRATION on the chain. +	 * Link the TCLEXCEPTION_REGISTRATION on the chain.  	 */  	"movl	    %%edx,	    %%fs:0"	    "\n\t" @@ -244,7 +223,7 @@ DoRenameFile(  	"call	    *%%eax"			    "\n\t"  	/* -	 * Come here on normal exit. Recover the EXCEPTION_REGISTRATION and +	 * Come here on normal exit. Recover the TCLEXCEPTION_REGISTRATION and  	 * put the status return from MoveFile into it.  	 */ @@ -253,7 +232,7 @@ DoRenameFile(  	"jmp	    2f"				    "\n"  	/* -	 * Come here on an exception. Recover the EXCEPTION_REGISTRATION +	 * Come here on an exception. Recover the TCLEXCEPTION_REGISTRATION  	 */  	"1:"					    "\t" @@ -262,7 +241,7 @@ DoRenameFile(  	/*  	 * Come here however we exited. Restore context from the -	 * EXCEPTION_REGISTRATION in case the stack is unbalanced. +	 * TCLEXCEPTION_REGISTRATION in case the stack is unbalanced.  	 */  	"2:"					    "\t" @@ -277,7 +256,7 @@ DoRenameFile(  	[registration]	"m"	(registration),  	[nativeDst]	"m"	(nativeDst),  	[nativeSrc]	"m"	(nativeSrc), -	[moveFile]	"r"	(tclWinProcs->moveFileProc) +	[moveFile]	"r"	(MoveFile)  	:  	"%eax", "%ebx", "%ecx", "%edx", "memory"  	); @@ -288,7 +267,7 @@ DoRenameFile(  #ifndef HAVE_NO_SEH      __try {  #endif -	if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) { +	if ((*MoveFile)(nativeSrc, nativeDst) != FALSE) {  	    retval = TCL_OK;  	}  #ifndef HAVE_NO_SEH @@ -302,10 +281,10 @@ DoRenameFile(      TclWinConvertError(GetLastError()); -    srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc); -    dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst); +    srcAttr = GetFileAttributes(nativeSrc); +    dstAttr = GetFileAttributes(nativeDst);      if (srcAttr == 0xffffffff) { -	if ((*tclWinProcs->getFullPathNameProc)(nativeSrc, 0, NULL, +	if (GetFullPathName(nativeSrc, 0, NULL,  		NULL) >= MAX_PATH) {  	    errno = ENAMETOOLONG;  	    return TCL_ERROR; @@ -313,7 +292,7 @@ DoRenameFile(  	srcAttr = 0;      }      if (dstAttr == 0xffffffff) { -	if ((*tclWinProcs->getFullPathNameProc)(nativeDst, 0, NULL, +	if (GetFullPathName(nativeDst, 0, NULL,  		NULL) >= MAX_PATH) {  	    errno = ENAMETOOLONG;  	    return TCL_ERROR; @@ -329,28 +308,28 @@ DoRenameFile(      decode:  	if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {  	    TCHAR *nativeSrcRest, *nativeDstRest; -	    CONST char **srcArgv, **dstArgv; +	    const char **srcArgv, **dstArgv;  	    int size, srcArgc, dstArgc; -	    WCHAR nativeSrcPath[MAX_PATH]; -	    WCHAR nativeDstPath[MAX_PATH]; +	    TCHAR nativeSrcPath[MAX_PATH]; +	    TCHAR nativeDstPath[MAX_PATH];  	    Tcl_DString srcString, dstString; -	    CONST char *src, *dst; +	    const char *src, *dst; -	    size = (*tclWinProcs->getFullPathNameProc)(nativeSrc, MAX_PATH, +	    size = GetFullPathName(nativeSrc, MAX_PATH,  		    nativeSrcPath, &nativeSrcRest);  	    if ((size == 0) || (size > MAX_PATH)) {  		return TCL_ERROR;  	    } -	    size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH, +	    size = GetFullPathName(nativeDst, MAX_PATH,  		    nativeDstPath, &nativeDstRest);  	    if ((size == 0) || (size > MAX_PATH)) {  		return TCL_ERROR;  	    } -	    (*tclWinProcs->charLowerProc)((TCHAR *) nativeSrcPath); -	    (*tclWinProcs->charLowerProc)((TCHAR *) nativeDstPath); +	    CharLower(nativeSrcPath); +	    CharLower(nativeDstPath); -	    src = Tcl_WinTCharToUtf((TCHAR *) nativeSrcPath, -1, &srcString); -	    dst = Tcl_WinTCharToUtf((TCHAR *) nativeDstPath, -1, &dstString); +	    src = Tcl_WinTCharToUtf(nativeSrcPath, -1, &srcString); +	    dst = Tcl_WinTCharToUtf(nativeDstPath, -1, &dstString);  	    /*  	     * Check whether the destination path is actually inside the @@ -397,8 +376,8 @@ DoRenameFile(  		Tcl_SetErrno(EXDEV);  	    } -	    ckfree((char *) srcArgv); -	    ckfree((char *) dstArgv); +	    ckfree(srcArgv); +	    ckfree(dstArgv);  	}  	/* @@ -429,7 +408,7 @@ DoRenameFile(  		     * directory back, for completeness.  		     */ -		    if ((*tclWinProcs->moveFileProc)(nativeSrc, +		    if (MoveFile(nativeSrc,  			    nativeDst) != FALSE) {  			return TCL_OK;  		    } @@ -440,8 +419,8 @@ DoRenameFile(  		     */  		    TclWinConvertError(GetLastError()); -		    (*tclWinProcs->createDirectoryProc)(nativeDst, NULL); -		    (*tclWinProcs->setFileAttributesProc)(nativeDst, dstAttr); +		    CreateDirectory(nativeDst, NULL); +		    SetFileAttributes(nativeDst, dstAttr);  		    if (Tcl_GetErrno() == EACCES) {  			/*  			 * Decode the EACCES to a more meaningful error. @@ -468,22 +447,20 @@ DoRenameFile(  		TCHAR *nativeRest, *nativeTmp, *nativePrefix;  		int result, size; -		WCHAR tempBuf[MAX_PATH]; +		TCHAR tempBuf[MAX_PATH]; -		size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH, +		size = GetFullPathName(nativeDst, MAX_PATH,  			tempBuf, &nativeRest);  		if ((size == 0) || (size > MAX_PATH) || (nativeRest == NULL)) {  		    return TCL_ERROR;  		}  		nativeTmp = (TCHAR *) tempBuf; -		((char *) nativeRest)[0] = '\0'; -		((char *) nativeRest)[1] = '\0';    /* In case it's Unicode. */ +		nativeRest[0] = L'\0';  		result = TCL_ERROR; -		nativePrefix = (tclWinProcs->useWide) -			? (TCHAR *) L"tclr" : (TCHAR *) "tclr"; -		if ((*tclWinProcs->getTempFileNameProc)(nativeTmp, -			nativePrefix, 0, tempBuf) != 0) { +		nativePrefix = (TCHAR *) L"tclr"; +		if (GetTempFileName(nativeTmp, nativePrefix, +			0, tempBuf) != 0) {  		    /*  		     * Strictly speaking, need the following DeleteFile and  		     * MoveFile to be joined as an atomic operation so no @@ -491,19 +468,16 @@ DoRenameFile(  		     * same temp file.  		     */ -		    nativeTmp = (TCHAR *) tempBuf; -		    (*tclWinProcs->deleteFileProc)(nativeTmp); -		    if ((*tclWinProcs->moveFileProc)(nativeDst, -			    nativeTmp) != FALSE) { -			if ((*tclWinProcs->moveFileProc)(nativeSrc, -				nativeDst) != FALSE) { -			    (*tclWinProcs->setFileAttributesProc)(nativeTmp, -				    FILE_ATTRIBUTE_NORMAL); -			    (*tclWinProcs->deleteFileProc)(nativeTmp); +		    nativeTmp = tempBuf; +		    DeleteFile(nativeTmp); +		    if (MoveFile(nativeDst, nativeTmp) != FALSE) { +			if (MoveFile(nativeSrc, nativeDst) != FALSE) { +			    SetFileAttributes(nativeTmp, FILE_ATTRIBUTE_NORMAL); +			    DeleteFile(nativeTmp);  			    return TCL_OK;  			} else { -			    (*tclWinProcs->deleteFileProc)(nativeDst); -			    (*tclWinProcs->moveFileProc)(nativeTmp, nativeDst); +			    DeleteFile(nativeDst); +			    MoveFile(nativeTmp, nativeDst);  			}  		    } @@ -566,11 +540,11 @@ TclpObjCopyFile(  static int  DoCopyFile( -    CONST TCHAR *nativeSrc,	/* Pathname of file to be copied (native). */ -    CONST TCHAR *nativeDst)	/* Pathname of file to copy to (native). */ +    const TCHAR *nativeSrc,	/* Pathname of file to be copied (native). */ +    const TCHAR *nativeDst)	/* Pathname of file to copy to (native). */  { -#ifdef HAVE_NO_SEH -    EXCEPTION_REGISTRATION registration; +#if defined(HAVE_NO_SEH) && !defined(_WIN64) +    TCLEXCEPTION_REGISTRATION registration;  #endif      int retval = -1; @@ -607,7 +581,7 @@ DoCopyFile(  	"movl	    %[nativeSrc],   %%ecx"	    "\n\t"  	/* -	 * Construct an EXCEPTION_REGISTRATION to protect the call to +	 * Construct an TCLEXCEPTION_REGISTRATION to protect the call to  	 * CopyFile.  	 */ @@ -621,7 +595,7 @@ DoCopyFile(  	"movl	    $0,		    0x10(%%edx)"    "\n\t" /* status */  	/* -	 * Link the EXCEPTION_REGISTRATION on the chain. +	 * Link the TCLEXCEPTION_REGISTRATION on the chain.  	 */  	"movl	    %%edx,	    %%fs:0"	    "\n\t" @@ -637,7 +611,7 @@ DoCopyFile(  	"call	    *%%eax"			    "\n\t"  	/* -	 * Come here on normal exit. Recover the EXCEPTION_REGISTRATION and +	 * Come here on normal exit. Recover the TCLEXCEPTION_REGISTRATION and  	 * put the status return from CopyFile into it.  	 */ @@ -646,7 +620,7 @@ DoCopyFile(  	"jmp	    2f"				    "\n"  	/* -	 * Come here on an exception. Recover the EXCEPTION_REGISTRATION +	 * Come here on an exception. Recover the TCLEXCEPTION_REGISTRATION  	 */  	"1:"					    "\t" @@ -655,7 +629,7 @@ DoCopyFile(  	/*  	 * Come here however we exited. Restore context from the -	 * EXCEPTION_REGISTRATION in case the stack is unbalanced. +	 * TCLEXCEPTION_REGISTRATION in case the stack is unbalanced.  	 */  	"2:"					    "\t" @@ -670,7 +644,7 @@ DoCopyFile(  	[registration]	"m"	(registration),  	[nativeDst]	"m"	(nativeDst),  	[nativeSrc]	"m"	(nativeSrc), -	[copyFile]	"r"	(tclWinProcs->copyFileProc) +	[copyFile]	"r"	(CopyFile)  	:  	"%eax", "%ebx", "%ecx", "%edx", "memory"  	); @@ -681,7 +655,7 @@ DoCopyFile(  #ifndef HAVE_NO_SEH      __try {  #endif -	if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) { +	if (CopyFile(nativeSrc, nativeDst, 0) != FALSE) {  	    retval = TCL_OK;  	}  #ifndef HAVE_NO_SEH @@ -701,8 +675,8 @@ DoCopyFile(      if (Tcl_GetErrno() == EACCES) {  	DWORD srcAttr, dstAttr; -	srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc); -	dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst); +	srcAttr = GetFileAttributes(nativeSrc); +	dstAttr = GetFileAttributes(nativeDst);  	if (srcAttr != 0xffffffff) {  	    if (dstAttr == 0xffffffff) {  		dstAttr = 0; @@ -718,9 +692,9 @@ DoCopyFile(  		Tcl_SetErrno(EISDIR);  	    }  	    if (dstAttr & FILE_ATTRIBUTE_READONLY) { -		(*tclWinProcs->setFileAttributesProc)(nativeDst, +		SetFileAttributes(nativeDst,  			dstAttr & ~((DWORD)FILE_ATTRIBUTE_READONLY)); -		if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, +		if (CopyFile(nativeSrc, nativeDst,  			0) != FALSE) {  		    return TCL_OK;  		} @@ -731,7 +705,7 @@ DoCopyFile(  		 */  		TclWinConvertError(GetLastError()); -		(*tclWinProcs->setFileAttributesProc)(nativeDst, dstAttr); +		SetFileAttributes(nativeDst, dstAttr);  	    }  	}      } @@ -772,34 +746,35 @@ TclpObjDeleteFile(  int  TclpDeleteFile( -    CONST TCHAR *nativePath)	/* Pathname of file to be removed (native). */ +    const void *nativePath)	/* Pathname of file to be removed (native). */  {      DWORD attr; +    const TCHAR *path = nativePath;      /*       * The DeleteFile API acts differently under Win95/98 and NT WRT NULL and       * "". Avoid passing these values.       */ -    if (nativePath == NULL || nativePath[0] == '\0') { +    if (path == NULL || path[0] == '\0') {  	Tcl_SetErrno(ENOENT);  	return TCL_ERROR;      } -    if ((*tclWinProcs->deleteFileProc)(nativePath) != FALSE) { +    if (DeleteFile(path) != FALSE) {  	return TCL_OK;      }      TclWinConvertError(GetLastError());      if (Tcl_GetErrno() == EACCES) { -	attr = (*tclWinProcs->getFileAttributesProc)(nativePath); +	attr = GetFileAttributes(path);  	if (attr != 0xffffffff) {  	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {  		if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {  		    /*  		     * It is a symbolic link - remove it.  		     */ -		    if (TclWinSymLinkDelete(nativePath, 0) == 0) { +		    if (TclWinSymLinkDelete(path, 0) == 0) {  			return TCL_OK;  		    }  		} @@ -813,21 +788,21 @@ TclpDeleteFile(  		Tcl_SetErrno(EISDIR);  	    } else if (attr & FILE_ATTRIBUTE_READONLY) { -		int res = (*tclWinProcs->setFileAttributesProc)(nativePath, -			attr & ~((DWORD)FILE_ATTRIBUTE_READONLY)); +		int res = SetFileAttributes(path, +			attr & ~((DWORD) FILE_ATTRIBUTE_READONLY)); -		if ((res != 0) && ((*tclWinProcs->deleteFileProc)(nativePath) -			!= FALSE)) { +		if ((res != 0) && +			(DeleteFile(path) != FALSE)) {  		    return TCL_OK;  		}  		TclWinConvertError(GetLastError());  		if (res != 0) { -		    (*tclWinProcs->setFileAttributesProc)(nativePath, attr); +		    SetFileAttributes(path, attr);  		}  	    }  	}      } else if (Tcl_GetErrno() == ENOENT) { -	attr = (*tclWinProcs->getFileAttributesProc)(nativePath); +	attr = GetFileAttributes(path);  	if (attr != 0xffffffff) {  	    if (attr & FILE_ATTRIBUTE_DIRECTORY) {  		/* @@ -884,11 +859,11 @@ TclpObjCreateDirectory(  static int  DoCreateDirectory( -    CONST TCHAR *nativePath)	/* Pathname of directory to create (native). */ +    const TCHAR *nativePath)	/* Pathname of directory to create (native). */  { -    DWORD error; -    if ((*tclWinProcs->createDirectoryProc)(nativePath, NULL) == 0) { -	error = GetLastError(); +    if (CreateDirectory(nativePath, NULL) == 0) { +	DWORD error = GetLastError(); +  	TclWinConvertError(error);  	return TCL_ERROR;      } @@ -1017,13 +992,12 @@ TclpObjRemoveDirectory(      }      if (ret != TCL_OK) { -	int len = Tcl_DStringLength(&ds); -	if (len > 0) { +	if (Tcl_DStringLength(&ds) > 0) {  	    if (normPtr != NULL &&  		    !strcmp(Tcl_DStringValue(&ds), TclGetString(normPtr))) {  		*errorPtr = pathPtr;  	    } else { -		*errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); +		*errorPtr = TclDStringToObj(&ds);  	    }  	    Tcl_IncrRefCount(*errorPtr);  	} @@ -1035,7 +1009,7 @@ TclpObjRemoveDirectory(  static int  DoRemoveJustDirectory( -    CONST TCHAR *nativePath,	/* Pathname of directory to be removed +    const TCHAR *nativePath,	/* Pathname of directory to be removed  				 * (native). */      int ignoreError,		/* If non-zero, don't initialize the errorPtr  				 * under some circumstances on return. */ @@ -1055,7 +1029,7 @@ DoRemoveJustDirectory(  	goto end;      } -    attr = (*tclWinProcs->getFileAttributesProc)(nativePath); +    attr = GetFileAttributes(nativePath);      if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {  	/* @@ -1069,7 +1043,7 @@ DoRemoveJustDirectory(  	 * Ordinary directory.  	 */ -	if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) { +	if (RemoveDirectory(nativePath) != FALSE) {  	    return TCL_OK;  	}      } @@ -1077,7 +1051,7 @@ DoRemoveJustDirectory(      TclWinConvertError(GetLastError());      if (Tcl_GetErrno() == EACCES) { -	attr = (*tclWinProcs->getFileAttributesProc)(nativePath); +	attr = GetFileAttributes(nativePath);  	if (attr != 0xffffffff) {  	    if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {  		/* @@ -1101,60 +1075,17 @@ DoRemoveJustDirectory(  	    if (attr & FILE_ATTRIBUTE_READONLY) {  		attr &= ~FILE_ATTRIBUTE_READONLY; -		if ((*tclWinProcs->setFileAttributesProc)(nativePath, +		if (SetFileAttributes(nativePath,  			attr) == FALSE) {  		    goto end;  		} -		if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) { +		if (RemoveDirectory(nativePath) != FALSE) {  		    return TCL_OK;  		}  		TclWinConvertError(GetLastError()); -		(*tclWinProcs->setFileAttributesProc)(nativePath, +		SetFileAttributes(nativePath,  			attr | FILE_ATTRIBUTE_READONLY);  	    } - -	    /* -	     * Windows 95 and Win32s report removing a non-empty directory as -	     * EACCES, not EEXIST. If the directory is not empty, change errno -	     * so caller knows what's going on. -	     */ - -	    if (TclWinGetPlatformId() != VER_PLATFORM_WIN32_NT) { -		CONST char *path, *find; -		HANDLE handle; -		WIN32_FIND_DATAA data; -		Tcl_DString buffer; -		int len; - -		path = (CONST char *) nativePath; - -		Tcl_DStringInit(&buffer); -		len = strlen(path); -		find = Tcl_DStringAppend(&buffer, path, len); -		if ((len > 0) && (find[len - 1] != '\\')) { -		    Tcl_DStringAppend(&buffer, "\\", 1); -		} -		find = Tcl_DStringAppend(&buffer, "*.*", 3); -		handle = FindFirstFileA(find, &data); -		if (handle != INVALID_HANDLE_VALUE) { -		    while (1) { -			if ((strcmp(data.cFileName, ".") != 0) -				&& (strcmp(data.cFileName, "..") != 0)) { -			    /* -			     * Found something in this directory. -			     */ - -			    Tcl_SetErrno(EEXIST); -			    break; -			} -			if (FindNextFileA(handle, &data) == FALSE) { -			    break; -			} -		    } -		    FindClose(handle); -		} -		Tcl_DStringFree(&buffer); -	    }  	}      } @@ -1177,7 +1108,12 @@ DoRemoveJustDirectory(    end:      if (errorPtr != NULL) { +	char *p;  	Tcl_WinTCharToUtf(nativePath, -1, errorPtr); +	p = Tcl_DStringValue(errorPtr); +	for (; *p; ++p) { +	    if (*p == '\\') *p = '/'; +	}      }      return TCL_ERROR; @@ -1194,7 +1130,7 @@ DoRemoveDirectory(  				 * filled with UTF-8 name of file causing  				 * error. */  { -    int res = DoRemoveJustDirectory(Tcl_DStringValue(pathPtr), recursive, +    int res = DoRemoveJustDirectory((const TCHAR *)Tcl_DStringValue(pathPtr), recursive,  	    errorPtr);      if ((res == TCL_ERROR) && (recursive != 0) && (Tcl_GetErrno() == EEXIST)) { @@ -1248,7 +1184,7 @@ TraverseWinTree(      TCHAR *nativeSource, *nativeTarget, *nativeErrfile;      int result, found, sourceLen, targetLen = 0, oldSourceLen, oldTargetLen;      HANDLE handle; -    WIN32_FIND_DATAT data; +    WIN32_FIND_DATA data;      nativeErrfile = NULL;      result = TCL_OK; @@ -1259,7 +1195,7 @@ TraverseWinTree(  	    (targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr));      oldSourceLen = Tcl_DStringLength(sourcePtr); -    sourceAttr = (*tclWinProcs->getFileAttributesProc)(nativeSource); +    sourceAttr = GetFileAttributes(nativeSource);      if (sourceAttr == 0xffffffff) {  	nativeErrfile = nativeSource;  	goto end; @@ -1270,7 +1206,7 @@ TraverseWinTree(  	 * Process the symbolic link  	 */ -	return (*traverseProc)(nativeSource, nativeTarget, DOTREE_LINK, +	return traverseProc(nativeSource, nativeTarget, DOTREE_LINK,  		errorPtr);      } @@ -1279,18 +1215,14 @@ TraverseWinTree(  	 * Process the regular file  	 */ -	return (*traverseProc)(nativeSource, nativeTarget, DOTREE_F, errorPtr); +	return traverseProc(nativeSource, nativeTarget, DOTREE_F, errorPtr);      } -    if (tclWinProcs->useWide) { -	Tcl_DStringAppend(sourcePtr, (char *) L"\\*.*", 4 * sizeof(WCHAR) + 1); -	Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1); -    } else { -	Tcl_DStringAppend(sourcePtr, "\\*.*", 4); -    } +    Tcl_DStringAppend(sourcePtr, (char *) TEXT("\\*.*"), 4 * sizeof(TCHAR) + 1); +    Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1);      nativeSource = (TCHAR *) Tcl_DStringValue(sourcePtr); -    handle = (*tclWinProcs->findFirstFileProc)(nativeSource, &data); +    handle = FindFirstFile(nativeSource, &data);      if (handle == INVALID_HANDLE_VALUE) {  	/*  	 * Can't read directory. @@ -1301,67 +1233,44 @@ TraverseWinTree(  	goto end;      } -    nativeSource[oldSourceLen + 1] = '\0'; +    Tcl_DStringSetLength(sourcePtr, oldSourceLen + 1);      Tcl_DStringSetLength(sourcePtr, oldSourceLen); -    result = (*traverseProc)(nativeSource, nativeTarget, DOTREE_PRED, +    result = traverseProc(nativeSource, nativeTarget, DOTREE_PRED,  	    errorPtr);      if (result != TCL_OK) {  	FindClose(handle);  	return result;      } -    sourceLen = oldSourceLen; - -    if (tclWinProcs->useWide) { -	sourceLen += sizeof(WCHAR); -	Tcl_DStringAppend(sourcePtr, (char *) L"\\", sizeof(WCHAR) + 1); -	Tcl_DStringSetLength(sourcePtr, sourceLen); -    } else { -	sourceLen += 1; -	Tcl_DStringAppend(sourcePtr, "\\", 1); -    } +    sourceLen = oldSourceLen + sizeof(TCHAR); +    Tcl_DStringAppend(sourcePtr, (char *) TEXT("\\"), sizeof(TCHAR) + 1); +    Tcl_DStringSetLength(sourcePtr, sourceLen);      if (targetPtr != NULL) {  	oldTargetLen = Tcl_DStringLength(targetPtr);  	targetLen = oldTargetLen; -	if (tclWinProcs->useWide) { -	    targetLen += sizeof(WCHAR); -	    Tcl_DStringAppend(targetPtr, (char *) L"\\", sizeof(WCHAR) + 1); -	    Tcl_DStringSetLength(targetPtr, targetLen); -	} else { -	    targetLen += 1; -	    Tcl_DStringAppend(targetPtr, "\\", 1); -	} +	targetLen += sizeof(TCHAR); +	Tcl_DStringAppend(targetPtr, (char *) TEXT("\\"), sizeof(TCHAR) + 1); +	Tcl_DStringSetLength(targetPtr, targetLen);      }      found = 1; -    for (; found; found = (*tclWinProcs->findNextFileProc)(handle, &data)) { +    for (; found; found = FindNextFile(handle, &data)) {  	TCHAR *nativeName;  	int len; -	if (tclWinProcs->useWide) { -	    WCHAR *wp; - -	    wp = data.w.cFileName; +	TCHAR *wp = data.cFileName; +	if (*wp == '.') { +	    wp++;  	    if (*wp == '.') {  		wp++; -		if (*wp == '.') { -		    wp++; -		} -		if (*wp == '\0') { -		    continue; -		}  	    } -	    nativeName = (TCHAR *) data.w.cFileName; -	    len = wcslen(data.w.cFileName) * sizeof(WCHAR); -	} else { -	    if ((strcmp(data.a.cFileName, ".") == 0) -		    || (strcmp(data.a.cFileName, "..") == 0)) { +	    if (*wp == '\0') {  		continue;  	    } -	    nativeName = (TCHAR *) data.a.cFileName; -	    len = strlen(data.a.cFileName);  	} +	nativeName = (TCHAR *) data.cFileName; +	len = _tcslen(data.cFileName) * sizeof(TCHAR);  	/*  	 * Append name after slash, and recurse on the file. @@ -1406,8 +1315,8 @@ TraverseWinTree(  	 * files in that directory.  	 */ -	result = (*traverseProc)(Tcl_DStringValue(sourcePtr), -		(targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)), +	result = traverseProc((const TCHAR *)Tcl_DStringValue(sourcePtr), +		(const TCHAR *)(targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)),  		DOTREE_POSTD, errorPtr);      } @@ -1442,8 +1351,8 @@ TraverseWinTree(  static int  TraversalCopy( -    CONST TCHAR *nativeSrc,	/* Source pathname to copy. */ -    CONST TCHAR *nativeDst,	/* Destination pathname of copy. */ +    const TCHAR *nativeSrc,	/* Source pathname to copy. */ +    const TCHAR *nativeDst,	/* Destination pathname of copy. */      int type,			/* Reason for call - see TraverseWinTree() */      Tcl_DString *errorPtr)	/* If non-NULL, initialized DString filled  				 * with UTF-8 name of file causing error. */ @@ -1461,9 +1370,9 @@ TraversalCopy(  	break;      case DOTREE_PRED:  	if (DoCreateDirectory(nativeDst) == TCL_OK) { -	    DWORD attr = (tclWinProcs->getFileAttributesProc)(nativeSrc); +	    DWORD attr = GetFileAttributes(nativeSrc); -	    if ((tclWinProcs->setFileAttributesProc)(nativeDst, +	    if (SetFileAttributes(nativeDst,  		    attr) != FALSE) {  		return TCL_OK;  	    } @@ -1508,8 +1417,8 @@ TraversalCopy(  static int  TraversalDelete( -    CONST TCHAR *nativeSrc,	/* Source pathname to delete. */ -    CONST TCHAR *dstPtr,	/* Not used. */ +    const TCHAR *nativeSrc,	/* Source pathname to delete. */ +    const TCHAR *dstPtr,	/* Not used. */      int type,			/* Reason for call - see TraverseWinTree() */      Tcl_DString *errorPtr)	/* If non-NULL, initialized DString filled  				 * with UTF-8 name of file causing error. */ @@ -1564,8 +1473,8 @@ StatError(  				 * error. */  {      TclWinConvertError(GetLastError()); -    Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName), -	    "\": ", Tcl_PosixError(interp), (char *) NULL); +    Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s", +	    TclGetString(fileName), Tcl_PosixError(interp)));  }  /* @@ -1595,11 +1504,11 @@ GetWinFileAttributes(      Tcl_Obj **attributePtrPtr)	/* A pointer to return the object with. */  {      DWORD result; -    CONST TCHAR *nativeName; +    const TCHAR *nativeName;      int attr;      nativeName = Tcl_FSGetNativePath(fileName); -    result = (*tclWinProcs->getFileAttributesProc)(nativeName); +    result = GetFileAttributes(nativeName);      if (result == 0xffffffff) {  	StatError(interp, fileName); @@ -1617,7 +1526,7 @@ GetWinFileAttributes(  	 */  	int len; -	char *str = Tcl_GetStringFromObj(fileName,&len); +	const char *str = Tcl_GetStringFromObj(fileName,&len);  	if (len < 4) {  	    if (len == 0) { @@ -1683,9 +1592,11 @@ ConvertFileNameFormat(      if (splitPath == NULL || pathc == 0) {  	if (interp != NULL) { -	    Tcl_AppendResult(interp, "could not read \"", -		    Tcl_GetString(fileName), "\": no such file or directory", -		    (char *) NULL); +	    Tcl_SetObjResult(interp, Tcl_ObjPrintf( +		    "could not read \"%s\": no such file or directory", +		    Tcl_GetString(fileName))); +	    errno = ENOENT; +	    Tcl_PosixError(interp);  	}  	goto cleanup;      } @@ -1726,10 +1637,10 @@ ConvertFileNameFormat(  	    Tcl_Obj *tempPath;  	    Tcl_DString ds;  	    Tcl_DString dsTemp; -	    TCHAR *nativeName; -	    char *tempString; +	    const TCHAR *nativeName; +	    const char *tempString;  	    int tempLen; -	    WIN32_FIND_DATAT data; +	    WIN32_FIND_DATA data;  	    HANDLE handle;  	    DWORD attr; @@ -1745,7 +1656,7 @@ ConvertFileNameFormat(  	    tempString = Tcl_GetStringFromObj(tempPath,&tempLen);  	    nativeName = Tcl_WinUtfToTChar(tempString, tempLen, &ds);  	    Tcl_DecrRefCount(tempPath); -	    handle = (*tclWinProcs->findFirstFileProc)(nativeName, &data); +	    handle = FindFirstFile(nativeName, &data);  	    if (handle == INVALID_HANDLE_VALUE) {  		/*  		 * FindFirstFile() doesn't like root directories. We would @@ -1754,7 +1665,7 @@ ConvertFileNameFormat(  		 * root directory  		 */ -		attr = (*tclWinProcs->getFileAttributesProc)(nativeName); +		attr = GetFileAttributes(nativeName);  		if ((attr!=0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY)) {  		    Tcl_DStringFree(&ds);  		    goto simple; @@ -1768,27 +1679,14 @@ ConvertFileNameFormat(  		}  		goto cleanup;  	    } -	    if (tclWinProcs->useWide) { -		nativeName = (TCHAR *) data.w.cAlternateFileName; -		if (longShort) { -		    if (data.w.cFileName[0] != '\0') { -			nativeName = (TCHAR *) data.w.cFileName; -		    } -		} else { -		    if (data.w.cAlternateFileName[0] == '\0') { -			nativeName = (TCHAR *) data.w.cFileName; -		    } +	    nativeName = data.cAlternateFileName; +	    if (longShort) { +		if (data.cFileName[0] != '\0') { +		    nativeName = data.cFileName;  		}  	    } else { -		nativeName = (TCHAR *) data.a.cAlternateFileName; -		if (longShort) { -		    if (data.a.cFileName[0] != '\0') { -			nativeName = (TCHAR *) data.a.cFileName; -		    } -		} else { -		    if (data.a.cAlternateFileName[0] == '\0') { -			nativeName = (TCHAR *) data.a.cFileName; -		    } +		if (data.cAlternateFileName[0] == '\0') { +		    nativeName = (TCHAR *) data.cFileName;  		}  	    } @@ -1806,22 +1704,21 @@ ConvertFileNameFormat(  	    Tcl_DStringInit(&dsTemp);  	    Tcl_WinTCharToUtf(nativeName, -1, &dsTemp); +	    Tcl_DStringFree(&ds);  	    /*  	     * Deal with issues of tildes being absolute.  	     */  	    if (Tcl_DStringValue(&dsTemp)[0] == '~') { -		tempPath = Tcl_NewStringObj("./",2); +		TclNewLiteralStringObj(tempPath, "./");  		Tcl_AppendToObj(tempPath, Tcl_DStringValue(&dsTemp),  			Tcl_DStringLength(&dsTemp)); +		Tcl_DStringFree(&dsTemp);  	    } else { -		tempPath = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp), -			Tcl_DStringLength(&dsTemp)); +		tempPath = TclDStringToObj(&dsTemp);  	    }  	    Tcl_ListObjReplace(NULL, splitPath, i, 1, 1, &tempPath); -	    Tcl_DStringFree(&ds); -	    Tcl_DStringFree(&dsTemp);  	    FindClose(handle);  	}      } @@ -1933,13 +1830,12 @@ SetWinFileAttributes(      Tcl_Obj *fileName,		/* The name of the file. */      Tcl_Obj *attributePtr)	/* The new value of the attribute. */  { -    DWORD fileAttributes; -    int yesNo; -    int result; -    CONST TCHAR *nativeName; +    DWORD fileAttributes, old; +    int yesNo, result; +    const TCHAR *nativeName;      nativeName = Tcl_FSGetNativePath(fileName); -    fileAttributes = (*tclWinProcs->getFileAttributesProc)(nativeName); +    fileAttributes = old = GetFileAttributes(nativeName);      if (fileAttributes == 0xffffffff) {  	StatError(interp, fileName); @@ -1957,7 +1853,8 @@ SetWinFileAttributes(  	fileAttributes &= ~(attributeArray[objIndex]);      } -    if (!(*tclWinProcs->setFileAttributesProc)(nativeName, fileAttributes)) { +    if ((fileAttributes != old) +	    && !SetFileAttributes(nativeName, fileAttributes)) {  	StatError(interp, fileName);  	return TCL_ERROR;      } @@ -1988,13 +1885,13 @@ CannotSetAttribute(      Tcl_Obj *fileName,		/* The name of the file. */      Tcl_Obj *attributePtr)	/* The new value of the attribute. */  { -    Tcl_AppendResult(interp, "cannot set attribute \"", -	    tclpFileAttrStrings[objIndex], "\" for file \"", -	    Tcl_GetString(fileName), "\": attribute is readonly", -	    (char *) NULL); +    Tcl_SetObjResult(interp, Tcl_ObjPrintf( +	    "cannot set attribute \"%s\" for file \"%s\": attribute is readonly", +	    tclpFileAttrStrings[objIndex], Tcl_GetString(fileName))); +    errno = EINVAL; +    Tcl_PosixError(interp);      return TCL_ERROR;  } -  /*   *--------------------------------------------------------------------------- @@ -2012,7 +1909,7 @@ CannotSetAttribute(   *---------------------------------------------------------------------------   */ -Tcl_Obj* +Tcl_Obj *  TclpObjListVolumes(void)  {      Tcl_Obj *resultPtr, *elemPtr; | 
