@@ -1947,6 +1947,7 @@ _winapi_GetFileType_impl(PyObject *module, HANDLE handle)
19471947 return result ;
19481948}
19491949
1950+
19501951/*[clinic input]
19511952_winapi._mimetypes_read_windows_registry
19521953
@@ -2075,6 +2076,67 @@ _winapi_NeedCurrentDirectoryForExePath_impl(PyObject *module,
20752076 return result ;
20762077}
20772078
2079+
2080+ /*[clinic input]
2081+ _winapi.CopyFile2
2082+
2083+ existing_file_name: LPCWSTR
2084+ new_file_name: LPCWSTR
2085+ flags: DWORD
2086+ progress_routine: object = None
2087+
2088+ Copies a file from one name to a new name.
2089+
2090+ This is implemented using the CopyFile2 API, which preserves all stat
2091+ and metadata information apart from security attributes.
2092+
2093+ progress_routine is reserved for future use, but is currently not
2094+ implemented. Its value is ignored.
2095+ [clinic start generated code]*/
2096+
2097+ static PyObject *
2098+ _winapi_CopyFile2_impl (PyObject * module , LPCWSTR existing_file_name ,
2099+ LPCWSTR new_file_name , DWORD flags ,
2100+ PyObject * progress_routine )
2101+ /*[clinic end generated code: output=43d960d9df73d984 input=fb976b8d1492d130]*/
2102+ {
2103+ HRESULT hr ;
2104+ COPYFILE2_EXTENDED_PARAMETERS params = { sizeof (COPYFILE2_EXTENDED_PARAMETERS ) };
2105+
2106+ if (PySys_Audit ("_winapi.CopyFile2" , "uuI" ,
2107+ existing_file_name , new_file_name , flags ) < 0 ) {
2108+ return NULL ;
2109+ }
2110+
2111+ params .dwCopyFlags = flags ;
2112+ /* For future implementation. We ignore the value for now so that
2113+ users only have to test for 'CopyFile2' existing and not whether
2114+ the additional parameter exists.
2115+ if (progress_routine != Py_None) {
2116+ params.pProgressRoutine = _winapi_CopyFile2ProgressRoutine;
2117+ params.pvCallbackContext = Py_NewRef(progress_routine);
2118+ }
2119+ */
2120+ Py_BEGIN_ALLOW_THREADS ;
2121+ hr = CopyFile2 (existing_file_name , new_file_name , & params );
2122+ Py_END_ALLOW_THREADS ;
2123+ /* For future implementation.
2124+ if (progress_routine != Py_None) {
2125+ Py_DECREF(progress_routine);
2126+ }
2127+ */
2128+ if (FAILED (hr )) {
2129+ if ((hr & 0xFFFF0000 ) == 0x80070000 ) {
2130+ PyErr_SetFromWindowsErr (hr & 0xFFFF );
2131+ } else {
2132+ PyErr_SetFromWindowsErr (hr );
2133+ }
2134+ return NULL ;
2135+ }
2136+ Py_RETURN_NONE ;
2137+ }
2138+
2139+
20782140static PyMethodDef winapi_functions [] = {
20792141 _WINAPI_CLOSEHANDLE_METHODDEF
20802142 _WINAPI_CONNECTNAMEDPIPE_METHODDEF
@@ -2110,6 +2172,7 @@ static PyMethodDef winapi_functions[] = {
21102172 _WINAPI_GETFILETYPE_METHODDEF
21112173 _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
21122174 _WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF
2175+ _WINAPI_COPYFILE2_METHODDEF
21132176 {NULL , NULL }
21142177};
21152178
@@ -2146,6 +2209,7 @@ static int winapi_exec(PyObject *m)
21462209 WINAPI_CONSTANT (F_DWORD , CREATE_NEW_PROCESS_GROUP );
21472210 WINAPI_CONSTANT (F_DWORD , DUPLICATE_SAME_ACCESS );
21482211 WINAPI_CONSTANT (F_DWORD , DUPLICATE_CLOSE_SOURCE );
2212+ WINAPI_CONSTANT (F_DWORD , ERROR_ACCESS_DENIED );
21492213 WINAPI_CONSTANT (F_DWORD , ERROR_ALREADY_EXISTS );
21502214 WINAPI_CONSTANT (F_DWORD , ERROR_BROKEN_PIPE );
21512215 WINAPI_CONSTANT (F_DWORD , ERROR_IO_PENDING );
@@ -2159,6 +2223,7 @@ static int winapi_exec(PyObject *m)
21592223 WINAPI_CONSTANT (F_DWORD , ERROR_OPERATION_ABORTED );
21602224 WINAPI_CONSTANT (F_DWORD , ERROR_PIPE_BUSY );
21612225 WINAPI_CONSTANT (F_DWORD , ERROR_PIPE_CONNECTED );
2226+ WINAPI_CONSTANT (F_DWORD , ERROR_PRIVILEGE_NOT_HELD );
21622227 WINAPI_CONSTANT (F_DWORD , ERROR_SEM_TIMEOUT );
21632228 WINAPI_CONSTANT (F_DWORD , FILE_FLAG_FIRST_PIPE_INSTANCE );
21642229 WINAPI_CONSTANT (F_DWORD , FILE_FLAG_OVERLAPPED );
@@ -2252,6 +2317,34 @@ static int winapi_exec(PyObject *m)
22522317 WINAPI_CONSTANT (F_DWORD , LCMAP_TRADITIONAL_CHINESE );
22532318 WINAPI_CONSTANT (F_DWORD , LCMAP_UPPERCASE );
22542319
2320+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_ALLOW_DECRYPTED_DESTINATION );
2321+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_COPY_SYMLINK );
2322+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_FAIL_IF_EXISTS );
2323+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_NO_BUFFERING );
2324+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_NO_OFFLOAD );
2325+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_OPEN_SOURCE_FOR_WRITE );
2326+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_RESTARTABLE );
2327+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_REQUEST_SECURITY_PRIVILEGES );
2328+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_RESUME_FROM_PAUSE );
2329+ #ifndef COPY_FILE_REQUEST_COMPRESSED_TRAFFIC
2330+ // Only defined in newer WinSDKs
2331+ #define COPY_FILE_REQUEST_COMPRESSED_TRAFFIC 0x10000000
2332+ #endif
2333+ WINAPI_CONSTANT (F_DWORD , COPY_FILE_REQUEST_COMPRESSED_TRAFFIC );
2334+
2335+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_CALLBACK_CHUNK_STARTED );
2336+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_CALLBACK_CHUNK_FINISHED );
2337+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_CALLBACK_STREAM_STARTED );
2338+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_CALLBACK_STREAM_FINISHED );
2339+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_CALLBACK_POLL_CONTINUE );
2340+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_CALLBACK_ERROR );
2341+
2342+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_PROGRESS_CONTINUE );
2343+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_PROGRESS_CANCEL );
2344+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_PROGRESS_STOP );
2345+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_PROGRESS_QUIET );
2346+ WINAPI_CONSTANT (F_DWORD , COPYFILE2_PROGRESS_PAUSE );
2347+
22552348 WINAPI_CONSTANT ("i" , NULL );
22562349
22572350 return 0 ;
0 commit comments