获取句柄的详细信息:(原代码)

获取进程名称:Windows句柄操作详解 GetInfoTable函数在Windows系统编程中扮演着重要的角色,尤其是在进程管理方面。其核心功能是从系统中检索关于特定进程的详细信息表。这个函数通常被应用于系统监控、性能分析、安全审计等多种场景,开发者通过调用GetInfoTable可以获取进程的ID、句柄、优先级、内存使用情况等信息。例如,系统管理员可能需要定期检查系统的进程活动,以监控恶意软件或服务的异常行为;而应用开发者则可能需要获取进程信息来优化应用程序的性能。在这些情况下,GetInfoTable函数都能够提供关键的数据支持。 阅读详情
一、驱动部分


extern "C"
{
#include <ntddk.h>
}
#include "ScSysInfo.h"

extern "C"
{
#include "native.h"
#include "../TestHandle/ob.h"
}

#if 1
#define dprintf DbgPrint
#else
#define dprintf
#endif

#define kprintf DbgPrint

#define NT_DEVICE_NAME L"//Device//ScSysInfo"
#define DOS_DEVICE_NAME L"//DosDevices//ScSysInfo"


typedef struct _OBJECT_TYPE {
 ERESOURCE Mutex;
 LIST_ENTRY TypeList;
 UNICODE_STRING Name;            // Copy from object header for convenience
 PVOID DefaultObject;
 ULONG Index;
 ULONG TotalNumberOfObjects;
 ULONG TotalNumberOfHandles;
 ULONG HighWaterNumberOfObjects;
 ULONG HighWaterNumberOfHandles;
 OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
 ULONG Key;
#endif //POOL_TAGGING
} OBJECT_TYPE, *POBJECT_TYPE;

struct ScHandleInfoOut
{
 OBJECT_HEADER obj_hdr;
 OBJECT_TYPE obj_type;
};


NTSTATUS ScSysInfoDispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS ScSysInfoDispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

NTSTATUS ScSysInfoDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

VOID ScSysInfoUnload(IN PDRIVER_OBJECT DriverObject);

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
 NTSTATUS ntStatus;
 PDEVICE_OBJECT DeviceObject = NULL;
 UNICODE_STRING ntDeviceName, dosDeviceName;

 RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
 ntStatus = IoCreateDevice(
  DriverObject,
  0,
  &ntDeviceName, // DeviceName
  FILE_DEVICE_SCSYSINFO, // DeviceType
  0, // DeviceCharacteristics
  FALSE, // Exclusive
  &DeviceObject // [OUT]
  );
 DeviceObject->Flags |= DO_BUFFERED_IO;

 if (!NT_SUCCESS(ntStatus))
 {
  dprintf("ScSysInfo IoCreateDevice=0x%x/n", ntStatus);
  goto __failed;
 }

 RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);

 ntStatus = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);

 if (!NT_SUCCESS(ntStatus))
 {
  goto __failed;
 }

 BOOLEAN fSymbolicLink = TRUE;

 DriverObject->MajorFunction[IRP_MJ_CREATE]         = ScSysInfoDispatchCreate;
 DriverObject->MajorFunction[IRP_MJ_CLOSE]          = ScSysInfoDispatchClose;
 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScSysInfoDispatchDeviceControl;
 DriverObject->DriverUnload                         = ScSysInfoUnload;

 if (!NT_SUCCESS(ntStatus))
 {
  goto __failed;
 }

 return ntStatus;

__failed:

 if (fSymbolicLink)
 {
  IoDeleteSymbolicLink(&dosDeviceName);
 }

 if (DeviceObject)
 {
  IoDeleteDevice(DeviceObject);
 }

 return ntStatus;
}

NTSTATUS ScSysInfoDispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
 Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 0;
 IoCompleteRequest(Irp, IO_NO_INCREMENT);
 return STATUS_SUCCESS;
}

NTSTATUS ScSysInfoDispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
 Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 0;
 IoCompleteRequest(Irp, IO_NO_INCREMENT);
 return STATUS_SUCCESS;
}

