int( (LONG)(LONG_PTR)&(((type *)0)->field))的最好解释

本文详细解释了ANSIC标准下如何利用NULL指针来计算结构体成员的偏移量,该方法避免了实例化结构体对象并在编译期完成计算,从而避免运行时的负担。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 http://blog.youkuaiyun.com/yzslhawk/article/details/5441036

 

在优快云上查到的。
ANSI C标准允许值为0的常量被强制转换成任何一种类型的指针,
并且转换结果是一个NULL指针,因此((type *)0)的结果就是一个类型为type *的NULL指针。
如果利用这个NULL指针来访问type的成员当然是非法的,
但&( ((type *)0)->field )的意图仅仅是计算field字段的地址。
聪明的编译器根本就不生成访问type的代码,
而仅仅是根据type的内存布局和结构体实例首址在编译期计算这个(常量)地址,
这样就完全避免了通过NULL指针访问内存的问题。
又因为首址为0,所以这个地址的值就是字段相对于结构体基址的偏移。
以上方法避免了实例化一个type对象,并且求值在编译期进行,没有运行期负担。

 

源代码: filter.cpp 源文件: #include "filter.h" #include "ioctl.h" ///global var wddm_filter_t __gbl_wddm_filter; #define DEV_NAME L"\\Device\\WddmFilterCtrlDevice" #define DOS_NAME L"\\DosDevices\\WddmFilterCtrlDevice" ///// static NTSTATUS create_ctrl_device() { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT devObj; UNICODE_STRING dev_name; UNICODE_STRING dos_name; RtlInitUnicodeString(&dev_name, DEV_NAME); RtlInitUnicodeString(&dos_name, DOS_NAME); status = IoCreateDevice( wf->driver_object, 0, &dev_name, //dev name FILE_DEVICE_VIDEO, FILE_DEVICE_SECURE_OPEN, FALSE, &devObj); if (!NT_SUCCESS(status)) { DPT("IoCreateDevice err=0x%X\n", status ); return status; } status = IoCreateSymbolicLink(&dos_name, &dev_name); if (!NT_SUCCESS(status)) { DPT("IoCreateSymbolicLink err=0x%X\n", status ); IoDeleteDevice(devObj); return status; } // attach wf->dxgkrnl_nextDevice = IoAttachDeviceToDeviceStack(devObj, wf->dxgkrnl_pdoDevice); if (!wf->dxgkrnl_nextDevice) { DPT("IoAttachDeviceToDeviceStack error.\n"); IoDeleteDevice(devObj); IoDeleteSymbolicLink(&dos_name); return STATUS_NOT_FOUND; } devObj->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO | DO_DIRECT_IO; wf->ctrl_devobj = devObj; ///// return status; } NTSTATUS create_wddm_filter_ctrl_device(PDRIVER_OBJECT drvObj ) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING drvPath; UNICODE_STRING drvName; RtlInitUnicodeString(&drvPath, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\SERVICES\\DXGKrnl"); RtlInitUnicodeString(&drvName, L"\\Device\\Dxgkrnl"); // RtlZeroMemory(wf, sizeof(wddm_filter_t)); wf->driver_object = drvObj; KeInitializeSpinLock(&wf->spin_lock); InitializeListHead(&wf->vidpn_if_head); InitializeListHead(&wf->topology_if_head); //����dxgkrnl.sys���� status = ZwLoadDriver(&drvPath); if (!NT_SUCCESS(status)) { if (status != STATUS_IMAGE_ALREADY_LOADED) { DPT("ZwLoadDriver error st=0x%X\n", status ); return status; } } status = IoGetDeviceObjectPointer(&drvName, FILE_ALL_ACCESS, &wf->dxgkrnl_fileobj, &wf->dxgkrnl_pdoDevice); if (!NT_SUCCESS(status)) { DPT("IoGetDeviceObjectPointer Get DxGkrnl err=0x%X\n", status ); return status; } KEVENT evt; IO_STATUS_BLOCK ioStatus; KeInitializeEvent(&evt, NotificationEvent, FALSE); PIRP pIrp = IoBuildDeviceIoControlRequest( IOCTL_VIDEO_DDI_FUNC_REGISTER, //0x23003F , dxgkrnl.sys ����ע�ắ�� wf->dxgkrnl_pdoDevice, NULL, 0, &wf->dxgkrnl_dpiInit, sizeof(PDXGKRNL_DPIINITIALIZE), TRUE, // IRP_MJ_INTERNAL_DEVICE_CONTROL &evt, &ioStatus); if (!pIrp) { DPT("IoBuildDeviceIoControlRequest return NULL.\n"); ObDereferenceObject(wf->dxgkrnl_fileobj); return STATUS_NO_MEMORY; } status = IoCallDriver(wf->dxgkrnl_pdoDevice, pIrp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&evt, Executive, KernelMode, FALSE, NULL); status = ioStatus.Status; } if (!wf->dxgkrnl_dpiInit) {// DPT("Can not Load PDXGKRNL_DPIINITIALIZE function address. st=0x%X\n", status ); ObDereferenceObject(wf->dxgkrnl_fileobj); return STATUS_NOT_FOUND; } ///create filter device status = create_ctrl_device(); if (!NT_SUCCESS(status)) { ObDereferenceObject(wf->dxgkrnl_fileobj); return status; } //// return status; } NTSTATUS log_event(PUNICODE_STRING str) { NTSTATUS status = STATUS_SUCCESS; return status; } filter.h 源文件: #pragma once #include <ntddk.h> #include <wdm.h> #include <ntstrsafe.h> #include <ntddvdeo.h> #include <initguid.h> #include <Dispmprt.h> #include <d3dkmdt.h> //////////////////////////////////////////////////////////// #ifdef DBG #define DPT DbgPrint #else #define DPT // #endif ///����VIDPN�����豸ID�� #define VIDPN_CHILD_UDID 0x667b0099 ///////// ///0x23003F , dxgkrnl.sys ����ע�ắ�� DXGKRNL_DPIINITIALIZE #define IOCTL_VIDEO_DDI_FUNC_REGISTER \ CTL_CODE( FILE_DEVICE_VIDEO, 0xF, METHOD_NEITHER, FILE_ANY_ACCESS ) typedef __checkReturn NTSTATUS DXGKRNL_DPIINITIALIZE( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath, DRIVER_INITIALIZATION_DATA* DriverInitData ); typedef DXGKRNL_DPIINITIALIZE* PDXGKRNL_DPIINITIALIZE; /////// struct vidpn_target_id { LONG num; D3DDDI_VIDEO_PRESENT_TARGET_ID ids[1]; }; struct vidpn_paths_t { LONG num_paths; vidpn_target_id* target_paths[1]; }; struct vidpn_intf_t { LIST_ENTRY list; /// D3DKMDT_HVIDPN hVidPn; DXGK_VIDPN_INTERFACE vidpn_if, mod_vidpn_if; //// D3DKMDT_HVIDPNTOPOLOGY hTopology; DXGK_VIDPNTOPOLOGY_INTERFACE topology_if, mod_topology_if; vidpn_paths_t* paths; //// }; struct wddm_filter_t { PDRIVER_OBJECT driver_object; //// PDEVICE_OBJECT ctrl_devobj; //// PFILE_OBJECT dxgkrnl_fileobj; PDEVICE_OBJECT dxgkrnl_pdoDevice; PDEVICE_OBJECT dxgkrnl_nextDevice; /// PDXGKRNL_DPIINITIALIZE dxgkrnl_dpiInit; /// KSPIN_LOCK spin_lock; KIRQL kirql; LIST_ENTRY vidpn_if_head; LIST_ENTRY topology_if_head; //// DRIVER_INITIALIZATION_DATA orgDpiFunc; //ԭʼ��DRIVER_INITIALIZATION_DATA ULONG vidpn_source_count; ULONG vidpn_target_count; DXGKRNL_INTERFACE DxgkInterface; }; extern wddm_filter_t __gbl_wddm_filter; #define wf (&(__gbl_wddm_filter)) #define wf_lock() KeAcquireSpinLock(&wf->spin_lock, &wf->kirql); #define wf_unlock() KeReleaseSpinLock(&wf->spin_lock, wf->kirql); ////////////////function NTSTATUS create_wddm_filter_ctrl_device(PDRIVER_OBJECT drvObj); inline NTSTATUS call_lower_driver(PIRP irp) { IoSkipCurrentIrpStackLocation(irp); return IoCallDriver(wf->dxgkrnl_nextDevice, irp); } NTSTATUS DpiInitialize( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath, DRIVER_INITIALIZATION_DATA* DriverInitData); NTSTATUS DxgkDdiEnumVidPnCofuncModality(CONST HANDLE hAdapter, CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg); NTSTATUS DxgkDdiIsSupportedVidPn( IN_CONST_HANDLE hAdapter, INOUT_PDXGKARG_ISSUPPORTEDVIDPN pIsSupportedVidPn); NTSTATUS DxgkDdiCommitVidPn( IN_CONST_HANDLE hAdapter, IN_CONST_PDXGKARG_COMMITVIDPN_CONST pCommitVidPn); NTSTATUS DxgkDdiSetVidPnSourceVisibility( IN_CONST_HANDLE hAdapter, IN_CONST_PDXGKARG_SETVIDPNSOURCEVISIBILITY pSetVidPnSourceVisibility); NTSTATUS APIENTRY DxgkDdiSetVidPnSourceAddress( const HANDLE hAdapter, const DXGKARG_SETVIDPNSOURCEADDRESS *pSetVidPnSourceAddress); main.cpp: /// by fanxiushu 2018-08-29 #include "filter.h" static NTSTATUS commonDispatch(PDEVICE_OBJECT devObj, PIRP irp) { PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(irp); switch (irpStack->MajorFunction) { case IRP_MJ_CREATE: break; case IRP_MJ_CLEANUP: break; case IRP_MJ_CLOSE: break; case IRP_MJ_INTERNAL_DEVICE_CONTROL: if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_VIDEO_DDI_FUNC_REGISTER) { ///////�Կ�������DxgkInitialize�����е��� IOCTL��ȡdxgkrnl.sys��ע��ص�����������hook�˴�����ȡ���Կ������ṩ������DDI���� irp->IoStatus.Information = 0; irp->IoStatus.Status = STATUS_SUCCESS; ///�����ǵĻص��������ظ��Կ�����. if (irp->UserBuffer) { /// irp->IoStatus.Information = sizeof(PDXGKRNL_DPIINITIALIZE); *((PDXGKRNL_DPIINITIALIZE*)irp->UserBuffer) = DpiInitialize; } ///// IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_SUCCESS; /// } break; } //// return call_lower_driver(irp); } extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; for (UCHAR i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i) { DriverObject->MajorFunction[i] = commonDispatch; } status = create_wddm_filter_ctrl_device(DriverObject); /// DriverObject->DriverUnload = NULL; ///������ж�� return status; } miniport.cpp 源文件: #include "filter.h" static NTSTATUS DxgkDdiAddDevice( IN_CONST_PDEVICE_OBJECT PhysicalDeviceObject, OUT PVOID *MiniportDeviceContext) { DPT("Hook: DxgkDdiAddDevice. \n"); return wf->orgDpiFunc.DxgkDdiAddDevice(PhysicalDeviceObject, MiniportDeviceContext); } static NTSTATUS DxgkDdiRemoveDevice(IN PVOID MiniportDeviceContext) { DPT("Hook: DxgkDdiRemoveDevice\n"); return wf->orgDpiFunc.DxgkDdiRemoveDevice(MiniportDeviceContext); } ////HOOK DxgkCbQueryVidPnInterface, �ҹ�DxgkCbQueryVidPnInterface��ص����лص�������������ƭԭʼ������Target Source �� Path ��ѯ. //��ѯ����·�������Ұ���SourceId���� static vidpn_paths_t* enum_all_paths(IN_CONST_D3DKMDT_HVIDPNTOPOLOGY topology_handle, const DXGK_VIDPNTOPOLOGY_INTERFACE* topology_if ) { NTSTATUS status = STATUS_SUCCESS; SIZE_T num = 0; status = topology_if->pfnGetNumPaths(topology_handle, &num); if (num <= 0) { return NULL; } LONG sz = sizeof(vidpn_paths_t) + sizeof(vidpn_target_id*)*wf->vidpn_source_count + wf->vidpn_source_count*( sizeof(vidpn_target_id) + num* sizeof(D3DDDI_VIDEO_PRESENT_TARGET_ID) ); vidpn_paths_t* p = (vidpn_paths_t*)ExAllocatePoolWithTag(NonPagedPool, sz, 'FXSD'); if (!p)return NULL; /// RtlZeroMemory(p, sz); //// p->num_paths = num; CHAR* ptr = (CHAR*)p + sizeof(vidpn_paths_t) + sizeof(vidpn_target_id*)*wf->vidpn_source_count; for (INT i = 0; i < wf->vidpn_source_count; ++i) { p->target_paths[i] = (vidpn_target_id*)( ptr + i* ( sizeof(vidpn_target_id) + num * sizeof(D3DDDI_VIDEO_PRESENT_TARGET_ID) ) ); } ////// CONST D3DKMDT_VIDPN_PRESENT_PATH *curr_path_info; CONST D3DKMDT_VIDPN_PRESENT_PATH *next_path_info; status = topology_if->pfnAcquireFirstPathInfo(topology_handle, &curr_path_info); if (status == STATUS_GRAPHICS_DATASET_IS_EMPTY) { ExFreePool(p); return NULL; } else if (!NT_SUCCESS(status)) { ExFreePool(p); return NULL; } ///// INT t_num = 0; do { /// UINT sid = curr_path_info->VidPnSourceId; UINT did = curr_path_info->VidPnTargetId; if ( sid < (UINT)wf->vidpn_source_count) { /// if (did != VIDPN_CHILD_UDID) {// skip my target path /// LONG n = p->target_paths[sid]->num; p->target_paths[sid]->num++; p->target_paths[sid]->ids[n] = did; /// t_num++; } /// } ///next status = topology_if->pfnAcquireNextPathInfo(topology_handle, curr_path_info, &next_path_info); topology_if->pfnReleasePathInfo(topology_handle, curr_path_info); curr_path_info = next_path_info; if (status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET) { /// end curr_path_info = NULL; // DPT("pfnAcquireNextPathInfo no more data.\n"); break; } else if (!NT_SUCCESS(status)) { curr_path_info = NULL; DPT("pfnAcquireNextPathInfo err=0x%X\n", status); break; } //// } while (TRUE); p->num_paths = t_num; /// return p; } NTSTATUS pfnGetNumPaths( IN_CONST_D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, OUT_PSIZE_T pNumPaths) { NTSTATUS status = STATUS_INVALID_PARAMETER; DXGKDDI_VIDPNTOPOLOGY_GETNUMPATHS ptr_pfnGetNumPaths = NULL; wf_lock(); for (PLIST_ENTRY entry = wf->topology_if_head.Flink; entry != &wf->topology_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (intf->hTopology == hVidPnTopology) { ptr_pfnGetNumPaths = intf->topology_if.pfnGetNumPaths; if (intf->paths && pNumPaths) { *pNumPaths = intf->paths->num_paths; wf_unlock(); DPT("pfnGetNumPaths Cache called num=%d\n", *pNumPaths); return STATUS_SUCCESS; } break; } } wf_unlock(); ///// if (!ptr_pfnGetNumPaths) { return STATUS_INVALID_PARAMETER; } status = ptr_pfnGetNumPaths(hVidPnTopology, pNumPaths); DPT("pfnGetNumPaths called num=%d\n", *pNumPaths ); return status; } NTSTATUS pfnGetNumPathsFromSource( IN_CONST_D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, IN_CONST_D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, OUT_PSIZE_T pNumPathsFromSource) { NTSTATUS status = STATUS_SUCCESS; DXGKDDI_VIDPNTOPOLOGY_GETNUMPATHSFROMSOURCE ptr_pfnGetNumPathsFromSource = NULL; wf_lock(); for (PLIST_ENTRY entry = wf->topology_if_head.Flink; entry != &wf->topology_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (intf->hTopology == hVidPnTopology) { ptr_pfnGetNumPathsFromSource = intf->topology_if.pfnGetNumPathsFromSource; if (intf->paths && pNumPathsFromSource && VidPnSourceId < wf->vidpn_source_count ) { *pNumPathsFromSource = intf->paths->target_paths[VidPnSourceId]->num; wf_unlock(); DPT("pfnGetNumPathsFromSource Cache called. num=%d\n", *pNumPathsFromSource); return STATUS_SUCCESS; } break; } } wf_unlock(); //// if (!ptr_pfnGetNumPathsFromSource) { return STATUS_INVALID_PARAMETER; } status = ptr_pfnGetNumPathsFromSource(hVidPnTopology, VidPnSourceId, pNumPathsFromSource); DPT("pfnGetNumPathsFromSource called. num=%d\n", *pNumPathsFromSource); return status; } NTSTATUS pfnEnumPathTargetsFromSource( IN_CONST_D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, IN_CONST_D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, IN_CONST_D3DKMDT_VIDPN_PRESENT_PATH_INDEX VidPnPresentPathIndex, OUT_PD3DDDI_VIDEO_PRESENT_TARGET_ID pVidPnTargetId) { NTSTATUS status = STATUS_SUCCESS; DXGKDDI_VIDPNTOPOLOGY_ENUMPATHTARGETSFROMSOURCE ptr_pfnEnumPathTargetsFromSource = NULL; wf_lock(); for (PLIST_ENTRY entry = wf->topology_if_head.Flink; entry != &wf->topology_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (intf->hTopology == hVidPnTopology) { ptr_pfnEnumPathTargetsFromSource = intf->topology_if.pfnEnumPathTargetsFromSource; if (intf->paths && VidPnSourceId < wf->vidpn_source_count && pVidPnTargetId ) { if (VidPnPresentPathIndex >= intf->paths->target_paths[VidPnSourceId]->num) { wf_unlock(); DPT("VidPnPresentPathIndex >= intf->paths->target_path_num[VidPnSourceId]\n"); return STATUS_INVALID_PARAMETER; } *pVidPnTargetId = intf->paths->target_paths[VidPnSourceId]->ids[VidPnPresentPathIndex]; //// wf_unlock(); DPT("pfnEnumPathTargetsFromSource Cache called sourceId=%d, index=%d, targetid=%d, st=0x%X\n", VidPnSourceId, VidPnPresentPathIndex, *pVidPnTargetId, status); return STATUS_SUCCESS; } break; } } wf_unlock(); ///// if (!ptr_pfnEnumPathTargetsFromSource) { return STATUS_INVALID_PARAMETER; } status = ptr_pfnEnumPathTargetsFromSource(hVidPnTopology, VidPnSourceId, VidPnPresentPathIndex, pVidPnTargetId); DPT("pfnEnumPathTargetsFromSource called sourceId=%d, index=%d, targetid=%d, st=0x%X\n", VidPnSourceId, VidPnPresentPathIndex, *pVidPnTargetId, status ); return status; } static NTSTATUS skip_my_target_path( IN_CONST_D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, IN_CONST_PD3DKMDT_VIDPN_PRESENT_PATH_CONST pVidPnPresentPathInfo, DEREF_OUT_CONST_PPD3DKMDT_VIDPN_PRESENT_PATH ppNextVidPnPresentPathInfo, DXGKDDI_VIDPNTOPOLOGY_ACQUIRENEXTPATHINFO ptr_pfnAcquireNextPathInfo, DXGKDDI_VIDPNTOPOLOGY_RELEASEPATHINFO ptr_pfnReleasePathInfo) { NTSTATUS status = STATUS_SUCCESS; CONST D3DKMDT_VIDPN_PRESENT_PATH* curr_path = pVidPnPresentPathInfo; do { if (curr_path->VidPnTargetId != VIDPN_CHILD_UDID) {//����Ƿ����ǵ�target ID break; } /////skip my target id status = ptr_pfnAcquireNextPathInfo(hVidPnTopology, curr_path, ppNextVidPnPresentPathInfo ); ptr_pfnReleasePathInfo(hVidPnTopology, curr_path); /// release pathinfo /// if (status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET) { break; } else if (!NT_SUCCESS(status)) { break; } curr_path = *ppNextVidPnPresentPathInfo; //// ///// } while (TRUE); /// return status; } static NTSTATUS pfnAcquireFirstPathInfo( IN_CONST_D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, DEREF_OUT_CONST_PPD3DKMDT_VIDPN_PRESENT_PATH ppFirstVidPnPresentPathInfo) { NTSTATUS status = STATUS_SUCCESS; DXGKDDI_VIDPNTOPOLOGY_ACQUIREFIRSTPATHINFO ptr_pfnAcquireFirstPathInfo = NULL; DXGKDDI_VIDPNTOPOLOGY_ACQUIRENEXTPATHINFO ptr_pfnAcquireNextPathInfo = NULL; DXGKDDI_VIDPNTOPOLOGY_RELEASEPATHINFO ptr_pfnReleasePathInfo = NULL; wf_lock(); for (PLIST_ENTRY entry = wf->topology_if_head.Flink; entry != &wf->topology_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (intf->hTopology == hVidPnTopology) { ptr_pfnAcquireFirstPathInfo = intf->topology_if.pfnAcquireFirstPathInfo; ptr_pfnAcquireNextPathInfo = intf->topology_if.pfnAcquireNextPathInfo; ptr_pfnReleasePathInfo = intf->topology_if.pfnReleasePathInfo; break; } } wf_unlock(); /// if (!ptr_pfnAcquireFirstPathInfo) { DPT("** pfnAcquireFirstPathInfo NULL.\n"); return STATUS_INVALID_PARAMETER; } status = ptr_pfnAcquireFirstPathInfo(hVidPnTopology, ppFirstVidPnPresentPathInfo); if ( NT_SUCCESS(status) && status != STATUS_GRAPHICS_DATASET_IS_EMPTY ) { CONST D3DKMDT_VIDPN_PRESENT_PATH* curr_path = *ppFirstVidPnPresentPathInfo; status = skip_my_target_path(hVidPnTopology, curr_path, ppFirstVidPnPresentPathInfo, ptr_pfnAcquireNextPathInfo, ptr_pfnReleasePathInfo); //// } // DPT("ppFirstVidPnPresentPathInfo called. st=0x%X\n", status ); ///// return status; } static NTSTATUS pfnAcquireNextPathInfo( IN_CONST_D3DKMDT_HVIDPNTOPOLOGY hVidPnTopology, IN_CONST_PD3DKMDT_VIDPN_PRESENT_PATH_CONST pVidPnPresentPathInfo, DEREF_OUT_CONST_PPD3DKMDT_VIDPN_PRESENT_PATH ppNextVidPnPresentPathInfo) { NTSTATUS status = STATUS_SUCCESS; DXGKDDI_VIDPNTOPOLOGY_ACQUIRENEXTPATHINFO ptr_pfnAcquireNextPathInfo = NULL; DXGKDDI_VIDPNTOPOLOGY_RELEASEPATHINFO ptr_pfnReleasePathInfo = NULL; wf_lock(); for (PLIST_ENTRY entry = wf->topology_if_head.Flink; entry != &wf->topology_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (intf->hTopology == hVidPnTopology) { ptr_pfnAcquireNextPathInfo = intf->topology_if.pfnAcquireNextPathInfo; ptr_pfnReleasePathInfo = intf->topology_if.pfnReleasePathInfo; break; } } wf_unlock(); ///// if (!ptr_pfnAcquireNextPathInfo) { DPT("** pfnAcquireNextPathInfo NULL.\n"); return STATUS_INVALID_PARAMETER; } status = ptr_pfnAcquireNextPathInfo(hVidPnTopology, pVidPnPresentPathInfo, ppNextVidPnPresentPathInfo ); if (NT_SUCCESS(status) && status != STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET ) { CONST D3DKMDT_VIDPN_PRESENT_PATH* curr_path = *ppNextVidPnPresentPathInfo; status = skip_my_target_path(hVidPnTopology, curr_path, ppNextVidPnPresentPathInfo, ptr_pfnAcquireNextPathInfo, ptr_pfnReleasePathInfo); //// } // DPT("pfnAcquireNextPathInfo called. st=0x%X\n", status ); return status; } static NTSTATUS pfnGetTopology( IN_CONST_D3DKMDT_HVIDPN hVidPn, OUT_PD3DKMDT_HVIDPNTOPOLOGY phVidPnTopology, DEREF_OUT_CONST_PPDXGK_VIDPNTOPOLOGY_INTERFACE ppVidPnTopologyInterface) { NTSTATUS status = STATUS_SUCCESS; DXGKDDI_VIDPN_GETTOPOLOGY ptr_pfnGetTopology = NULL; wf_lock(); for (PLIST_ENTRY entry = wf->vidpn_if_head.Flink; entry != &wf->vidpn_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (hVidPn == intf->hVidPn) { ptr_pfnGetTopology = intf->vidpn_if.pfnGetTopology; break; } } wf_unlock(); if (!ptr_pfnGetTopology) { DPT("pfnGetTopology==NULL.\n"); return STATUS_INVALID_PARAMETER; } status = ptr_pfnGetTopology(hVidPn, phVidPnTopology, ppVidPnTopologyInterface); // DPT("pfnGetTopology called.\n"); if (NT_SUCCESS(status) && ppVidPnTopologyInterface && *ppVidPnTopologyInterface && phVidPnTopology ) { ///���¼��㲻���������Լ���target path��·�� vidpn_paths_t* p = enum_all_paths(*phVidPnTopology, *ppVidPnTopologyInterface); /// //// wf_lock(); /// PLIST_ENTRY entry; BOOLEAN find = FALSE; vidpn_intf_t* intf = NULL; for (entry = wf->topology_if_head.Flink; entry != &wf->topology_if_head; entry = entry->Flink) { vidpn_intf_t* it = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (it->hTopology == *phVidPnTopology) { intf = it; if (intf->paths) { ExFreePool(intf->paths); intf->paths = NULL; }/// break; } } if (!intf) { intf = (vidpn_intf_t*)ExAllocatePoolWithTag(NonPagedPool, sizeof(vidpn_intf_t), 'FXSD'); if (intf) { InsertTailList(&wf->topology_if_head, &intf->list); intf->hTopology = *phVidPnTopology; intf->paths = NULL; ///// } } if (intf) { intf->paths = p; /// intf->topology_if = **ppVidPnTopologyInterface; intf->mod_topology_if = intf->topology_if; *ppVidPnTopologyInterface = &intf->mod_topology_if; /// ///�滻���� intf->mod_topology_if.pfnGetNumPaths = pfnGetNumPaths; intf->mod_topology_if.pfnGetNumPathsFromSource = pfnGetNumPathsFromSource; intf->mod_topology_if.pfnEnumPathTargetsFromSource = pfnEnumPathTargetsFromSource; intf->mod_topology_if.pfnAcquireFirstPathInfo = pfnAcquireFirstPathInfo; intf->mod_topology_if.pfnAcquireNextPathInfo = pfnAcquireNextPathInfo; ///// } //// wf_unlock(); } /// return status; } static NTSTATUS DxgkCbQueryVidPnInterface( IN_CONST_D3DKMDT_HVIDPN hVidPn, IN_CONST_DXGK_VIDPN_INTERFACE_VERSION VidPnInterfaceVersion, DEREF_OUT_CONST_PPDXGK_VIDPN_INTERFACE ppVidPnInterface) { NTSTATUS status = STATUS_SUCCESS; status = wf->DxgkInterface.DxgkCbQueryVidPnInterface(hVidPn, VidPnInterfaceVersion, ppVidPnInterface); /// �滻���Լ��Ļص���������������������Hook Driver��ߵ� Target . if (NT_SUCCESS(status) && ppVidPnInterface && *ppVidPnInterface ) { /// PLIST_ENTRY entry; BOOLEAN find = FALSE; /// wf_lock(); for (entry = wf->vidpn_if_head.Flink; entry != &wf->vidpn_if_head; entry = entry->Flink) { vidpn_intf_t* intf = CONTAINING_RECORD(entry, vidpn_intf_t, list); if (intf->hVidPn == hVidPn) { intf->vidpn_if = *(*ppVidPnInterface); intf->mod_vidpn_if = intf->vidpn_if; intf->mod_vidpn_if.pfnGetTopology = pfnGetTopology; //// *ppVidPnInterface = &intf->mod_vidpn_if; find = TRUE; break; } } if (!find) { vidpn_intf_t* intf = (vidpn_intf_t*)ExAllocatePoolWithTag(NonPagedPool, sizeof(vidpn_intf_t), 'Fxsd'); if (intf) { intf->hVidPn = hVidPn; intf->vidpn_if = *(*ppVidPnInterface); intf->mod_vidpn_if = intf->vidpn_if; intf->mod_vidpn_if.pfnGetTopology = pfnGetTopology; /// *ppVidPnInterface = &intf->mod_vidpn_if; InsertTailList(&wf->vidpn_if_head, &intf->list); //// //// } } wf_unlock(); //// } //// return status; } /////// static NTSTATUS DxgkDdiStartDevice( IN PVOID MiniportDeviceContext, IN PDXGK_START_INFO DxgkStartInfo, IN PDXGKRNL_INTERFACE DxgkInterface, OUT PULONG NumberOfVideoPresentSources, OUT PULONG NumberOfChildren) { NTSTATUS status = STATUS_SUCCESS; ////WDDM1.1 �� WDDM2.3 ÿ�������в�ͬ���壬������WDK7�±��룬���ֻcopy WDDM1.1�IJ��֡� wf->DxgkInterface = *DxgkInterface; /// save interface function,����VIDPN���� ///////�滻ԭ���Ľӿ� DxgkInterface->DxgkCbQueryVidPnInterface = DxgkCbQueryVidPnInterface; ////// status = wf->orgDpiFunc.DxgkDdiStartDevice(MiniportDeviceContext, DxgkStartInfo, DxgkInterface, NumberOfVideoPresentSources, NumberOfChildren); //// DxgkInterface->DxgkCbQueryVidPnInterface = wf->DxgkInterface.DxgkCbQueryVidPnInterface; /// DPT("Hook: DxgkDdiStartDevice status=0x%X.\n", status ); /// if (NT_SUCCESS(status)) { DPT("org: DxgkDdiStartDevice, NumberOfVideoPresentSources=%d, NumberOfChildren=%d\n", *NumberOfVideoPresentSources, *NumberOfChildren); //// �ֱ����� 1������ source �� target wf->vidpn_source_count = *NumberOfVideoPresentSources; // +1; wf->vidpn_target_count = *NumberOfChildren + 1; ////// *NumberOfVideoPresentSources = wf->vidpn_source_count; *NumberOfChildren = wf->vidpn_target_count; //// } //// return status; } static NTSTATUS DxgkDdiStopDevice(IN PVOID MiniportDeviceContext) { DPT("Hook: DxgkDdiStopDevice.\n"); return wf->orgDpiFunc.DxgkDdiStopDevice(MiniportDeviceContext); } static NTSTATUS DxgkDdiQueryChildRelations(IN PVOID pvMiniportDeviceContext, IN OUT PDXGK_CHILD_DESCRIPTOR pChildRelations, IN ULONG ChildRelationsSize) { NTSTATUS status; status = wf->orgDpiFunc.DxgkDdiQueryChildRelations(pvMiniportDeviceContext, pChildRelations, ChildRelationsSize); DPT("Hook: DxgkDdiQueryChildRelations status=0x%X\n", status); //// if (NT_SUCCESS(status)) { //// LONG reqSize = sizeof(DXGK_CHILD_DESCRIPTOR)*wf->vidpn_target_count; if (reqSize > ChildRelationsSize) { return STATUS_BUFFER_TOO_SMALL; } ///// pChildRelations[wf->vidpn_target_count - 1] = pChildRelations[0]; ///�ѵ�һ�����Ƹ����ǵ�target pChildRelations[wf->vidpn_target_count - 1].ChildUid = VIDPN_CHILD_UDID; //�������ǵ�target vidpn��ID pChildRelations[wf->vidpn_target_count - 1].AcpiUid = VIDPN_CHILD_UDID; //// } return status; } static NTSTATUS DxgkDdiQueryChildStatus(IN PVOID MiniportDeviceContext, IN PDXGK_CHILD_STATUS ChildStatus, IN BOOLEAN NonDestructiveOnly) { DPT("Hook: DxgkDdiQueryChildStatus Uid=0x%X\n", ChildStatus->ChildUid); if (ChildStatus->ChildUid == VIDPN_CHILD_UDID) { ChildStatus->HotPlug.Connected = TRUE; /// /// return STATUS_SUCCESS; } //// return wf->orgDpiFunc.DxgkDdiQueryChildStatus(MiniportDeviceContext, ChildStatus, NonDestructiveOnly); } static NTSTATUS DxgkDdiQueryDeviceDescriptor(IN_CONST_PVOID MiniportDeviceContext, IN_ULONG ChildUid, INOUT_PDXGK_DEVICE_DESCRIPTOR DeviceDescriptor) { DPT("Hook: DxgkDdiQueryDeviceDescriptor Uid=0x%X\n", ChildUid); if (ChildUid == VIDPN_CHILD_UDID) { /// return STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA; } //// return wf->orgDpiFunc.DxgkDdiQueryDeviceDescriptor(MiniportDeviceContext, ChildUid, DeviceDescriptor); } ///// NTSTATUS DpiInitialize( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath, DRIVER_INITIALIZATION_DATA* DriverInitData) { NTSTATUS status = STATUS_SUCCESS; static BOOLEAN is_hooked = FALSE; //// UNICODE_STRING vm_str; RtlInitUnicodeString(&vm_str, L"\\Driver\\vm3dmp_loader"); // Vmware 3D UNICODE_STRING igfx_str; RtlInitUnicodeString(&igfx_str, L"\\Driver\\igfx"); // Intel Graphics UNICODE_STRING nv_str; RtlInitUnicodeString(&nv_str, L"\\Driver\\nvlddmkm"); // nvidia Graphics if ( !is_hooked && ( RtlEqualUnicodeString(&vm_str, &DriverObject->DriverName, TRUE) || RtlEqualUnicodeString(&nv_str, &DriverObject->DriverName, TRUE) //vmware��������Կ�����Intel�Կ� ) ) { //����ֻHOOK��һ���Կ� is_hooked = TRUE; /// //���︴����Ҫע�⣺ // DRIVER_INITIALIZATION_DATA�ṹ���壬WDDM1.1 �� WDDM2.3 ÿ�������в�ͬ���壬������WDK7�±��룬���ֻcopy WDDM1.1�IJ��֡� RtlCopyMemory(&wf->orgDpiFunc, DriverInitData, sizeof(DRIVER_INITIALIZATION_DATA)); ////replace some function DriverInitData->DxgkDdiAddDevice = DxgkDdiAddDevice; DriverInitData->DxgkDdiRemoveDevice = DxgkDdiRemoveDevice; DriverInitData->DxgkDdiStartDevice = DxgkDdiStartDevice; DriverInitData->DxgkDdiStopDevice = DxgkDdiStopDevice; DriverInitData->DxgkDdiQueryChildRelations = DxgkDdiQueryChildRelations; DriverInitData->DxgkDdiQueryChildStatus = DxgkDdiQueryChildStatus; DriverInitData->DxgkDdiQueryDeviceDescriptor = DxgkDdiQueryDeviceDescriptor; DriverInitData->DxgkDdiEnumVidPnCofuncModality = DxgkDdiEnumVidPnCofuncModality; //// DriverInitData->DxgkDdiIsSupportedVidPn = DxgkDdiIsSupportedVidPn; DriverInitData->DxgkDdiCommitVidPn = DxgkDdiCommitVidPn; DriverInitData->DxgkDdiSetVidPnSourceVisibility = DxgkDdiSetVidPnSourceVisibility; DriverInitData->DxgkDdiSetVidPnSourceAddress = DxgkDdiSetVidPnSourceAddress; // DriverInitData->DxgkDdiPresent = DxgkDdiPresent; ///// } ///�滻��ijЩ�����󣬽��ŵ��� dxgkrnl.sys �ص�����ע�� return wf->dxgkrnl_dpiInit(DriverObject, RegistryPath, DriverInitData); } vidpn.cpp 源文件: #include "filter.h" static D3DKMDT_2DREGION Modes[]= { {1024, 768}, {1366, 768}, {1920, 1080}, // {6000, 4000} }; static NTSTATUS add_source_mode(D3DKMDT_HVIDPNSOURCEMODESET source_mode_set_hdl, CONST DXGK_VIDPNSOURCEMODESET_INTERFACE *source_mode_set_if, D3DKMDT_2DREGION* mode) { NTSTATUS status = STATUS_SUCCESS; D3DKMDT_VIDPN_SOURCE_MODE *source_mode; D3DKMDT_GRAPHICS_RENDERING_FORMAT *fmt; status = source_mode_set_if->pfnCreateNewModeInfo(source_mode_set_hdl, &source_mode); if (!NT_SUCCESS(status)) { DPT("** pfnCreateNewModeInfo(Source) err=0x%X\n", status ); return status; } /* Let OS assign the ID, set the type.*/ source_mode->Type = D3DKMDT_RMT_GRAPHICS; /* Initialize the rendering format per our constraints and the current mode. */ fmt = &source_mode->Format.Graphics; fmt->PrimSurfSize.cx = mode->cx; fmt->PrimSurfSize.cy = mode->cy; fmt->VisibleRegionSize.cx = mode->cx; fmt->VisibleRegionSize.cy = mode->cy; fmt->Stride = mode->cx*4 ; // RGBA fmt->PixelFormat = D3DDDIFMT_A8R8G8B8; fmt->ColorBasis = D3DKMDT_CB_SRGB; fmt->PixelValueAccessMode = D3DKMDT_PVAM_DIRECT; status = source_mode_set_if->pfnAddMode(source_mode_set_hdl, source_mode); if (!NT_SUCCESS(status)) { DPT("** pfnAddMode(Source) err=0x%X\n", status ); source_mode_set_if->pfnReleaseModeInfo(source_mode_set_hdl, source_mode); } /// return status; } static NTSTATUS update_source_modes( CONST D3DKMDT_HVIDPN vidpn_hdl, CONST D3DKMDT_VIDPN_PRESENT_PATH *curr_path_info, CONST DXGK_VIDPN_INTERFACE* vidpn_if) { NTSTATUS status = STATUS_SUCCESS; D3DKMDT_HVIDPNSOURCEMODESET source_mode_set_hdl = NULL; CONST DXGK_VIDPNSOURCEMODESET_INTERFACE *source_mode_set_if; CONST D3DKMDT_VIDPN_SOURCE_MODE *src_mode_info = NULL; status = vidpn_if->pfnAcquireSourceModeSet(vidpn_hdl, curr_path_info->VidPnSourceId, &source_mode_set_hdl, &source_mode_set_if); if (!NT_SUCCESS(status)) { DPT("** not pfnAcquireSourceModeSet st=0x%X\n", status ); return status; } //// status = source_mode_set_if->pfnAcquirePinnedModeInfo(source_mode_set_hdl, &src_mode_info); if (!NT_SUCCESS(status)) { vidpn_if->pfnReleaseSourceModeSet(vidpn_hdl, source_mode_set_hdl); DPT("pfnAcquirePinnedModeInfo(Source) err=0x%X\n", status ); return status; } //// if (src_mode_info != NULL) { source_mode_set_if->pfnReleaseModeInfo(source_mode_set_hdl, src_mode_info); } vidpn_if->pfnReleaseSourceModeSet(vidpn_hdl, source_mode_set_hdl); source_mode_set_hdl = NULL; /// /// if (status == STATUS_SUCCESS && src_mode_info != NULL) { // pinned mode . /// DPT("Source Mode Pinned Mode: 0x%X -> 0x%X\n", curr_path_info->VidPnSourceId, curr_path_info->VidPnTargetId); return STATUS_SUCCESS;///�Ѿ����ˣ������� } //// status = vidpn_if->pfnCreateNewSourceModeSet(vidpn_hdl, curr_path_info->VidPnSourceId, &source_mode_set_hdl, &source_mode_set_if); if (!NT_SUCCESS(status)) { DPT("** pfnCreateNewSourceModeSet err=0x%X\n", status); return status; } //// for (INT i = 0; i < sizeof(Modes) / sizeof(Modes[0]); ++i) { //// status = add_source_mode(source_mode_set_hdl, source_mode_set_if, &Modes[i]); if (!NT_SUCCESS(status)) { /// vidpn_if->pfnReleaseSourceModeSet(vidpn_hdl, source_mode_set_hdl); DPT("add_source_mode err=0x%X\n", status); return status; } //// } ////// status = vidpn_if->pfnAssignSourceModeSet(vidpn_hdl, curr_path_info->VidPnSourceId, source_mode_set_hdl); if (!NT_SUCCESS(status)) { DPT("** pfnAssignSourceModeSet err=0x%X\n", status); vidpn_if->pfnReleaseSourceModeSet(vidpn_hdl, source_mode_set_hdl); } //// return status; } //// target static NTSTATUS add_target_mode(D3DKMDT_HVIDPNTARGETMODESET tgt_mode_set_hdl, CONST DXGK_VIDPNTARGETMODESET_INTERFACE *target_mode_set_if, D3DKMDT_2DREGION* mode) { D3DKMDT_VIDPN_TARGET_MODE *target_mode; D3DKMDT_VIDEO_SIGNAL_INFO *signal_info; NTSTATUS status; status = target_mode_set_if->pfnCreateNewModeInfo(tgt_mode_set_hdl, &target_mode); if (!NT_SUCCESS(status)) { DPT("** pfnCreateNewModeInfo(Target) err=0x%X\n", status ); return status; } //// /* Let OS assign the ID, set the preferred mode field.*/ target_mode->Preference = D3DKMDT_MP_PREFERRED; //// #define REFRESH_RATE 60 signal_info = &target_mode->VideoSignalInfo; signal_info->VideoStandard = D3DKMDT_VSS_VESA_DMT;// D3DKMDT_VSS_OTHER; signal_info->TotalSize.cx = mode->cx; signal_info->TotalSize.cy = mode->cy; signal_info->ActiveSize.cx = mode->cx; signal_info->ActiveSize.cy = mode->cy; signal_info->PixelRate = mode->cx * mode->cy * REFRESH_RATE; signal_info->VSyncFreq.Numerator = REFRESH_RATE * 1000; signal_info->VSyncFreq.Denominator = 1000; signal_info->HSyncFreq.Numerator = (UINT)((signal_info->PixelRate / signal_info->TotalSize.cy) * 1000); signal_info->HSyncFreq.Denominator = 1000; signal_info->ScanLineOrdering = D3DDDI_VSSLO_PROGRESSIVE; status = target_mode_set_if->pfnAddMode(tgt_mode_set_hdl, target_mode); if (!NT_SUCCESS(status)) { DPT("pfnAddMode failed: 0x%x", status); target_mode_set_if->pfnReleaseModeInfo(tgt_mode_set_hdl, target_mode); return status; } return status; } static NTSTATUS update_target_modes( CONST D3DKMDT_HVIDPN vidpn_hdl, CONST D3DKMDT_VIDPN_PRESENT_PATH *curr_path_info, CONST DXGK_VIDPN_INTERFACE* vidpn_if) { NTSTATUS status = STATUS_SUCCESS; D3DKMDT_HVIDPNTARGETMODESET tgt_mode_set_hdl = NULL; CONST DXGK_VIDPNTARGETMODESET_INTERFACE *target_mode_set_if; CONST D3DKMDT_VIDPN_TARGET_MODE *tgt_mode_info = NULL; status = vidpn_if->pfnAcquireTargetModeSet(vidpn_hdl, curr_path_info->VidPnTargetId, &tgt_mode_set_hdl, &target_mode_set_if); if (!NT_SUCCESS(status)) { DPT("** pfnAcquireTargetModeSet err=0x%X\n", status ); return status; } status = target_mode_set_if->pfnAcquirePinnedModeInfo(tgt_mode_set_hdl, &tgt_mode_info); if (!NT_SUCCESS(status)) { vidpn_if->pfnReleaseTargetModeSet(vidpn_hdl, tgt_mode_set_hdl); DPT("** pfnAcquirePinnedModeInfo(Source) err=0x%X\n", status ); return status; } //// if (tgt_mode_info) { target_mode_set_if->pfnReleaseModeInfo(tgt_mode_set_hdl, tgt_mode_info); } vidpn_if->pfnReleaseTargetModeSet(vidpn_hdl, tgt_mode_set_hdl); tgt_mode_set_hdl = NULL; if (status == STATUS_SUCCESS && tgt_mode_info != NULL) { DPT("Target Mode Pinned Mode: 0x%X -> 0x%X\n", curr_path_info->VidPnSourceId, curr_path_info->VidPnTargetId); return STATUS_SUCCESS;///�Ѿ����ˣ������� /// } ///// status = vidpn_if->pfnCreateNewTargetModeSet(vidpn_hdl, curr_path_info->VidPnTargetId, &tgt_mode_set_hdl, &target_mode_set_if); if (!NT_SUCCESS(status)) { DPT("** pfnCreateNewTargetModeSet err=0x%X\n", status ); return status; } ///add target for (INT i = 0; i < sizeof(Modes) / sizeof(Modes[0]); ++i) { status = add_target_mode(tgt_mode_set_hdl, target_mode_set_if, &Modes[i]); if (!NT_SUCCESS(status)) { /// vidpn_if->pfnReleaseTargetModeSet(vidpn_hdl, tgt_mode_set_hdl); DPT("add_target_mode err=0x%X\n", status); return status; } /// } ////// status = vidpn_if->pfnAssignTargetModeSet(vidpn_hdl, curr_path_info->VidPnTargetId, tgt_mode_set_hdl); if (!NT_SUCCESS(status)) { DPT("** pfnAssignTargetModeSet err=0x%x\n", status ); vidpn_if->pfnReleaseTargetModeSet(vidpn_hdl, tgt_mode_set_hdl); return status; } return status; } static NTSTATUS DxgkDdiEnumVidPnCofuncModality_modify(CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST arg) { NTSTATUS status = STATUS_SUCCESS; D3DKMDT_HVIDPN hConstrainingVidPn = arg->hConstrainingVidPn; CONST DXGK_VIDPN_INTERFACE* vidpn_if; status = wf->DxgkInterface.DxgkCbQueryVidPnInterface( hConstrainingVidPn, DXGK_VIDPN_INTERFACE_VERSION_V1, &vidpn_if); if (!NT_SUCCESS(status)) { return status; } //// D3DKMDT_HVIDPNTOPOLOGY topology_handle = NULL; CONST DXGK_VIDPNTOPOLOGY_INTERFACE* topology_if = NULL; CONST D3DKMDT_VIDPN_PRESENT_PATH *curr_path_info; CONST D3DKMDT_VIDPN_PRESENT_PATH *next_path_info; status = vidpn_if->pfnGetTopology(hConstrainingVidPn, &topology_handle, &topology_if); if (!NT_SUCCESS(status)) { return status; } //// status = topology_if->pfnAcquireFirstPathInfo(topology_handle, &curr_path_info); if (status == STATUS_GRAPHICS_DATASET_IS_EMPTY) { // Empty topology, nothing to do. DPT("pfnAcquireFirstPathInfo: Empty topology.\n"); return STATUS_SUCCESS; } else if (!NT_SUCCESS(status)) { DPT("pfnAcquireFirstPathInfo failed: 0x%x", status); return STATUS_NO_MEMORY; //// } //// do { ////����ÿ��·�� DPT("0x%X --> 0x%X\n", curr_path_info->VidPnSourceId, curr_path_info->VidPnTargetId); if (curr_path_info->VidPnTargetId == VIDPN_CHILD_UDID) {//·��Ŀ���������Լ��� /// if ((arg->EnumPivotType != D3DKMDT_EPT_VIDPNSOURCE) || (arg->EnumPivot.VidPnSourceId != curr_path_info->VidPnSourceId)) { ///// status = update_source_modes(arg->hConstrainingVidPn, curr_path_info, vidpn_if); DPT("update_source_modes st=0x%X\n",status ); if (!NT_SUCCESS(status)) { DPT("** update_source_modes err=0x%X\n", status ); } ////// } ///// if ((arg->EnumPivotType != D3DKMDT_EPT_VIDPNTARGET) || (arg->EnumPivot.VidPnTargetId != curr_path_info->VidPnTargetId)) { status = update_target_modes(arg->hConstrainingVidPn, curr_path_info, vidpn_if); DPT("update_target_modes st=0x%X\n", status); if (!NT_SUCCESS(status)) { DPT("** update_target_modes err=0x%X\n", status); } } //////// } ///next status = topology_if->pfnAcquireNextPathInfo(topology_handle, curr_path_info, &next_path_info); topology_if->pfnReleasePathInfo(topology_handle, curr_path_info); curr_path_info = next_path_info; if (status == STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET) { /// end curr_path_info = NULL; // DPT("pfnAcquireNextPathInfo no more data.\n"); break; } else if (!NT_SUCCESS(status)) { curr_path_info = NULL; DPT("pfnAcquireNextPathInfo err=0x%X\n", status ); break; } ///// } while (TRUE); return status; } NTSTATUS DxgkDdiEnumVidPnCofuncModality(CONST HANDLE hAdapter, CONST DXGKARG_ENUMVIDPNCOFUNCMODALITY* CONST pEnumCofuncModalityArg) { NTSTATUS status = STATUS_SUCCESS; DPT("DxgkDdiEnumVidPnCofuncModality: type=%d, 0x%X -> 0x%X, [%d, %d]\n", pEnumCofuncModalityArg->EnumPivotType, pEnumCofuncModalityArg->EnumPivot.VidPnSourceId, pEnumCofuncModalityArg->EnumPivot.VidPnTargetId, wf->vidpn_source_count, wf->vidpn_target_count ); /// DxgkDdiEnumVidPnCofuncModality_modify(pEnumCofuncModalityArg); //// //// status = wf->orgDpiFunc.DxgkDdiEnumVidPnCofuncModality(hAdapter, pEnumCofuncModalityArg); if (!NT_SUCCESS(status)) { DPT("** DxgkDdiEnumVidPnCofuncModality err=0x%X\n", status ); } return status; } NTSTATUS DxgkDdiIsSupportedVidPn( IN_CONST_HANDLE hAdapter, INOUT_PDXGKARG_ISSUPPORTEDVIDPN pIsSupportedVidPn) { NTSTATUS status; status = wf->orgDpiFunc.DxgkDdiIsSupportedVidPn(hAdapter, pIsSupportedVidPn); if (NT_SUCCESS(status)) { DPT("DxgkDdiIsSupportedVidPn handle=%p, supported=%d, \n", pIsSupportedVidPn->hDesiredVidPn, pIsSupportedVidPn->IsVidPnSupported ); } else { DPT("** DxgkDdiIsSupportedVidPn err=0x%X, handle=%p, supported=%d\n", status , pIsSupportedVidPn->hDesiredVidPn, pIsSupportedVidPn->IsVidPnSupported ); } return status; } NTSTATUS DxgkDdiCommitVidPn( IN_CONST_HANDLE hAdapter, IN_CONST_PDXGKARG_COMMITVIDPN_CONST pCommitVidPn) { NTSTATUS status; status = wf->orgDpiFunc.DxgkDdiCommitVidPn(hAdapter, pCommitVidPn ); // if (!NT_SUCCESS(status)) { /// DPT(" DxgkDdiCommitVidPn st=0x%X\n", status ); // } //// return status; } NTSTATUS DxgkDdiSetVidPnSourceVisibility( IN_CONST_HANDLE hAdapter, IN_CONST_PDXGKARG_SETVIDPNSOURCEVISIBILITY pSetVidPnSourceVisibility) { NTSTATUS status; status = wf->orgDpiFunc.DxgkDdiSetVidPnSourceVisibility(hAdapter, pSetVidPnSourceVisibility); DPT(" DxgkDdiSetVidPnSourceVisibility sourceId=0x%X, visible=0x%X, st=0x%X\n", pSetVidPnSourceVisibility->VidPnSourceId, pSetVidPnSourceVisibility->Visible ,status ); return status; } NTSTATUS APIENTRY DxgkDdiSetVidPnSourceAddress( const HANDLE hAdapter, const DXGKARG_SETVIDPNSOURCEADDRESS *pSetVidPnSourceAddress) { NTSTATUS status; status = wf->orgDpiFunc.DxgkDdiSetVidPnSourceAddress(hAdapter, pSetVidPnSourceAddress ); DPT("DxgkDdiSetVidPnSourceAddress sourceId=0x%X, paddr=%llu, st=0x%X\n", pSetVidPnSourceAddress->VidPnSourceId, pSetVidPnSourceAddress->PrimaryAddress.QuadPart, status ); return status; } 修改以上代码,添加虚拟显示器管理代码
07-10
#include "stm32f10x.h" // Device header #include "Delay.h" #include "Key.h" #include "Led.h" #include "serial.h" #include "OLED.h" #include "Time.h" #include "Stack.h" static unsigned char Clear_Index=0; //清零检索 static unsigned char Count_Index=0; //计算检索 static uint32_t Index=0; static unsigned char Firmula[100]; //存储算数式子 static unsigned int Result; //存储结果 void USART1_IRQHandler(void); unsigned char a=19; int main(void) { Key_Init(); OLED_Init(); Serial_Init(); while(1) { if(Key_GetNum1()) //计算算数式 { Result=Deposit(Firmula); Count_Index=1; } if(Count_Index) //发送结果 { if(Key_GetNum2()) { printf("结果=%d",Result); OLED_ShowNum(1,1,Result,4); Index=0; Clear_Index=1; Count_Index=0; } } if(Clear_Index) //清零 { if(Key_GetNum3()) { Clear_Index=0; Init(); } } else if(!Clear_Index) { if(Key_GetNum3()) { printf("请输入运算式"); } } } } void USART1_IRQHandler(void) //串口中断函数 { Firmula[Index]=Serial_Getbyte(); printf("%c",Firmula[Index]); Index++; }#include "stm32f10x.h"// Device header #include "Stack.h" #include<ctype.h> #include "Serial.h" Stack_char Stack_CHAR; Stack_num Stack_NUM; uint8_t Push_char(Stack_char *stack,uint8_t CH); uint8_t Pop_char(Stack_char *stack,uint8_t *c); uint8_t Push_num(Stack_num *stack,unsigned int NUM); uint8_t Pop_num(Stack_num *stack,unsigned int *n); void Eval(void); uint16_t Priority(uint8_t ch); void Init(void) { Stack_NUM.top=0; Stack_CHAR.top=0; } uint16_t Priority(uint8_t ch) { switch(ch) { case '(' : case ')' : return 3; case '*' : case '/' : return 2; case '+' : case '-' : return 1; default : return 0; //分化优先级 } } uint32_t Deposit(uint8_t *String) { unsigned int i,j,index=0; uint8_t C; Init(); for(i = 0;String[i]!='\0'&&i < Stack_Size ;i++) { if(isdigit(String[i])) //判断是否 '0'<=string<='9' { index=0; j=i; for(;isdigit(String[j])&&j< Stack_Size;j++) { index=index*10+(String[j]-'0'); } Push_num(&Stack_NUM,index); i=j-1; //因为for循环多加了1,所以减去1 } else if(String[i]=='(') { Push_char(&Stack_CHAR,String[i]); } else if(String[i]==')') { while(Stack_CHAR.ch[Stack_CHAR.top] != '(') {Eval();} //直到遇到左括号,并且计算 if(Stack_CHAR.top != 0 && Stack_CHAR.ch[Stack_CHAR.top] == '(') { Pop_char(&Stack_CHAR,&C); //弹出左括号 } } else { while(Stack_CHAR.top!=0&&Stack_CHAR.ch[Stack_CHAR.top]!='('&&Priority(Stack_CHAR.ch[Stack_CHAR.top])>=Priority(String[i])) { Eval(); } Push_char(&Stack_CHAR,String[i]); } } while(Stack_CHAR.top) { Eval(); } //循环直至操作符为空 return Stack_NUM.num[Stack_NUM.top]; //此时数栈顶元素即为表达式值 } void Eval(void) { uint32_t a,x,b; uint8_t cha; Pop_num(&Stack_NUM,&b); Pop_num(&Stack_NUM,&a); //由于栈是陷进后出,与队列有区别(先进出) Pop_char(&Stack_CHAR,&cha); switch(cha) { case '*' : x=a*b;break; //计算 case '/' : { if(b==0) {printf("除数不能为0");x=0;} else {x=a/b;} break; } case '+' : {x=a+b;break;} case '-' : {x=a-b;break;} default :break; } Push_num(&Stack_NUM,x); } uint8_t Push_char(Stack_char *stack,uint8_t CH) { if(stack->top>=Stack_Size) { return 0; } stack->top++; stack->ch[stack->top]=CH; return 1; } uint8_t Push_num(Stack_num *stack,unsigned int NUM) { if(stack->top>=Stack_Size) { return 0; } stack->top++; stack->num[stack->top]=NUM; return 1; } uint8_t Pop_char(Stack_char *stack,uint8_t *c) { if(stack->top<=0) { return 0; } *c=stack->ch[stack->top]; stack->top--; return 1; } uint8_t Pop_num(Stack_num *stack,unsigned int *n) { if(stack->top<=0) { return 0; } *n=stack->num[stack->top]; stack->top--; return 1; } /* Copyright (C) ARM Ltd., 1999,2014 */ /* All rights reserved */ /* * RCS $Revision$ * Checkin $Date$ * Revising $Author: agrant $ */ #ifndef __stdint_h #define __stdint_h #define __ARMCLIB_VERSION 5060034 #ifdef __INT64_TYPE__ /* armclang predefines '__INT64_TYPE__' and '__INT64_C_SUFFIX__' */ #define __INT64 __INT64_TYPE__ #else /* armcc has builtin '__int64' which can be used in --strict mode */ #define __INT64 __int64 #define __INT64_C_SUFFIX__ ll #endif #define __PASTE2(x, y) x ## y #define __PASTE(x, y) __PASTE2(x, y) #define __INT64_C(x) __ESCAPE__(__PASTE(x, __INT64_C_SUFFIX__)) #define __UINT64_C(x) __ESCAPE__(__PASTE(x ## u, __INT64_C_SUFFIX__)) #if defined(__clang__) || (defined(__ARMCC_VERSION) && !defined(__STRICT_ANSI__)) /* armclang and non-strict armcc allow 'long long' in system headers */ #define __LONGLONG long long #else /* strict armcc has '__int64' */ #define __LONGLONG __int64 #endif #ifndef __STDINT_DECLS #define __STDINT_DECLS #undef __CLIBNS #ifdef __cplusplus namespace std { #define __CLIBNS std:: extern "C" { #else #define __CLIBNS #endif /* __cplusplus */ /* * 'signed' is redundant below, except for 'signed char' and if * the typedef is used to declare a bitfield. */ /* 7.18.1.1 */ /* exact-width signed integer types */ typedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef signed __INT64 int64_t; /* exact-width unsigned integer types */ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned __INT64 uint64_t; /* 7.18.1.2 */ /* smallest type of at least n bits */ /* minimum-width signed integer types */ typedef signed char int_least8_t; typedef signed short int int_least16_t; typedef signed int int_least32_t; typedef signed __INT64 int_least64_t; /* minimum-width unsigned integer types */ typedef unsigned char uint_least8_t; typedef unsigned short int uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned __INT64 uint_least64_t; /* 7.18.1.3 */ /* fastest minimum-width signed integer types */ typedef signed int int_fast8_t; typedef signed int int_fast16_t; typedef signed int int_fast32_t; typedef signed __INT64 int_fast64_t; /* fastest minimum-width unsigned integer types */ typedef unsigned int uint_fast8_t; typedef unsigned int uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned __INT64 uint_fast64_t; /* 7.18.1.4 integer types capable of holding object pointers */ #if __sizeof_ptr == 8 typedef signed __INT64 intptr_t; typedef unsigned __INT64 uintptr_t; #else typedef signed int intptr_t; typedef unsigned int uintptr_t; #endif /* 7.18.1.5 greatest-width integer types */ typedef signed __LONGLONG intmax_t; typedef unsigned __LONGLONG uintmax_t; #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) /* 7.18.2.1 */ /* minimum values of exact-width signed integer types */ #define INT8_MIN -128 #define INT16_MIN -32768 #define INT32_MIN (~0x7fffffff) /* -2147483648 is unsigned */ #define INT64_MIN __INT64_C(~0x7fffffffffffffff) /* -9223372036854775808 is unsigned */ /* maximum values of exact-width signed integer types */ #define INT8_MAX 127 #define INT16_MAX 32767 #define INT32_MAX 2147483647 #define INT64_MAX __INT64_C(9223372036854775807) /* maximum values of exact-width unsigned integer types */ #define UINT8_MAX 255 #define UINT16_MAX 65535 #define UINT32_MAX 4294967295u #define UINT64_MAX __UINT64_C(18446744073709551615) /* 7.18.2.2 */ /* minimum values of minimum-width signed integer types */ #define INT_LEAST8_MIN -128 #define INT_LEAST16_MIN -32768 #define INT_LEAST32_MIN (~0x7fffffff) #define INT_LEAST64_MIN __INT64_C(~0x7fffffffffffffff) /* maximum values of minimum-width signed integer types */ #define INT_LEAST8_MAX 127 #define INT_LEAST16_MAX 32767 #define INT_LEAST32_MAX 2147483647 #define INT_LEAST64_MAX __INT64_C(9223372036854775807) /* maximum values of minimum-width unsigned integer types */ #define UINT_LEAST8_MAX 255 #define UINT_LEAST16_MAX 65535 #define UINT_LEAST32_MAX 4294967295u #define UINT_LEAST64_MAX __UINT64_C(18446744073709551615) /* 7.18.2.3 */ /* minimum values of fastest minimum-width signed integer types */ #define INT_FAST8_MIN (~0x7fffffff) #define INT_FAST16_MIN (~0x7fffffff) #define INT_FAST32_MIN (~0x7fffffff) #define INT_FAST64_MIN __INT64_C(~0x7fffffffffffffff) /* maximum values of fastest minimum-width signed integer types */ #define INT_FAST8_MAX 2147483647 #define INT_FAST16_MAX 2147483647 #define INT_FAST32_MAX 2147483647 #define INT_FAST64_MAX __INT64_C(9223372036854775807) /* maximum values of fastest minimum-width unsigned integer types */ #define UINT_FAST8_MAX 4294967295u #define UINT_FAST16_MAX 4294967295u #define UINT_FAST32_MAX 4294967295u #define UINT_FAST64_MAX __UINT64_C(18446744073709551615) /* 7.18.2.4 */ /* minimum value of pointer-holding signed integer type */ #if __sizeof_ptr == 8 #define INTPTR_MIN INT64_MIN #else #define INTPTR_MIN INT32_MIN #endif /* maximum value of pointer-holding signed integer type */ #if __sizeof_ptr == 8 #define INTPTR_MAX INT64_MAX #else #define INTPTR_MAX INT32_MAX #endif /* maximum value of pointer-holding unsigned integer type */ #if __sizeof_ptr == 8 #define UINTPTR_MAX UINT64_MAX #else #define UINTPTR_MAX UINT32_MAX #endif /* 7.18.2.5 */ /* minimum value of greatest-width signed integer type */ #define INTMAX_MIN __ESCAPE__(~0x7fffffffffffffffll) /* maximum value of greatest-width signed integer type */ #define INTMAX_MAX __ESCAPE__(9223372036854775807ll) /* maximum value of greatest-width unsigned integer type */ #define UINTMAX_MAX __ESCAPE__(18446744073709551615ull) /* 7.18.3 */ /* limits of ptrdiff_t */ #if __sizeof_ptr == 8 #define PTRDIFF_MIN INT64_MIN #define PTRDIFF_MAX INT64_MAX #else #define PTRDIFF_MIN INT32_MIN #define PTRDIFF_MAX INT32_MAX #endif /* limits of sig_atomic_t */ #define SIG_ATOMIC_MIN (~0x7fffffff) #define SIG_ATOMIC_MAX 2147483647 /* limit of size_t */ #if __sizeof_ptr == 8 #define SIZE_MAX UINT64_MAX #else #define SIZE_MAX UINT32_MAX #endif /* limits of wchar_t */ /* NB we have to undef and redef because they're defined in both * stdint.h and wchar.h */ #undef WCHAR_MIN #undef WCHAR_MAX #if defined(__WCHAR32) || (defined(__ARM_SIZEOF_WCHAR_T) && __ARM_SIZEOF_WCHAR_T == 4) #define WCHAR_MIN 0 #define WCHAR_MAX 0xffffffffU #else #define WCHAR_MIN 0 #define WCHAR_MAX 65535 #endif /* limits of wint_t */ #define WINT_MIN (~0x7fffffff) #define WINT_MAX 2147483647 #endif /* __STDC_LIMIT_MACROS */ #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) /* 7.18.4.1 macros for minimum-width integer constants */ #define INT8_C(x) (x) #define INT16_C(x) (x) #define INT32_C(x) (x) #define INT64_C(x) __INT64_C(x) #define UINT8_C(x) (x ## u) #define UINT16_C(x) (x ## u) #define UINT32_C(x) (x ## u) #define UINT64_C(x) __UINT64_C(x) /* 7.18.4.2 macros for greatest-width integer constants */ #define INTMAX_C(x) __ESCAPE__(x ## ll) #define UINTMAX_C(x) __ESCAPE__(x ## ull) #endif /* __STDC_CONSTANT_MACROS */ #ifdef __cplusplus } /* extern "C" */ } /* namespace std */ #endif /* __cplusplus */ #endif /* __STDINT_DECLS */ #ifdef __cplusplus #ifndef __STDINT_NO_EXPORTS using ::std::int8_t; using ::std::int16_t; using ::std::int32_t; using ::std::int64_t; using ::std::uint8_t; using ::std::uint16_t; using ::std::uint32_t; using ::std::uint64_t; using ::std::int_least8_t; using ::std::int_least16_t; using ::std::int_least32_t; using ::std::int_least64_t; using ::std::uint_least8_t; using ::std::uint_least16_t; using ::std::uint_least32_t; using ::std::uint_least64_t; using ::std::int_fast8_t; using ::std::int_fast16_t; using ::std::int_fast32_t; using ::std::int_fast64_t; using ::std::uint_fast8_t; using ::std::uint_fast16_t; using ::std::uint_fast32_t; using ::std::uint_fast64_t; using ::std::intptr_t; using ::std::uintptr_t; using ::std::intmax_t; using ::std::uintmax_t; #endif #endif /* __cplusplus */ #undef __INT64 #undef __LONGLONG #endif /* __stdint_h */ /* end of stdint.h */ 在不改变原代码变量名情况下,实现小数点预算
07-16
#include “stdafx.h” #include #include using namespace std; struct data2 { _variant_t ColumnValue; _variant_t LineValue; }; class CSqlDatas { public: CSqlDatas(); ~CSqlDatas(); public: CString m_strDBIp; _ConnectionPtr m_pConn; _RecordsetPtr m_recordPtr; bool ConnectServer(CString m_strDBIp); bool ConnectServer2(CString m_strDBIp); bool ConnectServerModTest(CString m_strDBIp); void CloseServer(); bool CheckTable2(vector<long> input_lines, data2 input_data, vector<long> &output_lines); vector<_variant_t> col_names; public: bool LinkDataTable(_variant_t Source); /!<获得表中的所有数据/ bool CollectAllDatas(vector<vector> &datas);/!<Source(in)选表语句,ColDatas(out)所有列,datas(out)所有数据/ bool CollectPbiDatas(vector<vector> &datas); /!<获得所有列的名称/ bool GetColNames(vector<_variant_t> &col_names); bool CollectLimiteDatas(vector inputDates, vector<vector> &outputDatas); bool AddData(vector LineDatas);/!<LineDatas(in)加入表格中的数据,从0开始/ bool AddLine(vector LineDatas); void GetLineDatas(long line, vector<data2> &data);/*!<获得某一行的数据,line从1开始*/ void ChangeData(long i, vector<data2> datas);/*!<i(in)表示第几行,datas(in)新的数据*/ void DeleteData(int i);/*!<i(in)表示第几行,从0行开始*/ void DeleteAll();/*!<删除表中的所有数据*/ //void UpdataAll(CString path,_variant_t TableName);/*!<path(in)excle的完整路径,TableName(in)数据库表格的名称*/ void TableSort(_bstr_t Criteria); bool CheckMainColumnVal(data2 cdata);/*!<cdata(in)检查关键列是否已经有这个值,TRUE表示没有*/ void CollectComboCtr(_bstr_t typeStr, vector<_variant_t> &ComboStr);/*!<获得所有的typeStr不同的值*/ }; #include “StdAfx.h” #include “SqlDatas.h” CSqlDatas::CSqlDatas(void) { } CSqlDatas::~CSqlDatas(void) { CloseServer(); } bool CSqlDatas::ConnectServer(CString m_strDBIp) { HRESULT hr = CoInitialize(NULL); // 初始化COM环境 if (FAILED(hr)) return false; CString aStrConn; aStrConn.Format(_T(“driver=SQL Server;server=%s;database=MDS2;uid=;pwd=”), m_strDBIp); hr = m_pConn.CreateInstance(__uuidof(Connection)); if (FAILED(hr)) { AfxMessageBox(L"SQL异常!“); return false; } try { hr = m_pConn->Open((_bstr_t)aStrConn, _T(“mds”), _T(“password”), adConnectUnspecified); m_pConn->PutCursorLocation(adUseClient); } catch (_com_error &e) { CString strstring = e.Description(); //AfxMessageBox(L"SQL用户名或密码错误!”); return false; } return true; } bool CSqlDatas::ConnectServerModTest(CString m_strDBIp) { HRESULT hr = CoInitialize(NULL); // 初始化COM环境 if (FAILED(hr)) return false; CString aStrConn; aStrConn.Format(_T(“driver=MySQL ODBC 8.0 ANSI Driver;server=%s;database=jeesite;uid=;pwd=”), m_strDBIp); hr = m_pConn.CreateInstance(__uuidof(Connection)); if (FAILED(hr)) { AfxMessageBox(L"SQL异常!“); return false; } try { hr = m_pConn->Open((_bstr_t)aStrConn, _T(“root”), _T(“admin”), adConnectUnspecified); m_pConn->PutCursorLocation(adUseClient); } catch (_com_error &e) { CString strstring = e.Description(); //AfxMessageBox(L"SQL用户名或密码错误!”); return false; } return true; } bool CSqlDatas::ConnectServer2(CString m_strDBIp) { HRESULT hr = CoInitialize(NULL); // 初始化COM环境 if (FAILED(hr)) return false; CString aStrConn; aStrConn.Format(_T(“driver=SQL Server;server=%s;database=MDS;uid=;pwd=”), m_strDBIp); hr = m_pConn.CreateInstance(__uuidof(Connection)); if (FAILED(hr)) { AfxMessageBox(L"SQL异常!“); return false; } try { hr = m_pConn->Open((_bstr_t)aStrConn, _T(“mds”), _T(“password”), adConnectUnspecified); m_pConn->PutCursorLocation(adUseClient); } catch (_com_error &e) { CString strstring = e.Description(); //AfxMessageBox(L"SQL用户名或密码错误!”); return false; } return true; } void CSqlDatas::CloseServer() { //m_pConn->Close(); CoInitialize(NULL);//20230605 zxm修复因高频调用CoUninitialize函数使Creo的OLE对象无法播放的问题 CoUninitialize(); //注销COM库 col_names.clear(); } bool CSqlDatas::LinkDataTable(_variant_t Source) { m_recordPtr.CreateInstance(__uuidof(Recordset)); try { m_recordPtr->Open(Source, m_pConn.GetInterfacePtr(), adOpenStatic,//静态 adLockOptimistic,//乐观封锁法 adCmdText); } catch (_com_error e) { //AfxMessageBox(e.Description()); return FALSE; } return TRUE; } bool CSqlDatas::CollectPbiDatas(vector<vector> &datas) { datas.clear(); vector row_datas; long row_count = m_recordPtr->RecordCount; if (row_count > 10000) { AfxMessageBox(L"搜索结果过于庞大,请增加关键字数量"); return FALSE; } for (long i = 1; i <= row_count; i++) { GetLineDatas(i, row_datas); datas.push_back(row_datas); row_datas.clear(); } return true; } bool CSqlDatas::CollectAllDatas(vector<vector> &datas) { datas.clear(); vector row_datas; long row_count = m_recordPtr->RecordCount; for (long i = 1; i <= row_count; i++) { GetLineDatas(i, row_datas); datas.push_back(row_datas); row_datas.clear(); } return true; } void CSqlDatas::GetLineDatas(long line, vector &datas) { data2 rowdata; long count = m_recordPtr->GetFields()->GetCount(); m_recordPtr->MoveFirst(); m_recordPtr->Move((long)line - 1); for (long j = 0; j<count; j++) { rowdata.ColumnValue = m_recordPtr->GetFields()->GetItem(j)->GetName(); rowdata.LineValue = m_recordPtr->GetCollect(rowdata.ColumnValue); if (rowdata.LineValue.vt == VT_NULL) rowdata.LineValue = “”; datas.push_back(rowdata); } } bool CSqlDatas::GetColNames(vector<_variant_t> &col_names) { long count = m_recordPtr->GetFields()->GetCount(); if (count<1) { AfxMessageBox(_T(“没有列名称”)); return FALSE; } for (long j = 0; j<count; j++) { _variant_t name = m_recordPtr->GetFields()->GetItem(j)->GetName(); col_names.push_back(name); } return TRUE; } bool CSqlDatas::CheckTable2(vector input_lines, data2 input_data, vector &output_lines)/!<过滤搜索/ { if (input_lines.empty()) return TRUE; _variant_t lineVal; int num = 0; for (int i = 0; i < (int)input_lines.size(); i++) { m_recordPtr->MoveFirst(); m_recordPtr->Move(input_lines[i] - 1); lineVal = m_recordPtr->GetCollect(input_data.ColumnValue); num = m_recordPtr->AbsolutePosition; if (lineVal != input_data.LineValue) continue; output_lines.push_back(num); } if ((int)output_lines.size()<1) return FALSE; return TRUE; } bool CSqlDatas::CollectLimiteDatas(vector inputDates, vector<vector> &outputDatas) { vector inLines, outLines; vector datas; bool BL = TRUE; long row_count = m_recordPtr->RecordCount; for (int i = 1; i <= row_count; i++) inLines.push_back(i); for (int i = 0; i<(int)inputDates.size(); i++) { if (CString(inputDates[i].LineValue) == “”) continue; outLines.clear(); BL = CheckTable2(inLines, inputDates[i], outLines); inLines.clear(); std::copy(outLines.begin(), outLines.end(), std::back_inserter(inLines)); } for (int i = 0; i<(int)outLines.size(); i++) { GetLineDatas(outLines[i], datas); outputDatas.push_back(datas); datas.clear(); } outLines.clear(); return BL; } bool CSqlDatas::AddData(vector LineDatas) { if (LineDatas.empty()) return FALSE; _variant_t varBookmark; try { long count = m_recordPtr->RecordCount; if (count>0) m_recordPtr->MoveLast(); m_recordPtr->AddNew(LineDatas[0].ColumnValue,/LineDatas[0].LineValue/“”); ChangeData(count, LineDatas); } catch (_com_error&e) { AfxMessageBox(e.Description()); return FALSE; } return TRUE; } bool CSqlDatas::AddLine(vector LineDatas) { try { if (m_recordPtr->RecordCount>0) m_recordPtr->MoveLast(); m_recordPtr->AddNew(); for (int i = 0; i<(int)LineDatas.size(); i++) { _variant_t va = LineDatas[i].ColumnValue; _variant_t va2 = LineDatas[i].LineValue; if (va2.vt == VT_BSTR && ((CString)va2) == "") { // 如果是空字符串 则不插 //va2 = 'NULL'; // 插入效果是 'NULL'的ASCI码 //va2 = "NULL"; // 插入效果是 'NULL'字符串 //va2 = ""; // 插入效果是 空白 continue; // 直接跳过不插才是 为 NULL } if (va2.vt == VT_INT) { m_recordPtr->PutCollect(va, (_variant_t)va2.iVal);// 插入整数 } else { m_recordPtr->PutCollect(va, va2); } } m_recordPtr->Update(); // for 完了 填满了行后在update } catch (_com_error* e) { AfxMessageBox(e->Description()); return false; } return true; } void CSqlDatas::ChangeData(long i, vector datas) { if (datas.empty()) return; m_recordPtr->MoveFirst(); if (i>0) m_recordPtr->Move(i); for (int j = 0; j<(int)datas.size(); j++) { if (CString(datas[j].ColumnValue) == CString(“简图”)) continue; m_recordPtr->Update(datas[j].ColumnValue, datas[j].LineValue); } } void CSqlDatas::DeleteData(int i) { m_recordPtr->MoveFirst(); m_recordPtr->Move(i); m_recordPtr->Delete(adAffectCurrent); } void CSqlDatas::DeleteAll() { long item_num = m_recordPtr->RecordCount; if (item_num == 0) return; m_recordPtr->MoveFirst(); while (!m_recordPtr->adoEOF) { m_recordPtr->Delete(adAffectCurrent); m_recordPtr->MoveNext(); } } void CSqlDatas::TableSort(_bstr_t Criteria) { m_recordPtr->PutSort(Criteria); } bool CSqlDatas::CheckMainColumnVal(data2 cdata) { m_recordPtr->MoveFirst(); while (!m_recordPtr->adoEOF) try { _variant_t valStr = m_recordPtr->GetCollect(cdata.ColumnValue); if (valStr == cdata.LineValue) return FALSE; m_recordPtr->MoveNext(); } catch (_com_error e) { AfxMessageBox(e.Description()); return FALSE; } return TRUE; } void CSqlDatas::CollectComboCtr(_bstr_t typeStr, vector<_variant_t> &ComboStr) { if (m_recordPtr->RecordCount<1) return; m_recordPtr->PutSort(typeStr); m_recordPtr->MoveFirst(); _variant_t valStr1 = NULL; while (!m_recordPtr->adoEOF) { try { _variant_t valStr2 = m_recordPtr->GetCollect(typeStr); if (valStr1 == valStr2 || valStr2.vt == VT_NULL/*||CString(valStr2)==CString("")*/) { m_recordPtr->MoveNext(); continue; } ComboStr.push_back(valStr2); valStr1 = valStr2; } catch (_com_error e) { AfxMessageBox(e.Description()); return; } m_recordPtr->MoveNext(); } }换成qt
最新发布
08-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值