Leaked source code of windows server 2003
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.

879 lines
18 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. PVOID
  14. AllocMem(
  15. IN UINT cbSize
  16. )
  17. /*++
  18. Routine Description:
  19. Allocate memory from the heap
  20. Arguments:
  21. cbSize : Byte count
  22. Return Value:
  23. Pointer to the allocated memory
  24. --*/
  25. {
  26. return LocalAlloc(LPTR, cbSize);
  27. }
  28. VOID
  29. FreeMem(
  30. IN PVOID p
  31. )
  32. /*++
  33. Routine Description:
  34. Free memory allocated on the heap
  35. Arguments:
  36. p : Pointer to the memory to be freed
  37. Return Value:
  38. None
  39. --*/
  40. {
  41. LocalFree(p);
  42. }
  43. LPSTR
  44. AllocStrA(
  45. LPCSTR pszStr
  46. )
  47. /*++
  48. Routine Description:
  49. Allocate memory and make a copy of an ansi string field
  50. Arguments:
  51. pszStr : String to copy
  52. Return Value:
  53. Pointer to the copied string. Memory is allocated.
  54. --*/
  55. {
  56. LPSTR pszRet = NULL;
  57. if ( pszStr && *pszStr ) {
  58. pszRet = AllocMem((strlen(pszStr) + 1) * sizeof(CHAR));
  59. if ( pszRet )
  60. strcpy(pszRet, pszStr);
  61. }
  62. return pszRet;
  63. }
  64. LPSTR
  65. AllocStrAFromStrW(
  66. LPCWSTR pszStr
  67. )
  68. /*++
  69. Routine Description:
  70. Returns the ansi string for a give unicode string. Memory is allocated.
  71. Arguments:
  72. pszStr : Gives the ansi string to copy
  73. Return Value:
  74. Pointer to the copied ansi string. Memory is allocated.
  75. --*/
  76. {
  77. DWORD dwLen;
  78. LPSTR pszRet = NULL;
  79. if ( pszStr &&
  80. *pszStr &&
  81. (dwLen = wcslen(pszStr)) &&
  82. (pszRet = AllocMem((dwLen + 1 ) * sizeof(CHAR))) ) {
  83. WideCharToMultiByte(CP_ACP,
  84. 0,
  85. pszStr,
  86. dwLen,
  87. pszRet,
  88. dwLen,
  89. NULL,
  90. NULL );
  91. }
  92. return pszRet;
  93. }
  94. BOOL
  95. WriteToFile(
  96. HANDLE hFile,
  97. LPCSTR pszFormat,
  98. ...
  99. )
  100. /*++
  101. Routine Description:
  102. Format and write a string to the text file. This is used to write the
  103. printing configuration on Win9x
  104. Arguments:
  105. hFile : File handle
  106. pszFormat : Format string for the message
  107. Return Value:
  108. None
  109. --*/
  110. {
  111. CHAR szMsg[MAX_LINELENGTH];
  112. int iResult;
  113. va_list vargs;
  114. DWORD dwSize, dwWritten;
  115. BOOL bRet;
  116. bRet = TRUE;
  117. va_start(vargs, pszFormat);
  118. // vsprintf(szMsg, pszFormat, vargs);
  119. iResult = StringCbVPrintfA(szMsg, sizeof(szMsg), pszFormat, vargs);
  120. va_end(vargs);
  121. dwSize = strlen(szMsg) * sizeof(CHAR);
  122. if ( !WriteFile(hFile, (LPCVOID)szMsg, dwSize, &dwWritten, NULL) ||
  123. dwSize != dwWritten ) {
  124. bRet = FALSE;
  125. }
  126. return bRet;
  127. }
  128. LPSTR
  129. GetStringFromRcFileA(
  130. UINT uId
  131. )
  132. /*++
  133. Routine Description:
  134. Load a string from the .rc file and make a copy of it by doing AllocStr
  135. Arguments:
  136. uId : Identifier for the string to be loaded
  137. Return Value:
  138. String value loaded, NULL on error. Caller should free the memory
  139. --*/
  140. {
  141. CHAR buf[MAX_LINELENGTH+1];
  142. if(0 != LoadStringA(g_hInst, uId, buf, sizeof(buf))){
  143. buf[sizeof(buf)-1] = '\0';
  144. return AllocStrA(buf);
  145. } else {
  146. return NULL;
  147. } // if(0 != LoadStringA(g_hInst, uId, buf, sizeof(buf)))
  148. } // GetStringFromRcFileA()
  149. VOID
  150. ReadString(
  151. IN HANDLE hFile,
  152. OUT LPSTR *ppszParam1,
  153. OUT LPSTR *ppszParam2
  154. )
  155. {
  156. CHAR c;
  157. LPSTR pszParameter1;
  158. LPSTR pszParameter2;
  159. DWORD dwLen;
  160. CHAR LineBuffer[MAX_LINELENGTH+1];
  161. DWORD Idx;
  162. PCHAR pCurrent;
  163. //
  164. // Initialize local.
  165. //
  166. c = 0;
  167. pszParameter1 = NULL;
  168. pszParameter2 = NULL;
  169. dwLen = 0;
  170. Idx = 0;
  171. pCurrent = NULL;
  172. memset(LineBuffer, 0, sizeof(LineBuffer));
  173. //
  174. // Initialize caller buffer
  175. //
  176. *ppszParam1 = NULL;
  177. *ppszParam2 = NULL;
  178. //
  179. // First skip space/\r/\n.
  180. //
  181. c = (CHAR) My_fgetc(hFile);
  182. while( (' ' == c)
  183. || ('\n' == c)
  184. || ('\r' == c) )
  185. {
  186. c = (CHAR) My_fgetc(hFile);
  187. }
  188. //
  189. // See if it's EOF.
  190. //
  191. if(EOF == c){
  192. //
  193. // End of file.
  194. //
  195. goto ReadString_return;
  196. }
  197. //
  198. // Get a line.
  199. //
  200. Idx = 0;
  201. while( ('\n' != c) && (EOF != c) && (Idx < sizeof(LineBuffer)-2) ){
  202. LineBuffer[Idx++] = c;
  203. c = (CHAR) My_fgetc(hFile);
  204. } // while( ('\n' != c) && (EOF != c) )
  205. dwLen = Idx;
  206. //
  207. // See if it's EOF.
  208. //
  209. if(EOF == c){
  210. //
  211. // Illegal migration file.
  212. //
  213. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file.\r\n", LogSevError);
  214. goto ReadString_return;
  215. } else if ('\n' != c) {
  216. //
  217. // A line too long.
  218. //
  219. SetupLogError("WIA Migration: ReadString: ERROR!! Reading line is too long.\r\n", LogSevError);
  220. goto ReadString_return;
  221. }
  222. //
  223. // See if it's double quated.
  224. //
  225. if('\"' != LineBuffer[0]){
  226. //
  227. // There's no '"'. Invalid migration file.
  228. //
  229. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file with no Quote.\r\n", LogSevError);
  230. goto ReadString_return;
  231. } // if('\"' != LineBuffer[0])
  232. pszParameter1 = &LineBuffer[1];
  233. pCurrent = &LineBuffer[1];
  234. //
  235. // Find next '"' and replace with '\0'.
  236. //
  237. pCurrent = strchr(pCurrent, '\"');
  238. if(NULL == pCurrent){
  239. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file.\r\n", LogSevError);
  240. goto ReadString_return;
  241. } // if(NULL == pCurrent)
  242. *pCurrent++ = '\0';
  243. //
  244. // Find next (3rd) '"', it's beginning of 2nd parameter.
  245. //
  246. pCurrent = strchr(pCurrent, '\"');
  247. if(NULL == pCurrent){
  248. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file.\r\n", LogSevError);
  249. goto ReadString_return;
  250. } // if(NULL == pCurrent)
  251. pCurrent++;
  252. pszParameter2 = pCurrent;
  253. //
  254. // Find last '"' and replace with '\0'.
  255. //
  256. pCurrent = strchr(pCurrent, '\"');
  257. if(NULL == pCurrent){
  258. SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file.\r\n", LogSevError);
  259. goto ReadString_return;
  260. } // if(NULL == pCurrent)
  261. *pCurrent = '\0';
  262. //
  263. // Allocate buffer for returning string.
  264. //
  265. *ppszParam1 = AllocStrA(pszParameter1);
  266. *ppszParam2 = AllocStrA(pszParameter2);
  267. ReadString_return:
  268. return;
  269. } // ReadString()
  270. LONG
  271. WriteRegistryToFile(
  272. IN HANDLE hFile,
  273. IN HKEY hKey,
  274. IN LPCSTR pszPath
  275. )
  276. {
  277. LONG lError;
  278. HKEY hSubKey;
  279. DWORD dwValueSize;
  280. DWORD dwDataSize;
  281. DWORD dwSubKeySize;
  282. DWORD dwTypeBuffer;
  283. PCHAR pSubKeyBuffer;
  284. PCHAR pValueBuffer;
  285. PCHAR pDataBuffer;
  286. DWORD Idx;
  287. //
  288. // Initialize local.
  289. //
  290. lError = ERROR_SUCCESS;
  291. hSubKey = (HKEY)INVALID_HANDLE_VALUE;
  292. dwValueSize = 0;
  293. dwDataSize = 0;
  294. dwSubKeySize = 0;
  295. dwTypeBuffer = 0;
  296. Idx = 0;
  297. pSubKeyBuffer = NULL;
  298. pValueBuffer = NULL;
  299. pDataBuffer = NULL;
  300. //
  301. // Query necessary buffer size.
  302. //
  303. lError = RegQueryInfoKeyA(hKey,
  304. NULL,
  305. NULL,
  306. NULL,
  307. NULL,
  308. &dwSubKeySize,
  309. NULL,
  310. NULL,
  311. &dwValueSize,
  312. &dwDataSize,
  313. NULL,
  314. NULL);
  315. if(ERROR_SUCCESS != lError){
  316. //
  317. // Unable to retrieve key info.
  318. //
  319. goto WriteRegistryToFile_return;
  320. } // if(ERROR_SUCCESS != lError)
  321. //
  322. // Allocate buffers.
  323. //
  324. dwValueSize = (dwValueSize+1+1) * sizeof(CHAR);
  325. dwSubKeySize = (dwSubKeySize+1) * sizeof(CHAR);
  326. pValueBuffer = AllocMem(dwValueSize);
  327. pDataBuffer = AllocMem(dwDataSize);
  328. pSubKeyBuffer = AllocMem(dwSubKeySize);
  329. if( (NULL == pValueBuffer)
  330. || (NULL == pDataBuffer)
  331. || (NULL == pSubKeyBuffer) )
  332. {
  333. //
  334. // Insufficient memory.
  335. //
  336. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to allocate buffer.\r\n", LogSevError);
  337. lError = ERROR_NOT_ENOUGH_MEMORY;
  338. goto WriteRegistryToFile_return;
  339. } // if(NULL == pDataBuffer)
  340. //
  341. // Indicate beginning of this subkey to the file.
  342. //
  343. WriteToFile(hFile, "\"%s\" = \"BEGIN\"\r\n", pszPath);
  344. //
  345. // Enumerate all values.
  346. //
  347. while(ERROR_SUCCESS == lError){
  348. DWORD dwLocalValueSize;
  349. DWORD dwLocalDataSize;
  350. //
  351. // Reset buffer and size.
  352. //
  353. dwLocalValueSize = dwValueSize;
  354. dwLocalDataSize = dwDataSize;
  355. memset(pValueBuffer, 0, dwValueSize);
  356. memset(pDataBuffer, 0, dwDataSize);
  357. //
  358. // Acquire registry value/data..
  359. //
  360. lError = RegEnumValueA(hKey,
  361. Idx,
  362. pValueBuffer,
  363. &dwLocalValueSize,
  364. NULL,
  365. &dwTypeBuffer,
  366. pDataBuffer,
  367. &dwLocalDataSize);
  368. if(ERROR_NO_MORE_ITEMS == lError){
  369. //
  370. // End of data.
  371. //
  372. continue;
  373. } // if(ERROR_NO_MORE_ITEMS == lError)
  374. if(ERROR_SUCCESS != lError){
  375. //
  376. // Unable to read registry value.
  377. //
  378. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to acqure registry value/data.\r\n", LogSevError);
  379. goto WriteRegistryToFile_return;
  380. } // if(ERROR_NO_MORE_ITEMS == lError)
  381. //
  382. // Write this value to a file.
  383. //
  384. lError = WriteRegistryValueToFile(hFile,
  385. pValueBuffer,
  386. dwTypeBuffer,
  387. pDataBuffer,
  388. dwLocalDataSize);
  389. if(ERROR_SUCCESS != lError){
  390. //
  391. // Unable to write to a file.
  392. //
  393. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to write to a file.\r\n", LogSevError);
  394. goto WriteRegistryToFile_return;
  395. } // if(ERROR_SUCCESS != lError)
  396. //
  397. // Goto next value.
  398. //
  399. Idx++;
  400. } // while(ERROR_SUCCESS == lError)
  401. //
  402. // Enumerate all sub keys.
  403. //
  404. lError = ERROR_SUCCESS;
  405. Idx = 0;
  406. while(ERROR_SUCCESS == lError){
  407. memset(pSubKeyBuffer, 0, dwSubKeySize);
  408. lError = RegEnumKeyA(hKey, Idx++, pSubKeyBuffer, dwSubKeySize);
  409. if(ERROR_SUCCESS == lError){
  410. //
  411. // There's sub key exists. Spew it to the file and store all the
  412. // values recursively.
  413. //
  414. lError = RegOpenKey(hKey, pSubKeyBuffer, &hSubKey);
  415. if(ERROR_SUCCESS != lError){
  416. SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to open subkey.\r\n", LogSevError);
  417. continue;
  418. } // if(ERROR_SUCCESS != lError)
  419. //
  420. // Call subkey recursively.
  421. //
  422. lError = WriteRegistryToFile(hFile, hSubKey, pSubKeyBuffer);
  423. } // if(ERROR_SUCCESS == lError)
  424. } // while(ERROR_SUCCESS == lError)
  425. if(ERROR_NO_MORE_ITEMS == lError){
  426. //
  427. // Operation completed as expected.
  428. //
  429. lError = ERROR_SUCCESS;
  430. } // if(ERROR_NO_MORE_ITEMS == lError)
  431. //
  432. // Indicate end of this subkey to the file.
  433. //
  434. WriteToFile(hFile, "\"%s\" = \"END\"\r\n", pszPath);
  435. WriteRegistryToFile_return:
  436. //
  437. // Clean up.
  438. //
  439. if(NULL != pValueBuffer){
  440. FreeMem(pValueBuffer);
  441. } // if(NULL != pValueBuffer)
  442. if(NULL != pDataBuffer){
  443. FreeMem(pDataBuffer);
  444. } // if(NULL != pDataBuffer)
  445. if(NULL != pSubKeyBuffer){
  446. FreeMem(pSubKeyBuffer);
  447. } // if(NULL != pSubKeyBuffer)
  448. return lError;
  449. } // WriteRegistryToFile()
  450. LONG
  451. WriteRegistryValueToFile(
  452. HANDLE hFile,
  453. LPSTR pszValue,
  454. DWORD dwType,
  455. PCHAR pDataBuffer,
  456. DWORD dwSize
  457. )
  458. {
  459. LONG lError;
  460. PCHAR pSpewBuffer;
  461. DWORD Idx;
  462. //
  463. // Initialize locals.
  464. //
  465. lError = ERROR_SUCCESS;
  466. pSpewBuffer = NULL;
  467. //
  468. // Allocate buffer for actual spew.
  469. //
  470. pSpewBuffer = AllocMem(dwSize*3);
  471. if(NULL == pSpewBuffer){
  472. //
  473. // Unable to allocate buffer.
  474. //
  475. lError = ERROR_NOT_ENOUGH_MEMORY;
  476. goto WriteRegistryValueToFile_return;
  477. } // if(NULL == pSpewBuffer)
  478. for(Idx = 0; Idx < dwSize; Idx++){
  479. wsprintf(pSpewBuffer+Idx*3, "%02x", pDataBuffer[Idx]);
  480. *(pSpewBuffer+Idx*3+2) = ',';
  481. } // for(Idx = 0; Idx < dwSize; Idx++)
  482. *(pSpewBuffer+dwSize*3-1) = '\0';
  483. WriteToFile(hFile, "\"%s\" = \"%08x:%s\"\r\n", pszValue, dwType, pSpewBuffer);
  484. //
  485. // Operation succeeded.
  486. //
  487. lError = ERROR_SUCCESS;
  488. WriteRegistryValueToFile_return:
  489. //
  490. // Clean up.
  491. //
  492. if(NULL != pSpewBuffer){
  493. FreeMem(pSpewBuffer);
  494. } // if(NULL != pSpewBuffer)
  495. return lError;
  496. } // WriteRegistryValueToFile()
  497. LONG
  498. GetRegData(
  499. HKEY hKey,
  500. LPSTR pszValue,
  501. PCHAR *ppDataBuffer,
  502. PDWORD pdwType,
  503. PDWORD pdwSize
  504. )
  505. {
  506. LONG lError;
  507. PCHAR pTempBuffer;
  508. DWORD dwRequiredSize;
  509. DWORD dwType;
  510. //
  511. // Initialize local.
  512. //
  513. lError = ERROR_SUCCESS;
  514. pTempBuffer = NULL;
  515. dwRequiredSize = 0;
  516. dwType = 0;
  517. //
  518. // Get required size.
  519. //
  520. lError = RegQueryValueEx(hKey,
  521. pszValue,
  522. NULL,
  523. &dwType,
  524. NULL,
  525. &dwRequiredSize);
  526. if( (ERROR_SUCCESS != lError)
  527. || (0 == dwRequiredSize) )
  528. {
  529. pTempBuffer = NULL;
  530. goto GetRegData_return;
  531. } // if(ERROR_MORE_DATA != lError)
  532. //
  533. // If it doesn't need actual data, just bail out.
  534. //
  535. if(NULL == ppDataBuffer){
  536. lError = ERROR_SUCCESS;
  537. goto GetRegData_return;
  538. } // if(NULL == ppDataBuffer)
  539. //
  540. // Allocate buffer to receive data.
  541. //
  542. pTempBuffer = AllocMem(dwRequiredSize);
  543. if(NULL == pTempBuffer){
  544. //
  545. // Allocation failed.
  546. //
  547. SetupLogError("WIA Migration: GetRegData: ERROR!! Unable to allocate buffer.\r\n", LogSevError);
  548. lError = ERROR_NOT_ENOUGH_MEMORY;
  549. goto GetRegData_return;
  550. } // if(NULL == pTempBuffer)
  551. //
  552. // Query the data.
  553. //
  554. lError = RegQueryValueEx(hKey,
  555. pszValue,
  556. NULL,
  557. &dwType,
  558. pTempBuffer,
  559. &dwRequiredSize);
  560. if(ERROR_SUCCESS != lError){
  561. //
  562. // Data acquisition somehow failed. Free buffer.
  563. //
  564. goto GetRegData_return;
  565. } // if(ERROR_SUCCESS != lError)
  566. GetRegData_return:
  567. if(ERROR_SUCCESS != lError){
  568. //
  569. // Operation unsuccessful. Free the buffer if allocated.
  570. //
  571. if(NULL != pTempBuffer){
  572. FreeMem(pTempBuffer);
  573. pTempBuffer = NULL;
  574. } // if(NULL != pTempBuffer)
  575. } // if(ERROR_SUCCESS != lError)
  576. //
  577. // Copy the result.
  578. //
  579. if(NULL != pdwSize){
  580. *pdwSize = dwRequiredSize;
  581. } // if(NULL != pdwSize)
  582. if(NULL != ppDataBuffer){
  583. *ppDataBuffer = pTempBuffer;
  584. } // if(NULL != ppDataBuffer)
  585. if(NULL != pdwType){
  586. *pdwType = dwType;
  587. } // if(NULL != pdwType)
  588. return lError;
  589. } // GetRegData()
  590. VOID
  591. MyLogError(
  592. LPCSTR pszFormat,
  593. ...
  594. )
  595. {
  596. LPSTR psz;
  597. CHAR szMsg[1024];
  598. va_list vargs;
  599. if(NULL != pszFormat){
  600. va_start(vargs, pszFormat);
  601. vsprintf(szMsg, pszFormat, vargs);
  602. va_end(vargs);
  603. SetupLogError(szMsg, LogSevError);
  604. } // if(NULL != pszFormat)
  605. } // MyLogError()
  606. CHAR
  607. My_fgetc(
  608. HANDLE hFile
  609. )
  610. /*++
  611. Routine Description:
  612. Gets a character from the file
  613. Arguments:
  614. Return Value:
  615. --*/
  616. {
  617. CHAR c;
  618. DWORD cbRead;
  619. if ( ReadFile(hFile, (LPBYTE)&c, sizeof(c), &cbRead, NULL) &&
  620. cbRead == sizeof(c) )
  621. return c;
  622. else
  623. return (CHAR) EOF;
  624. } // My_fgetc()
  625. int
  626. MyStrCmpiA(
  627. LPCSTR str1,
  628. LPCSTR str2
  629. )
  630. {
  631. int iRet;
  632. //
  633. // Initialize local.
  634. //
  635. iRet = 0;
  636. //
  637. // Compare string.
  638. //
  639. if(CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,
  640. NORM_IGNORECASE,
  641. str1,
  642. -1,
  643. str2,
  644. -1) )
  645. {
  646. iRet = 0;
  647. } else {
  648. iRet = -1;
  649. }
  650. return iRet;
  651. }