NTSTATUS ScSysInfoDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
 NTSTATUS ntStatus;
 PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
 PVOID lpInOutBuffer;
 ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;

 Irp->IoStatus.Status = STATUS_SUCCESS;
 Irp->IoStatus.Information = 0;

 lpInOutBuffer = Irp->AssociatedIrp.SystemBuffer;
 HANDLE *inbuf=(HANDLE*)Irp->AssociatedIrp.SystemBuffer;
 ScHandleInfoOut *outbuf=(ScHandleInfoOut *)Irp->AssociatedIrp.SystemBuffer;
 nInBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
 nOutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

 dprintf("ScSysInfo IRP_MJ_DEVICE_CONTROL/n");

 dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

 switch (dwIoControlCode)
 {
 case IOCTL_SCSYSINFO_GETHANDLEOBJECT:
  {
   PVOID objbody=NULL;
   POBJECT_HEADER ObjectHeader=NULL;
   if(ObReferenceObjectByHandle(*inbuf,0x80000000,NULL,KernelMode,&objbody,NULL)==STATUS_SUCCESS)
   {
    if(objbody!=NULL)
    {
     ObjectHeader=OBJECT_TO_OBJECT_HEADER(objbody);
    }
   }
   memset(outbuf,0,sizeof(ScHandleInfoOut));
   if(ObjectHeader!=NULL)
   {
    outbuf->obj_hdr=*ObjectHeader;
    if(ObjectHeader->Type!=NULL)
    {
     outbuf->obj_type=*(ObjectHeader->Type);
    }
    ObDereferenceObject(objbody);
   }
   Irp->IoStatus.Information = sizeof(ScHandleInfoOut);
   Irp->IoStatus.Status = STATUS_SUCCESS;
   break;
  }

 default:
  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  dprintf("ScSysInfo unknown IRP_MJ_DEVICE_CONTROL/n");
  break;
 }

 ntStatus = Irp->IoStatus.Status;
 IoCompleteRequest(Irp, IO_NO_INCREMENT);
 return ntStatus;
}

VOID ScSysInfoUnload(IN PDRIVER_OBJECT DriverObject)
{
 UNICODE_STRING dosDeviceName;
 RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
 IoDeleteSymbolicLink(&dosDeviceName);
 IoDeleteDevice(DriverObject->DeviceObject);
}

 

posted on 2005-03-31 07:59 Diviner 阅读(287) 评论(6)   编辑  收藏
href="http://blog.vckbase.com/bastet/Services/Pingback.aspx" rel="pingback"/>

评论

#  native.h 2005-03-31 08:00 七猫的垃圾箱
#pragma once

