ddpdb.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:50k
源码类别:

Symbian

开发平台:

Visual C++

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