|  | #include <stdio.h> | 
        
          |  | #include <windows.h> | 
        
          |  | #include <D3dkmthk.h> | 
        
          |  | #include <d3d11.h> | 
        
          |  | #include <d3d11_1.h> | 
        
          |  | #pragma comment(lib, "d3d11") | 
        
          |  |  | 
        
          |  | extern "C" | 
        
          |  | { | 
        
          |  | __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; | 
        
          |  | __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; | 
        
          |  | } | 
        
          |  |  | 
        
          |  | /* | 
        
          |  | * Simple hexdump | 
        
          |  | * https://gist.github.com/ccbrown/9722406 | 
        
          |  | */ | 
        
          |  | void DumpHex(const void* data, size_t size) { | 
        
          |  | char ascii[17]; | 
        
          |  | size_t i, j; | 
        
          |  | ascii[16] = '\0'; | 
        
          |  | for (i = 0; i < size; ++i) { | 
        
          |  | printf(" %02X", ((unsigned char*)data)[i]); | 
        
          |  | if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { | 
        
          |  | ascii[i % 16] = ((unsigned char*)data)[i]; | 
        
          |  | } | 
        
          |  | else { | 
        
          |  | ascii[i % 16] = '.'; | 
        
          |  | } | 
        
          |  | if ((i + 1) % 8 == 0 || i + 1 == size) { | 
        
          |  | printf(" "); | 
        
          |  | if ((i + 1) % 16 == 0) { | 
        
          |  | printf("|  %s \n", ascii); | 
        
          |  | //printf("\n"); | 
        
          |  | } | 
        
          |  | else if (i + 1 == size) { | 
        
          |  | ascii[(i + 1) % 16] = '\0'; | 
        
          |  | if ((i + 1) % 16 <= 8) { | 
        
          |  | printf(" "); | 
        
          |  | } | 
        
          |  | for (j = (i + 1) % 16; j < 16; ++j) { | 
        
          |  | printf("   "); | 
        
          |  | } | 
        
          |  | printf("|  %s \n", ascii); | 
        
          |  | //printf("\n"); | 
        
          |  | } | 
        
          |  | } | 
        
          |  | } | 
        
          |  | } | 
        
          |  |  | 
        
          |  | /* | 
        
          |  | * Seems to be DXGI part of the data, representing a texture desc | 
        
          |  | */ | 
        
          |  | typedef struct DXGI_PRIVATEDATA { | 
        
          |  | UINT Size; | 
        
          |  | INT Id; | 
        
          |  | UINT Width; | 
        
          |  | UINT Height; | 
        
          |  | DXGI_FORMAT Format; | 
        
          |  | UINT ArraySize; | 
        
          |  | INT ReadOnly; | 
        
          |  | INT Sync; | 
        
          |  | INT KeyedMutex; | 
        
          |  | INT unk0; | 
        
          |  | INT NTHandle; | 
        
          |  | INT uin1; | 
        
          |  | INT unk2; | 
        
          |  | INT unk3; | 
        
          |  | D3D11_RESOURCE_DIMENSION Dimension; | 
        
          |  | D3D11_TEXTURE2D_DESC Desc; | 
        
          |  | } DXGI_PRIVATEDATA; | 
        
          |  |  | 
        
          |  | /* | 
        
          |  | * Seems to be the ICD implementation part of the data (vendor specific) | 
        
          |  | */ | 
        
          |  | #pragma pack(1) | 
        
          |  | typedef struct UNK_TOTALDRIVERPRIVATEDATA { | 
        
          |  | const char unk_pad0[0x13E]; | 
        
          |  | UINT pMagicValue; | 
        
          |  | }; | 
        
          |  |  | 
        
          |  | /* | 
        
          |  | * Helper to debug D3DKMT returns | 
        
          |  | */ | 
        
          |  | BOOL CHECK_NT(NTSTATUS status, const char* error) | 
        
          |  | { | 
        
          |  | if (FAILED(status)) | 
        
          |  | { | 
        
          |  | printf("Failed (%08X) %s\n", status, error); | 
        
          |  | return true; | 
        
          |  | } | 
        
          |  | printf("Success: %s\n", error); | 
        
          |  | return false; | 
        
          |  | } | 
        
          |  | #define CHECK_NTSTATUS(X) if(CHECK_NT(NT_RETURN, X)) return 0; | 
        
          |  |  | 
        
          |  |  | 
        
          |  | int main() | 
        
          |  | { | 
        
          |  | UINT WIDTH = 1000; | 
        
          |  | UINT HEIGHT = 500; | 
        
          |  |  | 
        
          |  | // Create a D3D11 device | 
        
          |  | ID3D11Device* device = NULL; | 
        
          |  | ID3D11DeviceContext* context = NULL; | 
        
          |  | UINT creation_flags = (D3D11_CREATE_DEVICE_VIDEO_SUPPORT | D3D11_CREATE_DEVICE_BGRA_SUPPORT); | 
        
          |  | static const D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3,  D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; | 
        
          |  | D3D_FEATURE_LEVEL* ftret = NULL; | 
        
          |  | if (FAILED(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creation_flags, feature_levels, 7, D3D11_SDK_VERSION, &device, ftret, &context))) return NULL; | 
        
          |  | printf("Success: D3D11CreateDevice\n"); | 
        
          |  |  | 
        
          |  | // Create a texture | 
        
          |  | ID3D11Texture2D* texture = NULL; | 
        
          |  | D3D11_TEXTURE2D_DESC texDesc{ 0 }; | 
        
          |  | texDesc.Width = WIDTH; | 
        
          |  | texDesc.Height = HEIGHT; | 
        
          |  | texDesc.MipLevels = 1; | 
        
          |  | texDesc.ArraySize = 1; | 
        
          |  | texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; | 
        
          |  | texDesc.SampleDesc.Count = 1; | 
        
          |  | texDesc.SampleDesc.Quality = 0; | 
        
          |  | texDesc.Usage = D3D11_USAGE_DEFAULT; | 
        
          |  | texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; | 
        
          |  | texDesc.CPUAccessFlags = 0; | 
        
          |  | texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED; | 
        
          |  | if (FAILED(device->CreateTexture2D(&texDesc, NULL, &texture))) return NULL; | 
        
          |  | printf("Success: ID3D11Device::CreateTexture2D (%dx%d)\n", texDesc.Width, texDesc.Height); | 
        
          |  |  | 
        
          |  | // Share the texture to a NT HANDLE | 
        
          |  | HANDLE		   ntHandle = 0; | 
        
          |  | IDXGIResource* dxgiRsrc = 0; | 
        
          |  | if (SUCCEEDED(texture->QueryInterface(&dxgiRsrc))) | 
        
          |  | { | 
        
          |  | IDXGIResource1* dxgiResource = 0; | 
        
          |  | if (SUCCEEDED(dxgiRsrc->QueryInterface(&dxgiResource))) | 
        
          |  | { | 
        
          |  | if (SUCCEEDED(dxgiResource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, NULL, &ntHandle))) | 
        
          |  | { | 
        
          |  | printf("Success: IDXGIResource::CreateSharedHandle (NTHANDLE: %08X)\n", ntHandle); | 
        
          |  | } | 
        
          |  | dxgiResource->Release(); | 
        
          |  | } | 
        
          |  | dxgiRsrc->Release(); | 
        
          |  | } | 
        
          |  | NTSTATUS NT_RETURN = 0; | 
        
          |  |  | 
        
          |  | /* | 
        
          |  | D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME OPENADAPTERFROMGDIDISPLAYNAME{ 0 }; | 
        
          |  | wsprintf(OPENADAPTERFROMGDIDISPLAYNAME.DeviceName, L"\\\\.\\DISPLAY1"); | 
        
          |  | NT_RETURN = D3DKMTOpenAdapterFromGdiDisplayName(&OPENADAPTERFROMGDIDISPLAYNAME); | 
        
          |  | CHECK_NTSTATUS("D3DKMTOpenAdapterFromGdiDisplayName"); | 
        
          |  | D3DKMT_HANDLE hAdapter = OPENADAPTERFROMGDIDISPLAYNAME.hAdapter; | 
        
          |  | */ | 
        
          |  |  | 
        
          |  | D3DKMT_ENUMADAPTERS ENUMADAPTERS{ 0 }; | 
        
          |  | NT_RETURN = D3DKMTEnumAdapters(&ENUMADAPTERS); | 
        
          |  | CHECK_NTSTATUS("D3DKMTEnumAdapters"); | 
        
          |  |  | 
        
          |  | D3DKMT_HANDLE hAdapter = ENUMADAPTERS.Adapters[0].hAdapter; | 
        
          |  |  | 
        
          |  | // Create a kmt device, what is this device? i dont know, but we close it later | 
        
          |  | D3DKMT_CREATEDEVICE CREATEDEVICE{ 0 }; | 
        
          |  | CREATEDEVICE.hAdapter = hAdapter; | 
        
          |  | NT_RETURN = D3DKMTCreateDevice(&CREATEDEVICE); | 
        
          |  | CHECK_NTSTATUS("D3DKMTCreateDevice"); | 
        
          |  |  | 
        
          |  | // Some debug info about the gl icd and device | 
        
          |  | D3DKMT_QUERYADAPTERINFO QUERYADAPTERINFO{ 0 }; | 
        
          |  | QUERYADAPTERINFO.hAdapter = hAdapter; | 
        
          |  | QUERYADAPTERINFO.Type = KMTQAITYPE_ADAPTERREGISTRYINFO; | 
        
          |  | D3DKMT_ADAPTERREGISTRYINFO ADAPTERREGISTRYINFO{ 0 }; | 
        
          |  | QUERYADAPTERINFO.PrivateDriverDataSize = sizeof(D3DKMT_ADAPTERREGISTRYINFO); | 
        
          |  | QUERYADAPTERINFO.pPrivateDriverData = &ADAPTERREGISTRYINFO; | 
        
          |  | NT_RETURN = D3DKMTQueryAdapterInfo(&QUERYADAPTERINFO); | 
        
          |  | CHECK_NTSTATUS("D3DKMTQueryAdapterInfo"); | 
        
          |  | wprintf(L" Adapter: %s\n BIOS: %s\n DAC: %s\n CHIP: %s\n", ADAPTERREGISTRYINFO.AdapterString, ADAPTERREGISTRYINFO.BiosString, ADAPTERREGISTRYINFO.DacType, ADAPTERREGISTRYINFO.ChipType); | 
        
          |  |  | 
        
          |  | D3DKMT_OPENGLINFO OPENGLINFO{ 0 }; | 
        
          |  | QUERYADAPTERINFO.Type = KMTQAITYPE_UMOPENGLINFO; | 
        
          |  | QUERYADAPTERINFO.PrivateDriverDataSize = sizeof(D3DKMT_OPENGLINFO); | 
        
          |  | QUERYADAPTERINFO.pPrivateDriverData = &OPENGLINFO; | 
        
          |  | NT_RETURN = D3DKMTQueryAdapterInfo(&QUERYADAPTERINFO); | 
        
          |  | CHECK_NTSTATUS("D3DKMTQueryAdapterInfo"); | 
        
          |  | wprintf(L" OpenGL ICD: %s\n Version: %d\n Flags: %d\n", OPENGLINFO.UmdOpenGlIcdFileName, OPENGLINFO.Version, OPENGLINFO.Flags); | 
        
          |  |  | 
        
          |  | // Obtain the sizes of the private data structures | 
        
          |  | D3DKMT_QUERYRESOURCEINFOFROMNTHANDLE QUERYRESOURCEINFOFROMNTHANDLE{ 0 }; | 
        
          |  | QUERYRESOURCEINFOFROMNTHANDLE.hDevice = CREATEDEVICE.hDevice; | 
        
          |  | QUERYRESOURCEINFOFROMNTHANDLE.hNtHandle = ntHandle; | 
        
          |  | NT_RETURN = D3DKMTQueryResourceInfoFromNtHandle(&QUERYRESOURCEINFOFROMNTHANDLE); | 
        
          |  | CHECK_NTSTATUS("D3DKMTQueryResourceInfoFromNtHandle"); | 
        
          |  | wprintf(L" PrivateRuntimeDataSize: %d\n TotalPrivateDriverDataSize: %d\n", QUERYRESOURCEINFOFROMNTHANDLE.PrivateRuntimeDataSize, QUERYRESOURCEINFOFROMNTHANDLE.TotalPrivateDriverDataSize); | 
        
          |  |  | 
        
          |  | /* non nt handles? (KMT) | 
        
          |  | D3DKMT_QUERYRESOURCEINFO QUERYRESOURCEINFO{ 0 }; | 
        
          |  | ntret = D3DKMTQueryResourceInfo(&QUERYRESOURCEINFO); | 
        
          |  | */ | 
        
          |  |  | 
        
          |  | // read the private data structures | 
        
          |  | D3DKMT_OPENRESOURCEFROMNTHANDLE OPENRESOURCEFROMNTHANDLE{ 0 }; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.hDevice = CREATEDEVICE.hDevice; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.hNtHandle = ntHandle; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.NumAllocations = QUERYRESOURCEINFOFROMNTHANDLE.NumAllocations; | 
        
          |  | D3DDDI_OPENALLOCATIONINFO2* OPENALLOCATIONINFO2 = (D3DDDI_OPENALLOCATIONINFO2*)calloc(sizeof(D3DDDI_OPENALLOCATIONINFO2), QUERYRESOURCEINFOFROMNTHANDLE.NumAllocations); | 
        
          |  | OPENRESOURCEFROMNTHANDLE.pOpenAllocationInfo2 = OPENALLOCATIONINFO2; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.KeyedMutexPrivateRuntimeDataSize = 0; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.PrivateRuntimeDataSize = QUERYRESOURCEINFOFROMNTHANDLE.PrivateRuntimeDataSize; | 
        
          |  | void* pPrivateRuntimeData = (void*)calloc(1, QUERYRESOURCEINFOFROMNTHANDLE.PrivateRuntimeDataSize); | 
        
          |  | OPENRESOURCEFROMNTHANDLE.pPrivateRuntimeData = pPrivateRuntimeData; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.ResourcePrivateDriverDataSize = QUERYRESOURCEINFOFROMNTHANDLE.ResourcePrivateDriverDataSize; | 
        
          |  | void* pResourcePrivateDriverData = (void*)calloc(1, QUERYRESOURCEINFOFROMNTHANDLE.ResourcePrivateDriverDataSize); | 
        
          |  | OPENRESOURCEFROMNTHANDLE.pResourcePrivateDriverData = pResourcePrivateDriverData; | 
        
          |  | OPENRESOURCEFROMNTHANDLE.TotalPrivateDriverDataBufferSize = QUERYRESOURCEINFOFROMNTHANDLE.TotalPrivateDriverDataSize; | 
        
          |  | void* pTotalPrivateDriverDataBuffer = (void*)calloc(1, QUERYRESOURCEINFOFROMNTHANDLE.TotalPrivateDriverDataSize); | 
        
          |  | OPENRESOURCEFROMNTHANDLE.pTotalPrivateDriverDataBuffer = pTotalPrivateDriverDataBuffer; | 
        
          |  | NT_RETURN = D3DKMTOpenResourceFromNtHandle(&OPENRESOURCEFROMNTHANDLE); | 
        
          |  | CHECK_NTSTATUS("D3DKMTOpenResourceFromNtHandle"); | 
        
          |  |  | 
        
          |  | // hex dump the structures | 
        
          |  | printf("PrivateRuntimeData:\n"); | 
        
          |  | DumpHex(OPENRESOURCEFROMNTHANDLE.pPrivateRuntimeData, OPENRESOURCEFROMNTHANDLE.PrivateRuntimeDataSize); | 
        
          |  | printf("TotalPrivateDriverData:\n"); | 
        
          |  | DumpHex(OPENRESOURCEFROMNTHANDLE.pTotalPrivateDriverDataBuffer, OPENRESOURCEFROMNTHANDLE.TotalPrivateDriverDataBufferSize); | 
        
          |  |  | 
        
          |  | // check sizes can be holded in our struct, seems to be constant, PrivateRuntimeDataSize: 104 and TotalPrivateDriverDataSize: 594 (at least on nvidia ICD) | 
        
          |  | if (sizeof(UNK_TOTALDRIVERPRIVATEDATA) > QUERYRESOURCEINFOFROMNTHANDLE.TotalPrivateDriverDataSize) return 0; | 
        
          |  | if (sizeof(DXGI_PRIVATEDATA) > QUERYRESOURCEINFOFROMNTHANDLE.PrivateRuntimeDataSize) return 0; | 
        
          |  |  | 
        
          |  | // cast buffers to readable structures | 
        
          |  | DXGI_PRIVATEDATA* dv = (DXGI_PRIVATEDATA*)OPENRESOURCEFROMNTHANDLE.pPrivateRuntimeData; | 
        
          |  | UNK_TOTALDRIVERPRIVATEDATA* pv = (UNK_TOTALDRIVERPRIVATEDATA*)OPENRESOURCEFROMNTHANDLE.pTotalPrivateDriverDataBuffer; | 
        
          |  |  | 
        
          |  | // debug | 
        
          |  | printf(" Texture size: %dx%d\n", dv->Width, dv->Height); | 
        
          |  | printf(" Texture format: %d MiscFlags: %d\n", dv->Format, dv->Desc.MiscFlags); | 
        
          |  | printf("\n Texture size: %d Bytes\n\n", pv->pMagicValue); | 
        
          |  |  | 
        
          |  | // the handle has been opened and an allocation is made, somehow this seems to close it | 
        
          |  | D3DKMT_DESTROYALLOCATION DESTROYALLOCATION{ 0 }; | 
        
          |  | DESTROYALLOCATION.hDevice = CREATEDEVICE.hDevice; | 
        
          |  | DESTROYALLOCATION.hResource = OPENRESOURCEFROMNTHANDLE.hResource; | 
        
          |  | NT_RETURN = D3DKMTDestroyAllocation(&DESTROYALLOCATION); | 
        
          |  | CHECK_NTSTATUS("D3DKMTDestroyAllocation"); | 
        
          |  |  | 
        
          |  | // not sure if i need to do this, i guess its ok¿? | 
        
          |  | CloseHandle(ntHandle); | 
        
          |  |  | 
        
          |  | // close the staging device | 
        
          |  | D3DKMT_DESTROYDEVICE DESTROYDEVICE{ 0 }; | 
        
          |  | DESTROYDEVICE.hDevice = CREATEDEVICE.hDevice; | 
        
          |  | NT_RETURN = D3DKMTDestroyDevice(&DESTROYDEVICE); | 
        
          |  | CHECK_NTSTATUS("D3DKMTDestroyDevice"); | 
        
          |  |  | 
        
          |  | // free resources | 
        
          |  | //ReleaseDC(0, OPENADAPTERFROMHDC.hDc); | 
        
          |  | free(OPENALLOCATIONINFO2); | 
        
          |  | free(pPrivateRuntimeData); | 
        
          |  | free(pResourcePrivateDriverData); | 
        
          |  | free(pTotalPrivateDriverDataBuffer); | 
        
          |  | texture->Release(); | 
        
          |  | context->Release(); | 
        
          |  | device->Release(); | 
        
          |  |  | 
        
          |  | getchar(); | 
        
          |  | return 0; | 
        
          |  | } | 
        
          |  |  |