В общем задача такова: Есть файл открытый каким-либо процессом в режиме эксклюзивного доступа. С помощью CreateFile не удается открыть его даже на чтение. Существует ли способ читать и писать в такой файл (по возможности не нарушая нормальной работы открывшей его программы).
Для решения этой задачи есть несколько методов: 1) Чтение файла через Shadow Copy Provider. Работает только на NTFS и только если включена соответствующая служба. 2) Чтение/запись файла путем поиска его хэндла в других процессах и копирования его себе. Запись возможна только если хэндл имеет соответствующие права доступа и даже чтение оказывает влияние на программу открывшую этот файл. Пример поиска хэндлов открытых файлов приведен в атаче. 3) Открытие файла с флагом FILE_FLAG_BACKUP_SEMANTICS. Этот флаг позволяет открыть файл в любом случае, но прочитать можно только его атрибуты. После чего нужно вручную поправить таблицу хэндлов своего процесса и разрешить чтение/запись через полученый хэндл. Чтение файла при этом не нарушает работу открывшей его программы, а вот запись может нарушить что угодно Для реализации этого метода нужен драйвер. Для начала нам потребуется найти таблицу хэндлов процесса, указатель на нее есть в структуре EPROCESS по смещению 0x128 в Windows 2000 и 0xC4 в Windows XP. Затем нужно найти элемент таблицы соответствующий нужному хэндлу. Структура таблиц хэндлов у Win XP и Win 2k разная, поэтому для поиска придется использовать разный код: Код (Text): PHANDLE_TABLE_ENTRY Win2kLookupHandleTableEntry( IN PWIN2K_HANDLE_TABLE HandleTable, IN EXHANDLE Handle ) { ULONG i, j, k; i = (Handle.Index >> 16) & 255; j = (Handle.Index >> 8) & 255; k = (Handle.Index) & 255; if (HandleTable->Table[i]) { if (HandleTable->Table[i][j]) { return &(HandleTable->Table[i][j][k]); } } return NULL; } Код (Text): PHANDLE_TABLE_ENTRY XpLookupHandleTableEntry( IN PXP_HANDLE_TABLE HandleTable, IN EXHANDLE Handle ) { ULONG i, j, k; PHANDLE_TABLE_ENTRY Entry = NULL; ULONG TableCode = HandleTable->TableCode & ~TABLE_LEVEL_MASK; i = (Handle.Index >> 17) & 0x1FF; j = (Handle.Index >> 9) & 0x1FF; k = (Handle.Index) & 0x1FF; switch (HandleTable->TableCode & TABLE_LEVEL_MASK) { case 0 : Entry = &((PHANDLE_TABLE_ENTRY)TableCode)[k]; break; case 1 : if (((PVOID *)TableCode)[j]) { Entry = &((PHANDLE_TABLE_ENTRY *)TableCode)[j][k]; } break; case 2 : if (((PVOID *)TableCode)[i]) if (((PVOID **)TableCode)[i][j]) { Entry = &((PHANDLE_TABLE_ENTRY **)TableCode)[i][j][k]; } break; } return Entry; } Сами структуры таблицы хэндлов для Windows 2000 и XP: Код (Text): typedef struct _XP_HANDLE_TABLE { ULONG TableCode; PEPROCESS QuotaProcess; PVOID UniqueProcessId; EX_PUSH_LOCK HandleTableLock[4]; LIST_ENTRY HandleTableList; EX_PUSH_LOCK HandleContentionEvent; PHANDLE_TRACE_DEBUG_INFO DebugInfo; LONG ExtraInfoPages; ULONG FirstFree; ULONG LastFree; ULONG NextHandleNeedingPool; LONG HandleCount; LONG Flags; UCHAR StrictFIFO; } XP_HANDLE_TABLE, *PXP_HANDLE_TABLE; Код (Text): typedef struct _WIN2K_HANDLE_TABLE { ULONG Flags; LONG HandleCount; PHANDLE_TABLE_ENTRY **Table; PEPROCESS QuotaProcess; HANDLE UniqueProcessId; LONG FirstFreeTableEntry; LONG NextIndexNeedingPool; ERESOURCE HandleTableLock; LIST_ENTRY HandleTableList; KEVENT HandleContentionEvent; } WIN2K_HANDLE_TABLE , *PWIN2K_HANDLE_TABLE ; Структура элемента таблицы хэндлов: Код (Text): typedef struct _HANDLE_TABLE_ENTRY { union { PVOID Object; ULONG ObAttributes; PHANDLE_TABLE_ENTRY_INFO InfoTable; ULONG Value; }; union { union { ACCESS_MASK GrantedAccess; struct { USHORT GrantedAccessIndex; USHORT CreatorBackTraceIndex; }; }; LONG NextFreeTableEntry; }; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; После нахождения элемента нужно поправить в нем поле GrantedAccess, которое определяет права доступа данного хэндла. Посмотреть примеры работы с таблицей хэндлов можно в исходниках моей программы Process Hunter, все нужные хедеры - на моем сайте. 1318100116__FCopy.rar
4) работать с файлом через собственный драйвер (на самом деле обычная юзер-моде прога) файловой системы. единственно нужны вроде админские права на открытие \\.\PhysicalDrive? я помнится показывал на бугтраке копирование sam-а с живой машины еще лет пять назад...