⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclwinfile.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 5 页
字号:
TclWinResolveShortcut(bufferPtr)    Tcl_DString *bufferPtr;	/* Holds name of file to resolve.  On 				 * return, holds resolved file name. */{    HRESULT hres;     IShellLink *psl;     IPersistFile *ppf;     WIN32_FIND_DATA wfd;     WCHAR wpath[MAX_PATH];    char *path, *ext;    char realFileName[MAX_PATH];    /*     * Windows system calls do not automatically resolve     * shortcuts like UNIX automatically will with symbolic links.     */    path = Tcl_DStringValue(bufferPtr);    ext = strrchr(path, '.');    if ((ext == NULL) || (stricmp(ext, ".lnk") != 0)) {	return 0;    }    CoInitialize(NULL);    path = Tcl_DStringValue(bufferPtr);    realFileName[0] = '\0';    hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, 	    &IID_IShellLink, &psl);     if (SUCCEEDED(hres)) { 	hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf);	if (SUCCEEDED(hres)) { 	    MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, sizeof(wpath));	    hres = ppf->lpVtbl->Load(ppf, wpath, STGM_READ); 	    if (SUCCEEDED(hres)) {		hres = psl->lpVtbl->Resolve(psl, NULL, 			SLR_ANY_MATCH | SLR_NO_UI); 		if (SUCCEEDED(hres)) { 		    hres = psl->lpVtbl->GetPath(psl, realFileName, MAX_PATH, 			    &wfd, 0);		} 	    } 	    ppf->lpVtbl->Release(ppf); 	} 	psl->lpVtbl->Release(psl);     }     CoUninitialize();    if (realFileName[0] != '\0') {	Tcl_DStringSetLength(bufferPtr, 0);	Tcl_DStringAppend(bufferPtr, realFileName, -1);	return 1;    }    return 0;}#endifTcl_Obj* TclpObjGetCwd(interp)    Tcl_Interp *interp;{    Tcl_DString ds;    if (TclpGetCwd(interp, &ds) != NULL) {	Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);	Tcl_IncrRefCount(cwdPtr);	Tcl_DStringFree(&ds);	return cwdPtr;    } else {	return NULL;    }}int TclpObjAccess(pathPtr, mode)    Tcl_Obj *pathPtr;    int mode;{    return NativeAccess((CONST TCHAR*) Tcl_FSGetNativePath(pathPtr), mode);}int TclpObjLstat(pathPtr, statPtr)    Tcl_Obj *pathPtr;    Tcl_StatBuf *statPtr; {    /*     * Ensure correct file sizes by forcing the OS to write any     * pending data to disk. This is done only for channels which are     * dirty, i.e. have been written to since the last flush here.     */    TclWinFlushDirtyChannels ();    return NativeStat((CONST TCHAR*) Tcl_FSGetNativePath(pathPtr), statPtr, 1);}#ifdef S_IFLNKTcl_Obj* TclpObjLink(pathPtr, toPtr, linkAction)    Tcl_Obj *pathPtr;    Tcl_Obj *toPtr;    int linkAction;{    if (toPtr != NULL) {	int res;	TCHAR* LinkTarget = (TCHAR*)Tcl_FSGetNativePath(toPtr);	TCHAR* LinkSource = (TCHAR*)Tcl_FSGetNativePath(pathPtr);	if (LinkSource == NULL || LinkTarget == NULL) {	    return NULL;	}	res = WinLink(LinkSource, LinkTarget, linkAction);	if (res == 0) {	    return toPtr;	} else {	    return NULL;	}    } else {	TCHAR* LinkSource = (TCHAR*)Tcl_FSGetNativePath(pathPtr);	if (LinkSource == NULL) {	    return NULL;	}	return WinReadLink(LinkSource);    }}#endif/* *--------------------------------------------------------------------------- * * TclpFilesystemPathType -- * *      This function is part of the native filesystem support, and *      returns the path type of the given path.  Returns NTFS or FAT *      or whatever is returned by the 'volume information' proc. * * Results: *      NULL at present. * * Side effects: *	None. * *--------------------------------------------------------------------------- */Tcl_Obj*TclpFilesystemPathType(pathObjPtr)    Tcl_Obj* pathObjPtr;{#define VOL_BUF_SIZE 32    int found;    char volType[VOL_BUF_SIZE];    char* firstSeparator;    CONST char *path;        Tcl_Obj *normPath = Tcl_FSGetNormalizedPath(NULL, pathObjPtr);    if (normPath == NULL) return NULL;    path = Tcl_GetString(normPath);    if (path == NULL) return NULL;        firstSeparator = strchr(path, '/');    if (firstSeparator == NULL) {	found = tclWinProcs->getVolumeInformationProc(		Tcl_FSGetNativePath(pathObjPtr), NULL, 0, NULL, NULL, 		NULL, (WCHAR *)volType, VOL_BUF_SIZE);    } else {	Tcl_Obj *driveName = Tcl_NewStringObj(path, firstSeparator - path+1);	Tcl_IncrRefCount(driveName);	found = tclWinProcs->getVolumeInformationProc(		Tcl_FSGetNativePath(driveName), NULL, 0, NULL, NULL, 		NULL, (WCHAR *)volType, VOL_BUF_SIZE);	Tcl_DecrRefCount(driveName);    }    if (found == 0) {	return NULL;    } else {	Tcl_DString ds;	Tcl_Obj *objPtr;		Tcl_WinTCharToUtf(volType, -1, &ds);	objPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));	Tcl_DStringFree(&ds);	return objPtr;    }#undef VOL_BUF_SIZE}/* *--------------------------------------------------------------------------- * * TclpObjNormalizePath -- * *	This function scans through a path specification and replaces it, *	in place, with a normalized version.  This means using the *	'longname', and expanding any symbolic links contained within the *	path. * * Results: *	The new 'nextCheckpoint' value, giving as far as we could *	understand in the path. * * Side effects: *	The pathPtr string, which must contain a valid path, is *	possibly modified in place. * *--------------------------------------------------------------------------- */intTclpObjNormalizePath(interp, pathPtr, nextCheckpoint)    Tcl_Interp *interp;    Tcl_Obj *pathPtr;    int nextCheckpoint;{    char *lastValidPathEnd = NULL;    /* This will hold the normalized string */    Tcl_DString dsNorm;    char *path;    char *currentPathEndPosition;    Tcl_DStringInit(&dsNorm);    path = Tcl_GetString(pathPtr);    if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) {	/* 	 * We're on Win95, 98 or ME.  There are two assumptions	 * in this block of code.  First that the native (NULL)	 * encoding is basically ascii, and second that symbolic	 * links are not possible.  Both of these assumptions	 * appear to be true of these operating systems.	 */	Tcl_Obj *temp = NULL;	int isDrive = 1;	Tcl_DString ds;	currentPathEndPosition = path + nextCheckpoint;	while (1) {	    char cur = *currentPathEndPosition;	    if ((cur == '/' || cur == 0) && (path != currentPathEndPosition)) {		/* Reached directory separator, or end of string */		CONST char *nativePath = Tcl_UtfToExternalDString(NULL, path, 			    currentPathEndPosition - path, &ds);		/*		 * Now we convert the tail of the current path to its		 * 'long form', and append it to 'dsNorm' which holds		 * the current normalized path, if the file exists.		 */		if (isDrive) {		    if (GetFileAttributesA(nativePath) 			== 0xffffffff) {			/* File doesn't exist */			Tcl_DStringFree(&ds);			break;		    }		    if (nativePath[0] >= 'a') {			((char*)nativePath)[0] -= ('a' - 'A');		    }		    Tcl_DStringAppend(&dsNorm,nativePath,Tcl_DStringLength(&ds));		} else {		    WIN32_FIND_DATA fData;		    HANDLE handle;		    		    handle = FindFirstFileA(nativePath, &fData);		    if (handle == INVALID_HANDLE_VALUE) {			if (GetFileAttributesA(nativePath) 			    == 0xffffffff) {			    /* File doesn't exist */			    Tcl_DStringFree(&ds);			    break;			}			/* This is usually the '/' in 'c:/' at end of string */			Tcl_DStringAppend(&dsNorm,"/", 1);		    } else {			char *nativeName;			if (fData.cFileName[0] != '\0') {			    nativeName = fData.cFileName;			} else {			    nativeName = fData.cAlternateFileName;			}			FindClose(handle);			Tcl_DStringAppend(&dsNorm,"/", 1);			Tcl_DStringAppend(&dsNorm,nativeName,-1);		    }		}		Tcl_DStringFree(&ds);		lastValidPathEnd = currentPathEndPosition;		if (cur == 0) {		    break;		}		/* 		 * If we get here, we've got past one directory		 * delimiter, so we know it is no longer a drive 		 */		isDrive = 0;	    }	    currentPathEndPosition++;	}    } else {	/* We're on WinNT or 2000 or XP */	Tcl_Obj *temp = NULL;	int isDrive = 1;	Tcl_DString ds;	currentPathEndPosition = path + nextCheckpoint;	while (1) {	    char cur = *currentPathEndPosition;	    if ((cur == '/' || cur == 0) && (path != currentPathEndPosition)) {		/* Reached directory separator, or end of string */		WIN32_FILE_ATTRIBUTE_DATA data;		CONST char *nativePath = Tcl_WinUtfToTChar(path, 			    currentPathEndPosition - path, &ds);		if ((*tclWinProcs->getFileAttributesExProc)(nativePath,		    GetFileExInfoStandard, &data) != TRUE) {		    /* File doesn't exist */		    Tcl_DStringFree(&ds);		    break;		}		/* 		 * File 'nativePath' does exist if we get here.  We		 * now want to check if it is a symlink and otherwise		 * continue with the rest of the path.		 */				/* 		 * Check for symlinks, except at last component		 * of path (we don't follow final symlinks). Also		 * a drive (C:/) for example, may sometimes have		 * the reparse flag set for some reason I don't		 * understand.  We therefore don't perform this		 * check for drives.		 */		if (cur != 0 && !isDrive && (data.dwFileAttributes 				 & FILE_ATTRIBUTE_REPARSE_POINT)) {		    Tcl_Obj *to = WinReadLinkDirectory(nativePath);		    if (to != NULL) {			/* Read the reparse point ok */			/* Tcl_GetStringFromObj(to, &pathLen); */			nextCheckpoint = 0; /* pathLen */			Tcl_AppendToObj(to, currentPathEndPosition, -1);			/* Convert link to forward slashes */			for (path = Tcl_GetString(to); *path != 0; path++) {			    if (*path == '\\') *path = '/';			}			path = Tcl_GetString(to);			currentPathEndPosition = path + nextCheckpoint;			if (temp != NULL) {			    Tcl_DecrRefCount(temp);			}			temp = to;			/* Reset variables so we can restart normalization */			isDrive = 1;			Tcl_DStringFree(&dsNorm);			Tcl_DStringInit(&dsNorm);			Tcl_DStringFree(&ds);			continue;		    }		}		/*		 * Now we convert the tail of the current path to its		 * 'long form', and append it to 'dsNorm' which holds		 * the current normalized path		 */		if (isDrive) {		    WCHAR drive = ((WCHAR*)nativePath)[0];		    if (drive >= L'a') {		        drive -= (L'a' - L'A');			((WCHAR*)nativePath)[0] = drive;		    }		    Tcl_DStringAppend(&dsNorm,nativePath,Tcl_DStringLength(&ds));		} else {		    WIN32_FIND_DATAW fData;		    HANDLE handle;		    		    handle = FindFirstFileW((WCHAR*)nativePath, &fData);		    if (handle == INVALID_HANDLE_VALUE) {			/* This is usually the '/' in 'c:/' at end of string */			Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", 					  sizeof(WCHAR));		    } else {			WCHAR *nativeName;			if (fData.cFileName[0] != '\0') {			    nativeName = fData.cFileName;			} else {			    nativeName = fData.cAlternateFileName;			}			FindClose(handle);			Tcl_DStringAppend(&dsNorm,(CONST char*)L"/", 					  sizeof(WCHAR));			Tcl_DStringAppend(&dsNorm,(TCHAR*)nativeName, 					  wcslen(nativeName)*sizeof(WCHAR));		    }		}		Tcl_DStringFree(&ds);		lastValidPathEnd = currentPathEndPosition;		if (cur == 0) {		    break;		}		/* 		 * If we get here, we've got past one directory		 * delimiter, so we know it is no longer a drive 		 */		isDrive = 0;	    }	    currentPathEndPosition++;	}    }    /* Common code path for all Windows platforms */    nextCheckpoint = currentPathEndPosition - path;    if (lastValidPathEnd != NULL) {	/* 	 * Concatenate the normalized string in dsNorm with the	 * tail of the path which we didn't recognise.  The	 * string in dsNorm is in the native encoding, so we	 * have to convert it to Utf.	 */	Tcl_DString dsTemp;	Tcl_WinTCharToUtf(Tcl_DStringValue(&dsNorm), 			  Tcl_DStringLength(&dsNorm), &dsTemp);	nextCheckpoint = Tcl_DStringLength(&dsTemp);	if (*lastValidPathEnd != 0) {	    /* Not the end of the string */	    int len;	    char *path;	    Tcl_Obj *tmpPathPtr;	    tmpPathPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp), 					  nextCheckpoint);	    Tcl_AppendToObj(tmpPathPtr, lastValidPathEnd, -1);	    path = Tcl_GetStringFromObj(tmpPathPtr, &len);	    Tcl_SetStringObj(pathPtr, path, len);	    Tcl_DecrRefCount(tmpPathPtr);	} else {	    /* End of string was reached above */	    Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&dsTemp),			     nextCheckpoint);	}	Tcl_DStringFree(&dsTemp);    }    Tcl_DStringFree(&dsNorm);    return nextCheckpoint;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -