Coverage for /Syzygy/snapshot/run_in_snapshot.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00129.C++source

Line-by-line coverage:

   1    :  // Copyright 2011 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // A command line utility that'll create snapshot of a given volume, and map it
  16    :  // to a drive letter, then run a command while the snapshot is mounted. This
  17    :  // is handy to simulate cold-start conditions, as a newly created and mounted
  18    :  // snapshot will be as cold as cold gets.
  19    :  
  20    :  #include <atlbase.h>
  21    :  #include <vss.h>
  22    :  #include <vswriter.h>
  23    :  #include <vsbackup.h>  // NOLINT: This has to be after vss.h and vswriter.h.
  24    :  #include <iostream>
  25    :  
  26    :  #include "base/at_exit.h"
  27    :  #include "base/command_line.h"
  28    :  #include "base/logging.h"
  29    :  #include "base/process/launch.h"
  30    :  #include "base/strings/utf_string_conversions.h"
  31    :  
  32  m :  const char kHelp[] =
  33  m :    "Available options:\n"
  34  m :    "  --volume=<volume> the volume to mount, e.g. C:\\\n"
  35  m :    "  --snapshot=<drive letter> the drive letter to mount the snapshot on, "
  36  m :        "e.g. M:\n"
  37  m :    "\n"
  38  m :    "Example:\n"
  39  m :    "   run_in_snapshot --volume=C:\\ --snapshot=M: -- cmd.exe /c echo no way\n";
  40    :  
  41    :  
  42  m :  int Usage() {
  43  m :    base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
  44    :  
  45  m :    std::cout << "Usage: " << cmd_line->GetProgram().BaseName().value().c_str()
  46  m :              << " [options] -- [command and argument]\n" << std::endl;
  47  m :    std::cout << kHelp;
  48    :  
  49  m :    return 1;
  50  m :  }
  51    :  
  52  m :  int main(int argc, char** argv) {
  53  m :    base::AtExitManager at_exit;
  54  m :    base::CommandLine::Init(argc, argv);
  55    :  
  56  m :    base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
  57    :  
  58  m :    std::wstring volume = cmd_line->GetSwitchValueNative("volume");
  59  m :    std::wstring snapshot = cmd_line->GetSwitchValueNative("snapshot");
  60  m :    base::CommandLine::StringVector args = cmd_line->GetArgs();
  61  m :    if (volume.empty() || snapshot.empty() || args.size() == 0) {
  62  m :      return Usage();
  63  m :    }
  64    :  
  65    :    // Initialize COM and open ourselves wide for callbacks by
  66    :    // CoInitializeSecurity.
  67  m :    HRESULT hr = ::CoInitialize(NULL);
  68  m :    if (SUCCEEDED(hr)) {
  69  m :      hr = ::CoInitializeSecurity(
  70  m :          NULL,  //  Allow *all* VSS writers to communicate back!
  71  m :          -1,  //  Default COM authentication service
  72  m :          NULL,  //  Default COM authorization service
  73  m :          NULL,  //  reserved parameter
  74  m :          RPC_C_AUTHN_LEVEL_PKT_PRIVACY,  //  Strongest COM authentication level
  75  m :          RPC_C_IMP_LEVEL_IDENTIFY,  //  Minimal impersonation abilities
  76  m :          NULL,  //  Default COM authentication settings
  77  m :          EOAC_NONE,  //  No special options
  78  m :          NULL);  //  Reserved parameter
  79  m :    }
  80    :  
  81  m :    DCHECK(SUCCEEDED(hr));
  82  m :    if (FAILED(hr)) {
  83  m :      LOG(ERROR) << "Failed to initialize COM";
  84  m :      return 1;
  85  m :    }
  86    :  
  87  m :    CComPtr<IVssBackupComponents> comp;
  88  m :    hr = ::CreateVssBackupComponents(&comp);
  89  m :    if (SUCCEEDED(hr))
  90  m :      hr = comp->InitializeForBackup(NULL);
  91  m :    if (SUCCEEDED(hr))
  92  m :      hr = comp->SetBackupState(true, true, VSS_BT_COPY, false);
  93    :  
  94  m :    DCHECK(SUCCEEDED(hr));
  95  m :    if (FAILED(hr)) {
  96  m :      LOG(ERROR) << "Failed to initialize snapshot, error " << hr;
  97  m :      return 1;
  98  m :    }
  99    :  
 100  m :    CComPtr<IVssAsync> async;
 101  m :    hr = comp->GatherWriterMetadata(&async);
 102  m :    if (SUCCEEDED(hr))
 103  m :      hr = async->Wait();
 104  m :    if (FAILED(hr)) {
 105  m :      LOG(ERROR) << "Failed to gather write data, error " << hr;
 106  m :      return 1;
 107  m :    }
 108    :  
 109  m :    VSS_ID id = {};
 110  m :    hr = comp->StartSnapshotSet(&id);
 111    :  
 112  m :    VSS_ID dummy = {};
 113  m :    if (SUCCEEDED(hr)) {
 114  m :      hr = comp->AddToSnapshotSet(const_cast<LPWSTR>(volume.c_str()),
 115  m :                                  GUID_NULL,
 116  m :                                  &dummy);
 117  m :    }
 118    :  
 119  m :    if (FAILED(hr)) {
 120  m :      LOG(ERROR) << "Failed to start snapshot, error " << hr;
 121  m :      return 1;
 122  m :    }
 123    :  
 124  m :    async.Release();
 125  m :    hr = comp->PrepareForBackup(&async);
 126  m :    if (SUCCEEDED(hr))
 127  m :      hr = async->Wait();
 128    :  
 129  m :    if (FAILED(hr)) {
 130  m :      LOG(ERROR) << "Failed to prepare for backup, error " << hr;
 131  m :      return 1;
 132  m :    }
 133    :  
 134  m :    async.Release();
 135  m :    hr = comp->DoSnapshotSet(&async);
 136  m :    if (SUCCEEDED(hr))
 137  m :      hr = async->Wait();
 138    :  
 139  m :    if (FAILED(hr)) {
 140  m :      LOG(ERROR) << "Failed to do snapshot, error " << hr;
 141  m :      return 1;
 142  m :    }
 143    :  
 144  m :    CComPtr<IVssEnumObject> enum_snapshots;
 145  m :    hr = comp->Query(GUID_NULL,
 146  m :                     VSS_OBJECT_NONE,
 147  m :                     VSS_OBJECT_SNAPSHOT,
 148  m :                     &enum_snapshots);
 149  m :    if (FAILED(hr)) {
 150  m :      LOG(ERROR) << "Failed to query snapshot, error " << hr;
 151  m :      return 1;
 152  m :    }
 153    :  
 154  m :    VSS_OBJECT_PROP prop;
 155  m :    ULONG fetched = 0;
 156  m :    hr = enum_snapshots->Next(1, &prop, &fetched);
 157  m :    if (FAILED(hr) || hr == S_FALSE) {
 158  m :      LOG(ERROR) << "Failed to retrieve snapshot volume, error " << hr;
 159  m :      return 1;
 160  m :    }
 161    :  
 162    :    // Bind the snapshot to a drive letter.
 163  m :    BOOL defined = ::DefineDosDevice(0,
 164  m :                                     snapshot.c_str(),
 165  m :                                     prop.Obj.Snap.m_pwszSnapshotDeviceObject);
 166  m :    if (!defined) {
 167  m :      LOG(ERROR) << "Failed to assign a drive letter to snapshot";
 168  m :      return 1;
 169  m :    }
 170  m :    ::VssFreeSnapshotProperties(&prop.Obj.Snap);
 171    :  
 172  m :    base::FilePath cmd_path(args[0]);
 173  m :    base::CommandLine cmd(cmd_path);
 174  m :    for (size_t i = 1; i < args.size(); ++i)
 175  m :      cmd.AppendArgNative(args[i]);
 176    :  
 177  m :    int ret = 0;
 178    :    // Launch the command line we were given, and wait on it to complete.
 179  m :    base::LaunchOptions options;
 180  m :    options.wait = true;
 181  m :    base::Process process = base::LaunchProcess(cmd, options);
 182  m :    if (!process.IsValid()) {
 183  m :      LOG(ERROR) << "Unable to launch application";
 184  m :      ret = 1;
 185  m :    }
 186    :  
 187    :    // Remove the drive mapping.
 188  m :    ::DefineDosDevice(DDD_REMOVE_DEFINITION, snapshot.c_str(), NULL);
 189    :  
 190  m :    return ret;
 191  m :  }

Coverage information generated Thu Jan 14 17:40:38 2016.