Code:
#include <windows.h>
#include <stdio.h>
typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
typedef DWORD ULONG_PTR;
#define STATUS_SUCCESS (NTSTATUS)0x00000000L
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define FILE_OPEN 0x00000001
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define FILE_DIRECTORY_FILE 0x00000001
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->uLength = sizeof( OBJECT_ATTRIBUTES ); \
(p)->hRootDirectory = r; \
(p)->uAttributes = a; \
(p)->pObjectName = n; \
(p)->pSecurityDescriptor = s; \
(p)->pSecurityQualityOfService = NULL; \
}
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
typedef USHORT RTL_STRING_LENGTH_TYPE;
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING;
typedef STRING *PSTRING;
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG uLength;
HANDLE hRootDirectory;
PUNICODE_STRING pObjectName;
ULONG uAttributes;
PVOID pSecurityDescriptor;
PVOID pSecurityQualityOfService;
} OBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->uLength = sizeof( OBJECT_ATTRIBUTES ); \
(p)->hRootDirectory = r; \
(p)->uAttributes = a; \
(p)->pObjectName = n; \
(p)->pSecurityDescriptor = s; \
(p)->pSecurityQualityOfService = NULL; \
}
typedef OBJECT_ATTRIBUTES * POBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef VOID (NTAPI *PIO_APC_ROUTINE) (IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved);
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileObjectIdInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileQuotaInformation,
FileReparsePointInformation,
FileNetworkOpenInformation,
FileAttributeTagInformation,
FileTrackingInformation,
FileIdBothDirectoryInformation,
FileIdFullDirectoryInformation,
FileValidDataLengthInformation,
FileShortNameInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef enum _EVENT_TYPE {NotificationEvent, SynchronizationEvent} EVENT_TYPE;
typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
NTSTATUS (WINAPI * pRtlInitUnicodeString)(PUNICODE_STRING, PCWSTR);
NTSTATUS (WINAPI * pZwCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
NTSTATUS (WINAPI * pZwCreateEvent)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN);
NTSTATUS (WINAPI * pZwQuerydirectoryFile)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN);
NTSTATUS (WINAPI * pZwWaitForSingleobject)(HANDLE, BOOLEAN, PLARGE_INTEGER);
NTSTATUS (WINAPI * pRtlUnicodeStringToAnsiString)(PANSI_STRING, PCUNICODE_STRING, BOOLEAN);
NTSTATUS (WINAPI * pZwClose)(HANDLE);
void IntializeNativeFunctions(VOID)
{
HMODULE hModule = LoadLibrary ("Ntdll.dll");
pRtlInitUnicodeString = (NTSTATUS (WINAPI *)(PUNICODE_STRING, PCWSTR)) GetProcAddress (hModule, "RtlInitUnicodeString");
pZwCreateFile = (NTSTATUS (WINAPI *)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG)) GetProcAddress (hModule, "ZwCreateFile");
pZwCreateEvent = (NTSTATUS (WINAPI *)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN)) GetProcAddress (hModule, "ZwCreateEvent");
pZwQuerydirectoryFile = (NTSTATUS (WINAPI *)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN, PUNICODE_STRING, BOOLEAN)) GetProcAddress (hModule, "ZwQueryDirectoryFile");
pZwWaitForSingleobject = (NTSTATUS (WINAPI *)(HANDLE, BOOLEAN, PLARGE_INTEGER)) GetProcAddress (hModule, "ZwWaitForSingleObject");
pRtlUnicodeStringToAnsiString = (NTSTATUS (WINAPI *)(PANSI_STRING, PCUNICODE_STRING, BOOLEAN)) GetProcAddress (hModule, "RtlUnicodeStringToAnsiString");
pZwClose = (NTSTATUS (WINAPI *)(HANDLE)) GetProcAddress (hModule, "ZwClose");
}
NTSTATUS ListDirectory(WCHAR * pszDirectoryName)
{
UNICODE_STRING RootDirectoryName;
ANSI_STRING as;
OBJECT_ATTRIBUTES RootDirectoryAttributes;
NTSTATUS ntStatus = STATUS_SUCCESS;
HANDLE RootDirectoryHandle;
IO_STATUS_BLOCK Iosb;
HANDLE Event;
PUCHAR Buffer[65536];
WCHAR wszBuffer[50];
PFILE_BOTH_DIR_INFORMATION DirInformation;
if(pRtlInitUnicodeString == NULL) return -1;
if(pRtlUnicodeStringToAnsiString == NULL) return -1;
_snwprintf(wszBuffer,sizeof(wszBuffer),L"\\??\\%s\\",pszDirectoryName);
ntStatus = ((pRtlInitUnicodeString)(&RootDirectoryName, wszBuffer));
if (!NT_SUCCESS(ntStatus))
return ntStatus;
InitializeObjectAttributes (&RootDirectoryAttributes, &RootDirectoryName, OBJ_CASE_INSENSITIVE, 0, 0);
if(pZwCreateFile == NULL) return -1;
ntStatus =((pZwCreateFile)(&RootDirectoryHandle,
GENERIC_READ,
&RootDirectoryAttributes,
&Iosb,
0,
FILE_ATTRIBUTE_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_DIRECTORY_FILE,
0, 0));
if (!NT_SUCCESS(ntStatus))
{
printf("Unable to open %s, error = 0x%x\n", &RootDirectoryName, ntStatus);
return ntStatus;
}
if(pZwCreateEvent == NULL) return -1;
ntStatus = ((pZwCreateEvent)(&Event, GENERIC_ALL, 0, NotificationEvent, FALSE));
if (!NT_SUCCESS(ntStatus))
{
printf("Event creation failed with error 0x%x\n", ntStatus);
return ntStatus;
}
if(pZwQuerydirectoryFile == NULL) return -1;
if(((pZwQuerydirectoryFile)(RootDirectoryHandle,
Event, 0, 0,
&Iosb,
Buffer,
sizeof(Buffer),
FileBothDirectoryInformation,
FALSE,
NULL,
FALSE)) == STATUS_PENDING)
{
if(pZwWaitForSingleobject == NULL) return -1;
ntStatus = ((pZwWaitForSingleobject)(Event, TRUE, 0));
}
if (!NT_SUCCESS(ntStatus))
{
printf("Unable to query directory contents, error 0x%x\n", ntStatus);
return ntStatus;
}
DirInformation = (PFILE_BOTH_DIR_INFORMATION) Buffer;
while (1)
{
UNICODE_STRING EntryName;
EntryName.MaximumLength = EntryName.Length = (USHORT) DirInformation -> FileNameLength;
EntryName.Buffer = &DirInformation -> FileName[0];
((pRtlUnicodeStringToAnsiString)(&as, &EntryName, TRUE));
printf("%s\n", as.Buffer);
if (0 == DirInformation -> NextEntryOffset)
break;
else
DirInformation = (PFILE_BOTH_DIR_INFORMATION) (((PUCHAR)DirInformation) + DirInformation -> NextEntryOffset);
}
((pZwClose)(RootDirectoryHandle));
return ntStatus;
}
int main(VOID)
{
WCHAR wszDirectory[] = {L"C:\\Temp"};
IntializeNativeFunctions();
ListDirectory(wszDirectory);
return 0;
}