15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/tests/common/test_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winioctl.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _REPARSE_DATA_BUFFER {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ULONG  ReparseTag;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  USHORT  ReparseDataLength;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  USHORT  Reserved;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  union {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameOffset;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameLength;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameOffset;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameLength;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ULONG Flags;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WCHAR PathBuffer[1];
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } SymbolicLinkReparseBuffer;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameOffset;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT SubstituteNameLength;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameOffset;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      USHORT PrintNameLength;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WCHAR PathBuffer[1];
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } MountPointReparseBuffer;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UCHAR DataBuffer[1];
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } GenericReparseBuffer;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets a reparse point. |source| will now point to |target|. Returns true if
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the call succeeds, false otherwise.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetReparsePoint(HANDLE source, const wchar_t* target) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer[2000] = {0};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD returned;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->ReparseTag = 0xa0000003;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->MountPointReparseBuffer.SubstituteNameLength = size_target;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->MountPointReparseBuffer.PrintNameOffset = size_target + 2;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data->ReparseDataLength = size_target + 4 + 8;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data_size = data->ReparseDataLength + 8;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NULL, 0, &returned, NULL)) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delete the reparse point referenced by |source|. Returns true if the call
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// succeeds, false otherwise.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeleteReparsePoint(HANDLE source) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD returned;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  REPARSE_DATA_BUFFER data = {0};
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.ReparseTag = 0xa0000003;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       &returned, NULL)) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73