summaryrefslogtreecommitdiffstats
path: root/private/mvdm/dpmi32/vxd.c
blob: a1a85d76478787f9645627f54fbba571613f75ea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*++

Copyright (c) 1992  Microsoft Corporation

Module Name:

    vxd.c

Abstract:

    This module contains misc dpmi functions for risc.

Revision History:

    Neil Sandlin (neilsa) Nov. 1, 95 - split off from "misc" source

--*/

#include "precomp.h"
#pragma hdrstop
#include "softpc.h"


LONG
    VcdPmGetPortArray(
        VOID
    )
/*++

Routine Description:

    Use the registry enteries in HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM
    to simulate the Virtual Comm Device API: VCD_PM_Get_Port_Array. See VCD.ASM
    in the Win 3.1 DDK.


Arguments:

    None

Return Value:

    Port Array in LOWORD. Bit array of valid ports:

    Bit Set   -> Port valid
    Bit clear -> Port invalid

    Bit 0 -> COM1, Bit 1 -> COM2, Bit 2 -> COM3...

--*/
{
    HKEY        hSerialCommKey;
    DWORD       dwPortArray;
    DWORD       dwPortNum;
    DWORD       cbPortName;
    DWORD       cbPortValue;
    CHAR        szPortName[16];
    CHAR        szPortValue[16];
    LONG        iPort;
    LONG        iStatus;

    dwPortArray = 0;
    if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
                      "HARDWARE\\DEVICEMAP\\SERIALCOMM",
                      0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
                      &hSerialCommKey) == ERROR_SUCCESS){

        cbPortName  = sizeof(szPortName);
        cbPortValue = sizeof(szPortValue);
        for (iPort = 0;
             (iStatus = RegEnumValue(hSerialCommKey,
                                     iPort, szPortName, &cbPortName,
                                     NULL, NULL, szPortValue,
                                     &cbPortValue)) != ERROR_NO_MORE_ITEMS;
             iPort++)
        {
            if ((iStatus == ERROR_SUCCESS) && (cbPortValue > 3)) {

                if (NT_SUCCESS(RtlCharToInteger(szPortValue+3,10,&dwPortNum))) {
                    dwPortArray |= (1 << (dwPortNum - 1));
                }

            }
            cbPortName  = sizeof(szPortName);
            cbPortValue = sizeof(szPortValue);
        }
    // WOW only supports 9 ports. See WU32OPENCOM in WUCOMM.C.
    dwPortArray &= 0x1FF;
    RegCloseKey(hSerialCommKey);
    }
    return(dwPortArray);
}

// The following values taken from Win 3.1 DDK VCD.ASM:

#define VCD_PM_Get_Version          0
#define VCD_PM_Get_Port_Array       1
#define VCD_PM_Get_Port_Behavior    2
#define VCD_PM_Set_Port_Behavior    3
#define VCD_PM_Acquire_Port         4
#define VCD_PM_Free_Port            5
#define VCD_PM_Steal_Port           6

VOID
    DpmiVcdPmSvcCall32(
        VOID
    )
/*++

Routine Description:

    Dispatch VCD API requests to the correct API.

Arguments:

    Client DX contains API function id.

Return Value:

    Depends on API.
--*/
{
    switch (getDX()) {
        case VCD_PM_Get_Version:
            setAX(0x30A);
            break;

        case VCD_PM_Get_Port_Array:
            setAX((WORD)VcdPmGetPortArray());
            break;

        default :
            ASSERT(0);
            setCF(1);
    }
}