📄 filecore.cpp
字号:
UNUSED(nCommand); // not used in retail build
return 0; // no support
}
void PASCAL CFile::Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName)
{
if (!::MoveFile((LPTSTR)lpszOldName, (LPTSTR)lpszNewName))
CFileException::ThrowOsError((LONG)::GetLastError());
}
void PASCAL CFile::Remove(LPCTSTR lpszFileName)
{
if (!::DeleteFile((LPTSTR)lpszFileName))
CFileException::ThrowOsError((LONG)::GetLastError());
}
/////////////////////////////////////////////////////////////////////////////
// CFile implementation helpers
#ifdef AfxGetFileName
#undef AfxGetFileName
#endif
#ifndef _AFX_NO_OLE_SUPPORT
HRESULT AFX_COM::CreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
REFIID riid, LPVOID* ppv)
{
// find the object's class factory
LPCLASSFACTORY pf = NULL;
HRESULT hRes = GetClassObject(rclsid, IID_IClassFactory, (LPVOID*)&pf);
if (FAILED(hRes))
return hRes;
// call it to create the instance
ASSERT(pf != NULL);
hRes = pf->CreateInstance(pUnkOuter, riid, ppv);
// let go of the factory
pf->Release();
return hRes;
}
HRESULT AFX_COM::GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
HINSTANCE hInst = NULL;
// find server name for this class ID
CString strCLSID = AfxStringFromCLSID(rclsid);
CString strServer;
if (!AfxGetInProcServer(strCLSID, strServer))
return REGDB_E_CLASSNOTREG;
// try to load it
hInst = LoadLibrary(strServer);
if (hInst == NULL)
return REGDB_E_CLASSNOTREG;
#pragma warning(disable:4191)
// get its entry point
HRESULT (STDAPICALLTYPE* pfn)(REFCLSID rclsid, REFIID riid, LPVOID* ppv);
pfn = (HRESULT (STDAPICALLTYPE*)(REFCLSID rclsid, REFIID riid, LPVOID* ppv))
GetProcAddress(hInst, "DllGetClassObject");
#pragma warning(default:4191)
// call it, if it worked
if (pfn != NULL)
return pfn(rclsid, riid, ppv);
return CO_E_ERRORINDLL;
}
CString AFXAPI AfxStringFromCLSID(REFCLSID rclsid)
{
TCHAR szCLSID[256];
wsprintf(szCLSID, _T("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
rclsid.Data1, rclsid.Data2, rclsid.Data3,
rclsid.Data4[0], rclsid.Data4[1], rclsid.Data4[2], rclsid.Data4[3],
rclsid.Data4[4], rclsid.Data4[5], rclsid.Data4[6], rclsid.Data4[7]);
return szCLSID;
}
BOOL AFXAPI AfxGetInProcServer(LPCTSTR lpszCLSID, CString& str)
{
HKEY hKey = NULL;
BOOL b = FALSE;
if (RegOpenKey(HKEY_CLASSES_ROOT, _T("CLSID"), &hKey) == ERROR_SUCCESS)
{
HKEY hKeyCLSID = NULL;
if (RegOpenKey(hKey, lpszCLSID, &hKeyCLSID) == ERROR_SUCCESS)
{
HKEY hKeyInProc = NULL;
if (RegOpenKey(hKeyCLSID, _T("InProcServer32"), &hKeyInProc) ==
ERROR_SUCCESS)
{
LPTSTR lpsz = str.GetBuffer(_MAX_PATH);
DWORD dwSize = _MAX_PATH * sizeof(TCHAR);
DWORD dwType;
LONG lRes = ::RegQueryValueEx(hKeyInProc, _T(""),
NULL, &dwType, (BYTE*)lpsz, &dwSize);
str.ReleaseBuffer();
b = (lRes == ERROR_SUCCESS);
RegCloseKey(hKeyInProc);
}
RegCloseKey(hKeyCLSID);
}
RegCloseKey(hKey);
}
return b;
}
#endif //!_AFX_NO_OLE_SUPPORT
BOOL AFXAPI AfxResolveShortcut(CWnd* pWnd, LPCTSTR lpszFileIn,
LPTSTR lpszFileOut, int cchPath)
{
USES_CONVERSION;
AFX_COM com;
IShellLink* psl;
*lpszFileOut = 0; // assume failure
SHFILEINFO info;
if ((SHGetFileInfo(lpszFileIn, 0, &info, sizeof(info),
SHGFI_ATTRIBUTES) == 0) || !(info.dwAttributes & SFGAO_LINK))
{
return FALSE;
}
if (FAILED(com.CreateInstance(CLSID_ShellLink, NULL, IID_IShellLink,
(LPVOID*)&psl)))
{
return FALSE;
}
IPersistFile *ppf;
if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf)))
{
if (SUCCEEDED(ppf->Load(T2COLE(lpszFileIn), STGM_READ)))
{
/* Resolve the link, this may post UI to find the link */
if (SUCCEEDED(psl->Resolve(pWnd->GetSafeHwnd(),
SLR_ANY_MATCH)))
{
psl->GetPath(lpszFileOut, cchPath, NULL, 0);
ppf->Release();
psl->Release();
return TRUE;
}
}
ppf->Release();
}
psl->Release();
return FALSE;
}
// turn a file, relative path or other into an absolute path
BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn)
// lpszPathOut = buffer of _MAX_PATH
// lpszFileIn = file, relative path or absolute path
// (both in ANSI character set)
{
ASSERT(AfxIsValidAddress(lpszPathOut, _MAX_PATH));
// first, fully qualify the path name
LPTSTR lpszFilePart;
if (!GetFullPathName(lpszFileIn, _MAX_PATH, lpszPathOut, &lpszFilePart))
{
#ifdef _DEBUG
if (lpszFileIn[0] != '\0')
TRACE1("Warning: could not parse the path '%s'.\n", lpszFileIn);
#endif
lstrcpyn(lpszPathOut, lpszFileIn, _MAX_PATH); // take it literally
return FALSE;
}
CString strRoot;
// determine the root name of the volume
AfxGetRoot(lpszPathOut, strRoot);
// get file system information for the volume
DWORD dwFlags, dwDummy;
if (!GetVolumeInformation(strRoot, NULL, 0, NULL, &dwDummy, &dwFlags,
NULL, 0))
{
TRACE1("Warning: could not get volume information '%s'.\n",
(LPCTSTR)strRoot);
return FALSE; // preserving case may not be correct
}
// not all characters have complete uppercase/lowercase
if (!(dwFlags & FS_CASE_IS_PRESERVED))
CharUpper(lpszPathOut);
// assume non-UNICODE file systems, use OEM character set
if (!(dwFlags & FS_UNICODE_STORED_ON_DISK))
{
WIN32_FIND_DATA data;
HANDLE h = FindFirstFile(lpszFileIn, &data);
if (h != INVALID_HANDLE_VALUE)
{
FindClose(h);
lstrcpy(lpszFilePart, data.cFileName);
}
}
return TRUE;
}
void AFXAPI AfxGetRoot(LPCTSTR lpszPath, CString& strRoot)
{
ASSERT(lpszPath != NULL);
// determine the root name of the volume
LPTSTR lpszRoot = strRoot.GetBuffer(_MAX_PATH);
memset(lpszRoot, 0, _MAX_PATH);
lstrcpyn(lpszRoot, lpszPath, _MAX_PATH);
for (LPTSTR lpsz = lpszRoot; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
{
// find first double slash and stop
if (IsDirSep(lpsz[0]) && IsDirSep(lpsz[1]))
break;
}
if (*lpsz != '\0')
{
// it is a UNC name, find second slash past '\\'
ASSERT(IsDirSep(lpsz[0]));
ASSERT(IsDirSep(lpsz[1]));
lpsz += 2;
while (*lpsz != '\0' && (!IsDirSep(*lpsz)))
lpsz = _tcsinc(lpsz);
if (*lpsz != '\0')
lpsz = _tcsinc(lpsz);
while (*lpsz != '\0' && (!IsDirSep(*lpsz)))
lpsz = _tcsinc(lpsz);
// terminate it just after the UNC root (ie. '\\server\share\')
if (*lpsz != '\0')
lpsz[1] = '\0';
}
else
{
// not a UNC, look for just the first slash
lpsz = lpszRoot;
while (*lpsz != '\0' && (!IsDirSep(*lpsz)))
lpsz = _tcsinc(lpsz);
// terminate it just after root (ie. 'x:\')
if (*lpsz != '\0')
lpsz[1] = '\0';
}
strRoot.ReleaseBuffer();
}
BOOL AFXAPI AfxComparePath(LPCTSTR lpszPath1, LPCTSTR lpszPath2)
{
// use case insensitive compare as a starter
if (lstrcmpi(lpszPath1, lpszPath2) != 0)
return FALSE;
// on non-DBCS systems, we are done
if (!GetSystemMetrics(SM_DBCSENABLED))
return TRUE;
// on DBCS systems, the file name may not actually be the same
// in particular, the file system is case sensitive with respect to
// "full width" roman characters.
// (ie. fullwidth-R is different from fullwidth-r).
int nLen = lstrlen(lpszPath1);
if (nLen != lstrlen(lpszPath2))
return FALSE;
ASSERT(nLen < _MAX_PATH);
// need to get both CT_CTYPE1 and CT_CTYPE3 for each filename
LCID lcid = GetThreadLocale();
WORD aCharType11[_MAX_PATH];
VERIFY(GetStringTypeEx(lcid, CT_CTYPE1, lpszPath1, -1, aCharType11));
WORD aCharType13[_MAX_PATH];
VERIFY(GetStringTypeEx(lcid, CT_CTYPE3, lpszPath1, -1, aCharType13));
WORD aCharType21[_MAX_PATH];
VERIFY(GetStringTypeEx(lcid, CT_CTYPE1, lpszPath2, -1, aCharType21));
#ifdef _DEBUG
WORD aCharType23[_MAX_PATH];
VERIFY(GetStringTypeEx(lcid, CT_CTYPE3, lpszPath2, -1, aCharType23));
#endif
// for every C3_FULLWIDTH character, make sure it has same C1 value
int i = 0;
for (LPCTSTR lpsz = lpszPath1; *lpsz != 0; lpsz = _tcsinc(lpsz))
{
// check for C3_FULLWIDTH characters only
if (aCharType13[i] & C3_FULLWIDTH)
{
#ifdef _DEBUG
ASSERT(aCharType23[i] & C3_FULLWIDTH); // should always match!
#endif
// if CT_CTYPE1 is different then file system considers these
// file names different.
if (aCharType11[i] != aCharType21[i])
return FALSE;
}
++i; // look at next character type
}
return TRUE; // otherwise file name is truly the same
}
UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax)
{
ASSERT(lpszTitle == NULL ||
AfxIsValidAddress(lpszTitle, _MAX_FNAME));
ASSERT(AfxIsValidString(lpszPathName));
// use a temporary to avoid bugs in ::GetFileTitle when lpszTitle is NULL
TCHAR szTemp[_MAX_PATH];
LPTSTR lpszTemp = lpszTitle;
if (lpszTemp == NULL)
{
lpszTemp = szTemp;
nMax = _countof(szTemp);
}
if (::GetFileTitle(lpszPathName, lpszTemp, (WORD)nMax) != 0)
{
// when ::GetFileTitle fails, use cheap imitation
return AfxGetFileName(lpszPathName, lpszTitle, nMax);
}
return lpszTitle == NULL ? lstrlen(lpszTemp)+1 : 0;
}
void AFXAPI AfxGetModuleShortFileName(HINSTANCE hInst, CString& strShortName)
{
TCHAR szLongPathName[_MAX_PATH];
::GetModuleFileName(hInst, szLongPathName, _MAX_PATH);
if (::GetShortPathName(szLongPathName,
strShortName.GetBuffer(_MAX_PATH), _MAX_PATH) == 0)
{
// rare failure case (especially on not-so-modern file systems)
strShortName = szLongPathName;
}
strShortName.ReleaseBuffer();
}
/////////////////////////////////////////////////////////////////////////////
// CFile diagnostics
#ifdef _DEBUG
void CFile::AssertValid() const
{
CObject::AssertValid();
// we permit the descriptor m_hFile to be any value for derived classes
}
void CFile::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << "with handle " << (UINT)m_hFile;
dc << " and name \"" << m_strFileName << "\"";
dc << "\n";
}
#endif
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
IMPLEMENT_DYNAMIC(CFile, CObject)
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -