mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
gh-88745: Add _winapi.CopyFile2 and update shutil.copy2 to use it (GH-105055)
This commit is contained in:
parent
d14eb3433c
commit
cda1bd3c9d
8 changed files with 210 additions and 1 deletions
|
@ -1947,6 +1947,7 @@ _winapi_GetFileType_impl(PyObject *module, HANDLE handle)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
_winapi._mimetypes_read_windows_registry
|
||||
|
||||
|
@ -2075,6 +2076,67 @@ _winapi_NeedCurrentDirectoryForExePath_impl(PyObject *module,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
_winapi.CopyFile2
|
||||
|
||||
existing_file_name: LPCWSTR
|
||||
new_file_name: LPCWSTR
|
||||
flags: DWORD
|
||||
progress_routine: object = None
|
||||
|
||||
Copies a file from one name to a new name.
|
||||
|
||||
This is implemented using the CopyFile2 API, which preserves all stat
|
||||
and metadata information apart from security attributes.
|
||||
|
||||
progress_routine is reserved for future use, but is currently not
|
||||
implemented. Its value is ignored.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_winapi_CopyFile2_impl(PyObject *module, LPCWSTR existing_file_name,
|
||||
LPCWSTR new_file_name, DWORD flags,
|
||||
PyObject *progress_routine)
|
||||
/*[clinic end generated code: output=43d960d9df73d984 input=fb976b8d1492d130]*/
|
||||
{
|
||||
HRESULT hr;
|
||||
COPYFILE2_EXTENDED_PARAMETERS params = { sizeof(COPYFILE2_EXTENDED_PARAMETERS) };
|
||||
|
||||
if (PySys_Audit("_winapi.CopyFile2", "uuI",
|
||||
existing_file_name, new_file_name, flags) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
params.dwCopyFlags = flags;
|
||||
/* For future implementation. We ignore the value for now so that
|
||||
users only have to test for 'CopyFile2' existing and not whether
|
||||
the additional parameter exists.
|
||||
if (progress_routine != Py_None) {
|
||||
params.pProgressRoutine = _winapi_CopyFile2ProgressRoutine;
|
||||
params.pvCallbackContext = Py_NewRef(progress_routine);
|
||||
}
|
||||
*/
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
hr = CopyFile2(existing_file_name, new_file_name, ¶ms);
|
||||
Py_END_ALLOW_THREADS;
|
||||
/* For future implementation.
|
||||
if (progress_routine != Py_None) {
|
||||
Py_DECREF(progress_routine);
|
||||
}
|
||||
*/
|
||||
if (FAILED(hr)) {
|
||||
if ((hr & 0xFFFF0000) == 0x80070000) {
|
||||
PyErr_SetFromWindowsErr(hr & 0xFFFF);
|
||||
} else {
|
||||
PyErr_SetFromWindowsErr(hr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef winapi_functions[] = {
|
||||
_WINAPI_CLOSEHANDLE_METHODDEF
|
||||
_WINAPI_CONNECTNAMEDPIPE_METHODDEF
|
||||
|
@ -2110,6 +2172,7 @@ static PyMethodDef winapi_functions[] = {
|
|||
_WINAPI_GETFILETYPE_METHODDEF
|
||||
_WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
|
||||
_WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF
|
||||
_WINAPI_COPYFILE2_METHODDEF
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -2146,6 +2209,7 @@ static int winapi_exec(PyObject *m)
|
|||
WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP);
|
||||
WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS);
|
||||
WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_ACCESS_DENIED);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING);
|
||||
|
@ -2159,6 +2223,7 @@ static int winapi_exec(PyObject *m)
|
|||
WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_PRIVILEGE_NOT_HELD);
|
||||
WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
|
||||
WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE);
|
||||
WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED);
|
||||
|
@ -2252,6 +2317,34 @@ static int winapi_exec(PyObject *m)
|
|||
WINAPI_CONSTANT(F_DWORD, LCMAP_TRADITIONAL_CHINESE);
|
||||
WINAPI_CONSTANT(F_DWORD, LCMAP_UPPERCASE);
|
||||
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_ALLOW_DECRYPTED_DESTINATION);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_COPY_SYMLINK);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_FAIL_IF_EXISTS);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_NO_BUFFERING);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_NO_OFFLOAD);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_OPEN_SOURCE_FOR_WRITE);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_RESTARTABLE);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_REQUEST_SECURITY_PRIVILEGES);
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_RESUME_FROM_PAUSE);
|
||||
#ifndef COPY_FILE_REQUEST_COMPRESSED_TRAFFIC
|
||||
// Only defined in newer WinSDKs
|
||||
#define COPY_FILE_REQUEST_COMPRESSED_TRAFFIC 0x10000000
|
||||
#endif
|
||||
WINAPI_CONSTANT(F_DWORD, COPY_FILE_REQUEST_COMPRESSED_TRAFFIC);
|
||||
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_CHUNK_STARTED);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_CHUNK_FINISHED);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_STREAM_STARTED);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_STREAM_FINISHED);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_POLL_CONTINUE);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_ERROR);
|
||||
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_CONTINUE);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_CANCEL);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_STOP);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_QUIET);
|
||||
WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_PAUSE);
|
||||
|
||||
WINAPI_CONSTANT("i", NULL);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue