2011-09-20 27 views
6

He escrito un programa que consulta los registros de diario de cambios y los enumera. El diario de cambios regresa:Necesito ayuda para usar NtCreateFile() para abrir por fileIndex

1) filereferencenumber (combinación de fileindex.high y fileindex.low) 2) parentfilereferencenumber (igual que el anterior, excepto que es para el directorio) 3) szReason (razón por la que aparece en el registro de cambio) 4) Nombre de archivo y longitud de archivo.

Quiero encontrar la ruta de este archivo enumerada en el diario de cambios. La mayoría de las implementaciones que he visto hacen un seguimiento de todo el número de referencia de archivo y lo consultan para comparar, o usan las funciones FindNextFile() para recorrer todo el volumen.

Me encontré con una discusión en la que dicen que pueden abrir un identificador de archivo utilizando solo el número de referencia del archivo. http://www.tech-archive.net/Archive/Windows/microsoft.public.windows.file_system/2004-11/0244.html

el artículo de MSDN dice, tenemos que cargar una biblioteca antes de llamar a la API interna http://msdn.microsoft.com/en-us/library/bb432380%28v=vs.85%29.aspx

Alguien me puede apuntar en la dirección correcta y dime exactamente qué hacer? ¿Cómo uso NtCreateFile()?

O, ¿hay alguna manera de acceder a la ruta del archivo utilizando solo el número de referencia del archivo?

+1

Esa no es exactamente la forma en que se supone que StackOverflow funciona. Las preguntas permanecen para que las personas futuras puedan encontrar la respuesta. –

+0

Lo siento @ Lyn Lynx, estaba un poco desesperado, y publiqué la pregunta. Y, como les debo una respuesta a todos, también la publiqué a continuación. – roymustang86

Respuesta

5

Aquí está el código que utilicé: http://www.ragestorm.net/blogs/?cat=7

#include windows.h 
typedef ULONG (__stdcall *pNtCreateFile)(
    PHANDLE FileHandle, 
    ULONG DesiredAccess, 
    PVOID ObjectAttributes, 
    PVOID IoStatusBlock, 
    PLARGE_INTEGER AllocationSize, 
    ULONG FileAttributes, 
    ULONG ShareAccess, 
    ULONG CreateDisposition, 
    ULONG CreateOptions, 
    PVOID EaBuffer, 
    ULONG EaLength 
); 

typedef ULONG (__stdcall *pNtReadFile)(
    IN HANDLE FileHandle, 
    IN HANDLE Event OPTIONAL, 
    IN PVOID ApcRoutine OPTIONAL, 
    IN PVOID ApcContext OPTIONAL, 
    OUT PVOID IoStatusBlock, 
    OUT PVOID Buffer, 
    IN ULONG Length, 
    IN PLARGE_INTEGER ByteOffset OPTIONAL, 
    IN PULONG Key OPTIONAL ); 

typedef struct _UNICODE_STRING { 
    USHORT Length, MaximumLength; 
    PWCH Buffer; 
} UNICODE_STRING, *PUNICODE_STRING; 

typedef struct _OBJECT_ATTRIBUTES { 
ULONG Length; 
HANDLE RootDirectory; 
PUNICODE_STRING ObjectName; 
ULONG Attributes; 
PVOID SecurityDescriptor;  // Points to type SECURITY_DESCRIPTOR 
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE 
} OBJECT_ATTRIBUTES; 

#define InitializeObjectAttributes(p, n, a, r, s) { \ 
(p)->Length = sizeof(OBJECT_ATTRIBUTES);   \ 
(p)->RootDirectory = r;        \ 
(p)->Attributes = a;        \ 
(p)->ObjectName = n;        \ 
(p)->SecurityDescriptor = s;      \ 
(p)->SecurityQualityOfService = NULL;    \ 
} 

#define OBJ_CASE_INSENSITIVE 0x00000040L 
#define FILE_NON_DIRECTORY_FILE 0×00000040 
#define FILE_OPEN_BY_FILE_ID 0×00002000 
#define FILE_OPEN 0×00000001 

int main(int argc, char* argv[]) 
{ 
    HANDLE d = CreateFile(L"\\\\.\\c:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 ); 
    BY_HANDLE_FILE_INFORMATION i; 
    HANDLE f = CreateFile(L"c:\\bla.bla", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    ULONG bla; 
    WriteFile(f, "helloworld", 11, &bla, NULL); 
    printf("%x, %d\n", f, GetLastError()); 
    GetFileInformationByHandle(f, &i); 
    printf("id:%08x-%08x\n", i.nFileIndexHigh, i.nFileIndexLow); 
    CloseHandle(f); 

    pNtCreateFile NtCreatefile = (pNtCreateFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateFile"); 
    pNtReadFile NtReadFile = (pNtReadFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtReadFile"); 

    ULONG fid[2] = {i.nFileIndexLow, i.nFileIndexHigh}; 
    UNICODE_STRING fidstr = {8, 8, (PWSTR) fid}; 

    OBJECT_ATTRIBUTES oa = {0}; 
    InitializeObjectAttributes (&oa, &fidstr, OBJ_CASE_INSENSITIVE, d, NULL); 

    ULONG iosb[2]; 
    ULONG status = NtCreatefile(&f, GENERIC_ALL, &oa, iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_OPEN_BY_FILE_ID | FILE_NON_DIRECTORY_FILE, NULL, 0); 
    printf("status: %X, handle: %x\n", status, f); 
    UCHAR buf[11] = {0}; 
    LONG Off[2] = {0}; 
    status = NtReadFile(f, NULL, NULL, NULL, (PVOID)&iosb, (PVOID)buf, sizeof(buf), (PLARGE_INTEGER)&Off, NULL); 
    printf("status: %X, bytes: %d\n", status, iosb[1]); 
    printf("buf: %s\n", buf); 
    CloseHandle(f); 
    CloseHandle(d); 
} 

Como se puede ver, una vez que dar la fileindex.high y fileindex.low parte de la filereferencenumber, le da un identificador para ese archivo. Y utilicé la función getFileMapping desde psapi, para obtener la ruta completa. Información para los curiosos: http://msdn.microsoft.com/en-us/library/aa366789.aspx

+1

Consejo profesional: 'ULONG iosb [2]' solo funciona para 32 bits. Si no va a utilizar un [IO_STATUS_BLOCK] real (https://msdn.microsoft.com/en-us/library/windows/hardware/ff550671), entonces quizás 'ULONG_PTR iosb [2];' sería mejor . –

Cuestiones relacionadas