- Timestamp:
- Jun 18, 2009, 6:27:45 PM (16 years ago)
- Location:
- trunk/src
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comdlg32/initcomdlg32.cpp
r9990 r21308 54 54 switch (fdwReason) 55 55 { 56 case DLL_PROCESS_ATTACH: 57 { 58 /* 59 * Find default printer and write name to win.ini 60 * Format: queuename,driver,portname 61 */ 62 char szWinDefPrn[256]; 63 szWinDefPrn[0] = '\0'; 64 65 /* 66 * OS/2 stores the default printer as a combination of printerdevice and queue. 67 * 68 * Printer Device is related to one port. It may have multiple printer 69 * drivers because the port may serve multiple queues with different drivers. 70 * The Ports are related to multiple queues. 71 * 72 * So we take the default default printer+queue combination and finds the 73 */ 74 char szDefPrnDev[20]; 75 char szDefPrnQue[20]; 76 if (PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER", "PRINTER", "", 77 szDefPrnDev, sizeof(szDefPrnDev)) > 1 78 && PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER", "QUEUE", "", 79 szDefPrnQue, sizeof(szDefPrnQue)) > 1 80 && szDefPrnDev[0] 81 && szDefPrnQue[0] 82 ) 83 { 84 char *psz; 85 /* remove everything beyond the first ';' */ 86 if ((psz = strchr(szDefPrnDev, ';')) != NULL) 87 *psz = '\0'; 88 if ((psz = strchr(szDefPrnQue, ';')) != NULL) 89 *psz = '\0'; 90 91 /* 92 * Now we must lookup the port name from the device settings. 93 * This is a string of this form: 94 * <port>;<driver1>[,<driver2>;<queue1>[,<queue2>];?;?; 95 */ 96 ULONG cb = 0; 97 if (PrfQueryProfileSize(HINI_SYSTEMPROFILE, "PM_SPOOLER_PRINTER", szDefPrnDev, &cb) 98 && cb > 0) 99 { 100 char *pszBufD = (char*)malloc(cb + 1); 101 if (pszBufD 102 && PrfQueryProfileString(HINI_SYSTEMPROFILE, "PM_SPOOLER_PRINTER", szDefPrnDev, 103 NULL, pszBufD, cb + 1) 104 > 1 105 ) 106 { 107 /* 108 * Now get the Default printer driver for the queue. 109 * This is stored as a ';' separated list of drivers, the first one is the default. 110 */ 111 if (PrfQueryProfileSize(HINI_SYSTEMPROFILE, "PM_SPOOLER_QUEUE_DD", szDefPrnQue, &cb) 112 && cb > 0) 113 { 114 char *pszBufQ = (char*)malloc(cb + 1); 115 if (pszBufQ 116 && PrfQueryProfileString(HINI_SYSTEMPROFILE, "PM_SPOOLER_QUEUE_DD", szDefPrnQue, 117 NULL, pszBufQ, cb + 1) 118 > 1 119 ) 120 { 121 /* 122 * We got everything now. just find the parts we need. 123 * First printer driver from QUEUE_DD 124 * Port name of the device. 125 */ 126 if ((psz = strchr(pszBufQ, ';')) != NULL) 127 *psz = '\0'; 128 if ((psz = strchr(pszBufQ, ',')) != NULL) //paranoia! in case comman separated list of some kind. 129 *psz = '\0'; 130 if ((psz = strchr(pszBufD, ';')) != NULL) 131 *psz = '\0'; 132 if ((psz = strchr(pszBufD, ',')) != NULL) //paranoia in case comman separated list of some kind. 133 *psz = '\0'; 134 135 /* 136 * Now make default printer string for the win.ini. 137 */ 138 strcpy(szWinDefPrn, szDefPrnQue); 139 strcat(strcat(szWinDefPrn, ","), pszBufQ); 140 strcat(strcat(szWinDefPrn, ","), pszBufD); 141 dprintf(("LibMainComdlg32: Successfully found default printer.'%s'", szWinDefPrn)); 142 free(pszBufQ); 143 } 144 } 145 else 146 { 147 /* OS/2 the device may exist though the default queue is destroyed. 148 * it may still exist even if there are no queues on the system at all! 149 */ 150 dprintf(("LibMainComdlg32: no queue driver entry for '%s'.", szDefPrnQue)); 151 } 152 153 free(pszBufD); 154 } 155 } 156 else 157 { 158 /* OS/2 doesn't remove the default settings if the default queue/printer is deleted. */ 159 dprintf(("LibMainComdlg32: can't find device settings for '%s'.", szDefPrnDev)); 160 } 161 } 162 else 163 { 164 dprintf(("LibMainComdlg32: no default printer? szDefPrnDev='%s' szDefPrnQue='%s'.", szDefPrnDev, szDefPrnQue)); 165 } 166 167 //Now get real printer name the one that will be used in DC calls 168 WriteProfileStringA("windows", "device", szWinDefPrn); 169 170 return COMDLG32_DllEntryPoint(hinstDLL, fdwReason, fImpLoad); 171 } 56 case DLL_PROCESS_ATTACH: 57 return COMDLG32_DllEntryPoint(hinstDLL, fdwReason, fImpLoad); 172 58 173 59 case DLL_THREAD_ATTACH: -
trunk/src/kernel32/initkernel32.cpp
r21302 r21308 60 60 #include <stats.h> 61 61 #include <heapshared.h> 62 #include <heapstring.h> 62 63 #include <_ras.h> 63 64 … … 71 72 extern DWORD kernel32_PEResTab; 72 73 } 74 75 extern PFN pfnImSetMsgQueueProperty; 73 76 74 77 ULONG flAllocMem = 0; /* flag to optimize DosAllocMem to use all the memory on SMP machines */ … … 79 82 BOOL fInit = FALSE; 80 83 BOOL fWin32k = FALSE; 84 HMODULE imHandle = 0; 85 char szModName[ 256 ] = ""; 81 86 82 87 /****************************************************************************/ … … 224 229 CODEPAGE_Init(); 225 230 231 if( IsDBCSEnv() && DosLoadModule( szModName, sizeof( szModName ), "OS2IM.DLL", &imHandle ) == 0 ) 232 DosQueryProcAddr( imHandle, 140, NULL, &pfnImSetMsgQueueProperty ); 233 226 234 InitSystemInfo(ulSysinfo); 227 235 //Set up environment as found in NT … … 272 280 dprintf(("kernel32 exit %d\n", ulReason)); 273 281 282 if( IsDBCSEnv() && imHandle ) 283 DosFreeModule( imHandle ); 284 274 285 //Flush and delete all open memory mapped files 275 286 Win32MemMap::deleteAll(); -
trunk/src/kernel32/oslibmisc.cpp
r21302 r21308 28 28 #include "dbglocal.h" 29 29 30 typedef APIRET ( APIENTRY *PFN_IMSETMSGQUEUEPROPERTY )( HMQ, ULONG ); 31 32 PFN_IMSETMSGQUEUEPROPERTY pfnImSetMsgQueueProperty = NULL; 33 30 34 //****************************************************************************** 31 35 //TODO: not reentrant! … … 351 355 //****************************************************************************** 352 356 //****************************************************************************** 353 357 ULONG OSLibImSetMsgQueueProperty( ULONG hmq, ULONG ulFlag ) 358 { 359 USHORT sel; 360 APIRET rc; 361 362 if( !pfnImSetMsgQueueProperty ) 363 return 1; 364 365 sel = RestoreOS2FS(); 366 rc = pfnImSetMsgQueueProperty( hmq, ulFlag ); 367 SetFS( sel ); 368 369 return rc; 370 } 371 //****************************************************************************** 372 //****************************************************************************** 373 -
trunk/src/kernel32/oslibmisc.h
r21302 r21308 103 103 void OSLibQueryBeginLibpath(char *lpszBeginlibpath, int size); 104 104 105 ULONG OSLibImSetMsgQueueProperty( ULONG hmq, ULONG ulFlag ); 106 105 107 #ifdef __cplusplus 106 108 } -
trunk/src/kernel32/thread.cpp
r21302 r21308 34 34 #include <handlemanager.h> 35 35 #include <codepage.h> 36 #include <heapstring.h> 36 37 37 38 #include "hmhandle.h" … … 48 49 49 50 static ULONG priorityclass = NORMAL_PRIORITY_CLASS; 51 52 #define MQP_INSTANCE_PERMQ 0x00000001 // from os2im.h 50 53 51 54 //****************************************************************************** … … 689 692 dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq)); 690 693 dprintf(("Stack top 0x%x, stack end 0x%x", winteb->stack_top, winteb->stack_low)); 694 695 if( IsDBCSEnv()) 696 /* IM instace is created per message queue, that is, thread */ 697 OSLibImSetMsgQueueProperty( winteb->o.odin.hmq, MQP_INSTANCE_PERMQ ); 691 698 692 699 //Note: The Win32 exception structure referenced by FS:[0] is the same -
trunk/src/kernel32/windllbase.cpp
r21302 r21308 708 708 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "CRTDLL32", "CRTDLL"); 709 709 } 710 if(PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "IMM32", "", renameddll, 711 sizeof(renameddll)-1) <= 1) 712 { 713 PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "IMM32", "IMM32OS2"); 714 PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "IMM32OS2", "IMM32"); 715 } 710 716 } 711 717 //****************************************************************************** -
trunk/src/oleaut32/stubs.cpp
r10634 r21308 173 173 //***************************************************************************** 174 174 //***************************************************************************** 175 HRESULT WIN32API VarDecFromStr(OLECHAR *strIn, LCID lcid, ULONG dwFlags, DECIMAL *pdecOut) 176 { 177 dprintf(("OLEAUT32: VarDecFromStr - stub")); 178 return S_OK; 179 } 180 181 //***************************************************************************** 182 //***************************************************************************** 175 183 HRESULT WIN32API VarDecFromDisp(IDispatch *pdispIn, LCID lcid, DECIMAL *pdecOut) 176 184 { … … 256 264 { 257 265 dprintf(("OLEAUT32: VarCyFromDec - stub")); 266 return S_OK; 267 } 268 269 //***************************************************************************** 270 //***************************************************************************** 271 HRESULT WIN32API VarBstrFromDec(DECIMAL *pdecIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) 272 { 273 dprintf(("OLEAUT32: VarBstrFromDec - stub")); 258 274 return S_OK; 259 275 } -
trunk/src/oleaut32/variant.c
r10629 r21308 201 201 {0x00 , 0, 0 , VT_NULL} 202 202 }; 203 204 205 /************** Form wine: oleaut32/variant.h **************/206 207 /* Value of sign for a positive decimal number */208 #define DECIMAL_POS 0209 210 /* Native headers don't change the union ordering for DECIMAL sign/scale (duh).211 * This means that the signscale member is only useful for setting both members to 0.212 * SIGNSCALE creates endian-correct values so that we can properly set both at once213 * to values other than 0.214 */215 #ifdef WORDS_BIGENDIAN216 #define SIGNSCALE(sign,scale) (((scale) << 8) | sign)217 #else218 #define SIGNSCALE(sign,scale) (((sign) << 8) | scale)219 #endif220 /* Macros for getting at a DECIMAL's parts */221 #define DEC_SIGN(d) ((d)->u.s.sign)222 #define DEC_SCALE(d) ((d)->u.s.scale)223 #define DEC_SIGNSCALE(d) ((d)->u.signscale)224 #define DEC_HI32(d) ((d)->Hi32)225 #define DEC_MID32(d) ((d)->u1.s1.Mid32)226 #define DEC_LO32(d) ((d)->u1.s1.Lo32)227 #define DEC_LO64(d) ((d)->u1.Lo64)228 229 /* DECIMAL */230 #define _VarDecFromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_DECIMAL)231 /* R8 (double) */232 #define _VarR8FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_R8)233 234 /* Internal flags for low level conversion functions */235 #define VAR_BOOLONOFF 0x0400 /* Convert bool to "On"/"Off" */236 #define VAR_BOOLYESNO 0x0800 /* Convert bool to "Yes"/"No" */237 #define VAR_NEGATIVE 0x1000 /* Number is negative */238 239 /* The localised characters that make up a valid number */240 typedef struct tagVARIANT_NUMBER_CHARS241 {242 WCHAR cNegativeSymbol;243 WCHAR cPositiveSymbol;244 WCHAR cDecimalPoint;245 WCHAR cDigitSeperator;246 WCHAR cCurrencyLocal;247 WCHAR cCurrencyLocal2;248 WCHAR cCurrencyDecimalPoint;249 WCHAR cCurrencyDigitSeperator;250 } VARIANT_NUMBER_CHARS;251 252 void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS*,LCID,DWORD);253 /********** End of Form wine: oleaut32/variant.h ************/254 255 /* Write a number from a UI8 and sign */256 #ifdef __WIN32OS2__257 static WCHAR *VARIANT_WriteNumber(ULONG ulVal, WCHAR* szOut)258 {259 //FIXME("%s: Hack! No real ULONG64 support here, using ULONG instead. ulVal=%x!!\n", __FUNCTION__, ulVal);260 #else261 static WCHAR *VARIANT_WriteNumber(ULONG64 ulVal, WCHAR* szOut)262 {263 #endif264 265 do266 {267 WCHAR ulNextDigit = ulVal % 10;268 269 *szOut-- = '0' + ulNextDigit;270 ulVal = (ulVal - ulNextDigit) / 10;271 } while (ulVal);272 273 szOut++;274 return szOut;275 }276 277 /* Create a (possibly localised) BSTR from a UI8 and sign */278 static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut)279 {280 WCHAR szConverted[256];281 282 if (dwFlags & VAR_NEGATIVE)283 *--szOut = '-';284 285 if (dwFlags & LOCALE_USE_NLS)286 {287 /* Format the number for the locale */288 szConverted[0] = '\0';289 GetNumberFormatW(lcid,290 dwFlags & LOCALE_NOUSEROVERRIDE,291 szOut, NULL, szConverted, sizeof(szConverted)/sizeof(WCHAR));292 szOut = szConverted;293 }294 return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR));295 }296 297 298 /******************************************************************************299 * VarBstrFromDec (OLEAUT32.232)300 *301 * Convert a VT_DECIMAL to a VT_BSTR.302 *303 * PARAMS304 * pDecIn [I] Source305 * lcid [I] LCID for the conversion306 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")307 * pbstrOut [O] Destination308 *309 * RETURNS310 * Success: S_OK.311 * Failure: E_INVALIDARG, if pbstrOut is invalid.312 * E_OUTOFMEMORY, if memory allocation fails.313 */314 HRESULT WINAPI VarBstrFromDec(DECIMAL* pDecIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)315 {316 TRACE("%s: entering function. pDecIn->lo32: %x, pDecIn->Mid32: %x, pDecIn->Hi32: %x, sign: %x, dwFlags: %x\n",317 __FUNCTION__, DEC_LO32(pDecIn), DEC_MID32(pDecIn), DEC_HI32(pDecIn), DEC_SIGN(pDecIn), dwFlags);318 if (!pbstrOut)319 return E_INVALIDARG;320 321 if (!DEC_SCALE(pDecIn) && !DEC_HI32(pDecIn))322 {323 WCHAR szBuff[256], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1;324 325 /* Create the basic number string */326 *szOut-- = '\0';327 328 329 #ifdef __WIN32OS2__330 szOut = VARIANT_WriteNumber(DEC_LO32(pDecIn), szOut);331 #else332 szOut = VARIANT_WriteNumber(DEC_LO64(pDecIn), szOut);333 #endif334 if (DEC_SIGN(pDecIn))335 dwFlags |= VAR_NEGATIVE;336 337 *pbstrOut = VARIANT_MakeBstr(lcid, dwFlags, szOut);338 TRACE("%s: returning %s\n", __FUNCTION__, debugstr_w(*pbstrOut));339 return *pbstrOut ? S_OK : E_OUTOFMEMORY;340 }341 FIXME("semi-stub\n");342 return E_INVALIDARG;343 }344 345 346 /* Copy data from one variant to another. */347 static inline void VARIANT_CopyData(const VARIANT *srcVar, VARTYPE vt, void *pOut)348 {349 // TRACE("%s: entering function.\n", __FUNCTION__);350 switch (vt)351 {352 case VT_I1:353 case VT_UI1: memcpy(pOut, &V_UI1(srcVar), sizeof(BYTE)); break;354 case VT_BOOL:355 case VT_I2:356 case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT)); break;357 case VT_R4:358 case VT_INT:359 case VT_I4:360 case VT_UINT:361 case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG)); break;362 case VT_R8:363 case VT_DATE:364 case VT_CY:365 case VT_I8:366 #ifdef __WIN32OS2__367 /* case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONGLONG)); break; */368 /* case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break; */369 case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break;370 #else371 case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONGLONG)); break;372 case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break;373 case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break;374 #endif375 default:376 FIXME("%s: VT_ type %d unhandled, please report!\n", __FUNCTION__, vt);377 }378 }379 380 /* Form wine: oleaut32/vartype.c */381 /* Coerce VT_BSTR to a numeric type */382 HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags,383 void* pOut, VARTYPE vt)384 {385 VARIANTARG dstVar;386 HRESULT hRet;387 NUMPARSE np;388 BYTE rgb[1024];389 390 TRACE("%s: (StrIn: %s, LCID: 0x%08lx, ulFlags: 0x%08lx )\n", __FUNCTION__, pStrIn, lcid, ulFlags );391 392 /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */393 np.cDig = sizeof(rgb) / sizeof(BYTE);394 np.dwInFlags = NUMPRS_STD;395 396 hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);397 398 if (SUCCEEDED(hRet))399 {400 /* 1 << vt gives us the VTBIT constant for the destination number type */401 hRet = VarNumFromParseNum(&np, rgb, 1 << vt, &dstVar);402 if (SUCCEEDED(hRet)) {403 VARIANT_CopyData(&dstVar, vt, pOut);404 TRACE("%s: Returning dstVar-> type : %x", __FUNCTION__, V_VT(&dstVar));405 }406 }407 return hRet;408 }409 410 203 411 204 /****************************************************************************** … … 2039 1832 void WINAPI VariantInit(VARIANTARG* pvarg) 2040 1833 { 2041 TRACE(" %s: (%p)\n", __FUNCTION__,pvarg);1834 TRACE("(%p)\n",pvarg); 2042 1835 2043 1836 memset(pvarg, 0, sizeof (VARIANTARG)); … … 2058 1851 { 2059 1852 HRESULT res = S_OK; 2060 TRACE(" %s: (%p)\n",__FUNCTION__,pvarg);1853 TRACE("(%p)\n",pvarg); 2061 1854 2062 1855 res = ValidateVariantType( V_VT(pvarg) ); … … 2118 1911 HRESULT res = S_OK; 2119 1912 2120 TRACE(" %s: (Dest: %p, Src: %p), vt=%d\n", __FUNCTION__, pvargDest, pvargSrc, V_VT(pvargSrc));1913 TRACE("(%p, %p), vt=%d\n", pvargDest, pvargSrc, V_VT(pvargSrc)); 2121 1914 2122 1915 res = ValidateVariantType( V_VT(pvargSrc) ); … … 2339 2132 VARIANTARG varg; 2340 2133 VariantInit( &varg ); 2341 TRACE("%s: (Dest: %p, source: %p, LCID: %ld, wFlags: %u, VARTYPE: %u) vt=%d\n", __FUNCTION__, pvargDest, pvargSrc, lcid, wFlags, vt, V_VT(pvargSrc)); 2134 2135 TRACE("(%p, %p, %ld, %u, %u) vt=%d\n", pvargDest, pvargSrc, lcid, wFlags, vt, V_VT(pvargSrc)); 2342 2136 TRACE("Src Var:\n"); 2343 2137 dump_Variant(pvargSrc); … … 2376 2170 */ 2377 2171 VARIANTARG Variant; 2378 2379 2172 VariantInit( &Variant ); 2380 2173 res = VariantCopyInd( &Variant, pvargSrc ); … … 2386 2179 VariantClear( &Variant ); 2387 2180 } 2181 2388 2182 } 2389 2183 else … … 2403 2197 V_VT(pvargDest) = vt; 2404 2198 2405 TRACE("Dest Var (re: %x)\n", res);2199 TRACE("Dest Var:\n"); 2406 2200 dump_Variant(pvargDest); 2407 2201 … … 2981 2775 LPSTR pNewString = NULL; 2982 2776 2983 TRACE(" %s: ( strIn: %p -> %s, lcid: 0x%08lx, dwFlags: 0x%08lx, plOut: %p ), stub\n", __FUNCTION__, strIn, debugstr_w(strIn), lcid, dwFlags, plOut );2777 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, plOut ); 2984 2778 2985 2779 /* Check if we have a valid argument … … 3305 3099 } 3306 3100 3307 #if 03308 3101 /****************************************************************************** 3309 3102 * VarR8FromStr [OLEAUT32.84] … … 3336 3129 3337 3130 return S_OK; 3338 }3339 #endif3340 3341 /************************************************************************3342 * VarR8FromStr (OLEAUT32.84)3343 *3344 * Convert a VT_BSTR to a VT_R8.3345 *3346 * PARAMS3347 * strIn [I] Source3348 * lcid [I] LCID for the conversion3349 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")3350 * pDblOut [O] Destination3351 *3352 * RETURNS3353 * Success: S_OK.3354 * Failure: E_INVALIDARG, if strIn or pDblOut is invalid.3355 * DISP_E_TYPEMISMATCH, if the type cannot be converted3356 */3357 HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double *pDblOut)3358 {3359 return _VarR8FromStr(strIn, lcid, dwFlags, pDblOut);3360 3131 } 3361 3132 … … 3562 3333 return S_OK; 3563 3334 } 3564 3565 3566 3335 3567 3336 /****************************************************************************** … … 4716 4485 4717 4486 4718 #define GET_NUMBER_TEXT(fld,name) \4719 buff[0] = 0; \4720 if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \4721 WARN("%s: buffer too small for " #fld "\n", __FUNCTION__); \4722 else \4723 if (buff[0]) lpChars->name = buff[0]; /* \4724 TRACE("lcid 0x%lx, " #name "=%d '%c'\n", lcid, lpChars->name, lpChars->name)*/4725 4726 /* Get the valid number characters for an lcid */4727 void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)4728 {4729 static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',',','$',0,'.',',' };4730 LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE;4731 WCHAR buff[4];4732 4733 memcpy(lpChars, &defaultChars, sizeof(defaultChars));4734 GET_NUMBER_TEXT(LOCALE_SNEGATIVESIGN, cNegativeSymbol);4735 GET_NUMBER_TEXT(LOCALE_SPOSITIVESIGN, cPositiveSymbol);4736 GET_NUMBER_TEXT(LOCALE_SDECIMAL, cDecimalPoint);4737 GET_NUMBER_TEXT(LOCALE_STHOUSAND, cDigitSeperator);4738 GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint);4739 GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeperator);4740 4741 /* Local currency symbols are often 2 characters */4742 lpChars->cCurrencyLocal2 = '\0';4743 switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR)))4744 {4745 case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */4746 case 2: lpChars->cCurrencyLocal = buff[0];4747 break;4748 default: WARN("buffer too small for LOCALE_SCURRENCY\n");4749 }4750 TRACE("lcid 0x%lx, cCurrencyLocal =%d,%d '%c','%c'\n", lcid, lpChars->cCurrencyLocal,4751 lpChars->cCurrencyLocal2, lpChars->cCurrencyLocal, lpChars->cCurrencyLocal2);4752 }4753 4754 /* Number Parsing States */4755 #define B_PROCESSING_EXPONENT 0x14756 #define B_NEGATIVE_EXPONENT 0x24757 #define B_EXPONENT_START 0x44758 #define B_INEXACT_ZEROS 0x84759 #define B_LEADING_ZERO 0x104760 #define B_PROCESSING_HEX 0x204761 #define B_PROCESSING_OCT 0x404762 /**********************************************************************4763 * VarParseNumFromStr [OLEAUT32.46]4764 *4765 * Parse a string containing a number into a NUMPARSE structure.4766 *4767 * PARAMS4768 * lpszStr [I] String to parse number from4769 * lcid [I] Locale Id for the conversion4770 * dwFlags [I] 0, or LOCALE_NOUSEROVERRIDE to use system default number chars4771 * pNumprs [I/O] Destination for parsed number4772 * rgbDig [O] Destination for digits read in4773 *4774 * RETURNS4775 * Success: S_OK. pNumprs and rgbDig contain the parsed representation of4776 * the number.4777 * Failure: E_INVALIDARG, if any parameter is invalid.4778 * DISP_E_TYPEMISMATCH, if the string is not a number or is formatted4779 * incorrectly.4780 * DISP_E_OVERFLOW, if rgbDig is too small to hold the number.4781 *4782 * NOTES4783 * pNumprs must have the following fields set:4784 * cDig: Set to the size of rgbDig.4785 * dwInFlags: Set to the allowable syntax of the number using NUMPRS_ flags4786 * from "oleauto.h".4787 *4788 * FIXME4789 * - I am unsure if this function should parse non-arabic (e.g. Thai)4790 * numerals, so this has not been implemented.4791 */4792 HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,4793 NUMPARSE *pNumprs, BYTE *rgbDig)4794 {4795 VARIANT_NUMBER_CHARS chars;4796 BYTE rgbTmp[1024];4797 DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;4798 int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE);4799 int cchUsed = 0;4800 4801 TRACE("%s: (%s, %ld, dwFlags: 0x%08lx,%p,%p, NUMPARSE->dwInFlags: %x)\n", __FUNCTION__, debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig, pNumprs->dwInFlags);4802 4803 if (!pNumprs || !rgbDig)4804 return E_INVALIDARG;4805 4806 if (pNumprs->cDig < iMaxDigits)4807 iMaxDigits = pNumprs->cDig;4808 4809 pNumprs->cDig = 0;4810 pNumprs->dwOutFlags = 0;4811 pNumprs->cchUsed = 0;4812 pNumprs->nBaseShift = 0;4813 pNumprs->nPwr10 = 0;4814 4815 if (!lpszStr)4816 return DISP_E_TYPEMISMATCH;4817 4818 VARIANT_GetLocalisedNumberChars(&chars, lcid, dwFlags);4819 4820 /* First consume all the leading symbols and space from the string */4821 while (1)4822 {4823 if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && isspaceW(*lpszStr))4824 {4825 pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;4826 do4827 {4828 cchUsed++;4829 lpszStr++;4830 } while (isspaceW(*lpszStr));4831 }4832 else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS &&4833 *lpszStr == chars.cPositiveSymbol &&4834 !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS))4835 {4836 pNumprs->dwOutFlags |= NUMPRS_LEADING_PLUS;4837 cchUsed++;4838 lpszStr++;4839 }4840 else if (pNumprs->dwInFlags & NUMPRS_LEADING_MINUS &&4841 *lpszStr == chars.cNegativeSymbol &&4842 !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS))4843 {4844 pNumprs->dwOutFlags |= (NUMPRS_LEADING_MINUS|NUMPRS_NEG);4845 cchUsed++;4846 lpszStr++;4847 }4848 else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&4849 !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) &&4850 *lpszStr == chars.cCurrencyLocal &&4851 (!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2))4852 {4853 pNumprs->dwOutFlags |= NUMPRS_CURRENCY;4854 cchUsed++;4855 lpszStr++;4856 /* Only accept currency characters */4857 chars.cDecimalPoint = chars.cCurrencyDecimalPoint;4858 chars.cDigitSeperator = chars.cCurrencyDigitSeperator;4859 }4860 else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' &&4861 !(pNumprs->dwOutFlags & NUMPRS_PARENS))4862 {4863 pNumprs->dwOutFlags |= NUMPRS_PARENS;4864 cchUsed++;4865 lpszStr++;4866 }4867 else4868 break;4869 } /* End of while */4870 4871 if(pNumprs->dwOutFlags & (1<<VT_LPWSTR))4872 {4873 TRACE(" I'm here");4874 }4875 if (!(pNumprs->dwOutFlags & NUMPRS_CURRENCY))4876 {4877 /* Only accept non-currency characters */4878 chars.cCurrencyDecimalPoint = chars.cDecimalPoint;4879 chars.cCurrencyDigitSeperator = chars.cDigitSeperator;4880 }4881 4882 if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&4883 pNumprs->dwInFlags & NUMPRS_HEX_OCT)4884 {4885 dwState |= B_PROCESSING_HEX;4886 pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;4887 cchUsed=cchUsed+2;4888 lpszStr=lpszStr+2;4889 }4890 else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&4891 pNumprs->dwInFlags & NUMPRS_HEX_OCT)4892 {4893 dwState |= B_PROCESSING_OCT;4894 pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;4895 cchUsed=cchUsed+2;4896 lpszStr=lpszStr+2;4897 }4898 4899 /* Strip Leading zeros */4900 while (*lpszStr == '0')4901 {4902 dwState |= B_LEADING_ZERO;4903 cchUsed++;4904 lpszStr++;4905 }4906 4907 while (*lpszStr)4908 {4909 if (isdigitW(*lpszStr))4910 {4911 if (dwState & B_PROCESSING_EXPONENT)4912 {4913 int exponentSize = 0;4914 if (dwState & B_EXPONENT_START)4915 {4916 while (*lpszStr == '0')4917 {4918 /* Skip leading zero's in the exponent */4919 cchUsed++;4920 lpszStr++;4921 }4922 if (!isdigitW(*lpszStr))4923 break; /* No exponent digits - invalid */4924 }4925 4926 while (isdigitW(*lpszStr))4927 {4928 exponentSize *= 10;4929 exponentSize += *lpszStr - '0';4930 cchUsed++;4931 lpszStr++;4932 }4933 if (dwState & B_NEGATIVE_EXPONENT)4934 exponentSize = -exponentSize;4935 /* Add the exponent into the powers of 10 */4936 pNumprs->nPwr10 += exponentSize;4937 dwState &= ~(B_PROCESSING_EXPONENT|B_EXPONENT_START);4938 lpszStr--; /* back up to allow processing of next char */4939 }4940 else4941 {4942 if ((pNumprs->cDig >= iMaxDigits) && !(dwState & B_PROCESSING_HEX)4943 && !(dwState & B_PROCESSING_OCT))4944 {4945 pNumprs->dwOutFlags |= NUMPRS_INEXACT;4946 4947 if (*lpszStr != '0')4948 dwState &= ~B_INEXACT_ZEROS; /* Inexact number with non-trailing zeros */4949 4950 /* This digit can't be represented, but count it in nPwr10 */4951 if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)4952 pNumprs->nPwr10--;4953 else4954 pNumprs->nPwr10++;4955 }4956 else4957 {4958 if ((dwState & B_PROCESSING_OCT) && ((*lpszStr == '8') || (*lpszStr == '9'))) {4959 return DISP_E_TYPEMISMATCH;4960 }4961 4962 if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)4963 pNumprs->nPwr10--; /* Count decimal points in nPwr10 */4964 4965 rgbTmp[pNumprs->cDig] = *lpszStr - '0';4966 }4967 pNumprs->cDig++;4968 cchUsed++;4969 }4970 }4971 else if (*lpszStr == chars.cDigitSeperator && pNumprs->dwInFlags & NUMPRS_THOUSANDS)4972 {4973 pNumprs->dwOutFlags |= NUMPRS_THOUSANDS;4974 cchUsed++;4975 }4976 else if (*lpszStr == chars.cDecimalPoint &&4977 pNumprs->dwInFlags & NUMPRS_DECIMAL &&4978 !(pNumprs->dwOutFlags & (NUMPRS_DECIMAL|NUMPRS_EXPONENT)))4979 {4980 pNumprs->dwOutFlags |= NUMPRS_DECIMAL;4981 cchUsed++;4982 4983 /* Remove trailing zeros from the whole number part */4984 while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])4985 {4986 pNumprs->nPwr10++;4987 pNumprs->cDig--;4988 }4989 4990 /* If we have no digits so far, skip leading zeros */4991 if (!pNumprs->cDig)4992 {4993 while (lpszStr[1] == '0')4994 {4995 dwState |= B_LEADING_ZERO;4996 cchUsed++;4997 lpszStr++;4998 }4999 }5000 }5001 else if ((*lpszStr == 'e' || *lpszStr == 'E') &&5002 pNumprs->dwInFlags & NUMPRS_EXPONENT &&5003 !(pNumprs->dwOutFlags & NUMPRS_EXPONENT))5004 {5005 dwState |= B_PROCESSING_EXPONENT;5006 pNumprs->dwOutFlags |= NUMPRS_EXPONENT;5007 cchUsed++;5008 }5009 else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cPositiveSymbol)5010 {5011 cchUsed++; /* Ignore positive exponent */5012 }5013 else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cNegativeSymbol)5014 {5015 dwState |= B_NEGATIVE_EXPONENT;5016 cchUsed++;5017 }5018 else if (((*lpszStr >= 'a' && *lpszStr <= 'f') ||5019 (*lpszStr >= 'A' && *lpszStr <= 'F')) &&5020 dwState & B_PROCESSING_HEX)5021 {5022 if (pNumprs->cDig >= iMaxDigits)5023 {5024 return DISP_E_OVERFLOW;5025 }5026 else5027 {5028 if (*lpszStr >= 'a')5029 rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10;5030 else5031 rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10;5032 }5033 pNumprs->cDig++;5034 cchUsed++;5035 }5036 else5037 break; /* Stop at an unrecognised character */5038 5039 lpszStr++;5040 }5041 5042 if (!pNumprs->cDig && dwState & B_LEADING_ZERO)5043 {5044 /* Ensure a 0 on its own gets stored */5045 pNumprs->cDig = 1;5046 rgbTmp[0] = 0;5047 }5048 5049 if (pNumprs->dwOutFlags & NUMPRS_EXPONENT && dwState & B_PROCESSING_EXPONENT)5050 {5051 pNumprs->cchUsed = cchUsed;5052 return DISP_E_TYPEMISMATCH; /* Failed to completely parse the exponent */5053 }5054 5055 if (pNumprs->dwOutFlags & NUMPRS_INEXACT)5056 {5057 if (dwState & B_INEXACT_ZEROS)5058 pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* All zeros doesn't set NUMPRS_INEXACT */5059 } else if(pNumprs->dwInFlags & NUMPRS_HEX_OCT)5060 {5061 /* copy all of the digits into the output digit buffer */5062 /* this is exactly what windows does although it also returns */5063 /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */5064 memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));5065 5066 if (dwState & B_PROCESSING_HEX) {5067 /* hex numbers have always the same format */5068 pNumprs->nPwr10=0;5069 pNumprs->nBaseShift=4;5070 } else {5071 if (dwState & B_PROCESSING_OCT) {5072 /* oct numbers have always the same format */5073 pNumprs->nPwr10=0;5074 pNumprs->nBaseShift=3;5075 } else {5076 while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])5077 {5078 if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)5079 pNumprs->nPwr10--;5080 else5081 pNumprs->nPwr10++;5082 5083 pNumprs->cDig--;5084 }5085 }5086 }5087 } else5088 {5089 /* Remove trailing zeros from the last (whole number or decimal) part */5090 while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])5091 {5092 if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)5093 pNumprs->nPwr10--;5094 else5095 pNumprs->nPwr10++;5096 5097 pNumprs->cDig--;5098 }5099 }5100 5101 if (pNumprs->cDig <= iMaxDigits)5102 pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* Ignore stripped zeros for NUMPRS_INEXACT */5103 else5104 pNumprs->cDig = iMaxDigits; /* Only return iMaxDigits worth of digits */5105 5106 /* Copy the digits we processed into rgbDig */5107 memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));5108 5109 /* Consume any trailing symbols and space */5110 while (1)5111 {5112 if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && isspaceW(*lpszStr))5113 {5114 pNumprs->dwOutFlags |= NUMPRS_TRAILING_WHITE;5115 do5116 {5117 cchUsed++;5118 lpszStr++;5119 } while (isspaceW(*lpszStr));5120 }5121 else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS &&5122 !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) &&5123 *lpszStr == chars.cPositiveSymbol)5124 {5125 pNumprs->dwOutFlags |= NUMPRS_TRAILING_PLUS;5126 cchUsed++;5127 lpszStr++;5128 }5129 else if (pNumprs->dwInFlags & NUMPRS_TRAILING_MINUS &&5130 !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS) &&5131 *lpszStr == chars.cNegativeSymbol)5132 {5133 pNumprs->dwOutFlags |= (NUMPRS_TRAILING_MINUS|NUMPRS_NEG);5134 cchUsed++;5135 lpszStr++;5136 }5137 else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == ')' &&5138 pNumprs->dwOutFlags & NUMPRS_PARENS)5139 {5140 cchUsed++;5141 lpszStr++;5142 pNumprs->dwOutFlags |= NUMPRS_NEG;5143 }5144 else5145 break;5146 }5147 5148 if (pNumprs->dwOutFlags & NUMPRS_PARENS && !(pNumprs->dwOutFlags & NUMPRS_NEG))5149 {5150 pNumprs->cchUsed = cchUsed;5151 return DISP_E_TYPEMISMATCH; /* Opening parenthesis not matched */5152 }5153 5154 if (pNumprs->dwInFlags & NUMPRS_USE_ALL && *lpszStr != '\0')5155 return DISP_E_TYPEMISMATCH; /* Not all chars were consumed */5156 5157 if (!pNumprs->cDig)5158 return DISP_E_TYPEMISMATCH; /* No Number found */5159 5160 pNumprs->cchUsed = cchUsed;5161 TRACE("%s: Returning, NUMPARS->cchUsed: %x, NUMPARS->cDig: %x, pNumprs->dwOutFlags: %x, NUMPARS->nBaseShift: %x,, NUMPARS->nPwr10: %x\n",5162 __FUNCTION__, cchUsed, pNumprs->cDig, pNumprs->dwOutFlags, pNumprs->nBaseShift, pNumprs->nPwr10);5163 return S_OK;5164 }5165 5166 #if 05167 4487 /********************************************************************** 5168 4488 * VarParseNumFromStr [OLEAUT32.46] … … 5204 4524 return S_OK; 5205 4525 } 5206 #endif5207 4526 5208 4527 5209 4528 /********************************************************************** 5210 4529 * VarNumFromParseNum [OLEAUT32.47] 5211 *5212 * Convert a NUMPARSE structure into a numeric Variant type.5213 *5214 * PARAMS5215 * pNumprs [I] Source for parsed number. cDig must be set to the size of rgbDig5216 * rgbDig [I] Source for the numbers digits5217 * dwVtBits [I] VTBIT_ flags from "oleauto.h" indicating the acceptable dest types5218 * pVarDst [O] Destination for the converted Variant value.5219 *5220 * RETURNS5221 * Success: S_OK. pVarDst contains the converted value.5222 * Failure: E_INVALIDARG, if any parameter is invalid.5223 * DISP_E_OVERFLOW, if the number is too big for the types set in dwVtBits.5224 *5225 * NOTES5226 * - The smallest favoured type present in dwVtBits that can represent the5227 * number in pNumprs without losing precision is used.5228 * - Signed types are preferrred over unsigned types of the same size.5229 * - Preferred types in order are: integer, float, double, currency then decimal.5230 * - Rounding (dropping of decimal points) occurs without error. See VarI8FromR8()5231 * for details of the rounding method.5232 * - pVarDst is not cleared before the result is stored in it.5233 4530 */ 5234 4531 HRESULT WINAPI VarNumFromParseNum(NUMPARSE * pnumprs, BYTE * rgbDig, 5235 4532 ULONG dwVtBits, VARIANT * pvar) 5236 4533 { 5237 #ifdef __WIN32OS2__5238 4534 DWORD xint; 5239 4535 int i; 5240 5241 TRACE("%s: NUMPARSE->cDig: %x, NUMPARSE->nBaseShift: %x, NUMPARSE->dwOutFlags: %x dwVtBits=%lx. rgbDig: \n", 5242 __FUNCTION__, pnumprs->cDig, pnumprs->nBaseShift, pnumprs->dwOutFlags, dwVtBits); 4536 FIXME("(..,dwVtBits=%lx,....), partial stub!\n",dwVtBits); 5243 4537 5244 4538 xint = 0; 5245 4539 for (i=0;i<pnumprs->cDig;i++) 5246 4540 xint = xint*10 + rgbDig[i]; 5247 4541 5248 4542 if (pnumprs->dwOutFlags & NUMPRS_NEG) { 5249 4543 xint = xint * -1; 5250 4544 } 5251 TRACE("%s: xint: %x (%ld)\n", __FUNCTION__, xint, xint);5252 4545 5253 4546 VariantInit(pvar); … … 5281 4574 } 5282 4575 5283 if (dwVtBits & VTBIT_DECIMAL)5284 {5285 int i;5286 ULONG carry;5287 /* ULONG64 tmp; */5288 ULONG tmp;5289 DECIMAL* pDec = &V_DECIMAL(pvar);5290 5291 V_VT(pvar) = VT_DECIMAL;5292 5293 DECIMAL_SETZERO(pDec);5294 DEC_LO32(pDec) = 0;5295 5296 if (pnumprs->dwOutFlags & NUMPRS_NEG)5297 DEC_SIGN(pDec) = DECIMAL_NEG;5298 else5299 DEC_SIGN(pDec) = DECIMAL_POS;5300 5301 /* Factor the significant digits */5302 for (i = 0; i < pnumprs->cDig; i++)5303 {5304 if(0xffffffff /10 - 9 < DEC_LO32(pDec) ) {5305 /* Overflow expected. This code only support 32Bit numbers for now */5306 FIXME("%s: Converted number will be > 32bit! Only partial implementation. Returning DISP_E_OVERFLOW.", __FUNCTION__);5307 DEC_LO32(pDec) = UI4_MAX;5308 return DISP_E_OVERFLOW;5309 }5310 5311 tmp = DEC_LO32(pDec) * 10 + rgbDig[i];5312 5313 /* No support for numbers > 32 bit for now. */5314 DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);5315 DEC_MID32(pDec) = (ULONG)0;5316 DEC_HI32(pDec) = (ULONG)0;5317 5318 /* The following is not working because of missing ULONG64 !! */5319 #if 05320 carry = (ULONG)(tmp >> 32);5321 DEC_LO64(pDec)=tmp;5322 DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);5323 tmp = (ULONG)DEC_MID32(pDec) * 10 + carry;5324 carry = (ULONG)(tmp >> 32);5325 DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);5326 tmp = (ULONG)DEC_HI32(pDec) * 10 + carry;5327 DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);5328 #endif5329 5330 if (tmp >> 32 & UI4_MAX)5331 {5332 VarNumFromParseNum_DecOverflow:5333 TRACE("Overflow\n");5334 DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX;5335 return DISP_E_OVERFLOW;5336 }5337 }5338 5339 TRACE("Done... LO32: %x, MID32: %x, HI32: %x, DEC_LO64: %x, SignScale: %x, sign: %x\n",5340 DEC_LO32(pDec), DEC_MID32(pDec), DEC_HI32(pDec), DEC_LO64(pDec), DEC_SIGNSCALE(pDec), DEC_SIGN(pDec) );5341 5342 return S_OK;5343 }5344 5345 FIXME("%s: (..,dwVtBits=%lx,....), partial stub!\n", __FUNCTION__, dwVtBits);5346 4576 FIXME("vtbitmask is unsupported %lx, int=%d\n",dwVtBits, (int) xint); 5347 4577 return E_FAIL; 5348 } /* End of __WIN32OS2__ */ 5349 5350 #else 5351 5352 /* Scale factors and limits for double arithmetic */ 5353 static const double dblMultipliers[11] = { 5354 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 5355 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0 5356 }; 5357 static const double dblMinimums[11] = { 5358 R8_MIN, R8_MIN*10.0, R8_MIN*100.0, R8_MIN*1000.0, R8_MIN*10000.0, 5359 R8_MIN*100000.0, R8_MIN*1000000.0, R8_MIN*10000000.0, 5360 R8_MIN*100000000.0, R8_MIN*1000000000.0, R8_MIN*10000000000.0 5361 }; 5362 static const double dblMaximums[11] = { 5363 R8_MAX, R8_MAX/10.0, R8_MAX/100.0, R8_MAX/1000.0, R8_MAX/10000.0, 5364 R8_MAX/100000.0, R8_MAX/1000000.0, R8_MAX/10000000.0, 5365 R8_MAX/100000000.0, R8_MAX/1000000000.0, R8_MAX/10000000000.0 5366 }; 5367 5368 int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0; 5369 5370 TRACE("(%p,%p,0x%lx,%p)\n", pNumprs, rgbDig, dwVtBits, pVarDst); 5371 5372 if (pNumprs->nBaseShift) 5373 { 5374 /* nBaseShift indicates a hex or octal number */ 5375 ULONG64 ul64 = 0; 5376 LONG64 l64; 5377 int i; 5378 5379 /* Convert the hex or octal number string into a UI64 */ 5380 for (i = 0; i < pNumprs->cDig; i++) 5381 { 5382 if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i])) 5383 { 5384 TRACE("Overflow multiplying digits\n"); 5385 return DISP_E_OVERFLOW; 5386 } 5387 ul64 = (ul64<<pNumprs->nBaseShift) + rgbDig[i]; 5388 } 5389 5390 /* also make a negative representation */ 5391 l64=-ul64; 5392 5393 /* Try signed and unsigned types in size order */ 5394 if (dwVtBits & VTBIT_I1 && ((ul64 <= I1_MAX)||(l64 >= I1_MIN))) 5395 { 5396 V_VT(pVarDst) = VT_I1; 5397 if (ul64 <= I1_MAX) 5398 V_I1(pVarDst) = ul64; 5399 else 5400 V_I1(pVarDst) = l64; 5401 return S_OK; 5402 } 5403 else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX) 5404 { 5405 V_VT(pVarDst) = VT_UI1; 5406 V_UI1(pVarDst) = ul64; 5407 return S_OK; 5408 } 5409 else if (dwVtBits & VTBIT_I2 && ((ul64 <= I2_MAX)||(l64 >= I2_MIN))) 5410 { 5411 V_VT(pVarDst) = VT_I2; 5412 if (ul64 <= I2_MAX) 5413 V_I2(pVarDst) = ul64; 5414 else 5415 V_I2(pVarDst) = l64; 5416 return S_OK; 5417 } 5418 else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX) 5419 { 5420 V_VT(pVarDst) = VT_UI2; 5421 V_UI2(pVarDst) = ul64; 5422 return S_OK; 5423 } 5424 else if (dwVtBits & VTBIT_I4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) 5425 { 5426 V_VT(pVarDst) = VT_I4; 5427 if (ul64 <= I4_MAX) 5428 V_I4(pVarDst) = ul64; 5429 else 5430 V_I4(pVarDst) = l64; 5431 return S_OK; 5432 } 5433 else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX) 5434 { 5435 V_VT(pVarDst) = VT_UI4; 5436 V_UI4(pVarDst) = ul64; 5437 return S_OK; 5438 } 5439 else if (dwVtBits & VTBIT_I8 && ((ul64 <= I4_MAX)||(l64>=I4_MIN))) 5440 { 5441 V_VT(pVarDst) = VT_I8; 5442 V_I8(pVarDst) = ul64; 5443 return S_OK; 5444 } 5445 else if (dwVtBits & VTBIT_UI8) 5446 { 5447 V_VT(pVarDst) = VT_UI8; 5448 V_UI8(pVarDst) = ul64; 5449 return S_OK; 5450 } 5451 else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) 5452 { 5453 V_VT(pVarDst) = VT_DECIMAL; 5454 DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0); 5455 DEC_HI32(&V_DECIMAL(pVarDst)) = 0; 5456 DEC_LO64(&V_DECIMAL(pVarDst)) = ul64; 5457 return S_OK; 5458 } 5459 else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) 5460 { 5461 V_VT(pVarDst) = VT_R4; 5462 if (ul64 <= I4_MAX) 5463 V_R4(pVarDst) = ul64; 5464 else 5465 V_R4(pVarDst) = l64; 5466 return S_OK; 5467 } 5468 else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) 5469 { 5470 V_VT(pVarDst) = VT_R8; 5471 if (ul64 <= I4_MAX) 5472 V_R8(pVarDst) = ul64; 5473 else 5474 V_R8(pVarDst) = l64; 5475 return S_OK; 5476 } 5477 TRACE("Overflow: possible return types: 0x%lx, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64)); 5478 return DISP_E_OVERFLOW; 5479 } 5480 5481 /* Count the number of relevant fractional and whole digits stored, 5482 * And compute the divisor/multiplier to scale the number by. 5483 */ 5484 if (pNumprs->nPwr10 < 0) 5485 { 5486 if (-pNumprs->nPwr10 >= pNumprs->cDig) 5487 { 5488 /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */ 5489 wholeNumberDigits = 0; 5490 fractionalDigits = pNumprs->cDig; 5491 divisor10 = -pNumprs->nPwr10; 5492 } 5493 else 5494 { 5495 /* An exactly represented real number e.g. 1.024 */ 5496 wholeNumberDigits = pNumprs->cDig + pNumprs->nPwr10; 5497 fractionalDigits = pNumprs->cDig - wholeNumberDigits; 5498 divisor10 = pNumprs->cDig - wholeNumberDigits; 5499 } 5500 } 5501 else if (pNumprs->nPwr10 == 0) 5502 { 5503 /* An exactly represented whole number e.g. 1024 */ 5504 wholeNumberDigits = pNumprs->cDig; 5505 fractionalDigits = 0; 5506 } 5507 else /* pNumprs->nPwr10 > 0 */ 5508 { 5509 /* A whole number followed by nPwr10 0's e.g. 102400 */ 5510 wholeNumberDigits = pNumprs->cDig; 5511 fractionalDigits = 0; 5512 multiplier10 = pNumprs->nPwr10; 5513 } 5514 5515 TRACE("cDig %d; nPwr10 %d, whole %d, frac %d ", pNumprs->cDig, 5516 pNumprs->nPwr10, wholeNumberDigits, fractionalDigits); 5517 TRACE("mult %d; div %d\n", multiplier10, divisor10); 5518 5519 if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) && 5520 (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL)))) 5521 { 5522 /* We have one or more integer output choices, and either: 5523 * 1) An integer input value, or 5524 * 2) A real number input value but no floating output choices. 5525 * Alternately, we have a DECIMAL output available and an integer input. 5526 * 5527 * So, place the integer value into pVarDst, using the smallest type 5528 * possible and preferring signed over unsigned types. 5529 */ 5530 BOOL bOverflow = FALSE, bNegative; 5531 ULONG64 ul64 = 0; 5532 int i; 5533 5534 /* Convert the integer part of the number into a UI8 */ 5535 for (i = 0; i < wholeNumberDigits; i++) 5536 { 5537 if (ul64 > (UI8_MAX / 10 - rgbDig[i])) 5538 { 5539 TRACE("Overflow multiplying digits\n"); 5540 bOverflow = TRUE; 5541 break; 5542 } 5543 ul64 = ul64 * 10 + rgbDig[i]; 5544 } 5545 5546 /* Account for the scale of the number */ 5547 if (!bOverflow && multiplier10) 5548 { 5549 for (i = 0; i < multiplier10; i++) 5550 { 5551 if (ul64 > (UI8_MAX / 10)) 5552 { 5553 TRACE("Overflow scaling number\n"); 5554 bOverflow = TRUE; 5555 break; 5556 } 5557 ul64 = ul64 * 10; 5558 } 5559 } 5560 5561 /* If we have any fractional digits, round the value. 5562 * Note we don't have to do this if divisor10 is < 1, 5563 * because this means the fractional part must be < 0.5 5564 */ 5565 if (!bOverflow && fractionalDigits && divisor10 > 0) 5566 { 5567 const BYTE* fracDig = rgbDig + wholeNumberDigits; 5568 BOOL bAdjust = FALSE; 5569 5570 TRACE("first decimal value is %d\n", *fracDig); 5571 5572 if (*fracDig > 5) 5573 bAdjust = TRUE; /* > 0.5 */ 5574 else if (*fracDig == 5) 5575 { 5576 for (i = 1; i < fractionalDigits; i++) 5577 { 5578 if (fracDig[i]) 5579 { 5580 bAdjust = TRUE; /* > 0.5 */ 5581 break; 5582 } 5583 } 5584 /* If exactly 0.5, round only odd values */ 5585 if (i == fractionalDigits && (ul64 & 1)) 5586 bAdjust = TRUE; 5587 } 5588 5589 if (bAdjust) 5590 { 5591 if (ul64 == UI8_MAX) 5592 { 5593 TRACE("Overflow after rounding\n"); 5594 bOverflow = TRUE; 5595 } 5596 ul64++; 5597 } 5598 } 5599 5600 /* Zero is not a negative number */ 5601 bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64 ? TRUE : FALSE; 5602 5603 TRACE("Integer value is %lld, bNeg %d\n", ul64, bNegative); 5604 5605 /* For negative integers, try the signed types in size order */ 5606 if (!bOverflow && bNegative) 5607 { 5608 if (dwVtBits & (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8)) 5609 { 5610 if (dwVtBits & VTBIT_I1 && ul64 <= -I1_MIN) 5611 { 5612 V_VT(pVarDst) = VT_I1; 5613 V_I1(pVarDst) = -ul64; 5614 return S_OK; 5615 } 5616 else if (dwVtBits & VTBIT_I2 && ul64 <= -I2_MIN) 5617 { 5618 V_VT(pVarDst) = VT_I2; 5619 V_I2(pVarDst) = -ul64; 5620 return S_OK; 5621 } 5622 else if (dwVtBits & VTBIT_I4 && ul64 <= -((LONGLONG)I4_MIN)) 5623 { 5624 V_VT(pVarDst) = VT_I4; 5625 V_I4(pVarDst) = -ul64; 5626 return S_OK; 5627 } 5628 else if (dwVtBits & VTBIT_I8 && ul64 <= (ULONGLONG)I8_MAX + 1) 5629 { 5630 V_VT(pVarDst) = VT_I8; 5631 V_I8(pVarDst) = -ul64; 5632 return S_OK; 5633 } 5634 else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) 5635 { 5636 /* Decimal is only output choice left - fast path */ 5637 V_VT(pVarDst) = VT_DECIMAL; 5638 DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_NEG,0); 5639 DEC_HI32(&V_DECIMAL(pVarDst)) = 0; 5640 DEC_LO64(&V_DECIMAL(pVarDst)) = -ul64; 5641 return S_OK; 5642 } 5643 } 5644 } 5645 else if (!bOverflow) 5646 { 5647 /* For positive integers, try signed then unsigned types in size order */ 5648 if (dwVtBits & VTBIT_I1 && ul64 <= I1_MAX) 5649 { 5650 V_VT(pVarDst) = VT_I1; 5651 V_I1(pVarDst) = ul64; 5652 return S_OK; 5653 } 5654 else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX) 5655 { 5656 V_VT(pVarDst) = VT_UI1; 5657 V_UI1(pVarDst) = ul64; 5658 return S_OK; 5659 } 5660 else if (dwVtBits & VTBIT_I2 && ul64 <= I2_MAX) 5661 { 5662 V_VT(pVarDst) = VT_I2; 5663 V_I2(pVarDst) = ul64; 5664 return S_OK; 5665 } 5666 else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX) 5667 { 5668 V_VT(pVarDst) = VT_UI2; 5669 V_UI2(pVarDst) = ul64; 5670 return S_OK; 5671 } 5672 else if (dwVtBits & VTBIT_I4 && ul64 <= I4_MAX) 5673 { 5674 V_VT(pVarDst) = VT_I4; 5675 V_I4(pVarDst) = ul64; 5676 return S_OK; 5677 } 5678 else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX) 5679 { 5680 V_VT(pVarDst) = VT_UI4; 5681 V_UI4(pVarDst) = ul64; 5682 return S_OK; 5683 } 5684 else if (dwVtBits & VTBIT_I8 && ul64 <= I8_MAX) 5685 { 5686 V_VT(pVarDst) = VT_I8; 5687 V_I8(pVarDst) = ul64; 5688 return S_OK; 5689 } 5690 else if (dwVtBits & VTBIT_UI8) 5691 { 5692 V_VT(pVarDst) = VT_UI8; 5693 V_UI8(pVarDst) = ul64; 5694 return S_OK; 5695 } 5696 else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) 5697 { 5698 /* Decimal is only output choice left - fast path */ 5699 V_VT(pVarDst) = VT_DECIMAL; 5700 DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0); 5701 DEC_HI32(&V_DECIMAL(pVarDst)) = 0; 5702 DEC_LO64(&V_DECIMAL(pVarDst)) = ul64; 5703 return S_OK; 5704 } 5705 } 5706 } 5707 5708 if (dwVtBits & REAL_VTBITS) 5709 { 5710 /* Try to put the number into a float or real */ 5711 BOOL bOverflow = FALSE, bNegative = pNumprs->dwOutFlags & NUMPRS_NEG; 5712 double whole = 0.0; 5713 int i; 5714 5715 /* Convert the number into a double */ 5716 for (i = 0; i < pNumprs->cDig; i++) 5717 whole = whole * 10.0 + rgbDig[i]; 5718 5719 TRACE("Whole double value is %16.16g\n", whole); 5720 5721 /* Account for the scale */ 5722 while (multiplier10 > 10) 5723 { 5724 if (whole > dblMaximums[10]) 5725 { 5726 dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); 5727 bOverflow = TRUE; 5728 break; 5729 } 5730 whole = whole * dblMultipliers[10]; 5731 multiplier10 -= 10; 5732 } 5733 if (multiplier10) 5734 { 5735 if (whole > dblMaximums[multiplier10]) 5736 { 5737 dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); 5738 bOverflow = TRUE; 5739 } 5740 else 5741 whole = whole * dblMultipliers[multiplier10]; 5742 } 5743 5744 TRACE("Scaled double value is %16.16g\n", whole); 5745 5746 while (divisor10 > 10) 5747 { 5748 if (whole < dblMinimums[10]) 5749 { 5750 dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */ 5751 bOverflow = TRUE; 5752 break; 5753 } 5754 whole = whole / dblMultipliers[10]; 5755 divisor10 -= 10; 5756 } 5757 if (divisor10) 5758 { 5759 if (whole < dblMinimums[divisor10]) 5760 { 5761 dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */ 5762 bOverflow = TRUE; 5763 } 5764 else 5765 whole = whole / dblMultipliers[divisor10]; 5766 } 5767 if (!bOverflow) 5768 TRACE("Final double value is %16.16g\n", whole); 5769 5770 if (dwVtBits & VTBIT_R4 && 5771 ((whole <= R4_MAX && whole >= R4_MIN) || whole == 0.0)) 5772 { 5773 TRACE("Set R4 to final value\n"); 5774 V_VT(pVarDst) = VT_R4; /* Fits into a float */ 5775 V_R4(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole; 5776 return S_OK; 5777 } 5778 5779 if (dwVtBits & VTBIT_R8) 5780 { 5781 TRACE("Set R8 to final value\n"); 5782 V_VT(pVarDst) = VT_R8; /* Fits into a double */ 5783 V_R8(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole; 5784 return S_OK; 5785 } 5786 5787 if (dwVtBits & VTBIT_CY) 5788 { 5789 if (SUCCEEDED(VarCyFromR8(bNegative ? -whole : whole, &V_CY(pVarDst)))) 5790 { 5791 V_VT(pVarDst) = VT_CY; /* Fits into a currency */ 5792 TRACE("Set CY to final value\n"); 5793 return S_OK; 5794 } 5795 TRACE("Value Overflows CY\n"); 5796 } 5797 } 5798 5799 if (dwVtBits & VTBIT_DECIMAL) 5800 { 5801 int i; 5802 ULONG carry; 5803 ULONG64 tmp; 5804 DECIMAL* pDec = &V_DECIMAL(pVarDst); 5805 5806 DECIMAL_SETZERO(pDec); 5807 DEC_LO32(pDec) = 0; 5808 5809 if (pNumprs->dwOutFlags & NUMPRS_NEG) 5810 DEC_SIGN(pDec) = DECIMAL_NEG; 5811 else 5812 DEC_SIGN(pDec) = DECIMAL_POS; 5813 5814 /* Factor the significant digits */ 5815 for (i = 0; i < pNumprs->cDig; i++) 5816 { 5817 tmp = (ULONG64)DEC_LO32(pDec) * 10 + rgbDig[i]; 5818 carry = (ULONG)(tmp >> 32); 5819 DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX); 5820 tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry; 5821 carry = (ULONG)(tmp >> 32); 5822 DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX); 5823 tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry; 5824 DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX); 5825 5826 if (tmp >> 32 & UI4_MAX) 5827 { 5828 VarNumFromParseNum_DecOverflow: 5829 TRACE("Overflow\n"); 5830 DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX; 5831 return DISP_E_OVERFLOW; 5832 } 5833 } 5834 5835 /* Account for the scale of the number */ 5836 while (multiplier10 > 0) 5837 { 5838 tmp = (ULONG64)DEC_LO32(pDec) * 10; 5839 carry = (ULONG)(tmp >> 32); 5840 DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX); 5841 tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry; 5842 carry = (ULONG)(tmp >> 32); 5843 DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX); 5844 tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry; 5845 DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX); 5846 5847 if (tmp >> 32 & UI4_MAX) 5848 goto VarNumFromParseNum_DecOverflow; 5849 multiplier10--; 5850 } 5851 DEC_SCALE(pDec) = divisor10; 5852 5853 V_VT(pVarDst) = VT_DECIMAL; 5854 return S_OK; 5855 } 5856 return DISP_E_OVERFLOW; /* No more output choices */ 5857 } 5858 #endif 4578 } 4579 5859 4580 5860 4581 /********************************************************************** … … 5875 4596 return E_NOTIMPL; 5876 4597 } 5877 5878 /**********************************************************************5879 * VarFormatNumber [OLEAUT32.107]5880 */5881 HRESULT WINAPI VarFormatNumber(LPVARIANT pvarIn, int iNumDig, int iIncLead, int iUseParens, int iGroup, ULONG dwFlags, BSTR* pbstrOut)5882 {5883 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);5884 return E_NOTIMPL;5885 }5886 5887 5888 /**********************************************************************5889 * VarFormatPercent [OLEAUT32.117]5890 */5891 HRESULT WINAPI VarFormatPercent(LPVARIANT pvarIn, int iNumDig, int iIncLead, int iUseParens, int iGroup, ULONG dwFlags, BSTR* pbstrOut)5892 {5893 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);5894 return E_NOTIMPL;5895 }5896 5897 5898 /**********************************************************************5899 * VarWeekdayName [OLEAUT32.128]5900 */5901 HRESULT WINAPI VarWeekdayName(int iWeekday, int fAbbrey, int iFirstDay, ULONG dwFlags, BSTR* pbstrOut)5902 {5903 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);5904 return E_NOTIMPL;5905 }5906 5907 5908 /**********************************************************************5909 * VarMonthName [OLEAUT32.129]5910 */5911 HRESULT WINAPI VarMonthName(int iMonth, int fAbbrey, ULONG dwFlags, BSTR* pbstrOut)5912 {5913 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);5914 return E_NOTIMPL;5915 }5916 5917 4598 5918 4599 /********************************************************************** … … 6339 5020 case VT_UI4 : rVal = V_UNION(right,ulVal); break; 6340 5021 case VT_UINT : rVal = V_UNION(right,ulVal); break; 6341 #ifdef __WIN32OS2__6342 case VT_R8 : rVal = V_UNION(right,dblVal); break;6343 #endif6344 5022 default: rOk = FALSE; 6345 5023 } … … 6429 5107 6430 5108 /********************************************************************** 6431 * VarOr [OLEAUT32.157]6432 *6433 * Perform a logical or (OR) operation on two variants.6434 *6435 * PARAMS6436 * pVarLeft [I] First variant6437 * pVarRight [I] Variant to OR with pVarLeft6438 * pVarOut [O] Destination for OR result6439 *6440 * RETURNS6441 * Success: S_OK. pVarOut contains the result of the operation with its type6442 * taken from the table listed under VarXor().6443 * Failure: An HRESULT error code indicating the error.6444 *6445 * NOTES6446 * See the Notes section of VarXor() for further information.6447 */6448 HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)6449 {6450 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6451 return E_NOTIMPL;6452 6453 6454 #if 06455 VARTYPE vt = VT_I4;6456 VARIANT varLeft, varRight, varStr;6457 HRESULT hRet;6458 6459 #if 06460 TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),6461 debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),6462 debugstr_VF(pVarRight), pVarOut);6463 #endif6464 if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||6465 V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||6466 V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH ||6467 V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD)6468 return DISP_E_BADVARTYPE;6469 6470 V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY;6471 6472 if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)6473 {6474 /* NULL OR Zero is NULL, NULL OR value is value */6475 if (V_VT(pVarLeft) == VT_NULL)6476 pVarLeft = pVarRight; /* point to the non-NULL var */6477 6478 V_VT(pVarOut) = VT_NULL;6479 V_I4(pVarOut) = 0;6480 6481 switch (V_VT(pVarLeft))6482 {6483 case VT_DATE: case VT_R8:6484 if (V_R8(pVarLeft))6485 goto VarOr_AsEmpty;6486 return S_OK;6487 case VT_BOOL:6488 if (V_BOOL(pVarLeft))6489 *pVarOut = *pVarLeft;6490 return S_OK;6491 case VT_I2: case VT_UI2:6492 if (V_I2(pVarLeft))6493 goto VarOr_AsEmpty;6494 return S_OK;6495 case VT_I1:6496 if (V_I1(pVarLeft))6497 goto VarOr_AsEmpty;6498 return S_OK;6499 case VT_UI1:6500 if (V_UI1(pVarLeft))6501 *pVarOut = *pVarLeft;6502 return S_OK;6503 case VT_R4:6504 if (V_R4(pVarLeft))6505 goto VarOr_AsEmpty;6506 return S_OK;6507 case VT_I4: case VT_UI4: case VT_INT: case VT_UINT:6508 if (V_I4(pVarLeft))6509 goto VarOr_AsEmpty;6510 return S_OK;6511 case VT_CY:6512 if (V_CY(pVarLeft).int64)6513 goto VarOr_AsEmpty;6514 return S_OK;6515 case VT_I8: case VT_UI8:6516 if (V_I8(pVarLeft))6517 goto VarOr_AsEmpty;6518 return S_OK;6519 case VT_DECIMAL:6520 if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft)))6521 goto VarOr_AsEmpty;6522 return S_OK;6523 case VT_BSTR:6524 {6525 VARIANT_BOOL b;6526 6527 if (!V_BSTR(pVarLeft))6528 return DISP_E_BADVARTYPE;6529 6530 hRet = VarBoolFromStr(V_BSTR(pVarLeft), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);6531 if (SUCCEEDED(hRet) && b)6532 {6533 V_VT(pVarOut) = VT_BOOL;6534 V_BOOL(pVarOut) = b;6535 }6536 return hRet;6537 }6538 case VT_NULL: case VT_EMPTY:6539 V_VT(pVarOut) = VT_NULL;6540 return S_OK;6541 default:6542 return DISP_E_BADVARTYPE;6543 }6544 }6545 6546 if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY)6547 {6548 if (V_VT(pVarLeft) == VT_EMPTY)6549 pVarLeft = pVarRight; /* point to the non-EMPTY var */6550 6551 VarOr_AsEmpty:6552 /* Since one argument is empty (0), OR'ing it with the other simply6553 * gives the others value (as 0|x => x). So just convert the other6554 * argument to the required result type.6555 */6556 switch (V_VT(pVarLeft))6557 {6558 case VT_BSTR:6559 if (!V_BSTR(pVarLeft))6560 return DISP_E_BADVARTYPE;6561 6562 hRet = VariantCopy(&varStr, pVarLeft);6563 if (FAILED(hRet))6564 goto VarOr_Exit;6565 pVarLeft = &varStr;6566 hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);6567 if (FAILED(hRet))6568 goto VarOr_Exit;6569 /* Fall Through ... */6570 case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2:6571 V_VT(pVarOut) = VT_I2;6572 break;6573 case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:6574 case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:6575 case VT_INT: case VT_UINT: case VT_UI8:6576 V_VT(pVarOut) = VT_I4;6577 break;6578 case VT_I8:6579 V_VT(pVarOut) = VT_I8;6580 break;6581 default:6582 return DISP_E_BADVARTYPE;6583 }6584 hRet = VariantCopy(&varLeft, pVarLeft);6585 if (FAILED(hRet))6586 goto VarOr_Exit;6587 pVarLeft = &varLeft;6588 hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut));6589 goto VarOr_Exit;6590 }6591 6592 if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)6593 {6594 V_VT(pVarOut) = VT_BOOL;6595 V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight);6596 return S_OK;6597 }6598 6599 if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)6600 {6601 V_VT(pVarOut) = VT_UI1;6602 V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight);6603 return S_OK;6604 }6605 6606 if (V_VT(pVarLeft) == VT_BSTR)6607 {6608 hRet = VariantCopy(&varStr, pVarLeft);6609 if (FAILED(hRet))6610 goto VarOr_Exit;6611 pVarLeft = &varStr;6612 hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);6613 if (FAILED(hRet))6614 goto VarOr_Exit;6615 }6616 6617 if (V_VT(pVarLeft) == VT_BOOL &&6618 (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR))6619 {6620 vt = VT_BOOL;6621 }6622 else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 ||6623 V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) &&6624 (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||6625 V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR))6626 {6627 vt = VT_I2;6628 }6629 else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)6630 {6631 if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)6632 return DISP_E_TYPEMISMATCH;6633 vt = VT_I8;6634 }6635 6636 hRet = VariantCopy(&varLeft, pVarLeft);6637 if (FAILED(hRet))6638 goto VarOr_Exit;6639 6640 hRet = VariantCopy(&varRight, pVarRight);6641 if (FAILED(hRet))6642 goto VarOr_Exit;6643 6644 if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4)6645 V_VT(&varLeft) = VT_I4; /* Don't overflow */6646 else6647 {6648 double d;6649 6650 if (V_VT(&varLeft) == VT_BSTR &&6651 FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d)))6652 hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL);6653 if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt)6654 hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);6655 if (FAILED(hRet))6656 goto VarOr_Exit;6657 }6658 6659 if (vt == VT_I4 && V_VT(&varRight) == VT_UI4)6660 V_VT(&varRight) = VT_I4; /* Don't overflow */6661 else6662 {6663 double d;6664 6665 if (V_VT(&varRight) == VT_BSTR &&6666 FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d)))6667 hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL);6668 if (SUCCEEDED(hRet) && V_VT(&varRight) != vt)6669 hRet = VariantChangeType(&varRight, &varRight, 0, vt);6670 if (FAILED(hRet))6671 goto VarOr_Exit;6672 }6673 6674 V_VT(pVarOut) = vt;6675 if (vt == VT_I8)6676 {6677 V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight);6678 }6679 else if (vt == VT_I4)6680 {6681 V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight);6682 }6683 else6684 {6685 V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight);6686 }6687 6688 VarOr_Exit:6689 VariantClear(&varStr);6690 VariantClear(&varLeft);6691 VariantClear(&varRight);6692 return hRet;6693 #endif6694 }6695 6696 6697 /**********************************************************************6698 * VarXor [OLEAUT32.167]6699 */6700 HRESULT WINAPI VarXor(LPVARIANT pvarLeft, LPVARIANT pvarRight, LPVARIANT pvarResult)6701 {6702 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6703 6704 return E_NOTIMPL;6705 }6706 6707 /**********************************************************************6708 5109 * VarNot [OLEAUT32.174] 6709 5110 * … … 6732 5133 TRACE("rc=%d, Result:\n", (int) rc); 6733 5134 dump_Variant(result); 6734 return rc;6735 }6736 6737 /**********************************************************************6738 * VarNeg [OLEAUT32.173]6739 *6740 * Negate the value of a variant.6741 *6742 * PARAMS6743 * pVarIn [I] Source variant6744 * pVarOut [O] Destination for converted value6745 *6746 * RETURNS6747 * Success: S_OK. pVarOut contains the converted value.6748 * Failure: An HRESULT error code indicating the error.6749 *6750 * NOTES6751 * - The type of the value stored in pVarOut depends on the type of pVarIn,6752 * according to the following table:6753 *| Input Type Output Type6754 *| ---------- -----------6755 *| VT_EMPTY VT_I26756 *| VT_UI1 VT_I26757 *| VT_BOOL VT_I26758 *| VT_BSTR VT_R86759 *| All Others Unchanged (unless promoted)6760 * - Where the negated value of a variant does not fit in its base type, the type6761 * is promoted according to the following table:6762 *| Input Type Promoted To6763 *| ---------- -----------6764 *| VT_I2 VT_I46765 *| VT_I4 VT_R86766 *| VT_I8 VT_R86767 * - The native version of this function returns DISP_E_BADVARTYPE for valid6768 * variant types that cannot be negated, and returns DISP_E_TYPEMISMATCH6769 * for types which are not valid. Since this is in contravention of the6770 * meaning of those error codes and unlikely to be relied on by applications,6771 * this implementation returns errors consistent with the other high level6772 * variant math functions.6773 */6774 HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)6775 {6776 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6777 return E_NOTIMPL;6778 }6779 6780 /**********************************************************************6781 * VarAbs [OLEAUT32.168]6782 *6783 * Convert a variant to its absolute value.6784 *6785 * PARAMS6786 * pVarIn [I] Source variant6787 * pVarOut [O] Destination for converted value6788 *6789 * RETURNS6790 * Success: S_OK. pVarOut contains the absolute value of pVarIn.6791 * Failure: An HRESULT error code indicating the error.6792 *6793 * NOTES6794 * - This function does not process by-reference variants.6795 * - The type of the value stored in pVarOut depends on the type of pVarIn,6796 * according to the following table:6797 *| Input Type Output Type6798 *| ---------- -----------6799 *| VT_BOOL VT_I26800 *| VT_BSTR VT_R86801 *| (All others) Unchanged6802 */6803 HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)6804 {6805 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6806 return E_NOTIMPL;6807 }6808 6809 /**********************************************************************6810 * VarFix [OLEAUT32.169]6811 */6812 HRESULT WINAPI VarFix(LPVARIANT pvarIn, LPVARIANT pvarResult)6813 {6814 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6815 return E_NOTIMPL;6816 }6817 6818 /**********************************************************************6819 * VarInt [OLEAUT32.172]6820 */6821 HRESULT WINAPI VarInt(LPVARIANT pvarIn, LPVARIANT pvarResult)6822 {6823 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6824 return E_NOTIMPL;6825 }6826 6827 /**********************************************************************6828 * VarImp [OLEAUT32.154]6829 */6830 HRESULT WINAPI VarImp(LPVARIANT pvarLeft, LPVARIANT pvarRight, LPVARIANT pvarResult)6831 {6832 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6833 return E_NOTIMPL;6834 }6835 6836 /**********************************************************************6837 * VarMod [OLEAUT32.155]6838 */6839 HRESULT WINAPI VarMod(LPVARIANT pvarLeft, LPVARIANT pvarRight, LPVARIANT pvarResult)6840 {6841 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6842 return E_NOTIMPL;6843 }6844 6845 /**********************************************************************6846 * VarEqv [OLEAUT32.152]6847 *6848 * Determine if two variants contain the same value.6849 *6850 * PARAMS6851 * pVarLeft [I] First variant to compare6852 * pVarRight [I] Variant to compare to pVarLeft6853 * pVarOut [O] Destination for comparison result6854 *6855 * RETURNS6856 * Success: S_OK. pVarOut contains the result of the comparison (VARIANT_TRUE6857 * if equivalent or non-zero otherwise.6858 * Failure: An HRESULT error code indicating the error.6859 *6860 * NOTES6861 * - This function simply calls VarXor() on pVarLeft and pVarRight and inverts6862 * the result.6863 */6864 HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)6865 {6866 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6867 return E_NOTIMPL;6868 }6869 6870 6871 /**********************************************************************6872 * VarIdiv [OLEAUT32.153]6873 */6874 HRESULT WINAPI VarIdiv(LPVARIANT pvarLeft, LPVARIANT pvarRight, LPVARIANT pvarResult)6875 {6876 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6877 6878 return E_NOTIMPL;6879 }6880 6881 /**********************************************************************6882 * VarRound [OLEAUT32.175]6883 */6884 HRESULT VarRound(LPVARIANT pvarIn, INT cDecimals, LPVARIANT pvarResult)6885 {6886 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);6887 6888 return E_NOTIMPL;6889 }6890 6891 /**********************************************************************6892 * VarPow [OLEAUT32.158]6893 *6894 */6895 HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)6896 {6897 HRESULT hr;6898 VARIANT dl,dr;6899 6900 #if 06901 TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), debugstr_VF(left),6902 right, debugstr_VT(right), debugstr_VF(right), result);6903 #endif6904 6905 hr = VariantChangeType(&dl,left,0,VT_R8);6906 if (!SUCCEEDED(hr)) {6907 ERR("Could not change passed left argument to VT_R8, handle it differently.\n");6908 return E_FAIL;6909 }6910 hr = VariantChangeType(&dr,right,0,VT_R8);6911 if (!SUCCEEDED(hr)) {6912 ERR("Could not change passed right argument to VT_R8, handle it differently.\n");6913 return E_FAIL;6914 }6915 V_VT(result) = VT_R8;6916 V_R8(result) = pow(V_R8(&dl),V_R8(&dr));6917 return S_OK;6918 }6919 6920 /**********************************************************************6921 * VarAdd [OLEAUT32.141]6922 * FIXME: From MSDN: If ... Then6923 * Both expressions are of the string type Concatenated.6924 * One expression is a string type and the other a character Addition.6925 * One expression is numeric and the other is a string Addition.6926 * Both expressions are numeric Addition.6927 * Either expression is NULL NULL is returned.6928 * Both expressions are empty Integer subtype is returned.6929 *6930 */6931 HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)6932 {6933 HRESULT rc = E_FAIL;6934 6935 #if 06936 TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),6937 debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);6938 #endif6939 6940 if ((V_VT(left)&VT_TYPEMASK) == VT_EMPTY)6941 return VariantCopy(result,right);6942 6943 if ((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)6944 return VariantCopy(result,left);6945 6946 /* check if we add doubles */6947 if (((V_VT(left)&VT_TYPEMASK) == VT_R8) || ((V_VT(right)&VT_TYPEMASK) == VT_R8)) {6948 BOOL lOk = TRUE;6949 BOOL rOk = TRUE;6950 double lVal = -1;6951 double rVal = -1;6952 double res = -1;6953 6954 lOk = TRUE;6955 switch (V_VT(left)&VT_TYPEMASK) {6956 case VT_I1 : lVal = V_UNION(left,cVal); break;6957 case VT_I2 : lVal = V_UNION(left,iVal); break;6958 case VT_I4 : lVal = V_UNION(left,lVal); break;6959 case VT_INT : lVal = V_UNION(left,lVal); break;6960 case VT_UI1 : lVal = V_UNION(left,bVal); break;6961 case VT_UI2 : lVal = V_UNION(left,uiVal); break;6962 case VT_UI4 : lVal = V_UNION(left,ulVal); break;6963 case VT_UINT : lVal = V_UNION(left,ulVal); break;6964 case VT_R4 : lVal = V_UNION(left,fltVal); break;6965 case VT_R8 : lVal = V_UNION(left,dblVal); break;6966 case VT_NULL : lVal = 0.0; break;6967 default: lOk = FALSE;6968 }6969 6970 rOk = TRUE;6971 switch (V_VT(right)&VT_TYPEMASK) {6972 case VT_I1 : rVal = V_UNION(right,cVal); break;6973 case VT_I2 : rVal = V_UNION(right,iVal); break;6974 case VT_I4 : rVal = V_UNION(right,lVal); break;6975 case VT_INT : rVal = V_UNION(right,lVal); break;6976 case VT_UI1 : rVal = V_UNION(right,bVal); break;6977 case VT_UI2 : rVal = V_UNION(right,uiVal); break;6978 case VT_UI4 : rVal = V_UNION(right,ulVal); break;6979 case VT_UINT : rVal = V_UNION(right,ulVal); break;6980 case VT_R4 : rVal = V_UNION(right,fltVal);break;6981 case VT_R8 : rVal = V_UNION(right,dblVal);break;6982 case VT_NULL : rVal = 0.0; break;6983 default: rOk = FALSE;6984 }6985 6986 if (lOk && rOk) {6987 res = (lVal + rVal);6988 V_VT(result) = VT_R8;6989 V_UNION(result,dblVal) = res;6990 rc = S_OK;6991 } else {6992 FIXME("Unhandled type pair %d / %d in double addition.\n",6993 (V_VT(left)&VT_TYPEMASK),6994 (V_VT(right)&VT_TYPEMASK)6995 );6996 }6997 return rc;6998 }6999 7000 /* now check if we add floats. VT_R8 can no longer happen here! */7001 if (((V_VT(left)&VT_TYPEMASK) == VT_R4) || ((V_VT(right)&VT_TYPEMASK) == VT_R4)) {7002 BOOL lOk = TRUE;7003 BOOL rOk = TRUE;7004 float lVal = -1;7005 float rVal = -1;7006 float res = -1;7007 7008 lOk = TRUE;7009 switch (V_VT(left)&VT_TYPEMASK) {7010 case VT_I1 : lVal = V_UNION(left,cVal); break;7011 case VT_I2 : lVal = V_UNION(left,iVal); break;7012 case VT_I4 : lVal = V_UNION(left,lVal); break;7013 case VT_INT : lVal = V_UNION(left,lVal); break;7014 case VT_UI1 : lVal = V_UNION(left,bVal); break;7015 case VT_UI2 : lVal = V_UNION(left,uiVal); break;7016 case VT_UI4 : lVal = V_UNION(left,ulVal); break;7017 case VT_UINT : lVal = V_UNION(left,ulVal); break;7018 case VT_R4 : lVal = V_UNION(left,fltVal); break;7019 case VT_NULL : lVal = 0.0; break;7020 default: lOk = FALSE;7021 }7022 7023 rOk = TRUE;7024 switch (V_VT(right)&VT_TYPEMASK) {7025 case VT_I1 : rVal = V_UNION(right,cVal); break;7026 case VT_I2 : rVal = V_UNION(right,iVal); break;7027 case VT_I4 : rVal = V_UNION(right,lVal); break;7028 case VT_INT : rVal = V_UNION(right,lVal); break;7029 case VT_UI1 : rVal = V_UNION(right,bVal); break;7030 case VT_UI2 : rVal = V_UNION(right,uiVal); break;7031 case VT_UI4 : rVal = V_UNION(right,ulVal); break;7032 case VT_UINT : rVal = V_UNION(right,ulVal); break;7033 case VT_R4 : rVal = V_UNION(right,fltVal);break;7034 case VT_NULL : rVal = 0.0; break;7035 default: rOk = FALSE;7036 }7037 7038 if (lOk && rOk) {7039 res = (lVal + rVal);7040 V_VT(result) = VT_R4;7041 V_UNION(result,fltVal) = res;7042 rc = S_OK;7043 } else {7044 FIXME("Unhandled type pair %d / %d in float addition.\n",7045 (V_VT(left)&VT_TYPEMASK),7046 (V_VT(right)&VT_TYPEMASK)7047 );7048 }7049 return rc;7050 }7051 7052 /* Handle strings as concat */7053 if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&7054 (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {7055 V_VT(result) = VT_BSTR;7056 return VarBstrCat(V_BSTR(left), V_BSTR(right), &V_BSTR(result));7057 } else {7058 7059 /* Integers */7060 BOOL lOk = TRUE;7061 BOOL rOk = TRUE;7062 LONGLONG lVal = -1;7063 LONGLONG rVal = -1;7064 LONGLONG res = -1;7065 int resT = 0; /* Testing has shown I2 + I2 == I2, all else7066 becomes I4 */7067 7068 lOk = TRUE;7069 switch (V_VT(left)&VT_TYPEMASK) {7070 case VT_I1 : lVal = V_UNION(left,cVal); resT=VT_I4; break;7071 case VT_I2 : lVal = V_UNION(left,iVal); resT=VT_I2; break;7072 case VT_I4 : lVal = V_UNION(left,lVal); resT=VT_I4; break;7073 case VT_INT : lVal = V_UNION(left,lVal); resT=VT_I4; break;7074 case VT_UI1 : lVal = V_UNION(left,bVal); resT=VT_I4; break;7075 case VT_UI2 : lVal = V_UNION(left,uiVal); resT=VT_I4; break;7076 case VT_UI4 : lVal = V_UNION(left,ulVal); resT=VT_I4; break;7077 case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;7078 case VT_NULL : lVal = 0; resT = VT_I4; break;7079 default: lOk = FALSE;7080 }7081 7082 rOk = TRUE;7083 switch (V_VT(right)&VT_TYPEMASK) {7084 case VT_I1 : rVal = V_UNION(right,cVal); resT=VT_I4; break;7085 case VT_I2 : rVal = V_UNION(right,iVal); resT=max(VT_I2, resT); break;7086 case VT_I4 : rVal = V_UNION(right,lVal); resT=VT_I4; break;7087 case VT_INT : rVal = V_UNION(right,lVal); resT=VT_I4; break;7088 case VT_UI1 : rVal = V_UNION(right,bVal); resT=VT_I4; break;7089 case VT_UI2 : rVal = V_UNION(right,uiVal); resT=VT_I4; break;7090 case VT_UI4 : rVal = V_UNION(right,ulVal); resT=VT_I4; break;7091 case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;7092 case VT_NULL : rVal = 0; resT=VT_I4; break;7093 default: rOk = FALSE;7094 }7095 7096 if (lOk && rOk) {7097 res = (lVal + rVal);7098 V_VT(result) = resT;7099 switch (resT) {7100 case VT_I2 : V_UNION(result,iVal) = res; break;7101 case VT_I4 : V_UNION(result,lVal) = res; break;7102 default:7103 FIXME("Unexpected result variant type %x\n", resT);7104 V_UNION(result,lVal) = res;7105 }7106 rc = S_OK;7107 7108 } else {7109 FIXME("unimplemented part (0x%x + 0x%x)\n",V_VT(left), V_VT(right));7110 }7111 }7112 #if 07113 TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),7114 debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));7115 #endif7116 return rc;7117 }7118 7119 /**********************************************************************7120 * VarSub [OLEAUT32.159]7121 *7122 */7123 HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)7124 {7125 HRESULT rc = E_FAIL;7126 VARTYPE lvt,rvt,resvt;7127 VARIANT lv,rv;7128 BOOL found;7129 7130 #if 07131 TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),7132 debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);7133 #endif7134 7135 VariantInit(&lv);VariantInit(&rv);7136 lvt = V_VT(left)&VT_TYPEMASK;7137 rvt = V_VT(right)&VT_TYPEMASK;7138 found = FALSE;resvt = VT_VOID;7139 if (((1<<lvt) | (1<<rvt)) & ((1<<VT_DATE)|(1<<VT_R4)|(1<<VT_R8))) {7140 found = TRUE;7141 resvt = VT_R8;7142 }7143 if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {7144 found = TRUE;7145 resvt = VT_I4;7146 }7147 if (!found) {7148 FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);7149 return E_FAIL;7150 }7151 rc = VariantChangeType(&lv, left, 0, resvt);7152 if (FAILED(rc)) {7153 FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);7154 return rc;7155 }7156 rc = VariantChangeType(&rv, right, 0, resvt);7157 if (FAILED(rc)) {7158 FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);7159 return rc;7160 }7161 switch (resvt) {7162 case VT_R8:7163 V_VT(result) = resvt;7164 V_R8(result) = V_R8(&lv) - V_R8(&rv);7165 rc = S_OK;7166 break;7167 case VT_I4:7168 V_VT(result) = resvt;7169 V_I4(result) = V_I4(&lv) - V_I4(&rv);7170 rc = S_OK;7171 break;7172 }7173 #if 07174 TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),7175 debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));7176 #endif7177 return rc;7178 }7179 7180 7181 /**********************************************************************7182 * VarDiv [OLEAUT32.143]7183 *7184 */7185 HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)7186 {7187 HRESULT rc = E_FAIL;7188 VARTYPE lvt,rvt,resvt;7189 VARIANT lv,rv;7190 BOOL found;7191 7192 #if 07193 TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),7194 debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);7195 #endif7196 7197 VariantInit(&lv);VariantInit(&rv);7198 lvt = V_VT(left)&VT_TYPEMASK;7199 rvt = V_VT(right)&VT_TYPEMASK;7200 found = FALSE;resvt = VT_VOID;7201 if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {7202 found = TRUE;7203 resvt = VT_R8;7204 }7205 if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {7206 found = TRUE;7207 resvt = VT_I4;7208 }7209 if (!found) {7210 FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);7211 return E_FAIL;7212 }7213 rc = VariantChangeType(&lv, left, 0, resvt);7214 if (FAILED(rc)) {7215 FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);7216 return rc;7217 }7218 rc = VariantChangeType(&rv, right, 0, resvt);7219 if (FAILED(rc)) {7220 FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);7221 return rc;7222 }7223 switch (resvt) {7224 case VT_R8:7225 V_VT(result) = resvt;7226 V_R8(result) = V_R8(&lv) / V_R8(&rv);7227 rc = S_OK;7228 break;7229 case VT_I4:7230 V_VT(result) = resvt;7231 V_I4(result) = V_I4(&lv) / V_I4(&rv);7232 rc = S_OK;7233 break;7234 }7235 #if 07236 TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),7237 debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));7238 #endif7239 return rc;7240 }7241 7242 /**********************************************************************7243 * VarMul [OLEAUT32.156]7244 *7245 */7246 HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)7247 {7248 HRESULT rc = E_FAIL;7249 VARTYPE lvt,rvt,resvt;7250 VARIANT lv,rv;7251 BOOL found;7252 #if 07253 TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),7254 debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);7255 #endif7256 VariantInit(&lv);VariantInit(&rv);7257 lvt = V_VT(left)&VT_TYPEMASK;7258 rvt = V_VT(right)&VT_TYPEMASK;7259 found = FALSE;resvt=VT_VOID;7260 if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {7261 found = TRUE;7262 resvt = VT_R8;7263 }7264 if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {7265 found = TRUE;7266 resvt = VT_I4;7267 }7268 if (!found) {7269 FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);7270 return E_FAIL;7271 }7272 rc = VariantChangeType(&lv, left, 0, resvt);7273 if (FAILED(rc)) {7274 FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);7275 return rc;7276 }7277 rc = VariantChangeType(&rv, right, 0, resvt);7278 if (FAILED(rc)) {7279 FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);7280 return rc;7281 }7282 switch (resvt) {7283 case VT_R8:7284 V_VT(result) = resvt;7285 V_R8(result) = V_R8(&lv) * V_R8(&rv);7286 rc = S_OK;7287 break;7288 case VT_I4:7289 V_VT(result) = resvt;7290 V_I4(result) = V_I4(&lv) * V_I4(&rv);7291 rc = S_OK;7292 break;7293 }7294 #if 07295 TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),7296 debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));7297 #endif7298 5135 return rc; 7299 5136 } … … 7737 5574 return rc; 7738 5575 } 7739 7740 7741 /**********************************************************************7742 * VarDecAdd [OLEAUT32.177]7743 */7744 HRESULT WINAPI VarDecAdd(LPDECIMAL pdecLeft, LPDECIMAL pdecRight, LPDECIMAL pdecResult)7745 {7746 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7747 return E_NOTIMPL;7748 }7749 7750 /**********************************************************************7751 * VarDecSub [OLEAUT32.181]7752 */7753 HRESULT WINAPI VarDecSub(LPDECIMAL pdecLeft, LPDECIMAL pdecRight, LPDECIMAL pdecResult)7754 {7755 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7756 return E_NOTIMPL;7757 }7758 7759 /**********************************************************************7760 * VarDecMul [OLEAUT32.179]7761 */7762 HRESULT WINAPI VarDecMul(LPDECIMAL pdecLeft, LPDECIMAL pdecRight, LPDECIMAL pdecResult)7763 {7764 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7765 return E_NOTIMPL;7766 }7767 7768 /**********************************************************************7769 * VarDecRound [OLEAUT32.203]7770 */7771 HRESULT WINAPI VarDecRound(LPDECIMAL pdecIn, int iDecimals, LPDECIMAL pdecResult)7772 {7773 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7774 return E_NOTIMPL;7775 }7776 7777 /**********************************************************************7778 * VarDecDiv [OLEAUT32.178]7779 */7780 HRESULT WINAPI VarDecDiv(LPDECIMAL pdecLeft, LPDECIMAL pdecRight, LPDECIMAL pdecResult)7781 {7782 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7783 return E_NOTIMPL;7784 }7785 7786 /**********************************************************************7787 * VarDecCmp [OLEAUT32.204]7788 */7789 HRESULT WINAPI VarDecCmp(LPDECIMAL pdecLeft, LPDECIMAL pdecRight)7790 {7791 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7792 return E_NOTIMPL;7793 }7794 7795 /**********************************************************************7796 * VarDecAbs [OLEAUT32.182]7797 */7798 HRESULT WINAPI VarDecAbs(LPDECIMAL pdecIn, LPDECIMAL pdecResult)7799 {7800 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7801 return E_NOTIMPL;7802 }7803 7804 /**********************************************************************7805 * VarDecFix [OLEAUT32.187]7806 */7807 HRESULT WINAPI VarDecFix(LPDECIMAL pdecIn, LPDECIMAL pdecResult)7808 {7809 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7810 return E_NOTIMPL;7811 }7812 7813 /**********************************************************************7814 * VarDecInt [OLEAUT32.188]7815 */7816 HRESULT WINAPI VarDecInt(LPDECIMAL pdecIn, LPDECIMAL pdecResult)7817 {7818 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7819 return E_NOTIMPL;7820 }7821 7822 7823 /**********************************************************************7824 * VarDecNeg [OLEAUT32.189]7825 */7826 HRESULT WINAPI VarDecNeg(LPDECIMAL pdecIn, LPDECIMAL pdecResult)7827 {7828 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7829 return E_NOTIMPL;7830 }7831 7832 /**********************************************************************7833 * VarDecCmpR8 [OLEAUT32.298]7834 */7835 HRESULT WINAPI VarDecCmpR8(LPDECIMAL pdecLeft, LPDECIMAL pdecRight)7836 {7837 FIXME("%s: Not implemented! (returning E_NOTIMPL)", __FUNCTION__);7838 return E_NOTIMPL;7839 }7840 7841 /************************************************************************7842 * VarDecFromStr (OLEAUT32.197)7843 *7844 * Convert a VT_BSTR to a DECIMAL.7845 *7846 * PARAMS7847 * strIn [I] Source7848 * lcid [I] LCID for the conversion7849 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")7850 * pDecOut [O] Destination7851 *7852 * RETURNS7853 * Success: S_OK.7854 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination7855 */7856 HRESULT WINAPI VarDecFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DECIMAL* pDecOut)7857 {7858 TRACE("%s: now calling VARIANT_NumberFromBstr\n", __FUNCTION__);7859 return _VarDecFromStr(strIn, lcid, dwFlags, pDecOut);7860 }7861 -
trunk/src/pmkbdhk/makefile
r7185 r21308 7 7 # 8 8 9 NOPEHDR=1 9 10 10 11 # -
trunk/src/psapi/psapi.DEF
r2223 r21308 10 10 EmptyWorking = _EmptyWorkingSet@4 @1 11 11 EnumDeviceDrivers = _EnumDeviceDrivers@12 @2 12 EnumProcessModules = _ EnumProcessModules@16@312 EnumProcessModules = _PSAPI_EnumProcessModules@16 @3 13 13 EnumProcesses = _EnumProcesses@12 @4 14 14 GetDeviceDriverBaseNameA = _GetDeviceDriverBaseNameA@12 @5 … … 22 22 GetModuleFileNameExA = _GetModuleFileNameExA@16 @13 23 23 GetModuleFileNameExW = _GetModuleFileNameExW@16 @14 24 GetModuleInformation = _ GetModuleInformation@16@1524 GetModuleInformation = _PSAPI_GetModuleInformation@16 @15 25 25 GetProcessMemoryInfo = _GetProcessMemoryInfo@12 @16 26 26 GetWsChanges = _GetWsChanges@12 @17 -
trunk/src/psapi/psapi.cpp
r1710 r21308 56 56 } 57 57 58 #ifndef __WIN32OS2__ 58 59 /*********************************************************************** 59 60 * EnumProcessModules (PSAPI.4) … … 70 71 return TRUE; 71 72 } 73 #endif 72 74 73 75 /*********************************************************************** … … 191 193 } 192 194 195 #ifdef __WIN32OS2__ 193 196 /*********************************************************************** 194 197 * GetModuleFileNameExA (PSAPI.13) … … 197 200 HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize) 198 201 { 199 #ifdef DEBUG 200 dprintf(("PSAPI: GetModuleFileNameExA not implemented\n")); 201 #endif 202 if(hProcess != GetCurrentProcess()) { 203 dprintf(("PSAPI: GetModuleFileNameExA not implemented for other processes (%x %x)\n", hProcess, hModule)); 204 return 0; 205 } 206 return GetModuleFileNameA(hModule, lpFilename, nSize); 207 } 208 #else 209 /*********************************************************************** 210 * GetModuleFileNameExA (PSAPI.13) 211 */ 212 DWORD WINAPI GetModuleFileNameExA( 213 HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize) 214 { 202 215 if(lpFilename&&nSize) 203 216 lpFilename[0]='\0'; … … 205 218 return 0; 206 219 } 220 #endif 207 221 208 222 /*********************************************************************** … … 221 235 } 222 236 237 #ifndef __WIN32OS2__ 223 238 /*********************************************************************** 224 239 * GetModuleInformation (PSAPI.15) … … 234 249 return TRUE; 235 250 } 251 #endif 236 252 237 253 /*********************************************************************** -
trunk/src/riched32/charlist.c
r9407 r21308 32 32 33 33 WINE_DEFAULT_DEBUG_CHANNEL(richedit); 34 35 #ifdef __WIN32OS2__ /* no useful trace in this file! */ 36 #define TRACE(a) do {} while (0) 37 #endif 34 38 35 39 extern HANDLE RICHED32_hHeap; -
trunk/src/riched32/reader.c
r9407 r21308 80 80 81 81 WINE_DEFAULT_DEBUG_CHANNEL(richedit); 82 83 #ifdef __WIN32OS2__ /* no useful trace in this file! */ 84 #define TRACE(a) do {} while (0) 85 #endif 82 86 83 87 extern HANDLE RICHED32_hHeap; -
trunk/src/riched32/richedit.c
r9859 r21308 43 43 WINE_DEFAULT_DEBUG_CHANNEL(richedit); 44 44 45 #ifdef __WIN32OS2__ 46 /** custom build hack. */ 47 BOOL (* WINAPI pfnCustomRichedHack_EM_STREAMIN)(HWND, LPSTR) = NULL; 48 #endif 49 45 50 HANDLE RICHED32_hHeap = (HANDLE)NULL; 46 51 /* LPSTR RICHED32_aSubclass = (LPSTR)NULL; */ … … 198 203 { 199 204 RTFToBuffer(rtfBuffer, rtfBufferSize); 205 #ifdef __WIN32OS2__ 206 /* This is a very very ugly hack to work around some major parsing errors. */ 207 if (pfnCustomRichedHack_EM_STREAMIN) 208 pfnCustomRichedHack_EM_STREAMIN(hwnd, rtfBuffer); 209 else 210 #endif 200 211 SetWindowTextA(hwnd,rtfBuffer); 201 212 HeapFree(RICHED32_hHeap, 0,rtfBuffer); … … 843 854 return ret; 844 855 } 856 857 858 #ifdef __WIN32OS2__ 859 /** Enables a callback replacement for the SetWindowTextA call finalizing 860 * the handling of an EM_STREAMIN message. 861 * @remark don't use this hack. 862 */ 863 BOOL WINAPI ODIN_RichedHack_EM_STREAMIN(BOOL (* WINAPI pfn)(HWND, LPSTR)) 864 { 865 pfnCustomRichedHack_EM_STREAMIN = pfn; 866 return TRUE; 867 } 868 #endif 869 -
trunk/src/riched32/textwriter.c
r9410 r21308 45 45 46 46 WINE_DEFAULT_DEBUG_CHANNEL(richedit); 47 48 #ifdef __WIN32OS2__ /* no useful trace in this file! */ 49 #define TRACE(a) do {} while (0) 50 #endif 47 51 48 52 static void TextClass (); -
trunk/src/user32/Makefile
r21303 r21308 130 130 $(ODIN32_LIB)/libuls.lib \ 131 131 $(ODIN32_LIB)/$(ODINCRT).lib \ 132 $(ODIN32_LIB)/imm32os2.lib \ 132 133 OS2386.LIB \ 133 134 $(RTLLIB_O) -
trunk/src/user32/USER32.DEF
r21303 r21308 750 750 _clipboardPMToOdinFormat@4 @2043 NONAME 751 751 _clipboardOdinToPMFormat@4 @2044 NONAME 752 753 _GetOS2Icon@4 @2045 NONAME -
trunk/src/user32/edit.c
r21303 r21308 31 31 #include "ctrlconf.h" 32 32 #include <heapstring.h> 33 #include <imm.h> 33 34 #endif 34 35 … … 128 129 HLOCAL hloc32A; /* alias for ANSI control receiving EM_GETHANDLE 129 130 or EM_SETHANDLE */ 131 #ifdef __WIN32OS2__ 132 LPWSTR compStr; 133 INT compStrLen; 134 BOOL moveCaret; 135 DWORD sentenceMode; 136 #endif 130 137 } EDITSTATE; 131 138 … … 1113 1120 // always DBCS char 1114 1121 CHAR charA[ 2 ]; 1115 1122 INT lenA = 1; 1123 1124 if( IsDBCSLeadByte(( CHAR )( wParam >> 8 ))) 1125 { 1116 1126 charA[ 0 ] = ( CHAR )( wParam >> 8 ); 1117 1127 charA[ 1 ] = ( CHAR )wParam; 1118 1119 MultiByteToWideChar( CP_ACP, 0, ( LPSTR )charA, 2, ( LPWSTR )&charW, 1); 1128 lenA = 2; 1129 } 1130 else 1131 charA[ 0 ] = ( CHAR )wParam; 1132 1133 MultiByteToWideChar( CP_ACP, 0, ( LPSTR )charA, lenA, ( LPWSTR )&charW, 1); 1120 1134 } 1121 1135 … … 1123 1137 break; 1124 1138 } 1139 1140 case WM_IME_COMPOSITION: 1141 { 1142 HIMC himc; 1143 LONG bufSize; 1144 INT i; 1145 BOOL passToDefWnd = FALSE; 1146 #ifdef DEBUG 1147 LPSTR strA; 1148 INT lenA; 1149 #endif 1150 1151 DPRINTF_EDIT_MSG32("WM_IME_COMPOSITION"); 1152 1153 himc = ImmGetContext( hwnd ); 1154 1155 if( es->sentenceMode ) 1156 passToDefWnd = TRUE; 1157 else if( lParam & GCS_RESULTSTR ) 1158 { 1159 LPWSTR resultStr = NULL; 1160 INT resultStrLen = 0; 1161 1162 dprintf(("WM_IME_COMPOSITION : GCS_RESULTSTR")); 1163 1164 bufSize = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 ); 1165 if( bufSize > 0 ) 1166 { 1167 INT i; 1168 1169 resultStrLen = bufSize / sizeof( WCHAR ); 1170 resultStr = malloc( bufSize + sizeof( WCHAR )); 1171 resultStr[ resultStrLen ] = 0; 1172 1173 ImmGetCompositionStringW( himc, GCS_RESULTSTR, resultStr, bufSize ); 1174 1175 #ifdef DEBUG 1176 lenA = WideCharToMultiByte( CP_ACP, 0, resultStr, resultStrLen, 0, 0, 0, 0 ); 1177 strA = malloc( lenA + 1 ); 1178 WideCharToMultiByte( CP_ACP, 0, resultStr, resultStrLen, strA, lenA, 0, 0 ); 1179 strA[ lenA ] = 0; 1180 dprintf(("Result String : '%s'", strA )); 1181 free( strA ); 1182 dprintf(("Composition Len %d", es->compStrLen )); 1183 #endif 1184 DestroyCaret(); 1185 if( es->compStrLen > 0 ) 1186 { 1187 EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE); 1188 for( i = 0; i < es->compStrLen; i++ ) 1189 EDIT_MoveForward(hwnd, es, TRUE); 1190 EDIT_WM_Clear(hwnd, es); 1191 } 1192 1193 EDIT_EM_ReplaceSel(hwnd, es, TRUE, resultStr, TRUE); 1194 1195 CreateCaret(hwnd, 0, 2, es->line_height); 1196 EDIT_SetCaretPos(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP); 1197 ShowCaret(hwnd); 1198 1199 free( resultStr ); 1200 1201 } 1202 1203 if( es->compStr ) 1204 free( es->compStr ); 1205 1206 es->compStr = NULL; 1207 es->compStrLen = 0; 1208 } 1209 else if( lParam & GCS_COMPSTR ) 1210 { 1211 INT prevLen = es->compStrLen; 1212 1213 dprintf(("WM_IME_COMPOSITION : GCS_COMPSTR")); 1214 1215 if( es->compStr ) 1216 free( es->compStr ); 1217 1218 es->compStr = NULL; 1219 es->compStrLen = 0; 1220 1221 bufSize = ImmGetCompositionStringW( himc, GCS_COMPSTR, NULL, 0 ); 1222 if( bufSize > 0 ) 1223 { 1224 HDC hdc; 1225 SIZE size; 1226 BOOL oldMoveCaret; 1227 1228 es->compStrLen = bufSize / sizeof( WCHAR ); 1229 es->compStr = malloc( bufSize + sizeof( WCHAR )); 1230 es->compStr[ es->compStrLen ] = 0; 1231 1232 ImmGetCompositionStringW( himc, GCS_COMPSTR, es->compStr, bufSize ); 1233 1234 #ifdef DEBUG 1235 lenA = WideCharToMultiByte( CP_ACP, 0, es->compStr, es->compStrLen, 0, 0, 0, 0 ); 1236 strA = malloc( lenA + 1 ); 1237 WideCharToMultiByte( CP_ACP, 0, es->compStr, es->compStrLen, strA, lenA, 0, 0 ); 1238 strA[ lenA ] = 0; 1239 dprintf(("Composition String : '%s'", strA )); 1240 free( strA ); 1241 #endif 1242 hdc = GetDC( hwnd ); 1243 GetTextExtentPoint32W( hdc, es->compStr, es->compStrLen, &size); 1244 ReleaseDC( hwnd, hdc ); 1245 1246 oldMoveCaret = es->moveCaret; 1247 1248 es->moveCaret = FALSE; // to prevent cursor from flashing too many 1249 1250 if( prevLen > 0 ) 1251 { 1252 EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE); 1253 for( i = 0; i < prevLen; i++ ) 1254 EDIT_MoveForward(hwnd, es, TRUE); 1255 EDIT_WM_Clear(hwnd, es); 1256 } 1257 1258 EDIT_EM_ReplaceSel(hwnd, es, TRUE, es->compStr, TRUE); 1259 1260 for( i = 0; i < es->compStrLen; i++ ) 1261 EDIT_MoveBackward(hwnd, es, FALSE); 1262 1263 es->moveCaret = oldMoveCaret; 1264 1265 CreateCaret(hwnd, 0, size.cx, es->line_height); 1266 EDIT_SetCaretPos(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP); 1267 ShowCaret(hwnd); 1268 } 1269 } 1270 else 1271 passToDefWnd = TRUE; 1272 1273 ImmReleaseContext( hwnd, himc ); 1274 1275 if( passToDefWnd ) 1276 { 1277 if( unicode ) 1278 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1279 else 1280 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1281 } 1282 break; 1283 } 1284 1285 case WM_IME_COMPOSITIONFULL: 1286 DPRINTF_EDIT_MSG32("WM_IME_COMPOSITIONFULL"); 1287 if( unicode ) 1288 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1289 else 1290 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1291 break; 1292 1293 case WM_IME_CONTROL: 1294 DPRINTF_EDIT_MSG32("WM_IME_CONTROL"); 1295 if( unicode ) 1296 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1297 else 1298 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1299 break; 1300 1301 case WM_IME_ENDCOMPOSITION: 1302 DPRINTF_EDIT_MSG32("WM_IME_ENDCOMPOSITION"); 1303 1304 if( es->compStr ) 1305 { 1306 INT i; 1307 1308 DestroyCaret(); 1309 1310 EDIT_EM_SetSel(hwnd, es, (UINT)-1, 0, FALSE); 1311 for( i = 0; i < es->compStrLen; i++ ) 1312 EDIT_MoveForward(hwnd, es, TRUE); 1313 EDIT_WM_Clear(hwnd, es); 1314 1315 CreateCaret(hwnd, 0, 2, es->line_height); 1316 EDIT_SetCaretPos(hwnd, es, es->selection_end, es->flags & EF_AFTER_WRAP); 1317 ShowCaret(hwnd); 1318 1319 free( es->compStr ); 1320 } 1321 1322 es->compStr = NULL; 1323 es->compStrLen = 0; 1324 1325 if( unicode ) 1326 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1327 else 1328 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1329 break; 1330 1331 case WM_IME_NOTIFY: 1332 DPRINTF_EDIT_MSG32("WM_IME_NOTIFY"); 1333 1334 if( wParam == IMN_SETSENTENCEMODE ) 1335 { 1336 HIMC himc; 1337 DWORD conversionMode; 1338 1339 himc = ImmGetContext( hwnd ); 1340 1341 ImmGetConversionStatus( himc, &conversionMode, &es->sentenceMode ); 1342 1343 ImmReleaseContext( hwnd, himc ); 1344 } 1345 1346 if( unicode ) 1347 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1348 else 1349 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1350 break; 1351 1352 case WM_IME_REQUEST: 1353 DPRINTF_EDIT_MSG32("WM_IME_REQUEST"); 1354 if( unicode ) 1355 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1356 else 1357 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1358 break; 1359 1360 case WM_IME_SELECT: 1361 DPRINTF_EDIT_MSG32("WM_IME_SELECT"); 1362 if( unicode ) 1363 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1364 else 1365 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1366 break; 1367 1368 case WM_IME_SETCONTEXT: 1369 DPRINTF_EDIT_MSG32("WM_IME_SETCONTEXT"); 1370 1371 dprintf(("ImmGetProperty %08lx", ImmGetProperty( 0, IGP_CONVERSION ))); 1372 1373 if( unicode ) 1374 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1375 else 1376 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1377 break; 1378 1379 case WM_IME_STARTCOMPOSITION: 1380 DPRINTF_EDIT_MSG32("WM_IME_STARTCOMPOSITION"); 1381 1382 es->compStr = NULL; 1383 es->compStrLen = 0; 1384 1385 if( unicode ) 1386 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1387 else 1388 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1389 break; 1390 1391 case EM_GETIMESTATUS: 1392 DPRINTF_EDIT_MSG32("EM_GETIMESTATUS"); 1393 if( unicode ) 1394 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1395 else 1396 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1397 break; 1398 1399 case EM_SETIMESTATUS: 1400 DPRINTF_EDIT_MSG32("EM_SETIMESTATUS"); 1401 if( unicode ) 1402 result = DefWindowProcW( hwnd, msg, wParam, lParam ); 1403 else 1404 result = DefWindowProcA( hwnd, msg, wParam, lParam ); 1405 break; 1125 1406 #endif 1126 1407 … … 2440 2721 { 2441 2722 LRESULT res = EDIT_EM_PosFromChar(hwnd, es, pos, after_wrap); 2723 2724 #ifdef __WIN32OS2__ 2725 if( es->moveCaret ) 2726 { 2727 HIMC himc; 2728 CANDIDATEFORM candForm; 2729 2730 himc = ImmGetContext( hwnd ); 2731 2732 #endif 2733 2442 2734 SetCaretPos(SLOWORD(res), SHIWORD(res)); 2735 2736 #ifdef __WIN32OS2__ 2737 if( es->sentenceMode ) 2738 { 2739 COMPOSITIONFORM cf; 2740 2741 cf.dwStyle = CFS_POINT; 2742 cf.ptCurrentPos.x = SLOWORD( res ); 2743 cf.ptCurrentPos.y = SHIWORD( res ); 2744 2745 ImmSetCompositionWindow( himc, &cf ); 2746 } 2747 2748 candForm.dwIndex = 0; 2749 candForm.dwStyle = CFS_CANDIDATEPOS; 2750 candForm.ptCurrentPos.x = SLOWORD( res ); 2751 candForm.ptCurrentPos.y = SHIWORD( res ) + es->line_height; 2752 2753 ImmSetCandidateWindow( himc, &candForm ); 2754 2755 ImmReleaseContext( hwnd, himc ); 2756 } 2757 #endif 2443 2758 } 2444 2759 … … 4773 5088 } 4774 5089 5090 #ifdef __WIN32OS2__ 5091 es->compStr = NULL; 5092 es->compStrLen = 0; 5093 es->moveCaret = TRUE; 5094 { 5095 HIMC himc; 5096 DWORD conversionMode; 5097 5098 himc = ImmGetContext( hwnd ); 5099 5100 ImmGetConversionStatus( himc, &conversionMode, &es->sentenceMode ); 5101 5102 ImmReleaseContext( hwnd, himc ); 5103 } 5104 #endif 5105 4775 5106 return TRUE; 4776 5107 } … … 4904 5235 es->font = font; 4905 5236 dc = GetDC(hwnd); 5237 #ifdef __WIN32OS2__ 5238 // todo : set font of IME window 5239 #endif 4906 5240 if (font) 4907 5241 old_font = SelectObject(dc, font); -
trunk/src/user32/listbox.c
r21303 r21308 3028 3028 // always DBCS char 3029 3029 CHAR charA[ 2 ]; 3030 3030 INT lenA = 1; 3031 3032 if( IsDBCSLeadByte(( CHAR )( wParam >> 8 ))) 3033 { 3031 3034 charA[ 0 ] = ( CHAR )( wParam >> 8 ); 3032 3035 charA[ 1 ] = ( CHAR )wParam; 3033 3034 MultiByteToWideChar( CP_ACP, 0, ( LPSTR )charA, 2, ( LPWSTR )&charW, 1); 3036 lenA = 2; 3037 } 3038 else 3039 charA[ 0 ] = ( CHAR )wParam; 3040 3041 MultiByteToWideChar( CP_ACP, 0, ( LPSTR )charA, lenA, ( LPWSTR )&charW, 1); 3035 3042 } 3036 3043 return LISTBOX_HandleChar( hwnd, descr, charW ); -
trunk/src/user32/oslibmsgtranslate.cpp
r21303 r21308 15 15 * 16 16 */ 17 #define INCL_NLS 18 #define INCL_GPI 17 19 #define INCL_WIN 18 20 #define INCL_PM … … 42 44 #include "user32api.h" 43 45 46 #include <os2im.h> 47 #include <im32.h> 44 48 45 49 #define DBG_LOCALLOG DBG_oslibmsgtranslate … … 48 52 static BOOL fGenerateDoubleClick = FALSE; 49 53 static MSG doubleClickMsg = {0}; 54 55 extern UINT WINAPI GetACP(void); // from winnls.h 50 56 51 57 //For wheel mouse translation … … 753 759 if( scanCode != 0 ) 754 760 { 761 switch( SHORT2FROMMP( os2Msg->mp2 )) 762 { 763 // for Korean 764 case VK_DBE_HANJA : 765 bWinVKey = 0x19; 766 break; 767 768 case VK_DBE_HANGEUL : 769 bWinVKey = 0x15; 770 break; 771 772 case VK_DBE_JAMO : 773 bWinVKey = 0; 774 break; 775 776 // for Japan 777 case VK_DBE_KATAKANA : 778 bWinVKey = 0; 779 break; 780 781 case VK_DBE_HIRAGANA : 782 bWinVKey = 0; 783 break; 784 785 case VK_DBE_SBCSCHAR : 786 bWinVKey = 0; 787 break; 788 789 case VK_DBE_DBCSCHAR : 790 bWinVKey = 0; 791 break; 792 793 case VK_DBE_SBCSDBCSCHAR : 794 bWinVKey = 0; 795 break; 796 797 case VK_DBE_ROMAN : 798 bWinVKey = 0; 799 break; 800 801 // for PRC-Chinese 802 case VK_DBE_HANZI : 803 bWinVKey = 0; 804 break; 805 806 // for Taiwan 807 case VK_DBE_TSANGJYE : 808 bWinVKey = 0; 809 break; 810 811 case VK_DBE_PHONETIC : 812 bWinVKey = 0; 813 break; 814 815 case VK_DBE_CONV : 816 bWinVKey = 0; 817 break; 818 819 case VK_DBE_NOCONV : 820 bWinVKey = 0; 821 break; 822 823 case VK_DBE_ALPHANUMERIC : 824 switch( GetACP()) 825 { 826 case 949 : // Korea 827 case 1361 : 828 bWinVKey = 0x15; 829 break; 830 831 case 932 : // Japan 832 case 942 : 833 case 943 : 834 835 case 936 : // PRC 836 case 1381 : 837 838 case 950 : // Taiwan 839 default : 840 bWinVKey = 0; 841 } 842 break; 843 844 default : 755 845 KeyTranslatePMScanToWinVKey(usPMScanCode, 756 846 FALSE, … … 758 848 &wWinScan, 759 849 &fWinExtended); 850 } 851 760 852 winMsg->wParam = bWinVKey; 761 853 } … … 1079 1171 break; 1080 1172 1173 case WM_IMENOTIFY: 1174 dprintf(("WM_IMENOTIFY")); 1175 1176 winMsg->wParam = 0; 1177 winMsg->lParam = 0; 1178 1179 switch(( ULONG )os2Msg->mp1 ) 1180 { 1181 case IMN_STARTCONVERSION : 1182 winMsg->message = WM_IME_STARTCOMPOSITION_W; 1183 break; 1184 1185 case IMN_ENDCONVERSION : 1186 winMsg->message = WM_IME_ENDCOMPOSITION_W; 1187 break; 1188 1189 case IMN_CONVERSIONFULL : 1190 winMsg->message = WM_IME_COMPOSITIONFULL_W; 1191 break; 1192 1193 case IMN_IMECHANGED : 1194 winMsg->message = WM_IME_SELECT_W; 1195 // todo 1196 // fall through 1197 1198 default : 1199 goto dummymessage; 1200 1201 } 1202 break; 1203 1204 case WM_IMEREQUEST: 1205 winMsg->wParam = 0; 1206 winMsg->lParam = 0; 1207 1208 switch(( ULONG )os2Msg->mp1 ) 1209 { 1210 case IMR_INSTANCEACTIVATE : 1211 { 1212 USHORT usIMR_IA = LOUSHORT( os2Msg->mp2 ); 1213 1214 winMsg->message = WM_IME_SETCONTEXT_W; 1215 winMsg->wParam = HIUSHORT( os2Msg->mp2 ); 1216 1217 if( usIMR_IA & IMR_IA_STATUS ) 1218 winMsg->lParam |= ISC_SHOWUIGUIDELINE_W; 1219 1220 if( usIMR_IA & IMR_IA_CONVERSION ) 1221 winMsg->lParam |= ISC_SHOWUICOMPOSITIONWINDOW_W; 1222 1223 if( usIMR_IA & IMR_IA_CANDIDATE ) 1224 winMsg->lParam |= ISC_SHOWUIALLCANDIDATEWINDOW_W; 1225 1226 if( usIMR_IA & IMR_IA_INFOMSG ) 1227 winMsg->lParam |= 0; // todo 1228 1229 if( usIMR_IA & IMR_IA_REGWORD ) 1230 winMsg->lParam |= 0; // todo 1231 break; 1232 } 1233 1234 case IMR_STATUS : 1235 winMsg->message = WM_IME_NOTIFY_W; 1236 1237 switch(( ULONG )os2Msg->mp2 ) 1238 { 1239 case IMR_STATUS_SHOW : 1240 winMsg->wParam = IMN_OPENSTATUSWINDOW_W; 1241 break; 1242 1243 case IMR_STATUS_HIDE : 1244 winMsg->wParam = IMN_CLOSESTATUSWINDOW_W; 1245 break; 1246 1247 case IMR_STATUS_INPUTMODE : // IMN_SETOPENSTATUS followed by IMN_SETCONVERSIONMODE 1248 winMsg->wParam = IMN_SETOPENSTATUS_W; 1249 break; 1250 1251 case IMR_STATUS_CONVERSIONMODE : 1252 winMsg->wParam = IMN_SETSENTENCEMODE_W; 1253 break; 1254 1255 case IMR_STATUS_STATUSPOS : 1256 winMsg->wParam = IMN_SETSTATUSWINDOWPOS_W; 1257 break; 1258 1259 case IMR_STATUS_STRING : 1260 case IMR_STATUS_STRINGATTR : 1261 case IMR_STATUS_CURSORPOS : 1262 case IMR_STATUS_CURSORATTR : 1263 1264 default : 1265 // todo 1266 goto dummymessage; 1267 1268 } 1269 break; 1270 1271 case IMR_CONVRESULT : 1272 { 1273 ULONG ulIMR = ( ULONG )os2Msg->mp2; 1274 1275 winMsg->message = WM_IME_COMPOSITION_W; 1276 winMsg->wParam = 0; // todo : current DBCS char 1277 1278 if( ulIMR & IMR_CONV_CONVERSIONSTRING ) 1279 winMsg->lParam |= GCS_COMPSTR_W; 1280 1281 if( ulIMR & IMR_CONV_CONVERSIONATTR ) 1282 winMsg->lParam |= GCS_COMPATTR_W; 1283 1284 if( ulIMR & IMR_CONV_CONVERSIONCLAUSE ) 1285 winMsg->lParam |= GCS_COMPCLAUSE_W; 1286 1287 if( ulIMR & IMR_CONV_READINGSTRING ) 1288 winMsg->lParam |= GCS_COMPREADSTR_W; 1289 1290 if( ulIMR & IMR_CONV_READINGATTR ) 1291 winMsg->lParam |= GCS_COMPREADATTR_W; 1292 1293 if( ulIMR & IMR_CONV_READINGCLAUSE ) 1294 winMsg->lParam |= GCS_COMPREADCLAUSE_W; 1295 1296 if( ulIMR & IMR_CONV_CURSORPOS ) 1297 winMsg->lParam |= GCS_CURSORPOS_W; 1298 1299 if( ulIMR & IMR_CONV_CURSORATTR ) 1300 winMsg->lParam |= 0; // todo 1301 1302 if( ulIMR & IMR_CONV_CHANGESTART ) 1303 winMsg->lParam |= GCS_DELTASTART_W; 1304 1305 if( ulIMR & IMR_CONV_INSERTCHAR ) 1306 winMsg->lParam |= CS_INSERTCHAR_W; 1307 1308 if( ulIMR & IMR_CONV_NOMOVECARET ) 1309 winMsg->lParam |= CS_NOMOVECARET_W; 1310 1311 if( ulIMR & IMR_CONV_CONVERSIONFONT ) 1312 winMsg->lParam |= 0; // todo 1313 1314 if( ulIMR & IMR_CONV_CONVERSIONPOS ) 1315 winMsg->lParam |= 0; // todo 1316 1317 if( ulIMR & IMR_RESULT_RESULTSTRING ) 1318 winMsg->lParam = GCS_RESULTSTR_W; // clear all composition info 1319 1320 if( ulIMR & IMR_RESULT_RESULTATTR ) 1321 winMsg->lParam |= 0; // todo 1322 1323 if( ulIMR & IMR_RESULT_RESULTCLAUSE ) 1324 winMsg->lParam |= GCS_RESULTCLAUSE_W; 1325 1326 if( ulIMR & IMR_RESULT_READINGSTRING ) 1327 winMsg->lParam |= GCS_RESULTREADSTR_W; 1328 1329 if( ulIMR & IMR_RESULT_READINGATTR ) 1330 winMsg->lParam |= 0; // todo 1331 1332 if( ulIMR & IMR_RESULT_READINGCLAUSE ) 1333 winMsg->lParam |= GCS_RESULTREADCLAUSE_W; 1334 1335 if( ulIMR && ( winMsg->lParam == 0 )) 1336 goto dummymessage; 1337 break; 1338 } 1339 1340 case IMR_CANDIDATE : 1341 winMsg->message = WM_IME_NOTIFY_W; 1342 switch(( ULONG )os2Msg->mp2 ) 1343 { 1344 case IMR_CANDIDATE_SHOW : 1345 case IMR_CANDIDATE_HIDE : 1346 case IMR_CANDIDATE_SELECT : 1347 case IMR_CANDIDATE_CHANGE : 1348 case IMR_CANDIDATE_CANDIDATEPOS : 1349 default : 1350 // todo 1351 goto dummymessage; 1352 } 1353 break; 1354 1355 case IMR_INFOMSG : 1356 winMsg->message = WM_IME_NOTIFY_W; 1357 winMsg->wParam = IMN_GUIDELINE_W; 1358 break; 1359 1360 case IMR_REGWORD : 1361 goto dummymessage; 1362 1363 case IMR_IMECHANGE : 1364 winMsg->message = WM_IME_SELECT_W; 1365 // todo 1366 goto dummymessage; 1367 1368 case IMR_CONFIG : 1369 // todo 1370 goto dummymessage; 1371 1372 case IMR_DICTIONARY : 1373 // todo 1374 goto dummymessage; 1375 1376 case IMR_OTHERINFO : 1377 // todo 1378 goto dummymessage; 1379 } 1380 break; 1381 1382 #if 0 // application cannot receive this message 1383 case WM_IMECONTROL: 1384 #endif 1081 1385 case WM_INITMENU: 1082 1386 case WM_MENUSELECT: -
trunk/src/user32/pmwindow.cpp
r21303 r21308 61 61 #include "user32api.h" 62 62 #include <kbdhook.h> 63 #include <heapstring.h> 64 65 #include <os2im.h> 66 #include <im32.h> 63 67 64 68 #define DBG_LOCALLOG DBG_pmwindow … … 140 144 #endif 141 145 146 extern "C" ULONG OSLibImSetMsgQueueProperty( ULONG, ULONG ); 147 142 148 //****************************************************************************** 143 149 // Initialize PM; create hab, message queue and register special Win32 window classes … … 194 200 BOOL rc = WinSetCp(hmq, GetDisplayCodepage()); 195 201 dprintf(("InitPM: WinSetCP was %sOK", rc ? "" : "not ")); 202 203 /* IM instace is created per message queue, that is, thread */ 204 if( IsDBCSEnv()) 205 OSLibImSetMsgQueueProperty( hmq, MQP_INSTANCE_PERMQ ); 196 206 197 207 //CD polling window class … … 1004 1014 dprintf(("OS2: %s %x %x %x", (msg == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL", win32wnd->getWindowHandle(), mp1, mp2)); 1005 1015 win32wnd->DispatchMsgA(pWinMsg); 1016 break; 1017 1018 case WM_IMEREQUEST: 1019 case WM_IMECONTROL: 1020 case WM_IMENOTIFY: 1021 if( pWinMsg->message ) 1022 { 1023 win32wnd->DispatchMsgA( pWinMsg ); 1024 1025 if(( pWinMsg->message = WM_IME_NOTIFY_W ) && 1026 ( pWinMsg->wParam == IMN_SETOPENSTATUS_W )) 1027 { 1028 MSG m; 1029 1030 m.message = WM_IME_NOTIFY_W; 1031 m.wParam = IMN_SETCONVERSIONMODE_W; 1032 m.lParam = 0; 1033 1034 win32wnd->DispatchMsgA( &m ); 1035 } 1036 } 1037 else 1038 goto RunDefWndProc; 1006 1039 break; 1007 1040 … … 2210 2243 break; 2211 2244 2245 case WM_IMEREQUEST: 2246 case WM_IMECONTROL: 2247 case WM_IMENOTIFY: 2248 if( pWinMsg->message ) 2249 { 2250 dprintf(("Frame window received IME message")); 2251 win32wnd->DispatchMsgA( pWinMsg ); 2252 2253 if(( pWinMsg->message = WM_IME_NOTIFY_W ) && 2254 ( pWinMsg->wParam == IMN_SETOPENSTATUS_W )) 2255 { 2256 MSG m; 2257 2258 m.message = WM_IME_NOTIFY_W; 2259 m.wParam = IMN_SETCONVERSIONMODE_W; 2260 m.lParam = 0; 2261 2262 win32wnd->DispatchMsgA( &m ); 2263 } 2264 } 2265 else 2266 goto RunDefWndProc; 2267 break; 2268 2212 2269 #ifdef DEBUG 2213 2270 case WM_DDE_INITIATE: -
trunk/src/version/dbgwrap.cpp
r10296 r21308 15 15 #include <heapstring.h> 16 16 #include <version.h> 17 18 #define DBG_LOCALLOG DBG_trace 19 #include <dbglocal.h> 17 20 18 21 #define DBGWRAP_MODULE "VERSION" -
trunk/src/win16ldr/odin.c
r5979 r21308 1 #if ndef MSC61 #ifdef WATCOMC 2 2 #include <windows.h> 3 3 #else 4 4 #include "msc60win.h" 5 5 #endif 6 //#include <ddeml.h> 6 7 #include <stdlib.h> 7 8 #include <string.h> … … 19 20 HANDLE hModule = 0; 20 21 22 typedef void (FAR * PASCAL FUNC_SetPELdr)(LPCSTR); 23 24 #ifdef DDE_COMM 25 HDDEDATA CALLBACK MyDdeCallback(UINT wType, UINT wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2); 26 27 DWORD idInst = 0; 28 HSZ hszServer = 0, hszTopic = 0; 29 30 #define MSG_DDE_WILDCONNECT WM_USER+1 31 #define MSG_DDE_CONNECT WM_USER+2 32 #endif 21 33 22 34 //***************************************************************************************** … … 25 37 { 26 38 MSG msg; 39 FUNC_SetPELdr pfnSetPELdr; 40 char szPEPath[260]; 41 LPSTR tmp; 42 43 hDll = LoadLibrary("odindll.dll"); 44 if(hDll == 0) { 45 return 0; 46 } 47 48 pfnSetPELdr = (FUNC_SetPELdr)GetProcAddress(hDll, "SETPELDR"); 49 if(pfnSetPELdr == NULL) { 50 return 0; 51 } 52 //check if the caller specified the path of the PE loader; if so, pass 53 //it on to odindll 54 tmp = strstr(lpCmdLine, "/PELDR=["); 55 if(tmp) { 56 tmp += 8; //skip /peldr=[ 57 strcpy(szPEPath, tmp); 58 tmp = szPEPath; 59 60 while(*tmp != ']' && *tmp != 0) tmp++; 61 62 if(*tmp == ']') { 63 *tmp = 0; 64 pfnSetPELdr(szPEPath); 65 } 66 67 //now skip this parameter 68 tmp = strstr(lpCmdLine, "/PELDR=["); 69 while(*tmp != ']' && *tmp != 0) tmp++; 70 if(*tmp == ']') { 71 tmp++; 72 } 73 lpCmdLine = tmp; 74 } 27 75 28 76 if (!hPrevInstance) … … 32 80 if (!InitInstance(hInstance, nCmdShow)) 33 81 return (FALSE); 82 83 #ifdef DDE_COMM 84 if(DdeInitialize(&idInst, MyDdeCallback, APPCLASS_STANDARD, 0) != DMLERR_NO_ERROR) { 85 return FALSE; 86 } 87 hszServer = DdeCreateStringHandle(idInst, "Win16OdinServer", CP_WINANSI); 88 if(hszServer == 0) { 89 return FALSE; 90 } 91 hszTopic = DdeCreateStringHandle(idInst, "Win16Broadcast", CP_WINANSI); 92 if(hszTopic == 0) { 93 return FALSE; 94 } 95 if(DdeNameService(idInst, hszServer, 0, DNS_REGISTER) == 0) { 96 return FALSE; 97 } 98 #endif 34 99 35 100 while(*lpCmdLine == ' ') lpCmdLine++; … … 48 113 49 114 sprintf(errormsg, "WinExec %s failed with error %d", lpCmdLine, hModule); 50 MessageBox(hwnd, errormsg, " Ïnternal Error", MB_ICONHAND);115 MessageBox(hwnd, errormsg, "Internal Error", MB_ICONHAND); 51 116 DestroyWindow(hwnd); 52 117 } 53 118 119 #ifdef DDE_COMM 120 DdeNameService(idInst, hszServer, 0, DNS_UNREGISTER); 121 DdeFreeStringHandle(idInst, hszServer); 122 DdeFreeStringHandle(idInst, hszTopic); 123 DdeUninitialize(idInst); 124 #endif 54 125 FreeLibrary(hDll); 55 126 return (msg.wParam); … … 60 131 { 61 132 WNDCLASS wc; 62 63 hDll = LoadLibrary("odindll.dll");64 if(hDll == 0) {65 return 0;66 }67 133 68 134 wc.style = NULL; … … 88 154 "Win16OdinClass", 89 155 "Odin Win16 Program Launcher", 156 #if 1 157 WS_POPUP, 158 #else 90 159 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 160 #endif 91 161 CW_USEDEFAULT, 92 162 CW_USEDEFAULT, … … 127 197 break; 128 198 199 #ifdef DDE_COMM 200 case MSG_DDE_WILDCONNECT: 201 break; 202 case MSG_DDE_CONNECT: 203 MessageBox(0, "MyDdeCallback", "WILDCONNECT", MB_OK); 204 break; 205 #endif 129 206 default: 130 207 return (DefWindowProc(hWnd, message, wParam, lParam)); … … 132 209 return (NULL); 133 210 } 134 //***************************************************************************************** 135 //***************************************************************************************** 211 #ifdef DDE_COMM 212 //***************************************************************************************** 213 //***************************************************************************************** 214 HDDEDATA CALLBACK MyDdeCallback(UINT wType, UINT wFmt, HCONV hConv, 215 HSZ hszTopic, HSZ hszItem, 216 HDDEDATA hData, DWORD dwData1, DWORD dwData2) 217 { 218 // WORD i, j; 219 // WORD cItems, iFmt; 220 // HDDEDATA hDataRet; 221 222 char msg[128]; 223 224 //// MessageBeep(500); 225 // sprintf(msg, "type=%x format=%x %x %x %x %x %x %x", wType, wFmt, hConv, hszTopic, hszItem, hData, dwData1, dwData2); 226 // MessageBox(0, "MyDdeCallback", "test", MB_OK); 227 228 if(wType == XTYP_EXECUTE && wFmt == CF_TEXT) 229 { 230 char szExec[64]; 231 232 DdeGetData(hData, (LPBYTE)szExec, 64, 0); 233 szExec[63] = 0; 234 MessageBox(0, "MyDdeCallback", szExec, MB_OK); 235 return (HDDEDATA)TRUE; 236 } 237 /* 238 * Process wild initiates here 239 */ 240 if (wType == XTYP_WILDCONNECT) { 241 HSZ ahsz[(1 + 1) * 2]; 242 /* 243 * He wants a hsz list of all our available app/topic pairs 244 * that conform to hszTopic and hszItem(App). 245 */ 246 247 // MessageBox(0, "MyDdeCallback", "WILDCONNECT", MB_OK); 248 249 // if (!ValidateContext((PCONVCONTEXT)lData1)) { 250 // return(FALSE); 251 // } 252 253 if (hszItem != hszServer && hszItem != 0) { 254 // we only support the hszAppName service 255 return(0); 256 } 257 258 ahsz[0] = hszServer; 259 ahsz[1] = hszTopic; 260 // cap off the list with 0s 261 ahsz[2] = ahsz[3] = 0L; 262 263 // send it back 264 return(DdeCreateDataHandle(idInst, (LPBYTE)&ahsz[0], sizeof(HSZ) * 4, 0L, 0, wFmt, 0)); 265 } 266 return 0; 267 } 268 //***************************************************************************************** 269 //***************************************************************************************** 270 #endif -
trunk/src/win16ldr/odindll.c
r5979 r21308 1 #ifndef MSC62 1 #include <windows.h> 3 #else4 #include "msc60win.h"5 #endif6 2 #include <string.h> 3 #include <stdlib.h> 4 #include <stdio.h> 7 5 #include "peexe.h" 8 6 … … 10 8 UINT FAR _loadds PASCAL MyWinExec(LPCSTR lpszCmdLine, UINT fuShowCmd); 11 9 10 BOOL FAR _loadds PASCAL MyPostMessage(HWND, UINT, WPARAM, LPARAM); 11 LRESULT FAR _loadds PASCAL MySendMessage(HWND, UINT, WPARAM, LPARAM); 12 12 13 BOOL GetPEFileHeader (LPVOID lpFile, PIMAGE_FILE_HEADER pHeader); 13 14 BOOL GetPEOptionalHeader (LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader); 14 15 15 #if defined(__WATCOMC__) 16 typedef DWORD (FAR * WINAPI * FUNC_GetVersion)(void); 17 typedef UINT (FAR * WINAPI * FUNC_WinExec)(LPCSTR, UINT); 18 #else 19 typedef DWORD (FAR * WINAPI FUNC_GetVersion)(void); 20 typedef UINT (FAR * WINAPI FUNC_WinExec)(LPCSTR, UINT); 21 #endif 16 typedef DWORD (FAR * PASCAL FUNC_GetVersion)(void); 17 typedef UINT (FAR * PASCAL FUNC_WinExec)(LPCSTR, UINT); 18 #ifdef PATCH_POSTSENDMSG 19 typedef BOOL (FAR * PASCAL FUNC_PostMessage)(HWND, UINT, WPARAM, LPARAM); 20 typedef LRESULT (FAR * PASCAL FUNC_SendMessage)(HWND, UINT, WPARAM, LPARAM); 21 #endif 22 23 BYTE oldcodeEXEC; 24 DWORD olddataEXEC; 25 UINT selEXEC; 26 BYTE FAR *jumpEXEC; 22 27 23 28 BYTE oldcodeVER; 24 29 DWORD olddataVER; 25 30 UINT selVER; 26 BYTE oldcodeEXEC;27 DWORD olddataEXEC;28 UINT selEXEC;29 31 BYTE FAR *jumpVER; 30 BYTE FAR *jumpEXEC; 32 33 #ifdef PATCH_POSTSENDMSG 34 BYTE oldcodeSEND; 35 DWORD olddataSEND; 36 UINT selSEND; 37 BYTE FAR *jumpSEND; 38 39 BYTE oldcodePOST; 40 DWORD olddataPOST; 41 UINT selPOST; 42 BYTE FAR *jumpPOST; 43 #endif 31 44 32 45 BOOL fUnloaded = FALSE; … … 35 48 char szPEPath[256] = {0}; 36 49 50 FUNC_GetVersion orggetver = NULL; 51 FUNC_WinExec orgwinexec = NULL; 52 #ifdef PATCH_POSTSENDMSG 53 FUNC_SendMessage orgsendmsg = NULL; 54 FUNC_PostMessage orgpostmsg = NULL; 55 #endif 56 37 57 //***************************************************************************************** 38 58 //***************************************************************************************** 39 59 int FAR _loadds CALLBACK LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeap, LPSTR lpszCmdLine) 40 60 { 41 FUNC_GetVersion getver;42 FUNC_WinExec winexec;43 61 DWORD FAR *addr; 44 62 45 if (fInit == FALSE) { 63 if(fInit == FALSE) 64 { 46 65 fInit = TRUE; 47 66 48 GetProfileString("Odin", "PEPath", "PE.EXE", szPEPath, sizeof(szPEPath)); 49 getver = (FUNC_GetVersion)&GetVersion; 67 GetProfileString("PELDR", "LdrPath", "PE.EXE", szPEPath, sizeof(szPEPath)); 68 69 orggetver = (FUNC_GetVersion)GetVersion; 50 70 selVER = AllocSelector(0); 51 PrestoChangoSelector(SELECTOROF( getver), selVER);52 53 jumpVER = MAKELP(selVER, OFFSETOF( getver));71 PrestoChangoSelector(SELECTOROF(orggetver), selVER); 72 73 jumpVER = MAKELP(selVER, OFFSETOF(orggetver)); 54 74 addr = (DWORD FAR *)(jumpVER+1); 55 75 oldcodeVER = *jumpVER; 56 76 olddataVER = *addr; 57 77 *jumpVER = 0xEA; //jmp 58 *addr = (DWORD) &MyGetVersion;59 60 winexec = (FUNC_WinExec)&WinExec;78 *addr = (DWORD)MyGetVersion; 79 80 orgwinexec = (FUNC_WinExec)WinExec; 61 81 selEXEC = AllocSelector(0); 62 PrestoChangoSelector(SELECTOROF( winexec), selEXEC);63 64 jumpEXEC = MAKELP(selEXEC, OFFSETOF( winexec));82 PrestoChangoSelector(SELECTOROF(orgwinexec), selEXEC); 83 84 jumpEXEC = MAKELP(selEXEC, OFFSETOF(orgwinexec)); 65 85 addr = (DWORD FAR *)(jumpEXEC+1); 66 86 oldcodeEXEC = *jumpEXEC; 67 87 olddataEXEC = *addr; 68 88 *jumpEXEC = 0xEA; //jmp 69 *addr = (DWORD)&MyWinExec; 89 *addr = (DWORD)MyWinExec; 90 91 #ifdef PATCH_POSTSENDMSG 92 orgsendmsg = (FUNC_SendMessage)SendMessage; 93 selSEND = AllocSelector(0); 94 PrestoChangoSelector(SELECTOROF(orgsendmsg), selSEND); 95 96 jumpSEND = MAKELP(selSEND, OFFSETOF(orgsendmsg)); 97 addr = (DWORD FAR *)(jumpSEND+1); 98 oldcodeSEND = *jumpSEND; 99 olddataSEND = *addr; 100 *jumpSEND = 0xEA; //jmp 101 *addr = (DWORD)MySendMessage; 102 103 orgpostmsg = (FUNC_PostMessage)PostMessage; 104 selPOST = AllocSelector(0); 105 PrestoChangoSelector(SELECTOROF(orgpostmsg), selPOST); 106 107 jumpPOST = MAKELP(selPOST, OFFSETOF(orgpostmsg)); 108 addr = (DWORD FAR *)(jumpPOST+1); 109 oldcodePOST = *jumpPOST; 110 olddataPOST = *addr; 111 *jumpPOST = 0xEA; //jmp 112 *addr = (DWORD)MyPostMessage; 113 #endif 70 114 } 71 115 return 1; … … 89 133 *jumpEXEC = oldcodeEXEC; 90 134 *addr = olddataEXEC; 135 136 #ifdef PATCH_POSTSENDMSG 137 addr = (DWORD FAR *)(jumpSEND + 1); 138 *jumpSEND = oldcodeSEND; 139 *addr = olddataSEND; 140 141 addr = (DWORD FAR *)(jumpPOST + 1); 142 *jumpPOST = oldcodePOST; 143 *addr = olddataPOST; 144 #endif 91 145 } 92 146 return 1; … … 97 151 { 98 152 return 0x00005F0C; 153 } 154 #ifdef PATCH_POSTSENDMSG 155 //***************************************************************************************** 156 //***************************************************************************************** 157 BOOL FAR _loadds PASCAL MyPostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) 158 { 159 DWORD FAR *addr; 160 BOOL ret; 161 char buffer[64]; 162 163 addr = (DWORD FAR *)(jumpPOST + 1); 164 *jumpPOST = oldcodePOST; 165 *addr = olddataPOST; 166 167 #ifdef DEBUG 168 if(hwnd == HWND_BROADCAST) { 169 sprintf(buffer, "Broadcast %x %lx %lx", Msg, wParam, lParam); 170 MessageBox(0, "PostMessage", buffer, MB_OK); 171 } 172 #endif 173 ret = PostMessage(hwnd, Msg, wParam, lParam); 174 175 *jumpPOST = 0xEA; //jmp 176 *addr = (DWORD)&MyPostMessage; 177 178 return ret; 179 } 180 //***************************************************************************************** 181 //***************************************************************************************** 182 LRESULT FAR _loadds PASCAL MySendMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) 183 { 184 DWORD FAR *addr; 185 BOOL ret; 186 char buffer[64]; 187 188 addr = (DWORD FAR *)(jumpSEND + 1); 189 *jumpSEND = oldcodeSEND; 190 *addr = olddataSEND; 191 192 #ifdef DEBUG 193 if(hwnd == HWND_BROADCAST) { 194 sprintf(buffer, "Broadcast %x %lx %lx", Msg, wParam, lParam); 195 MessageBox(0, "SendMessage", buffer, MB_OK); 196 } 197 #endif 198 ret = SendMessage(hwnd, Msg, wParam, lParam); 199 200 *jumpSEND = 0xEA; //jmp 201 *addr = (DWORD)&MySendMessage; 202 203 return ret; 204 } 205 #endif 206 //***************************************************************************************** 207 //***************************************************************************************** 208 void FAR _loadds PASCAL SetPELdr(LPCSTR lpszPELdr) 209 { 210 strcpy(szPEPath, lpszPELdr); 99 211 } 100 212 //***************************************************************************************** … … 116 228 BOOL fFail = TRUE; 117 229 230 if(szPEPath[0] == 0) goto calloldfunc; 231 118 232 of.cBytes = sizeof(OFSTRUCT); 119 233 … … 124 238 strcpy(cmdline, lpszCmdLine); 125 239 240 //isolate path of executable 126 241 while(*cmdline == ' ') cmdline++; 127 242 tmp = cmdline; 128 243 while(*tmp != ' ' && *tmp != 0) tmp++; 129 tmp++;130 244 *tmp = 0; 131 245 246 //open it to check the executable type; we only care about PE (win32) executables 247 //we'll let the original WinExec function handle everything else 132 248 hFile = OpenFile(cmdline, &of, OF_READ); 133 249 bytesRead = _lread(hFile, &doshdr, sizeof(doshdr)); … … 163 279 } 164 280 281 //Ok, it's a PE executable. Use the PE loader to launch it 165 282 tmp = cmdline; 166 283 hMem4 = hMem1; … … 194 311 _lclose(hFile); 195 312 313 //restore original WinExec entrypoint 196 314 addr = (DWORD FAR *)(jumpEXEC + 1); 197 315 *jumpEXEC = oldcodeEXEC; 198 316 *addr = olddataEXEC; 199 317 318 //and call it 200 319 if(fFail) { 320 //non-PE executable 201 321 ret = WinExec(lpszCmdLine, fuShowCmd); 202 322 } 203 323 else { 324 //PE executable 204 325 ret = WinExec(cmdline, fuShowCmd); 205 326 if(ret >= 32) { … … 216 337 } 217 338 339 //put back our WinExec override 218 340 *jumpEXEC = 0xEA; //jmp 219 341 *addr = (DWORD)&MyWinExec; -
trunk/src/win16ldr/odindll.def
r5954 r21308 17 17 MYGETVERSION @1 18 18 MYWINEXEC @2 19 SETPELDR @3 -
trunk/src/ws2_32/ws2_32.def
r9836 r21308 16 16 ; WS2HELP.dll 17 17 18 accept = WSOCK32.119 bind = WSOCK32.220 closesocket = WSOCK32.321 connect = WSOCK32.422 gethostbyaddr = WSOCK32.5123 gethostbyname = WSOCK32.5224 gethostname = WSOCK32.5725 getpeername = WSOCK32.526 getprotobyname = WSOCK32.5327 getprotobynumber = WSOCK32.5428 getservbyname = WSOCK32.5529 getservbyport = WSOCK32.5630 getsockname = WSOCK32.631 htonl = WSOCK32.832 htons = WSOCK32.933 inet_addr = WSOCK32.1034 inet_ntoa = WSOCK32.1135 ioctlsocket = WSOCK32.1236 listen = WSOCK32.1337 ntohl = WSOCK32.1438 ntohs = WSOCK32.1539 recv = WSOCK32.1640 recvfrom = WSOCK32.1741 select = WSOCK32.1842 send = WSOCK32.1943 sendto = WSOCK32.2044 shutdown = WSOCK32.2245 socket = WSOCK32.2346 WSAEventSelect = WSOCK32.300147 WSAEnumNetworkEvents = WSOCK32.300248 18 49 19 EXPORTS 50 accept@151 bind@252 closesocket@353 connect@454 getpeername@555 getsockname@620 accept = _accept@12 @1 21 bind = _bind@12 @2 22 closesocket = _closesocket@4 @3 23 connect = _connect@12 @4 24 getpeername = _getpeername@12 @5 25 getsockname = _getsockname@12 @6 56 26 getsockopt = _WS2getsockopt@20 @7 57 htonl@858 htons@959 ioctlsocket@1060 inet_addr@1161 inet_ntoa@1262 listen@1363 ntohl@1464 ntohs@1565 recv@1666 recvfrom@1767 select@1868 send@1969 sendto@2027 htonl = _htonl@4 @8 28 htons = _htons@4 @9 29 ioctlsocket = _ioctlsocket@12 @10 30 inet_addr = _inet_addr@4 @11 31 inet_ntoa = _inet_ntoa@4 @12 32 listen = _listen@8 @13 33 ntohl = _ntohl@4 @14 34 ntohs = _ntohs@4 @15 35 recv = _recv@16 @16 36 recvfrom = _recvfrom@24 @17 37 select = _select@20 @18 38 send = _send@16 @19 39 sendto = _sendto@24 @20 70 40 setsockopt = _WS2setsockopt@20 @21 71 shutdown@2272 socket@2341 shutdown = _shutdown@8 @22 42 socket = _socket@12 @23 73 43 74 44 ; WSApSetPostRoutine @24 … … 85 55 ; WSAEnumNameSpaceProvidersA @34 86 56 ; WSAEnumNameSpaceProvidersW @35 87 WSAEnumNetworkEvents 57 WSAEnumNetworkEvents = _WSAEnumNetworkEvents@12 @36 88 58 WSAEnumProtocolsA = _WSAEnumProtocolsA@12 @37 89 59 WSAEnumProtocolsW = _WSAEnumProtocolsW@12 @38 90 WSAEventSelect @39 60 WSAEventSelect = _WSAEventSelect@12 @39 61 91 62 ; WSAGetOverlappedResult @40 92 63 ; WSAGetQOSByName @41 … … 101 72 WSAIoctl = _WSAIoctl@36 @50 102 73 103 gethostbyaddr @51104 gethostbyname @52105 gethostname @57106 getprotobyname @53107 getprotobynumber 108 getservbyname @55109 getservbyport @5674 gethostbyaddr = _gethostbyaddr@12 @51 75 gethostbyname = _gethostbyname@4 @52 76 gethostname = _gethostname@8 @57 77 getprotobyname = _getprotobyname@4 @53 78 getprotobynumber = _getprotobynumber@4 @54 79 getservbyname = _getservbyname@8 @55 80 getservbyport = _getservbyport@8 @56 110 81 111 82 ; WSAJoinLeaf @58 -
trunk/src/wsock32/makefile
r10222 r21308 46 46 $(ODIN32_LIB)/user32.lib \ 47 47 $(ODIN32_LIB)/libwrap.lib \ 48 $(ODIN32_LIB)/iphlpapi.lib \49 48 $(ODIN32_LIB)/$(ODINCRT).lib \ 50 49 so32dll.lib \ -
trunk/src/wsock32/wsock32.cpp
r9887 r21308 55 55 #include <winuser32.h> 56 56 #include <wprocess.h> 57 #include <misc.h> 57 #include <dbglog.h> 58 59 #include <sys/types.h> 60 #include <sys/socket.h> 61 #include <net/if.h> 58 62 59 63 #include "wsock32.h" … … 212 216 strcpy(msg, "WSAEHOSTUNREACH"); 213 217 break; 218 case WSAETIMEDOUT: 219 strcpy(msg, "WSAETIMEDOUT"); 220 break; 214 221 default: 215 222 strcpy(msg, "unknown"); … … 663 670 664 671 if(ret == SOCKET_ERROR) { 665 WSASetLastError(wsaErrno()); 666 return SOCKET_ERROR; 672 if(wsaErrno() == WSAEWOULDBLOCK) { 673 struct timeval tv; 674 int optlen = sizeof(tv); 675 ret = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, &optlen); 676 if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) { 677 dprintf(("WSAEWOULDBLOCK: recv timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec)); 678 WSASetLastError(WSAETIMEDOUT); 679 } 680 else WSASetLastError(WSAEWOULDBLOCK); 681 ret = SOCKET_ERROR; 682 } 683 else WSASetLastError(wsaErrno()); 667 684 } 668 685 else … … 684 701 else 685 702 if(state & SS_ISCONNECTED && flags != MSG_PEEK) { 686 dprintf(("recv returned 0, but socket is still connected -> return WSA WOULDBLOCK"));703 dprintf(("recv returned 0, but socket is still connected -> return WSAEWOULDBLOCK")); 687 704 WSASetLastError(WSAEWOULDBLOCK); 688 705 return SOCKET_ERROR; … … 699 716 } 700 717 701 //Reset FD_READ event flag forWSAAsyncSelect thread if one was created for this socket718 //Reset FD_READ event flag for WSAAsyncSelect thread if one was created for this socket 702 719 EnableAsyncEvent(s, FD_READ); 703 720 return ret; … … 732 749 733 750 if(ret == SOCKET_ERROR) { 734 WSASetLastError(wsaErrno()); 751 if(wsaErrno() == WSAEWOULDBLOCK) { 752 struct timeval tv; 753 int optlen = sizeof(tv); 754 ret = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, &optlen); 755 if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) { 756 dprintf(("WSAEWOULDBLOCK: recvfrom timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec)); 757 WSASetLastError(WSAETIMEDOUT); 758 } 759 else WSASetLastError(WSAEWOULDBLOCK); 760 ret = SOCKET_ERROR; 761 } 762 else WSASetLastError(wsaErrno()); 735 763 } 736 764 else { … … 789 817 790 818 if(ret == SOCKET_ERROR) { 791 WSASetLastError(wsaErrno()); 819 if(wsaErrno() == WSAEWOULDBLOCK) { 820 struct timeval tv; 821 int optlen = sizeof(tv); 822 ret = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, &optlen); 823 if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) { 824 dprintf(("WSAEWOULDBLOCK: send timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec)); 825 WSASetLastError(WSAETIMEDOUT); 826 } 827 else WSASetLastError(WSAEWOULDBLOCK); 828 ret = SOCKET_ERROR; 829 } 830 else WSASetLastError(wsaErrno()); 792 831 } 793 832 else WSASetLastError(NO_ERROR); … … 844 883 845 884 if(ret == SOCKET_ERROR) { 846 WSASetLastError(wsaErrno()); 885 if(wsaErrno() == WSAEWOULDBLOCK) { 886 struct timeval tv; 887 int optlen = sizeof(tv); 888 ret = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, &optlen); 889 if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) { 890 dprintf(("WSAEWOULDBLOCK: sendto timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec)); 891 WSASetLastError(WSAETIMEDOUT); 892 } 893 else WSASetLastError(WSAEWOULDBLOCK); 894 ret = SOCKET_ERROR; 895 } 896 else WSASetLastError(wsaErrno()); 847 897 } 848 898 else WSASetLastError(NO_ERROR); … … 906 956 907 957 sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept)); 908 if(readfds ) {958 if(readfds && nrread) { 909 959 memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET)); 910 960 } 911 if(writefds ) {961 if(writefds && nrwrite) { 912 962 memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET)); 913 963 } 914 if(exceptfds ) {964 if(exceptfds && nrexcept) { 915 965 memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET)); 916 966 } … … 940 990 for(i=0;i<nrread;i++) { 941 991 if(socktmp[i] != -1) { 942 readfds->fd_array[i] = socktmp[i]; 992 readfds->fd_array[j] = socktmp[i]; 993 dprintf(("Socket %d read pending", socktmp[i])); 943 994 j++; 944 995 } … … 952 1003 for(i=0;i<nrwrite;i++) { 953 1004 if(socktmp[i] != -1) { 954 writefds->fd_array[i] = socktmp[i]; 1005 writefds->fd_array[j] = socktmp[i]; 1006 dprintf(("Socket %d write pending", socktmp[i])); 955 1007 j++; 956 1008 } … … 963 1015 for(i=0;i<nrexcept;i++) { 964 1016 if(socktmp[i] != -1) { 965 exceptfds->fd_array[ i] = socktmp[i];1017 exceptfds->fd_array[j] = socktmp[i]; 966 1018 j++; 967 1019 } … … 984 1036 return ret; 985 1037 } 1038 #ifdef DEBUG_LOGGING 1039 //****************************************************************************** 1040 //****************************************************************************** 1041 char *debugsockopt(int optname) 1042 { 1043 switch(optname) { 1044 case SO_DONTLINGER: 1045 return "SO_DONTLINGER"; 1046 case SO_LINGER: 1047 return "SO_LINGER"; 1048 case SO_REUSEADDR: 1049 return "SO_REUSEADDR"; 1050 case SO_SNDTIMEO: 1051 return "SO_SNDTIMEO"; 1052 case SO_RCVTIMEO: 1053 return "SO_RCVTIMEO"; 1054 case SO_SNDBUF: 1055 return "SO_SNDBUF"; 1056 case SO_RCVBUF: 1057 return "SO_RCVBUF"; 1058 case SO_BROADCAST: 1059 return "SO_BROADCAST"; 1060 case SO_DEBUG: 1061 return "SO_DEBUG"; 1062 case SO_KEEPALIVE: 1063 return "SO_KEEPALIVE"; 1064 case SO_DONTROUTE: 1065 return "SO_DONTROUTE"; 1066 case SO_OOBINLINE: 1067 return "SO_OOBINLINE"; 1068 case SO_TYPE: 1069 return "SO_TYPE"; 1070 case SO_ERROR: 1071 return "SO_ERROR"; 1072 case SO_SNDLOWAT: 1073 return "SO_SNDLOWAT"; 1074 case SO_RCVLOWAT: 1075 return "SO_RCVLOWAT"; 1076 case SO_USELOOPBACK: 1077 return "SO_USELOOPBACK"; 1078 case SO_ACCEPTCONN: 1079 return "SO_ACCEPTCONN"; 1080 default: 1081 return "unknown option"; 1082 } 1083 } 1084 #endif 986 1085 //****************************************************************************** 987 1086 //****************************************************************************** … … 1064 1163 case SO_SNDTIMEO: 1065 1164 case SO_RCVTIMEO: 1165 { 1166 if(optlen < (int)sizeof(int)) 1167 { 1168 dprintf(("SO_RCVTIMEO, SO_SNDTIMEO, optlen too small")); 1169 WSASetLastError(WSAEFAULT); 1170 return SOCKET_ERROR; 1171 } 1066 1172 // convert "int" to "struct timeval" 1067 1173 struct timeval tv; 1068 tv.tv_sec = *optval / 1000; 1069 tv.tv_usec = (*optval % 1000) * 1000; 1174 tv.tv_sec = (*(int *)optval) / 1000; 1175 tv.tv_usec = ((*(int *)optval) % 1000) * 1000; 1176 if(optname == SO_SNDTIMEO) { 1177 dprintf(("SO_SNDTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec)); 1178 } 1179 else dprintf(("SO_RCVTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec)); 1180 1070 1181 ret = setsockopt(s, level, optname, (char *)&tv, sizeof(tv) ); 1071 1182 break; 1183 } 1184 1185 case SO_REUSEADDR: 1186 if(optlen < (int)sizeof(int)) { 1187 dprintf(("SO_REUSEADDR, optlen too small")); 1188 WSASetLastError(WSAEFAULT); 1189 return SOCKET_ERROR; 1190 } 1191 dprintf(("option SO_REUSEADDR value %d", *(int *)optval)); 1192 ret = setsockopt(s, level, SO_REUSEADDR, (char *)optval, optlen); 1193 if(ret) { 1194 dprintf(("setsockopt SO_REUSEADDR failed!!")); 1195 } 1196 ret = setsockopt(s, level, SO_REUSEPORT_OS2, (char *)optval, optlen); 1197 if(ret) { 1198 dprintf(("setsockopt SO_REUSEPORT failed!!")); 1199 } 1200 break; 1072 1201 1073 1202 case SO_BROADCAST: … … 1076 1205 case SO_DONTROUTE: 1077 1206 case SO_OOBINLINE: 1078 case SO_REUSEADDR: 1207 case SO_ERROR: 1208 case SO_SNDLOWAT: 1209 case SO_RCVLOWAT: 1210 case SO_ACCEPTCONN: 1211 case SO_USELOOPBACK: 1079 1212 if(optlen < (int)sizeof(int)) { 1080 dprintf((" SOL_SOCKET, SO_REUSEADDR, optlen too small"));1213 dprintf(("%s optlen too small", debugsockopt(optname))); 1081 1214 WSASetLastError(WSAEFAULT); 1082 1215 return SOCKET_ERROR; 1083 1216 } 1217 dprintf(("option %s = %x", debugsockopt(optname), *(int *)optval)); 1084 1218 ret = setsockopt(s, level, optname, (char *)optval, optlen); 1085 1219 break; … … 1153 1287 { 1154 1288 u_int flLoop; 1155 if (optlen < sizeof(u_ char))1289 if (optlen < sizeof(u_int)) 1156 1290 { 1157 1291 dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small")); … … 1161 1295 flLoop = (*optval == 0) ? 0 : 1; 1162 1296 dprintf(("IP_MULTICAST_LOOP %d", *optval)); 1163 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)&flLoop, optlen);1297 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)&flLoop, sizeof(u_char)); 1164 1298 break; 1165 1299 } … … 1167 1301 case IP_MULTICAST_TTL: 1168 1302 case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2): 1169 if (optlen < sizeof(u_ char))1303 if (optlen < sizeof(u_int)) 1170 1304 { 1171 1305 dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small")); … … 1173 1307 return SOCKET_ERROR; 1174 1308 } 1175 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen); 1309 dprintf(("IP_MULTICAST_TTL %d", *optval)); 1310 ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, sizeof(u_char)); 1176 1311 break; 1177 1312 … … 1210 1345 dprintf(("IPPROTO_IP, IP_HDRINCL 0x%x", val)); 1211 1346 ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)&val, optlen); 1347 break; 1348 1349 case IP_DONTFRAGMENT: 1350 case WS2_IPPROTO_OPT(IP_DONTFRAGMENT_WS2): 1351 //MSDN says these options are silently ignored 1352 dprintf(("IPPROTO_IP: IP_DONTFRAGMENT ignored")); 1353 ret = 0; 1212 1354 break; 1213 1355 … … 1269 1411 break; 1270 1412 1413 case SO_REUSEADDR: 1414 if(optlen == NULL || *optlen < sizeof(int)) { 1415 WSASetLastError(WSAEFAULT); 1416 return SOCKET_ERROR; 1417 } 1418 ret = getsockopt(s, level, SO_REUSEADDR, (char *)optval, optlen); 1419 dprintf(("getsockopt SO_REUSEADDR returned %d", *(int *)optval, optname)); 1420 break; 1421 break; 1422 1423 case SO_SNDTIMEO: 1424 case SO_RCVTIMEO: 1425 { 1426 if(optlen == NULL || *optlen < sizeof(int)) 1427 { 1428 dprintf(("SO_RCVTIMEO, SO_SNDTIMEO, optlen too small")); 1429 WSASetLastError(WSAEFAULT); 1430 return SOCKET_ERROR; 1431 } 1432 struct timeval tv; 1433 int size = sizeof(tv); 1434 ret = getsockopt(s, level, optname, (char *)&tv, &size ); 1435 1436 // convert "struct timeval" to "int" 1437 *(int *)optval = (tv.tv_sec * 1000) + tv.tv_usec/1000; 1438 if(optname == SO_SNDTIMEO) { 1439 dprintf(("SO_SNDTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec)); 1440 } 1441 else dprintf(("SO_RCVTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec)); 1442 1443 break; 1444 } 1445 1271 1446 case SO_SNDBUF: 1272 1447 case SO_RCVBUF: … … 1276 1451 case SO_DONTROUTE: 1277 1452 case SO_OOBINLINE: 1278 case SO_REUSEADDR:1279 1453 case SO_TYPE: 1454 case SO_ERROR: 1455 case SO_SNDLOWAT: 1456 case SO_RCVLOWAT: 1457 case SO_USELOOPBACK: 1280 1458 if(optlen == NULL || *optlen < sizeof(int)) { 1281 1459 WSASetLastError(WSAEFAULT); … … 1283 1461 } 1284 1462 ret = getsockopt(s, level, optname, (char *)optval, optlen); 1463 dprintf(("getsockopt %s returned %d", debugsockopt(optname), *(int *)optval)); 1285 1464 break; 1465 1286 1466 case SO_ACCEPTCONN: 1287 1467 if(optlen == NULL || *optlen < sizeof(int)) { … … 1294 1474 *(BOOL *)optval = (options & SO_ACCEPTCONN) == SO_ACCEPTCONN; 1295 1475 *optlen = sizeof(BOOL); 1476 dprintf(("SO_ACCEPTCONN returned %d", *(BOOL *)optval)); 1296 1477 } 1297 1478 break; … … 1357 1538 break; 1358 1539 1540 case IP_MULTICAST_LOOP_WS2: //for buggy applications that intended to call ws_32.getsockopt 1359 1541 case IP_MULTICAST_LOOP: 1360 1542 case WS2_IPPROTO_OPT(IP_MULTICAST_LOOP_WS2): 1361 1543 { 1362 if (*optlen < sizeof(u_ char))1544 if (*optlen < sizeof(u_int)) 1363 1545 { 1364 1546 dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small")); … … 1366 1548 return SOCKET_ERROR; 1367 1549 } 1550 memset(optval, 0, *optlen); 1368 1551 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)optval, optlen); 1369 1552 break; … … 1372 1555 case IP_MULTICAST_TTL: 1373 1556 case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2): 1374 if (*optlen < sizeof(u_ char))1557 if (*optlen < sizeof(u_int)) 1375 1558 { 1376 1559 dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small")); … … 1378 1561 return SOCKET_ERROR; 1379 1562 } 1563 memset(optval, 0, *optlen); 1380 1564 ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen); 1565 dprintf(("getsockopt IP_MULTICAST_TTL_OS2 returned %d, size %d", (int)*optval, *optlen)); 1381 1566 break; 1382 1567 … … 1389 1574 return SOCKET_ERROR; 1390 1575 } 1576 memset(optval, 0, *optlen); 1391 1577 ret = getsockopt(s, IPPROTO_IP, IP_TTL_OS2, (char *)optval, optlen); 1392 1578 break; … … 1415 1601 } 1416 1602 break; 1603 1604 case IP_DONTFRAGMENT: 1605 case WS2_IPPROTO_OPT(IP_DONTFRAGMENT_WS2): 1606 //MSDN says these options are silently ignored 1607 if (*optlen < sizeof(u_int)) 1608 { 1609 dprintf(("IP_DONTFRAGMENT, IP_DONTFRAGMENT_WS2, optlen too small")); 1610 WSASetLastError(WSAEFAULT); 1611 return SOCKET_ERROR; 1612 } 1613 dprintf(("IPPROTO_IP: IP_DONTFRAGMENT ignored")); 1614 *optlen = sizeof(u_int); 1615 *(int *)optval = 0; 1616 ret = 0; 1617 break; 1618 1417 1619 1418 1620 default: … … 1481 1683 // I.e. start ISDNPM without dialing in. gethostbyname will query 1482 1684 // each name server and retry several times (60+ seconds per name server) 1685 // 1686 static struct ws_hostent localhost; 1687 static DWORD localhost_address; 1688 static DWORD localhost_addrlist[2] = {(DWORD)&localhost_address, 0}; 1689 static DWORD localhost_aliaslist[1] = {0}; 1483 1690 //****************************************************************************** 1484 1691 ODINFUNCTION1(ws_hostent *,OS2gethostbyname, … … 1493 1700 1494 1701 dprintf(("gethostbyname %s", name)); 1495 if (gethostname(localhostname, sizeof(localhostname)) == NO_ERROR)1702 if (!gethostname(localhostname, sizeof(localhostname))) 1496 1703 { 1497 if(!strcmp(name, localhostname)) { 1704 /* 1705 * This is a fast non-blocking path for the hostname of this machine. 1706 * It's probably not 100% correct though.. 1707 */ 1708 if (!strcmp(name, localhostname)) 1709 { 1710 /* 1711 * Lookup lan0 address, and move on to lo address if that fails. 1712 */ 1713 sock_init(); /* ??? */ 1714 int s = socket(PF_INET, SOCK_STREAM, 0); 1715 if (s >= 0) 1716 { 1717 struct ifreq ifr = {0}; 1718 strcpy(ifr.ifr_name, "lan0"); 1719 int rc = ioctl(s, SIOCGIFADDR, (char*)&ifr, sizeof(ifr)); 1720 if (rc == -1) 1721 { 1722 strcpy(ifr.ifr_name, "lo"); 1723 rc = ioctl(s, SIOCGIFADDR, (char*)&ifr, sizeof(ifr)); 1724 } 1725 soclose(s); 1726 1727 if (rc != -1) 1728 { 1729 /* ASSUMES: family is AF_INET */ 1730 /* Doesn't work with aliases on lan0. */ 1731 struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr; 1732 1733 localhost_address = *(unsigned long *)&addr->sin_addr; 1734 localhost.h_name = "localhost"; /* This is what the old workaround did. */ 1735 localhost.h_addrtype = AF_INET; 1736 localhost.h_length = 4; 1737 localhost.h_addr_list = (char **)&localhost_addrlist[0]; 1738 localhost.h_aliases = (char **)&localhost_aliaslist[0]; 1739 WSASetLastError(NO_ERROR); 1740 return &localhost; 1741 } 1742 } 1743 1744 /* 1745 * bail out.. 1746 */ 1498 1747 strcpy(localhostname, "localhost"); 1499 1748 name = localhostname; -
trunk/src/wsock32/wsock32.def
r6201 r21308 107 107 ; TransmitFile = _OS2TransmitFile 108 108 109 ; 110 ; ENDOFEXPORTS 111 ; Internal function marker 112 ; 113 109 114 ; ----------------------- 110 115 ; ODIN internal functions -
trunk/src/wsock32/wsock32.h
r7977 r21308 24 24 #define IP_TTL 7 25 25 #define IP_TOS 8 26 #define IP_DONTFRAGMENT 9 26 27 #endif 27 28
Note:
See TracChangeset
for help on using the changeset viewer.