Вверх ↑
Ответов: 2059
Рейтинг: 132
#1: 2016-05-28 12:17:10 ЛС | профиль | цитата
Леонид, nesco, какие Вы эамечательные!

------------ Дoбавленo в 12.16:
Ну значется так:
Я, такой-секой, не мазанный, находясь в здравой памяти подтверждою всё сказанное на медне.
Вот рабочий some_ntdef.pas (пока на delphi7)
unit some_ntdef;

interface

uses windows;

const

ntdll = 'ntdll.dll';

STATUS_SUCCESS = 0;

// Define the create disposition values
//

FILE_SUPERSEDE = $00000000;
FILE_OPEN = $00000001;
FILE_CREATE = $00000002;
FILE_OPEN_IF = $00000003;
FILE_OVERWRITE = $00000004;
FILE_OVERWRITE_IF = $00000005;
FILE_MAXIMUM_DISPOSITION = $00000005;

//
// Define the create/open option flags
//

FILE_DIRECTORY_FILE = $00000001;
FILE_WRITE_THROUGH = $00000002;
FILE_SEQUENTIAL_ONLY = $00000004;
FILE_NO_INTERMEDIATE_BUFFERING = 00000008;


// Valid values for the Attributes field
//

OBJ_INHERIT = $00000002;
OBJ_PERMANENT = $00000010;
OBJ_EXCLUSIVE = $00000020;
OBJ_CASE_INSENSITIVE = $00000040;
OBJ_OPENIF = $00000080;
OBJ_OPENLINK = $00000100;
OBJ_KERNEL_HANDLE = $00000200;
OBJ_FORCE_ACCESS_CHECK = $00000400;
OBJ_VALID_ATTRIBUTES = $000007F2;


type
PNTSTATUS = ^NTSTATUS;
NTSTATUS = Integer;
ULONG_PTR = Longword;
USHORT = Word;
PWSTR = LPWSTR;
HANDLE = THandle;
PVOID = Pointer;
CCHAR = Char;
LONG = Longint;


PUNICODE_STRING = ^UNICODE_STRING;
_UNICODE_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PWSTR;
end;
UNICODE_STRING = _UNICODE_STRING;
PCUNICODE_STRING = ^UNICODE_STRING;
TUnicodeString = UNICODE_STRING;
PUnicodeString = PUNICODE_STRING;


PString = ^TString;
_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PCHAR;
end;
TString = _STRING;

ANSI_STRING = _STRING;
PANSI_STRING = PSTRING;


LPLARGE_INTEGER = ^LARGE_INTEGER;

{$IFDEF USE_DELPHI_TYPES}
_LARGE_INTEGER = Windows._LARGE_INTEGER;
LARGE_INTEGER = Windows.LARGE_INTEGER;
TLargeInteger = Windows.TLargeInteger;
{$ELSE}
_LARGE_INTEGER = record
case Integer of
0: (
LowPart: DWORD;
HighPart: LONG);
1: (
QuadPart: LONGLONG);
end;
LARGE_INTEGER = _LARGE_INTEGER;
TLargeInteger = LARGE_INTEGER;
{$ENDIF}

PLARGE_INTEGER = ^LARGE_INTEGER;
PLargeInteger = LPLARGE_INTEGER;

LPULARGE_INTEGER = ^ULARGE_INTEGER;

{$IFDEF USE_DELPHI_TYPES}
ULARGE_INTEGER = Windows.ULARGE_INTEGER;
TULargeInteger = Windows.TULargeInteger;
PULargeInteger = Windows.PULargeInteger;
{$ELSE}
ULARGE_INTEGER = record
case Integer of
0: (
LowPart: DWORD;
HighPart: DWORD);
1: (
QuadPart: LONGLONG);
end;
TULargeInteger = ULARGE_INTEGER;
PULargeInteger = LPULARGE_INTEGER;
{$ENDIF}

PULARGE_INTEGER = ^ULARGE_INTEGER;


POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
_OBJECT_ATTRIBUTES = record
Length: ULONG;
RootDirectory: HANDLE;
ObjectName: PUNICODE_STRING;
Attributes: ULONG;
SecurityDescriptor: PVOID; // Points to type SECURITY_DESCRIPTOR
SecurityQualityOfService: PVOID; // Points to type SECURITY_QUALITY_OF_SERVICE
end;
OBJECT_ATTRIBUTES = _OBJECT_ATTRIBUTES;
TObjectAttributes = OBJECT_ATTRIBUTES;
PObjectAttributes = POBJECT_ATTRIBUTES;


_IO_STATUS_BLOCK = record
//union {
Status: NTSTATUS;
// PVOID Pointer;
//}
Information: ULONG_PTR;
end;
IO_STATUS_BLOCK = _IO_STATUS_BLOCK;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;

TIOStatusBlock = IO_STATUS_BLOCK;
PIOStatusBlock = PIO_STATUS_BLOCK;


