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.

1136 lines
22 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. Util.c
  6. Abstract:
  7. Uitility routines for printer migration from Win9x to NT
  8. Author:
  9. Muhunthan Sivapragasam (MuhuntS) 02-Jan-1996
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. VOID
  14. DebugMsg(
  15. LPCSTR pszFormat,
  16. ...
  17. )
  18. /*++
  19. Routine Description:
  20. On debug builds brings up a message box on severe errors
  21. Arguments:
  22. pszFormat : Format string
  23. Return Value:
  24. None
  25. --*/
  26. {
  27. #if DBG
  28. LPSTR psz;
  29. CHAR szMsg[1024];
  30. va_list vargs;
  31. va_start(vargs, pszFormat);
  32. vsprintf(szMsg, pszFormat, vargs);
  33. va_end(vargs);
  34. #ifdef MYDEBUG
  35. if ( psz = GetStringFromRcFileA(IDS_TITLE) ) {
  36. MessageBoxA(NULL, szMsg, psz, MB_OK);
  37. FreeMem(psz);
  38. }
  39. #else
  40. OutputDebugStringA("Printing Migration : ");
  41. OutputDebugStringA(szMsg);
  42. OutputDebugStringA("\n");
  43. #endif
  44. #endif
  45. }
  46. VOID
  47. LogError(
  48. IN LogSeverity Severity,
  49. IN UINT uMessageId,
  50. ...
  51. )
  52. /*++
  53. Routine Description:
  54. Logs an error in the setup error log on NT side when something can not be
  55. upgraded
  56. Arguments:
  57. uMessageId : Id to string in .rc file
  58. Return Value:
  59. None
  60. --*/
  61. {
  62. LPSTR pszFormat;
  63. CHAR szMsg[1024];
  64. va_list vargs;
  65. va_start(vargs, uMessageId);
  66. pszFormat = GetStringFromRcFileA(uMessageId);
  67. if ( pszFormat ) {
  68. wvsprintfA(szMsg, pszFormat, vargs);
  69. DebugMsg("%s", szMsg);
  70. SetupLogErrorA(szMsg, Severity);
  71. }
  72. FreeMem(pszFormat);
  73. va_end(vargs);
  74. }
  75. LPSTR
  76. ErrorMsg(
  77. VOID
  78. )
  79. /*++
  80. Routine Description:
  81. Returns the error message string from a Win32 error
  82. Arguments:
  83. None
  84. Return Value:
  85. Pointer to a message string. Caller should free the string
  86. --*/
  87. {
  88. DWORD dwLastError;
  89. LPSTR pszStr = NULL;
  90. if ( !(dwLastError = GetLastError()) )
  91. dwLastError = STG_E_UNKNOWN;
  92. FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  93. FORMAT_MESSAGE_IGNORE_INSERTS |
  94. FORMAT_MESSAGE_FROM_SYSTEM |
  95. FORMAT_MESSAGE_MAX_WIDTH_MASK,
  96. NULL,
  97. dwLastError,
  98. 0,
  99. (LPSTR)&pszStr,
  100. 0,
  101. NULL);
  102. return pszStr;
  103. }
  104. PVOID
  105. AllocMem(
  106. IN UINT cbSize
  107. )
  108. /*++
  109. Routine Description:
  110. Allocate memory from the heap
  111. Arguments:
  112. cbSize : Byte count
  113. Return Value:
  114. Pointer to the allocated memory
  115. --*/
  116. {
  117. return LocalAlloc(LPTR, cbSize);
  118. }
  119. VOID
  120. FreeMem(
  121. IN PVOID p
  122. )
  123. /*++
  124. Routine Description:
  125. Free memory allocated on the heap
  126. Arguments:
  127. p : Pointer to the memory to be freed
  128. Return Value:
  129. None
  130. --*/
  131. {
  132. LocalFree(p);
  133. }
  134. LPSTR
  135. AllocStrA(
  136. LPCSTR pszStr
  137. )
  138. /*++
  139. Routine Description:
  140. Allocate memory and make a copy of an ansi string field
  141. Arguments:
  142. pszStr : String to copy
  143. Return Value:
  144. Pointer to the copied string. Memory is allocated.
  145. --*/
  146. {
  147. LPSTR pszRet = NULL;
  148. if ( pszStr && *pszStr ) {
  149. pszRet = AllocMem((strlen(pszStr) + 1) * sizeof(CHAR));
  150. if ( pszRet )
  151. strcpy(pszRet, pszStr);
  152. }
  153. return pszRet;
  154. }
  155. LPWSTR
  156. AllocStrW(
  157. LPCWSTR pszStr
  158. )
  159. /*++
  160. Routine Description:
  161. Allocate memory and make a copy of a unicode string field
  162. Arguments:
  163. pszStr : String to copy
  164. Return Value:
  165. Pointer to the copied string. Memory is allocated.
  166. --*/
  167. {
  168. LPWSTR pszRet = NULL;
  169. if ( pszStr && *pszStr ) {
  170. pszRet = AllocMem((wcslen(pszStr) + 1) * sizeof(WCHAR));
  171. if ( pszRet )
  172. wcscpy(pszRet, pszStr);
  173. }
  174. return pszRet;
  175. }
  176. LPWSTR
  177. AllocStrWFromStrA(
  178. LPCSTR pszStr
  179. )
  180. /*++
  181. Routine Description:
  182. Returns the unicode string for a give ansi string. Memory is allocated.
  183. Arguments:
  184. pszStr : Gives the ansi string to copy
  185. Return Value:
  186. Pointer to the copied unicode string. Memory is allocated.
  187. --*/
  188. {
  189. DWORD dwLen;
  190. LPWSTR pszRet = NULL;
  191. if ( pszStr &&
  192. *pszStr &&
  193. (dwLen = strlen(pszStr)) &&
  194. (pszRet = AllocMem((dwLen + 1) * sizeof(WCHAR))) ) {
  195. if ( MultiByteToWideChar(CP_ACP,
  196. MB_PRECOMPOSED,
  197. pszStr,
  198. dwLen,
  199. pszRet,
  200. dwLen) ) {
  201. pszRet[dwLen] = 0;
  202. } else {
  203. FreeMem(pszRet);
  204. pszRet = NULL;
  205. }
  206. }
  207. return pszRet;
  208. }
  209. LPSTR
  210. AllocStrAFromStrW(
  211. LPCWSTR pszStr
  212. )
  213. /*++
  214. Routine Description:
  215. Returns the ansi string for a give unicode string. Memory is allocated.
  216. Arguments:
  217. pszStr : Gives the ansi string to copy
  218. Return Value:
  219. Pointer to the copied ansi string. Memory is allocated.
  220. --*/
  221. {
  222. DWORD dwLen;
  223. LPSTR pszRet = NULL;
  224. if ( pszStr &&
  225. *pszStr &&
  226. (dwLen = wcslen(pszStr)) &&
  227. (pszRet = AllocMem((dwLen + 1 ) * sizeof(CHAR))) ) {
  228. WideCharToMultiByte(CP_ACP,
  229. 0,
  230. pszStr,
  231. dwLen,
  232. pszRet,
  233. dwLen,
  234. NULL,
  235. NULL );
  236. }
  237. return pszRet;
  238. }
  239. BOOL
  240. WriteToFile(
  241. HANDLE hFile,
  242. LPCSTR pszFormat,
  243. ...
  244. )
  245. /*++
  246. Routine Description:
  247. Format and write a string to the text file. This is used to write the
  248. printing configuration on Win9x
  249. Arguments:
  250. hFile : File handle
  251. pszFormat : Format string for the message
  252. Return Value:
  253. None
  254. --*/
  255. {
  256. CHAR szMsg[1024];
  257. va_list vargs;
  258. DWORD dwSize, dwWritten;
  259. BOOL bRet;
  260. bRet = TRUE;
  261. va_start(vargs, pszFormat);
  262. vsprintf(szMsg, pszFormat, vargs);
  263. va_end(vargs);
  264. dwSize = strlen(szMsg) * sizeof(CHAR);
  265. if ( !WriteFile(hFile, (LPCVOID)szMsg, dwSize, &dwWritten, NULL) ||
  266. dwSize != dwWritten ) {
  267. bRet = FALSE;
  268. }
  269. return bRet;
  270. }
  271. VOID
  272. WriteString(
  273. IN HANDLE hFile,
  274. IN OUT LPBOOL pbFail,
  275. IN LPCSTR pszStr
  276. )
  277. /*++
  278. Routine Description:
  279. Writes a string to the upgrade file on Win9x side. Since spooler strings
  280. (ex. printer name, driver name) can have space in them we would write
  281. all strings with []\n. So we can read strings with space on NT.
  282. Arguments:
  283. hFile : File handle
  284. pszFormat : Format string for the message
  285. pszStr : String to write
  286. Return Value:
  287. None
  288. --*/
  289. {
  290. DWORD dwLen;
  291. if ( pszStr ) {
  292. dwLen = strlen(pszStr);
  293. WriteToFile(hFile, "%3d [%s]\n", dwLen, pszStr);
  294. }
  295. }
  296. LPSTR
  297. GetStringFromRcFileA(
  298. UINT uId
  299. )
  300. /*++
  301. Routine Description:
  302. Load a string from the .rc file and make a copy of it by doing AllocStr
  303. Arguments:
  304. uId : Identifier for the string to be loaded
  305. Return Value:
  306. String value loaded, NULL on error. Caller should free the memory
  307. --*/
  308. {
  309. CHAR buf[MAX_PATH];
  310. if ( LoadStringA(g_hInst, uId, buf, sizeof(buf) ))
  311. return AllocStrA(buf);
  312. else
  313. return NULL;
  314. }
  315. VOID
  316. ReadString(
  317. IN HANDLE hFile,
  318. OUT LPSTR *ppszParam1,
  319. OUT LPSTR *ppszParam2
  320. )
  321. {
  322. CHAR c;
  323. LPSTR pszParameter1;
  324. LPSTR pszParameter2;
  325. DWORD dwLen;
  326. CHAR LineBuffer[MAX_PATH];
  327. DWORD Idx;
  328. //
  329. // Initialize local.
  330. //
  331. c = 0;
  332. pszParameter1 = NULL;
  333. pszParameter2 = NULL;
  334. dwLen = 0;
  335. Idx = 0;
  336. memset(LineBuffer, 0, sizeof(LineBuffer));
  337. //
  338. // Initialize caller buffer
  339. //
  340. *ppszParam1 = NULL;
  341. *ppszParam2 = NULL;
  342. //
  343. // First skip space/\r/\n.
  344. //
  345. c = (CHAR) My_fgetc(hFile);
  346. while( (' ' == c)
  347. || ('\n' == c)
  348. || ('\r' == c) )
  349. {
  350. c = (CHAR) My_fgetc(hFile);
  351. }
  352. //
  353. // See if it's EOF.
  354. //
  355. if(EOF == c){
  356. //
  357. // End of file.
  358. //
  359. goto ReadString_return;
  360. }
  361. //
  362. // Get a line.
  363. //
  364. Idx = 0;
  365. while( ('\n' != c) && (EOF != c) ){
  366. LineBuffer[Idx++] = c;
  367. c = (CHAR) My_fgetc(hFile);
  368. } // while( ('\n' != c) && (EOF != c) )
  369. dwLen = Idx;
  370. //
  371. // See if it's EOF.
  372. //
  373. if(EOF == c){
  374. //
  375. // Illegal migration file.
  376. //
  377. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file.", LogSevError);
  378. goto ReadString_return;
  379. }
  380. //
  381. // See if it's double quated.
  382. //
  383. if('\"' == LineBuffer[0]){
  384. pszParameter1 = &LineBuffer[1];
  385. Idx = 1;
  386. } else { // if('\"' == LineBuffer[0])
  387. //
  388. // There's no '"'. Invalid migration file.
  389. //
  390. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file with no Quote.", LogSevError);
  391. goto ReadString_return;
  392. } // if('\"' == LineBuffer[0])
  393. //
  394. // Find next '"' and replace with '\0'.
  395. //
  396. for(;'\"' != LineBuffer[Idx]; Idx++);
  397. LineBuffer[Idx] = '\0';
  398. //
  399. // Find next (3rd) '"', it's beginning of 2nd parameter.
  400. //
  401. for(;'\"' != LineBuffer[Idx]; Idx++);
  402. pszParameter2 = &LineBuffer[++Idx];
  403. //
  404. // Find last '"' and replace with '\0'.
  405. //
  406. for(;'\"' != LineBuffer[Idx]; Idx++);
  407. LineBuffer[Idx] = '\0';
  408. //
  409. // Allocate buffer for returning string.
  410. //
  411. *ppszParam1 = AllocStrA(pszParameter1);
  412. *ppszParam2 = AllocStrA(pszParameter2);
  413. ReadString_return:
  414. return;
  415. } // ReadString()
  416. VOID
  417. ReadDword(
  418. IN HANDLE hFile,
  419. IN LPSTR pszLine,
  420. IN DWORD dwLineSize,
  421. IN LPSTR pszPrefix,
  422. OUT LPDWORD pdwValue,
  423. IN OUT LPBOOL pbFail
  424. )
  425. {
  426. LPSTR psz;
  427. if ( *pbFail || My_fgets(pszLine, dwLineSize, hFile) == NULL ) {
  428. *pbFail = TRUE;
  429. return;
  430. }
  431. //
  432. // First check the prefix matches to make sure we are in the right line
  433. //
  434. for ( psz = (LPSTR)pszLine ;
  435. *pszPrefix && *psz == *pszPrefix ;
  436. ++psz, ++pszPrefix )
  437. ;
  438. if ( *pszPrefix ) {
  439. *pbFail = TRUE;
  440. return;
  441. }
  442. //
  443. // Skip spaces
  444. //
  445. while ( *psz && *psz == ' ' )
  446. ++psz;
  447. *pdwValue = atoi(psz);
  448. }
  449. VOID
  450. ReadDevMode(
  451. IN HANDLE hFile,
  452. OUT LPDEVMODEA *ppDevMode,
  453. IN OUT LPBOOL pbFail
  454. )
  455. {
  456. LPSTR pszPrefix = "DevMode:";
  457. CHAR c;
  458. DWORD dwLen;
  459. LPINT ptr;
  460. if ( *pbFail )
  461. return;
  462. // First skip the prefix
  463. //
  464. while ( *pszPrefix && (c = (CHAR) My_fgetc(hFile)) == *pszPrefix++ )
  465. ;
  466. if ( *pszPrefix )
  467. goto Fail;
  468. //
  469. // Skip spaces
  470. //
  471. while ( (c = (CHAR) My_fgetc(hFile)) == ' ' )
  472. ;
  473. //
  474. // Now is the devmode size
  475. //
  476. if ( !isdigit(c) )
  477. goto Fail;
  478. dwLen = c - '0';
  479. while ( isdigit(c = (CHAR) My_fgetc(hFile)) )
  480. dwLen = dwLen * 10 + c - '0';
  481. if ( dwLen == 0 )
  482. return;
  483. if ( c != ' ' )
  484. goto Fail;
  485. //
  486. // Now the devmode is there between []
  487. //
  488. if ( *ppDevMode = (LPDEVMODEA) AllocMem(dwLen) ) {
  489. if ( (c = (CHAR) My_fgetc(hFile)) != '[' )
  490. goto Fail;
  491. if ( dwLen != My_fread((LPVOID)*ppDevMode, dwLen, hFile) )
  492. goto Fail;
  493. //
  494. // Make sure now we have "]\n" to End
  495. //
  496. if ( (CHAR) My_fgetc(hFile) != ']' || (CHAR) My_fgetc(hFile) != '\n' ) {
  497. DebugMsg("Char check fails");
  498. goto Fail;
  499. }
  500. return; // Succesful exit
  501. }
  502. Fail:
  503. *pbFail = TRUE;
  504. }
  505. LONG
  506. WriteRegistryToFile(
  507. IN HANDLE hFile,
  508. IN HKEY hKey,
  509. IN LPCSTR pszPath
  510. )
  511. {
  512. LONG lError;
  513. HKEY hSubKey;
  514. DWORD dwValueSize;
  515. DWORD dwDataSize;
  516. DWORD dwSubKeySize;
  517. DWORD dwTypeBuffer;
  518. PCHAR pSubKeyBuffer;
  519. PCHAR pValueBuffer;
  520. PCHAR pDataBuffer;
  521. DWORD Idx;
  522. //
  523. // Initialize local.
  524. //
  525. lError = ERROR_SUCCESS;
  526. hSubKey = (HKEY)INVALID_HANDLE_VALUE;
  527. dwValueSize = 0;
  528. dwDataSize = 0;
  529. dwSubKeySize = 0;
  530. dwTypeBuffer = 0;
  531. Idx = 0;
  532. pSubKeyBuffer = NULL;
  533. pValueBuffer = NULL;
  534. pDataBuffer = NULL;
  535. //
  536. // Query necessary buffer size.
  537. //
  538. lError = RegQueryInfoKeyA(hKey,
  539. NULL,
  540. NULL,
  541. NULL,
  542. NULL,
  543. &dwSubKeySize,
  544. NULL,
  545. NULL,
  546. &dwValueSize,
  547. &dwDataSize,
  548. NULL,
  549. NULL);
  550. if(ERROR_SUCCESS != lError){
  551. //
  552. // Unable to retrieve key info.
  553. //
  554. goto WriteRegistryToFile_return;
  555. } // if(ERROR_SUCCESS != lError)
  556. //
  557. // Allocate buffers.
  558. //
  559. dwValueSize = (dwValueSize+1+1) * sizeof(CHAR);
  560. dwSubKeySize = (dwSubKeySize+1) * sizeof(CHAR);
  561. pValueBuffer = AllocMem(dwValueSize);
  562. pDataBuffer = AllocMem(dwDataSize);
  563. pSubKeyBuffer = AllocMem(dwSubKeySize);
  564. if( (NULL == pValueBuffer)
  565. || (NULL == pDataBuffer)
  566. || (NULL == pSubKeyBuffer) )
  567. {
  568. //
  569. // Insufficient memory.
  570. //
  571. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to allocate buffer.", LogSevError);
  572. lError = ERROR_NOT_ENOUGH_MEMORY;
  573. goto WriteRegistryToFile_return;
  574. } // if(NULL == pDataBuffer)
  575. //
  576. // Indicate beginning of this subkey to the file.
  577. //
  578. WriteToFile(hFile, "\"%s\" = \"BEGIN\"\r\n", pszPath);
  579. //
  580. // Enumerate all values.
  581. //
  582. while(ERROR_SUCCESS == lError){
  583. DWORD dwLocalValueSize;
  584. DWORD dwLocalDataSize;
  585. //
  586. // Reset buffer and size.
  587. //
  588. dwLocalValueSize = dwValueSize;
  589. dwLocalDataSize = dwDataSize;
  590. memset(pValueBuffer, 0, dwValueSize);
  591. memset(pDataBuffer, 0, dwDataSize);
  592. //
  593. // Acquire registry value/data..
  594. //
  595. lError = RegEnumValueA(hKey,
  596. Idx,
  597. pValueBuffer,
  598. &dwLocalValueSize,
  599. NULL,
  600. &dwTypeBuffer,
  601. pDataBuffer,
  602. &dwLocalDataSize);
  603. if(ERROR_NO_MORE_ITEMS == lError){
  604. //
  605. // End of data.
  606. //
  607. continue;
  608. } // if(ERROR_NO_MORE_ITEMS == lError)
  609. if(ERROR_SUCCESS != lError){
  610. //
  611. // Unable to read registry value.
  612. //
  613. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to acqure registry value/data.", LogSevError);
  614. goto WriteRegistryToFile_return;
  615. } // if(ERROR_NO_MORE_ITEMS == lError)
  616. //
  617. // Write this value to a file.
  618. //
  619. lError = WriteRegistryValueToFile(hFile,
  620. pValueBuffer,
  621. dwTypeBuffer,
  622. pDataBuffer,
  623. dwLocalDataSize);
  624. if(ERROR_SUCCESS != lError){
  625. //
  626. // Unable to write to a file.
  627. //
  628. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to write to a file.", LogSevError);
  629. goto WriteRegistryToFile_return;
  630. } // if(ERROR_SUCCESS != lError)
  631. //
  632. // Goto next value.
  633. //
  634. Idx++;
  635. } // while(ERROR_SUCCESS == lError)
  636. //
  637. // Enumerate all sub keys.
  638. //
  639. lError = ERROR_SUCCESS;
  640. Idx = 0;
  641. while(ERROR_SUCCESS == lError){
  642. memset(pSubKeyBuffer, 0, dwSubKeySize);
  643. lError = RegEnumKeyA(hKey, Idx++, pSubKeyBuffer, dwSubKeySize);
  644. if(ERROR_SUCCESS == lError){
  645. //
  646. // There's sub key exists. Spew it to the file and store all the
  647. // values recursively.
  648. //
  649. lError = RegOpenKey(hKey, pSubKeyBuffer, &hSubKey);
  650. if(ERROR_SUCCESS != lError){
  651. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to open subkey.", LogSevError);
  652. continue;
  653. } // if(ERROR_SUCCESS != lError)
  654. //
  655. // Call subkey recursively.
  656. //
  657. lError = WriteRegistryToFile(hFile, hSubKey, pSubKeyBuffer);
  658. } // if(ERROR_SUCCESS == lError)
  659. } // while(ERROR_SUCCESS == lError)
  660. if(ERROR_NO_MORE_ITEMS == lError){
  661. //
  662. // Operation completed as expected.
  663. //
  664. lError = ERROR_SUCCESS;
  665. } // if(ERROR_NO_MORE_ITEMS == lError)
  666. //
  667. // Indicate end of this subkey to the file.
  668. //
  669. WriteToFile(hFile, "\"%s\" = \"END\"\r\n", pszPath);
  670. WriteRegistryToFile_return:
  671. //
  672. // Clean up.
  673. //
  674. if(NULL != pValueBuffer){
  675. FreeMem(pValueBuffer);
  676. } // if(NULL != pValueBuffer)
  677. if(NULL != pDataBuffer){
  678. FreeMem(pDataBuffer);
  679. } // if(NULL != pDataBuffer)
  680. if(NULL != pSubKeyBuffer){
  681. FreeMem(pSubKeyBuffer);
  682. } // if(NULL != pSubKeyBuffer)
  683. return lError;
  684. } // WriteRegistryToFile()
  685. LONG
  686. WriteRegistryValueToFile(
  687. HANDLE hFile,
  688. LPSTR pszValue,
  689. DWORD dwType,
  690. PCHAR pDataBuffer,
  691. DWORD dwSize
  692. )
  693. {
  694. LONG lError;
  695. PCHAR pSpewBuffer;
  696. DWORD Idx;
  697. //
  698. // Initialize locals.
  699. //
  700. lError = ERROR_SUCCESS;
  701. pSpewBuffer = NULL;
  702. //
  703. // Allocate buffer for actual spew.
  704. //
  705. pSpewBuffer = AllocMem(dwSize*3);
  706. if(NULL == pSpewBuffer){
  707. //
  708. // Unable to allocate buffer.
  709. //
  710. lError = ERROR_NOT_ENOUGH_MEMORY;
  711. goto WriteRegistryValueToFile_return;
  712. } // if(NULL == pSpewBuffer)
  713. for(Idx = 0; Idx < dwSize; Idx++){
  714. wsprintf(pSpewBuffer+Idx*3, "%02x", pDataBuffer[Idx]);
  715. *(pSpewBuffer+Idx*3+2) = ',';
  716. } // for(Idx = 0; Idx < dwSize; Idx++)
  717. *(pSpewBuffer+dwSize*3-1) = '\0';
  718. WriteToFile(hFile, "\"%s\" = \"%08x:%s\"\r\n", pszValue, dwType, pSpewBuffer);
  719. //
  720. // Operation succeeded.
  721. //
  722. lError = ERROR_SUCCESS;
  723. WriteRegistryValueToFile_return:
  724. //
  725. // Clean up.
  726. //
  727. if(NULL != pSpewBuffer){
  728. FreeMem(pSpewBuffer);
  729. } // if(NULL != pSpewBuffer)
  730. return lError;
  731. } // WriteRegistryValueToFile()
  732. LONG
  733. GetRegData(
  734. HKEY hKey,
  735. LPSTR pszValue,
  736. PCHAR *ppDataBuffer,
  737. PDWORD pdwType,
  738. PDWORD pdwSize
  739. )
  740. {
  741. LONG lError;
  742. PCHAR pTempBuffer;
  743. DWORD dwRequiredSize;
  744. DWORD dwType;
  745. //
  746. // Initialize local.
  747. //
  748. lError = ERROR_SUCCESS;
  749. pTempBuffer = NULL;
  750. dwRequiredSize = 0;
  751. dwType = 0;
  752. //
  753. // Get required size.
  754. //
  755. lError = RegQueryValueEx(hKey,
  756. pszValue,
  757. NULL,
  758. &dwType,
  759. NULL,
  760. &dwRequiredSize);
  761. if( (ERROR_SUCCESS != lError)
  762. || (0 == dwRequiredSize) )
  763. {
  764. pTempBuffer = NULL;
  765. goto GetRegData_return;
  766. } // if(ERROR_MORE_DATA != lError)
  767. //
  768. // If it doesn't need actual data, just bail out.
  769. //
  770. if(NULL == ppDataBuffer){
  771. lError = ERROR_SUCCESS;
  772. goto GetRegData_return;
  773. } // if(NULL == ppDataBuffer)
  774. //
  775. // Allocate buffer to receive data.
  776. //
  777. pTempBuffer = AllocMem(dwRequiredSize);
  778. if(NULL == pTempBuffer){
  779. //
  780. // Allocation failed.
  781. //
  782. SetupLogError("WIA Migration: GetRegData: ERROR!! Unable to allocate buffer.", LogSevError);
  783. lError = ERROR_NOT_ENOUGH_MEMORY;
  784. goto GetRegData_return;
  785. } // if(NULL == pTempBuffer)
  786. //
  787. // Query the data.
  788. //
  789. lError = RegQueryValueEx(hKey,
  790. pszValue,
  791. NULL,
  792. &dwType,
  793. pTempBuffer,
  794. &dwRequiredSize);
  795. if(ERROR_SUCCESS != lError){
  796. //
  797. // Data acquisition somehow failed. Free buffer.
  798. //
  799. goto GetRegData_return;
  800. } // if(ERROR_SUCCESS != lError)
  801. GetRegData_return:
  802. if(ERROR_SUCCESS != lError){
  803. //
  804. // Operation unsuccessful. Free the buffer if allocated.
  805. //
  806. if(NULL != pTempBuffer){
  807. FreeMem(pTempBuffer);
  808. pTempBuffer = NULL;
  809. } // if(NULL != pTempBuffer)
  810. } // if(ERROR_SUCCESS != lError)
  811. //
  812. // Copy the result.
  813. //
  814. if(NULL != pdwSize){
  815. *pdwSize = dwRequiredSize;
  816. } // if(NULL != pdwSize)
  817. if(NULL != ppDataBuffer){
  818. *ppDataBuffer = pTempBuffer;
  819. } // if(NULL != ppDataBuffer)
  820. if(NULL != pdwType){
  821. *pdwType = dwType;
  822. } // if(NULL != pdwType)
  823. return lError;
  824. } // GetRegData()
  825. VOID
  826. MyLogError(
  827. LPCSTR pszFormat,
  828. ...
  829. )
  830. {
  831. LPSTR psz;
  832. CHAR szMsg[1024];
  833. va_list vargs;
  834. if(NULL != pszFormat){
  835. va_start(vargs, pszFormat);
  836. vsprintf(szMsg, pszFormat, vargs);
  837. va_end(vargs);
  838. SetupLogError(szMsg, LogSevError);
  839. } // if(NULL != pszFormat)
  840. } // MyLogError()