Chinaunix首页 | 论坛 | 博客
  • 博客访问: 846023
  • 博文数量: 756
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 4980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:40
文章分类

全部博文(756)

文章存档

2011年(1)

2008年(755)

我的朋友

分类:

2008-10-13 16:13:17

有几个地方的定义我比资料上说的多加了一些,后来一看,是为了放一个UNICODE的字符串。
1\native.h

typedef LONG NTSTATUS;

typedef struct _UNICODE_STRING {
 USHORT Length;
 USHORT MaximumLength;
#ifdef MIDL_PASS
 [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
 PWSTR  Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;

typedef enum _POOL_TYPE {
 NonPagedPool,
 PagedPool,
 NonPagedPoolMustSucceed,
 DontUseThisType,
 NonPagedPoolCacheAligned,
 PagedPoolCacheAligned,
 NonPagedPoolCacheAlignedMustS
} POOL_TYPE;

typedef enum _OBJECT_INFORMATION_CLASS
{
 ObjectBasicInformation,
 ObjectNameInformation,
 ObjectTypeInformation,
 ObjectTypesInformation,
 ObjectHandleFlagInformation
} OBJECT_INFORMATION_CLASS;

typedef struct _OBJECT_BASIC_INFORMATION
{
 ULONG                   Attributes;
 ACCESS_MASK             GrantedAccess;
 ULONG                   HandleCount;
 ULONG                   PointerCount;
 ULONG                   PagedPoolCharge;
 ULONG                   NonPagedPoolCharge;
 LARGE_INTEGER   CreationTime;
 ULONG     NameInfoSize;
 ULONG     TypeInfoSize;
 ULONG     SecurityDescriptorSize;
 BYTE                    Unknown2[12];
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION
{
 UNICODE_STRING          ObjectName;
 BYTE                    Unknown2[32];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;

typedef struct _OBJECT_TYPE_INFORMATION
{
 UNICODE_STRING          TypeName;
 ULONG                   TotalNumberOfHandles;
 ULONG                   TotalNumberOfObjects;
 WCHAR                   Unused1[8];
 ULONG                   HighWaterNumberOfHandles;
 ULONG                   HighWaterNumberOfObjects;
 WCHAR                   Unused2[8];
 ACCESS_MASK             InvalidAttributes;
 GENERIC_MAPPING         GenericMapping;
 ACCESS_MASK             ValidAttributes;
 BOOLEAN                 SecurityRequired;
 BOOLEAN                 MaintainHandleCount;
 USHORT                  MaintainTypeList;
 POOL_TYPE               PoolType;
 ULONG                   DefaultPagedPoolCharge;
 ULONG                   DefaultNonPagedPoolCharge;
 BYTE                    Unknown2[16];
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;

typedef struct _OBJECT_TYPES_INFORMATION
{
 ULONG                   NumberOfObjectsTypes;
 OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;


typedef struct _OBJECT_HANDLE_FLAG_INFORMATION
{
 BOOLEAN Inherit;
 BOOLEAN ProtectFromClose;
}OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION;

NTSYSAPI
NTSTATUS
NTAPI
NtQueryObject (
      IN HANDLE Handle,
      IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
      OUT PVOID ObjectInformation,
      IN ULONG ObjectInformationLength,
      OUT PULONG ReturnLength OPTIONAL
      );

#define WIN32_LEAN_AND_MEAN
#include
#include

extern "C"
{
#include "native.h"
}

#pragma comment(lib,"ntdll")
#pragma comment(lib,"ws2_32")

class Winsock2Env
{
public:
 Winsock2Env(){WSADATA m_data;WSAStartup(MAKEWORD(2,2),&m_data);}
 ~Winsock2Env(){WSACleanup();}
};

Winsock2Env gWinsock2Env;

int main(int argc, char *argv[])
{
 HANDLE handle=(HANDLE)socket(AF_INET,SOCK_STREAM,0);
 sockaddr_in sa;
 memset(&sa,0,sizeof(sa));
 sa.sin_family=AF_INET;
 sa.sin_addr.S_un.S_addr=INADDR_ANY;
 sa.sin_port=htons(500);
 int ret=bind((SOCKET)handle,(sockaddr*)&sa,sizeof(sa));

 DWORD retlen=0;

 OBJECT_BASIC_INFORMATION basic_info;
 NtQueryObject(handle,ObjectBasicInformation,&basic_info,sizeof(basic_info),&retlen);

 retlen=0;
 OBJECT_NAME_INFORMATION name_info;
 NtQueryObject(handle,ObjectNameInformation,&name_info,sizeof(name_info),&retlen);

 OBJECT_TYPE_INFORMATION type_info;
 int sizeddd=sizeof(type_info);
 NtQueryObject(handle,ObjectTypeInformation,&type_info,sizeof(type_info),&retlen);
 return 0;
}


--------------------next---------------------
TSTATUS
NtQueryObject (
IN HANDLE Handle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG ObjectInformationLength,
OUT PULONG ReturnLength OPTIONAL
)

/*++

Routine description:

This routine is used to query information about a given object

Arguments:

Handle - Supplies a handle to the object being queried. This value
is ignored if the requested information class is for type
information.

ObjectInformationClass - Specifies the type of information to return

ObjectInformation - Supplies an output buffer for the information being
returned

ObjectInformationLength - Specifies, in bytes, the length of the
preceding object information buffer

ReturnLength - Optionally receives the length, in bytes, used to store
the object information

Return Value:

An appropriate status value

--*/

{
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PVOID Object;
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
POBJECT_HEADER_NAME_INFO NameInfo;
POBJECT_TYPE ObjectType;
POBJECT_HEADER ObjectDirectoryHeader;
POBJECT_DIRECTORY ObjectDirectory;
ACCESS_MASK GrantedAccess;
POBJECT_HANDLE_FLAG_INFORMATION HandleFlags;
OBJECT_HANDLE_INFORMATION HandleInformation;
ULONG NameInfoSize;
ULONG SecurityDescriptorSize;
ULONG TempReturnLength;
OBJECT_BASIC_INFORMATION ObjectBasicInfo;
POBJECT_TYPES_INFORMATION TypesInformation;
POBJECT_TYPE_INFORMATION TypeInfo;
ULONG i;

PAGED_CODE();

//
// Initialize our local variables
//

TempReturnLength = 0;

//
// Get previous processor mode and probe output argument if necessary.
//

PreviousMode = KeGetPreviousMode();

if (PreviousMode != KernelMode) {

try {

if (ObjectInformationClass != ObjectHandleFlagInformation) {

ProbeForWrite( ObjectInformation,
ObjectInformationLength,
sizeof( ULONG ));

} else {

ProbeForWrite( ObjectInformation,
ObjectInformationLength,
1 );
}

//
// We'll use a local temp return length variable to pass
// through to the later ob query calls which will increment
// its value. We can't pass the users return length directly
// because the user might also be altering its value behind
// our back.
//

if (ARGUMENT_PRESENT( ReturnLength )) {

ProbeForWriteUlong( ReturnLength );
}

} except( EXCEPTION_EXECUTE_HANDLER ) {

return( GetExceptionCode() );
}
}

//
// If the query is not for types information then we
// will have to get the object in question. Otherwise
// for types information there really isn't an object
// to grab.
//

if (ObjectInformationClass != ObjectTypesInformation) {

Status = ObReferenceObjectByHandle( Handle,
0,
NULL,
PreviousMode,
&Object,
&HandleInformation );

if (!NT_SUCCESS( Status )) {

return( Status );
}

GrantedAccess = HandleInformation.GrantedAccess;

ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
ObjectType = ObjectHeader->Type;

} else {

GrantedAccess = 0;
Object = NULL;
ObjectHeader = NULL;
ObjectType = NULL;
}

//
// Now process the particular information class being
// requested
//

switch( ObjectInformationClass ) {

case ObjectBasicInformation:

//
// Make sure the output buffer is long enough and then
// fill in the appropriate fields into our local copy
// of basic information.
//

if (ObjectInformationLength != sizeof( OBJECT_BASIC_INFORMATION )) {

ObDereferenceObject( Object );

return( STATUS_INFO_LENGTH_MISMATCH );
}

ObjectBasicInfo.Attributes = HandleInformation.HandleAttributes;

if (ObjectHeader->Flags & OB_FLAG_PERMANENT_OBJECT) {

ObjectBasicInfo.Attributes |= OBJ_PERMANENT;
}

if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE_OBJECT) {

ObjectBasicInfo.Attributes |= OBJ_EXCLUSIVE;
}

ObjectBasicInfo.GrantedAccess = GrantedAccess;
ObjectBasicInfo.HandleCount = ObjectHeader->HandleCount;
ObjectBasicInfo.PointerCount = ObjectHeader->PointerCount;

QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader );

if (QuotaInfo != NULL) {

ObjectBasicInfo.PagedPoolCharge = QuotaInfo->PagedPoolCharge;
ObjectBasicInfo.NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge;

} else {

ObjectBasicInfo.PagedPoolCharge = 0;
ObjectBasicInfo.NonPagedPoolCharge = 0;
}

if (ObjectType == ObpSymbolicLinkObjectType) {

ObjectBasicInfo.CreationTime = ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime;

} else {

RtlZeroMemory( &ObjectBasicInfo.CreationTime,
sizeof( ObjectBasicInfo.CreationTime ));
}

//
// Compute the size of the object name string by taking its name plus
// seperators and traversing up to the root adding each directories
// name length plus seperators
//

NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );

if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) {

ObpEnterRootDirectoryMutex();

ObjectDirectory = NameInfo->Directory;

//
// **** this "IF" is probably not needed because of the preceding
// "IF"
//

if (ObjectDirectory) {

NameInfoSize = sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length;

while (ObjectDirectory) {

ObjectDirectoryHeader = OBJECT_TO_OBJECT_HEADER( ObjectDirectory );
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectDirectoryHeader );

if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) {

NameInfoSize += sizeof( OBJ_NAME_PATH_SEPARATOR ) + NameInfo->Name.Length;
ObjectDirectory = NameInfo->Directory;

} else {

break;
}
}

NameInfoSize += sizeof( OBJECT_NAME_INFORMATION ) + sizeof( UNICODE_NULL );
}

ObpLeaveRootDirectoryMutex();

} else {

NameInfoSize = 0;
}

ObjectBasicInfo.NameInfoSize = NameInfoSize;
ObjectBasicInfo.TypeInfoSize = ObjectType->Name.Length + sizeof( UNICODE_NULL ) +
sizeof( OBJECT_TYPE_INFORMATION );

ObpAcquireDescriptorCacheReadLock();

if ((GrantedAccess & READ_CONTROL) &&
ARGUMENT_PRESENT( ObjectHeader->SecurityDescriptor )) {

SecurityDescriptorSize = RtlLengthSecurityDescriptor(
ObjectHeader->SecurityDescriptor);

} else {

SecurityDescriptorSize = 0;
}

ObpReleaseDescriptorCacheLock();

ObjectBasicInfo.SecurityDescriptorSize = SecurityDescriptorSize;

//
// Now that we've packaged up our local copy of basic info we need
// to copy it into the output buffer and set the return
// length
//

try {

*(POBJECT_BASIC_INFORMATION) ObjectInformation = ObjectBasicInfo;

TempReturnLength = ObjectInformationLength;

} except( EXCEPTION_EXECUTE_HANDLER ) {

//
// Fall through, since we cannot undo what we have done.
//
}

break;

case ObjectNameInformation:

//
// Call a local worker routine
//

Status = ObQueryNameString( Object,
(POBJECT_NAME_INFORMATION)ObjectInformation,
ObjectInformationLength,
&TempReturnLength );
break;

case ObjectTypeInformation:

//
// Call a local worker routine
//

Status = ObQueryTypeInfo( ObjectType,
(POBJECT_TYPE_INFORMATION)ObjectInformation,
ObjectInformationLength,
&TempReturnLength );
break;

case ObjectTypesInformation:

try {

//
// The first thing we do is set the return length to cover the
// types info record. Later in each call to query type info
// this value will be updated as necessary
//

TempReturnLength = sizeof( OBJECT_TYPES_INFORMATION );

//
// Make sure there is enough room to hold the types info record
// and if so then compute the number of defined types there are
//

TypesInformation = (POBJECT_TYPES_INFORMATION)ObjectInformation;

if (ObjectInformationLength < sizeof( OBJECT_TYPES_INFORMATION ) ) {

Status = STATUS_INFO_LENGTH_MISMATCH;

} else {

TypesInformation->NumberOfTypes = 0;

for (i=0; i
ObjectType = ObpObjectTypes[ i ];

if (ObjectType == NULL) {

break;
}

TypesInformation->NumberOfTypes += 1;
}
}

//
// For each defined type we will query the type info for the
// object type and adjust the TypeInfo pointer to the next
// free spot
//

TypeInfo = (POBJECT_TYPE_INFORMATION)(TypesInformation + 1);

for (i=0; i
ObjectType = ObpObjectTypes[ i ];

if (ObjectType == NULL) {

break;
}

Status = ObQueryTypeInfo( ObjectType,
TypeInfo,
ObjectInformationLength,
&TempReturnLength );

if (NT_SUCCESS( Status )) {

TypeInfo = (POBJECT_TYPE_INFORMATION)
((PCHAR)(TypeInfo+1) + ALIGN_UP( TypeInfo->TypeName.MaximumLength, ULONG ));
}
}

} except( EXCEPTION_EXECUTE_HANDLER ) {

Status = GetExceptionCode();
}

break;

case ObjectHandleFlagInformation:

try {

//
// Set the amount of data we are going to return
//

TempReturnLength = sizeof(OBJECT_HANDLE_FLAG_INFORMATION);

HandleFlags = (POBJECT_HANDLE_FLAG_INFORMATION)ObjectInformation;

//
// Make sure we have enough room for the query, and if so we'll
// set the output based on the flags stored in the handle
//

if (ObjectInformationLength < sizeof( OBJECT_HANDLE_FLAG_INFORMATION)) {

Status = STATUS_INFO_LENGTH_MISMATCH;

} else {

HandleFlags->Inherit = FALSE;

if (HandleInformation.HandleAttributes & OBJ_INHERIT) {

HandleFlags->Inherit = TRUE;
}

HandleFlags->ProtectFromClose = FALSE;

if (HandleInformation.HandleAttributes & OBJ_PROTECT_CLOSE) {

HandleFlags->ProtectFromClose = TRUE;
}
}

} except( EXCEPTION_EXECUTE_HANDLER ) {

Status = GetExceptionCode();
}

break;

default:

//
// To get to this point we must have had an object and the
// information class is not defined, so we should dereference the
// object and return to our user the bad status
//

ObDereferenceObject( Object );

return( STATUS_INVALID_INFO_CLASS );
}

//
// Now if the caller asked for a return length we'll set it from
// our local copy
//

try {

if (ARGUMENT_PRESENT( ReturnLength ) ) {

*ReturnLength = TempReturnLength;
}

} except( EXCEPTION_EXECUTE_HANDLER ) {

//
// Fall through, since we cannot undo what we have done.
//
}

//
// In the end we can free the object if there was one and return
// to our caller
//

if (Object != NULL) {

ObDereferenceObject( Object );
}

return( Status );
}

--------------------next---------------------

阅读(1341) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~