PIO_APC_ROUTINE = procedure (ApcContext: PVOID; IoStatusBlock: PIO_STATUS_BLOCK; Reserved: ULONG); stdcall;

_EVENT_TYPE = (NotificationEvent, SynchronizationEvent);
EVENT_TYPE = _EVENT_TYPE;
PEVENT_TYPE = ^EVENT_TYPE;


_FILE_INFORMATION_CLASS = (
FileFiller0,
FileDirectoryInformation, // 1
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4 wdm
FileStandardInformation, // 5 wdm
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14 wdm
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20 wdm
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileMaximumInformation);
FILE_INFORMATION_CLASS = _FILE_INFORMATION_CLASS;
PFILE_INFORMATION_CLASS = ^FILE_INFORMATION_CLASS;


PFILE_BOTH_DIR_INFORMATION = ^FILE_BOTH_DIR_INFORMATION;
_FILE_BOTH_DIR_INFORMATION = record
NextEntryOffset : ULONG;
FileIndex : ULONG;
CreationTime : LARGE_INTEGER;
LastAccessTime : LARGE_INTEGER;
LastWriteTime : LARGE_INTEGER;
ChangeTime : LARGE_INTEGER;
EndOfFile : LARGE_INTEGER;
AllocationSize : LARGE_INTEGER;
FileAttributes : ULONG;
FileNameLength : ULONG;
EaSize : ULONG;
ShortNameLength : CCHAR;
ShortName : array[0..11] of WCHAR;
FileName : array[0..0] of WCHAR;
end;
FILE_BOTH_DIR_INFORMATION = _FILE_BOTH_DIR_INFORMATION;
TFileBothDirInformation = FILE_BOTH_DIR_INFORMATION;
PFileBothDirInformation = PFILE_BOTH_DIR_INFORMATION;


function NT_SUCCESS(Status:NTSTATUS):boolean;

procedure InitializeObjectAttributes(p: POBJECT_ATTRIBUTES; n: PUNICODE_STRING;
a: ULONG; r: HANDLE; s: PVOID{PSECURITY_DESCRIPTOR});

function NtCreateFile(FileHandle: PHANDLE; DesiredAccess: ACCESS_MASK; ObjectAttributes: POBJECT_ATTRIBUTES;
IoStatusBlock: PIO_STATUS_BLOCK; AllocationSize: PLARGE_INTEGER; FileAttributes: ULONG;
ShareAccess: ULONG; CreateDisposition: ULONG; CreateOptions: ULONG; EaBuffer: PVOID;
EaLength: ULONG): NTSTATUS; stdcall;

function NtQueryDirectoryFile(FileHandle: HANDLE; Event: HANDLE; ApcRoutine: PIO_APC_ROUTINE; ApcContext: PVOID;
IoStatusBlock: PIO_STATUS_BLOCK; FileInformation: PVOID; FileInformationLength: ULONG;
FileInformationClass: FILE_INFORMATION_CLASS; ReturnSingleEntry: ByteBool; FileName: PUNICODE_STRING;
RestartScan: ByteBool): NTSTATUS; stdcall;

function NtCreateEvent(EventHandle: PHANDLE; DesiredAccess: ACCESS_MASK; ObjectAttributes: POBJECT_ATTRIBUTES; EventType: EVENT_TYPE;
InitialState: ByteBool): NTSTATUS; stdcall;

function NtWaitForSingleObject(Handle: HANDLE; Alertable: ByteBool; Timeout: PLARGE_INTEGER): NTSTATUS; stdcall;

procedure RtlInitUnicodeString(DestinationString: PUNICODE_STRING; SourceString: LPCWSTR); stdcall;

function RtlUnicodeStringToAnsiString(DestinationString: PANSI_STRING; SourceString: PUNICODE_STRING;
AllocateDestinationString: ByteBool): NTSTATUS; stdcall;

implementation

function NT_SUCCESS(Status:NTSTATUS):boolean;
begin
result:=Status >= 0
end;

procedure InitializeObjectAttributes(p: POBJECT_ATTRIBUTES; n: PUNICODE_STRING;
a: ULONG; r: HANDLE; s: PVOID{PSECURITY_DESCRIPTOR});
begin
p^.Length := sizeof(OBJECT_ATTRIBUTES);
p^.RootDirectory := r;
p^.Attributes := a;
p^.ObjectName := n;
p^.SecurityDescriptor := s;
p^.SecurityQualityOfService := nil;
end;

function NtCreateFile; external ntdll name 'NtCreateFile';
function NtQueryDirectoryFile; external ntdll name 'NtQueryDirectoryFile';
function NtCreateEvent; external ntdll name 'NtCreateEvent';
function NtWaitForSingleObject; external ntdll name 'NtWaitForSingleObject';
procedure RtlInitUnicodeString; external ntdll name 'RtlInitUnicodeString';
function RtlUnicodeStringToAnsiString; external ntdll name 'RtlUnicodeStringToAnsiString';

end.

Вот консольное приложение:
 
program dirinfo_nt;

{$APPTYPE CONSOLE}

