Home | History | Annotate | Download | only in common
      1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sandbox/win/tests/common/test_utils.h"
      6 
      7 #include <winioctl.h>
      8 
      9 typedef struct _REPARSE_DATA_BUFFER {
     10   ULONG  ReparseTag;
     11   USHORT  ReparseDataLength;
     12   USHORT  Reserved;
     13   union {
     14     struct {
     15       USHORT SubstituteNameOffset;
     16       USHORT SubstituteNameLength;
     17       USHORT PrintNameOffset;
     18       USHORT PrintNameLength;
     19       ULONG Flags;
     20       WCHAR PathBuffer[1];
     21       } SymbolicLinkReparseBuffer;
     22     struct {
     23       USHORT SubstituteNameOffset;
     24       USHORT SubstituteNameLength;
     25       USHORT PrintNameOffset;
     26       USHORT PrintNameLength;
     27       WCHAR PathBuffer[1];
     28       } MountPointReparseBuffer;
     29     struct {
     30       UCHAR DataBuffer[1];
     31     } GenericReparseBuffer;
     32   };
     33 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
     34 
     35 // Sets a reparse point. |source| will now point to |target|. Returns true if
     36 // the call succeeds, false otherwise.
     37 bool SetReparsePoint(HANDLE source, const wchar_t* target) {
     38   USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]);
     39 
     40   char buffer[2000] = {0};
     41   DWORD returned;
     42 
     43   REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer);
     44 
     45   data->ReparseTag = 0xa0000003;
     46   memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2);
     47   data->MountPointReparseBuffer.SubstituteNameLength = size_target;
     48   data->MountPointReparseBuffer.PrintNameOffset = size_target + 2;
     49   data->ReparseDataLength = size_target + 4 + 8;
     50 
     51   int data_size = data->ReparseDataLength + 8;
     52 
     53   if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size,
     54                        NULL, 0, &returned, NULL)) {
     55     return false;
     56   }
     57   return true;
     58 }
     59 
     60 // Delete the reparse point referenced by |source|. Returns true if the call
     61 // succeeds, false otherwise.
     62 bool DeleteReparsePoint(HANDLE source) {
     63   DWORD returned;
     64   REPARSE_DATA_BUFFER data = {0};
     65   data.ReparseTag = 0xa0000003;
     66   if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0,
     67                        &returned, NULL)) {
     68     return false;
     69   }
     70 
     71   return true;
     72 }
     73