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