uses
windows, some_ntdef;


var
RootDirectoryName : UNICODE_STRING;
EntryName : UNICODE_STRING;
RootAnsiName : ANSI_STRING;
RootDirectoryAttributes: OBJECT_ATTRIBUTES;
Status : NTSTATUS;
RootDirectoryHandle : HANDLE;
Iosb: IO_STATUS_BLOCK;
Event : HANDLE;
Buffer:array [0..65535] of byte;
DirInformation : PFILE_BOTH_DIR_INFORMATION;

begin

// We use the name DosDevices rather than ?? so that it works on NT 3.51 as well as NT 4.0

RtlInitUnicodeString(@RootDirectoryName, '\DosDevices\C:\');

// Now open it

InitializeObjectAttributes(@RootDirectoryAttributes,
@RootDirectoryName,OBJ_CASE_INSENSITIVE,
0, // absolute open, no relative directory handle
nil // no security descriptor necessary
);

Status := NtCreateFile(@RootDirectoryHandle,
GENERIC_READ,
@RootDirectoryAttributes,
@Iosb,
nil, // no meaning for allocation
FILE_ATTRIBUTE_DIRECTORY, // MUST be a directory
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, // share all
FILE_OPEN, // must already exist
FILE_DIRECTORY_FILE, // MUST be a directory
nil,0);
if (not NT_SUCCESS(Status)) then
begin
writeln('Unable to open root directory, error = ',Status);
halt(Status);
end;

// Create an event

Status := NtCreateEvent(@Event,
GENERIC_ALL,
nil, // no object attributes
NotificationEvent,FALSE);
if (not NT_SUCCESS(Status)) then
begin
writeln('Event creation failed with error = ',Status);
halt(Status);
end;

// We pass NO NAME which is the same as *.*

Status := NtQueryDirectoryFile(RootDirectoryHandle,Event,
nil, // No APC routine
nil, // No APC context
@Iosb,
@Buffer,
length(Buffer),
FileBothDirectoryInformation,
FALSE,
nil,
FALSE);

// If the directory operation is in progress, wait for it to finish.

if (Status = STATUS_PENDING) then Status := NtWaitForSingleObject(Event, TRUE, nil);

// Check for errors.

if (not NT_SUCCESS(Status)) then
begin
writeln('Unable to query directory contents, error = ',Status);
halt(Status)
end;


// Note that as this is an example we're not ITERATING over the directory. To
// do so we should use a loop and query the directory AGAIN until we get back
// STATUS_NO_MORE_FILES. If the directory was TOTALLY EMPTY we'd get back
// STATUS_NO_SUCH_FILE - but only the ROOT directory can ever be TOTALLY EMPTY.

DirInformation := PFILE_BOTH_DIR_INFORMATION(@Buffer);

writeln('File/Dir Name, Allocation_Size');
writeln('------------------------------',#13#10);

while true do
begin
EntryName.MaximumLength := DirInformation^.FileNameLength;
EntryName.Length := DirInformation^.FileNameLength;
EntryName.Buffer := @DirInformation^.FileName;

RtlUnicodeStringToAnsiString(@RootAnsiName,@EntryName,TRUE);


// Dump the full name of the file. We could dump the other information
// here as well, but we'll keep the example shorter instead.

writeln(RootAnsiName.Buffer,', ',DirInformation^.AllocationSize.QuadPart);

// If there is no offset in the entry, the buffer has been exhausted.

if (DirInformation^.NextEntryOffset=0) then break else
begin
// Advance to the next entry.
DirInformation := PFILE_BOTH_DIR_INFORMATION(Cardinal(DirInformation)+DirInformation^.NextEntryOffset);
end;

// Skip a line
writeln;

end; //while

// Note that we skip closing our handles. The process death will do it for us.

halt(STATUS_SUCCESS)
end.

Пока не адаптировал под IC, какие-то ошибки были с delphi4, не помню.
Пока больший интерес вызывают вышеобозначенные функции. Пока хочу с ними поиграть.
[flood]
Для тех, кто в поиске рецептов - рассказываю:
Чтобы чувствовать себя хорошо, надо употребить ровно половину того, что было выпито вчера и не рюмкой больше и ни какого пива!!!
Неправильное похмелье приводит к длительному запою. Это золотое правило.
(Удивительно, но если Вы вчера приняли на грудь 3 литра, то выпив сегодня полтора литра Вы вовсе не будете пьяным, в то врем, как в обычные дни с двух стаканов может "повести".)
В качестве факультатива можно принять капустный, или огуречный рассол, для восстановления кислотно-щелочного баланса.
Также можно обратиться к творчеству Булгакова и поискать там рецепты, коих не мало. Но это займёт время, а тут проверенный десятилетиями рецепт, начиная с брежневских времён. При Хрущёве вообще ни капли в рот не брал!

Вот так она хранится советская граница
и никакая сволочь её не перейдёт
...
Пограничников - с праздником!
[/flood]
to be continued...
карма: 6

0