mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 21:21:33 +00:00
- Sync msctf, mscoree, mciqtz32, localspl, inetmib1 with Wine 1.1.21
svn path=/trunk/; revision=40850
This commit is contained in:
parent
cc308abba4
commit
8a68f45533
12 changed files with 1300 additions and 89 deletions
|
@ -125,6 +125,7 @@ static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
AsnInteger32 *pErrorStatus)
|
||||
{
|
||||
AsnObjectIdentifier numberOid = DEFINE_OID(mib2IfNumber);
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -155,12 +156,13 @@ static BOOL mib2IfNumberQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void copyOperStatus(AsnAny *value, void *src)
|
||||
|
@ -431,45 +433,61 @@ static AsnInteger32 getItemAndInstanceFromTable(AsnObjectIdentifier *oid,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base,
|
||||
static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base,
|
||||
UINT item)
|
||||
{
|
||||
UINT id;
|
||||
AsnObjectIdentifier oid;
|
||||
INT ret;
|
||||
|
||||
SnmpUtilOidCpy(dst, base);
|
||||
oid.idLength = 1;
|
||||
oid.ids = &id;
|
||||
id = item;
|
||||
SnmpUtilOidAppend(dst, &oid);
|
||||
ret = SnmpUtilOidCpy(dst, base);
|
||||
if (ret)
|
||||
{
|
||||
oid.idLength = 1;
|
||||
oid.ids = &id;
|
||||
id = item;
|
||||
ret = SnmpUtilOidAppend(dst, &oid);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void setOidWithItemAndIpAddr(AsnObjectIdentifier *dst,
|
||||
static INT setOidWithItemAndIpAddr(AsnObjectIdentifier *dst,
|
||||
AsnObjectIdentifier *base, UINT item, DWORD addr)
|
||||
{
|
||||
UINT id;
|
||||
BYTE *ptr;
|
||||
AsnObjectIdentifier oid;
|
||||
INT ret;
|
||||
|
||||
setOidWithItem(dst, base, item);
|
||||
oid.idLength = 1;
|
||||
oid.ids = &id;
|
||||
for (ptr = (BYTE *)&addr; ptr < (BYTE *)&addr + sizeof(DWORD); ptr++)
|
||||
ret = setOidWithItem(dst, base, item);
|
||||
if (ret)
|
||||
{
|
||||
id = *ptr;
|
||||
SnmpUtilOidAppend(dst, &oid);
|
||||
oid.idLength = 1;
|
||||
oid.ids = &id;
|
||||
for (ptr = (BYTE *)&addr; ret && ptr < (BYTE *)&addr + sizeof(DWORD);
|
||||
ptr++)
|
||||
{
|
||||
id = *ptr;
|
||||
ret = SnmpUtilOidAppend(dst, &oid);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void setOidWithItemAndInteger(AsnObjectIdentifier *dst,
|
||||
static INT setOidWithItemAndInteger(AsnObjectIdentifier *dst,
|
||||
AsnObjectIdentifier *base, UINT item, UINT instance)
|
||||
{
|
||||
AsnObjectIdentifier oid;
|
||||
INT ret;
|
||||
|
||||
setOidWithItem(dst, base, item);
|
||||
oid.idLength = 1;
|
||||
oid.ids = &instance;
|
||||
SnmpUtilOidAppend(dst, &oid);
|
||||
ret = setOidWithItem(dst, base, item);
|
||||
if (ret)
|
||||
{
|
||||
oid.idLength = 1;
|
||||
oid.ids = &instance;
|
||||
ret = SnmpUtilOidAppend(dst, &oid);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct structToAsnValue mib2IfEntryMap[] = {
|
||||
|
@ -502,6 +520,7 @@ static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
AsnInteger32 *pErrorStatus)
|
||||
{
|
||||
AsnObjectIdentifier entryOid = DEFINE_OID(mib2IfEntry);
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -536,20 +555,21 @@ static BOOL mib2IfEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
&ifTable->table[tableIndex - 1], item, bPduType,
|
||||
pVarBind);
|
||||
if (bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItemAndInteger(&pVarBind->name, &entryOid,
|
||||
item, tableIndex);
|
||||
ret = setOidWithItemAndInteger(&pVarBind->name,
|
||||
&entryOid, item, tableIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2Ip[] = { 1,3,6,1,2,1,4 };
|
||||
|
@ -591,6 +611,7 @@ static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2Ip);
|
||||
UINT item = 0;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -606,17 +627,18 @@ static BOOL mib2IpStatsQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
*pErrorStatus = mapStructEntryToValue(mib2IpMap,
|
||||
DEFINE_SIZEOF(mib2IpMap), &ipStats, item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
ret = setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2IpAddr[] = { 1,3,6,1,2,1,4,20,1 };
|
||||
|
@ -669,6 +691,7 @@ static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2IpAddr);
|
||||
UINT tableIndex = 0, item = 0;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -689,18 +712,19 @@ static BOOL mib2IpAddrQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
DEFINE_SIZEOF(mib2IpAddrMap),
|
||||
&ipAddrTable->table[tableIndex - 1], item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
|
||||
ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
|
||||
ipAddrTable->table[tableIndex - 1].dwAddr);
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2IpRoute[] = { 1,3,6,1,2,1,4,21,1 };
|
||||
|
@ -760,6 +784,7 @@ static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2IpRoute);
|
||||
UINT tableIndex = 0, item = 0;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -780,18 +805,19 @@ static BOOL mib2IpRouteQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
DEFINE_SIZEOF(mib2IpRouteMap),
|
||||
&ipRouteTable->table[tableIndex - 1], item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
|
||||
ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
|
||||
ipRouteTable->table[tableIndex - 1].dwForwardDest);
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2IpNet[] = { 1,3,6,1,2,1,4,22,1 };
|
||||
|
@ -828,6 +854,7 @@ static BOOL mib2IpNetQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
AsnInteger32 *pErrorStatus)
|
||||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2IpNet);
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -856,20 +883,21 @@ static BOOL mib2IpNetQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
DEFINE_SIZEOF(mib2IpNetMap),
|
||||
&ipNetTable[tableIndex - 1], item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItemAndInteger(&pVarBind->name, &myOid, item,
|
||||
tableIndex);
|
||||
ret = setOidWithItemAndInteger(&pVarBind->name, &myOid,
|
||||
item, tableIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2Icmp[] = { 1,3,6,1,2,1,5 };
|
||||
|
@ -914,6 +942,7 @@ static BOOL mib2IcmpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2Icmp);
|
||||
UINT item = 0;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -930,17 +959,18 @@ static BOOL mib2IcmpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
DEFINE_SIZEOF(mib2IcmpMap), &icmpStats, item, bPduType,
|
||||
pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
ret = setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2Tcp[] = { 1,3,6,1,2,1,6 };
|
||||
|
@ -974,6 +1004,7 @@ static BOOL mib2TcpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2Tcp);
|
||||
UINT item = 0;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -989,17 +1020,18 @@ static BOOL mib2TcpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
*pErrorStatus = mapStructEntryToValue(mib2TcpMap,
|
||||
DEFINE_SIZEOF(mib2TcpMap), &tcpStats, item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
ret = setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2Udp[] = { 1,3,6,1,2,1,7 };
|
||||
|
@ -1022,6 +1054,7 @@ static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2Udp);
|
||||
UINT item;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -1037,17 +1070,18 @@ static BOOL mib2UdpQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
*pErrorStatus = mapStructEntryToValue(mib2UdpMap,
|
||||
DEFINE_SIZEOF(mib2UdpMap), &udpStats, item, bPduType, pVarBind);
|
||||
if (!*pErrorStatus && bPduType == SNMP_PDU_GETNEXT)
|
||||
setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
ret = setOidWithItem(&pVarBind->name, &myOid, item);
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UINT mib2UdpEntry[] = { 1,3,6,1,2,1,7,5,1 };
|
||||
|
@ -1102,6 +1136,7 @@ static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
AsnInteger32 *pErrorStatus)
|
||||
{
|
||||
AsnObjectIdentifier myOid = DEFINE_OID(mib2UdpEntry);
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %s, %p)\n", bPduType, SnmpUtilOidToA(&pVarBind->name),
|
||||
pErrorStatus);
|
||||
|
@ -1131,23 +1166,27 @@ static BOOL mib2UdpEntryQuery(BYTE bPduType, SnmpVarBind *pVarBind,
|
|||
{
|
||||
AsnObjectIdentifier oid;
|
||||
|
||||
setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
|
||||
ret = setOidWithItemAndIpAddr(&pVarBind->name, &myOid, item,
|
||||
udpTable->table[tableIndex - 1].dwLocalAddr);
|
||||
oid.idLength = 1;
|
||||
oid.ids = &udpTable->table[tableIndex - 1].dwLocalPort;
|
||||
SnmpUtilOidAppend(&pVarBind->name, &oid);
|
||||
if (ret)
|
||||
{
|
||||
oid.idLength = 1;
|
||||
oid.ids = &udpTable->table[tableIndex - 1].dwLocalPort;
|
||||
ret = SnmpUtilOidAppend(&pVarBind->name, &oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SNMP_PDU_SET:
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_READONLY;
|
||||
ret = FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("0x%02x: unsupported PDU type\n", bPduType);
|
||||
*pErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This list MUST BE lexicographically sorted */
|
||||
|
@ -1240,6 +1279,7 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
|||
AsnObjectIdentifier mib2oid = DEFINE_OID(mib2);
|
||||
AsnInteger32 error = SNMP_ERRORSTATUS_NOERROR, errorIndex = 0;
|
||||
UINT i;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(0x%02x, %p, %p, %p)\n", bPduType, pVarBindList,
|
||||
pErrorStatus, pErrorIndex);
|
||||
|
@ -1261,7 +1301,7 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
|||
impl = findSupportedQuery(pVarBindList->list[i].name.ids, len,
|
||||
&matchingIndex);
|
||||
if (impl && impl->query)
|
||||
impl->query(bPduType, &pVarBindList->list[i], &error);
|
||||
ret = impl->query(bPduType, &pVarBindList->list[i], &error);
|
||||
else
|
||||
error = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
if (error == SNMP_ERRORSTATUS_NOSUCHNAME &&
|
||||
|
@ -1278,7 +1318,8 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
|||
error = SNMP_ERRORSTATUS_NOERROR;
|
||||
impl = &supportedIDs[matchingIndex];
|
||||
if (impl->query)
|
||||
impl->query(bPduType, &pVarBindList->list[i], &error);
|
||||
ret = impl->query(bPduType, &pVarBindList->list[i],
|
||||
&error);
|
||||
else
|
||||
error = SNMP_ERRORSTATUS_NOSUCHNAME;
|
||||
}
|
||||
|
@ -1288,7 +1329,7 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
|||
if (error == SNMP_ERRORSTATUS_NOSUCHNAME)
|
||||
{
|
||||
SnmpUtilOidFree(&pVarBindList->list[i].name);
|
||||
SnmpUtilOidCpy(&pVarBindList->list[i].name,
|
||||
ret = SnmpUtilOidCpy(&pVarBindList->list[i].name,
|
||||
&supportedIDs[matchingIndex - 1].name);
|
||||
pVarBindList->list[i].name.ids[
|
||||
pVarBindList->list[i].name.idLength - 1] += 1;
|
||||
|
@ -1300,7 +1341,7 @@ BOOL WINAPI SnmpExtensionQuery(BYTE bPduType, SnmpVarBindList *pVarBindList,
|
|||
}
|
||||
*pErrorStatus = error;
|
||||
*pErrorIndex = errorIndex;
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
|
@ -62,6 +62,11 @@ static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero( size_t len )
|
|||
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
|
||||
}
|
||||
|
||||
static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero( void * mem, size_t len )
|
||||
{
|
||||
return HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len );
|
||||
}
|
||||
|
||||
static inline BOOL heap_free( void *mem )
|
||||
{
|
||||
return HeapFree( GetProcessHeap(), 0, mem );
|
||||
|
|
|
@ -80,6 +80,13 @@ typedef struct {
|
|||
LPCWSTR versionsubdir;
|
||||
} printenv_t;
|
||||
|
||||
typedef struct {
|
||||
LPWSTR name;
|
||||
LPWSTR printername;
|
||||
monitor_t * pm;
|
||||
HANDLE hXcv;
|
||||
} printer_t;
|
||||
|
||||
/* ############################### */
|
||||
|
||||
static struct list monitor_handles = LIST_INIT( monitor_handles );
|
||||
|
@ -88,6 +95,7 @@ static monitor_t * pm_localport;
|
|||
static const PRINTPROVIDOR * pprovider = NULL;
|
||||
|
||||
static const WCHAR backslashW[] = {'\\',0};
|
||||
static const WCHAR bs_ports_bsW[] = {'\\','P','o','r','t','s','\\',0};
|
||||
static const WCHAR configuration_fileW[] = {'C','o','n','f','i','g','u','r','a','t','i','o','n',' ','F','i','l','e',0};
|
||||
static const WCHAR datatypeW[] = {'D','a','t','a','t','y','p','e',0};
|
||||
static const WCHAR data_fileW[] = {'D','a','t','a',' ','F','i','l','e',0};
|
||||
|
@ -118,20 +126,30 @@ static const WCHAR oem_urlW[] = {'O','E','M',' ','U','r','l',0};
|
|||
static const WCHAR parametersW[] = {'P','a','r','a','m','e','t','e','r','s',0};
|
||||
static const WCHAR portW[] = {'P','o','r','t',0};
|
||||
static const WCHAR previous_namesW[] = {'P','r','e','v','i','o','u','s',' ','N','a','m','e','s',0};
|
||||
static const WCHAR printersW[] = {'S','y','s','t','e','m','\\',
|
||||
'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
|
||||
'C','o','n','t','r','o','l','\\',
|
||||
'P','r','i','n','t','\\',
|
||||
'P','r','i','n','t','e','r','s',0};
|
||||
static const WCHAR spooldriversW[] = {'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\',0};
|
||||
static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
|
||||
|
||||
static const WCHAR win40_envnameW[] = {'W','i','n','d','o','w','s',' ','4','.','0',0};
|
||||
static const WCHAR win40_subdirW[] = {'w','i','n','4','0',0};
|
||||
static const WCHAR version0_regpathW[] = {'\\','V','e','r','s','i','o','n','-','0',0};
|
||||
static const WCHAR version0_subdirW[] = {'\\','0',0};
|
||||
|
||||
static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0};
|
||||
static const WCHAR version3_subdirW[] = {'\\','3',0};
|
||||
static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
|
||||
static const WCHAR win40_envnameW[] = {'W','i','n','d','o','w','s',' ','4','.','0',0};
|
||||
static const WCHAR win40_subdirW[] = {'w','i','n','4','0',0};
|
||||
static const WCHAR winnt_cv_portsW[] = {'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s',' ','N','T','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'P','o','r','t','s',0};
|
||||
static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0};
|
||||
static const WCHAR x64_subdirW[] = {'x','6','4',0};
|
||||
static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0};
|
||||
static const WCHAR x86_subdirW[] = {'w','3','2','x','8','6',0};
|
||||
static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0};
|
||||
static const WCHAR version3_subdirW[] = {'\\','3',0};
|
||||
static const WCHAR XcvMonitorW[] = {',','X','c','v','M','o','n','i','t','o','r',' ',0};
|
||||
static const WCHAR XcvPortW[] = {',','X','c','v','P','o','r','t',' ',0};
|
||||
|
||||
|
||||
static const printenv_t env_x86 = {x86_envnameW, x86_subdirW, 3,
|
||||
|
@ -273,6 +291,32 @@ static LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
|
|||
return serverlen;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* get_basename_from_name (internal)
|
||||
*
|
||||
* skip over the serverpart from the full name
|
||||
*
|
||||
*/
|
||||
static LPCWSTR get_basename_from_name(LPCWSTR name)
|
||||
{
|
||||
if (name == NULL) return NULL;
|
||||
if ((name[0] == '\\') && (name[1] == '\\')) {
|
||||
/* skip over the servername and search for the following '\' */
|
||||
name = strchrW(&name[2], '\\');
|
||||
if ((name) && (name[1])) {
|
||||
/* found a separator ('\') followed by a name:
|
||||
skip over the separator and return the rest */
|
||||
name++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no basename present (we found only a servername) */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* monitor_unload [internal]
|
||||
*
|
||||
|
@ -512,6 +556,65 @@ static DWORD monitor_loadall(void)
|
|||
return loaded;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* monitor_load_by_port [internal]
|
||||
*
|
||||
* load a printmonitor for a given port
|
||||
*
|
||||
* On failure, NULL is returned
|
||||
*/
|
||||
|
||||
static monitor_t * monitor_load_by_port(LPCWSTR portname)
|
||||
{
|
||||
HKEY hroot;
|
||||
HKEY hport;
|
||||
LPWSTR buffer;
|
||||
monitor_t * pm = NULL;
|
||||
DWORD registered = 0;
|
||||
DWORD id = 0;
|
||||
DWORD len;
|
||||
|
||||
TRACE("(%s)\n", debugstr_w(portname));
|
||||
|
||||
/* Try the Local Monitor first */
|
||||
if (RegOpenKeyW(HKEY_LOCAL_MACHINE, winnt_cv_portsW, &hroot) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueExW(hroot, portname, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
|
||||
/* found the portname */
|
||||
RegCloseKey(hroot);
|
||||
return monitor_load(localportW, NULL);
|
||||
}
|
||||
RegCloseKey(hroot);
|
||||
}
|
||||
|
||||
len = MAX_PATH + lstrlenW(bs_ports_bsW) + lstrlenW(portname) + 1;
|
||||
buffer = heap_alloc(len * sizeof(WCHAR));
|
||||
if (buffer == NULL) return NULL;
|
||||
|
||||
if (RegOpenKeyW(HKEY_LOCAL_MACHINE, monitorsW, &hroot) == ERROR_SUCCESS) {
|
||||
EnterCriticalSection(&monitor_handles_cs);
|
||||
RegQueryInfoKeyW(hroot, NULL, NULL, NULL, ®istered, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
while ((pm == NULL) && (id < registered)) {
|
||||
buffer[0] = '\0';
|
||||
RegEnumKeyW(hroot, id, buffer, MAX_PATH);
|
||||
TRACE("testing %s\n", debugstr_w(buffer));
|
||||
len = lstrlenW(buffer);
|
||||
lstrcatW(buffer, bs_ports_bsW);
|
||||
lstrcatW(buffer, portname);
|
||||
if (RegOpenKeyW(hroot, buffer, &hport) == ERROR_SUCCESS) {
|
||||
RegCloseKey(hport);
|
||||
buffer[len] = '\0'; /* use only the Monitor-Name */
|
||||
pm = monitor_load(buffer, NULL);
|
||||
}
|
||||
id++;
|
||||
}
|
||||
LeaveCriticalSection(&monitor_handles_cs);
|
||||
RegCloseKey(hroot);
|
||||
}
|
||||
heap_free(buffer);
|
||||
return pm;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* Return the number of bytes for an multi_sz string.
|
||||
* The result includes all \0s
|
||||
|
@ -907,6 +1010,139 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname)
|
|||
return hui;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* printer_free
|
||||
* free the data pointer of an opened printer
|
||||
*/
|
||||
static VOID printer_free(printer_t * printer)
|
||||
{
|
||||
if (printer->hXcv)
|
||||
printer->pm->monitor->pfnXcvClosePort(printer->hXcv);
|
||||
|
||||
monitor_unload(printer->pm);
|
||||
|
||||
heap_free(printer->printername);
|
||||
heap_free(printer->name);
|
||||
heap_free(printer);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* printer_alloc_handle
|
||||
* alloc a printer handle and remember the data pointer in the printer handle table
|
||||
*
|
||||
*/
|
||||
static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault)
|
||||
{
|
||||
WCHAR servername[MAX_COMPUTERNAME_LENGTH + 1];
|
||||
printer_t *printer = NULL;
|
||||
LPCWSTR printername;
|
||||
HKEY hkeyPrinters;
|
||||
HKEY hkeyPrinter;
|
||||
DWORD len;
|
||||
|
||||
if (copy_servername_from_name(name, servername)) {
|
||||
FIXME("server %s not supported\n", debugstr_w(servername));
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printername = get_basename_from_name(name);
|
||||
if (name != printername) TRACE("converted %s to %s\n", debugstr_w(name), debugstr_w(printername));
|
||||
|
||||
/* an empty printername is invalid */
|
||||
if (printername && (!printername[0])) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printer = heap_alloc_zero(sizeof(printer_t));
|
||||
if (!printer) goto end;
|
||||
|
||||
/* clone the base name. This is NULL for the printserver */
|
||||
printer->printername = strdupW(printername);
|
||||
|
||||
/* clone the full name */
|
||||
printer->name = strdupW(name);
|
||||
if (name && (!printer->name)) {
|
||||
printer_free(printer);
|
||||
printer = NULL;
|
||||
}
|
||||
if (printername) {
|
||||
len = sizeof(XcvMonitorW)/sizeof(WCHAR) - 1;
|
||||
if (strncmpW(printername, XcvMonitorW, len) == 0) {
|
||||
/* OpenPrinter(",XcvMonitor ", ...) detected */
|
||||
TRACE(",XcvMonitor: %s\n", debugstr_w(&printername[len]));
|
||||
printer->pm = monitor_load(&printername[len], NULL);
|
||||
if (printer->pm == NULL) {
|
||||
printer_free(printer);
|
||||
SetLastError(ERROR_UNKNOWN_PORT);
|
||||
printer = NULL;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = sizeof(XcvPortW)/sizeof(WCHAR) - 1;
|
||||
if (strncmpW( printername, XcvPortW, len) == 0) {
|
||||
/* OpenPrinter(",XcvPort ", ...) detected */
|
||||
TRACE(",XcvPort: %s\n", debugstr_w(&printername[len]));
|
||||
printer->pm = monitor_load_by_port(&printername[len]);
|
||||
if (printer->pm == NULL) {
|
||||
printer_free(printer);
|
||||
SetLastError(ERROR_UNKNOWN_PORT);
|
||||
printer = NULL;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (printer->pm) {
|
||||
if ((printer->pm->monitor) && (printer->pm->monitor->pfnXcvOpenPort)) {
|
||||
printer->pm->monitor->pfnXcvOpenPort(&printername[len],
|
||||
pDefault ? pDefault->DesiredAccess : 0,
|
||||
&printer->hXcv);
|
||||
}
|
||||
if (printer->hXcv == NULL) {
|
||||
printer_free(printer);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
printer = NULL;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Does the Printer exist? */
|
||||
if (RegCreateKeyW(HKEY_LOCAL_MACHINE, printersW, &hkeyPrinters) != ERROR_SUCCESS) {
|
||||
ERR("Can't create Printers key\n");
|
||||
printer_free(printer);
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
printer = NULL;
|
||||
goto end;
|
||||
}
|
||||
if (RegOpenKeyW(hkeyPrinters, printername, &hkeyPrinter) != ERROR_SUCCESS) {
|
||||
WARN("Printer not found in Registry: %s\n", debugstr_w(printername));
|
||||
RegCloseKey(hkeyPrinters);
|
||||
printer_free(printer);
|
||||
SetLastError(ERROR_INVALID_PRINTER_NAME);
|
||||
printer = NULL;
|
||||
goto end;
|
||||
}
|
||||
RegCloseKey(hkeyPrinter);
|
||||
RegCloseKey(hkeyPrinters);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("using the local printserver\n");
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
TRACE("==> %p\n", printer);
|
||||
return (HANDLE)printer;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* myAddPrinterDriverEx [internal]
|
||||
*
|
||||
|
@ -1213,6 +1449,34 @@ static BOOL WINAPI fpAddPrinterDriverEx(LPWSTR pName, DWORD level, LPBYTE pDrive
|
|||
|
||||
return myAddPrinterDriverEx(level, pDriverInfo, dwFileCopyFlags, TRUE);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* fpClosePrinter [exported through PRINTPROVIDOR]
|
||||
*
|
||||
* Close a printer handle and free associated resources
|
||||
*
|
||||
* PARAMS
|
||||
* hPrinter [I] Printerhandle to close
|
||||
*
|
||||
* RESULTS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
*/
|
||||
static BOOL WINAPI fpClosePrinter(HANDLE hPrinter)
|
||||
{
|
||||
printer_t *printer = (printer_t *) hPrinter;
|
||||
|
||||
TRACE("(%p)\n", hPrinter);
|
||||
|
||||
if (printer) {
|
||||
printer_free(printer);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* fpDeleteMonitor [exported through PRINTPROVIDOR]
|
||||
*
|
||||
|
@ -1425,13 +1689,115 @@ emP_cleanup:
|
|||
return (res);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* fpOpenPrinter [exported through PRINTPROVIDOR]
|
||||
*
|
||||
* Open a Printer / Printserver or a Printer-Object
|
||||
*
|
||||
* PARAMS
|
||||
* lpPrinterName [I] Name of Printserver, Printer, or Printer-Object
|
||||
* pPrinter [O] The resulting Handle is stored here
|
||||
* pDefaults [I] PTR to Default Printer Settings or NULL
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* NOTES
|
||||
* lpPrinterName is one of:
|
||||
*| Printserver (NT only): "Servername" or NULL for the local Printserver
|
||||
*| Printer: "PrinterName"
|
||||
*| Printer-Object: "PrinterName,Job xxx"
|
||||
*| XcvMonitor: "Servername,XcvMonitor MonitorName"
|
||||
*| XcvPort: "Servername,XcvPort PortName"
|
||||
*
|
||||
*
|
||||
*/
|
||||
static BOOL WINAPI fpOpenPrinter(LPWSTR lpPrinterName, HANDLE *pPrinter,
|
||||
LPPRINTER_DEFAULTSW pDefaults)
|
||||
{
|
||||
|
||||
TRACE("(%s, %p, %p)\n", debugstr_w(lpPrinterName), pPrinter, pDefaults);
|
||||
|
||||
*pPrinter = printer_alloc_handle(lpPrinterName, pDefaults);
|
||||
|
||||
return (*pPrinter != 0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* fpXcvData [exported through PRINTPROVIDOR]
|
||||
*
|
||||
* Execute commands in the Printmonitor DLL
|
||||
*
|
||||
* PARAMS
|
||||
* hXcv [i] Handle from fpOpenPrinter (with XcvMonitor or XcvPort)
|
||||
* pszDataName [i] Name of the command to execute
|
||||
* pInputData [i] Buffer for extra Input Data (needed only for some commands)
|
||||
* cbInputData [i] Size in Bytes of Buffer at pInputData
|
||||
* pOutputData [o] Buffer to receive additional Data (needed only for some commands)
|
||||
* cbOutputData [i] Size in Bytes of Buffer at pOutputData
|
||||
* pcbOutputNeeded [o] PTR to receive the minimal Size in Bytes of the Buffer at pOutputData
|
||||
* pdwStatus [o] PTR to receive the win32 error code from the Printmonitor DLL
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* NOTES
|
||||
* Returning "TRUE" does mean, that the Printmonitor DLL was called successful.
|
||||
* The execution of the command can still fail (check pdwStatus for ERROR_SUCCESS).
|
||||
*
|
||||
* Minimal List of commands, that a Printmonitor DLL should support:
|
||||
*
|
||||
*| "MonitorUI" : Return the Name of the Userinterface-DLL as WSTR in pOutputData
|
||||
*| "AddPort" : Add a Port
|
||||
*| "DeletePort": Delete a Port
|
||||
*
|
||||
* Many Printmonitors support additional commands. Examples for localspl.dll:
|
||||
* "GetDefaultCommConfig", "SetDefaultCommConfig",
|
||||
* "GetTransmissionRetryTimeout", "ConfigureLPTPortCommandOK"
|
||||
*
|
||||
*/
|
||||
static BOOL WINAPI fpXcvData(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
|
||||
DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData,
|
||||
PDWORD pcbOutputNeeded, PDWORD pdwStatus)
|
||||
{
|
||||
printer_t *printer = (printer_t * ) hXcv;
|
||||
|
||||
TRACE("(%p, %s, %p, %d, %p, %d, %p, %p)\n", hXcv, debugstr_w(pszDataName),
|
||||
pInputData, cbInputData, pOutputData,
|
||||
cbOutputData, pcbOutputNeeded, pdwStatus);
|
||||
|
||||
if (!printer || (!printer->hXcv)) {
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pcbOutputNeeded) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pszDataName || !pdwStatus || (!pOutputData && (cbOutputData > 0))) {
|
||||
SetLastError(RPC_X_NULL_REF_POINTER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pcbOutputNeeded = 0;
|
||||
|
||||
*pdwStatus = printer->pm->monitor->pfnXcvDataPort(printer->hXcv, pszDataName,
|
||||
pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* setup_provider [internal]
|
||||
*/
|
||||
void setup_provider(void)
|
||||
{
|
||||
static const PRINTPROVIDOR backend = {
|
||||
NULL, /* fpOpenPrinter */
|
||||
fpOpenPrinter,
|
||||
NULL, /* fpSetJob */
|
||||
NULL, /* fpGetJob */
|
||||
NULL, /* fpEnumJobs */
|
||||
|
@ -1462,7 +1828,7 @@ void setup_provider(void)
|
|||
NULL, /* fpGetPrinterData */
|
||||
NULL, /* fpSetPrinterData */
|
||||
NULL, /* fpWaitForPrinterChange */
|
||||
NULL, /* fpClosePrinter */
|
||||
fpClosePrinter,
|
||||
NULL, /* fpAddForm */
|
||||
NULL, /* fpDeleteForm */
|
||||
NULL, /* fpGetForm */
|
||||
|
@ -1507,7 +1873,7 @@ void setup_provider(void)
|
|||
NULL, /* fpAddPerMachineConnection */
|
||||
NULL, /* fpDeletePerMachineConnection */
|
||||
NULL, /* fpEnumPerMachineConnections */
|
||||
NULL, /* fpXcvData */
|
||||
fpXcvData,
|
||||
fpAddPrinterDriverEx,
|
||||
NULL, /* fpSplReadPrinter */
|
||||
NULL, /* fpDriverUnloadComplete */
|
||||
|
|
|
@ -337,6 +337,110 @@ static DWORD MCIQTZ_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
|
|||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* MCIQTZ_mciGetDevCaps [internal]
|
||||
*/
|
||||
static DWORD MCIQTZ_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
|
||||
{
|
||||
WINE_MCIQTZ* wma;
|
||||
|
||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||
|
||||
if (!lpParms)
|
||||
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||
|
||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||
if (!wma)
|
||||
return MCIERR_INVALID_DEVICE_ID;
|
||||
|
||||
if (!(dwFlags & MCI_STATUS_ITEM)) {
|
||||
WARN("No capability item specified\n");
|
||||
return MCIERR_UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
|
||||
switch (lpParms->dwItem) {
|
||||
case MCI_GETDEVCAPS_CAN_RECORD:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
||||
TRACE("MCI_GETDEVCAPS_CAN_RECORD = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_HAS_AUDIO:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
||||
TRACE("MCI_GETDEVCAPS_HAS_AUDIO = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_HAS_VIDEO:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
||||
TRACE("MCI_GETDEVCAPS_HAS_VIDEO = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_DEVICE_TYPE:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_DIGITAL_VIDEO, MCI_DEVTYPE_DIGITAL_VIDEO);
|
||||
TRACE("MCI_GETDEVCAPS_DEVICE_TYPE = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_USES_FILES:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
||||
TRACE("MCI_GETDEVCAPS_USES_FILES = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_COMPOUND_DEVICE:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
||||
TRACE("MCI_GETDEVCAPS_COMPOUND_DEVICE = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_CAN_EJECT:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
||||
TRACE("MCI_GETDEVCAPS_EJECT = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_CAN_PLAY:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
|
||||
TRACE("MCI_GETDEVCAPS_CAN_PLAY = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
case MCI_GETDEVCAPS_CAN_SAVE:
|
||||
lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
|
||||
TRACE("MCI_GETDEVCAPS_CAN_SAVE = %08x\n", lpParms->dwReturn);
|
||||
break;
|
||||
default:
|
||||
ERR("Unknown capability %08x\n", lpParms->dwItem);
|
||||
return MCIERR_UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
|
||||
return MCI_RESOURCE_RETURNED;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* MCIQTZ_mciSet [internal]
|
||||
*/
|
||||
static DWORD MCIQTZ_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
|
||||
{
|
||||
WINE_MCIQTZ* wma;
|
||||
|
||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||
|
||||
if (!lpParms)
|
||||
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||
|
||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||
if (!wma)
|
||||
return MCIERR_INVALID_DEVICE_ID;
|
||||
|
||||
if (dwFlags & MCI_SET_TIME_FORMAT) {
|
||||
switch (lpParms->dwTimeFormat) {
|
||||
case MCI_FORMAT_MILLISECONDS:
|
||||
TRACE("MCI_SET_TIME_FORMAT = MCI_FORMAT_MILLISECONDS\n");
|
||||
wma->time_format = MCI_FORMAT_MILLISECONDS;
|
||||
break;
|
||||
case MCI_FORMAT_FRAMES:
|
||||
TRACE("MCI_SET_TIME_FORMAT = MCI_FORMAT_FRAMES\n");
|
||||
wma->time_format = MCI_FORMAT_FRAMES;
|
||||
break;
|
||||
default:
|
||||
WARN("Bad time format %u\n", lpParms->dwTimeFormat);
|
||||
return MCIERR_BAD_TIME_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
if (dwFlags & ~MCI_SET_TIME_FORMAT)
|
||||
FIXME("Flags not supported yet %08lX\n", dwFlags & ~MCI_SET_TIME_FORMAT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* MCIQTZ_mciStatus [internal]
|
||||
*/
|
||||
|
@ -415,6 +519,90 @@ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMS
|
|||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* MCIQTZ_mciWhere [internal]
|
||||
*/
|
||||
static DWORD MCIQTZ_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
|
||||
{
|
||||
WINE_MCIQTZ* wma;
|
||||
IVideoWindow* pVideoWindow;
|
||||
HRESULT hr;
|
||||
HWND hWnd;
|
||||
RECT rc;
|
||||
|
||||
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
|
||||
|
||||
if (!lpParms)
|
||||
return MCIERR_NULL_PARAMETER_BLOCK;
|
||||
|
||||
wma = MCIQTZ_mciGetOpenDev(wDevID);
|
||||
if (!wma)
|
||||
return MCIERR_INVALID_DEVICE_ID;
|
||||
|
||||
/* Find if there is a video stream and get the display window */
|
||||
hr = IGraphBuilder_QueryInterface(wma->pgraph, &IID_IVideoWindow, (LPVOID*)&pVideoWindow);
|
||||
if (FAILED(hr)) {
|
||||
ERR("Cannot get IVideoWindow interface (hr = %x)\n", hr);
|
||||
return MCIERR_INTERNAL;
|
||||
}
|
||||
|
||||
hr = IVideoWindow_get_Owner(pVideoWindow, (OAHWND*)&hWnd);
|
||||
IVideoWindow_Release(pVideoWindow);
|
||||
if (FAILED(hr)) {
|
||||
TRACE("No video stream, returning no window error\n");
|
||||
return MCIERR_NO_WINDOW;
|
||||
}
|
||||
|
||||
if (dwFlags & MCI_DGV_WHERE_SOURCE) {
|
||||
if (dwFlags & MCI_DGV_WHERE_MAX)
|
||||
FIXME("MCI_DGV_WHERE_SOURCE_MAX not supported yet\n");
|
||||
else
|
||||
FIXME("MCI_DGV_WHERE_SOURCE not supported yet\n");
|
||||
return MCIERR_UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
if (dwFlags & MCI_DGV_WHERE_DESTINATION) {
|
||||
if (dwFlags & MCI_DGV_WHERE_MAX) {
|
||||
GetClientRect(hWnd, &rc);
|
||||
TRACE("MCI_DGV_WHERE_DESTINATION_MAX %s\n", wine_dbgstr_rect(&rc));
|
||||
} else {
|
||||
FIXME("MCI_DGV_WHERE_DESTINATION not supported yet\n");
|
||||
return MCIERR_UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
}
|
||||
if (dwFlags & MCI_DGV_WHERE_FRAME) {
|
||||
if (dwFlags & MCI_DGV_WHERE_MAX)
|
||||
FIXME("MCI_DGV_WHERE_FRAME_MAX not supported yet\n");
|
||||
else
|
||||
FIXME("MCI_DGV_WHERE_FRAME not supported yet\n");
|
||||
return MCIERR_UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
if (dwFlags & MCI_DGV_WHERE_VIDEO) {
|
||||
if (dwFlags & MCI_DGV_WHERE_MAX)
|
||||
FIXME("MCI_DGV_WHERE_VIDEO_MAX not supported yet\n");
|
||||
else
|
||||
FIXME("MCI_DGV_WHERE_VIDEO not supported yet\n");
|
||||
return MCIERR_UNRECOGNIZED_COMMAND;
|
||||
}
|
||||
if (dwFlags & MCI_DGV_WHERE_WINDOW) {
|
||||
if (dwFlags & MCI_DGV_WHERE_MAX) {
|
||||
GetWindowRect(GetDesktopWindow(), &rc);
|
||||
TRACE("MCI_DGV_WHERE_WINDOW_MAX %s\n", wine_dbgstr_rect(&rc));
|
||||
} else {
|
||||
GetWindowRect(hWnd, &rc);
|
||||
TRACE("MCI_DGV_WHERE_WINDOW %s\n", wine_dbgstr_rect(&rc));
|
||||
}
|
||||
}
|
||||
|
||||
/* In MCI, RECT structure is used differently: rc.right = width & rc.bottom = height
|
||||
* So convert the normal RECT into a MCI RECT before returning */
|
||||
lpParms->rc.left = rc.left;
|
||||
lpParms->rc.top = rc.right;
|
||||
lpParms->rc.right = rc.right - rc.left;
|
||||
lpParms->rc.bottom = rc.bottom - rc.top;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* MCI QTZ entry points *
|
||||
*======================================================================*/
|
||||
|
@ -451,12 +639,13 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
|
|||
case MCI_PLAY: return MCIQTZ_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2);
|
||||
case MCI_SEEK: return MCIQTZ_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
|
||||
case MCI_STOP: return MCIQTZ_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
|
||||
case MCI_GETDEVCAPS: return MCIQTZ_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
|
||||
case MCI_SET: return MCIQTZ_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2);
|
||||
case MCI_STATUS: return MCIQTZ_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSW) dwParam2);
|
||||
case MCI_WHERE: return MCIQTZ_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
|
||||
case MCI_RECORD:
|
||||
case MCI_SET:
|
||||
case MCI_PAUSE:
|
||||
case MCI_RESUME:
|
||||
case MCI_GETDEVCAPS:
|
||||
case MCI_INFO:
|
||||
case MCI_PUT:
|
||||
case MCI_WINDOW:
|
||||
|
@ -466,7 +655,6 @@ LRESULT CALLBACK MCIQTZ_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
|
|||
case MCI_REALIZE:
|
||||
case MCI_UNFREEZE:
|
||||
case MCI_UPDATE:
|
||||
case MCI_WHERE:
|
||||
case MCI_STEP:
|
||||
case MCI_COPY:
|
||||
case MCI_CUT:
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef struct {
|
|||
IGraphBuilder* pgraph;
|
||||
IMediaControl* pmctrl;
|
||||
BOOL started;
|
||||
DWORD time_format;
|
||||
} WINE_MCIQTZ;
|
||||
|
||||
#endif /* __WINE_PRIVATE_MCIQTZ_H */
|
||||
|
|
|
@ -103,8 +103,8 @@
|
|||
@ stub StrongNameSignatureGeneration
|
||||
@ stub StrongNameSignatureGenerationEx
|
||||
@ stub StrongNameSignatureSize
|
||||
@ stub StrongNameSignatureVerification
|
||||
@ stub StrongNameSignatureVerificationEx
|
||||
@ stdcall StrongNameSignatureVerification(wstr long ptr)
|
||||
@ stdcall StrongNameSignatureVerificationEx(wstr long ptr)
|
||||
@ stub StrongNameSignatureVerificationFromImage
|
||||
@ stub StrongNameTokenFromAssembly
|
||||
@ stub StrongNameTokenFromAssemblyEx
|
||||
|
|
|
@ -324,6 +324,18 @@ HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags)
|
||||
{
|
||||
FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename), inFlags, pOutFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerification, BOOL* pVerified)
|
||||
{
|
||||
FIXME("(%s, %u, %p): stub\n", debugstr_w(filename), forceVerification, pVerified);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
{
|
||||
FIXME("(%p, %p, %p): stub\n", rclsid, riid, ppv);
|
||||
|
|
|
@ -144,9 +144,37 @@ static HRESULT WINAPI CategoryMgr_RegisterCategory ( ITfCategoryMgr *iface,
|
|||
static HRESULT WINAPI CategoryMgr_UnregisterCategory ( ITfCategoryMgr *iface,
|
||||
REFCLSID rclsid, REFGUID rcatid, REFGUID rguid)
|
||||
{
|
||||
WCHAR fullkey[110];
|
||||
WCHAR buf[39];
|
||||
WCHAR buf2[39];
|
||||
HKEY tipkey;
|
||||
CategoryMgr *This = (CategoryMgr*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
static const WCHAR ctg[] = {'C','a','t','e','g','o','r','y',0};
|
||||
static const WCHAR itm[] = {'I','t','e','m',0};
|
||||
static const WCHAR fmt[] = {'%','s','\\','%','s',0};
|
||||
static const WCHAR fmt2[] = {'%','s','\\','%','s','\\','%','s','\\','%','s',0};
|
||||
|
||||
TRACE("(%p) %s %s %s\n",This,debugstr_guid(rclsid), debugstr_guid(rcatid), debugstr_guid(rguid));
|
||||
|
||||
StringFromGUID2(rclsid, buf, 39);
|
||||
sprintfW(fullkey,fmt,szwSystemTIPKey,buf);
|
||||
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ | KEY_WRITE,
|
||||
&tipkey ) != ERROR_SUCCESS)
|
||||
return E_FAIL;
|
||||
|
||||
StringFromGUID2(rcatid, buf, 39);
|
||||
StringFromGUID2(rguid, buf2, 39);
|
||||
sprintfW(fullkey,fmt2,ctg,ctg,buf,buf2);
|
||||
|
||||
sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
|
||||
RegDeleteTreeW(tipkey, fullkey);
|
||||
sprintfW(fullkey,fmt2,ctg,itm,buf2,buf);
|
||||
RegDeleteTreeW(tipkey, fullkey);
|
||||
|
||||
RegCloseKey(tipkey);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CategoryMgr_EnumCategoriesInItem ( ITfCategoryMgr *iface,
|
||||
|
@ -284,25 +312,77 @@ static HRESULT WINAPI CategoryMgr_RegisterGUID ( ITfCategoryMgr *iface,
|
|||
REFGUID rguid, TfGuidAtom *pguidatom
|
||||
)
|
||||
{
|
||||
DWORD index;
|
||||
GUID *checkguid;
|
||||
DWORD id;
|
||||
CategoryMgr *This = (CategoryMgr*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p) %s %p\n",This,debugstr_guid(rguid),pguidatom);
|
||||
|
||||
if (!pguidatom)
|
||||
return E_INVALIDARG;
|
||||
|
||||
index = 0;
|
||||
do {
|
||||
id = enumerate_Cookie(COOKIE_MAGIC_GUIDATOM,&index);
|
||||
if (id && IsEqualGUID(rguid,get_Cookie_data(id)))
|
||||
{
|
||||
*pguidatom = id;
|
||||
return S_OK;
|
||||
}
|
||||
} while(id);
|
||||
|
||||
checkguid = HeapAlloc(GetProcessHeap(),0,sizeof(GUID));
|
||||
*checkguid = *rguid;
|
||||
id = generate_Cookie(COOKIE_MAGIC_GUIDATOM,checkguid);
|
||||
|
||||
if (!id)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,checkguid);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
*pguidatom = id;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CategoryMgr_GetGUID ( ITfCategoryMgr *iface,
|
||||
TfGuidAtom guidatom, GUID *pguid)
|
||||
{
|
||||
CategoryMgr *This = (CategoryMgr*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p) %i\n",This,guidatom);
|
||||
|
||||
if (!pguid)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pguid = GUID_NULL;
|
||||
|
||||
if (get_Cookie_magic(guidatom) == COOKIE_MAGIC_GUIDATOM)
|
||||
*pguid = *((REFGUID)get_Cookie_data(guidatom));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI CategoryMgr_IsEqualTfGuidAtom ( ITfCategoryMgr *iface,
|
||||
TfGuidAtom guidatom, REFGUID rguid, BOOL *pfEqual)
|
||||
{
|
||||
CategoryMgr *This = (CategoryMgr*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p) %i %s %p\n",This,guidatom,debugstr_guid(rguid),pfEqual);
|
||||
|
||||
if (!pfEqual)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pfEqual = FALSE;
|
||||
if (get_Cookie_magic(guidatom) == COOKIE_MAGIC_GUIDATOM)
|
||||
{
|
||||
if (IsEqualGUID(rguid,get_Cookie_data(guidatom)))
|
||||
*pfEqual = TRUE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -288,18 +288,61 @@ static HRESULT WINAPI InputProcessorProfiles_ActivateLanguageProfile(
|
|||
ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid,
|
||||
REFGUID guidProfiles)
|
||||
{
|
||||
HRESULT hr;
|
||||
BOOL enabled;
|
||||
TF_LANGUAGEPROFILE LanguageProfile;
|
||||
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p) %s %x %s\n",This,debugstr_guid(rclsid),langid,debugstr_guid(guidProfiles));
|
||||
|
||||
if (langid != This->currentLanguage) return E_INVALIDARG;
|
||||
|
||||
if (get_active_textservice(rclsid,NULL))
|
||||
{
|
||||
TRACE("Already Active\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(iface, rclsid,
|
||||
langid, guidProfiles, &enabled);
|
||||
if (FAILED(hr) || !enabled)
|
||||
{
|
||||
TRACE("Not Enabled\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
LanguageProfile.clsid = *rclsid;
|
||||
LanguageProfile.langid = langid;
|
||||
LanguageProfile.guidProfile = *guidProfiles;
|
||||
|
||||
hr = add_active_textservice(&LanguageProfile);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InputProcessorProfiles_GetActiveLanguageProfile(
|
||||
ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID *plangid,
|
||||
GUID *pguidProfile)
|
||||
{
|
||||
TF_LANGUAGEPROFILE profile;
|
||||
InputProcessorProfiles *This = (InputProcessorProfiles*)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p) %s %p %p\n",This,debugstr_guid(rclsid),plangid,pguidProfile);
|
||||
|
||||
if (!rclsid || !plangid || !pguidProfile)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (get_active_textservice(rclsid, &profile))
|
||||
{
|
||||
*plangid = profile.langid;
|
||||
*pguidProfile = profile.guidProfile;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pguidProfile = GUID_NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI InputProcessorProfiles_GetLanguageProfileDescription(
|
||||
|
@ -756,8 +799,7 @@ static INT next_LanguageProfile(EnumTfLanguageProfiles *This, CLSID clsid, TF_LA
|
|||
|
||||
tflp->clsid = clsid;
|
||||
tflp->langid = This->langid;
|
||||
/* FIXME */
|
||||
tflp->fActive = FALSE;
|
||||
tflp->fActive = get_active_textservice(&clsid, NULL);
|
||||
tflp->guidProfile = profile;
|
||||
if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
|
||||
&tflp->catid, tipcats, 3) != S_OK)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define COBJMACROS
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
|
@ -50,11 +51,28 @@ typedef struct
|
|||
LPVOID data;
|
||||
} CookieInternal;
|
||||
|
||||
typedef struct {
|
||||
TF_LANGUAGEPROFILE LanguageProfile;
|
||||
ITfTextInputProcessor *pITfTextInputProcessor;
|
||||
ITfThreadMgr *pITfThreadMgr;
|
||||
TfClientId tid;
|
||||
} ActivatedTextService;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct list entry;
|
||||
ActivatedTextService *ats;
|
||||
} AtsEntry;
|
||||
|
||||
static CookieInternal *cookies;
|
||||
static UINT id_last;
|
||||
static UINT array_size;
|
||||
|
||||
static struct list AtsList = LIST_INIT(AtsList);
|
||||
static UINT activated = 0;
|
||||
|
||||
DWORD tlsIndex = 0;
|
||||
TfClientId processId = 0;
|
||||
|
||||
const WCHAR szwSystemTIPKey[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','C','T','F','\\','T','I','P',0};
|
||||
|
||||
|
@ -252,6 +270,192 @@ LPVOID remove_Cookie(DWORD id)
|
|||
return cookies[index].data;
|
||||
}
|
||||
|
||||
DWORD enumerate_Cookie(DWORD magic, DWORD *index)
|
||||
{
|
||||
int i;
|
||||
for (i = *index; i < id_last; i++)
|
||||
if (cookies[i].id != 0 && cookies[i].magic == magic)
|
||||
{
|
||||
*index = (i+1);
|
||||
return cookies[i].id;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Active Text Service Management
|
||||
*****************************************************************************/
|
||||
static HRESULT activate_given_ts(ActivatedTextService *actsvr, ITfThreadMgr* tm)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
/* Already Active? */
|
||||
if (actsvr->pITfTextInputProcessor)
|
||||
return S_OK;
|
||||
|
||||
hr = CoCreateInstance (&actsvr->LanguageProfile.clsid, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_ITfTextInputProcessor, (void**)&actsvr->pITfTextInputProcessor);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = ITfTextInputProcessor_Activate(actsvr->pITfTextInputProcessor, tm, actsvr->tid);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ITfTextInputProcessor_Release(actsvr->pITfTextInputProcessor);
|
||||
actsvr->pITfTextInputProcessor = NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
actsvr->pITfThreadMgr = tm;
|
||||
ITfThreadMgr_AddRef(tm);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT deactivate_given_ts(ActivatedTextService *actsvr)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (actsvr->pITfTextInputProcessor)
|
||||
{
|
||||
hr = ITfTextInputProcessor_Deactivate(actsvr->pITfTextInputProcessor);
|
||||
ITfTextInputProcessor_Release(actsvr->pITfTextInputProcessor);
|
||||
ITfThreadMgr_Release(actsvr->pITfThreadMgr);
|
||||
actsvr->pITfTextInputProcessor = NULL;
|
||||
actsvr->pITfThreadMgr = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void deactivate_remove_conflicting_ts(REFCLSID catid)
|
||||
{
|
||||
AtsEntry *ats, *cursor2;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(ats, cursor2, &AtsList, AtsEntry, entry)
|
||||
{
|
||||
if (IsEqualCLSID(catid,&ats->ats->LanguageProfile.catid))
|
||||
{
|
||||
deactivate_given_ts(ats->ats);
|
||||
list_remove(&ats->entry);
|
||||
HeapFree(GetProcessHeap(),0,ats->ats);
|
||||
HeapFree(GetProcessHeap(),0,ats);
|
||||
/* we are guarenteeing there is only 1 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp)
|
||||
{
|
||||
ActivatedTextService *actsvr;
|
||||
ITfCategoryMgr *catmgr;
|
||||
AtsEntry *entry;
|
||||
ITfThreadMgr *tm = (ITfThreadMgr*)TlsGetValue(tlsIndex);
|
||||
ITfClientId *clientid;
|
||||
|
||||
if (!tm) return E_UNEXPECTED;
|
||||
|
||||
actsvr = HeapAlloc(GetProcessHeap(),0,sizeof(ActivatedTextService));
|
||||
if (!actsvr) return E_OUTOFMEMORY;
|
||||
|
||||
entry = HeapAlloc(GetProcessHeap(),0,sizeof(AtsEntry));
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,actsvr);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ITfThreadMgr_QueryInterface(tm,&IID_ITfClientId,(LPVOID)&clientid);
|
||||
ITfClientId_GetClientId(clientid, &lp->clsid, &actsvr->tid);
|
||||
ITfClientId_Release(clientid);
|
||||
|
||||
if (!actsvr->tid)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,actsvr);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
actsvr->pITfTextInputProcessor = NULL;
|
||||
actsvr->LanguageProfile = *lp;
|
||||
actsvr->LanguageProfile.fActive = TRUE;
|
||||
|
||||
/* get TIP category */
|
||||
if (SUCCEEDED(CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr)))
|
||||
{
|
||||
static const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING};
|
||||
|
||||
ITfCategoryMgr_FindClosestCategory(catmgr,
|
||||
&actsvr->LanguageProfile.clsid, &actsvr->LanguageProfile.catid,
|
||||
list, 3);
|
||||
|
||||
ITfCategoryMgr_Release(catmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("CategoryMgr construction failed\n");
|
||||
actsvr->LanguageProfile.catid = GUID_NULL;
|
||||
}
|
||||
|
||||
if (!IsEqualGUID(&actsvr->LanguageProfile.catid,&GUID_NULL))
|
||||
deactivate_remove_conflicting_ts(&actsvr->LanguageProfile.catid);
|
||||
|
||||
if (activated > 0)
|
||||
activate_given_ts(actsvr, tm);
|
||||
|
||||
entry->ats = actsvr;
|
||||
list_add_head(&AtsList, &entry->entry);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *profile)
|
||||
{
|
||||
AtsEntry *ats;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
|
||||
{
|
||||
if (IsEqualCLSID(rclsid,&ats->ats->LanguageProfile.clsid))
|
||||
{
|
||||
if (profile)
|
||||
*profile = ats->ats->LanguageProfile;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT activate_textservices(ITfThreadMgr *tm)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
AtsEntry *ats;
|
||||
|
||||
activated ++;
|
||||
if (activated > 1)
|
||||
return S_OK;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
|
||||
{
|
||||
hr = activate_given_ts(ats->ats, tm);
|
||||
if (FAILED(hr))
|
||||
FIXME("Failed to activate text service\n");
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT deactivate_textservices(void)
|
||||
{
|
||||
AtsEntry *ats;
|
||||
|
||||
if (activated > 0)
|
||||
activated --;
|
||||
|
||||
if (activated == 0)
|
||||
LIST_FOR_EACH_ENTRY(ats, &AtsList, AtsEntry, entry)
|
||||
deactivate_given_ts(ats->ats);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* MSCTF DllMain
|
||||
*/
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
|
||||
#define COOKIE_MAGIC_TMSINK 0x0010
|
||||
#define COOKIE_MAGIC_CONTEXTSINK 0x0020
|
||||
#define COOKIE_MAGIC_GUIDATOM 0x0030
|
||||
|
||||
extern DWORD tlsIndex;
|
||||
extern TfClientId processId;
|
||||
|
||||
extern HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut);
|
||||
extern HRESULT DocumentMgr_Constructor(ITfThreadMgrEventSink*, ITfDocumentMgr **ppOut);
|
||||
|
@ -37,6 +39,13 @@ extern DWORD generate_Cookie(DWORD magic, LPVOID data);
|
|||
extern DWORD get_Cookie_magic(DWORD id);
|
||||
extern LPVOID get_Cookie_data(DWORD id);
|
||||
extern LPVOID remove_Cookie(DWORD id);
|
||||
extern DWORD enumerate_Cookie(DWORD magic, DWORD *index);
|
||||
|
||||
/* activated text services functions */
|
||||
extern HRESULT add_active_textservice(TF_LANGUAGEPROFILE *lp);
|
||||
extern BOOL get_active_textservice(REFCLSID rclsid, TF_LANGUAGEPROFILE *lp);
|
||||
extern HRESULT activate_textservices(ITfThreadMgr *tm);
|
||||
extern HRESULT deactivate_textservices(void);
|
||||
|
||||
extern const WCHAR szwSystemTIPKey[];
|
||||
#endif /* __WINE_MSCTF_I_H */
|
||||
|
|
|
@ -56,15 +56,29 @@ typedef struct tagThreadMgrSink {
|
|||
} interfaces;
|
||||
} ThreadMgrSink;
|
||||
|
||||
typedef struct tagPreservedKey
|
||||
{
|
||||
struct list entry;
|
||||
GUID guid;
|
||||
TF_PRESERVEDKEY prekey;
|
||||
LPWSTR description;
|
||||
TfClientId tid;
|
||||
} PreservedKey;
|
||||
|
||||
typedef struct tagACLMulti {
|
||||
const ITfThreadMgrVtbl *ThreadMgrVtbl;
|
||||
const ITfSourceVtbl *SourceVtbl;
|
||||
const ITfKeystrokeMgrVtbl *KeystrokeMgrVtbl;
|
||||
const ITfMessagePumpVtbl *MessagePumpVtbl;
|
||||
const ITfClientIdVtbl *ClientIdVtbl;
|
||||
LONG refCount;
|
||||
|
||||
const ITfThreadMgrEventSinkVtbl *ThreadMgrEventSinkVtbl; /* internal */
|
||||
|
||||
ITfDocumentMgr *focus;
|
||||
LONG activationCount;
|
||||
|
||||
struct list CurrentPreservedKeys;
|
||||
|
||||
/* kept as separate lists to reduce unnecessary iterations */
|
||||
struct list ActiveLanguageProfileNotifySink;
|
||||
|
@ -85,6 +99,16 @@ static inline ThreadMgr *impl_from_ITfKeystrokeMgrVtbl(ITfKeystrokeMgr *iface)
|
|||
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,KeystrokeMgrVtbl));
|
||||
}
|
||||
|
||||
static inline ThreadMgr *impl_from_ITfMessagePumpVtbl(ITfMessagePump *iface)
|
||||
{
|
||||
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,MessagePumpVtbl));
|
||||
}
|
||||
|
||||
static inline ThreadMgr *impl_from_ITfClientIdVtbl(ITfClientId *iface)
|
||||
{
|
||||
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ClientIdVtbl));
|
||||
}
|
||||
|
||||
static inline ThreadMgr *impl_from_ITfThreadMgrEventSink(ITfThreadMgrEventSink *iface)
|
||||
{
|
||||
return (ThreadMgr *)((char *)iface - FIELD_OFFSET(ThreadMgr,ThreadMgrEventSinkVtbl));
|
||||
|
@ -143,6 +167,14 @@ static void ThreadMgr_Destructor(ThreadMgr *This)
|
|||
free_sink(sink);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_SAFE(cursor, cursor2, &This->CurrentPreservedKeys)
|
||||
{
|
||||
PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
|
||||
list_remove(cursor);
|
||||
HeapFree(GetProcessHeap(),0,key->description);
|
||||
HeapFree(GetProcessHeap(),0,key);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
|
@ -163,6 +195,14 @@ static HRESULT WINAPI ThreadMgr_QueryInterface(ITfThreadMgr *iface, REFIID iid,
|
|||
{
|
||||
*ppvOut = &This->KeystrokeMgrVtbl;
|
||||
}
|
||||
else if (IsEqualIID(iid, &IID_ITfMessagePump))
|
||||
{
|
||||
*ppvOut = &This->MessagePumpVtbl;
|
||||
}
|
||||
else if (IsEqualIID(iid, &IID_ITfClientId))
|
||||
{
|
||||
*ppvOut = &This->ClientIdVtbl;
|
||||
}
|
||||
|
||||
if (*ppvOut)
|
||||
{
|
||||
|
@ -198,23 +238,48 @@ static ULONG WINAPI ThreadMgr_Release(ITfThreadMgr *iface)
|
|||
static HRESULT WINAPI ThreadMgr_fnActivate( ITfThreadMgr* iface, TfClientId *ptid)
|
||||
{
|
||||
ThreadMgr *This = (ThreadMgr *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p) %p\n",This, ptid);
|
||||
|
||||
if (!ptid)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!processId)
|
||||
{
|
||||
GUID guid;
|
||||
CoCreateGuid(&guid);
|
||||
ITfClientId_GetClientId((ITfClientId*)&This->ClientIdVtbl,&guid,&processId);
|
||||
}
|
||||
|
||||
activate_textservices(iface);
|
||||
This->activationCount++;
|
||||
*ptid = processId;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ThreadMgr_fnDeactivate( ITfThreadMgr* iface)
|
||||
{
|
||||
ThreadMgr *This = (ThreadMgr *)iface;
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if (This->focus)
|
||||
if (This->activationCount == 0)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
This->activationCount --;
|
||||
|
||||
if (This->activationCount == 0)
|
||||
{
|
||||
ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
|
||||
ITfDocumentMgr_Release(This->focus);
|
||||
This->focus = 0;
|
||||
if (This->focus)
|
||||
{
|
||||
ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus);
|
||||
ITfDocumentMgr_Release(This->focus);
|
||||
This->focus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return E_NOTIMPL;
|
||||
deactivate_textservices();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr
|
||||
|
@ -508,8 +573,25 @@ static HRESULT WINAPI KeystrokeMgr_IsPreservedKey(ITfKeystrokeMgr *iface,
|
|||
REFGUID rguid, const TF_PRESERVEDKEY *pprekey, BOOL *pfRegistered)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
struct list *cursor;
|
||||
|
||||
TRACE("(%p) %s (%x %x) %p\n",This,debugstr_guid(rguid), (pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0, pfRegistered);
|
||||
|
||||
if (!rguid || !pprekey || !pfRegistered)
|
||||
return E_INVALIDARG;
|
||||
|
||||
LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
|
||||
{
|
||||
PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
|
||||
if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
|
||||
{
|
||||
*pfRegistered = TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*pfRegistered = FALSE;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
|
||||
|
@ -517,16 +599,71 @@ static HRESULT WINAPI KeystrokeMgr_PreserveKey(ITfKeystrokeMgr *iface,
|
|||
const WCHAR *pchDesc, ULONG cchDesc)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
struct list *cursor;
|
||||
PreservedKey *newkey;
|
||||
|
||||
TRACE("(%p) %x %s (%x,%x) %s\n",This,tid, debugstr_guid(rguid),(prekey)?prekey->uVKey:0,(prekey)?prekey->uModifiers:0,debugstr_wn(pchDesc,cchDesc));
|
||||
|
||||
if (!tid || ! rguid || !prekey || (cchDesc && !pchDesc))
|
||||
return E_INVALIDARG;
|
||||
|
||||
LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
|
||||
{
|
||||
PreservedKey* key = LIST_ENTRY(cursor,PreservedKey,entry);
|
||||
if (IsEqualGUID(rguid,&key->guid) && prekey->uVKey == key->prekey.uVKey && prekey->uModifiers == key->prekey.uModifiers)
|
||||
return TF_E_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
newkey = HeapAlloc(GetProcessHeap(),0,sizeof(PreservedKey));
|
||||
if (!newkey)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
newkey->guid = *rguid;
|
||||
newkey->prekey = *prekey;
|
||||
newkey->tid = tid;
|
||||
if (cchDesc)
|
||||
{
|
||||
newkey->description = HeapAlloc(GetProcessHeap(),0,cchDesc * sizeof(WCHAR));
|
||||
if (!newkey->description)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,newkey);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(newkey->description, pchDesc, cchDesc*sizeof(WCHAR));
|
||||
}
|
||||
|
||||
list_add_head(&This->CurrentPreservedKeys,&newkey->entry);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI KeystrokeMgr_UnpreserveKey(ITfKeystrokeMgr *iface,
|
||||
REFGUID rguid, const TF_PRESERVEDKEY *pprekey)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfKeystrokeMgrVtbl(iface);
|
||||
FIXME("STUB:(%p)\n",This);
|
||||
return E_NOTIMPL;
|
||||
PreservedKey* key = NULL;
|
||||
struct list *cursor;
|
||||
TRACE("(%p) %s (%x %x)\n",This,debugstr_guid(rguid),(pprekey)?pprekey->uVKey:0, (pprekey)?pprekey->uModifiers:0);
|
||||
|
||||
if (!pprekey || !rguid)
|
||||
return E_INVALIDARG;
|
||||
|
||||
LIST_FOR_EACH(cursor, &This->CurrentPreservedKeys)
|
||||
{
|
||||
key = LIST_ENTRY(cursor,PreservedKey,entry);
|
||||
if (IsEqualGUID(rguid,&key->guid) && pprekey->uVKey == key->prekey.uVKey && pprekey->uModifiers == key->prekey.uModifiers)
|
||||
break;
|
||||
key = NULL;
|
||||
}
|
||||
|
||||
if (!key)
|
||||
return CONNECT_E_NOCONNECTION;
|
||||
|
||||
list_remove(&key->entry);
|
||||
HeapFree(GetProcessHeap(),0,key->description);
|
||||
HeapFree(GetProcessHeap(),0,key);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI KeystrokeMgr_SetPreservedKeyDescription(ITfKeystrokeMgr *iface,
|
||||
|
@ -575,6 +712,128 @@ static const ITfKeystrokeMgrVtbl ThreadMgr_KeystrokeMgrVtbl =
|
|||
KeystrokeMgr_SimulatePreservedKey
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
* ITfMessagePump functions
|
||||
*****************************************************/
|
||||
|
||||
static HRESULT WINAPI MessagePump_QueryInterface(ITfMessagePump *iface, REFIID iid, LPVOID *ppvOut)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
|
||||
return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
|
||||
}
|
||||
|
||||
static ULONG WINAPI MessagePump_AddRef(ITfMessagePump *iface)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
|
||||
return ThreadMgr_AddRef((ITfThreadMgr*)This);
|
||||
}
|
||||
|
||||
static ULONG WINAPI MessagePump_Release(ITfMessagePump *iface)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfMessagePumpVtbl(iface);
|
||||
return ThreadMgr_Release((ITfThreadMgr *)This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MessagePump_PeekMessageA(ITfMessagePump *iface,
|
||||
LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
|
||||
UINT wRemoveMsg, BOOL *pfResult)
|
||||
{
|
||||
if (!pfResult)
|
||||
return E_INVALIDARG;
|
||||
*pfResult = PeekMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MessagePump_GetMessageA(ITfMessagePump *iface,
|
||||
LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
|
||||
BOOL *pfResult)
|
||||
{
|
||||
if (!pfResult)
|
||||
return E_INVALIDARG;
|
||||
*pfResult = GetMessageA(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MessagePump_PeekMessageW(ITfMessagePump *iface,
|
||||
LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
|
||||
UINT wRemoveMsg, BOOL *pfResult)
|
||||
{
|
||||
if (!pfResult)
|
||||
return E_INVALIDARG;
|
||||
*pfResult = PeekMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI MessagePump_GetMessageW(ITfMessagePump *iface,
|
||||
LPMSG pMsg, HWND hwnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
|
||||
BOOL *pfResult)
|
||||
{
|
||||
if (!pfResult)
|
||||
return E_INVALIDARG;
|
||||
*pfResult = GetMessageW(pMsg, hwnd, wMsgFilterMin, wMsgFilterMax);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const ITfMessagePumpVtbl ThreadMgr_MessagePumpVtbl =
|
||||
{
|
||||
MessagePump_QueryInterface,
|
||||
MessagePump_AddRef,
|
||||
MessagePump_Release,
|
||||
|
||||
MessagePump_PeekMessageA,
|
||||
MessagePump_GetMessageA,
|
||||
MessagePump_PeekMessageW,
|
||||
MessagePump_GetMessageW
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
* ITfClientId functions
|
||||
*****************************************************/
|
||||
|
||||
static HRESULT WINAPI ClientId_QueryInterface(ITfClientId *iface, REFIID iid, LPVOID *ppvOut)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
|
||||
return ThreadMgr_QueryInterface((ITfThreadMgr *)This, iid, *ppvOut);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ClientId_AddRef(ITfClientId *iface)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
|
||||
return ThreadMgr_AddRef((ITfThreadMgr*)This);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ClientId_Release(ITfClientId *iface)
|
||||
{
|
||||
ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
|
||||
return ThreadMgr_Release((ITfThreadMgr *)This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ClientId_GetClientId(ITfClientId *iface,
|
||||
REFCLSID rclsid, TfClientId *ptid)
|
||||
|
||||
{
|
||||
HRESULT hr;
|
||||
ITfCategoryMgr *catmgr;
|
||||
ThreadMgr *This = impl_from_ITfClientIdVtbl(iface);
|
||||
|
||||
TRACE("(%p) %s\n",This,debugstr_guid(rclsid));
|
||||
|
||||
CategoryMgr_Constructor(NULL,(IUnknown**)&catmgr);
|
||||
hr = ITfCategoryMgr_RegisterGUID(catmgr,rclsid,ptid);
|
||||
ITfCategoryMgr_Release(catmgr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const ITfClientIdVtbl ThreadMgr_ClientIdVtbl =
|
||||
{
|
||||
ClientId_QueryInterface,
|
||||
ClientId_AddRef,
|
||||
ClientId_Release,
|
||||
|
||||
ClientId_GetClientId
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
* ITfThreadMgrEventSink functions (internal)
|
||||
*****************************************************/
|
||||
|
@ -718,10 +977,14 @@ HRESULT ThreadMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
|
|||
This->ThreadMgrVtbl= &ThreadMgr_ThreadMgrVtbl;
|
||||
This->SourceVtbl = &ThreadMgr_SourceVtbl;
|
||||
This->KeystrokeMgrVtbl= &ThreadMgr_KeystrokeMgrVtbl;
|
||||
This->MessagePumpVtbl= &ThreadMgr_MessagePumpVtbl;
|
||||
This->ClientIdVtbl = &ThreadMgr_ClientIdVtbl;
|
||||
This->ThreadMgrEventSinkVtbl = &ThreadMgr_ThreadMgrEventSinkVtbl;
|
||||
This->refCount = 1;
|
||||
TlsSetValue(tlsIndex,This);
|
||||
|
||||
list_init(&This->CurrentPreservedKeys);
|
||||
|
||||
list_init(&This->ActiveLanguageProfileNotifySink);
|
||||
list_init(&This->DisplayAttributeNotifySink);
|
||||
list_init(&This->KeyTraceEventSink);
|
||||
|
|
Loading…
Reference in a new issue