Backed out changeset: 17df50df62c7

This commit is contained in:
Tim Golden 2014-04-27 18:35:36 +01:00
parent 15efd2b643
commit fbf963c064
5 changed files with 36 additions and 208 deletions

View File

@ -39,10 +39,6 @@ try:
import fcntl import fcntl
except ImportError: except ImportError:
fcntl = None fcntl = None
try:
import _winapi
except ImportError:
_winapi = None
from test.script_helper import assert_python_ok from test.script_helper import assert_python_ok
@ -1777,37 +1773,6 @@ class Win32SymlinkTests(unittest.TestCase):
shutil.rmtree(level1) 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 @support.skip_unless_symlink
class NonLocalSymlinkTests(unittest.TestCase): class NonLocalSymlinkTests(unittest.TestCase):
@ -2579,7 +2544,6 @@ def test_main():
RemoveDirsTests, RemoveDirsTests,
CPUCountTests, CPUCountTests,
FDInheritanceTests, FDInheritanceTests,
Win32JunctionTests,
) )
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -468,7 +468,6 @@ Chris Gonnerman
Shelley Gooch Shelley Gooch
David Goodger David Goodger
Hans de Graaff Hans de Graaff
Kim Gräsman
Nathaniel Gray Nathaniel Gray
Eddy De Greef Eddy De Greef
Grant Griffin Grant Griffin

View File

@ -40,7 +40,6 @@
#define WINDOWS_LEAN_AND_MEAN #define WINDOWS_LEAN_AND_MEAN
#include "windows.h" #include "windows.h"
#include <crtdbg.h> #include <crtdbg.h>
#include "winreparse.h"
#if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(MS_WIN32) && !defined(MS_WIN64)
#define HANDLE_TO_PYNUM(handle) \ #define HANDLE_TO_PYNUM(handle) \
@ -401,112 +400,6 @@ winapi_CreateFile(PyObject *self, PyObject *args)
return Py_BuildValue(F_HANDLE, handle); 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 * static PyObject *
winapi_CreateNamedPipe(PyObject *self, PyObject *args) winapi_CreateNamedPipe(PyObject *self, PyObject *args)
{ {
@ -1332,8 +1225,6 @@ static PyMethodDef winapi_functions[] = {
METH_VARARGS | METH_KEYWORDS, ""}, METH_VARARGS | METH_KEYWORDS, ""},
{"CreateFile", winapi_CreateFile, METH_VARARGS, {"CreateFile", winapi_CreateFile, METH_VARARGS,
""}, ""},
{"CreateJunction", winapi_CreateJunction, METH_VARARGS,
""},
{"CreateNamedPipe", winapi_CreateNamedPipe, METH_VARARGS, {"CreateNamedPipe", winapi_CreateNamedPipe, METH_VARARGS,
""}, ""},
{"CreatePipe", winapi_CreatePipe, METH_VARARGS, {"CreatePipe", winapi_CreatePipe, METH_VARARGS,

View File

@ -27,8 +27,6 @@
#include "Python.h" #include "Python.h"
#ifndef MS_WINDOWS #ifndef MS_WINDOWS
#include "posixmodule.h" #include "posixmodule.h"
#else
#include "winreparse.h"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -303,9 +301,6 @@ extern int lstat(const char *, struct stat *);
#ifndef IO_REPARSE_TAG_SYMLINK #ifndef IO_REPARSE_TAG_SYMLINK
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) #define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif #endif
#ifndef IO_REPARSE_TAG_MOUNT_POINT
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
#endif
#include "osdefs.h" #include "osdefs.h"
#include <malloc.h> #include <malloc.h>
#include <windows.h> #include <windows.h>
@ -1114,6 +1109,41 @@ _PyVerify_fd_dup2(int fd1, int fd2)
#endif #endif
#ifdef MS_WINDOWS #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 static int
win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) 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); find_data_handle = FindFirstFileW(lpFileName, &find_data);
if(find_data_handle != INVALID_HANDLE_VALUE) { if(find_data_handle != INVALID_HANDLE_VALUE) {
/* IO_REPARSE_TAG_SYMLINK if it is a symlink and is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
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;
FindClose(find_data_handle); FindClose(find_data_handle);
} }
} }

View File

@ -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 */