source: trunk/eraser/Eraser.Util.Native/OpenHandle.cpp @ 2334

Revision 2334, 3.6 KB checked in by lowjoel, 3 years ago (diff)

Fixed compilo introduced in earlier revision.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2010 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22#include "stdafx.h"
23#include "OpenHandle.h"
24
25namespace Eraser {
26namespace Util {
27    IList<OpenHandle^>^ OpenHandle::Items::get()
28    {
29        List<OpenHandle^>^ handles = gcnew List<OpenHandle^>();
30
31        //Get the number of handles on the system then load up the complete list.
32        std::auto_ptr<SYSTEM_HANDLES> handlesList(new SYSTEM_HANDLES);
33        {
34            DWORD bufferSize = 0;
35            NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(SystemHandleInformation),
36                handlesList.get(), sizeof(SYSTEM_HANDLES), &bufferSize);
37
38            //Then get the whole list
39            handlesList.reset(reinterpret_cast<PSYSTEM_HANDLES>(new char[bufferSize]));
40            NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(SystemHandleInformation),
41                handlesList.get(), bufferSize, &bufferSize);
42
43            if (bufferSize == 0)
44                throw gcnew InvalidOperationException(S::_(L"The list of open system handles could not be retrieved."));
45        }
46
47        //Iterate over the handles
48        for (ULONG i = 0; i != handlesList->NumberOfHandles; ++i)
49        {
50            //Only consider files
51            SYSTEM_HANDLE_INFORMATION handleInfo = handlesList->Information[i];
52            if (handleInfo.ObjectTypeNumber != 25 && handleInfo.ObjectTypeNumber != 23 &&
53                handleInfo.ObjectTypeNumber != 28)
54            {
55                continue;
56            }
57
58            //Try to resolve the path of the handle, continue if we can't get it
59            String^ handlePath = ResolveHandlePath(IntPtr(handleInfo.Handle),
60                handleInfo.ProcessId);
61            if (String::IsNullOrEmpty(handlePath))
62                continue;
63
64            //Store the entry
65            OpenHandle^ listItem = gcnew OpenHandle(IntPtr(handleInfo.Handle),
66                handleInfo.ProcessId, handlePath);
67            handles->Add(listItem);
68        }
69
70        return handles->AsReadOnly();
71    }
72
73    List<OpenHandle^>^ OpenHandle::Close(String^ path)
74    {
75        List<OpenHandle^>^ result = gcnew List<OpenHandle^>();
76        for each (OpenHandle^ handle in Items)
77        {
78            if (handle->Path == path)
79                if (!handle->Close())
80                    result->Add(handle);
81        }
82       
83        return result;
84    }
85
86    String^ OpenHandle::ResolveHandlePath(IntPtr handle, int pid)
87    {
88        std::wstring result(ResolveHandleName(static_cast<void*>(handle), pid));
89        return result.empty() ? nullptr :
90            gcnew String(result.c_str(), 0, static_cast<int>(result.length()));
91    }
92
93    bool OpenHandle::Close()
94    {
95        //Open a handle to the owning process
96        HANDLE processHandle = OpenProcess(PROCESS_DUP_HANDLE, false, processId);
97
98        //Forcibly close the handle
99        HANDLE duplicateHandle = NULL;
100        DuplicateHandle(processHandle, static_cast<void*>(Handle), GetCurrentProcess(),
101            &duplicateHandle, 0, false, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
102        CloseHandle(duplicateHandle);
103
104        //Check if the handle is closed
105        bool result = true;
106        if (DuplicateHandle(processHandle, static_cast<void*>(Handle), GetCurrentProcess(),
107            &duplicateHandle, 0, false, DUPLICATE_SAME_ACCESS))
108        {
109            result = false;
110            CloseHandle(duplicateHandle);
111        }
112
113        //Close the process handle
114        CloseHandle(processHandle);
115
116        //Return the result
117        return result;
118    }
119}
120}
Note: See TracBrowser for help on using the repository browser.