| 1 | /* |
|---|
| 2 | * $Id$ |
|---|
| 3 | * Copyright 2008-2009 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 "Eraser.Util.Unlocker.h" |
|---|
| 24 | |
|---|
| 25 | #pragma managed(push) |
|---|
| 26 | #pragma unmanaged |
|---|
| 27 | |
|---|
| 28 | namespace { |
|---|
| 29 | DWORD __stdcall nameResolutionThread(void* data) |
|---|
| 30 | { |
|---|
| 31 | //Get the thread parameters |
|---|
| 32 | NameResolutionThreadParams& param = *static_cast<NameResolutionThreadParams*>(data); |
|---|
| 33 | |
|---|
| 34 | //Get the list of logical drives |
|---|
| 35 | wchar_t drives[26 * 3]; |
|---|
| 36 | if (!GetLogicalDriveStrings(sizeof(drives) / sizeof(drives[0]), drives)) |
|---|
| 37 | return 1; |
|---|
| 38 | for (wchar_t* i = drives; *i; i += 4) |
|---|
| 39 | *(i + 2) = 0; |
|---|
| 40 | |
|---|
| 41 | //Get the file path |
|---|
| 42 | char name[4096]; |
|---|
| 43 | PUNICODE_STRING nameStr = reinterpret_cast<PUNICODE_STRING>(name); |
|---|
| 44 | |
|---|
| 45 | for ( ; ; ) |
|---|
| 46 | { |
|---|
| 47 | WaitForSingleObject(param.Semaphore, INFINITE); |
|---|
| 48 | std::list<NameResult*>::iterator i = param.Input.begin(); |
|---|
| 49 | |
|---|
| 50 | //If the iterator points to a NULL handle terminate us. |
|---|
| 51 | if (*i == NULL) |
|---|
| 52 | break; |
|---|
| 53 | |
|---|
| 54 | //Erase this entry from the queue |
|---|
| 55 | NameResult& result = **i; |
|---|
| 56 | param.Input.erase(i); |
|---|
| 57 | |
|---|
| 58 | //Query the name of the object |
|---|
| 59 | if (NtQueryObject(result.Handle, static_cast<OBJECT_INFORMATION_CLASS>(ObjectNameInformation), |
|---|
| 60 | name, sizeof(name), NULL) == STATUS_SUCCESS) |
|---|
| 61 | { |
|---|
| 62 | if (nameStr && nameStr->Length) |
|---|
| 63 | { |
|---|
| 64 | std::wstring& name = result.Name; |
|---|
| 65 | |
|---|
| 66 | //Resolve the file path into logical drives |
|---|
| 67 | wchar_t path[MAX_PATH]; |
|---|
| 68 | name.assign(nameStr->Buffer); |
|---|
| 69 | for (wchar_t* j = drives; *j; j += 4) |
|---|
| 70 | if (QueryDosDevice(j, path, MAX_PATH)) |
|---|
| 71 | { |
|---|
| 72 | size_t pathLen = wcslen(path); |
|---|
| 73 | if (name.substr(0, pathLen) == path) |
|---|
| 74 | { |
|---|
| 75 | name.replace(0, pathLen, j); |
|---|
| 76 | break; |
|---|
| 77 | } |
|---|
| 78 | } |
|---|
| 79 | } |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | //Tell the waiting thread that we're done |
|---|
| 83 | SetEvent(result.Event); |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | return 0; |
|---|
| 87 | } |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | #pragma managed(pop) |
|---|
| 91 | |
|---|
| 92 | void CreateNameThread(HANDLE& handle, NameResolutionThreadParams& params) |
|---|
| 93 | { |
|---|
| 94 | //If the handle is valid terminate the thread |
|---|
| 95 | if (handle) |
|---|
| 96 | { |
|---|
| 97 | TerminateThread(handle, 1); |
|---|
| 98 | CloseHandle(handle); |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | //Create the thread |
|---|
| 102 | handle = CreateThread(NULL, 0, nameResolutionThread, ¶ms, 0, NULL); |
|---|
| 103 | } |
|---|