1137 lines
22 KiB
C
1137 lines
22 KiB
C
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Util.c
|
|
|
|
Abstract:
|
|
|
|
Uitility routines for printer migration from Win9x to NT
|
|
|
|
Author:
|
|
|
|
Muhunthan Sivapragasam (MuhuntS) 02-Jan-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
VOID
|
|
DebugMsg(
|
|
LPCSTR pszFormat,
|
|
...
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
On debug builds brings up a message box on severe errors
|
|
|
|
Arguments:
|
|
pszFormat : Format string
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
#if DBG
|
|
LPSTR psz;
|
|
CHAR szMsg[1024];
|
|
va_list vargs;
|
|
|
|
va_start(vargs, pszFormat);
|
|
vsprintf(szMsg, pszFormat, vargs);
|
|
va_end(vargs);
|
|
|
|
#ifdef MYDEBUG
|
|
if ( psz = GetStringFromRcFileA(IDS_TITLE) ) {
|
|
|
|
MessageBoxA(NULL, szMsg, psz, MB_OK);
|
|
FreeMem(psz);
|
|
}
|
|
#else
|
|
OutputDebugStringA("Printing Migration : ");
|
|
OutputDebugStringA(szMsg);
|
|
OutputDebugStringA("\n");
|
|
#endif
|
|
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
LogError(
|
|
IN LogSeverity Severity,
|
|
IN UINT uMessageId,
|
|
...
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Logs an error in the setup error log on NT side when something can not be
|
|
upgraded
|
|
|
|
Arguments:
|
|
uMessageId : Id to string in .rc file
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
LPSTR pszFormat;
|
|
CHAR szMsg[1024];
|
|
|
|
va_list vargs;
|
|
|
|
va_start(vargs, uMessageId);
|
|
|
|
pszFormat = GetStringFromRcFileA(uMessageId);
|
|
|
|
if ( pszFormat ) {
|
|
|
|
wvsprintfA(szMsg, pszFormat, vargs);
|
|
DebugMsg("%s", szMsg);
|
|
SetupLogErrorA(szMsg, Severity);
|
|
}
|
|
|
|
FreeMem(pszFormat);
|
|
|
|
va_end(vargs);
|
|
}
|
|
|
|
|
|
LPSTR
|
|
ErrorMsg(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the error message string from a Win32 error
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Value:
|
|
Pointer to a message string. Caller should free the string
|
|
|
|
--*/
|
|
{
|
|
DWORD dwLastError;
|
|
LPSTR pszStr = NULL;
|
|
|
|
if ( !(dwLastError = GetLastError()) )
|
|
dwLastError = STG_E_UNKNOWN;
|
|
|
|
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
|
NULL,
|
|
dwLastError,
|
|
0,
|
|
(LPSTR)&pszStr,
|
|
0,
|
|
NULL);
|
|
|
|
return pszStr;
|
|
}
|
|
|
|
|
|
PVOID
|
|
AllocMem(
|
|
IN UINT cbSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Allocate memory from the heap
|
|
|
|
Arguments:
|
|
cbSize : Byte count
|
|
|
|
Return Value:
|
|
Pointer to the allocated memory
|
|
|
|
--*/
|
|
{
|
|
return LocalAlloc(LPTR, cbSize);
|
|
}
|
|
|
|
|
|
VOID
|
|
FreeMem(
|
|
IN PVOID p
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Free memory allocated on the heap
|
|
|
|
Arguments:
|
|
p : Pointer to the memory to be freed
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
LocalFree(p);
|
|
}
|
|
|
|
|
|
LPSTR
|
|
AllocStrA(
|
|
LPCSTR pszStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Allocate memory and make a copy of an ansi string field
|
|
|
|
Arguments:
|
|
pszStr : String to copy
|
|
|
|
Return Value:
|
|
Pointer to the copied string. Memory is allocated.
|
|
|
|
--*/
|
|
{
|
|
LPSTR pszRet = NULL;
|
|
|
|
if ( pszStr && *pszStr ) {
|
|
|
|
pszRet = AllocMem((strlen(pszStr) + 1) * sizeof(CHAR));
|
|
if ( pszRet )
|
|
strcpy(pszRet, pszStr);
|
|
}
|
|
|
|
return pszRet;
|
|
}
|
|
|
|
|
|
LPWSTR
|
|
AllocStrW(
|
|
LPCWSTR pszStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Allocate memory and make a copy of a unicode string field
|
|
|
|
Arguments:
|
|
pszStr : String to copy
|
|
|
|
Return Value:
|
|
Pointer to the copied string. Memory is allocated.
|
|
|
|
--*/
|
|
{
|
|
LPWSTR pszRet = NULL;
|
|
|
|
if ( pszStr && *pszStr ) {
|
|
|
|
pszRet = AllocMem((wcslen(pszStr) + 1) * sizeof(WCHAR));
|
|
if ( pszRet )
|
|
wcscpy(pszRet, pszStr);
|
|
}
|
|
|
|
return pszRet;
|
|
}
|
|
|
|
|
|
LPWSTR
|
|
AllocStrWFromStrA(
|
|
LPCSTR pszStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the unicode string for a give ansi string. Memory is allocated.
|
|
|
|
Arguments:
|
|
pszStr : Gives the ansi string to copy
|
|
|
|
Return Value:
|
|
Pointer to the copied unicode string. Memory is allocated.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwLen;
|
|
LPWSTR pszRet = NULL;
|
|
|
|
if ( pszStr &&
|
|
*pszStr &&
|
|
(dwLen = strlen(pszStr)) &&
|
|
(pszRet = AllocMem((dwLen + 1) * sizeof(WCHAR))) ) {
|
|
|
|
if ( MultiByteToWideChar(CP_ACP,
|
|
MB_PRECOMPOSED,
|
|
pszStr,
|
|
dwLen,
|
|
pszRet,
|
|
dwLen) ) {
|
|
|
|
pszRet[dwLen] = 0;
|
|
} else {
|
|
|
|
FreeMem(pszRet);
|
|
pszRet = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
return pszRet;
|
|
}
|
|
|
|
|
|
LPSTR
|
|
AllocStrAFromStrW(
|
|
LPCWSTR pszStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the ansi string for a give unicode string. Memory is allocated.
|
|
|
|
Arguments:
|
|
pszStr : Gives the ansi string to copy
|
|
|
|
Return Value:
|
|
Pointer to the copied ansi string. Memory is allocated.
|
|
|
|
--*/
|
|
{
|
|
DWORD dwLen;
|
|
LPSTR pszRet = NULL;
|
|
|
|
if ( pszStr &&
|
|
*pszStr &&
|
|
(dwLen = wcslen(pszStr)) &&
|
|
(pszRet = AllocMem((dwLen + 1 ) * sizeof(CHAR))) ) {
|
|
|
|
WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
pszStr,
|
|
dwLen,
|
|
pszRet,
|
|
dwLen,
|
|
NULL,
|
|
NULL );
|
|
}
|
|
|
|
return pszRet;
|
|
}
|
|
|
|
|
|
BOOL
|
|
WriteToFile(
|
|
HANDLE hFile,
|
|
LPCSTR pszFormat,
|
|
...
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Format and write a string to the text file. This is used to write the
|
|
printing configuration on Win9x
|
|
|
|
Arguments:
|
|
hFile : File handle
|
|
pszFormat : Format string for the message
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
CHAR szMsg[1024];
|
|
va_list vargs;
|
|
DWORD dwSize, dwWritten;
|
|
BOOL bRet;
|
|
|
|
bRet = TRUE;
|
|
|
|
va_start(vargs, pszFormat);
|
|
vsprintf(szMsg, pszFormat, vargs);
|
|
va_end(vargs);
|
|
|
|
dwSize = strlen(szMsg) * sizeof(CHAR);
|
|
|
|
if ( !WriteFile(hFile, (LPCVOID)szMsg, dwSize, &dwWritten, NULL) ||
|
|
dwSize != dwWritten ) {
|
|
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
VOID
|
|
WriteString(
|
|
IN HANDLE hFile,
|
|
IN OUT LPBOOL pbFail,
|
|
IN LPCSTR pszStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Writes a string to the upgrade file on Win9x side. Since spooler strings
|
|
(ex. printer name, driver name) can have space in them we would write
|
|
all strings with []\n. So we can read strings with space on NT.
|
|
|
|
Arguments:
|
|
hFile : File handle
|
|
pszFormat : Format string for the message
|
|
pszStr : String to write
|
|
|
|
Return Value:
|
|
None
|
|
|
|
--*/
|
|
{
|
|
DWORD dwLen;
|
|
|
|
if ( pszStr ) {
|
|
|
|
dwLen = strlen(pszStr);
|
|
WriteToFile(hFile, "%3d [%s]\n", dwLen, pszStr);
|
|
}
|
|
|
|
}
|
|
|
|
LPSTR
|
|
GetStringFromRcFileA(
|
|
UINT uId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Load a string from the .rc file and make a copy of it by doing AllocStr
|
|
|
|
Arguments:
|
|
uId : Identifier for the string to be loaded
|
|
|
|
Return Value:
|
|
String value loaded, NULL on error. Caller should free the memory
|
|
|
|
--*/
|
|
{
|
|
CHAR buf[MAX_PATH];
|
|
|
|
if ( LoadStringA(g_hInst, uId, buf, sizeof(buf) ))
|
|
return AllocStrA(buf);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
ReadString(
|
|
IN HANDLE hFile,
|
|
OUT LPSTR *ppszParam1,
|
|
OUT LPSTR *ppszParam2
|
|
)
|
|
{
|
|
CHAR c;
|
|
LPSTR pszParameter1;
|
|
LPSTR pszParameter2;
|
|
DWORD dwLen;
|
|
CHAR LineBuffer[MAX_PATH];
|
|
DWORD Idx;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
c = 0;
|
|
pszParameter1 = NULL;
|
|
pszParameter2 = NULL;
|
|
dwLen = 0;
|
|
Idx = 0;
|
|
|
|
memset(LineBuffer, 0, sizeof(LineBuffer));
|
|
|
|
//
|
|
// Initialize caller buffer
|
|
//
|
|
|
|
*ppszParam1 = NULL;
|
|
*ppszParam2 = NULL;
|
|
|
|
//
|
|
// First skip space/\r/\n.
|
|
//
|
|
|
|
c = (CHAR) My_fgetc(hFile);
|
|
while( (' ' == c)
|
|
|| ('\n' == c)
|
|
|| ('\r' == c) )
|
|
{
|
|
c = (CHAR) My_fgetc(hFile);
|
|
}
|
|
|
|
//
|
|
// See if it's EOF.
|
|
//
|
|
|
|
if(EOF == c){
|
|
|
|
//
|
|
// End of file.
|
|
//
|
|
|
|
goto ReadString_return;
|
|
}
|
|
|
|
//
|
|
// Get a line.
|
|
//
|
|
|
|
Idx = 0;
|
|
while( ('\n' != c) && (EOF != c) ){
|
|
LineBuffer[Idx++] = c;
|
|
c = (CHAR) My_fgetc(hFile);
|
|
} // while( ('\n' != c) && (EOF != c) )
|
|
dwLen = Idx;
|
|
|
|
//
|
|
// See if it's EOF.
|
|
//
|
|
|
|
if(EOF == c){
|
|
|
|
//
|
|
// Illegal migration file.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file.", LogSevError);
|
|
goto ReadString_return;
|
|
}
|
|
|
|
//
|
|
// See if it's double quated.
|
|
//
|
|
|
|
if('\"' == LineBuffer[0]){
|
|
pszParameter1 = &LineBuffer[1];
|
|
Idx = 1;
|
|
} else { // if('\"' == LineBuffer[0])
|
|
|
|
//
|
|
// There's no '"'. Invalid migration file.
|
|
//
|
|
SetupLogError("WIA Migration: ReadString: ERROR!! Illegal migration file with no Quote.", LogSevError);
|
|
goto ReadString_return;
|
|
} // if('\"' == LineBuffer[0])
|
|
|
|
//
|
|
// Find next '"' and replace with '\0'.
|
|
//
|
|
|
|
for(;'\"' != LineBuffer[Idx]; Idx++);
|
|
LineBuffer[Idx] = '\0';
|
|
|
|
//
|
|
// Find next (3rd) '"', it's beginning of 2nd parameter.
|
|
//
|
|
|
|
for(;'\"' != LineBuffer[Idx]; Idx++);
|
|
pszParameter2 = &LineBuffer[++Idx];
|
|
|
|
//
|
|
// Find last '"' and replace with '\0'.
|
|
//
|
|
|
|
for(;'\"' != LineBuffer[Idx]; Idx++);
|
|
LineBuffer[Idx] = '\0';
|
|
|
|
//
|
|
// Allocate buffer for returning string.
|
|
//
|
|
|
|
*ppszParam1 = AllocStrA(pszParameter1);
|
|
*ppszParam2 = AllocStrA(pszParameter2);
|
|
|
|
ReadString_return:
|
|
return;
|
|
} // ReadString()
|
|
|
|
|
|
VOID
|
|
ReadDword(
|
|
IN HANDLE hFile,
|
|
IN LPSTR pszLine,
|
|
IN DWORD dwLineSize,
|
|
IN LPSTR pszPrefix,
|
|
OUT LPDWORD pdwValue,
|
|
IN OUT LPBOOL pbFail
|
|
)
|
|
{
|
|
LPSTR psz;
|
|
|
|
if ( *pbFail || My_fgets(pszLine, dwLineSize, hFile) == NULL ) {
|
|
|
|
*pbFail = TRUE;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// First check the prefix matches to make sure we are in the right line
|
|
//
|
|
for ( psz = (LPSTR)pszLine ;
|
|
*pszPrefix && *psz == *pszPrefix ;
|
|
++psz, ++pszPrefix )
|
|
;
|
|
|
|
if ( *pszPrefix ) {
|
|
|
|
*pbFail = TRUE;
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Skip spaces
|
|
//
|
|
while ( *psz && *psz == ' ' )
|
|
++psz;
|
|
|
|
*pdwValue = atoi(psz);
|
|
}
|
|
|
|
|
|
VOID
|
|
ReadDevMode(
|
|
IN HANDLE hFile,
|
|
OUT LPDEVMODEA *ppDevMode,
|
|
IN OUT LPBOOL pbFail
|
|
)
|
|
{
|
|
LPSTR pszPrefix = "DevMode:";
|
|
CHAR c;
|
|
DWORD dwLen;
|
|
LPINT ptr;
|
|
|
|
if ( *pbFail )
|
|
return;
|
|
|
|
// First skip the prefix
|
|
//
|
|
while ( *pszPrefix && (c = (CHAR) My_fgetc(hFile)) == *pszPrefix++ )
|
|
;
|
|
|
|
if ( *pszPrefix )
|
|
goto Fail;
|
|
|
|
//
|
|
// Skip spaces
|
|
//
|
|
while ( (c = (CHAR) My_fgetc(hFile)) == ' ' )
|
|
;
|
|
|
|
//
|
|
// Now is the devmode size
|
|
//
|
|
if ( !isdigit(c) )
|
|
goto Fail;
|
|
|
|
dwLen = c - '0';
|
|
while ( isdigit(c = (CHAR) My_fgetc(hFile)) )
|
|
dwLen = dwLen * 10 + c - '0';
|
|
|
|
if ( dwLen == 0 )
|
|
return;
|
|
|
|
if ( c != ' ' )
|
|
goto Fail;
|
|
|
|
//
|
|
// Now the devmode is there between []
|
|
//
|
|
if ( *ppDevMode = (LPDEVMODEA) AllocMem(dwLen) ) {
|
|
|
|
if ( (c = (CHAR) My_fgetc(hFile)) != '[' )
|
|
goto Fail;
|
|
|
|
if ( dwLen != My_fread((LPVOID)*ppDevMode, dwLen, hFile) )
|
|
goto Fail;
|
|
|
|
//
|
|
// Make sure now we have "]\n" to End
|
|
//
|
|
if ( (CHAR) My_fgetc(hFile) != ']' || (CHAR) My_fgetc(hFile) != '\n' ) {
|
|
|
|
DebugMsg("Char check fails");
|
|
goto Fail;
|
|
}
|
|
|
|
return; // Succesful exit
|
|
}
|
|
|
|
Fail:
|
|
*pbFail = TRUE;
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
WriteRegistryToFile(
|
|
IN HANDLE hFile,
|
|
IN HKEY hKey,
|
|
IN LPCSTR pszPath
|
|
)
|
|
{
|
|
LONG lError;
|
|
HKEY hSubKey;
|
|
DWORD dwValueSize;
|
|
DWORD dwDataSize;
|
|
DWORD dwSubKeySize;
|
|
DWORD dwTypeBuffer;
|
|
|
|
PCHAR pSubKeyBuffer;
|
|
PCHAR pValueBuffer;
|
|
PCHAR pDataBuffer;
|
|
|
|
DWORD Idx;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
hSubKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
dwValueSize = 0;
|
|
dwDataSize = 0;
|
|
dwSubKeySize = 0;
|
|
dwTypeBuffer = 0;
|
|
Idx = 0;
|
|
|
|
pSubKeyBuffer = NULL;
|
|
pValueBuffer = NULL;
|
|
pDataBuffer = NULL;
|
|
|
|
//
|
|
// Query necessary buffer size.
|
|
//
|
|
|
|
lError = RegQueryInfoKeyA(hKey,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&dwSubKeySize,
|
|
NULL,
|
|
NULL,
|
|
&dwValueSize,
|
|
&dwDataSize,
|
|
NULL,
|
|
NULL);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to retrieve key info.
|
|
//
|
|
|
|
goto WriteRegistryToFile_return;
|
|
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
//
|
|
// Allocate buffers.
|
|
//
|
|
|
|
dwValueSize = (dwValueSize+1+1) * sizeof(CHAR);
|
|
dwSubKeySize = (dwSubKeySize+1) * sizeof(CHAR);
|
|
|
|
pValueBuffer = AllocMem(dwValueSize);
|
|
pDataBuffer = AllocMem(dwDataSize);
|
|
pSubKeyBuffer = AllocMem(dwSubKeySize);
|
|
|
|
if( (NULL == pValueBuffer)
|
|
|| (NULL == pDataBuffer)
|
|
|| (NULL == pSubKeyBuffer) )
|
|
{
|
|
|
|
//
|
|
// Insufficient memory.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to allocate buffer.", LogSevError);
|
|
lError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto WriteRegistryToFile_return;
|
|
} // if(NULL == pDataBuffer)
|
|
|
|
//
|
|
// Indicate beginning of this subkey to the file.
|
|
//
|
|
|
|
WriteToFile(hFile, "\"%s\" = \"BEGIN\"\r\n", pszPath);
|
|
|
|
//
|
|
// Enumerate all values.
|
|
//
|
|
|
|
while(ERROR_SUCCESS == lError){
|
|
|
|
DWORD dwLocalValueSize;
|
|
DWORD dwLocalDataSize;
|
|
|
|
//
|
|
// Reset buffer and size.
|
|
//
|
|
|
|
dwLocalValueSize = dwValueSize;
|
|
dwLocalDataSize = dwDataSize;
|
|
memset(pValueBuffer, 0, dwValueSize);
|
|
memset(pDataBuffer, 0, dwDataSize);
|
|
|
|
//
|
|
// Acquire registry value/data..
|
|
//
|
|
|
|
lError = RegEnumValueA(hKey,
|
|
Idx,
|
|
pValueBuffer,
|
|
&dwLocalValueSize,
|
|
NULL,
|
|
&dwTypeBuffer,
|
|
pDataBuffer,
|
|
&dwLocalDataSize);
|
|
if(ERROR_NO_MORE_ITEMS == lError){
|
|
|
|
//
|
|
// End of data.
|
|
//
|
|
|
|
continue;
|
|
} // if(ERROR_NO_MORE_ITEMS == lError)
|
|
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to read registry value.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to acqure registry value/data.", LogSevError);
|
|
goto WriteRegistryToFile_return;
|
|
} // if(ERROR_NO_MORE_ITEMS == lError)
|
|
|
|
//
|
|
// Write this value to a file.
|
|
//
|
|
|
|
lError = WriteRegistryValueToFile(hFile,
|
|
pValueBuffer,
|
|
dwTypeBuffer,
|
|
pDataBuffer,
|
|
dwLocalDataSize);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to write to a file.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to write to a file.", LogSevError);
|
|
goto WriteRegistryToFile_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
//
|
|
// Goto next value.
|
|
//
|
|
|
|
Idx++;
|
|
|
|
} // while(ERROR_SUCCESS == lError)
|
|
|
|
//
|
|
// Enumerate all sub keys.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
Idx = 0;
|
|
|
|
while(ERROR_SUCCESS == lError){
|
|
|
|
memset(pSubKeyBuffer, 0, dwSubKeySize);
|
|
lError = RegEnumKeyA(hKey, Idx++, pSubKeyBuffer, dwSubKeySize);
|
|
if(ERROR_SUCCESS == lError){
|
|
|
|
//
|
|
// There's sub key exists. Spew it to the file and store all the
|
|
// values recursively.
|
|
//
|
|
|
|
lError = RegOpenKey(hKey, pSubKeyBuffer, &hSubKey);
|
|
if(ERROR_SUCCESS != lError){
|
|
SetupLogError("WIA Migration: WriteRegistryToFile: ERROR!! Unable to open subkey.", LogSevError);
|
|
continue;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
//
|
|
// Call subkey recursively.
|
|
//
|
|
|
|
lError = WriteRegistryToFile(hFile, hSubKey, pSubKeyBuffer);
|
|
|
|
} // if(ERROR_SUCCESS == lError)
|
|
} // while(ERROR_SUCCESS == lError)
|
|
|
|
if(ERROR_NO_MORE_ITEMS == lError){
|
|
|
|
//
|
|
// Operation completed as expected.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
|
|
} // if(ERROR_NO_MORE_ITEMS == lError)
|
|
|
|
//
|
|
// Indicate end of this subkey to the file.
|
|
//
|
|
|
|
WriteToFile(hFile, "\"%s\" = \"END\"\r\n", pszPath);
|
|
|
|
WriteRegistryToFile_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(NULL != pValueBuffer){
|
|
FreeMem(pValueBuffer);
|
|
} // if(NULL != pValueBuffer)
|
|
|
|
if(NULL != pDataBuffer){
|
|
FreeMem(pDataBuffer);
|
|
} // if(NULL != pDataBuffer)
|
|
|
|
if(NULL != pSubKeyBuffer){
|
|
FreeMem(pSubKeyBuffer);
|
|
} // if(NULL != pSubKeyBuffer)
|
|
|
|
return lError;
|
|
} // WriteRegistryToFile()
|
|
|
|
|
|
LONG
|
|
WriteRegistryValueToFile(
|
|
HANDLE hFile,
|
|
LPSTR pszValue,
|
|
DWORD dwType,
|
|
PCHAR pDataBuffer,
|
|
DWORD dwSize
|
|
)
|
|
{
|
|
|
|
LONG lError;
|
|
PCHAR pSpewBuffer;
|
|
DWORD Idx;
|
|
|
|
//
|
|
// Initialize locals.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
pSpewBuffer = NULL;
|
|
|
|
//
|
|
// Allocate buffer for actual spew.
|
|
//
|
|
|
|
pSpewBuffer = AllocMem(dwSize*3);
|
|
if(NULL == pSpewBuffer){
|
|
|
|
//
|
|
// Unable to allocate buffer.
|
|
//
|
|
|
|
lError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto WriteRegistryValueToFile_return;
|
|
} // if(NULL == pSpewBuffer)
|
|
|
|
for(Idx = 0; Idx < dwSize; Idx++){
|
|
|
|
wsprintf(pSpewBuffer+Idx*3, "%02x", pDataBuffer[Idx]);
|
|
*(pSpewBuffer+Idx*3+2) = ',';
|
|
|
|
} // for(Idx = 0; Idx < dwSize; Idx++)
|
|
|
|
*(pSpewBuffer+dwSize*3-1) = '\0';
|
|
|
|
WriteToFile(hFile, "\"%s\" = \"%08x:%s\"\r\n", pszValue, dwType, pSpewBuffer);
|
|
|
|
//
|
|
// Operation succeeded.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
|
|
WriteRegistryValueToFile_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(NULL != pSpewBuffer){
|
|
FreeMem(pSpewBuffer);
|
|
} // if(NULL != pSpewBuffer)
|
|
|
|
return lError;
|
|
|
|
} // WriteRegistryValueToFile()
|
|
|
|
|
|
LONG
|
|
GetRegData(
|
|
HKEY hKey,
|
|
LPSTR pszValue,
|
|
PCHAR *ppDataBuffer,
|
|
PDWORD pdwType,
|
|
PDWORD pdwSize
|
|
)
|
|
{
|
|
|
|
LONG lError;
|
|
PCHAR pTempBuffer;
|
|
DWORD dwRequiredSize;
|
|
DWORD dwType;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
pTempBuffer = NULL;
|
|
dwRequiredSize = 0;
|
|
dwType = 0;
|
|
|
|
//
|
|
// Get required size.
|
|
//
|
|
|
|
lError = RegQueryValueEx(hKey,
|
|
pszValue,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwRequiredSize);
|
|
if( (ERROR_SUCCESS != lError)
|
|
|| (0 == dwRequiredSize) )
|
|
{
|
|
|
|
pTempBuffer = NULL;
|
|
goto GetRegData_return;
|
|
|
|
} // if(ERROR_MORE_DATA != lError)
|
|
|
|
//
|
|
// If it doesn't need actual data, just bail out.
|
|
//
|
|
|
|
if(NULL == ppDataBuffer){
|
|
lError = ERROR_SUCCESS;
|
|
goto GetRegData_return;
|
|
} // if(NULL == ppDataBuffer)
|
|
|
|
//
|
|
// Allocate buffer to receive data.
|
|
//
|
|
|
|
pTempBuffer = AllocMem(dwRequiredSize);
|
|
if(NULL == pTempBuffer){
|
|
|
|
//
|
|
// Allocation failed.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: GetRegData: ERROR!! Unable to allocate buffer.", LogSevError);
|
|
lError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto GetRegData_return;
|
|
} // if(NULL == pTempBuffer)
|
|
|
|
//
|
|
// Query the data.
|
|
//
|
|
|
|
lError = RegQueryValueEx(hKey,
|
|
pszValue,
|
|
NULL,
|
|
&dwType,
|
|
pTempBuffer,
|
|
&dwRequiredSize);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Data acquisition somehow failed. Free buffer.
|
|
//
|
|
|
|
goto GetRegData_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
GetRegData_return:
|
|
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Operation unsuccessful. Free the buffer if allocated.
|
|
//
|
|
|
|
if(NULL != pTempBuffer){
|
|
FreeMem(pTempBuffer);
|
|
pTempBuffer = NULL;
|
|
} // if(NULL != pTempBuffer)
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
//
|
|
// Copy the result.
|
|
//
|
|
|
|
if(NULL != pdwSize){
|
|
*pdwSize = dwRequiredSize;
|
|
} // if(NULL != pdwSize)
|
|
|
|
if(NULL != ppDataBuffer){
|
|
*ppDataBuffer = pTempBuffer;
|
|
} // if(NULL != ppDataBuffer)
|
|
|
|
if(NULL != pdwType){
|
|
*pdwType = dwType;
|
|
} // if(NULL != pdwType)
|
|
|
|
return lError;
|
|
} // GetRegData()
|
|
|
|
VOID
|
|
MyLogError(
|
|
LPCSTR pszFormat,
|
|
...
|
|
)
|
|
{
|
|
LPSTR psz;
|
|
CHAR szMsg[1024];
|
|
va_list vargs;
|
|
|
|
if(NULL != pszFormat){
|
|
va_start(vargs, pszFormat);
|
|
vsprintf(szMsg, pszFormat, vargs);
|
|
va_end(vargs);
|
|
|
|
SetupLogError(szMsg, LogSevError);
|
|
} // if(NULL != pszFormat)
|
|
|
|
} // MyLogError()
|
|
|