Author: dchapyshev Date: Sat May 9 13:24:59 2009 New Revision: 40850
URL: http://svn.reactos.org/svn/reactos?rev=40850&view=rev Log: - Sync msctf, mscoree, mciqtz32, localspl, inetmib1 with Wine 1.1.21
Modified: trunk/reactos/dll/win32/inetmib1/main.c trunk/reactos/dll/win32/localspl/localspl_private.h trunk/reactos/dll/win32/localspl/provider.c trunk/reactos/dll/win32/mciqtz32/mciqtz.c trunk/reactos/dll/win32/mciqtz32/mciqtz_private.h trunk/reactos/dll/win32/mscoree/mscoree.spec trunk/reactos/dll/win32/mscoree/mscoree_main.c trunk/reactos/dll/win32/msctf/categorymgr.c trunk/reactos/dll/win32/msctf/inputprocessor.c trunk/reactos/dll/win32/msctf/msctf.c trunk/reactos/dll/win32/msctf/msctf_internal.h trunk/reactos/dll/win32/msctf/threadmgr.c
Modified: trunk/reactos/dll/win32/inetmib1/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/inetmib1/main.c?r... ============================================================================== --- trunk/reactos/dll/win32/inetmib1/main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/inetmib1/main.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -125,6 +125,7 @@ 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 @@ 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 @@ return ret; }
-static void setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, +static INT setOidWithItem(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, UINT item) { UINT id; AsnObjectIdentifier oid; - - SnmpUtilOidCpy(dst, base); - oid.idLength = 1; - oid.ids = &id; - id = item; - SnmpUtilOidAppend(dst, &oid); -} - -static void setOidWithItemAndIpAddr(AsnObjectIdentifier *dst, + INT ret; + + ret = SnmpUtilOidCpy(dst, base); + if (ret) + { + oid.idLength = 1; + oid.ids = &id; + id = item; + ret = SnmpUtilOidAppend(dst, &oid); + } + return ret; +} + +static INT setOidWithItemAndIpAddr(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, UINT item, DWORD addr) { UINT id; BYTE *ptr; AsnObjectIdentifier oid; - - setOidWithItem(dst, base, item); - oid.idLength = 1; - oid.ids = &id; - for (ptr = (BYTE *)&addr; ptr < (BYTE *)&addr + sizeof(DWORD); ptr++) - { - id = *ptr; - SnmpUtilOidAppend(dst, &oid); - } -} - -static void setOidWithItemAndInteger(AsnObjectIdentifier *dst, + INT ret; + + ret = setOidWithItem(dst, base, item); + if (ret) + { + 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 INT setOidWithItemAndInteger(AsnObjectIdentifier *dst, AsnObjectIdentifier *base, UINT item, UINT instance) { AsnObjectIdentifier oid; - - setOidWithItem(dst, base, item); - oid.idLength = 1; - oid.ids = &instance; - SnmpUtilOidAppend(dst, &oid); + INT ret; + + 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 @@ 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 @@ &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 @@ { 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 @@ *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 @@ { 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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ 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 @@ { 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 @@ *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 @@ { 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 @@ *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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } *pErrorStatus = error; *pErrorIndex = errorIndex; - return TRUE; + return ret; }
/*****************************************************************************
Modified: trunk/reactos/dll/win32/localspl/localspl_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/localspl/localspl... ============================================================================== --- trunk/reactos/dll/win32/localspl/localspl_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/localspl/localspl_private.h [iso-8859-1] Sat May 9 13:24:59 2009 @@ -62,6 +62,11 @@ 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 );
Modified: trunk/reactos/dll/win32/localspl/provider.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/localspl/provider... ============================================================================== --- trunk/reactos/dll/win32/localspl/provider.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/localspl/provider.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -80,6 +80,13 @@ 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 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 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 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 version0_regpathW[] = {'\','V','e','r','s','i','o','n','-','0',0}; -static const WCHAR version0_subdirW[] = {'\','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, @@ -271,6 +289,32 @@ } } 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; }
/****************************************************************** @@ -513,6 +557,65 @@ }
/****************************************************************** + * 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 * (specifically the extra \0, that is needed as multi_sz terminator). @@ -907,6 +1010,139 @@ 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 @@
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 @@ 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 @@ NULL, /* fpGetPrinterData */ NULL, /* fpSetPrinterData */ NULL, /* fpWaitForPrinterChange */ - NULL, /* fpClosePrinter */ + fpClosePrinter, NULL, /* fpAddForm */ NULL, /* fpDeleteForm */ NULL, /* fpGetForm */ @@ -1507,7 +1873,7 @@ NULL, /* fpAddPerMachineConnection */ NULL, /* fpDeletePerMachineConnection */ NULL, /* fpEnumPerMachineConnections */ - NULL, /* fpXcvData */ + fpXcvData, fpAddPrinterDriverEx, NULL, /* fpSplReadPrinter */ NULL, /* fpDriverUnloadComplete */
Modified: trunk/reactos/dll/win32/mciqtz32/mciqtz.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mciqtz32/mciqtz.c... ============================================================================== --- trunk/reactos/dll/win32/mciqtz32/mciqtz.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/mciqtz32/mciqtz.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -338,6 +338,110 @@ }
/*************************************************************************** + * 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] */ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpParms) @@ -411,6 +515,90 @@
if (dwFlags & MCI_NOTIFY) mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), wDevID, MCI_NOTIFY_SUCCESSFUL); + + 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; } @@ -451,12 +639,13 @@ 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 @@ case MCI_REALIZE: case MCI_UNFREEZE: case MCI_UPDATE: - case MCI_WHERE: case MCI_STEP: case MCI_COPY: case MCI_CUT:
Modified: trunk/reactos/dll/win32/mciqtz32/mciqtz_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mciqtz32/mciqtz_p... ============================================================================== --- trunk/reactos/dll/win32/mciqtz32/mciqtz_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/mciqtz32/mciqtz_private.h [iso-8859-1] Sat May 9 13:24:59 2009 @@ -31,6 +31,7 @@ IGraphBuilder* pgraph; IMediaControl* pmctrl; BOOL started; + DWORD time_format; } WINE_MCIQTZ;
#endif /* __WINE_PRIVATE_MCIQTZ_H */
Modified: trunk/reactos/dll/win32/mscoree/mscoree.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/mscoree.s... ============================================================================== --- trunk/reactos/dll/win32/mscoree/mscoree.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/mscoree/mscoree.spec [iso-8859-1] Sat May 9 13:24:59 2009 @@ -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
Modified: trunk/reactos/dll/win32/mscoree/mscoree_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mscoree/mscoree_m... ============================================================================== --- trunk/reactos/dll/win32/mscoree/mscoree_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/mscoree/mscoree_main.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -324,6 +324,18 @@ 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);
Modified: trunk/reactos/dll/win32/msctf/categorymgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/categorymgr... ============================================================================== --- trunk/reactos/dll/win32/msctf/categorymgr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msctf/categorymgr.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -144,9 +144,37 @@ static HRESULT WINAPI CategoryMgr_UnregisterCategory ( ITfCategoryMgr *iface, REFCLSID rclsid, REFGUID rcatid, REFGUID rguid) { - CategoryMgr *This = (CategoryMgr*)iface; - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + WCHAR fullkey[110]; + WCHAR buf[39]; + WCHAR buf2[39]; + HKEY tipkey; + CategoryMgr *This = (CategoryMgr*)iface; + + 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 @@ REFGUID rguid, TfGuidAtom *pguidatom ) { - CategoryMgr *This = (CategoryMgr*)iface; - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + DWORD index; + GUID *checkguid; + DWORD id; + CategoryMgr *This = (CategoryMgr*)iface; + + 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; }
Modified: trunk/reactos/dll/win32/msctf/inputprocessor.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/inputproces... ============================================================================== --- trunk/reactos/dll/win32/msctf/inputprocessor.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msctf/inputprocessor.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -288,18 +288,61 @@ ITfInputProcessorProfiles *iface, REFCLSID rclsid, LANGID langid, REFGUID guidProfiles) { - InputProcessorProfiles *This = (InputProcessorProfiles*)iface; - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + HRESULT hr; + BOOL enabled; + TF_LANGUAGEPROFILE LanguageProfile; + InputProcessorProfiles *This = (InputProcessorProfiles*)iface; + + 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) { - InputProcessorProfiles *This = (InputProcessorProfiles*)iface; - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + TF_LANGUAGEPROFILE profile; + InputProcessorProfiles *This = (InputProcessorProfiles*)iface; + + 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 @@
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)
Modified: trunk/reactos/dll/win32/msctf/msctf.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/msctf.c?rev... ============================================================================== --- trunk/reactos/dll/win32/msctf/msctf.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msctf/msctf.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -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 @@ 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 @@ 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 */
Modified: trunk/reactos/dll/win32/msctf/msctf_internal.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/msctf_inter... ============================================================================== --- trunk/reactos/dll/win32/msctf/msctf_internal.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msctf/msctf_internal.h [iso-8859-1] Sat May 9 13:24:59 2009 @@ -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 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 */
Modified: trunk/reactos/dll/win32/msctf/threadmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/threadmgr.c... ============================================================================== --- trunk/reactos/dll/win32/msctf/threadmgr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msctf/threadmgr.c [iso-8859-1] Sat May 9 13:24:59 2009 @@ -56,15 +56,29 @@ } 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 @@ 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 @@ 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); }
@@ -162,6 +194,14 @@ else if (IsEqualIID(iid, &IID_ITfKeystrokeMgr)) { *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 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); - - if (This->focus) - { - ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus); - ITfDocumentMgr_Release(This->focus); - This->focus = 0; - } - - return E_NOTIMPL; + TRACE("(%p)\n",This); + + if (This->activationCount == 0) + return E_UNEXPECTED; + + This->activationCount --; + + if (This->activationCount == 0) + { + if (This->focus) + { + ITfThreadMgrEventSink_OnSetFocus((ITfThreadMgrEventSink*)&This->ThreadMgrEventSinkVtbl, 0, This->focus); + ITfDocumentMgr_Release(This->focus); + This->focus = 0; + } + } + + deactivate_textservices(); + + return S_OK; }
static HRESULT WINAPI ThreadMgr_CreateDocumentMgr( ITfThreadMgr* iface, ITfDocumentMgr @@ -508,8 +573,25 @@ 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 @@ 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, @@ -576,6 +713,128 @@ };
/***************************************************** + * 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) *****************************************************/ static HRESULT WINAPI ThreadMgrEventSink_QueryInterface(ITfThreadMgrEventSink *iface, REFIID iid, LPVOID *ppvOut) @@ -718,9 +977,13 @@ 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);