#/*- * Copyright 2006-2007 Guram Dukashvili * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ //--------------------------------------------------------------------------- #include /*#if HAVE_NTDLL_H #include #else #include #endif*/ //--------------------------------------------------------------------------- namespace ksys { //--------------------------------------------------------------------------- #if defined(__WIN32__) || defined(__WIN64__) //--------------------------------------------------------------------------- #define NT_SUCCESS(Status) ((LONG)(Status) >= 0) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) static inline PVOID getInfoTable(IN ULONG ATableType,HANDLE hHeap) { ULONG mSize = 0x8000; PVOID mPtr; NTSTATUS status; do { mPtr = HeapAlloc(hHeap, 0, mSize); if( mPtr == NULL ) return NULL; memset(mPtr, 0, mSize); status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) ATableType, mPtr, mSize, NULL); if( status == STATUS_INFO_LENGTH_MISMATCH ){ HeapFree(hHeap,0,mPtr); mSize = mSize * 2; } } while( status == STATUS_INFO_LENGTH_MISMATCH ); if( NT_SUCCESS(status) ) return mPtr; HeapFree(hHeap, 0, mPtr); return NULL; } //--------------------------------------------------------------------------- #pragma warning(disable : 4200) typedef VOID *POBJECT; typedef struct _SYSTEM_HANDLE { ULONG uIdProcess; UCHAR ObjectType; // OB_TYPE_* (OB_TYPE_TYPE, etc.) UCHAR Flags; // HANDLE_FLAG_* (HANDLE_FLAG_INHERIT, etc.) USHORT Handle; POBJECT pObject; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE, *PSYSTEM_HANDLE; //--------------------------------------------------------------------------- typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG uCount; SYSTEM_HANDLE aSH[]; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; //--------------------------------------------------------------------------- typedef enum _SYSTEMINFOCLASS { SystemBasicInformation, // 0x002C SystemProcessorInformation, // 0x000C SystemPerformanceInformation, // 0x0138 SystemTimeInformation, // 0x0020 SystemPathInformation, // not implemented SystemProcessInformation, // 0x00C8+ per process SystemCallInformation, // 0x0018 + (n * 0x0004) SystemConfigurationInformation, // 0x0018 SystemProcessorCounters, // 0x0030 per cpu SystemGlobalFlag, // 0x0004 (fails if size != 4) SystemCallTimeInformation, // not implemented SystemModuleInformation, // 0x0004 + (n * 0x011C) SystemLockInformation, // 0x0004 + (n * 0x0024) SystemStackTraceInformation, // not implemented SystemPagedPoolInformation, // checked build only SystemNonPagedPoolInformation, // checked build only SystemHandleInformation, // 0x0004 + (n * 0x0010) SystemObjectTypeInformation, // 0x0038+ + (n * 0x0030+) SystemPageFileInformation, // 0x0018+ per page file SystemVdmInstemulInformation, // 0x0088 SystemVdmBopInformation, // invalid info class SystemCacheInformation, // 0x0024 SystemPoolTagInformation, // 0x0004 + (n * 0x001C) SystemInterruptInformation, // 0x0000, or 0x0018 per cpu SystemDpcInformation, // 0x0014 SystemFullMemoryInformation, // checked build only SystemLoadDriver, // 0x0018, set mode only SystemUnloadDriver, // 0x0004, set mode only SystemTimeAdjustmentInformation, // 0x000C, 0x0008 writeable SystemSummaryMemoryInformation, // checked build only SystemNextEventIdInformation, // checked build only SystemEventIdsInformation, // checked build only SystemCrashDumpInformation, // 0x0004 SystemExceptionInformation, // 0x0010 SystemCrashDumpStateInformation, // 0x0004 SystemDebuggerInformation, // 0x0002 SystemContextSwitchInformation, // 0x0030 SystemRegistryQuotaInformation, // 0x000C SystemAddDriver, // 0x0008, set mode only SystemPrioritySeparationInformation,// 0x0004, set mode only SystemPlugPlayBusInformation, // not implemented SystemDockInformation, // not implemented SystemPowerInfo, // 0x0060 (XP only!) SystemProcessorSpeedInformation, // 0x000C (XP only!) SystemTimeZoneInformation, // 0x00AC SystemLookasideInformation, // n * 0x0020 SystemSetTimeSlipEvent, SystemCreateSession, // set mode only SystemDeleteSession, // set mode only SystemInvalidInfoClass1, // invalid info class SystemRangeStartInformation, // 0x0004 (fails if size != 4) SystemVerifierInformation, SystemAddVerifier, SystemSessionProcessesInformation, // checked build only MaxSystemInfoClass } SYSTEMINFOCLASS, *PSYSTEMINFOCLASS; //--------------------------------------------------------------------------- static inline UCHAR getFileHandleType(HANDLE hHeap) { HANDLE hFile; PSYSTEM_HANDLE_INFORMATION Info; ULONG r; UCHAR Result = 0; hFile = CreateFile("NUL", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); if( hFile != INVALID_HANDLE_VALUE ){ Info = (PSYSTEM_HANDLE_INFORMATION) getInfoTable(SystemHandleInformation,hHeap); if( Info ){ for( r = 0; r < Info->uCount; r++ ){ if( Info->aSH[r].Handle == (USHORT) hFile && Info->aSH[r].uIdProcess == GetCurrentProcessId()){ Result = Info->aSH[r].ObjectType; break; } } HeapFree(hHeap, 0, Info); } CloseHandle(hFile); } return Result; } //--------------------------------------------------------------------------- typedef struct _FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[1]; } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; //--------------------------------------------------------------------------- typedef struct _NM_INFO { HANDLE hFile; FILE_NAME_INFORMATION Info; WCHAR Name[MAX_PATH]; } NM_INFO, *PNM_INFO; //--------------------------------------------------------------------------- typedef enum _FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, FileFullDirectoryInformation, // 2 FileBothDirectoryInformation, // 3 FileBasicInformation, // 4 FileStandardInformation, // 5 FileInternalInformation, // 6 FileEaInformation, // 7 FileAccessInformation, // 8 FileNameInformation, // 9 FileRenameInformation, // 10 FileLinkInformation, // 11 FileNamesInformation, // 12 FileDispositionInformation, // 13 FilePositionInformation, // 14 FileFullEaInformation, // 15 FileModeInformation, // 16 FileAlignmentInformation, // 17 FileAllInformation, // 18 FileAllocationInformation, // 19 FileEndOfFileInformation, // 20 FileAlternateNameInformation, // 21 FileStreamInformation, // 22 FilePipeInformation, // 23 FilePipeLocalInformation, // 24 FilePipeRemoteInformation, // 25 FileMailslotQueryInformation, // 26 FileMailslotSetInformation, // 27 FileCompressionInformation, // 28 FileObjectIdInformation, // 29 FileCompletionInformation, // 30 FileMoveClusterInformation, // 31 FileInformationReserved32, // 32 FileInformationReserved33, // 33 FileNetworkOpenInformation, // 34 FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; //--------------------------------------------------------------------------- typedef NTSYSAPI NTSTATUS (NTAPI * NtQueryInformationFile)( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass ); static DWORD WINAPI getFileNameThread(PVOID lpParameter) { PNM_INFO NmInfo = (PNM_INFO) lpParameter; IO_STATUS_BLOCK IoStatus; NtQueryInformationFile q = (NtQueryInformationFile) GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQueryInformationFile"); q(NmInfo->hFile, &IoStatus, &NmInfo->Info, sizeof(NM_INFO) - sizeof(HANDLE), FileNameInformation); return 0; } //--------------------------------------------------------------------------- utf8::String getFileNameByHandle(HANDLE hFile) { HANDLE hHeap = GetProcessHeap(); PNM_INFO Info = (PNM_INFO) HeapAlloc(hHeap, 0, sizeof(NM_INFO)); Info->hFile = hFile; HANDLE hThread = CreateThread(NULL, 0, getFileNameThread, Info, 0, NULL); if( WaitForSingleObject(hThread,INFINITE) == WAIT_TIMEOUT ) TerminateThread(hThread,0); CloseHandle(hThread); utf8::String name(Info->Info.FileName,Info->Info.FileNameLength >> 1); HeapFree(hHeap,0,Info); return name; } //--------------------------------------------------------------------------- /*void main() { PSYSTEM_HANDLE_INFORMATION Info; ULONG r; CHAR Name[MAX_PATH]; HANDLE hProcess, hFile; UCHAR ObFileType; hHeap = GetProcessHeap(); ObFileType = GetFileHandleType(); Info = GetInfoTable(SystemHandleInformation); if (Info) { for (r = 0; r < Info->uCount; r++) { if (Info->aSH[r].ObjectType == ObFileType) { hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, Info->aSH[r].uIdProcess); if (hProcess) { if (DuplicateHandle(hProcess, (HANDLE)Info->aSH[r].Handle, GetCurrentProcess(), &hFile, 0, FALSE, DUPLICATE_SAME_ACCESS)) { GetFileName(hFile, Name); printf("%s\n", Name); CloseHandle(hFile); } CloseHandle(hProcess); } } } HeapFree(hHeap, 0, Info); } } */ //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- } //---------------------------------------------------------------------------