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.
669 lines
16 KiB
669 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
Win9x.c
|
|
|
|
Abstract:
|
|
|
|
Routines to pre-migrate Win9x to NT
|
|
|
|
Author:
|
|
|
|
Keisuke Tsuchida (KeisukeT) 10-Oct-2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#include "devguid.h"
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
LPCSTR g_WorkingDirectory = NULL;
|
|
LPCSTR g_SourceDirectory = NULL;
|
|
LPCSTR g_MediaDirectory = NULL;
|
|
//LPCSTR g_WorkingDirectory = ".";
|
|
//LPCSTR g_SourceDirectory = ".";
|
|
//LPCSTR g_MediaDirectory = ".";
|
|
|
|
LONG
|
|
CALLBACK
|
|
Initialize9x(
|
|
IN LPCSTR pszWorkingDir,
|
|
IN LPCSTR pszSourceDir,
|
|
IN LPCSTR pszMediaDir
|
|
)
|
|
{
|
|
LONG lError;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
|
|
//
|
|
// Save given parameters.
|
|
//
|
|
|
|
g_WorkingDirectory = AllocStrA(pszWorkingDir);
|
|
g_SourceDirectory = AllocStrA(pszSourceDir);
|
|
g_MediaDirectory = AllocStrA(pszMediaDir);
|
|
|
|
if( (NULL == g_WorkingDirectory)
|
|
|| (NULL == g_SourceDirectory)
|
|
|| (NULL == g_MediaDirectory) )
|
|
{
|
|
SetupLogError("WIA Migration: Initialize9x: ERROR!! insufficient memory.\r\n", LogSevError);
|
|
|
|
lError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Initialize9x_return;
|
|
}
|
|
|
|
Initialize9x_return:
|
|
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Can't process migration. Clean up.
|
|
//
|
|
|
|
if(NULL != g_WorkingDirectory){
|
|
FreeMem((PVOID)g_WorkingDirectory);
|
|
g_WorkingDirectory = NULL;
|
|
}
|
|
|
|
if(NULL != g_SourceDirectory){
|
|
FreeMem((PVOID)g_SourceDirectory);
|
|
g_SourceDirectory = NULL;
|
|
}
|
|
|
|
if(NULL != g_MediaDirectory){
|
|
FreeMem((PVOID)g_MediaDirectory);
|
|
g_MediaDirectory = NULL;
|
|
}
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
return lError;
|
|
} // Initialize9x()
|
|
|
|
|
|
LONG
|
|
CALLBACK
|
|
MigrateUser9x(
|
|
IN HWND hwndParent,
|
|
IN LPCSTR pszUnattendFile,
|
|
IN HKEY hUserRegKey,
|
|
IN LPCSTR pszUserName,
|
|
LPVOID Reserved
|
|
)
|
|
{
|
|
//
|
|
// Nothing to do
|
|
//
|
|
|
|
return ERROR_SUCCESS;
|
|
} // MigrateUser9x()
|
|
|
|
|
|
LONG
|
|
CALLBACK
|
|
MigrateSystem9x(
|
|
IN HWND hwndParent,
|
|
IN LPCSTR pszUnattendFile,
|
|
IN LPVOID Reserved
|
|
)
|
|
{
|
|
LONG lError;
|
|
CHAR szFile[MAX_PATH];
|
|
CHAR szInfName[MAX_PATH];
|
|
|
|
HANDLE hSettingStore;
|
|
|
|
//
|
|
// Initialize locals.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
hSettingStore = (HANDLE)INVALID_HANDLE_VALUE;
|
|
|
|
//
|
|
// Check global initialization.
|
|
//
|
|
|
|
if( (NULL == g_WorkingDirectory)
|
|
|| (NULL == g_SourceDirectory)
|
|
|| (NULL == g_MediaDirectory) )
|
|
{
|
|
SetupLogError("WIA Migration: MigrateSystem9x: ERROR!! Initialize failed.\r\n", LogSevError);
|
|
|
|
lError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto MigrateSystem9x_return;
|
|
}
|
|
|
|
//
|
|
// Create path to the files.
|
|
//
|
|
|
|
wsprintfA(szFile, "%s\\%s", g_WorkingDirectory, NAME_WIN9X_SETTING_FILE_A);
|
|
wsprintfA(szInfName, "%s\\%s", g_WorkingDirectory, NAME_MIGRATE_INF_A);
|
|
|
|
//
|
|
// Create files.
|
|
//
|
|
|
|
|
|
hSettingStore = CreateFileA(szFile,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if(INVALID_HANDLE_VALUE == hSettingStore){
|
|
SetupLogError("WIA Migration: MigrateSystem9x: ERROR!! Unable to create setting file.\r\n", LogSevError);
|
|
lError = GetLastError();
|
|
goto MigrateSystem9x_return;
|
|
} // if(INVALID_HANDLE_VALUE == hSettingStore)
|
|
|
|
//
|
|
// Create setting file based on device registry.
|
|
//
|
|
|
|
|
|
lError = Mig9xGetDeviceInfo(hSettingStore);
|
|
if(ERROR_SUCCESS != lError){
|
|
goto MigrateSystem9x_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
MigrateSystem9x_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(hSettingStore != INVALID_HANDLE_VALUE){
|
|
CloseHandle(hSettingStore);
|
|
}
|
|
|
|
|
|
return lError;
|
|
|
|
} // MigrateSystem9x()
|
|
|
|
|
|
LONG
|
|
CALLBACK
|
|
Mig9xGetDeviceInfo(
|
|
IN HANDLE hFile
|
|
)
|
|
{
|
|
|
|
LONG lError;
|
|
DWORD Idx;
|
|
GUID Guid;
|
|
HANDLE hDevInfo;
|
|
SP_DEVINFO_DATA spDevInfoData;
|
|
HKEY hKeyDevice;
|
|
PCHAR pTempBuffer;
|
|
|
|
|
|
//
|
|
// Initialize locals.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
Guid = GUID_DEVCLASS_IMAGE;
|
|
hDevInfo = (HANDLE)INVALID_HANDLE_VALUE;
|
|
Idx = 0;
|
|
hKeyDevice = (HKEY)INVALID_HANDLE_VALUE;
|
|
pTempBuffer = NULL;
|
|
|
|
//
|
|
// Enumerate WIA/STI devices and spew device info.
|
|
//
|
|
|
|
|
|
hDevInfo = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PROFILE);
|
|
if(INVALID_HANDLE_VALUE == hDevInfo){
|
|
|
|
SetupLogError("WIA Migration: Mig9xGetDeviceInfo: ERROR!! Unable to acquire device list.\r\n", LogSevError);
|
|
lError = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Mig9xGetDeviceInfo_return;
|
|
|
|
} // if(INVALID_HANDLE_VALUE == hDevInfo)
|
|
|
|
//
|
|
// Save installed device setting.
|
|
//
|
|
|
|
spDevInfoData.cbSize = sizeof(spDevInfoData);
|
|
for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
|
|
|
|
//
|
|
// Open device registry key.
|
|
//
|
|
|
|
hKeyDevice = SetupDiOpenDevRegKey(hDevInfo,
|
|
&spDevInfoData,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DRV,
|
|
KEY_READ);
|
|
|
|
if (INVALID_HANDLE_VALUE != hKeyDevice) {
|
|
|
|
if( (TRUE == IsSti(hKeyDevice))
|
|
&& (FALSE == IsKernelDriverRequired(hKeyDevice)) )
|
|
{
|
|
|
|
//
|
|
// This is STI/WIA device with no kernel driver . Spew required info.
|
|
//
|
|
|
|
WriteDeviceToFile(hFile, hKeyDevice);
|
|
|
|
} // if( IsSti(hKeyDevice) && !IsKernelDriverRequired(hKeyDevice))
|
|
} // if (INVALID_HANDLE_VALUE != hKeyDevice)
|
|
} // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
|
|
|
|
|
|
|
|
|
|
Mig9xGetDeviceInfo_return:
|
|
|
|
if(NULL != pTempBuffer){
|
|
FreeMem(pTempBuffer);
|
|
} // if(NULL != pTempBuffer)
|
|
|
|
return lError;
|
|
} // Mig9xGetGlobalInfo()
|
|
|
|
|
|
|
|
BOOL
|
|
IsSti(
|
|
HKEY hKeyDevice
|
|
)
|
|
{
|
|
BOOL bRet;
|
|
PCHAR pTempBuffer;
|
|
LONG lError;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
bRet = FALSE;
|
|
pTempBuffer = NULL;
|
|
lError = ERROR_SUCCESS;
|
|
|
|
//
|
|
// See if it's StillImage device.
|
|
//
|
|
|
|
lError = GetRegData(hKeyDevice,
|
|
REGVAL_USDCLASS_A,
|
|
&pTempBuffer,
|
|
NULL,
|
|
NULL);
|
|
|
|
if( (ERROR_SUCCESS != lError)
|
|
|| (NULL == pTempBuffer) )
|
|
{
|
|
//
|
|
// Unable to get "SubClass" data. This is not STI/WIA.
|
|
//
|
|
|
|
bRet = FALSE;
|
|
goto IsSti_return;
|
|
} // if( (ERROR_SUCCESS != lError) || (NULL == pTempBuffer)
|
|
|
|
//
|
|
// This is STI/WIA device.
|
|
//
|
|
|
|
bRet = TRUE;
|
|
|
|
IsSti_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(NULL != pTempBuffer){
|
|
FreeMem(pTempBuffer);
|
|
} // if(NULL != pTempBuffer)
|
|
|
|
return bRet;
|
|
} // IsSti()
|
|
|
|
|
|
BOOL
|
|
IsKernelDriverRequired(
|
|
HKEY hKeyDevice
|
|
)
|
|
{
|
|
BOOL bRet;
|
|
PCHAR pTempBuffer;
|
|
LONG lError;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
bRet = FALSE;
|
|
pTempBuffer = NULL;
|
|
lError = ERROR_SUCCESS;
|
|
|
|
//
|
|
// See if it's StillImage device.
|
|
//
|
|
|
|
lError = GetRegData(hKeyDevice,
|
|
REGVAL_NTMPDRIVER_A,
|
|
&pTempBuffer,
|
|
NULL,
|
|
NULL);
|
|
|
|
if( (ERROR_SUCCESS != lError)
|
|
|| (NULL == pTempBuffer) )
|
|
{
|
|
//
|
|
// Unable to get "NTMPDriver" data. This device doesn't require kernel mode component.
|
|
//
|
|
|
|
bRet = FALSE;
|
|
goto IsKernelDriverRequired_return;
|
|
} // if( (ERROR_SUCCESS != lError) || (NULL == pTempBuffer)
|
|
|
|
//
|
|
// This device requires kernel mode component.
|
|
//
|
|
|
|
bRet = TRUE;
|
|
|
|
IsKernelDriverRequired_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(NULL != pTempBuffer){
|
|
FreeMem(pTempBuffer);
|
|
} // if(NULL != pTempBuffer)
|
|
|
|
return bRet;
|
|
} // IsKernelDriverRequired()
|
|
|
|
LONG
|
|
WriteDeviceToFile(
|
|
HANDLE hFile,
|
|
HKEY hKey
|
|
)
|
|
{
|
|
LONG lError;
|
|
PCHAR pFriendlyName;
|
|
PCHAR pCreateFileName;
|
|
PCHAR pInfPath;
|
|
PCHAR pInfSection;
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
CHAR SpewBuffer[256];
|
|
HKEY hDeviceData;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
lError = ERROR_SUCCESS;
|
|
pFriendlyName = NULL;
|
|
pCreateFileName = NULL;
|
|
pInfPath = NULL;
|
|
pInfSection = NULL;
|
|
dwSize = 0;
|
|
hDeviceData = (HKEY)INVALID_HANDLE_VALUE;
|
|
|
|
memset(SpewBuffer, 0, sizeof(SpewBuffer));
|
|
|
|
//
|
|
// Get FriendlyName.
|
|
//
|
|
|
|
dwSize = 0;
|
|
lError = GetRegData(hKey, NAME_FRIENDLYNAME_A, &pFriendlyName, &dwType, &dwSize);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to get FriendlyName.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! Unable to get FriendlyName.\r\n", LogSevError);
|
|
goto WriteDeviceToFile_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
if(REG_SZ != dwType){
|
|
|
|
//
|
|
// FriendlyName key is other than REG_SZ.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! FriendlyName is other than REG_SZ.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
} // if(REG_SZ != dwType)
|
|
|
|
if(dwSize > MAX_FRIENDLYNAME+1){
|
|
|
|
//
|
|
// Too long
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! FriendlyName is too long.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
}
|
|
|
|
//
|
|
// Get CreateFileName.
|
|
//
|
|
|
|
dwSize = 0;
|
|
lError = GetRegData(hKey, NAME_CREATEFILENAME_A, &pCreateFileName, &dwType, &dwSize);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to get CreateFileName.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! Unable to get CreateFileName.\r\n", LogSevError);
|
|
goto WriteDeviceToFile_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
if(REG_SZ != dwType){
|
|
|
|
//
|
|
// CreateFileName key is other than REG_SZ.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! CreateFileName is other than REG_SZ.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
} // if(REG_SZ != dwType)
|
|
|
|
if(dwSize > MAX_PATH+1){
|
|
|
|
//
|
|
// Too long
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! CreateFileName is too long.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
}
|
|
|
|
//
|
|
// Get InfPath.
|
|
//
|
|
|
|
dwSize = 0;
|
|
lError = GetRegData(hKey, NAME_INF_PATH_A, &pInfPath, &dwType, &dwSize);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to get InfPath.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! Unable to get InfPath.\r\n", LogSevError);
|
|
goto WriteDeviceToFile_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
if(REG_SZ != dwType){
|
|
|
|
//
|
|
// InfPath key is other than REG_SZ.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! InfPath is other than REG_SZ.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
} // if(REG_SZ != dwType)
|
|
|
|
if(dwSize > MAX_PATH+1){
|
|
|
|
//
|
|
// Too long
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! InfPath is too long.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
}
|
|
|
|
//
|
|
// Get InfSection.
|
|
//
|
|
|
|
dwSize = 0;
|
|
lError = GetRegData(hKey, NAME_INF_SECTION_A, &pInfSection, &dwType, &dwSize);
|
|
if(ERROR_SUCCESS != lError){
|
|
|
|
//
|
|
// Unable to get InfSection.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! Unable to get InfSection.\r\n", LogSevError);
|
|
goto WriteDeviceToFile_return;
|
|
} // if(ERROR_SUCCESS != lError)
|
|
|
|
if(REG_SZ != dwType){
|
|
|
|
//
|
|
// InfSection key is other than REG_SZ.
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! InfSection is other than REG_SZ.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
} // if(REG_SZ != dwType)
|
|
|
|
if(dwSize > MAX_PATH+1){
|
|
|
|
//
|
|
// Too long
|
|
//
|
|
|
|
SetupLogError("WIA Migration: WriteDeviceToFile: ERROR!! InfSection is too long.\r\n", LogSevError);
|
|
lError = ERROR_REGISTRY_CORRUPT;
|
|
goto WriteDeviceToFile_return;
|
|
}
|
|
|
|
//
|
|
// Spew device information.
|
|
//
|
|
|
|
WriteToFile(hFile, "\r\n");
|
|
WriteToFile(hFile, "\"%s\" = \"%s\"\r\n", NAME_DEVICE_A, NAME_BEGIN_A);
|
|
WriteToFile(hFile, "\"%s\" = \"%s\"\r\n", NAME_FRIENDLYNAME_A, pFriendlyName);
|
|
WriteToFile(hFile, "\"%s\" = \"%s\"\r\n", NAME_CREATEFILENAME_A, pCreateFileName);
|
|
WriteToFile(hFile, "\"%s\" = \"%s\"\r\n", NAME_INF_PATH_A, pInfPath);
|
|
WriteToFile(hFile, "\"%s\" = \"%s\"\r\n", NAME_INF_SECTION_A, pInfSection);
|
|
|
|
//
|
|
// Spew DaviceData section.
|
|
//
|
|
|
|
lError = RegOpenKey(hKey,
|
|
REGKEY_DEVICEDATA_A,
|
|
&hDeviceData);
|
|
|
|
if(lError != ERROR_SUCCESS){
|
|
|
|
//
|
|
// Unable to open DeviceData or doesn't exist.
|
|
//
|
|
|
|
}
|
|
|
|
//
|
|
// Spew DeviceData section if exists.
|
|
//
|
|
|
|
if(INVALID_HANDLE_VALUE != hDeviceData){
|
|
|
|
lError = WriteRegistryToFile(hFile, hDeviceData, REGKEY_DEVICEDATA_A);
|
|
|
|
} // if(INVALID_HANDLE_VALUE != hDeviceData)
|
|
|
|
//
|
|
// Indicate the end of device description.
|
|
//
|
|
|
|
WriteToFile(hFile, "\"%s\" = \"%s\"\r\n", NAME_DEVICE_A, NAME_END_A);
|
|
|
|
WriteDeviceToFile_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(INVALID_HANDLE_VALUE != hDeviceData){
|
|
RegCloseKey(hDeviceData);
|
|
} //if(INVALID_HANDLE_VALUE != hDeviceData)
|
|
|
|
if(NULL != pFriendlyName){
|
|
FreeMem(pFriendlyName);
|
|
}
|
|
|
|
if(NULL != pCreateFileName){
|
|
FreeMem(pCreateFileName);
|
|
}
|
|
|
|
if(NULL != pInfPath){
|
|
FreeMem(pInfPath);
|
|
}
|
|
|
|
if(NULL != pInfSection){
|
|
FreeMem(pInfSection);
|
|
}
|
|
|
|
return lError;
|
|
} // WriteDeviceToFile()
|
|
|
|
|
|
//
|
|
// The following are to make sure if setup changes the header file they
|
|
// first tell me (otherwise they will break build of this)
|
|
//
|
|
|
|
P_INITIALIZE_9X pfnInitialize9x = Initialize9x;
|
|
P_MIGRATE_USER_9X pfnMigrateUser9x = MigrateUser9x;
|
|
P_MIGRATE_SYSTEM_9X pfnMigrateSystem9x = MigrateSystem9x;
|