typedef struct _OBJECT_CREATE_INFORMATION {
ULONG Attributes;
HANDLE RootDirectory;
PVOID ParseContext;
KPROCESSOR_MODE ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;

typedef struct _OBJECT_HEADER {
LONG PointerCount;
union {
LONG HandleCount;
PSINGLE_LIST_ENTRY SEntry;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};

PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;


#define OBJECT_TO_OBJECT_HEADER( o ) /
CONTAINING_RECORD( (o), OBJECT_HEADER, Body )

#  头文件 2005-03-31 08:00 七猫的垃圾箱
#pragma once

#define FILE_DEVICE_SCSYSINFO 0x8000
#define SCSYSINFO_IOCTL_BASE 0x800


#define CTL_CODE_SCSYSINFO(i) CTL_CODE(FILE_DEVICE_SCSYSINFO, SCSYSINFO_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_SCSYSINFO_GETHANDLEOBJECT CTL_CODE_SCSYSINFO(0)
#define IOCTL_SCSYSINFO_TEST CTL_CODE_SCSYSINFO(1)


#define SCSYSINFO_DEVICE_NAME_WIN32 ".//ScSysInfo"

#  ob.h 2005-03-31 08:01 Diviner
#pragma once


typedef struct _OBJECT_DUMP_CONTROL {
PVOID Stream;
ULONG Detail;
} OB_DUMP_CONTROL, *POB_DUMP_CONTROL;

typedef VOID (*OB_DUMP_METHOD)(
IN PVOID Object,
IN POB_DUMP_CONTROL Control OPTIONAL
);

typedef enum _OB_OPEN_REASON {
ObCreateHandle,
ObOpenHandle,
ObDuplicateHandle,
ObInheritHandle,
ObMaxOpenReason
} OB_OPEN_REASON;

typedef struct _EPROCESS *PEPROCESS;
typedef VOID (*OB_OPEN_METHOD)(
IN OB_OPEN_REASON OpenReason,
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG HandleCount
);

typedef BOOLEAN (*OB_OKAYTOCLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN HANDLE Handle
);

typedef VOID (*OB_CLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG ProcessHandleCount,
IN ULONG SystemHandleCount
);

typedef VOID (*OB_DELETE_METHOD)(
IN PVOID Object
);






typedef CCHAR KPROCESSOR_MODE;
typedef NTSTATUS (*OB_PARSE_METHOD)(
IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object
);



typedef NTSTATUS (*OB_SECURITY_METHOD)(
IN PVOID Object,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG CapturedLength,
IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping
);

typedef NTSTATUS (*OB_QUERYNAME_METHOD)(
IN PVOID Object,
IN BOOLEAN HasObjectName,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength
);



typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length;
BOOLEAN UseDefaultObject;
BOOLEAN Reserved;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
BOOLEAN MaintainTypeList;
POOL_TYPE PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
OB_DUMP_METHOD DumpProcedure;
OB_OPEN_METHOD OpenProcedure;
OB_CLOSE_METHOD CloseProcedure;
OB_DELETE_METHOD DeleteProcedure;
OB_PARSE_METHOD ParseProcedure;
OB_SECURITY_METHOD SecurityProcedure;
OB_QUERYNAME_METHOD QueryNameProcedure;
OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

#  打开驱动部分 2005-03-31 08:01 Diviner
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

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

typedef CCHAR KPROCESSOR_MODE;

typedef enum _MODE {
KernelMode,
UserMode,
MaximumMode
} MODE;
typedef ULONG_PTR ERESOURCE_THREAD;
typedef struct _OWNER_ENTRY {
ERESOURCE_THREAD OwnerThread;
union {
LONG OwnerCount;
ULONG TableSize;
};

} OWNER_ENTRY, *POWNER_ENTRY;



typedef struct _ERESOURCE {
LIST_ENTRY SystemResourcesList;
POWNER_ENTRY OwnerTable;
SHORT ActiveCount;
USHORT Flag;
PKSEMAPHORE SharedWaiters;
PKEVENT ExclusiveWaiters;
OWNER_ENTRY OwnerThreads[2];
ULONG ContentionCount;
USHORT NumberOfSharedWaiters;
USHORT NumberOfExclusiveWaiters;
union {
PVOID Address;
ULONG_PTR CreatorBackTraceIndex;
};

KSPIN_LOCK SpinLock;
} ERESOURCE, *PERESOURCE;


typedef struct _OBJECT_TYPE {
ERESOURCE Mutex;
LIST_ENTRY TypeList;
UNICODE_STRING Name; // Copy from object header for convenience
PVOID DefaultObject;
ULONG Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
ULONG Key;
#endif //POOL_TAGGING
} OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT_TYPE *POBJECT_TYPE;

typedef double DOUBLE;

typedef struct _QUAD { // QUAD is for those times we want
double DoNotUseThisField; // an 8 byte aligned 8 byte long structure
} QUAD; // which is NOT really a floating point
// number. Use DOUBLE if you want an FP
// number.

#include "../ScSysInfo/ScSysInfo.h"
#include "../ScSysInfo/native.h"

struct ScHandleInfoOut
{
OBJECT_HEADER obj_hdr;
OBJECT_TYPE obj_type;
};

class MemDriver
{
public:
MemDriver(){_handle=NULL;}
~MemDriver(){if(_handle!=NULL)CloseHandle(_handle);}
bool InstallAndStart();
bool UnInstall();
ScHandleInfoOut *GetHeaderByHandle(HANDLE queryhandle);
public:
bool OpenDriver();
private:
HANDLE _handle;
};

extern MemDriver gMemDriver;

#include "Memdriver.h"
#include <WinSvc.h>
#include <winioctl.h>
#include <stdlib.h>
#include <stdio.h>

MemDriver gMemDriver;

#define DRIVERNAME "ScSysInfo"
#define DRIVERFILANAME "ScSysInfo.sys"

bool MemDriver::UnInstall()
{
SC_HANDLE scmHandle=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(scmHandle!=0)
{
SC_HANDLE handle=OpenService(scmHandle,DRIVERNAME,SERVICE_ALL_ACCESS);
if(handle!=0)
{
SERVICE_STATUS status;
ControlService(handle,SERVICE_CONTROL_STOP,&status);
DeleteService(handle);
CloseServiceHandle(handle);
}
CloseServiceHandle(scmHandle);
}
return true;
}

bool MemDriver::InstallAndStart()
{
char systemDir[MAX_PATH];
GetSystemDirectory(systemDir,MAX_PATH);
strcat(systemDir,"//drivers//");
strcat(systemDir,DRIVERFILANAME);
UnInstall();
SetFileAttributes(systemDir,0);
DeleteFile(systemDir);
if(CopyFile("D://HandleInfo//debug//ScSysInfo.sys",systemDir,FALSE)==0)
return false;

SC_HANDLE scmHandle=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(scmHandle==0)
return false;
SC_HANDLE newDriver=CreateService(scmHandle,DRIVERNAME,DRIVERNAME,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,systemDir,NULL,NULL,NULL,NULL,NULL);
if(newDriver!=NULL)
{
const char *args=NULL;
StartService(newDriver,0,&args);
CloseServiceHandle(newDriver);
}
CloseServiceHandle(scmHandle);
return true;
}

bool MemDriver::OpenDriver()
{
char drvName[MAX_PATH];
wsprintf(drvName,".//%s",DRIVERNAME);
_handle=CreateFile(drvName,GENERIC_ALL,0,NULL,OPEN_EXISTING,0,0);
if(_handle==INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}

ScHandleInfoOut *MemDriver::GetHeaderByHandle(HANDLE queryhandle)
{
static ScHandleInfoOut outbuf;
HANDLE inbuf=queryhandle;
DWORD retLen=sizeof(outbuf);
memset(&outbuf,0,sizeof(outbuf));
if(!DeviceIoControl(_handle,IOCTL_SCSYSINFO_GETHANDLEOBJECT,&inbuf,sizeof(inbuf),&outbuf,sizeof(outbuf),&retLen,NULL))
{
//glog.log(__FUNCTION__,"pa acquire error");
return 0;
}
return &outbuf;
}

#  re: 获取句柄的详细信息:(原代码) 2005-03-31 08:02 七猫的垃圾箱
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "socknative.h"
#include "MemDriver.h"

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

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

Winsock2Env gWinsock2Env;

int main(int argc, char *argv[])
{
gMemDriver.InstallAndStart();
gMemDriver.OpenDriver();
//HANDLE handle=CreateEvent(NULL,TRUE,TRUE,NULL);
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(5011);
int ret=bind((SOCKET)handle,(sockaddr*)&sa,sizeof(sa));

ScHandleInfoOut *pheader=gMemDriver.GetHeaderByHandle(handle);

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;
}
#  native.h 2005-03-31 08:00 七猫的垃圾箱
#pragma once

typedef struct _OBJECT_CREATE_INFORMATION {
ULONG Attributes;
HANDLE RootDirectory;
PVOID ParseContext;
KPROCESSOR_MODE ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;

typedef struct _OBJECT_HEADER {
LONG PointerCount;
union {
LONG HandleCount;
PSINGLE_LIST_ENTRY SEntry;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};

PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;


#define OBJECT_TO_OBJECT_HEADER( o ) /
CONTAINING_RECORD( (o), OBJECT_HEADER, Body )

#  头文件 2005-03-31 08:00 七猫的垃圾箱
#pragma once

#define FILE_DEVICE_SCSYSINFO 0x8000
#define SCSYSINFO_IOCTL_BASE 0x800


#define CTL_CODE_SCSYSINFO(i) CTL_CODE(FILE_DEVICE_SCSYSINFO, SCSYSINFO_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_SCSYSINFO_GETHANDLEOBJECT CTL_CODE_SCSYSINFO(0)
#define IOCTL_SCSYSINFO_TEST CTL_CODE_SCSYSINFO(1)


#define SCSYSINFO_DEVICE_NAME_WIN32 ".//ScSysInfo"

#  ob.h 2005-03-31 08:01 Diviner
#pragma once


typedef struct _OBJECT_DUMP_CONTROL {
PVOID Stream;
ULONG Detail;
} OB_DUMP_CONTROL, *POB_DUMP_CONTROL;

typedef VOID (*OB_DUMP_METHOD)(
IN PVOID Object,
IN POB_DUMP_CONTROL Control OPTIONAL
);

typedef enum _OB_OPEN_REASON {
ObCreateHandle,
ObOpenHandle,
ObDuplicateHandle,
ObInheritHandle,
ObMaxOpenReason
} OB_OPEN_REASON;

typedef struct _EPROCESS *PEPROCESS;
typedef VOID (*OB_OPEN_METHOD)(
IN OB_OPEN_REASON OpenReason,
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG HandleCount
);

typedef BOOLEAN (*OB_OKAYTOCLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN HANDLE Handle
);

typedef VOID (*OB_CLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG ProcessHandleCount,
IN ULONG SystemHandleCount
);

typedef VOID (*OB_DELETE_METHOD)(
IN PVOID Object
);






typedef CCHAR KPROCESSOR_MODE;
typedef NTSTATUS (*OB_PARSE_METHOD)(
IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object
);



typedef NTSTATUS (*OB_SECURITY_METHOD)(
IN PVOID Object,
IN SECURITY_OPERATION_CODE OperationCode,
IN PSECURITY_INFORMATION SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN OUT PULONG CapturedLength,
IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping
);

typedef NTSTATUS (*OB_QUERYNAME_METHOD)(
IN PVOID Object,
IN BOOLEAN HasObjectName,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength
);



typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length;
BOOLEAN UseDefaultObject;
BOOLEAN Reserved;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
BOOLEAN MaintainTypeList;
POOL_TYPE PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
OB_DUMP_METHOD DumpProcedure;
OB_OPEN_METHOD OpenProcedure;
OB_CLOSE_METHOD CloseProcedure;
OB_DELETE_METHOD DeleteProcedure;
OB_PARSE_METHOD ParseProcedure;
OB_SECURITY_METHOD SecurityProcedure;
OB_QUERYNAME_METHOD QueryNameProcedure;
OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

#  打开驱动部分 2005-03-31 08:01 Diviner
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

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

typedef CCHAR KPROCESSOR_MODE;

typedef enum _MODE {
KernelMode,
UserMode,
MaximumMode
} MODE;
typedef ULONG_PTR ERESOURCE_THREAD;
typedef struct _OWNER_ENTRY {
ERESOURCE_THREAD OwnerThread;
union {
LONG OwnerCount;
ULONG TableSize;
};

} OWNER_ENTRY, *POWNER_ENTRY;



typedef struct _ERESOURCE {
LIST_ENTRY SystemResourcesList;
POWNER_ENTRY OwnerTable;
SHORT ActiveCount;
USHORT Flag;
PKSEMAPHORE SharedWaiters;
PKEVENT ExclusiveWaiters;
OWNER_ENTRY OwnerThreads[2];
ULONG ContentionCount;
USHORT NumberOfSharedWaiters;
USHORT NumberOfExclusiveWaiters;
union {
PVOID Address;
ULONG_PTR CreatorBackTraceIndex;
};

KSPIN_LOCK SpinLock;
} ERESOURCE, *PERESOURCE;


typedef struct _OBJECT_TYPE {
ERESOURCE Mutex;
LIST_ENTRY TypeList;
UNICODE_STRING Name; // Copy from object header for convenience
PVOID DefaultObject;
ULONG Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
ULONG Key;
#endif //POOL_TAGGING
} OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT_TYPE *POBJECT_TYPE;

typedef double DOUBLE;

typedef struct _QUAD { // QUAD is for those times we want
double DoNotUseThisField; // an 8 byte aligned 8 byte long structure
} QUAD; // which is NOT really a floating point
// number. Use DOUBLE if you want an FP
// number.

#include "../ScSysInfo/ScSysInfo.h"
#include "../ScSysInfo/native.h"

struct ScHandleInfoOut
{
OBJECT_HEADER obj_hdr;
OBJECT_TYPE obj_type;
};

class MemDriver
{
public:
MemDriver(){_handle=NULL;}
~MemDriver(){if(_handle!=NULL)CloseHandle(_handle);}
bool InstallAndStart();
bool UnInstall();
ScHandleInfoOut *GetHeaderByHandle(HANDLE queryhandle);
public:
bool OpenDriver();
private:
HANDLE _handle;
};

extern MemDriver gMemDriver;

#include "Memdriver.h"
#include <WinSvc.h>
#include <winioctl.h>
#include <stdlib.h>
#include <stdio.h>

MemDriver gMemDriver;

#define DRIVERNAME "ScSysInfo"
#define DRIVERFILANAME "ScSysInfo.sys"

bool MemDriver::UnInstall()
{
SC_HANDLE scmHandle=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(scmHandle!=0)
{
SC_HANDLE handle=OpenService(scmHandle,DRIVERNAME,SERVICE_ALL_ACCESS);
if(handle!=0)
{
SERVICE_STATUS status;
ControlService(handle,SERVICE_CONTROL_STOP,&status);
DeleteService(handle);
CloseServiceHandle(handle);
}
CloseServiceHandle(scmHandle);
}
return true;
}

bool MemDriver::InstallAndStart()
{
char systemDir[MAX_PATH];
GetSystemDirectory(systemDir,MAX_PATH);
strcat(systemDir,"//drivers//");
strcat(systemDir,DRIVERFILANAME);
UnInstall();
SetFileAttributes(systemDir,0);
DeleteFile(systemDir);
if(CopyFile("D://HandleInfo//debug//ScSysInfo.sys",systemDir,FALSE)==0)
return false;

SC_HANDLE scmHandle=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(scmHandle==0)
return false;
SC_HANDLE newDriver=CreateService(scmHandle,DRIVERNAME,DRIVERNAME,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,systemDir,NULL,NULL,NULL,NULL,NULL);
if(newDriver!=NULL)
{
const char *args=NULL;
StartService(newDriver,0,&args);
CloseServiceHandle(newDriver);
}
CloseServiceHandle(scmHandle);
return true;
}

bool MemDriver::OpenDriver()
{
char drvName[MAX_PATH];
wsprintf(drvName,".//%s",DRIVERNAME);
_handle=CreateFile(drvName,GENERIC_ALL,0,NULL,OPEN_EXISTING,0,0);
if(_handle==INVALID_HANDLE_VALUE)
{
return false;
}
return true;
}

ScHandleInfoOut *MemDriver::GetHeaderByHandle(HANDLE queryhandle)
{
static ScHandleInfoOut outbuf;
HANDLE inbuf=queryhandle;
DWORD retLen=sizeof(outbuf);
memset(&outbuf,0,sizeof(outbuf));
if(!DeviceIoControl(_handle,IOCTL_SCSYSINFO_GETHANDLEOBJECT,&inbuf,sizeof(inbuf),&outbuf,sizeof(outbuf),&retLen,NULL))
{
//glog.log(__FUNCTION__,"pa acquire error");
return 0;
}
return &outbuf;
}

#  re: 获取句柄的详细信息:(原代码) 2005-03-31 08:02 七猫的垃圾箱
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "socknative.h"
#include "MemDriver.h"

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

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

Winsock2Env gWinsock2Env;

int main(int argc, char *argv[])
{
gMemDriver.InstallAndStart();
gMemDriver.OpenDriver();
//HANDLE handle=CreateEvent(NULL,TRUE,TRUE,NULL);
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(5011);
int ret=bind((SOCKET)handle,(sockaddr*)&sa,sizeof(sa));

ScHandleInfoOut *pheader=gMemDriver.GetHeaderByHandle(handle);

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;
}
掌握webspy技术:网页句柄获取与应用 SPY++是Microsoft提供的一个程序设计工具,它用于监视Windows消息传递、图形界面和句柄,使得开发者可以深入探索和理解应用程序的运行时行为。界面主要由菜单栏、工具栏、窗口列表、消息窗口和详细信息窗口组成。SPY++的主要功能包括:消息监视:实时显示应用程序之间交换的消息。窗口浏览:查看和操作系统中的所有窗口。图形对象信息:显示有关各种图形对象(如控件、按钮、文本框等)的详细信息。进程信息:获取当前运行的进程列表及其属性。控制台输出。 阅读详情

相关推荐

对比学习损失函数避坑指南:为什么你的自监督模型不收敛?

本文深入剖析对比学习损失函数中的关键陷阱,揭示自监督模型不收敛的根本原因。通过分析温度系数选择、负样本采样策略和特征归一化等核心因素,提供实用解决方案。实验数据表明,正确设置温度系数τ(建议0.07起)可提升30%性能,而MoCo风格的负样本队列比SimCLR方案在小批量时准确率高6-8%。

nokia的博客 922

windows 句柄

windows中,句柄非常常见。如文件句柄,事件句柄,线程句柄,进程句柄等等。那么ju

byte4096的专栏 763

杭电计算机组成原理课程设计-实验七-寄存器堆设计实验

寄存器堆实验实验原理实验内容模块功能说明模块逻辑引脚图寄存器堆模块代码REG模块测试用例REG-ALU测试用例实验结果记录 寄存器堆实验结果及分析ALU_REG运算器模块实验结果及分析探索与思考 实验原理   32×32位的寄存器堆模块示意图如图所示,含有32个寄存器,每个寄存器32位。该寄存器堆具有A和B两个读端口,分别由 5 位的寄存器编号 R_Addr_A 和 R_Addr_B 来寻址 2 个寄存器,读出的数据则由 R_Data_A(32 位)和R_Data_B(32 位)输出。读访问时,没有使能或者

HDU-整蛊小子-⏰☂️/蚂蚁集团研发工程师 1万+

VC 各种情况下的窗口句柄的获取

<br />AfxGetMainWnd<br /> <br />AfxGetMainWnd获取自身窗口句柄<br />HWND hWnd = AfxGetMainWnd()->m_hWnd;<br /><br />GetTopWindow<br />函数功能:该函数检查与特定父窗口相联的子窗口z序(Z序:垂直屏幕的方向,即叠放次序),并返回在z序顶部的子窗口的句柄。<br />函数原型:HWND GetTopWindow(HWND hWnd);<br />参数:<br />  hWnd:被查序的父窗口的句柄

luheng2006的专栏 6603

AI视频生成技术研究报告:现状、挑战与展望

AI 视频生成技术概述:介绍 AI 视频生成技术的基本概念,回顾其发展历程,从早期依赖图像拼接的简单生成方式,到如今融合多种先进技术的复杂模型应用,梳理技术演进的关键节点和重要突破。同时,分析该技术在当前阶段的特点,包括生成视频的质量、速度、灵活性等方面,以及与传统视频制作方式的差异,阐述 AI 视频生成技术如何改变视频创作的流程和模式。技术实现路径分析。

daqsdfas的博客 4574

大模型蒸馏实战:让小模型获得大模型的知识

本文为初学者提供了一份大模型蒸馏实战指南,通过情感分析任务演示如何将 BERT 的知识迁移到轻量级 TextCNN。文章结合原理图解与 PyTorch 代码,详解软标签生成、温度调节和双损失设计等核心概念,并对比蒸馏前后的性能差异(准确率提升 4.6%,推理速度达 1200 句 / 秒)。内含可直接运行的代码片段、训练技巧及常见问题解答,助力开发者快速掌握模型压缩核心技术,实现工业级部署效率。适合 NLP 入门者学习实践。

1368

得到进程列表的例子代码

#include #include #include //  Forward declarations:BOOL GetProcessList( );BOOL ListProcessModules( DWORD dwPID );BOOL ListProcessThreads( DWORD dwOwnerPID );void printError( TCHAR* msg );void main( )

vingo888的专栏 617

MATLAB - 利用非线性模型预测控制(Nonlinear MPC)来控制四旋翼飞行器

本示例展示了如何利用非线性模型预测控制(MPC)为四旋翼飞行器设计一个跟踪轨迹的控制器。

机器人控制与仿真应用 4432

【python句柄获取】——简单明了的获取窗口句柄,并使用句柄操作获取相应内容(全网最详细)

点个赞留个关注吧!! 所使用模块 import sys import win32gui import win32con 通过标题名称获取句柄 #通过窗口标题获取句柄 hld = win32gui.FindWindow(None,u"此电脑") 通过句柄获得标题 # 通过句柄获得标题 def get_title(hwnd): title = win32gui.GetWindowText(hwnd) print('窗口标题:%s' % (title)) retu...

₰₯₮ 的博客 17万+

配置 SAP Web Dispatcher 的实战指南:打通 SAP Fiori、SAP Gateway 与前端系统的关键一跳

SAP Web Dispatcher 在 Fiori 架构中扮演关键角色,作为统一入口处理 HTTPS 请求、实现安全代理和流量分发。它将分散在不同系统的访问路径统一收口,解决浏览器同源策略限制,集中管理 HTTPS 终止和客户端信息传递。典型配置中,Web Dispatcher 监听 443 端口,根据路径将 OData 请求转发至 Gateway 系统,静态资源请求送至前端服务器。SSL 相关配置(如 PSE 文件)确保安全通信,而路由规则(wdisp/system_xx)决定请求转发目标。实施时需注意

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 102

自动驾驶感知新方案:YOLOv13多模态(RGB+LiDAR+热成像)融合实战

YOLOv13的RGB+LiDAR+热成像多模态融合方案,解决了自动驾驶感知的鲁棒性问题,通过跨模态特征互补和注意力融合,实现了复杂场景下的高精度检测。本文从架构设计、数据预处理、核心模块实现到车载部署,完成了全流程实战。动态模态权重:根据场景自动调整各模态的权重(如黑夜场景提升热成像权重);端到端3D检测:直接从原始点云与图像进行3D检测,减少预处理步骤;轻量化优化:针对车载设备进一步剪枝量化,提升推理速度。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 534

窗口句柄 小知识

查找的 无论类名为啥,都不要紧,只要窗口名是title就可以。是不同的,FindWindow(L"",L"title");查找的是类名为“”, 窗口名为title的窗口。GetTopWindow函数检查与特定父窗口相联的子窗口z序,并返回在z序顶部的子窗口的句柄。将创建指定窗口的线程引入前台并激活窗口。如果函数成功,返回值为在Z序顶部的子窗口句柄。如果指定的窗口无子窗口,返回值为NULL。:被查序的父窗口的句柄。系统为创建前台窗口的线程分配的优先级略高于其他线程的优先级。获得指定窗口的第一个子窗口的句柄。

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 4473

使用 Python 爬取 Wikipedia 数据:抓取百科条目及其内容

维基百科的 API 提供了一些方便的接口,通过这些接口,我们可以轻松获取到维基百科的条目、类别、图片和其他相关信息。维基百科的 API 主要是基于 HTTP 请求的,通过向特定的 URL 发送 GET 请求来获取信息。:获取指定条目的内容。在本博客中,我们介绍了如何使用 Python 爬取维基百科的条目数据。通过使用 Wikipedia API 和网页抓取技术,我们能够高效地获取条目内容,并将其存储和分析。希望本篇教程能帮助你深入理解如何抓取和处理维基百科的数据。

2201_76125261的博客 475

获取句柄的详细信息:(原代码) http://blog.vckbase.com/bastet/archive/2005/03/31/4244.html

一、驱动部分extern "C"{#include }#include "ScSysInfo.h"extern "C"{#include "native.h"#include "../TestHandle/ob.h"}#if 1#define dprintf DbgPrint#else#define dprintf#endif#define kprintf DbgPrint#d

www.pingfi.com 1302

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

什么是句柄,如何获取句柄

句柄是一个用来标识对象或者项目的标识符,它可以是一个整数、指针或其他数据类型,用于在操作系统或应用程序中唯一地标识某个对象。这些对象可以包括窗口、文件、进程、控件、位图、GDI对象(如画笔、画刷等)等。句柄的引入主要是为了解决内存管理机制中虚拟地址变动的问题,使得系统能够记录和管理数据地址的变更。

2301_80019403的博客 5103

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Qt获取当前窗口句柄/获取窗口中控件的句柄

1. 句柄是什么 大家可以看这篇文章,讲的比较详细。https://blog.youkuaiyun.com/wenzhou1219/article/details/17659485 2. Qt如何获取句柄 winId()函数。(Qt5里面) 如果想获取Qt窗口的句柄用于显示图片;且看我操作 HWND m_hwndDisplay = (HWND)this->winId();//获取当前this窗口的句柄 MyCamera->Display(m_hwndDisplay);//调用你camera的di

qq_41951658的博客 2万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

按键精灵通过句柄获取窗口坐标_学会用按键精灵获取子窗口句柄

有道云笔记下的这两个子窗口的类名、标题都是一样的。hwnd=Plugin.Window.find(0,"有道云笔记Haiye")HwndEx=Plugin.Window.findex(hwnd,0,"Popo.UI.Controls.Class.SkinSplitter",0)上面的代码只能找到第一个类名为Popo.UI.Controls.Class.SkinSplitter的子...

weixin_39600837的博客 3277

C++ 获取窗口句柄

1、使用FindWindow函数获取窗口句柄 示例:使用FindWindow函数获取窗口句柄,然后获得窗口大小和标题,并且移动窗口到指定位置。 [html] view plaincopy #include Windows.h>   #include stdio.h>   #include string.h>   #include iostre

ArtLife 2万+

MFC 窗口句柄获取

句柄获取方法(获取该窗口的句柄后,即可向该窗口类类发送消息、处理程序):0。获取所在类窗口的句柄: this->m_hwnd 1。主窗口的句柄: 无论在主窗口类内,还是子窗口类内,获取主窗口句柄的方法: AfxGetMainWnd()->m_hWnd, 如:::SendMessage(AfxGetMainWnd()->m_hWnd , WM_MY_DOSOME , 0 ,(LPARAM)

4万+

获取窗口句柄

获取父窗口句柄 HWND hWnddlg = AfxGetMainWnd()->m_hWnd; //主窗口句柄 或者 HWND hWnddlg = this->m_hWnd; //主窗口句柄 获取子窗口句柄 如果子窗口是控件,并有控件ID号, 则如下获取其子窗口句柄 HWND hwnd=::GetDlgItem(hWnddlg,IDC_BUTTON_SETUPBLOCK); //子窗...

bmjhappy的专栏 2786

如何获取窗口内文本框的句柄

一  背景   某种情况下,需要从某窗体获取该窗体文本框内的内容,发现文本框并没有标题名,无法获取文本框控件的句柄。接下来,我将介绍我获取所需文本框控件句柄方法。 二  使用Spy++获取   如图,打开Spy++可以直接获取到“测试窗口”的所有控件句柄。        三  EnumChildWindows遍历所有句柄   一般窗体内文本框前面都有一个lable控件来标注,比如“测试...

王小壮的博客 8623

关于在DLL中获取主调用窗口的句柄

近来在弄远程DLL注入,在DLL中创建了窗口,因某种需要,需获取宿主窗口的句柄,找了n多资料都没有很好的解决办法,然后找到如下一篇文章:通过进程ID获得该进程主窗口的句柄     一个进程可以拥有很多主窗口,也可以不拥有主窗口,所以这样的函数是不存在的,所幸的是,相反的函数是有的。所以我们可以调用EnumWindows来判断所有的窗口是否属于这个进程。typedef struct tagW

柴门的编程学习基地 8533

mfc获取窗口句柄

本节为VC中常用的文档类,视图类,框架类,应用程序类,自定义类中获取其它四个类的方法:  GET App     AfxGetInstanceHandle()     AfxGetApp()  GET Frame->View->Document      SDI   AfxGetMainWnd() -> GetActiveView() -> GetDocument()      MDI

zhengliuguo的专栏 3921

win32 获取窗口句柄的方法

第一种方法是根据窗口句柄值获取窗口句柄 使用spy++获取指定窗口的窗口句柄值,因为句柄值是16进制数,所以前面加0x,然后进行强制转换为HWND类型。 HWND hWnd=(HWND)0x00280726;   第二种方法是使用FindWindow或者FindWindowEx根据窗口类名和窗口标题找到相应的窗口句柄 HWND FindWindow(LPCTSTR lpClassName

享受开发技术,享受计算机科学 8960

MFC中获取窗口句柄及相关函数

一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,无论是多文档还是单文档,都存在指针和句柄获取和操作问题。本文中将针对各类句柄的获得、指针的获得以及MFC中常见应用进行阐述并举例。 本文内容索引: ========================================================= MFC中获取常

xiaoyun8822的专栏 2万+
上一篇: WINDOWS2k内存管理
下一篇: CriticalSection原代码
pll621
博客等级 码龄25年 27粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值