Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

509 lines
14 KiB

  1. //
  2. // Copyright 2001 - Microsoft Corporation
  3. //
  4. //
  5. // Created By:
  6. // Geoff Pease (GPease) 30-JAN-2001
  7. //
  8. // Maintained By:
  9. // Geoff Pease (GPease) 30-JAN-2001
  10. //
  11. #include "pch.h"
  12. #include "propvar.h"
  13. #pragma hdrstop
  14. //
  15. // Description:
  16. // Since there isn't a PropVariantChangeType() API, we have to create our
  17. // own string conversion routine.
  18. //
  19. // Return Values:
  20. // S_OK
  21. // Success!
  22. //
  23. // E_POINTER
  24. // pvarIn is NULL.
  25. //
  26. // OLE_E_CANTCONVERT
  27. // Conversion of string to a particular type failed.
  28. //
  29. // HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
  30. // Unknown or invalid type - If the type is valid, then the function
  31. // needs to be modified to handle this type.
  32. //
  33. // E_NOTIMPL
  34. // Purposely not implemented type.
  35. //
  36. // other HRESULTs.
  37. //
  38. HRESULT
  39. PropVariantFromString(
  40. LPWSTR pszTextIn
  41. , UINT nCodePageIn
  42. , ULONG dwFlagsIn
  43. , VARTYPE vtSaveIn
  44. , PROPVARIANT * pvarIn
  45. )
  46. {
  47. TraceFunc( "" );
  48. HRESULT hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  49. LCID lcid = GetUserDefaultLCID();
  50. if ( NULL == pvarIn )
  51. goto InvalidPointer;
  52. THR( PropVariantClear( pvarIn ) );
  53. // some strings are allowed
  54. // to have an empty string
  55. // otherwise we need to fail on empty
  56. if ( ( NULL != pszTextIn )
  57. && ( ( 0 != *pszTextIn ) || ( VT_BSTR == vtSaveIn ) || ( VT_LPWSTR == vtSaveIn ) )
  58. )
  59. {
  60. switch( vtSaveIn )
  61. {
  62. case VT_EMPTY:
  63. case VT_NULL:
  64. case VT_ILLEGAL:
  65. break;
  66. case VT_UI1:
  67. hr = THR( VarUI1FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->bVal ) );
  68. break;
  69. case VT_I2:
  70. hr = THR( VarI2FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->iVal ) );
  71. break;
  72. case VT_UI2:
  73. hr = THR( VarUI2FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->uiVal ) );
  74. break;
  75. case VT_BOOL:
  76. hr = THR( VarBoolFromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->boolVal ) );
  77. break;
  78. case VT_I4:
  79. hr = THR( VarI4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->lVal ) );
  80. break;
  81. case VT_UI4:
  82. hr = THR( VarUI4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->ulVal ) );
  83. break;
  84. case VT_R4:
  85. hr = THR( VarR4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->fltVal ) );
  86. break;
  87. case VT_ERROR:
  88. hr = THR( VarI4FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->scode ) );
  89. break;
  90. //case VT_I8:
  91. // return _i64tot(hVal.QuadPart, pszBuf, 10);
  92. //case VT_UI8:
  93. // return _ui64tot(hVal.QuadPart, pszBuf, 10);
  94. case VT_R8:
  95. hr = THR( VarR8FromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->dblVal ) );
  96. break;
  97. case VT_CY:
  98. hr = THR( VarCyFromStr( pszTextIn, lcid, dwFlagsIn, &pvarIn->cyVal ) );
  99. break;
  100. case VT_DATE:
  101. hr = THR( VarDateFromStr( pszTextIn, lcid, VAR_DATEVALUEONLY, &pvarIn->date) );
  102. break;
  103. case VT_FILETIME:
  104. {
  105. SYSTEMTIME st;
  106. DATE d;
  107. hr = THR( VarDateFromStr( pszTextIn, lcid, VAR_DATEVALUEONLY, &d ) );
  108. if ( SUCCEEDED( hr ) )
  109. {
  110. BOOL bRet;
  111. hr = OLE_E_CANTCONVERT;
  112. bRet = TBOOL( VariantTimeToSystemTime( d, &st ) );
  113. if ( bRet )
  114. {
  115. bRet = TBOOL( SystemTimeToFileTime( &st, &pvarIn->filetime ) );
  116. if ( bRet )
  117. {
  118. hr = S_OK;
  119. }
  120. }
  121. }
  122. }
  123. break;
  124. case VT_CLSID:
  125. {
  126. CLSID clsid;
  127. hr = THR( CLSIDFromString( pszTextIn, &clsid ) );
  128. if ( SUCCEEDED( hr ) )
  129. {
  130. pvarIn->puuid = (CLSID*) CoTaskMemAlloc( sizeof(clsid) );
  131. if ( NULL == pvarIn->puuid )
  132. goto OutOfMemory;
  133. *pvarIn->puuid = clsid;
  134. hr = S_OK;
  135. }
  136. }
  137. break;
  138. case VT_BSTR:
  139. pvarIn->bstrVal = SysAllocString( pszTextIn );
  140. if ( NULL == pvarIn->bstrVal )
  141. goto OutOfMemory;
  142. hr = S_OK;
  143. break;
  144. case VT_LPWSTR:
  145. hr = SHStrDup( pszTextIn, &pvarIn->pwszVal );
  146. break;
  147. case VT_LPSTR:
  148. {
  149. DWORD cchRet;
  150. DWORD cch = wcslen( pszTextIn ) + 1;
  151. pvarIn->pszVal = (LPSTR) CoTaskMemAlloc( cch );
  152. if ( NULL == pvarIn->pszVal )
  153. goto OutOfMemory;
  154. cchRet = WideCharToMultiByte( nCodePageIn, dwFlagsIn, pszTextIn, cch, pvarIn->pszVal, cch, 0, NULL );
  155. if (( 0 == cchRet ) && ( 1 < cch ))
  156. {
  157. DWORD dwErr = TW32( GetLastError( ) );
  158. hr = HRESULT_FROM_WIN32( dwErr );
  159. CoTaskMemFree( pvarIn->pszVal );
  160. pvarIn->pszVal = NULL;
  161. goto Cleanup;
  162. }
  163. hr = S_OK;
  164. }
  165. break;
  166. #ifdef DEBUG
  167. case VT_VECTOR | VT_UI1:
  168. //pvarIn->caub;
  169. case VT_VECTOR | VT_I2:
  170. //pvarIn->cai;
  171. case VT_VECTOR | VT_UI2:
  172. //pvarIn->caui;
  173. case VT_VECTOR | VT_I4:
  174. //pvarIn->cal;
  175. case VT_VECTOR | VT_UI4:
  176. //pvarIn->caul;
  177. case VT_VECTOR | VT_I8:
  178. //pvarIn->cah;
  179. case VT_VECTOR | VT_UI8:
  180. //pvarIn->cauh;
  181. case VT_VECTOR | VT_R4:
  182. //pvarIn->caflt;
  183. case VT_VECTOR | VT_R8:
  184. //pvarIn->cadbl;
  185. case VT_VECTOR | VT_CY:
  186. //pvarIn->cacy;
  187. case VT_VECTOR | VT_DATE:
  188. //pvarIn->cadate;
  189. case VT_VECTOR | VT_BSTR:
  190. //pvarIn->cabstr;
  191. case VT_VECTOR | VT_BOOL:
  192. //pvarIn->cabool;
  193. case VT_VECTOR | VT_ERROR:
  194. //pvarIn->cascode;
  195. case VT_VECTOR | VT_LPSTR:
  196. //pvarIn->calpstr;
  197. case VT_VECTOR | VT_LPWSTR:
  198. //pvarIn->calpwstr;
  199. case VT_VECTOR | VT_FILETIME:
  200. //pvarIn->cafiletime;
  201. case VT_VECTOR | VT_CLSID:
  202. //pvarIn->cauuid;
  203. case VT_VECTOR | VT_CF:
  204. //pvarIn->caclipdata;
  205. case VT_VECTOR | VT_VARIANT:
  206. //pvarIn->capropvar;
  207. hr = THR( E_NOTIMPL );
  208. // Illegal types for which to assign value from display text.
  209. case VT_BLOB:
  210. case VT_CF :
  211. case VT_STREAM:
  212. case VT_STORAGE:
  213. #endif // DEBUG
  214. // not handled
  215. default:
  216. hr = THR( HRESULT_FROM_WIN32(ERROR_INVALID_DATA) );
  217. }
  218. }
  219. // set current VARTYPE always
  220. if ( SUCCEEDED( hr ) )
  221. {
  222. pvarIn->vt = vtSaveIn;
  223. }
  224. Cleanup:
  225. HRETURN( hr );
  226. InvalidPointer:
  227. hr = THR( E_POINTER );
  228. goto Cleanup;
  229. OutOfMemory:
  230. hr = E_OUTOFMEMORY;
  231. goto Cleanup;
  232. }
  233. //
  234. // Description:
  235. // Since there isn't a PropVariantChangeType() API, we have to create our
  236. // own string conversion routine.
  237. //
  238. // Return Values:
  239. // S_OK
  240. // Success!
  241. //
  242. // E_POINTER
  243. // pbstrOut is NULL.
  244. //
  245. // E_INVALIDARG
  246. // ppropvarIn is NULL.
  247. //
  248. // HRESULT_FROM_WIN32(ERROR_INVALID_DATA)
  249. // Unknown or invalid type - If the type is valid, then the function
  250. // needs to be modified to handle this type.
  251. //
  252. // E_NOTIMPL
  253. // Purposely not implemented type.
  254. //
  255. HRESULT
  256. PropVariantToBSTR(
  257. PROPVARIANT * pvarIn
  258. , UINT nCodePageIn
  259. , ULONG dwFlagsIn
  260. , BSTR * pbstrOut
  261. )
  262. {
  263. TraceFunc( "" );
  264. HRESULT hr;
  265. LCID lcid = GetUserDefaultLCID( );
  266. //
  267. // Check parameters
  268. //
  269. if ( NULL == pbstrOut )
  270. goto InvalidPointer;
  271. if ( NULL == pvarIn )
  272. goto InvalidArg;
  273. *pbstrOut = NULL;
  274. switch ( pvarIn->vt )
  275. {
  276. case VT_UI1:
  277. hr = THR( VarBstrFromUI1( pvarIn->bVal, lcid, dwFlagsIn, pbstrOut ) );
  278. break;
  279. case VT_I2:
  280. hr = THR( VarBstrFromI2( pvarIn->iVal, lcid, dwFlagsIn, pbstrOut ) );
  281. break;
  282. case VT_UI2:
  283. hr = THR( VarBstrFromUI2( pvarIn->uiVal, lcid, dwFlagsIn, pbstrOut ) );
  284. break;
  285. case VT_BOOL:
  286. hr = THR( VarBstrFromBool( pvarIn->boolVal, lcid, dwFlagsIn, pbstrOut ) );
  287. break;
  288. case VT_I4:
  289. hr = THR( VarBstrFromI4( pvarIn->lVal, lcid, dwFlagsIn, pbstrOut ) );
  290. break;
  291. case VT_UI4:
  292. hr = THR( VarBstrFromUI4( pvarIn->ulVal, lcid, dwFlagsIn, pbstrOut ) );
  293. break;
  294. case VT_R4:
  295. hr = THR( VarBstrFromR4( pvarIn->fltVal, lcid, dwFlagsIn, pbstrOut ) );
  296. break;
  297. case VT_ERROR:
  298. hr = THR( VarBstrFromI4( pvarIn->scode, lcid, dwFlagsIn, pbstrOut ) );
  299. break;
  300. //case VT_I8:
  301. // return _i64tot(hVal.QuadPart, pszBuf, 10); ????
  302. //case VT_UI8:
  303. // return _ui64tot(hVal.QuadPart, pszBuf, 10); ?????
  304. case VT_R8:
  305. hr = THR( VarBstrFromR8( pvarIn->dblVal, lcid, dwFlagsIn, pbstrOut ) );
  306. break;
  307. case VT_CY:
  308. hr = THR( VarBstrFromCy( pvarIn->cyVal, lcid, dwFlagsIn, pbstrOut ) );
  309. break;
  310. case VT_DATE:
  311. hr = THR( VarBstrFromDate( pvarIn->date, lcid, VAR_DATEVALUEONLY, pbstrOut ) );
  312. break;
  313. case VT_FILETIME:
  314. {
  315. BOOL bRet;
  316. SYSTEMTIME st;
  317. DATE d;
  318. bRet = TBOOL( FileTimeToSystemTime( &pvarIn->filetime, &st ) );
  319. if ( !bRet )
  320. goto ErrorCantConvert;
  321. bRet = TBOOL( SystemTimeToVariantTime( &st, &d ) );
  322. if ( !bRet )
  323. goto ErrorCantConvert;
  324. hr = THR( VarBstrFromDate( d, lcid, VAR_DATEVALUEONLY, pbstrOut ) );
  325. }
  326. break;
  327. case VT_CLSID:
  328. hr = THR( StringFromCLSID( *pvarIn->puuid, pbstrOut ) );
  329. break;
  330. case VT_BSTR:
  331. *pbstrOut = SysAllocString( pvarIn->bstrVal );
  332. if ( NULL == *pbstrOut )
  333. goto OutOfMemory;
  334. hr = S_OK;
  335. break;
  336. case VT_LPWSTR:
  337. *pbstrOut = SysAllocString( pvarIn->pwszVal );
  338. if ( NULL == *pbstrOut )
  339. goto OutOfMemory;
  340. hr = S_OK;
  341. break;
  342. case VT_LPSTR:
  343. {
  344. DWORD cchRet;
  345. DWORD cch = lstrlenA( pvarIn->pszVal );
  346. *pbstrOut = SysAllocStringLen( NULL, cch );
  347. if ( NULL == *pbstrOut )
  348. goto OutOfMemory;
  349. cchRet = MultiByteToWideChar( nCodePageIn, dwFlagsIn, pvarIn->pszVal, cch + 1, *pbstrOut, cch + 1 );
  350. if (( 0 == cchRet ) && ( 0 != cch ))
  351. {
  352. DWORD dwErr = TW32( GetLastError( ) );
  353. hr = HRESULT_FROM_WIN32( dwErr );
  354. SysFreeString( *pbstrOut );
  355. *pbstrOut = NULL;
  356. goto Cleanup;
  357. }
  358. hr = S_OK;
  359. }
  360. break;
  361. #ifdef DEBUG
  362. case VT_VECTOR | VT_UI1:
  363. //pvarIn->caub;
  364. case VT_VECTOR | VT_I2:
  365. //pvarIn->cai;
  366. case VT_VECTOR | VT_UI2:
  367. //pvarIn->caui;
  368. case VT_VECTOR | VT_I4:
  369. //pvarIn->cal;
  370. case VT_VECTOR | VT_UI4:
  371. //pvarIn->caul;
  372. case VT_VECTOR | VT_I8:
  373. //pvarIn->cah;
  374. case VT_VECTOR | VT_UI8:
  375. //pvarIn->cauh;
  376. case VT_VECTOR | VT_R4:
  377. //pvarIn->caflt;
  378. case VT_VECTOR | VT_R8:
  379. //pvarIn->cadbl;
  380. case VT_VECTOR | VT_CY:
  381. //pvarIn->cacy;
  382. case VT_VECTOR | VT_DATE:
  383. //pvarIn->cadate;
  384. case VT_VECTOR | VT_BSTR:
  385. //pvarIn->cabstr;
  386. case VT_VECTOR | VT_BOOL:
  387. //pvarIn->cabool;
  388. case VT_VECTOR | VT_ERROR:
  389. //pvarIn->cascode;
  390. case VT_VECTOR | VT_LPSTR:
  391. //pvarIn->calpstr;
  392. case VT_VECTOR | VT_LPWSTR:
  393. //pvarIn->calpwstr;
  394. case VT_VECTOR | VT_FILETIME:
  395. //pvarIn->cafiletime;
  396. case VT_VECTOR | VT_CLSID:
  397. //pvarIn->cauuid;
  398. case VT_VECTOR | VT_CF:
  399. //pvarIn->caclipdata;
  400. case VT_VECTOR | VT_VARIANT:
  401. //pvarIn->capropvar;
  402. hr = THR( E_NOTIMPL );
  403. // Illegal types for which to assign value from display text.
  404. case VT_BLOB:
  405. case VT_CF :
  406. case VT_STREAM:
  407. case VT_STORAGE:
  408. #endif // DEBUG
  409. case VT_EMPTY:
  410. case VT_NULL:
  411. case VT_ILLEGAL:
  412. default:
  413. hr = THR( HRESULT_FROM_WIN32(ERROR_INVALID_DATA) );
  414. }
  415. Cleanup:
  416. HRETURN( hr );
  417. InvalidPointer:
  418. hr = THR( E_POINTER );
  419. goto Cleanup;
  420. InvalidArg:
  421. hr = THR( E_INVALIDARG );
  422. goto Cleanup;
  423. ErrorCantConvert:
  424. hr = OLE_E_CANTCONVERT;
  425. goto Cleanup;
  426. OutOfMemory:
  427. hr = E_OUTOFMEMORY;
  428. goto Cleanup;
  429. }