ddpdb.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:49k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /* Windows include files: */
  36. #include <windows.h>
  37. #include <regstr.h>
  38. #include <ddraw.h>
  39. #ifdef IMPORT
  40. #include <initguid.h>
  41. #endif
  42. /* standard libraries: */
  43. #include <stdio.h>
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <string.h>
  47. /* our headers: */
  48. #include "hxdx5032.h"   // for win95 driver info in CFullScreenInfo
  49. #include "ddpdb.h"
  50. #include "colormap.h"
  51. #include "hxdllldr.h"
  52. #define F(cid)          (1U << (cid))   /* converts CID into a bitmask  */
  53. #define MAX_BUF         512
  54. #define ENUM_MAX        6
  55. /*
  56.  * DirectDraw profiles:
  57.  */
  58. #define DDPDB_MAGIC     "DDPDB"
  59. #define DDPDB_VERSION   0x100
  60. #define MAXPROFILES     256
  61. static struct
  62. {
  63.     char            szMagic[8];                 /* some identifier      */
  64.     DWORD           dwVersion;                  /* database version     */
  65.     DWORD           dwNumProfiles;              /* # of records         */
  66.     DDDEVICEPROFILE ddProfiles[MAXPROFILES];    /* data                 */
  67. } DDPDB =
  68. {
  69.     DDPDB_MAGIC,
  70.     DDPDB_VERSION,
  71.     30,  /* # of profiles !!!!!!!!! */
  72.     {{
  73.         VER_PLATFORM_WIN32_WINDOWS,
  74.         {"ATI Rage II+ PCI (ati_m64)", "ati_m64.drv", 0x6b8,0x4000a,
  75.         0x1002, 0x4755, 0x0, 0x9a5b,
  76.         {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  77.         /* buggy driver... do NOT use overlays !!!: */
  78.         {0, 0, 0, 0, 0},
  79.         /* blits (use YUVs only !!!): */
  80.         {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  81.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  82.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  83.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  84.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY)}
  85.     },
  86.     {
  87. VER_PLATFORM_WIN32_WINDOWS,
  88. {"RAGE PRO TURBO AGP 2X (English)",
  89.  "macxdd32.dll",
  90.  0x10937,0x4000a,
  91.  0x1002, 0x4742, 0x47421002, 0x5c, 
  92.  {0xd7b71ee2,0x402,0x11cf,{0x85,0x7a,0x43,0x67,0xf9,0xc2,0xc9,0x35}}},
  93.         /* do NOT use overlays !!!: */
  94.         {0, 0, 0, 0, 0},
  95.         /* no blits either: */
  96.         {0, 0, 0, 0, 0}
  97.     },
  98.      {
  99.          VER_PLATFORM_WIN32_NT,
  100.          {"1002-4C46-03",
  101.           "ati2dvai.dll",
  102.           0x10426,0x5000c,
  103.           0x3320334d, 0x7a484d33, 0x50474128, 0x400029,
  104.           {0x800,0x4,0x0,{0x48,0x7,0x13,0x0,0xffffffd2,0x2c,0x40,0x0}}},
  105.          /* do NOT use overlays !!!: */
  106.          {0, 0, 0, 0, 0},
  107.          /* no blits either: */
  108.          {0, 0, 0, 0, 0}
  109.     },
  110.     {
  111.         VER_PLATFORM_WIN32_WINDOWS,
  112.         {"Matrox Millennium G200 AGP", "MGAXDD32.DLL", 0x1100e,0x4000a, 0x102B, 0x521, 0, 0,
  113.         {0xd7b71ecb,0x4661,0x11cf,{0xbe,0x73,0x01,0x20,0xa5,0xc2,0xc9,0x35}}},
  114.         /* overlays (use YUVs only): */
  115.         {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  116.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  117.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  118.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  119.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY)},
  120.         /* blits (use YUVs & matching RGBs): */
  121.         {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB32),
  122.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB24),
  123.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB565),
  124.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB555),
  125.         F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB8)}
  126.     },
  127.     {
  128.         VER_PLATFORM_WIN32_NT,
  129.         {"Matrox Millennium G200 AGP", "mga64.dll", 0x0,0x40000,
  130.         /* MGA-G200 B8 R1: */ 0x2d41474d, 0x30303247, 0x20384220, 0x03152, {0,0,0,{0,0,0,0,0,0,0,0}}},
  131.         /* do NOT use overlays !!!: */
  132.         {0, 0, 0, 0, 0},
  133.         /* blits (use YUY2s & matching RGBs only): */
  134.         {F(CID_YUY2) + F(CID_RGB32),
  135.          F(CID_YUY2) + F(CID_RGB24),
  136.          F(CID_YUY2) + F(CID_RGB565),
  137.          F(CID_YUY2) + F(CID_RGB555),
  138.          F(CID_YUY2) + F(CID_RGB8)}
  139.     },
  140.     {
  141.         VER_PLATFORM_WIN32_NT,
  142.         {"Matrox Millennium G200 AGP", "tsirchnl.dll", 0xc9,0x70008,
  143.         0x2d41474d, 0x30303247, 0x20384220, 0x4b003152,
  144.         {0x4f4e4d4c,0x5150,0x5352,{0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b}}},
  145.         /* do NOT use overlays !!!: */
  146.         {0, 0, 0, 0, 0},
  147.         /* blits (use YUY2s & matching RGBs only): */
  148.         {F(CID_YUY2) + F(CID_RGB32),
  149.          F(CID_YUY2) + F(CID_RGB24),
  150.          F(CID_YUY2) + F(CID_RGB565),
  151.          F(CID_YUY2) + F(CID_RGB555),
  152.          F(CID_YUY2) + F(CID_RGB8)}
  153.     },
  154.     {
  155.         VER_PLATFORM_WIN32_WINDOWS,
  156.         {"Matrox Millennium II PowerDesk", "MGAXDD32.DLL", 0x10ee2,0x4000a,
  157.         0x102b, 0x51b, 0x0, 0x0,
  158.         {0xd7b71ecb,0x465b,0x11cf,{0x52,0x6d,0x1,0x20,0xa5,0xc2,0xc9,0x35}}},
  159.         /* does not have overlays... */
  160.         {0, 0, 0, 0, 0},
  161.         /* blits (use YUY2s only): */
  162.         {F(CID_YUY2),
  163.          F(CID_YUY2),
  164.          F(CID_YUY2),
  165.          F(CID_YUY2),
  166.          F(CID_YUY2)}
  167.     },
  168.     {
  169.         VER_PLATFORM_WIN32_WINDOWS,
  170.         {"Matrox Millennium II PowerDesk", "MGAXDD32.DLL", 0xe2e,0x40003,
  171.         0x102b, 0x51b, 0x0, 0x0,
  172.         {0xd7b71ecb,0x465b,0x11cf,{0x9e,0x6d,0x0,0x20,0xac,0xc2,0xc9,0x35}}},
  173.         /* does not have overlays... */
  174.         {0, 0, 0, 0, 0},
  175.         /* blits (use YUY2s only): */
  176.         {F(CID_YUY2),
  177.          F(CID_YUY2),
  178.          F(CID_YUY2),
  179.          F(CID_YUY2),
  180.          F(CID_YUY2)}
  181.     },
  182.     {
  183.         VER_PLATFORM_WIN32_WINDOWS,
  184.         {"Matrox Millennium II PCI", "mgapdx64.drv", 0x110b8,0x4000a,
  185.         0x102b, 0x51b, 0x0, 0x25b,
  186.         {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  187.         /* does not have overlays... */
  188.         {0, 0, 0, 0, 0},
  189.         /* blits (use YUY2s only): */
  190.         {F(CID_YUY2),
  191.          F(CID_YUY2),
  192.          F(CID_YUY2),
  193.          F(CID_YUY2),
  194.          F(CID_YUY2)}
  195.     },
  196.     {
  197.         VER_PLATFORM_WIN32_WINDOWS,
  198.         {"Diamond Viper V330", "vprddle.DLL", 0x10080,0x4000a, 0x12d2, 0x18, 0, 0,
  199.         {0xd7b71c32,0x4358,0x11cf,{0x30,0x63,0x01,0x20,0xa5,0xc2,0xc9,0x35}}},
  200.         /* overlays (use YUY2 & UYVY only): */
  201.         {F(CID_YUY2) + F(CID_UYVY),
  202.         F(CID_YUY2) + F(CID_UYVY),
  203.         F(CID_YUY2) + F(CID_UYVY),
  204.         F(CID_YUY2) + F(CID_UYVY),
  205.         F(CID_YUY2) + F(CID_UYVY)},
  206.         /* blits (use YUY2, UYVY & matching RGBs): */
  207.         {F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB32),
  208.         F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB24),
  209.         F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB565),
  210.         F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB555),
  211.         F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB8)}
  212.     },
  213.     {
  214. VER_PLATFORM_WIN32_WINDOWS,
  215. {"NVIDIA GeForce 256 AGP Plus (Dell)",
  216.  "NVDD32.DLL",
  217.  0x10179,0x4000c,
  218.  0x10de, 0x100, 0x810de, 0x10, 
  219. {0xd7b71e3e,0x4240,0x11cf,{0x17,0x72,0x9,0x20,0xb3,0xc2,0xc9,0x35}}},
  220.         /* do NOT use overlays !!!: */
  221.         {0, 0, 0, 0, 0},
  222.         /* no blits either: */
  223.         {0, 0, 0, 0, 0}
  224.     },
  225.     {
  226.         VER_PLATFORM_WIN32_WINDOWS,
  227.         {"Diamond Viper V330", "vprdrvle.drv", 0x1007e, 0x4000a, 0x12d2, 0x18, 0x0, 0x0,
  228.         {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  229.         /* do NOT use overlays !!!: */
  230.         {0, 0, 0, 0, 0},
  231.         /* blits (use YUY2s & matching RGBs only): */
  232.         {F(CID_YUY2) + F(CID_RGB32),
  233.          F(CID_YUY2) + F(CID_RGB24),
  234.          F(CID_YUY2) + F(CID_RGB565),
  235.          F(CID_YUY2) + F(CID_RGB555),
  236.          F(CID_YUY2) + F(CID_RGB8)}
  237.     },
  238.     {
  239. VER_PLATFORM_WIN32_WINDOWS,
  240. {"Diamond Viper V550", "NVDD32.DLL", 0x10170,0x4000c, 0x10de, 0x20, 0x5501092, 0x4,
  241. {0xd7b71e3e,0x4360,0x11cf,{0x52,0x72,0x51,0x25,0xa7,0xc2,0xc9,0x35}}},
  242.         /* do NOT use overlays !!!: */
  243.         {0, 0, 0, 0, 0},
  244.         /* no blits either: */
  245.         {0, 0, 0, 0, 0}
  246.     },
  247.     {
  248. VER_PLATFORM_WIN32_WINDOWS,
  249.         {"[Hercules]  Thriller 3D Series (v 0.81.3539)",
  250.          "v200032.dll",
  251.          0xdd2,0x4000a,
  252.          0x1163, 0x2000, 0x34843, 0x6,
  253. {0xd7b71f83,0x6340,0x11cf,{0x21,0x26,0x3,0x20,0xa3,0xc2,0xc9,0x35}}},
  254.         /* do NOT use overlays !!!: */
  255.         {0, 0, 0, 0, 0},
  256.         /* no blits either: */
  257.         {0, 0, 0, 0, 0}
  258.     },
  259.     {
  260.         VER_PLATFORM_WIN32_NT,
  261.         {"Diamond Multimedia Systems, Inc.  Stealth II G460  Ver. 1.12x0dx0aV",
  262.         "stlthg46.dll", 0x0,0x40000,
  263.         /* Intel740: */  0x65746e49, 0x3034376c, 0, 0, {0,0,0,{0,0,0,0,0,0,0,0}}},
  264.         /* do NOT use overlays !!!: */
  265.         {0, 0, 0, 0, 0},
  266.         /* no blits either: */
  267.         {0, 0, 0, 0, 0}
  268.     },
  269.     {
  270. VER_PLATFORM_WIN32_WINDOWS,
  271. {"STB Lightspeed 128, with STB Vision 95",
  272.  "stbvisn.drv", 0x514,0x40003,
  273.  0x100c, 0x3208, 0x0, 0x0, {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  274.         /* do NOT use overlays !!!: */
  275.         {0, 0, 0, 0, 0},
  276.         /* no blits either: */
  277.         {0, 0, 0, 0, 0}
  278.     },
  279.     {
  280.         VER_PLATFORM_WIN32_WINDOWS,
  281.         {"Diamond SpeedStar A50 for Windows 98", "DMSSA50x.dll", 0xc8,0x4000a,
  282.         0x1039, 0x6326, 0xa501092, 0xb,
  283.         {0xd7b71ed9,0x2066,0x11cf,{0xea,0x73,0x50,0x2a,0xae,0xc2,0xc9,0x35}}},
  284.         /* do NOT use overlays in 16-bit mode !!!: */
  285.         {F(CID_YUY2),
  286.          F(CID_YUY2),
  287.          0,
  288.          0,
  289.          F(CID_YUY2)},
  290.         /* no blits: */
  291.         {0, 0, 0, 0, 0}
  292.     },
  293.     /* these STB cards use nVidia Riva 182zx: */
  294.     {
  295.         VER_PLATFORM_WIN32_WINDOWS,
  296.         {"STB Velocity 128 3D", "stbv128.drv",
  297.         0x10074,0x4000a, 0x12d2, 0x18, 0x0, 0x0, {0,0,0,{0,0,0,0,0,0,0,0}}},
  298.         /* do NOT use overlays !!!: */
  299.         {0, 0, 0, 0, 0},
  300.         /* blits (use YUY2s & matching RGBs only): */
  301.         {F(CID_YUY2) + F(CID_RGB32),
  302.          F(CID_YUY2) + F(CID_RGB24),
  303.          F(CID_YUY2) + F(CID_RGB565),
  304.          F(CID_YUY2) + F(CID_RGB555),
  305.          F(CID_YUY2) + F(CID_RGB8)}
  306.     },
  307.     {
  308.         VER_PLATFORM_WIN32_WINDOWS,
  309.         {"STB Velocity 128 (TV Support)", "STBV128.DRV",
  310.         0x1006d,0x4000a, 0x12d2, 0x18, 0x0, 0x0, {0,0,0,{0,0,0,0,0,0,0,0}}},
  311.         /* do NOT use overlays !!!: */
  312.         {0, 0, 0, 0, 0},
  313.         /* blits (use YUY2s & matching RGBs only): */
  314.         {F(CID_YUY2) + F(CID_RGB32),
  315.          F(CID_YUY2) + F(CID_RGB24),
  316.          F(CID_YUY2) + F(CID_RGB565),
  317.          F(CID_YUY2) + F(CID_RGB555),
  318.          F(CID_YUY2) + F(CID_RGB8)}
  319.     },
  320.     {
  321.         VER_PLATFORM_WIN32_WINDOWS,
  322.         {"STB Lightspeed 128, without STB Vision 95", "stbls128.drv",
  323.         0x514,0x40003, 0x100c, 0x3208, 0x0, 0x0, {0,0,0,{0,0,0,0,0,0,0,0}}},
  324.         /* overlays (use UYVY only): */
  325.         {F(CID_UYVY),
  326.         F(CID_UYVY),
  327.         F(CID_UYVY),
  328.         F(CID_UYVY),
  329.         0 /* this driver has a bug in 8-bit mode!!! */},
  330.         /* blits are not available anyway: */
  331.         {0, 0, 0, 0, 0}
  332.     },
  333.     {
  334.         VER_PLATFORM_WIN32_WINDOWS,
  335.         {"S3 Inc. Trio64V+", "s3_2.drv", 0x1083c,0x4000a,
  336.         0x5333, 0x8811, 0x0, 0x0,
  337.         {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  338.         /* disable overlays: */
  339.         {0, 0, 0, 0, 0},
  340.         /* RGB blits only: */
  341.         {F(CID_RGB32),
  342.          F(CID_RGB24),
  343.          F(CID_RGB565),
  344.          F(CID_RGB555),
  345.          F(CID_RGB8)}
  346.     },
  347.     {
  348.         VER_PLATFORM_WIN32_WINDOWS,
  349.         {"Chips And Technologies, Accelerator (new)", "chipsnd.drv",
  350.         0x3b6,0x40013,0x102c, 0xe0, 0x0, 0x0, {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  351.         /* do NOT use overlays !!!: */
  352.         {0, 0, 0, 0, 0},
  353.         /* blits (use YUY2s & matching RGBs only): */
  354.         {F(CID_YUY2) + F(CID_RGB32),
  355.          F(CID_YUY2) + F(CID_RGB24),
  356.          F(CID_YUY2) + F(CID_RGB565),
  357.          F(CID_YUY2) + F(CID_RGB555),
  358.          F(CID_YUY2) + F(CID_RGB8)}
  359.     },
  360.     {
  361.         VER_PLATFORM_WIN32_WINDOWS,
  362.         {"Cirrus Logic 7548 PCI", "cirrusmm.drv", 0x7ee,0x40003,
  363.          0x1013, 0x38, 0x0, 0x0,
  364.          {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  365.         /* does not have overlays...: */
  366.         {0, 0, 0, 0, 0},
  367.         /* RGB blits only: */
  368.         {F(CID_RGB32),
  369.          F(CID_RGB24),
  370.          F(CID_RGB565),
  371.          F(CID_RGB555),
  372.          F(CID_RGB8)}
  373.     },
  374.     /* NeoMagic controllers (widely used in Dell laptops): */
  375.     {
  376.         VER_PLATFORM_WIN32_WINDOWS,
  377.         {"NeoMagic MagicGraph 128XD", "NmgcDD.dll", 0x10006,0x4000a,
  378.         0x10c8, 0x4, 0x751028, 0x0,
  379.         {0xd7b71e28,0x4344,0x11cf,{0x9e,0x73,0x74,0x20,0xa5,0xc2,0xc9,0x35}}},
  380.         /* overlays (use YUY2 only): */
  381.         {F(CID_YUY2),
  382.         F(CID_YUY2),
  383.         F(CID_YUY2),
  384.         F(CID_YUY2),
  385.         F(CID_YUY2)},
  386.         /* don't use BLITS!!!: */
  387.         {0, 0, 0, 0, 0}
  388.     },
  389.     {
  390.         VER_PLATFORM_WIN32_WINDOWS,
  391.         {"NeoMagic MagicGraph 128XD", "Nmgc.drv",
  392.         0x10004,0x4000a, 0x10c8, 0x4, 0x0, 0x0, {0,0,0,{0,0,0,0,0,0,0,0}}},
  393.         /* overlays (use YUY2 only): */
  394.         {F(CID_YUY2),
  395.         F(CID_YUY2),
  396.         F(CID_YUY2),
  397.         F(CID_YUY2),
  398.         F(CID_YUY2)},
  399.         /* don't use BLITS!!!: */
  400.         {0, 0, 0, 0, 0}
  401.     },
  402.     {
  403.         VER_PLATFORM_WIN32_WINDOWS,
  404.         {"NeoMagic MagicGraph 128 PCI", "nmx.drv",
  405.         0x5920000,0x40003, 0x0, 0x0, 0x0, 0x0, {0,0,0,{0,0,0,0,0,0,0,0}}},
  406.         /* overlays (use YUY2 only): */
  407.         {F(CID_YUY2),
  408.         F(CID_YUY2),
  409.         F(CID_YUY2),
  410.         F(CID_YUY2),
  411.         F(CID_YUY2)},
  412.         /* don't use BLITS!!!: */
  413.         {0, 0, 0, 0, 0}
  414.     },
  415.     {
  416.         VER_PLATFORM_WIN32_WINDOWS,
  417.         {"Diamond Stealth II G460",
  418.          "s2g432le.dll",
  419.          0x10542,0x4000a,
  420.          0x8086, 0x7800, 0x0, 0x0,
  421.          {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}},
  422.         /* overlays (use YUY2 only): */
  423.         {F(CID_YUY2),
  424.         F(CID_YUY2),
  425.         F(CID_YUY2),
  426.         F(CID_YUY2),
  427.         F(CID_YUY2)},
  428.         /* blits (use matching RGBs only): */
  429.         {F(CID_RGB32),
  430.         F(CID_RGB24),
  431.         F(CID_RGB565),
  432.         F(CID_RGB555),
  433.         F(CID_RGB8)}
  434.     },
  435.     {
  436.         VER_PLATFORM_WIN32_WINDOWS,
  437.         {"Diamond Stealth II G460",
  438.          "s2g432le.dll",
  439.          0x10542,0x4000a,
  440.          0x8086, 0x7800, 0x1001092, 0x21,
  441.          {0xd7b78e66,0x3b40,0x11cf,{0x60,0x76,0x1,0x21,0x84,0xc2,0xc9,0x35}}},
  442.         /* don't use overlays: */
  443.         {0, 0, 0, 0, 0},
  444.         /* blits (use matching RGBs only): */
  445.         {F(CID_RGB32),
  446.         F(CID_RGB24),
  447.         F(CID_RGB565),
  448.         F(CID_RGB555),
  449.         F(CID_RGB8)}
  450.     },
  451.     {
  452. VER_PLATFORM_WIN32_WINDOWS,
  453. {"NeoMagic MagicMedia 256AV",
  454.  "NmgcDD5.dll",
  455.  0x11451,0x4000a,
  456.  0x10c8, 0x5, 0x8f1028, 0x20, 
  457. {0xd7b71e28,0x4345,0x11cf,{0xc9,0x67,0x8e,0x20,0x85,0xc2,0xc9,0x35}}},
  458.         /* do NOT use overlays !!!: */
  459.         {0, 0, 0, 0, 0},
  460.         /* no blits either: */
  461.         {0, 0, 0, 0, 0}
  462.     },
  463.     {
  464. VER_PLATFORM_WIN32_WINDOWS,
  465.         {"NVIDIA RIVA TNT2 Ultra",
  466.          "NVDD32.DLL",
  467.          0x10170,0x4000c,
  468.          0x10de, 0x29, 0x10211102, 0x11, 
  469. {0xd7b71e3e,0x4369,0x11cf,{0xc2,0x73,0x20,0x30,0xb2,0xc2,0xc9,0x35}}},
  470.         /* don't use overlays: */
  471.         {0, 0, 0, 0, 0},
  472.         /* no blits either: */
  473.         {0, 0, 0, 0, 0}
  474.     }}
  475. };
  476. static BOOL DDPDB_Opened = FALSE;
  477. static BOOL DDPDB_NewProfile = FALSE;
  478. static time_t DDPDB_FileTime;
  479. /*
  480.  * Initializes profile database:        
  481.  */
  482. BOOL DDPDB_Open(char *pszProfile)
  483. {
  484.     BOOL bRet = FALSE;
  485.     /* check arguments: */
  486.     if (pszProfile && *pszProfile) {
  487.         struct _stat st;
  488.         /* get profile info: */
  489.         if (!_stat(pszProfile, &st) &&
  490.             /* check if we need to reload it: */
  491.             (!DDPDB_Opened || st.st_mtime != DDPDB_FileTime)) {
  492.             FILE *fp;
  493.             size_t s;
  494.             /* save profile time: */
  495.             DDPDB_FileTime = st.st_mtime;
  496.             /* try to open profile: */
  497.             if ((fp = fopen(pszProfile, "rb")) != NULL) {
  498.                 /* try to read this file: */
  499.                 if ((s = fread((void*)&DDPDB, 1, sizeof DDPDB, fp)) > 0 &&
  500.                     !strncmp(DDPDB.szMagic, DDPDB_MAGIC, 5) &&
  501.                     DDPDB.dwVersion >= DDPDB_VERSION &&
  502.                     DDPDB.dwNumProfiles >= 1 &&
  503.                     DDPDB.dwNumProfiles < MAXPROFILES &&
  504.                     DDPDB.dwNumProfiles * sizeof(DDDEVICEPROFILE) + 16 == s) {
  505.                     /* success: */
  506.                     DDPDB_Opened ++;
  507.                     DDPDB_NewProfile = TRUE;
  508.                     bRet = TRUE;
  509.                 }
  510.                 /* close file: */
  511.                 fclose(fp);
  512.             }
  513.         }
  514.     }
  515.     return bRet;
  516. }
  517. /*
  518.  * Terminates the use of profile database:
  519.  */
  520. BOOL DDPDB_Close ()
  521. {
  522.     return DDPDB_Opened && !--DDPDB_Opened;
  523. }
  524. /*
  525.  * Checks if profile has been updated.
  526.  */
  527. BOOL DDPDB_IsNewProfile ()
  528. {
  529.     BOOL bResult = DDPDB_NewProfile;
  530.     DDPDB_NewProfile = FALSE;
  531.     return bResult;
  532. }
  533. /*********************
  534.  * Default device profiles:
  535.  */
  536. static DDDEVICEPROFILE ddWinNTDefaultProfile =
  537. {
  538.     VER_PLATFORM_WIN32_NT,
  539.     {"", "", 0,0, 0},
  540.     /* overlays (use YUVs only): */
  541.     {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  542.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  543.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  544.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  545.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY)},
  546.     /* blits (use YUVs & matching RGBs): */
  547.     {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB32),
  548.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB24),
  549.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB565),
  550.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB555),
  551.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB8)}
  552. };
  553. static DDDEVICEPROFILE ddWin9xDefaultProfile =
  554. {
  555.     VER_PLATFORM_WIN32_WINDOWS,
  556.     {"", "", 0,0, 0,0,0,0, 0},
  557.     /* overlays (use YUVs only): */
  558.     {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  559.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  560.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  561.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY),
  562.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY)},
  563.     /* blits (use YUVs & matching RGBs): */
  564.     {F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB32),
  565.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB24),
  566.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB565),
  567.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB555),
  568.      F(CID_YV12) + F(CID_YUY2) + F(CID_UYVY) + F(CID_RGB8)}
  569. };
  570. /*
  571.  * Get pointer to a best matching DirectDraw device profile.
  572.  */
  573. LPDDDEVICEPROFILE DDPDB_GetDeviceProfile (LPDIRECTDRAW lpDD)
  574. {
  575.     OSVERSIONINFO osVersion;
  576.     DDDEVICEIDENTIFIER ddID;                    /* DirectDraw & Win95 info */
  577.     char szChipType[MAXCHIPTYPE];               /* NT info      */
  578.     unsigned int bestMatchIdx, deviceBestMatch, driverBestMatch;
  579.     unsigned int i, deviceMatch, driverMatch;
  580. #if DIRECTDRAW_VERSION > 0x0500
  581.     LPDIRECTDRAW4 lpDD4;
  582. #endif
  583.     /* check if we are runnning NT: */
  584.     memset(&osVersion,0, sizeof(OSVERSIONINFO));
  585.     osVersion.dwOSVersionInfoSize  = sizeof(OSVERSIONINFO);
  586.     if (GetVersionEx(&osVersion) && osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  587.         /* try to get WinNT device information: */
  588.         if (GetWinNTDeviceID (&ddID, szChipType)) {
  589.             /* clear best match criteria: */
  590.             deviceBestMatch = driverBestMatch = bestMatchIdx = 0;
  591.             /* scan database: */
  592.             for (i = 0; i < DDPDB.dwNumProfiles; i++) {
  593.                 /* check platform ID: */
  594.                 if (DDPDB.ddProfiles[i].dwPlatformId == VER_PLATFORM_WIN32_NT) {
  595.                     /* clear match criteria: */
  596.                     deviceMatch = driverMatch = 0;
  597.                     /* check non-critical parameters: */
  598.                     if (!DDPDB.ddProfiles[i].ID.WinNT.szDescription[0] ||
  599.                         !strncmp (DDPDB.ddProfiles[i].ID.WinNT.szDescription, ddID.szDescription, MAXDESCRIPT-1))
  600.                         deviceMatch ++;
  601.                     if (!DDPDB.ddProfiles[i].ID.WinNT.szDriver[0] ||
  602.                         !strnicmp (DDPDB.ddProfiles[i].ID.WinNT.szDriver, ddID.szDriver, MAXDRIVER-1))
  603.                         driverMatch ++;
  604.                     /* check critical data: */
  605.                     if (!DDPDB.ddProfiles[i].ID.WinNT.dwDriverVersionHighPart)
  606.                         driverMatch ++;
  607.                     else if (DDPDB.ddProfiles[i].ID.WinNT.dwDriverVersionHighPart == (DWORD)ddID.liDriverVersion.HighPart)
  608.                         driverMatch += 2;
  609.                     else
  610.                         continue;
  611.                     if (!DDPDB.ddProfiles[i].ID.WinNT.dwDriverVersionLowPart)
  612.                         driverMatch ++;
  613.                     else if (DDPDB.ddProfiles[i].ID.WinNT.dwDriverVersionLowPart == (DWORD)ddID.liDriverVersion.LowPart)
  614.                         driverMatch += 2;
  615.                     else
  616.                         continue;
  617.                     if (!DDPDB.ddProfiles[i].ID.WinNT.szChipType[0])
  618.                         deviceMatch += 1;
  619.                     else if (!strncmp (DDPDB.ddProfiles[i].ID.WinNT.szChipType, szChipType, MAXCHIPTYPE-1))
  620.                         deviceMatch += 2;
  621.                     else
  622.                         continue;
  623.                     /* check the results: */
  624.                     if (deviceMatch + driverMatch > deviceBestMatch + driverBestMatch &&
  625.                         deviceMatch >= deviceBestMatch && driverMatch >= driverBestMatch)
  626.                     {
  627.                         /* update best match: */
  628.                         deviceBestMatch = deviceMatch;
  629.                         driverBestMatch = driverMatch;
  630.                         bestMatchIdx = i;
  631.                     }
  632.                 }
  633.             }
  634.             /* check overal search results: */
  635.             if (deviceBestMatch && driverBestMatch >= 3)
  636.             {
  637.                 return DDPDB.ddProfiles + bestMatchIdx ;
  638.             }
  639.             
  640.         }
  641.         /* return WinNT default profile: */
  642.         return &ddWinNTDefaultProfile;
  643.     } else { /* Win9x: */
  644.         /* try to get DirectDraw device identifier: */
  645.         memset (&ddID, 0, sizeof (DDDEVICEIDENTIFIER));
  646.         
  647. #if DIRECTDRAW_VERSION > 0x0500 && !defined(IMPORT)
  648.         if ((IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void**)&lpDD4) == DD_OK &&
  649.             IDirectDraw4_GetDeviceIdentifier(lpDD4, &ddID, DDGDI_GETHOSTIDENTIFIER) == DD_OK) ||
  650.             /* try to gather Win9x device information manually: */
  651.             GetWin9xDeviceID (&ddID)) {
  652.             /* clear best match criteria: */
  653.             deviceBestMatch = driverBestMatch = bestMatchIdx = 0;
  654.             /* scan database: */
  655.             for (i = 0; i < DDPDB.dwNumProfiles; i++) {
  656.                 /* check platform ID: */
  657.                 if (DDPDB.ddProfiles[i].dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
  658.                     /* clear match criteria: */
  659.                     deviceMatch = driverMatch = 0;
  660.                     /* check non-critical parameters: */
  661.                     if (!DDPDB.ddProfiles[i].ID.Win9x.szDescription[0] ||
  662.                         !strncmp (DDPDB.ddProfiles[i].ID.Win9x.szDescription, ddID.szDescription, MAXDESCRIPT-1))
  663.                         deviceMatch ++;
  664.                     if (!DDPDB.ddProfiles[i].ID.Win9x.szDriver[0] ||
  665.                         !strnicmp (DDPDB.ddProfiles[i].ID.Win9x.szDriver, ddID.szDriver, MAXDRIVER-1))
  666.                         driverMatch ++;
  667.                     /* check critical data: */
  668.                     if (!DDPDB.ddProfiles[i].ID.Win9x.dwDriverVersionHighPart)
  669.                         driverMatch ++;
  670.                     else if (DDPDB.ddProfiles[i].ID.Win9x.dwDriverVersionHighPart == (DWORD)ddID.liDriverVersion.HighPart)
  671.                         driverMatch += 2;
  672.                     else
  673.                         continue;
  674.                     if (!DDPDB.ddProfiles[i].ID.Win9x.dwDriverVersionLowPart)
  675.                         driverMatch ++;
  676.                     else if (DDPDB.ddProfiles[i].ID.Win9x.dwDriverVersionLowPart == (DWORD)ddID.liDriverVersion.LowPart)
  677.                         driverMatch += 2;
  678.                     else
  679.                         continue;
  680.                     if (!DDPDB.ddProfiles[i].ID.Win9x.dwVendorId)
  681.                         deviceMatch ++;
  682.                     else if (DDPDB.ddProfiles[i].ID.Win9x.dwVendorId == ddID.dwVendorId)
  683.                         deviceMatch += 2;
  684.                     else
  685.                         continue;
  686.                     if (!DDPDB.ddProfiles[i].ID.Win9x.dwDeviceId)
  687.                         deviceMatch ++;
  688.                     else if (DDPDB.ddProfiles[i].ID.Win9x.dwDeviceId == ddID.dwDeviceId)
  689.                         deviceMatch += 2;
  690.                     else
  691.                         continue;
  692.                     /* check the results: */
  693.                     if (deviceMatch + driverMatch > deviceBestMatch + driverBestMatch &&
  694.                         deviceMatch >= deviceBestMatch && driverMatch >= driverBestMatch) {
  695.                         /* update best match: */
  696.                         deviceBestMatch = deviceMatch;
  697.                         driverBestMatch = driverMatch;
  698.                         bestMatchIdx  = i;
  699.                     }
  700.                 }
  701.             }
  702.             /* check overal search results: */
  703.             if (deviceBestMatch >= 3 && driverBestMatch >= 3)
  704.                 return DDPDB.ddProfiles + bestMatchIdx;
  705.         }
  706. #endif //DIRECTDRAW_VERSION <= 0x0500
  707.         /* return default profile: */
  708.         return &ddWin9xDefaultProfile;
  709.     }
  710. }
  711. /* packs 2-character string into a normal, single-character one: */
  712. static void PackWideString (char *dest, char *src, int n)
  713. {
  714.     register char *d = dest, *s = src;
  715.     while (n-- && *s) {
  716.         *d = *s;
  717.         s += 2;
  718.         d += 1;
  719.     }
  720.     *d = '';
  721. }
  722. static BOOL GetFileVersion(LPTSTR pPath, LPDDDEVICEIDENTIFIER lpddID)
  723. {
  724.     DWORD   dwVerInfoSize;
  725.     DWORD   dwVerHnd;
  726.     BOOL    fSuccess = FALSE;
  727.     // load version.dll
  728.     HINSTANCE     hLib = NULL;
  729.     VERQUERYVALUE     _pVerQueryValue = NULL;
  730.     GETFILEVERSIONINFO     _pGetFileVersionInfo = NULL;
  731.     GETFILEVERSIONINFOSIZE  _pGetFileVersionInfoSize = NULL;
  732.     hLib = LoadLibrary("version.dll");
  733.     if (hLib)
  734.     {
  735. _pVerQueryValue = (VERQUERYVALUE)GetProcAddress(hLib, "VerQueryValueA");
  736. _pGetFileVersionInfo = (GETFILEVERSIONINFO)GetProcAddress(hLib, "GetFileVersionInfoA");
  737. _pGetFileVersionInfoSize = (GETFILEVERSIONINFOSIZE)GetProcAddress(hLib, "GetFileVersionInfoSizeA");
  738.     }
  739.     if (_pVerQueryValue &&
  740. _pGetFileVersionInfo &&
  741. _pGetFileVersionInfoSize)
  742.     {
  743. /* set everything to 0: */
  744. lpddID->liDriverVersion.HighPart = 0;
  745. lpddID->liDriverVersion.LowPart = 0;
  746. /* get size of version info: */
  747. if ((dwVerInfoSize = _pGetFileVersionInfoSize(pPath, &dwVerHnd)) != 0) {
  748.     HANDLE  hMem;                     /* handle to mem alloc'ed */
  749.     LPSTR   lpstrVffInfo;             /* Pointer to block to hold info */
  750.     /* Get a block big enough to hold version info */
  751.     hMem          = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  752.     lpstrVffInfo  = (char *)GlobalLock(hMem);
  753.     /* get file version info: */
  754.     if (_pGetFileVersionInfo(pPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) {
  755. UINT    VersionLen;
  756. LPSTR   lpVersion;
  757. /* query version info: */
  758. if (_pVerQueryValue(lpstrVffInfo, "\",
  759.     (void FAR* FAR*)&lpVersion, &VersionLen)) {
  760.     /* copy version info: */
  761.     VS_FIXEDFILEINFO* pFileInfo = (VS_FIXEDFILEINFO*)lpVersion;
  762.     lpddID->liDriverVersion.HighPart = pFileInfo->dwFileVersionMS;
  763.     lpddID->liDriverVersion.LowPart = pFileInfo->dwFileVersionLS;
  764.     /* indicate success: */
  765.     fSuccess = TRUE;
  766. }
  767.     }
  768.     /* Let go of the memory */
  769.     GlobalUnlock(hMem);
  770.     GlobalFree(hMem);
  771. }
  772.     }
  773.     FreeLibrary(hLib);
  774.     return fSuccess;
  775. }
  776. #define MAX_BUF        512
  777. #ifdef TRACE
  778. #define Trace(pMsg)  printf("-->%sn", pMsg)
  779. #else
  780. #define Trace(pMsg)  ((void)0)
  781. #endif
  782. /*
  783.  * This whole thing is based on Jeff's CFullScreenInfo:: code:
  784.  */
  785. BOOL GetWinNTDeviceID (LPDDDEVICEIDENTIFIER lpddID, char *pszChipType)
  786. {
  787.     HKEY        hKey;
  788.     char        szBuffer[MAX_BUF];
  789.     DWORD       bufSize  = sizeof(szBuffer) - 1;
  790.     char        pDLLPath[_MAX_PATH];
  791.     const char* pszStrip = "\registry\machine\";
  792.     LONG        res = ERROR_SUCCESS;
  793.     BOOL        retVal = FALSE;
  794.     
  795.     /* open Hardware\DEVICEMAP\VIDEO key: */
  796.     res = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  797.                         "Hardware\DEVICEMAP\VIDEO",
  798.                         0,
  799.                         KEY_READ,
  800.                         &hKey
  801.                         );
  802.     
  803.     if( ERROR_SUCCESS == res )
  804.     {
  805.         /* query a Video0 entry: */
  806.         memset(szBuffer, 0, sizeof(szBuffer) );
  807.         res = RegQueryValueEx(hKey,
  808.                               "\Device\Video0",
  809.                               NULL,
  810.                               NULL,
  811.                               (LPBYTE) szBuffer,
  812.                               (LPDWORD)&bufSize);
  813.         //Done with first key.
  814.         RegCloseKey(hKey);
  815.         
  816.         if( ERROR_SUCCESS == res )
  817.         {
  818.             //Find RegistryMachine in the key's values and strip it
  819.             //off. Some machines write the key in different cases.
  820.             //If we can't find it, something is wrong. It also must
  821.             //be at the start of the string.
  822.             _strlwr( szBuffer );
  823.             if( strstr(szBuffer, pszStrip) == szBuffer )
  824.             {
  825.                 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  826.                                    szBuffer + strlen(pszStrip), //Skip pre-log.
  827.                                    0,
  828.                                    KEY_READ,
  829.                                    &hKey);
  830.                 if( res == ERROR_SUCCESS )
  831.                 {
  832.                     /* get Device Description: */
  833.                     memset( szBuffer, 0, sizeof(szBuffer) );
  834.                     bufSize = sizeof( szBuffer)-1;
  835.                     res = RegQueryValueEx( hKey,
  836.                                            "HardwareInformation.AdapterString",
  837.                                            NULL,
  838.                                            NULL,
  839.                                            (LPBYTE) szBuffer,
  840.                                            (LPDWORD)&bufSize);
  841.             
  842.                     if( ERROR_SUCCESS == res )
  843.                     {
  844.                         /* move it to dddid: */
  845.                         PackWideString(lpddID->szDescription, szBuffer, MAXDESCRIPT-1);
  846.                         /* get ChipType information: */
  847.                         memset( szBuffer, 0, sizeof(szBuffer) );
  848.                         bufSize = sizeof( szBuffer)-1;
  849.                         res = RegQueryValueEx( hKey,
  850.                                                "HardwareInformation.ChipType",
  851.                                                NULL,
  852.                                                NULL,
  853.                                                (LPBYTE) szBuffer,
  854.                                                (LPDWORD)&bufSize);
  855.             
  856.                         if( ERROR_SUCCESS == res )
  857.                         {
  858.                             /* copy it: */
  859.                             PackWideString (pszChipType, szBuffer, MAXCHIPTYPE-1);
  860.                             /* get driver name: */
  861.                             memset( szBuffer, 0, sizeof(szBuffer) );
  862.                             bufSize = sizeof( szBuffer)-1;
  863.                             res = RegQueryValueEx( hKey,
  864.                                                    "InstalledDisplayDrivers",
  865.                                                    NULL,
  866.                                                    NULL,
  867.                                                    (LPBYTE) szBuffer,
  868.                                                    (LPDWORD)&bufSize);
  869.                             if( ERROR_SUCCESS == res && bufSize )
  870.                             {
  871.                                 //copy driver name
  872.                                 strcat(szBuffer, ".dll");
  873.                                 strncpy(lpddID->szDriver, szBuffer, MAXDRIVER-1);
  874.                                 // get full path to the driver:
  875.                                 if(GetSystemDirectory(pDLLPath, _MAX_PATH) != 0)
  876.                                 {
  877.                                     strcat(pDLLPath, "\");
  878.                                     strcat(pDLLPath, szBuffer);
  879.                                     // query file version:
  880.                                     if( GetFileVersion(pDLLPath, lpddID) )
  881.                                     {
  882.                                         retVal = TRUE;
  883.                                     }
  884.                                     
  885.                                 }
  886.                             }
  887.                         }
  888.                     }
  889.                     RegCloseKey(hKey);
  890.                 }
  891.             }
  892.         }
  893.     }
  894.     
  895.     return retVal;
  896. }
  897. static BOOL DevNodeIsActive(char *szDeviceID)
  898. {
  899.     HINSTANCE hDevNodeInst;
  900.     DWORD dwStatus;
  901.     DWORD dwProblemNumber;
  902.     DWORD cr;
  903.     DWORD (WINAPI *pGetDevNodeStatus32Call) (const char *, LPDWORD, LPDWORD);
  904.     /*
  905.      * 10 is a magic number for the configuration manager api
  906.      * that eventually gets called in the 16 bit dll.
  907.      */
  908.     dwStatus = dwProblemNumber = cr = 10;
  909.     pGetDevNodeStatus32Call = 0;
  910.     if ((hDevNodeInst = LoadLibrary(_32BIT_DLLNAME)) != 0)
  911.     {
  912.         if (((FARPROC)pGetDevNodeStatus32Call = GetProcAddress(hDevNodeInst, "GetDevNodeStatus32Call")) != NULL)
  913.         {
  914.             cr = (* pGetDevNodeStatus32Call) (szDeviceID, &dwStatus, &dwProblemNumber);
  915.         }
  916.         FreeLibrary(hDevNodeInst);
  917.     }
  918.     return cr == 0 && dwProblemNumber == 0;
  919. }
  920. static unsigned int hex2uint (char *p, int n)
  921. {
  922.     register unsigned int i = 0;
  923.     while (n--)
  924.     {
  925.         register unsigned int j = *p;
  926.         i <<= 4;
  927.         if (j <= '9')   j -= '0';
  928.         else            j -= 'A' - 10;
  929.         p ++;
  930.         i |= j;
  931.     }
  932.     return i;
  933. }
  934. /*
  935.  * Extract Win9x DirectDraw device information:
  936.  */
  937. BOOL GetWin9xDeviceID (LPDDDEVICEIDENTIFIER lpddID)
  938. {
  939.     static char *szEnum_Name [ENUM_MAX] = {
  940.         REGSTR_KEY_ROOTENUM, REGSTR_KEY_BIOSENUM,
  941.         REGSTR_KEY_PCIENUM,  REGSTR_KEY_ISAENUM,
  942.         REGSTR_KEY_EISAENUM, REGSTR_KEY_PCMCIAENUM
  943.     };
  944.     /* moved out of stack for safety reasons... */
  945.     static char szCurrentKey [MAX_BUF];
  946.     static char szCurrentDeviceNode[MAX_BUF];
  947.     static char szCurrentDevice [MAX_BUF];
  948.     static char szClass [64];
  949.     static char szDeviceID [MAX_BUF];
  950.     static char szSoftwareKey [MAX_BUF];
  951.     static char pDLLPath [_MAX_PATH];
  952.     ULONG ulType;
  953.     ULONG32 cbData;
  954.     HKEY hSoftwareKey;
  955.     char *p;
  956.     int i;
  957.     Trace("entering GetWin9xDeviceID... ");
  958.     /* we want to look through the ENUMBIOS, ENUMISAPNP, and ENUMPCI
  959.      * trees for devices of the DISPLAY class.  For each display device
  960.      * we find we will ask the Device manager if it is active. */
  961.     for (i = 0; i < ENUM_MAX; i++)
  962.     {
  963.         HKEY hBusKey;
  964.         /* construct a string for the current key: */
  965.         strcpy(szCurrentKey, REGSTR_KEY_ENUM);
  966.         strcat(szCurrentKey, "\");
  967.         strcat(szCurrentKey, szEnum_Name[i]);
  968.         Trace("nopenining LOCAL_MACHINE key:");
  969.         Trace(szCurrentKey);
  970.         /* start reading the devices */
  971.         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szCurrentKey, 0, KEY_READ, &hBusKey) == ERROR_SUCCESS)
  972.         {
  973.             ULONG32 dwDevNodeEnumIndex = 0;
  974.             Trace("opened;");
  975.             /* Enumerate all of the devices on the bus */
  976.             while (1)
  977.             {
  978.                 HKEY hDeviceNodeKey;
  979.                 memset(szCurrentDeviceNode, 0, sizeof(szCurrentDeviceNode));
  980.                 cbData = sizeof(szCurrentDeviceNode) - 1;
  981.                 if (RegEnumKeyEx(hBusKey, dwDevNodeEnumIndex, szCurrentDeviceNode, &cbData, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  982.                     break;
  983.                 /* construct a string for current device node: */
  984.                 strcpy(szCurrentKey,REGSTR_KEY_ENUM);
  985.                 strcat(szCurrentKey, "\");
  986.                 strcat(szCurrentKey, szEnum_Name[i]);
  987.                 strcat(szCurrentKey, "\");
  988.                 strcat(szCurrentKey, szCurrentDeviceNode);
  989.                 Trace("opening device node:");
  990.                 Trace(szCurrentKey);
  991.                 /* get the registry key for the current device node */
  992.                 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szCurrentKey, 0, KEY_READ, &hDeviceNodeKey) == ERROR_SUCCESS)
  993.                 {
  994.                     ULONG32 dwHWDeviceEnumIndex = 0;
  995.                     Trace("opened;");
  996.                     /* enumerate all of the hardware devices in this Device Node */
  997.                     while (1)
  998.                     {
  999.                         HKEY hHWDeviceKey;
  1000.                         int nBaseKeyLength;
  1001.                         memset(szCurrentDevice, 0, sizeof(szCurrentDevice));
  1002.                         cbData = sizeof(szCurrentDevice) - 1;
  1003.                         if (RegEnumKeyEx(hDeviceNodeKey, dwHWDeviceEnumIndex, szCurrentDevice, &cbData, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  1004.                             break;
  1005.                         /* get the registry key for the current hardware device */
  1006.                         nBaseKeyLength = strlen(szCurrentKey);
  1007.                         /* append currect device name: */
  1008.                         strcat(szCurrentKey, "\");
  1009.                         strcat(szCurrentKey, szCurrentDevice);
  1010.                         Trace("opening device named:");
  1011.                         Trace(szCurrentKey);
  1012.                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szCurrentKey, 0, KEY_READ, &hHWDeviceKey) == ERROR_SUCCESS)
  1013.                         {
  1014.                             Trace("opened;");
  1015.                             /* ask if this device is a "DISPLAY" device by checking it's class */
  1016.                             cbData = sizeof(szClass);
  1017.                             szClass[0] = 0;
  1018.                             Trace("quering class of this device: ");
  1019.                             if (RegQueryValueEx(hHWDeviceKey, "Class", 0, &ulType, (LPBYTE) szClass, &cbData) == ERROR_SUCCESS)
  1020.                             {
  1021.                                 Trace("obtained:");
  1022.                                 Trace(szClass);
  1023.                                 /* is it Display??? */
  1024.                                 if (!stricmp(szClass, "DISPLAY"))
  1025.                                 {
  1026.                                     Trace("looks like a display adapter!!");
  1027.                                     /* if it is a display device then we want to find out if it is
  1028.                                      * the active device for this class. */
  1029.                                     memset(szSoftwareKey, 0, sizeof(szSoftwareKey));
  1030.                                     cbData = sizeof(szSoftwareKey) - 1;
  1031.                                     /* create a string for Device ID: */
  1032.                                     strcpy(szDeviceID, szEnum_Name[i]);
  1033.                                     strcat(szDeviceID, "\");
  1034.                                     strcat(szDeviceID, szCurrentDeviceNode);
  1035.                                     strcat(szDeviceID, "\");
  1036.                                     strcat(szDeviceID, szCurrentDevice);
  1037.                                     Trace("quering device ID:");
  1038.                                     Trace(szDeviceID);
  1039.                                     /* get the registry key name for the software key for the device,
  1040.                                      * if it is not null and this is the active device then we are done. */
  1041.                                     if (RegQueryValueEx(hHWDeviceKey, "Driver", 0, &ulType, (LPBYTE) szSoftwareKey, &cbData) == ERROR_SUCCESS &&
  1042.                                         szSoftwareKey[0] != '0' &&
  1043.                                         DevNodeIsActive(szDeviceID))    /* Call Config Manager in 16-bit code */
  1044.                                     {
  1045.                                         Trace("device found!!!:");
  1046.                                         /* close all open keys and continue processing... */
  1047.                                         RegCloseKey(hHWDeviceKey);
  1048.                                         RegCloseKey(hDeviceNodeKey);
  1049.                                         RegCloseKey(hBusKey);
  1050.                                         goto cont;
  1051.                                     }
  1052.                                 }
  1053.                             }
  1054.                             /* close hardware device key: */
  1055.                             RegCloseKey(hHWDeviceKey);
  1056.                         }
  1057.                         /* reset the key to the base for the next time through the loop: */
  1058.                         memset (szCurrentKey + nBaseKeyLength, 0, sizeof(szCurrentKey) - nBaseKeyLength);
  1059.                         /* move to next device key */
  1060.                         dwHWDeviceEnumIndex ++;
  1061.                     }
  1062.                     /* close device node key: */
  1063.                     RegCloseKey(hDeviceNodeKey);
  1064.                 }
  1065.                 /* move to the next device node */
  1066.                 dwDevNodeEnumIndex ++;
  1067.             }
  1068.             /* close bus key: */
  1069.             RegCloseKey(hBusKey);
  1070.         }
  1071.     }
  1072.     Trace("exiting GetWin9xDeviceID (device not found):");
  1073.     /* not found: */
  1074.     return FALSE;
  1075. cont:
  1076.     /* get Vendor ID: */
  1077.     if ((p = strstr(szDeviceID, "VEN_")) != 0)
  1078.         lpddID->dwVendorId = hex2uint (p + strlen("VEN_"), 4);
  1079.     /* get DeviceID: */
  1080.     if ((p = strstr(szDeviceID, "DEV_")) != 0)
  1081.         lpddID->dwDeviceId = hex2uint (p + strlen("DEV_"), 4);
  1082.     /* get Revision #: */
  1083.     if ((p = strstr(szDeviceID, "REV_")) != 0)
  1084.         lpddID->dwRevision = hex2uint (p + strlen("REV_"), 4);
  1085.     /* if we found the software key, we want to go get the Driver description
  1086.      * and the driver file name: */
  1087.     /* create a software key string: */
  1088.     strcpy(szCurrentKey, REGSTR_PATH_CLASS);
  1089.     strcat(szCurrentKey, "\");
  1090.     strcat(szCurrentKey, szSoftwareKey);
  1091.     Trace("opening software key:");
  1092.     Trace(szCurrentKey);
  1093.     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szCurrentKey, 0, KEY_READ, &hSoftwareKey) == ERROR_SUCCESS)
  1094.     {
  1095.         /* use external buffer: */
  1096.         char* szAdapterString = lpddID->szDescription;
  1097.         cbData = MAX_DDDEVICEID_STRING;
  1098.         Trace("opened;");
  1099.         /* query device description: */
  1100.         RegQueryValueEx(hSoftwareKey, "DriverDesc", 0, &ulType, (LPBYTE)szAdapterString, &cbData);
  1101.         /* close software key; */
  1102.         RegCloseKey(hSoftwareKey);
  1103.     }
  1104.     /* now look in the Default key for the driver file name */
  1105.     strcat(szCurrentKey, "\DEFAULT");
  1106.     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szCurrentKey, 0, KEY_READ, &hSoftwareKey) == ERROR_SUCCESS)
  1107.     {
  1108.         char* szDisplayDriverName = lpddID->szDriver;
  1109.         cbData = MAX_DDDEVICEID_STRING;
  1110.         /* query driver name: */
  1111.         RegQueryValueEx(hSoftwareKey, "drv", 0, &ulType, (LPBYTE)szDisplayDriverName, &cbData);
  1112.         /* close software key: */
  1113.         RegCloseKey(hSoftwareKey);
  1114.         /* get the file version: */
  1115.         if (GetSystemDirectory(pDLLPath, _MAX_PATH) != 0)
  1116.         {
  1117.             strcat(pDLLPath, "\");
  1118.             strcat(pDLLPath, szDisplayDriverName);
  1119.             Trace("trying to get a file version:");
  1120.             /* query file version: */
  1121.             GetFileVersion(pDLLPath, lpddID);
  1122.         }
  1123.     }
  1124.     Trace("exiting GetWin9xDeviceID:");
  1125.     return TRUE;
  1126. }
  1127. /***********************************
  1128.  * Utilities:
  1129.  **************************************/
  1130. #ifdef DUMP
  1131. /* a simple database creation program: */
  1132. int main (int argc, char *argv[])
  1133. {
  1134.     FILE *fp;
  1135.     int s;
  1136.     /* check arguments: */
  1137.     if (argc < 2) {
  1138.         fprintf (stderr, "Use:ntDDPDB <file name>n");
  1139.         exit (EXIT_FAILURE);
  1140.     }
  1141.     /* create a file: */
  1142.     if ((fp = fopen (argv[1], "wb+")) == NULL) {
  1143.         fprintf (stderr, "Cannot open database file.n");
  1144.         exit (EXIT_FAILURE);
  1145.     }
  1146.     /* calculate the size of file: */
  1147.     s = 16 + DDPDB.dwNumProfiles * sizeof(DDDEVICEPROFILE);
  1148.     /* dump raw data: */
  1149.     if (fwrite((void*)&DDPDB, 1, s, fp) != s) {
  1150.         fprintf (stderr, "Write error (out of disk space?).n");
  1151.         exit (EXIT_FAILURE);
  1152.     }
  1153.     /* close file: */
  1154.     fclose(fp);
  1155.     exit (EXIT_SUCCESS);
  1156. }
  1157. #endif /* DUMP */
  1158. #ifdef IMPORT
  1159. /* a profile generation program: */
  1160. int main ()
  1161. {
  1162.     OSVERSIONINFO osVersion;
  1163.     LPDIRECTDRAW lpDD;
  1164.     LPDIRECTDRAW4 lpDD4;
  1165.     DDDEVICEIDENTIFIER ddID;                    /* DirectDraw & Win95 info      */
  1166.     char szChipType[MAXCHIPTYPE];               /* NT info      */
  1167.     /* try to load DirectDraw library: */
  1168.     if (DirectDrawCreate (NULL, &lpDD, NULL) != DD_OK) {
  1169.         printf ("Cannot create DirectDraw object!");
  1170.         exit(EXIT_FAILURE);
  1171.     }
  1172.     /* check if we are runnning NT: */
  1173.     memset(&osVersion,0, sizeof(OSVERSIONINFO));
  1174.     osVersion.dwOSVersionInfoSize  = sizeof(OSVERSIONINFO);
  1175.     if (GetVersionEx(&osVersion) && osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT)
  1176.     {
  1177.         /* try to get WinNT device information: */
  1178.         if (!GetWinNTDeviceID (&ddID, szChipType)) {
  1179.             fprintf (stderr, "Cannot get NT driver infon");
  1180.             exit (EXIT_FAILURE);
  1181.         }
  1182.         /* print header: */
  1183.         printf ("tVER_PLATFORM_WIN32_NT,n");
  1184.     }
  1185.     else
  1186.     { /* Win9x: */
  1187. #ifndef IMPORT        
  1188.         /* try to get DirectDraw device identifier: */
  1189.         memset (&ddID, 0, sizeof (DDDEVICEIDENTIFIER));
  1190.         if (
  1191.             (IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void**)&lpDD4) != DD_OK ||
  1192.             IDirectDraw4_GetDeviceIdentifier(lpDD4, &ddID, DDGDI_GETHOSTIDENTIFIER) != DD_OK) &&
  1193.             /* try to gather Win9x device information manually: */
  1194.             !GetWin9xDeviceID (&ddID)) {
  1195.                 fprintf (stderr, "Cannot get Win9x driver infon");
  1196.                 exit (EXIT_FAILURE);
  1197.             }
  1198.         /* print header: */
  1199.         printf( "tVER_PLATFORM_WIN32_WINDOWS,n");
  1200. #else
  1201.         printf( "Need more work to run this tool on win95 machines.....n" );
  1202. #endif        
  1203.     }
  1204.     /* dump description: */
  1205.     ddID.szDescription[MAXDESCRIPT-1] = '';
  1206.     printf ("t{"%s",n", ddID.szDescription);
  1207.     /* dump driver: */
  1208.     ddID.szDriver[MAXDRIVER-1] = '';
  1209.     printf ("t "%s",n", ddID.szDriver);
  1210.     /* driver version: */
  1211.     printf ("t 0x%x,0x%x,n", ddID.liDriverVersion.LowPart, ddID.liDriverVersion.HighPart);
  1212.     if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
  1213.         /* dump: WinNT vars:*/
  1214.         printf ("t 0x%x, 0x%x, 0x%x, 0x%x, n",
  1215.             *(DWORD*)(szChipType), *(DWORD*)(szChipType+4), *(DWORD*)(szChipType+8), *(DWORD*)(szChipType+12));
  1216.         printf ("t {0x%x,0x%x,0x%x,{0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}}n",
  1217.             *(DWORD*)(szChipType+16), *(WORD*)(szChipType+20), *(WORD*)(szChipType+22),
  1218.             szChipType[24], szChipType[25], szChipType[26], szChipType[27],
  1219.             szChipType[28], szChipType[29], szChipType[30], szChipType[31]);
  1220.     } else {
  1221.         /* dump: Win9x vars:*/
  1222.         printf ("t 0x%x, 0x%x, 0x%x, 0x%x, n",
  1223.             ddID.dwVendorId, ddID.dwDeviceId, ddID.dwSubSysId, ddID.dwRevision);
  1224.         printf ("t {0x%x,0x%x,0x%x,{0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}}n",
  1225.             ddID.guidDeviceIdentifier.Data1,
  1226.             ddID.guidDeviceIdentifier.Data2,    ddID.guidDeviceIdentifier.Data3,
  1227.             ddID.guidDeviceIdentifier.Data4[0], ddID.guidDeviceIdentifier.Data4[1],
  1228.             ddID.guidDeviceIdentifier.Data4[2], ddID.guidDeviceIdentifier.Data4[3],
  1229.             ddID.guidDeviceIdentifier.Data4[4], ddID.guidDeviceIdentifier.Data4[5],
  1230.             ddID.guidDeviceIdentifier.Data4[6], ddID.guidDeviceIdentifier.Data4[7]);
  1231.     }
  1232.     exit (EXIT_SUCCESS);
  1233. }
  1234. #endif /* IMPORT */
  1235. /* ddpdb.c -- end of file */