oh,what a strange thing?

i want to test the function ZwQueryDirectoryObject in different os(w2k
and wxp),and i write a simple driver and test,and a strange thing
happened,the results of two os are most diffenent.in w2k return 18 for
pObjectIndex,but return 1 in wxp,what is the matter, and the input of the
func is the same.
the sourcecode is below:

#include “ntddk.h”
#include “string.h”

#define IOCTL_EVENT_MSG CTL_CODE(FILE_DEVICE_UNKNOWN, 0x928,
METHOD_BUFFERED , FILE_ANY_ACCESS)

//extern “C”
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryDirectoryObject (
IN HANDLE DirectoryHandle,
OUT PVOID Buffer,
IN ULONG Length,
IN BOOLEAN ReturnSingleEntry,
IN BOOLEAN RestartScan,
IN OUT PULONG Context,
OUT PULONG ReturnLength OPTIONAL
);

NTSTATUS
ZwOpenDirectoryObject(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);

typedef enum _DIRECTORYINFOCLASS
{
ObjectArray,
ObjectByOne
} DIRECTORYINFOCLASS, *PDIRECTORYINFOCLASS;

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp);
static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING
RegistryPath)
{
UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
WCHAR wBuffer[200];
ULONG CR0VALUE;

nameString.Buffer = wBuffer;
nameString.MaximumLength = 200;

DriverObject->DriverUnload = DriverUnload;

RtlInitUnicodeString(&nameString, L"\Device\Skykernel");

status = IoCreateDevice(
DriverObject,
0, //
&nameString,
FILE_DEVICE_UNKNOWN,
0,
TRUE,
&deviceObject
);

if (!NT_SUCCESS( status ))
return status;

deviceObject->Flags |= DO_BUFFERED_IO;

RtlInitUnicodeString(&linkString, L"\??\Skykernel");

status = IoCreateSymbolicLink (&linkString, &nameString);

if (!NT_SUCCESS( status ))
{
IoDeleteDevice (DriverObject->DeviceObject);
return status;
}

DriverObject->MajorFunction[IRP_MJ_CREATE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MydrvDispatchIoctl;

return STATUS_SUCCESS;
}

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;

UNREFERENCED_PARAMETER(DeviceObject);

irpSp = IoGetCurrentIrpStackLocation( Irp );

switch (irpSp->MajorFunction)
{
case IRP_MJ_CREATE:
DbgPrint(“IRP_MJ_CREATE\n”);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;

break;

case IRP_MJ_CLOSE:
DbgPrint(“IRP_MJ_CLOSE\n”);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;

break;
}

IoCompleteRequest(Irp, 0);
return STATUS_SUCCESS;

}

static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp)
{
PIO_STACK_LOCATION IrpStack;
NTSTATUS status;
ULONG ControlCode;
ULONG InputLength,OutputLength;
TCHAR wInputBuffer[200];
HANDLE hDir;
UNICODE_STRING dirString;
OBJECT_ATTRIBUTES dirAttr;
BOOLEAN bFirst=TRUE;
char Buf[2048]={0};
ULONG pObjectIndex = 0;
ULONG pLengthReturned = 0;
//NTSTATUS status;
//TCHAR OutMsg = “Message send by driver”;

//PCWSTR CurrentDir=“\??\d:”;

IrpStack = IoGetCurrentIrpStackLocation(Irp);

ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

switch (ControlCode)
{
case IOCTL_EVENT_MSG:
// DbgPrint(“IOCTL_EVENT_MSG\n”);

//RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, OutMsg,
sizeof(OutMsg));
Irp->IoStatus.Status = STATUS_SUCCESS;
//OutputLength = sizeof(OutMsg);
Irp->IoStatus.Information = 0;

RtlInitUnicodeString(&dirString, L"\??");
InitializeObjectAttributes(&dirAttr, &dirString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
status=ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &dirAttr);
if (status!=STATUS_SUCCESS)
{
DbgPrint(“status!=STATUS_SUCCESS”);
break;
}
else
DbgPrint(“status == STATUS_SUCCESS”);

ZwQueryDirectoryObject(hDir, Buf, 2048, ObjectArray, bFirst,
&pObjectIndex, &pLengthReturned) >= 0)

DbgPrint(“%d”,pObjectIndex);
DbgPrint(“------------------------------”);

}

status = Irp->IoStatus.Status;

IoCompleteRequest(Irp, 0);
return status;
}

VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING nameString;

