@@ -1947,6 +1947,7 @@ _winapi_GetFileType_impl(PyObject *module, HANDLE handle)
1947
1947
return result ;
1948
1948
}
1949
1949
1950
+
1950
1951
/*[clinic input]
1951
1952
_winapi._mimetypes_read_windows_registry
1952
1953
@@ -2075,6 +2076,67 @@ _winapi_NeedCurrentDirectoryForExePath_impl(PyObject *module,
2075
2076
return result ;
2076
2077
}
2077
2078
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
+
2078
2140
static PyMethodDef winapi_functions [] = {
2079
2141
_WINAPI_CLOSEHANDLE_METHODDEF
2080
2142
_WINAPI_CONNECTNAMEDPIPE_METHODDEF
@@ -2110,6 +2172,7 @@ static PyMethodDef winapi_functions[] = {
2110
2172
_WINAPI_GETFILETYPE_METHODDEF
2111
2173
_WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
2112
2174
_WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF
2175
+ _WINAPI_COPYFILE2_METHODDEF
2113
2176
{NULL , NULL }
2114
2177
};
2115
2178
@@ -2146,6 +2209,7 @@ static int winapi_exec(PyObject *m)
2146
2209
WINAPI_CONSTANT (F_DWORD , CREATE_NEW_PROCESS_GROUP );
2147
2210
WINAPI_CONSTANT (F_DWORD , DUPLICATE_SAME_ACCESS );
2148
2211
WINAPI_CONSTANT (F_DWORD , DUPLICATE_CLOSE_SOURCE );
2212
+ WINAPI_CONSTANT (F_DWORD , ERROR_ACCESS_DENIED );
2149
2213
WINAPI_CONSTANT (F_DWORD , ERROR_ALREADY_EXISTS );
2150
2214
WINAPI_CONSTANT (F_DWORD , ERROR_BROKEN_PIPE );
2151
2215
WINAPI_CONSTANT (F_DWORD , ERROR_IO_PENDING );
@@ -2159,6 +2223,7 @@ static int winapi_exec(PyObject *m)
2159
2223
WINAPI_CONSTANT (F_DWORD , ERROR_OPERATION_ABORTED );
2160
2224
WINAPI_CONSTANT (F_DWORD , ERROR_PIPE_BUSY );
2161
2225
WINAPI_CONSTANT (F_DWORD , ERROR_PIPE_CONNECTED );
2226
+ WINAPI_CONSTANT (F_DWORD , ERROR_PRIVILEGE_NOT_HELD );
2162
2227
WINAPI_CONSTANT (F_DWORD , ERROR_SEM_TIMEOUT );
2163
2228
WINAPI_CONSTANT (F_DWORD , FILE_FLAG_FIRST_PIPE_INSTANCE );
2164
2229
WINAPI_CONSTANT (F_DWORD , FILE_FLAG_OVERLAPPED );
@@ -2252,6 +2317,34 @@ static int winapi_exec(PyObject *m)
2252
2317
WINAPI_CONSTANT (F_DWORD , LCMAP_TRADITIONAL_CHINESE );
2253
2318
WINAPI_CONSTANT (F_DWORD , LCMAP_UPPERCASE );
2254
2319
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
+
2255
2348
WINAPI_CONSTANT ("i" , NULL );
2256
2349
2257
2350
return 0 ;
0 commit comments