有几个地方的定义我比资料上说的多加了一些,后来一看,是为了放一个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---------------------