RtlInitUnicodeString(&nameString, L"\??\Skykernel");
IoDeleteSymbolicLink(&nameString);
IoDeleteDevice(pDriverObject->DeviceObject);

//*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase

  • 0x97) = RealZwQuerySystemInformation;

return;
}

who can help me?


Ãâ·ÑÏÂÔØ MSN Explorer: http://explorer.msn.com/lccn/

Posting code, which normally is eye-popping difficult to read because what
looks good on your monitor looks like crap on mine, typically leads to
unexpected results.First, ZwQueryDirectoryObject must be undocumented since
you prototyped it. I see no AddDevice, indeed you create a DO in
DriverEntry, so I assume you are loading this as a legacy driver. When
testing returned status in the kernel the convention, indeed the discipline,
is to ALWYAS USE THE NT_SUCCESS(status) MACRO!!! Your debug print of
“status != STATUS_SUCCESS” is blatantly wrong since STATUS_SUCCESS can have
many enumerations. If the error or warning bits are not set in the 32 bits
of status returned by a kernel function then you have a successful return
with additional information provided. Verifier is notorious for testing this
and bouncing an offending driver that does not use the MACRO to test status.

Now, since ZwQueryDirectoryObject is undocumented, we really do not know the
significance of the differing return values, and we don’t even know if
ZwQueryDirectoryObject returned an error since you don’t capture and test
status, which would imply that any returned value is or is not valid. But
then, ZwQueryDirectoryObject is undocumented, so who can tell anyway?


The personal opinion of
Gary G. Little

“shark mouse” wrote in message news:xxxxx@ntdev…
> i want to test the function ZwQueryDirectoryObject in different os(w2k
> and wxp),and i write a simple driver and test,and a strange thing
> happened,the results of two os are most diffenent.in w2k return 18 for
> pObjectIndex,but return 1 in wxp,what is the matter, and the input of the
> func is the same.
> the sourcecode is below:
>
> #include “ntddk.h”
> #include “string.h”
>
> #define IOCTL_EVENT_MSG CTL_CODE(FILE_DEVICE_UNKNOWN, 0x928,
> METHOD_BUFFERED , FILE_ANY_ACCESS)
> //extern “C” NTSYSAPI
> NTSTATUS
> NTAPI
> ZwQueryDirectoryObject (
> IN HANDLE DirectoryHandle,
> OUT PVOID Buffer,
> IN ULONG Length,
> IN BOOLEAN ReturnSingleEntry,
> IN BOOLEAN RestartScan,
> IN OUT PULONG Context,
> OUT PULONG ReturnLength OPTIONAL
> );
>
> NTSTATUS
> ZwOpenDirectoryObject(
> OUT PHANDLE DirectoryHandle,
> IN ACCESS_MASK DesiredAccess,
> IN POBJECT_ATTRIBUTES ObjectAttributes
> );
>
>
> typedef enum _DIRECTORYINFOCLASS {
> ObjectArray,
> ObjectByOne
> } DIRECTORYINFOCLASS, PDIRECTORYINFOCLASS;
>
> static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP
> Irp); static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp);
> VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
>
> NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING
> RegistryPath) { UNICODE_STRING nameString, linkString; PDEVICE_OBJECT
> deviceObject; NTSTATUS status; WCHAR wBuffer[200]; ULONG CR0VALUE;
>
> nameString.Buffer = wBuffer; nameString.MaximumLength = 200;
> DriverObject->DriverUnload = DriverUnload;
> RtlInitUnicodeString(&nameString, L"\Device\Skykernel");
> status = IoCreateDevice(
> DriverObject, 0, // &nameString, FILE_DEVICE_UNKNOWN, 0,
> TRUE, &deviceObject );
> if (!NT_SUCCESS( status )) return status;
> deviceObject->Flags |= DO_BUFFERED_IO;
>
> RtlInitUnicodeString(&linkString, L"\??\Skykernel");
>
> status = IoCreateSymbolicLink (&linkString, &nameString);
> if (!NT_SUCCESS( status )) { IoDeleteDevice (DriverObject->DeviceObject);
> return status; }
> DriverObject->MajorFunction[IRP_MJ_CREATE] = MydrvDispatch;
> DriverObject->MajorFunction[IRP_MJ_CLOSE] = MydrvDispatch;
> DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MydrvDispatchIoctl;
>
>
> return STATUS_SUCCESS; }
>
> static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP
> Irp)
>
> { NTSTATUS status; PIO_STACK_LOCATION irpSp;
> UNREFERENCED_PARAMETER(DeviceObject);
>
> irpSp = IoGetCurrentIrpStackLocation( Irp );
> switch (irpSp->MajorFunction) { case IRP_MJ_CREATE:
> DbgPrint(“IRP_MJ_CREATE\n”);
> Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0L;
> break;
> case IRP_MJ_CLOSE: DbgPrint(“IRP_MJ_CLOSE\n”);
> Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0L;
> break; }
> IoCompleteRequest(Irp, 0);
> return STATUS_SUCCESS;
> }
>
> static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP
> Irp)
> { PIO_STACK_LOCATION IrpStack; NTSTATUS status; ULONG ControlCode; ULONG
> InputLength,OutputLength; TCHAR wInputBuffer[200]; HANDLE hDir;
> UNICODE_STRING dirString;
> OBJECT_ATTRIBUTES dirAttr;
> BOOLEAN bFirst=TRUE;
> char Buf[2048]={0};
> ULONG pObjectIndex = 0;
> ULONG pLengthReturned = 0;
> //NTSTATUS status;
> //TCHAR OutMsg[] = “Message send by driver”;
>
> //PCWSTR CurrentDir=“\??\d:”;
>
>
> IrpStack = IoGetCurrentIrpStackLocation(Irp);
>
> ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
> InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
> OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
> switch (ControlCode)
> { case IOCTL_EVENT_MSG:
> // DbgPrint(“IOCTL_EVENT_MSG\n”);
>
> //RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, OutMsg, sizeof(OutMsg));
> Irp->IoStatus.Status = STATUS_SUCCESS;
> //OutputLength = sizeof(OutMsg);
> Irp->IoStatus.Information = 0;
>
>
> RtlInitUnicodeString(&dirString, L"\??“);
> InitializeObjectAttributes(&dirAttr, &dirString,
> OBJ_CASE_INSENSITIVE, NULL, NULL);
> status=ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &dirAttr);
> if (status!=STATUS_SUCCESS)
> {
> DbgPrint(“status!=STATUS_SUCCESS”);
> break;
> }
> else
> DbgPrint(“status == STATUS_SUCCESS”);
> ZwQueryDirectoryObject(hDir, Buf, 2048, ObjectArray, bFirst,
> &pObjectIndex, &pLengthReturned) >= 0)
> DbgPrint(”%d",pObjectIndex);
> DbgPrint(“------------------------------”);
> }
> status = Irp->IoStatus.Status;
> IoCompleteRequest(Irp, 0); return status; }
>
> VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject) { UNICODE_STRING
> nameString;
> RtlInitUnicodeString(&nameString, L"\??\Skykernel");
> IoDeleteSymbolicLink(&nameString);
> IoDeleteDevice(pDriverObject->DeviceObject);
>
>
> //
(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase
> + 0x97) = RealZwQuerySystemInformation;
>
> return; }
>
>
> who can help me?
>
> _________________________________________________________________
> Ãâ·ÑÏÂÔØ MSN Explorer: http://explorer.msn.com/lccn/
>

