/*++ 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;