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.

1189 lines
28 KiB

  1. /*****************************************************************************
  2. *
  3. * OsUtil.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. * Various OS dependent utility functions
  9. *
  10. * Contents:
  11. *
  12. * History:
  13. *
  14. * vlads 11/05/1996 created
  15. *****************************************************************************/
  16. /*
  17. #include <windows.h>
  18. #include <windowsx.h>
  19. #include <objbase.h>
  20. #include <regstr.h>
  21. #include <setupapi.h>
  22. #include <cfgmgr32.h>
  23. #include <devguid.h>
  24. #include <stdio.h>
  25. #include <stilog.h>
  26. #include <stiregi.h>
  27. #include <sti.h>
  28. #include <stierr.h>
  29. #include <stiusd.h>
  30. #include "wia.h"
  31. #include "stipriv.h"
  32. #include "stiapi.h"
  33. #include "stirc.h"
  34. #include "debug.h"
  35. */
  36. #include "sticomm.h"
  37. #define DbgFl DbgFlUtil
  38. BOOL WINAPI
  39. OSUtil_IsPlatformUnicode()
  40. {
  41. OSVERSIONINFOA ver;
  42. BOOL bReturn = FALSE;
  43. ZeroX(ver);
  44. ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  45. // Just always call the ANSI function
  46. if(!GetVersionExA(&ver)) {
  47. DebugOutPtszV(DbgFl, TEXT("Unable to determinte platform -- setting flag to ANSI"));
  48. bReturn = FALSE;
  49. }
  50. else {
  51. switch(ver.dwPlatformId) {
  52. case VER_PLATFORM_WIN32_WINDOWS:
  53. bReturn = FALSE;
  54. break;
  55. case VER_PLATFORM_WIN32_NT:
  56. bReturn = TRUE;
  57. break;
  58. default:
  59. bReturn = FALSE;
  60. break;
  61. }
  62. }
  63. // Keep the compiler happy
  64. return bReturn;
  65. } // endproc OSUtil_IsUnicodePlatform
  66. HRESULT WINAPI
  67. OSUtil_GetAnsiString(
  68. LPSTR * ppszAnsi,
  69. LPCWSTR lpszWide
  70. )
  71. {
  72. HRESULT hres;
  73. int cbStrLen;
  74. if (!lpszWide) {
  75. *ppszAnsi = NULL;
  76. return S_OK;
  77. }
  78. // We can use WideToChar to figure out exact resultant width
  79. cbStrLen = 2*(OSUtil_StrLenW(lpszWide)+1);
  80. hres = AllocCbPpv(cbStrLen, ppszAnsi);
  81. if (!*ppszAnsi) {
  82. DebugOutPtszV(DbgFl, TEXT("could not get ansi string -- out of memory"));
  83. return E_OUTOFMEMORY;
  84. }
  85. UToA(*ppszAnsi,cbStrLen,lpszWide);
  86. return S_OK;
  87. } // OSUtil_GetAnsiString
  88. HRESULT WINAPI
  89. OSUtil_GetWideString(
  90. LPWSTR *ppszWide,
  91. LPCSTR pszAnsi
  92. )
  93. {
  94. HRESULT hres;
  95. int cbStrLen;
  96. if (!pszAnsi) {
  97. *ppszWide = NULL;
  98. return S_OK;
  99. }
  100. // We can use WideToChar to figure out exact resultant width
  101. cbStrLen = 2*(lstrlenA(pszAnsi)+1);
  102. hres = AllocCbPpv(cbStrLen, (PPV)ppszWide);
  103. if (!*ppszWide) {
  104. DebugOutPtszV(DbgFl,TEXT("Could not get unicode string -- out of memory"));
  105. return E_OUTOFMEMORY;
  106. }
  107. AToU(*ppszWide,cbStrLen,pszAnsi);
  108. return S_OK;
  109. } // OSUtil_GetWideString
  110. HINSTANCE
  111. OSUtil_LoadLibraryW(
  112. LPCWSTR lpszWFileName
  113. )
  114. {
  115. HINSTANCE hinstRet = NULL;
  116. if (g_NoUnicodePlatform) {
  117. CHAR *pFileNameA = NULL;
  118. if ( SUCCEEDED(OSUtil_GetAnsiString(&pFileNameA,lpszWFileName))) {
  119. hinstRet = LoadLibraryA(pFileNameA);
  120. FreePpv(&pFileNameA);
  121. }
  122. else {
  123. DebugOutPtszV(DbgFl,TEXT("Failed in LoadLibraryW"));
  124. }
  125. }
  126. else {
  127. hinstRet = LoadLibraryW(lpszWFileName);
  128. }
  129. return hinstRet;
  130. } // OSUtil_LoadLibrary
  131. /*
  132. // There seems to be no getproc addressW
  133. FARPROC
  134. WINAPI
  135. OSUtil_GetProcAddress(HMODULE hModule,LPCTSTR lpProcName)
  136. {
  137. #ifndef UNICODE
  138. return GetProcAddress(hModule,lpProcNameW);
  139. #else
  140. FARPROC pProcAddr = NULL;
  141. CHAR *pProcNameA = NULL;
  142. if ( SUCCEEDED(OSUtil_GetAnsiString(&pProcNameA,lpProcName))) {
  143. pProcAddr = GetProcAddress(hModule,pProcNameA);
  144. FreePpv(&pProcNameA);
  145. }
  146. else {
  147. DebugOutPtszV(DbgFl,TEXT("Failed in GetProcAddress "));
  148. }
  149. return pProcAddr;
  150. #endif
  151. } // OSUtil_GetProcAddress
  152. */
  153. LONG
  154. WINAPI
  155. OSUtil_RegOpenKeyExW(
  156. HKEY hKey,
  157. LPCWSTR lpszKeyStrW,
  158. DWORD dwReserved,
  159. REGSAM samDesired,
  160. PHKEY phkResult)
  161. {
  162. LONG lRet = 0L;
  163. if (g_NoUnicodePlatform) {
  164. CHAR *lpszKeyStrA = NULL;
  165. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszKeyStrA,lpszKeyStrW))) {
  166. lRet = RegOpenKeyExA(hKey,lpszKeyStrA,dwReserved,samDesired,phkResult);
  167. FreePpv(&lpszKeyStrA);
  168. }
  169. else {
  170. DebugOutPtszV(DbgFl,TEXT("Failed in RegOpenKeyExW"));
  171. lRet = ERROR_INVALID_PARAMETER;
  172. }
  173. }
  174. else {
  175. lRet = RegOpenKeyExW(hKey,lpszKeyStrW,dwReserved,samDesired,phkResult);
  176. }
  177. return (lRet);
  178. }
  179. LONG WINAPI
  180. OSUtil_RegDeleteValueW(
  181. HKEY hKey,
  182. LPWSTR lpszValueNameW
  183. )
  184. {
  185. long lRet = NOERROR;
  186. if (g_NoUnicodePlatform) {
  187. CHAR *lpszValueNameA = NULL;
  188. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszValueNameA,lpszValueNameW))) {
  189. lRet = RegDeleteValueA(hKey, lpszValueNameA);
  190. FreePpv(&lpszValueNameA);
  191. }
  192. else {
  193. DebugOutPtszV(DbgFl,TEXT("Failed in RegDeleteValueKeyW"));
  194. lRet = ERROR_INVALID_PARAMETER;
  195. }
  196. }
  197. else {
  198. lRet = RegDeleteValueW(hKey, lpszValueNameW);
  199. }
  200. return lRet;
  201. }
  202. LONG
  203. WINAPI
  204. OSUtil_RegCreateKeyExW(
  205. HKEY hKey,
  206. LPWSTR lpszSubKeyW, DWORD dwReserved, LPWSTR lpszClassW,
  207. DWORD dwOptions,
  208. REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  209. PHKEY phkResult,
  210. LPDWORD lpdwDisposition
  211. )
  212. {
  213. LPSTR lpszSubKeyA = NULL;
  214. LPSTR lpszClassA = NULL;
  215. long lRet = NOERROR;
  216. if (g_NoUnicodePlatform) {
  217. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszClassA,lpszClassW)) &&
  218. SUCCEEDED(OSUtil_GetAnsiString(&lpszSubKeyA,lpszSubKeyW))) {
  219. lRet = RegCreateKeyExA(hKey, lpszSubKeyA, dwReserved, lpszClassA, dwOptions,
  220. samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
  221. FreePpv(&lpszSubKeyA);
  222. FreePpv(&lpszClassA);
  223. }
  224. else {
  225. DebugOutPtszV(DbgFl,TEXT("Failed in RegCreateKeyExW"));
  226. lRet = ERROR_INVALID_PARAMETER;
  227. }
  228. }
  229. else {
  230. lRet = RegCreateKeyExW(hKey, lpszSubKeyW, dwReserved, lpszClassW, dwOptions,
  231. samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
  232. }
  233. return lRet;
  234. }
  235. LONG WINAPI
  236. OSUtil_RegQueryValueExW(
  237. HKEY hKey,
  238. LPCWSTR lpszValueNameW,
  239. DWORD *pdwType,
  240. BYTE* lpData,
  241. DWORD *pcbData,
  242. BOOL fUnicodeCaller // =FALSE
  243. )
  244. {
  245. long lRet = NOERROR;
  246. DWORD cbDataGiven = *pcbData ;
  247. if (g_NoUnicodePlatform || !fUnicodeCaller) {
  248. CHAR *lpszValueNameA = NULL;
  249. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszValueNameA,lpszValueNameW))) {
  250. lRet = RegQueryValueExA( hKey,
  251. lpszValueNameA,
  252. NULL,
  253. pdwType,
  254. lpData,
  255. pcbData );
  256. FreePpv(&lpszValueNameA);
  257. #if 1
  258. //
  259. // The string came back as ANSI but we need UNICODE. Conversion in place
  260. // is not allowed, so do it with second buffer
  261. //
  262. if ( fUnicodeCaller && (NOERROR == lRet) && (*pdwType == REG_SZ)) {
  263. LPWSTR pwszWideData = NULL;
  264. DWORD dwNewSize = *pcbData * sizeof(WCHAR);
  265. HRESULT hres;
  266. if (cbDataGiven >= dwNewSize ) {
  267. hres = OSUtil_GetWideString(&pwszWideData,lpData);
  268. if (SUCCEEDED(hres) && pwszWideData) {
  269. memcpy(lpData,pwszWideData,dwNewSize);
  270. FreePpv(&pwszWideData);
  271. }
  272. else {
  273. lRet = GetLastError();
  274. }
  275. }
  276. else {
  277. lRet = ERROR_MORE_DATA;
  278. }
  279. *pcbData *= sizeof(WCHAR);
  280. }
  281. #endif
  282. }
  283. else {
  284. DebugOutPtszV(DbgFl,TEXT("Failed in RegDeleteValueKeyW"));
  285. lRet = ERROR_INVALID_PARAMETER;
  286. }
  287. }
  288. else {
  289. lRet = RegQueryValueExW( hKey,
  290. lpszValueNameW,
  291. NULL,
  292. pdwType,
  293. lpData,
  294. pcbData );
  295. }
  296. return lRet;
  297. }
  298. LONG WINAPI
  299. OSUtil_RegSetValueExW(
  300. HKEY hKey,
  301. LPCWSTR lpszValueNameW,
  302. DWORD dwType,
  303. BYTE* lpData,
  304. DWORD cbData,
  305. BOOL fUnicodeCaller // =FALSE
  306. )
  307. {
  308. long lRet = NOERROR;
  309. if (g_NoUnicodePlatform || !fUnicodeCaller) {
  310. CHAR *lpszValueNameA = NULL;
  311. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszValueNameA,lpszValueNameW))) {
  312. lRet = RegSetValueExA(hKey,
  313. lpszValueNameA,
  314. 0,
  315. dwType,
  316. lpData,
  317. cbData);
  318. FreePpv(&lpszValueNameA);
  319. }
  320. else {
  321. DebugOutPtszV(DbgFl,TEXT("Failed in RegDeleteValueKeyW"));
  322. lRet = ERROR_INVALID_PARAMETER;
  323. }
  324. }
  325. else {
  326. lRet = RegSetValueExW( hKey,
  327. (LPVOID)lpszValueNameW,
  328. 0,
  329. dwType,
  330. lpData,
  331. cbData);
  332. }
  333. return lRet;
  334. }
  335. DWORD ReadRegistryDwordW( HKEY hkey,
  336. LPCWSTR pszValueNameW,
  337. DWORD dwDefaultValue )
  338. {
  339. DWORD err = NOERROR;
  340. DWORD dwBuffer = 0;
  341. DWORD cbBuffer = sizeof(dwBuffer);
  342. DWORD dwType;
  343. if( hkey != NULL ) {
  344. if (g_NoUnicodePlatform) {
  345. CHAR *pszValueNameA = NULL;
  346. dwType = REG_DWORD;
  347. if ( SUCCEEDED(OSUtil_GetAnsiString(&pszValueNameA,pszValueNameW))) {
  348. err = RegQueryValueExA( hkey,
  349. pszValueNameA,
  350. NULL,
  351. &dwType,
  352. (LPBYTE)&dwBuffer,
  353. &cbBuffer );
  354. FreePpv(&pszValueNameA);
  355. }
  356. else {
  357. DebugOutPtszV(DbgFl,TEXT("Failed in ReadRegistryDwordW "));
  358. err = ERROR_INVALID_PARAMETER;
  359. }
  360. } else {
  361. err = RegQueryValueExW( hkey,
  362. pszValueNameW,
  363. NULL,
  364. &dwType,
  365. (LPBYTE)&dwBuffer,
  366. &cbBuffer );
  367. }
  368. if( ( err == NO_ERROR ) &&
  369. ( ( dwType == REG_DWORD ) || ( dwType == REG_BINARY ) )
  370. ) {
  371. dwDefaultValue = dwBuffer;
  372. }
  373. }
  374. return dwDefaultValue;
  375. } // ReadRegistryDwordW()
  376. DWORD
  377. WriteRegistryDwordW(
  378. IN HKEY hkey,
  379. IN LPCWSTR pszValueNameW,
  380. IN DWORD dwValue)
  381. {
  382. DWORD err = NOERROR;
  383. if ( hkey == NULL || pszValueNameW == NULL) {
  384. err = ( ERROR_INVALID_PARAMETER);
  385. } else {
  386. if (g_NoUnicodePlatform) {
  387. CHAR *pszValueNameA = NULL;
  388. if ( SUCCEEDED(OSUtil_GetAnsiString(&pszValueNameA,pszValueNameW))) {
  389. err = RegSetValueExA( hkey,pszValueNameA,0,REG_DWORD,(LPBYTE ) &dwValue,sizeof( dwValue));
  390. FreePpv(&pszValueNameA);
  391. }
  392. else {
  393. DebugOutPtszV(DbgFl,TEXT("Failed in ReadRegistryDwordW "));
  394. err = ERROR_INVALID_PARAMETER;
  395. }
  396. }
  397. else {
  398. err = RegSetValueExW( hkey,(LPVOID)pszValueNameW,0,REG_DWORD,(LPBYTE ) &dwValue,sizeof( dwValue));
  399. }
  400. }
  401. return ( err);
  402. } // WriteRegistryDwordW()
  403. DWORD
  404. WriteRegistryStringA(
  405. IN HKEY hkey,
  406. IN LPCSTR pszValueName,
  407. IN LPCSTR pszValue,
  408. IN DWORD cbValue,
  409. IN DWORD fdwType)
  410. {
  411. DWORD err = NOERROR;
  412. if ( hkey == NULL ||
  413. pszValueName == NULL ||
  414. cbValue == 0 ) {
  415. err = ERROR_INVALID_PARAMETER;
  416. } else {
  417. err = RegSetValueExA(
  418. hkey,
  419. pszValueName,
  420. 0,
  421. fdwType,
  422. (LPBYTE ) pszValue,
  423. cbValue); // + 1 for null character
  424. }
  425. return ( err);
  426. } // WriteRegistryStringA()
  427. DWORD
  428. WriteRegistryStringW(
  429. IN HKEY hkey,
  430. IN LPCWSTR pszValueNameW,
  431. IN LPCWSTR pszValueW,
  432. IN DWORD cbValue,
  433. IN DWORD fdwType)
  434. {
  435. DWORD err = NOERROR;
  436. DWORD le;
  437. if ( hkey == NULL ||
  438. pszValueNameW == NULL ||
  439. cbValue == 0 ) {
  440. err = ERROR_INVALID_PARAMETER;
  441. } else {
  442. if (g_NoUnicodePlatform) {
  443. err = ERROR_INVALID_PARAMETER;
  444. if ( (fdwType == REG_SZ) || (fdwType == REG_EXPAND_SZ)) {
  445. LPSTR lpszAnsi = NULL;
  446. LPSTR lpszAnsiName = NULL;
  447. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsi,pszValueW)) &&
  448. SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsiName,pszValueNameW))
  449. ) {
  450. err = WriteRegistryStringA(hkey,
  451. lpszAnsiName,
  452. lpszAnsi,
  453. (lstrlenA(lpszAnsi)+1)*sizeof(CHAR),
  454. fdwType);
  455. }
  456. FreePpv(&lpszAnsi);
  457. FreePpv(&lpszAnsiName);
  458. }
  459. else {
  460. ValidateF(FALSE,("Wrong registry value type in WriteRegistryStringW"));
  461. err = ERROR_INVALID_PARAMETER;
  462. }
  463. }
  464. else {
  465. err = RegSetValueExW(
  466. hkey,
  467. pszValueNameW,
  468. 0,
  469. fdwType,
  470. (LPBYTE ) pszValueW,
  471. cbValue);
  472. le = GetLastError();
  473. }
  474. }
  475. return ( err);
  476. } // WriteRegistryStringW()
  477. HRESULT
  478. ReadRegistryStringA(
  479. HKEY hkey,
  480. LPCWSTR pszValueNameW,
  481. LPCWSTR pszDefaultValueW,
  482. BOOL fExpand,
  483. LPWSTR * ppwszResult
  484. )
  485. {
  486. WCHAR * pszBuffer1 = NULL;
  487. WCHAR * pszBuffer2 = NULL;
  488. DWORD cbBuffer;
  489. DWORD dwType;
  490. DWORD err = NOERROR;
  491. CHAR *pszValueNameA = NULL;
  492. if (!ppwszResult) {
  493. return STIERR_INVALID_PARAM;
  494. }
  495. *ppwszResult = NULL;
  496. if ( !SUCCEEDED(OSUtil_GetAnsiString(&pszValueNameA,pszValueNameW))) {
  497. return STIERR_INVALID_PARAM;
  498. }
  499. //
  500. // Determine the buffer size.
  501. //
  502. pszBuffer1 = NULL;
  503. pszBuffer2 = NULL;
  504. cbBuffer = 0;
  505. if( hkey == NULL ) {
  506. //
  507. // Pretend the key wasn't found.
  508. //
  509. err = ERROR_FILE_NOT_FOUND;
  510. }
  511. else {
  512. err = RegQueryValueExA( hkey,
  513. pszValueNameA,
  514. NULL,
  515. &dwType,
  516. NULL,
  517. &cbBuffer );
  518. if( ( err == NO_ERROR ) || ( err == ERROR_MORE_DATA ) ) {
  519. if( ( dwType != REG_SZ ) &&
  520. ( dwType != REG_MULTI_SZ ) &&
  521. ( dwType != REG_EXPAND_SZ ) ) {
  522. //
  523. // Type mismatch, registry data NOT a string.
  524. // Use default.
  525. //
  526. err = ERROR_FILE_NOT_FOUND;
  527. }
  528. else {
  529. //
  530. // Item found, allocate a buffer.
  531. //
  532. if (!SUCCEEDED(AllocCbPpv(2*cbBuffer+sizeof(WCHAR),&pszBuffer1)) ){
  533. err = GetLastError();
  534. }
  535. else {
  536. //
  537. // Now read the value into the buffer.
  538. //
  539. //if (g_NoUnicodePlatform) {
  540. DWORD dwType;
  541. err = RegQueryValueExA( hkey,
  542. pszValueNameA,
  543. NULL,
  544. &dwType,
  545. (LPBYTE)pszBuffer1,
  546. &cbBuffer );
  547. //
  548. // The string came back as ANSI but we need UNICODE. Conversion in place
  549. // is not allowed, so do it with second buffer
  550. //
  551. if (SUCCEEDED(AllocCbPpv(2*cbBuffer+sizeof(WCHAR),&pszBuffer2))){
  552. AToU(pszBuffer2,cbBuffer,(LPSTR)pszBuffer1);
  553. memcpy(pszBuffer1,pszBuffer2,2*cbBuffer+sizeof(WCHAR));
  554. FreePpv(&pszBuffer2);
  555. //
  556. // Truncate returned string to MAX_REG_CHAR characters
  557. // (only for REG_SZ)
  558. //
  559. if ((dwType == REG_SZ) && (cbBuffer >= MAX_REG_CHAR)) {
  560. pszBuffer1[MAX_REG_CHAR] = L'\0';
  561. }
  562. }
  563. //}
  564. }
  565. }
  566. }
  567. }
  568. FreePpv(&pszValueNameA);
  569. //if( err == ERROR_FILE_NOT_FOUND ) {
  570. if( err != NOERROR ) {
  571. //
  572. // Item not found, use empty string (L"") as value
  573. //
  574. err = NO_ERROR;
  575. if( pszDefaultValueW != NULL ) {
  576. if (!SUCCEEDED(AllocCbPpv((OSUtil_StrLenW(L"") + 1) * sizeof(WCHAR),&pszBuffer1))) {
  577. err = GetLastError();
  578. }
  579. else {
  580. OSUtil_lstrcpyW( pszBuffer1, L"" );
  581. }
  582. }
  583. }
  584. if( err != NO_ERROR )
  585. {
  586. //
  587. // Tragic error reading registry, abort now.
  588. //
  589. goto ErrorCleanup;
  590. }
  591. //
  592. // pszBuffer1 holds the registry value. Now expand
  593. // the environment strings if necessary.
  594. //
  595. if( !fExpand ) {
  596. *ppwszResult = pszBuffer1;
  597. return S_OK;
  598. }
  599. #if 0
  600. // Does not work on Win95 ?
  601. //
  602. // Returns number of characters
  603. //
  604. cbBuffer = ExpandEnvironmentStrings( pszBuffer1,
  605. NULL,
  606. 0 );
  607. if (!SUCCEEDED(OSUtil_GetAnsiString(&pszBuffer2, (cbBuffer+1)*sizeof(TCHAR) ))){
  608. goto ErrorCleanup;
  609. }
  610. if( ExpandEnvironmentStrings( pszBuffer1,
  611. pszBuffer2,
  612. cbBuffer ) > cbBuffer ) {
  613. goto ErrorCleanup;
  614. }
  615. //
  616. // pszBuffer2 now contains the registry value with
  617. // environment strings expanded.
  618. //
  619. FreePpv(&pszBuffer1);
  620. return pszBuffer2;
  621. #endif
  622. ErrorCleanup:
  623. //
  624. // Something tragic happend; free any allocated buffers
  625. // and return NULL to the caller, indicating failure.
  626. //
  627. FreePpv(&pszValueNameA);
  628. FreePpv(&pszBuffer1);
  629. FreePpv(&pszBuffer2);
  630. return HRESULT_FROM_WIN32(err);
  631. }
  632. HRESULT
  633. ReadRegistryStringW(
  634. HKEY hkey,
  635. LPCWSTR pszValueNameW,
  636. LPCWSTR pszDefaultValueW,
  637. BOOL fExpand,
  638. LPWSTR * ppwszResult
  639. )
  640. {
  641. WCHAR * pszBuffer1 = NULL;
  642. DWORD cbBuffer;
  643. DWORD dwType;
  644. DWORD err = NOERROR;
  645. if (!ppwszResult) {
  646. return STIERR_INVALID_PARAM;
  647. }
  648. *ppwszResult = NULL;
  649. //
  650. // Determine the buffer size.
  651. //
  652. pszBuffer1 = NULL;
  653. cbBuffer = 0;
  654. if( hkey == NULL ) {
  655. //
  656. // Pretend the key wasn't found.
  657. //
  658. err = ERROR_FILE_NOT_FOUND;
  659. }
  660. else {
  661. err = RegQueryValueExW( hkey,
  662. pszValueNameW,
  663. NULL,
  664. &dwType,
  665. NULL,
  666. &cbBuffer );
  667. if( ( err == NO_ERROR ) || ( err == ERROR_MORE_DATA ) ) {
  668. if( ( dwType != REG_SZ ) &&
  669. ( dwType != REG_MULTI_SZ ) &&
  670. ( dwType != REG_EXPAND_SZ ) ) {
  671. //
  672. // Type mismatch, registry data NOT a string.
  673. // Use default.
  674. //
  675. err = ERROR_FILE_NOT_FOUND;
  676. }
  677. else {
  678. //
  679. // Item found, allocate a buffer.
  680. //
  681. if (!SUCCEEDED(AllocCbPpv(cbBuffer+sizeof(WCHAR),&pszBuffer1)) ){
  682. err = GetLastError();
  683. }
  684. else {
  685. //
  686. // Now read the value into the buffer.
  687. //
  688. DWORD dwType;
  689. err = RegQueryValueExW( hkey,
  690. pszValueNameW,
  691. NULL,
  692. &dwType,
  693. (LPBYTE)pszBuffer1,
  694. &cbBuffer );
  695. }
  696. }
  697. }
  698. }
  699. if( err != NOERROR ) {
  700. //
  701. // Item not found, use empty string (L"") as value
  702. //
  703. err = NO_ERROR;
  704. if( pszDefaultValueW != NULL ) {
  705. if (!SUCCEEDED(AllocCbPpv((OSUtil_StrLenW(L"") + 1) * sizeof(WCHAR),&pszBuffer1))) {
  706. err = GetLastError();
  707. }
  708. else {
  709. OSUtil_lstrcpyW( pszBuffer1, L"" );
  710. }
  711. }
  712. }
  713. if( err != NO_ERROR )
  714. {
  715. //
  716. // Tragic error reading registry, abort now.
  717. //
  718. goto ErrorCleanup;
  719. }
  720. //
  721. // pszBuffer1 holds the registry value. Now expand
  722. // the environment strings if necessary.
  723. //
  724. if( !fExpand ) {
  725. *ppwszResult = pszBuffer1;
  726. return S_OK;
  727. }
  728. ErrorCleanup:
  729. //
  730. // Something tragic happend; free any allocated buffers
  731. // and return NULL to the caller, indicating failure.
  732. //
  733. FreePpv(&pszBuffer1);
  734. return HRESULT_FROM_WIN32(err);
  735. }
  736. HANDLE
  737. WINAPI
  738. OSUtil_CreateFileW(
  739. LPCWSTR lpszFileNameW,
  740. DWORD dwDesiredAccess,
  741. DWORD dwShareMode,
  742. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  743. DWORD dwCreationDisposition,
  744. DWORD dwFlagsAndAttributes,
  745. HANDLE hTemplateFile
  746. )
  747. {
  748. HANDLE hRet = INVALID_HANDLE_VALUE;
  749. if (g_NoUnicodePlatform) {
  750. CHAR *pFileNameA = NULL;
  751. if ( SUCCEEDED(OSUtil_GetAnsiString(&pFileNameA,lpszFileNameW))) {
  752. hRet = CreateFileA(pFileNameA,
  753. dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,
  754. dwFlagsAndAttributes,hTemplateFile);
  755. FreePpv(&pFileNameA);
  756. }
  757. else {
  758. DebugOutPtszV(DbgFl,TEXT("Failed in LoadLibraryW"));
  759. hRet = INVALID_HANDLE_VALUE;
  760. }
  761. }
  762. else {
  763. hRet = CreateFileW(lpszFileNameW,
  764. dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,
  765. dwFlagsAndAttributes,hTemplateFile);
  766. }
  767. return hRet;
  768. } // OSUtil_LoadLibrary
  769. HRESULT
  770. WINAPI
  771. ExtractCommandLineArgumentW(
  772. LPCSTR lpszSwitchName,
  773. LPWSTR pwszSwitchValue
  774. )
  775. {
  776. HRESULT hres;
  777. LPSTR lpszCommandLine;
  778. LPSTR lpszSwitch;
  779. LPSTR pszT;
  780. DWORD cch;
  781. lpszCommandLine = GetCommandLineA();
  782. if (!lpszCommandLine || !*lpszCommandLine) {
  783. return STIERR_GENERIC;
  784. }
  785. if (!pwszSwitchValue) {
  786. return STIERR_GENERIC;
  787. }
  788. // Search for switch with given name
  789. lpszSwitch = strstr(lpszCommandLine,lpszSwitchName);
  790. if (!lpszSwitch ) {
  791. return STIERR_GENERIC;
  792. }
  793. lpszSwitch += lstrlenA(lpszSwitchName);
  794. if (*lpszSwitch != ':') {
  795. return STIERR_GENERIC;
  796. }
  797. lpszSwitch=CharNextA(lpszSwitch);
  798. // Skip till space
  799. pszT = lpszSwitch;
  800. while (*pszT && *pszT > ' ') {
  801. pszT = CharNextA(pszT);
  802. }
  803. cch = MultiByteToWideChar(CP_ACP, 0,
  804. lpszSwitch, (INT)(pszT-lpszSwitch),
  805. pwszSwitchValue,STI_MAX_INTERNAL_NAME_LENGTH
  806. );
  807. pwszSwitchValue[cch] = L'\0';
  808. hres = (cch) ? STI_OK : HRESULT_FROM_WIN32(GetLastError());
  809. return hres;
  810. }
  811. HRESULT
  812. WINAPI
  813. ExtractCommandLineArgumentA(
  814. LPCSTR lpszSwitchName,
  815. LPSTR pszSwitchValue
  816. )
  817. {
  818. HRESULT hres;
  819. LPSTR lpszCommandLine;
  820. LPSTR lpszSwitch;
  821. LPSTR pszT;
  822. DWORD cch;
  823. lpszCommandLine = GetCommandLineA();
  824. if (!lpszCommandLine || !*lpszCommandLine) {
  825. return STIERR_GENERIC;
  826. }
  827. if (!pszSwitchValue) {
  828. return STIERR_GENERIC;
  829. }
  830. // Search for switch with given name
  831. lpszSwitch = strstr(lpszCommandLine,lpszSwitchName);
  832. if (!lpszSwitch ) {
  833. return STIERR_GENERIC;
  834. }
  835. lpszSwitch += lstrlenA(lpszSwitchName);
  836. if (*lpszSwitch != ':') {
  837. return STIERR_GENERIC;
  838. }
  839. lpszSwitch=CharNextA(lpszSwitch);
  840. // Skip till space
  841. pszT = lpszSwitch;
  842. while (*pszT && *pszT > ' ') {
  843. pszT = CharNextA(pszT);
  844. }
  845. cch = min((INT)(pszT-lpszSwitch),STI_MAX_INTERNAL_NAME_LENGTH);
  846. memcpy(pszSwitchValue,lpszSwitch,cch);
  847. pszSwitchValue[cch] = L'\0';
  848. hres = (cch) ? STI_OK : STIERR_INVALID_PARAM;
  849. return hres;
  850. }
  851. /*****************************************************************************
  852. *
  853. * @doc INTERNAL
  854. *
  855. * @func HRESULT | DupEventHandle |
  856. *
  857. * Duplicate an event handle intra-process-ly. If the incoming
  858. * handle is NULL, then so is the output handle (and the call
  859. * succeeds).
  860. *
  861. * @parm HANDLE | h |
  862. *
  863. * Source handle.
  864. *
  865. * @parm LPHANDLE | phOut |
  866. *
  867. * Receives output handle.
  868. *
  869. *****************************************************************************/
  870. HRESULT EXTERNAL
  871. DupEventHandle(HANDLE h, LPHANDLE phOut)
  872. {
  873. HRESULT hres;
  874. EnterProc(DupEventHandle, (_ "p", h));
  875. if (h) {
  876. HANDLE hProcessMe = GetCurrentProcess();
  877. if (DuplicateHandle(hProcessMe, h, hProcessMe, phOut,
  878. EVENT_MODIFY_STATE, 0, 0)) {
  879. hres = S_OK;
  880. } else {
  881. hres = hresLe(GetLastError());
  882. }
  883. } else {
  884. *phOut = h;
  885. hres = S_OK;
  886. }
  887. ExitOleProc();
  888. return hres;
  889. }
  890. void
  891. WINAPI
  892. StiLogTrace(
  893. DWORD dwMessageType,
  894. DWORD idMessage,
  895. ...
  896. )
  897. {
  898. va_list list;
  899. va_start (list, idMessage);
  900. if(g_hStiFileLog) {
  901. TCHAR *pchBuff = NULL;
  902. DWORD cch;
  903. HMODULE hm;
  904. DWORD dwError;
  905. pchBuff = NULL;
  906. hm = GetModuleHandleA("STI.dll") ;
  907. cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  908. FORMAT_MESSAGE_MAX_WIDTH_MASK |
  909. FORMAT_MESSAGE_FROM_HMODULE,
  910. hm,
  911. idMessage,
  912. 0,
  913. (LPTSTR) &pchBuff,
  914. 1024,
  915. (va_list *)&list
  916. );
  917. dwError = GetLastError();
  918. if (cch && pchBuff) {
  919. ReportStiLogMessage(g_hStiFileLog,
  920. dwMessageType,
  921. pchBuff);
  922. }
  923. if (pchBuff) {
  924. LocalFree(pchBuff);
  925. }
  926. }
  927. va_end(list);
  928. }