shark mouse wrote:

i want to test the function ZwQueryDirectoryObject in different os(w2k
and wxp),and i write a simple driver and test,and a strange thing
happened,the results of two os are most diffenent.in w2k return 18 for
pObjectIndex,but return 1 in wxp,what is the matter, and the input of
the func is the same.

It doesn’t matter. That value is just a helper used by the function to
keep track of where it is. You aren’t expected to understand what the
value means. The valuable information will be in your “Buf” buffer.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

thanks,i alreadly know the information is in the buffer,but the index
show how many data is in buffer,so the index is most important.
in w2k,the buffer have some data like the driver object name,such as
“D:”,etc,but wxp only have the “Global”,this is the problem,how to solve
this?


ÓëÁª»úµÄÅóÓѽøÐн»Á÷£¬ÇëʹÓà MSN Messenger: http://messenger.msn.com/cn

the list in the buffer of my test:
WXP:
Global

W2K:
D:
ArcName
Ntfs
SeLsaCommandPort
REGISTRY
XactSrvLpcPort
DbgUiApiPort
NLS
DosDevices
SeRmCommandPort
NlsCacheMutant
LsaAuthenticationPort


Ãâ·ÑÏÂÔØ MSN Explorer: http://explorer.msn.com/lccn/

shark mouse wrote:

the list in the buffer of my test:
WXP:
Global

Unless I’m off my chum, “Global” contains all those other names. You
need to go one level deeper. The same thing happens on Win2K if you run
Terminal Services.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.