1// Copyright (c) 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#ifndef SANDBOX_SANDBOX_POC_POCDLL_UTILS_H__
6#define SANDBOX_SANDBOX_POC_POCDLL_UTILS_H__
7
8#include <stdio.h>
9#include <io.h>
10#include "base/basictypes.h"
11
12// Class to convert a HANDLE to a FILE *. The FILE * is closed when the
13// object goes out of scope
14class HandleToFile {
15 public:
16  HandleToFile() {
17    file_ = NULL;
18  };
19
20  // Note: c_file_handle_ does not need to be closed because fclose does it.
21  ~HandleToFile() {
22    if (file_) {
23      fflush(file_);
24      fclose(file_);
25    }
26  };
27
28  // Translates a HANDLE (handle) to a FILE * opened with the mode "mode".
29  // The return value is the FILE * or NULL if there is an error.
30  FILE* Translate(HANDLE handle, const char *mode) {
31    if (file_) {
32      return  NULL;
33    }
34
35    HANDLE new_handle;
36    BOOL result = ::DuplicateHandle(::GetCurrentProcess(),
37                                    handle,
38                                    ::GetCurrentProcess(),
39                                    &new_handle,
40                                    0,  // Don't ask for a specific
41                                        // desired access.
42                                    FALSE,  // Not inheritable.
43                                    DUPLICATE_SAME_ACCESS);
44
45    if (!result) {
46      return NULL;
47    }
48
49    int c_file_handle = _open_osfhandle(reinterpret_cast<LONG_PTR>(new_handle),
50                                        0);  // No flags
51    if (-1 == c_file_handle) {
52      return NULL;
53    }
54
55    file_ = _fdopen(c_file_handle, mode);
56    return file_;
57  };
58 private:
59  // the FILE* returned. We need to closed it at the end.
60  FILE* file_;
61
62  DISALLOW_COPY_AND_ASSIGN(HandleToFile);
63};
64
65#endif  // SANDBOX_SANDBOX_POC_POCDLL_UTILS_H__
66