Backed out changeset: 17df50df62c7
This commit is contained in:
parent
15efd2b643
commit
fbf963c064
|
@ -39,10 +39,6 @@ try:
|
|||
import fcntl
|
||||
except ImportError:
|
||||
fcntl = None
|
||||
try:
|
||||
import _winapi
|
||||
except ImportError:
|
||||
_winapi = None
|
||||
|
||||
from test.script_helper import assert_python_ok
|
||||
|
||||
|
@ -1777,37 +1773,6 @@ class Win32SymlinkTests(unittest.TestCase):
|
|||
shutil.rmtree(level1)
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
|
||||
class Win32JunctionTests(unittest.TestCase):
|
||||
junction = 'junctiontest'
|
||||
junction_target = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def setUp(self):
|
||||
assert os.path.exists(self.junction_target)
|
||||
assert not os.path.exists(self.junction)
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.junction):
|
||||
# os.rmdir delegates to Windows' RemoveDirectoryW,
|
||||
# which removes junction points safely.
|
||||
os.rmdir(self.junction)
|
||||
|
||||
def test_create_junction(self):
|
||||
_winapi.CreateJunction(self.junction_target, self.junction)
|
||||
self.assertTrue(os.path.exists(self.junction))
|
||||
self.assertTrue(os.path.isdir(self.junction))
|
||||
|
||||
# Junctions are not recognized as links.
|
||||
self.assertFalse(os.path.islink(self.junction))
|
||||
|
||||
def test_unlink_removes_junction(self):
|
||||
_winapi.CreateJunction(self.junction_target, self.junction)
|
||||
self.assertTrue(os.path.exists(self.junction))
|
||||
|
||||
os.unlink(self.junction)
|
||||
self.assertFalse(os.path.exists(self.junction))
|
||||
|
||||
|
||||
@support.skip_unless_symlink
|
||||
class NonLocalSymlinkTests(unittest.TestCase):
|
||||
|
||||
|
@ -2579,7 +2544,6 @@ def test_main():
|
|||
RemoveDirsTests,
|
||||
CPUCountTests,
|
||||
FDInheritanceTests,
|
||||
Win32JunctionTests,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -468,7 +468,6 @@ Chris Gonnerman
|
|||
Shelley Gooch
|
||||
David Goodger
|
||||
Hans de Graaff
|
||||
Kim Gräsman
|
||||
Nathaniel Gray
|
||||
Eddy De Greef
|
||||
Grant Griffin
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include "windows.h"
|
||||
#include <crtdbg.h>
|
||||
#include "winreparse.h"
|
||||
|
||||
#if defined(MS_WIN32) && !defined(MS_WIN64)
|
||||
#define HANDLE_TO_PYNUM(handle) \
|
||||
|
@ -401,112 +400,6 @@ winapi_CreateFile(PyObject *self, PyObject *args)
|
|||
return Py_BuildValue(F_HANDLE, handle);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winapi_CreateJunction(PyObject *self, PyObject *args)
|
||||
{
|
||||
/* Input arguments */
|
||||
LPWSTR src_path = NULL;
|
||||
LPWSTR dst_path = NULL;
|
||||
|
||||
/* Privilege adjustment */
|
||||
HANDLE token = NULL;
|
||||
TOKEN_PRIVILEGES tp;
|
||||
|
||||
/* Reparse data buffer */
|
||||
const USHORT prefix_len = 4;
|
||||
USHORT print_len = 0;
|
||||
USHORT rdb_size = 0;
|
||||
PREPARSE_DATA_BUFFER rdb = NULL;
|
||||
|
||||
/* Junction point creation */
|
||||
HANDLE junction = NULL;
|
||||
DWORD ret = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "uu",
|
||||
&src_path, &dst_path))
|
||||
return NULL;
|
||||
|
||||
if (memcmp(src_path, L"\\??\\", prefix_len * sizeof(WCHAR)) == 0)
|
||||
return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER);
|
||||
|
||||
/* Adjust privileges to allow rewriting directory entry as a
|
||||
junction point. */
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
|
||||
goto cleanup;
|
||||
|
||||
if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid))
|
||||
goto cleanup;
|
||||
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
|
||||
NULL, NULL))
|
||||
goto cleanup;
|
||||
|
||||
if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES)
|
||||
goto cleanup;
|
||||
|
||||
print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL);
|
||||
if (print_len == 0)
|
||||
goto cleanup;
|
||||
|
||||
/* NUL terminator should not be part of print_len */
|
||||
--print_len;
|
||||
|
||||
rdb_size = REPARSE_DATA_BUFFER_HEADER_SIZE +
|
||||
sizeof(rdb->MountPointReparseBuffer) -
|
||||
sizeof(rdb->MountPointReparseBuffer.PathBuffer) +
|
||||
/* Two +1's for NUL terminators. */
|
||||
(prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR);
|
||||
rdb = (PREPARSE_DATA_BUFFER)PyMem_RawMalloc(rdb_size, 1);
|
||||
|
||||
rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
rdb->ReparseDataLength = rdb_size - REPARSE_DATA_BUFFER_HEADER_SIZE;
|
||||
rdb->MountPointReparseBuffer.SubstituteNameOffset = 0;
|
||||
rdb->MountPointReparseBuffer.SubstituteNameLength =
|
||||
(prefix_len + print_len) * sizeof(WCHAR);
|
||||
rdb->MountPointReparseBuffer.PrintNameOffset =
|
||||
rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
|
||||
rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR);
|
||||
|
||||
lstrcpyW(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\");
|
||||
if (GetFullPathNameW(src_path, print_len + 1,
|
||||
rdb->MountPointReparseBuffer.PathBuffer + prefix_len,
|
||||
NULL) == 0)
|
||||
goto cleanup;
|
||||
|
||||
lstrcpyW(rdb->MountPointReparseBuffer.PathBuffer +
|
||||
prefix_len + print_len + 1,
|
||||
rdb->MountPointReparseBuffer.PathBuffer + prefix_len);
|
||||
|
||||
/* Create a directory for the junction point. */
|
||||
if (!CreateDirectoryW(dst_path, NULL))
|
||||
goto cleanup;
|
||||
|
||||
junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (junction == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
|
||||
/* Make the directory entry a junction point. */
|
||||
if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size,
|
||||
NULL, 0, &ret, NULL))
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
ret = GetLastError();
|
||||
|
||||
CloseHandle(token);
|
||||
CloseHandle(junction);
|
||||
free(rdb);
|
||||
|
||||
if (ret != 0)
|
||||
return PyErr_SetFromWindowsErr(ret);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winapi_CreateNamedPipe(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -1332,8 +1225,6 @@ static PyMethodDef winapi_functions[] = {
|
|||
METH_VARARGS | METH_KEYWORDS, ""},
|
||||
{"CreateFile", winapi_CreateFile, METH_VARARGS,
|
||||
""},
|
||||
{"CreateJunction", winapi_CreateJunction, METH_VARARGS,
|
||||
""},
|
||||
{"CreateNamedPipe", winapi_CreateNamedPipe, METH_VARARGS,
|
||||
""},
|
||||
{"CreatePipe", winapi_CreatePipe, METH_VARARGS,
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include "Python.h"
|
||||
#ifndef MS_WINDOWS
|
||||
#include "posixmodule.h"
|
||||
#else
|
||||
#include "winreparse.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -303,9 +301,6 @@ extern int lstat(const char *, struct stat *);
|
|||
#ifndef IO_REPARSE_TAG_SYMLINK
|
||||
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
|
||||
#endif
|
||||
#ifndef IO_REPARSE_TAG_MOUNT_POINT
|
||||
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
|
||||
#endif
|
||||
#include "osdefs.h"
|
||||
#include <malloc.h>
|
||||
#include <windows.h>
|
||||
|
@ -1114,6 +1109,41 @@ _PyVerify_fd_dup2(int fd1, int fd2)
|
|||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* The following structure was copied from
|
||||
http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
|
||||
include doesn't seem to be present in the Windows SDK (at least as included
|
||||
with Visual Studio Express). */
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
};
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
|
||||
GenericReparseBuffer)
|
||||
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
|
||||
|
||||
static int
|
||||
win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
|
||||
|
@ -4462,10 +4492,7 @@ BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
|
|||
find_data_handle = FindFirstFileW(lpFileName, &find_data);
|
||||
|
||||
if(find_data_handle != INVALID_HANDLE_VALUE) {
|
||||
/* IO_REPARSE_TAG_SYMLINK if it is a symlink and
|
||||
IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
|
||||
is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
|
||||
find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
|
||||
is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
|
||||
FindClose(find_data_handle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
#ifndef Py_WINREPARSE_H
|
||||
#define Py_WINREPARSE_H
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
#include <Windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The following structure was copied from
|
||||
http://msdn.microsoft.com/en-us/library/ff552012.aspx as the required
|
||||
include doesn't seem to be present in the Windows SDK (at least as included
|
||||
with Visual Studio Express). */
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
};
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
|
||||
GenericReparseBuffer)
|
||||
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
#endif /* !Py_WINREPARSE_H */
|
Loading…
Reference in New Issue