📄 shlfileop.c
字号:
if (!b_MultiFrom && !b_MultiTo)
b_MultiFrom = (pNextFrom[0]);
pFromFile = SHFileStrCpyCatW(pTempFrom, pFrom, NULL);
if (pTo)
{
pToFile = SHFileStrCpyCatW(pTempTo, pTo, NULL);
}
if (!b_MultiPaired)
{
b_MultiPaired =
SHELL_FileNamesMatch(lpFileOp->pFrom, lpFileOp->pTo, (!b_Multi || b_MultiFrom));
}
if (!(b_MultiPaired) || !(pFromFile) || !(pFromFile[1]) || ((pTo) && !(pToFile)))
{
retCode = ERROR_SHELL_INTERNAL_FILE_NOT_FOUND;
goto shfileop_end;
}
if (pTo)
{
b_ToTailSlash = (!pToFile[1]);
if (b_ToTailSlash)
{
pToFile[0] = '\0';
if (StrChrW(pTempTo,'\\'))
{
pToFile = SHFileStrCpyCatW(pTempTo, NULL, NULL);
}
}
b_ToInvalidTail = (NULL != StrPBrkW(&pToFile[1], wWildcardChars));
}
/* for all */
b_Mask = (NULL != StrPBrkW(&pFromFile[1], wWildcardChars));
if (FO_RENAME == FuncSwitch)
{
/* temporary only for FO_RENAME */
if (b_MultiTo || b_MultiFrom || (b_Mask && !b_ToInvalidTail))
{
#ifndef W98_FO_FUNCTION
retCode = ERROR_GEN_FAILURE; /* W2K ERROR_GEN_FAILURE, W98 returns no error */
#endif
goto shfileop_end;
}
}
hFind = FindFirstFileW(pFrom, &wfd);
if (INVALID_HANDLE_VALUE == hFind)
{
if ((FO_DELETE == FuncSwitch) && (b_Mask) && IsAttribDir(shfileops_get_parent_attr(pFromFile,pTempFrom)))
{
/* FO_DELETE with mask and without found is valid */
goto shfileop_end;
}
/* root (without mask) is also not allowed as source, tested in W98 */
retCode = ERROR_SHELL_INTERNAL_FILE_NOT_FOUND;
goto shfileop_end;
}
/* for all */
/* ??? b_Mask = (!SHFileStrICmpA(&pFromFile[1], &wfd.cFileName[0], HIGH_ADR, HIGH_ADR)); */
if (!pTo) /* FO_DELETE */
{
retCode = shfileops_delete(&wfd,nFileOp,pFromFile,pTempFrom,&hFind);
/* if ret is not 0, nFileOp.fAnyOperationsAborted is TRUE and the loop will end */
continue;
} /* FO_DELETE ends, pTo must be always valid from here */
b_SameRoot = (toupperW(pTempFrom[0]) == toupperW(pTempTo[0]));
b_SameTailName = SHFileStrICmpW(pToFile, pFromFile, NULL, NULL);
ToPathAttr = ToAttr = GetFileAttributesW(pTempTo);
if (!b_Mask && (ToAttr == INVALID_FILE_ATTRIBUTES) && (pToFile))
{
ToPathAttr = shfileops_get_parent_attr(pToFile,pTempTo);
}
if (FO_RENAME == FuncSwitch)
{
if (!b_SameRoot || b_Mask /* FO_RENAME works not with Mask */
|| !SHFileStrICmpW(pTempFrom, pTempTo, pFromFile, NULL)
|| (SHFileStrICmpW(pTempFrom, pTempTo, pFromFile, HIGH_ADR) && !b_ToTailSlash))
{
retCode = 0x73;
goto shfileop_end;
}
if (b_ToInvalidTail)
{
retCode=0x2;
goto shfileop_end;
}
if (INVALID_FILE_ATTRIBUTES == ToPathAttr)
{
retCode = 0x75;
goto shfileop_end;
}
if (IsAttribDir(wfd.dwFileAttributes) && IsAttribDir(ToAttr))
{
retCode = (b_ToTailSlash) ? 0xb7 : 0x7b;
goto shfileop_end;
}
/* we use SHNotifyMoveFile() instead MoveFileW */
if (SHNotifyMoveFileW(pTempFrom, pTempTo) != ERROR_SUCCESS)
{
/* we need still the value for the returncode, we use the mostly assumed */
retCode = 0xb7;
goto shfileop_end;
}
goto shfileop_end;
}
/* W98 Bug with FO_MOVE different from FO_COPY, better the same as FO_COPY */
b_ToValid = ((b_SameTailName && b_SameRoot && (FO_COPY == FuncSwitch)) ||
(b_SameTailName && !b_SameRoot) || (b_ToInvalidTail));
/* handle mask in source */
if (b_Mask)
{
if (!IsAttribDir(ToAttr))
{
retCode = (b_ToInvalidTail &&/* b_SameTailName &&*/ (FO_MOVE == FuncSwitch)) \
? 0x2 : 0x75;
goto shfileop_end;
}
pToFile = SHFileStrCpyCatW(pTempTo, NULL, wBackslash);
nFileOp.fFlags = (nFileOp.fFlags | FOF_MULTIDESTFILES);
do
{
retCode = shfileops_do_operation(wfd,&nFileOp,pToFile,pFromFile);
} while(!nFileOp.fAnyOperationsAborted && FindNextFileW(hFind, &wfd));
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
/* FO_COPY/FO_MOVE with mask, FO_DELETE and FO_RENAME are solved */
if (b_Mask)
continue;
/* only FO_COPY/FO_MOVE without mask, all others are (must be) solved */
if (IsAttribDir(wfd.dwFileAttributes) && (ToAttr == INVALID_FILE_ATTRIBUTES))
{
if (pToFile)
{
ToPathAttr = shfileops_get_parent_attr2(pToFile,pTempTo,b_ToValid,&retCode);
if (retCode)
goto shfileop_end;
if (b_ToInvalidTail)
{
retCode = 0x10003;
goto shfileop_end;
}
}
}
/* trailing BackSlash is ever removed and pToFile points to BackSlash before */
if (!b_MultiTo && (b_MultiFrom || (!(b_Multi) && IsAttribDir(ToAttr))))
{
if ((FO_MOVE == FuncSwitch) && IsAttribDir(ToAttr) && IsAttribDir(wfd.dwFileAttributes))
{
if (b_Multi)
{
retCode = 0x73; /* !b_Multi = 0x8 ?? */
goto shfileop_end;
}
}
pToFile = SHFileStrCpyCatW(pTempTo, NULL, wfd.cFileName);
ToAttr = GetFileAttributesW(pTempTo);
}
if (IsAttribDir(ToAttr))
{
if (IsAttribFile(wfd.dwFileAttributes))
{
retCode = (FO_COPY == FuncSwitch) ? 0x75 : 0xb7;
goto shfileop_end;
}
}
else
{
ToPathAttr = shfileops_get_parent_attr(pToFile,pTempTo);
if (IsAttribFile(ToPathAttr))
{
/* error, is this tested ? */
retCode = 0x777402;
goto shfileop_end;
}
}
/* singlesource + no mask */
if (INVALID_FILE_ATTRIBUTES == (ToAttr & ToPathAttr))
{
/* Target-dir does not exist, and cannot be created */
retCode=0x75;
goto shfileop_end;
}
switch(FuncSwitch)
{
case FO_MOVE:
pToFile = NULL;
if ((ToAttr == INVALID_FILE_ATTRIBUTES) && SHFileStrICmpW(pTempFrom, pTempTo, pFromFile, NULL))
{
nFileOp.wFunc = ((level+1)<<4) + FO_RENAME;
}
else
{
if (b_SameRoot && IsAttribDir(ToAttr) && IsAttribDir(wfd.dwFileAttributes))
{
/* we need pToFile for FO_DELETE after FO_MOVE contence */
pToFile = SHFileStrCpyCatW(pTempFrom, NULL, wWildcardFile);
}
else
{
nFileOp.wFunc = ((level+1)<<4) + FO_COPY;
}
}
retCode = SHFileOperationW(&nFileOp);
if (pToFile)
((DWORD*)pToFile)[0] = '\0';
if (!nFileOp.fAnyOperationsAborted && (FO_RENAME != (nFileOp.wFunc & 0xf)))
{
nFileOp.wFunc = ((level+1)<<4) + FO_DELETE;
retCode = SHFileOperationW(&nFileOp);
}
continue;
case FO_COPY:
if (SHFileStrICmpW(pTempFrom, pTempTo, NULL, NULL))
{ /* target is the same as source ? */
/* we still need the value for the returncode, we assume 0x71 */
retCode = 0x71;
goto shfileop_end;
}
if (IsAttribDir((ToAttr & wfd.dwFileAttributes)))
{
if (IsAttribDir(ToAttr) || !SHNotifyCreateDirectoryW(pTempTo, NULL))
{
/* ??? nFileOp.fFlags = (nFileOp.fFlags | FOF_MULTIDESTFILES); */
SHFileStrCpyCatW(pTempFrom, NULL, wWildcardFile);
retCode = SHFileOperationW(&nFileOp);
}
else
{
retCode = 0x750;/* value unknown */
goto shfileop_end;
}
}
else
{
if (!(ask_overwrite && SHELL_ConfirmDialogW(ASK_OVERWRITE_FILE, pTempTo))
&& (not_overwrite))
{
/* we still need the value for the returncode, we use the mostly assumed */
retCode = 0x73;
goto shfileop_end;
}
if (SHNotifyCopyFileW(pTempFrom, pTempTo, TRUE) != ERROR_SUCCESS)
{
retCode = 0x77; /* value unknown */
goto shfileop_end;
}
}
}
}
shfileop_end:
if (hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
HeapFree(GetProcessHeap(), 0, pTempFrom);
if (retCode)
nFileOp.fAnyOperationsAborted = TRUE;
TRACE("%s level=%ld AnyOpsAborted=%s ret=0x%x, with %s %s%s\n",
debug_shfileops_action(FuncSwitch), level,
nFileOp.fAnyOperationsAborted ? "TRUE":"FALSE",
retCode, debugstr_w(pFrom), pTo ? "-> ":"", debugstr_w(pTo));
lpFileOp->fAnyOperationsAborted = nFileOp.fAnyOperationsAborted;
return retCode;
}
#define SHDSA_GetItemCount(hdsa) (*(int*)(hdsa))
/*************************************************************************
* SHFreeNameMappings [shell32.246]
*
* Free the mapping handle returned by SHFileoperation if FOF_WANTSMAPPINGHANDLE
* was specified.
*
* PARAMS
* hNameMapping [I] handle to the name mappings used during renaming of files
*
* RETURNS
* Nothing
*/
void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
{
if (hNameMapping)
{
int i = SHDSA_GetItemCount((HDSA)hNameMapping) - 1;
for (; i>= 0; i--)
{
LPSHNAMEMAPPINGW lp = DSA_GetItemPtr((HDSA)hNameMapping, i);
SHFree(lp->pszOldPath);
SHFree(lp->pszNewPath);
}
DSA_Destroy((HDSA)hNameMapping);
}
}
/*************************************************************************
* SheGetDirA [SHELL32.@]
*
*/
HRESULT WINAPI SheGetDirA(LPSTR u, LPSTR v)
{ FIXME("%p %p stub\n",u,v);
return 0;
}
/*************************************************************************
* SheGetDirW [SHELL32.@]
*
*/
HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
{ FIXME("%p %p stub\n",u,v);
return 0;
}
/*************************************************************************
* SheChangeDirA [SHELL32.@]
*
*/
HRESULT WINAPI SheChangeDirA(LPSTR u)
{ FIXME("(%s),stub\n",debugstr_a(u));
return 0;
}
/*************************************************************************
* SheChangeDirW [SHELL32.@]
*
*/
HRESULT WINAPI SheChangeDirW(LPWSTR u)
{ FIXME("(%s),stub\n",debugstr_w(u));
return 0;
}
/*************************************************************************
* IsNetDrive [SHELL32.66]
*/
BOOL WINAPI IsNetDrive(DWORD drive)
{
char root[4];
strcpy(root, "A:\\");
root[0] += (char)drive;
return (GetDriveTypeA(root) == DRIVE_REMOTE);
}
/*************************************************************************
* RealDriveType [SHELL32.524]
*/
INT WINAPI RealDriveType(INT drive, BOOL bQueryNet)
{
char root[] = "A:\\";
root[0] += (char)drive;
return GetDriveTypeA(root);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -