- Sync msctf, mscoree, mciqtz32, localspl, inetmib1 with Wine 1.1.21

svn path=/trunk/; revision=40850
This commit is contained in:
Dmitry Chapyshev 2009-05-09 09:24:59 +00:00
parent cc308abba4
commit 8a68f45533
12 changed files with 1300 additions and 89 deletions

View file

@ -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;
}
/*****************************************************************************

View file

@ -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 );

View file

@ -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, &registered, 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 */

View file

@ -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:

View file

@ -31,6 +31,7 @@ typedef struct {
IGraphBuilder* pgraph;
IMediaControl* pmctrl;
BOOL started;
DWORD time_format;
} WINE_MCIQTZ;
#endif /* __WINE_PRIVATE_MCIQTZ_H */

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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)

View file

@ -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
*/

View file

@ -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 */

View file

@ -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);