Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

icmupg.c

Go to the documentation of this file.
00001 /****************************Module*Header******************************\ 00002 * Module Name: ICMUPG.C 00003 * 00004 * Module Descripton: This file has code that upgrades Win9x ICM to 00005 * Memphis and NT 5.0 00006 * 00007 * Warnings: 00008 * 00009 * Issues: 00010 * 00011 * Public Routines: 00012 * 00013 * Created: 14 November 1996 00014 * Author: Srinivasan Chandrasekar [srinivac] 00015 * 00016 * Copyright (c) 1996, 1997 Microsoft Corporation 00017 \***********************************************************************/ 00018 00019 #include "icmupg.h" 00020 #include "msg.h" 00021 #include <setupapi.h> 00022 #include <stdio.h> 00023 00024 00025 //#define ICM_MIG_DEBUG 00026 00027 #ifdef UNICODE 00028 error. 00029 This dll needs to be built with ANSI, not UNICODE because it must run on 00030 Win95, Win98 and on Windows 2000 00031 #endif 00032 00033 00034 // 00035 // Local typedefs 00036 // 00037 00038 typedef struct tagMANUMODELIDS { 00039 DWORD dwManuID; 00040 DWORD dwModelID; 00041 } MANUMODELIDS, *PMANUMODELIDS; 00042 00043 typedef struct tagREGDATA { 00044 DWORD dwRefCount; 00045 DWORD dwManuID; 00046 DWORD dwModelID; 00047 } REGDATA, *PREGDATA; 00048 00049 typedef BOOL (WINAPI *PFNINSTALLCOLORPROFILEA)(PSTR, PSTR); 00050 typedef BOOL (WINAPI *PFNINSTALLCOLORPROFILE)(LPCTSTR, LPCTSTR); 00051 typedef BOOL (WINAPI *PFNENUMCOLORPROFILES)(PCTSTR, PENUMTYPE, PBYTE, PDWORD, PDWORD); 00052 00053 typedef struct { 00054 CHAR CompanyName[256]; 00055 CHAR SupportNumber[256]; 00056 CHAR SupportUrl[256]; 00057 CHAR InstructionsToUser[1024]; 00058 } VENDORINFO, *PVENDORINFO; 00059 00060 00061 // 00062 // Global variables 00063 // 00064 00065 TCHAR const gszICMRegPath[] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ICM"; 00066 TCHAR const gszProfile[] = "profile"; 00067 TCHAR const gszMSCMSdll[] = "mscms.dll"; 00068 00069 char const gszProductID[] = "Microsoft Color Management System"; 00070 00071 char const gszInstallColorProfile[] = "InstallColorProfileA"; 00072 char const gszGetColorDirectory[] = "GetColorDirectoryA"; 00073 char const gszEnumColorProfiles[] = "EnumColorProfilesA"; 00074 VENDORINFO gVendorInfo; 00075 char gszMigInf[MAX_PATH]; 00076 char const gszFullICMRegPath[] = "\"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ICM\""; 00077 00078 char const gszInstallColorProfileA[] = "InstallColorProfileA"; 00079 00080 00081 //BOOL gbWin98 = FALSE; 00082 00083 #ifdef DBG 00084 DWORD gdwDebugControl; 00085 #endif 00086 TCHAR szValue[MAX_PATH]; 00087 TCHAR szName[MAX_PATH]; 00088 00089 PFNINSTALLCOLORPROFILEA pInstallColorProfileA = NULL; 00090 PFNINSTALLCOLORPROFILE pInstallColorProfile = NULL; 00091 PFNENUMCOLORPROFILES pEnumColorProfiles = NULL; 00092 00093 // 00094 // Local functions 00095 // 00096 00097 VOID InternalUpgradeICM(); 00098 VOID UpgradeClass(HKEY); 00099 BOOL AssociateMonitorProfile(); 00100 BOOL AssociatePrinterProfiles(HKEY); 00101 VOID InstallProfiles(); 00102 VOID DeleteOldICMKey(); 00103 void GetManuAndModelIDs(PTSTR, DWORD*, DWORD*); 00104 int lstrcmpn(PTSTR, PTSTR, DWORD); 00105 00106 HINSTANCE hinstMigDll; 00107 00108 00109 BOOL WINAPI 00110 DllEntryPoint(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved) { 00111 if(dwReason==DLL_PROCESS_ATTACH) { 00112 hinstMigDll = hinstDll; 00113 } 00114 return TRUE; 00115 } 00116 00117 00118 00119 /****************************************************************************** 00120 * 00121 * QueryVersion 00122 * 00123 * Function: 00124 * This function is called to get the DLL version information. 00125 * 00126 * Arguments: 00127 * pszProductID - Fill in a unique string identifying us. 00128 * puDllVersion - Our DLL version 00129 * 00130 * None of the other arguments are used 00131 * 00132 * Returns: 00133 * ERROR_SUCCESS to indicate success 00134 * 00135 ******************************************************************************/ 00136 00137 LONG 00138 CALLBACK 00139 QueryVersion( 00140 OUT LPCSTR *pszProductID, 00141 OUT LPUINT puDllVersion, 00142 OUT LPINT *pCodePageArray, OPTIONAL 00143 OUT LPCSTR *ppszExeNamesBuf, OPTIONAL 00144 OUT PVENDORINFO *ppVendorInfo 00145 ) 00146 { 00147 *pszProductID = gszProductID; 00148 *puDllVersion = 1; 00149 *ppszExeNamesBuf = NULL; 00150 *pCodePageArray = NULL; 00151 *ppVendorInfo = &gVendorInfo; 00152 memset(&gVendorInfo, 0, sizeof(VENDORINFO)); 00153 FormatMessageA( 00154 FORMAT_MESSAGE_FROM_HMODULE, 00155 hinstMigDll, 00156 MSG_VI_COMPANY_NAME, 00157 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00158 gVendorInfo.CompanyName, 00159 sizeof(gVendorInfo.CompanyName), 00160 NULL 00161 ); 00162 00163 FormatMessageA( 00164 FORMAT_MESSAGE_FROM_HMODULE, 00165 hinstMigDll, 00166 MSG_VI_SUPPORT_NUMBER, 00167 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00168 gVendorInfo.SupportNumber, 00169 sizeof(gVendorInfo.SupportNumber), 00170 NULL 00171 ); 00172 00173 FormatMessageA( 00174 FORMAT_MESSAGE_FROM_HMODULE, 00175 hinstMigDll, 00176 MSG_VI_SUPPORT_URL, 00177 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00178 gVendorInfo.SupportUrl, 00179 sizeof(gVendorInfo.SupportUrl), 00180 NULL 00181 ); 00182 00183 FormatMessageA( 00184 FORMAT_MESSAGE_FROM_HMODULE, 00185 hinstMigDll, 00186 MSG_VI_INSTRUCTIONS, 00187 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00188 gVendorInfo.InstructionsToUser, 00189 sizeof(gVendorInfo.InstructionsToUser), 00190 NULL 00191 ); 00192 WARNING((__TEXT("QueryVersion called\n"))); 00193 return ERROR_SUCCESS; 00194 } 00195 00196 00197 /****************************************************************************** 00198 * 00199 * Initialize9x 00200 * 00201 * Function: 00202 * This function is called when upgrading to NT 5.0 from Win9x on the 00203 * Win9x side. 00204 * 00205 * Arguments: 00206 * pszWorkingDir - Directory where migrate.inf will be found 00207 * 00208 * Returns: 00209 * ERROR_SUCCESS to indicate success 00210 * 00211 ******************************************************************************/ 00212 00213 LONG 00214 CALLBACK 00215 Initialize9x( 00216 IN LPCSTR pszWorkingDir, 00217 IN LPCSTR pszSourceDir, 00218 IN LPVOID pvReserved 00219 ) 00220 { 00221 // 00222 // Lets figure out if we're on a Win98 or Win95 system 00223 // We don't migrate Win95 because Win95 doesn't have a 00224 // profile database to migrate. 00225 // 00226 00227 /* OSVERSIONINFO osVer; 00228 00229 osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00230 GetVersionEx(&osVer); 00231 gbWin98 = 00232 (osVer.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && 00233 ( (osVer.dwMajorVersion > 4) || 00234 ( (osVer.dwMajorVersion == 4) && (osVer.dwMinorVersion > 0) ) ); 00235 */ 00236 WARNING((__TEXT("Initialize9x called\n"))); 00237 00238 lstrcpyA(gszMigInf, pszWorkingDir); 00239 lstrcatA(gszMigInf, "\\migrate.inf"); 00240 00241 return ERROR_SUCCESS; 00242 } 00243 00244 00245 /****************************************************************************** 00246 * 00247 * MigrateUser9x 00248 * 00249 * Function: 00250 * This function is called on Win9x to upgrade per user settings. 00251 * 00252 * Arguments: 00253 * None of the arguments are used 00254 * 00255 * Returns: 00256 * ERROR_SUCCES to indicate success 00257 * 00258 ******************************************************************************/ 00259 00260 LONG 00261 CALLBACK 00262 MigrateUser9x( 00263 IN HWND hwndParent, 00264 IN LPCSTR pszUnattendFile, 00265 IN HKEY hUserRegKey, 00266 IN LPCSTR pszUserName, 00267 LPVOID pvReserved 00268 ) 00269 { 00270 // 00271 // Nothing to do 00272 // 00273 00274 WARNING((__TEXT("MigrateUser9x called\n"))); 00275 return ERROR_SUCCESS; 00276 } 00277 00278 00279 /****************************************************************************** 00280 * 00281 * MigrateSystem9x 00282 * 00283 * Function: 00284 * This function is called on the Win9x to upgrade system settings. 00285 * 00286 * Arguments: 00287 * None of the arguments are used 00288 * 00289 * Returns: 00290 * ERROR_SUCCES to indicate success 00291 * 00292 ******************************************************************************/ 00293 00294 LONG 00295 CALLBACK 00296 MigrateSystem9x( 00297 IN HWND hwndParent, 00298 IN LPCSTR pszUnattendFile, 00299 LPVOID pvReserved 00300 ) 00301 { 00302 DWORD nProfiles; 00303 DWORD dwSize; 00304 char szColorDir[MAX_PATH]; 00305 char szNewColorDir[MAX_PATH]; 00306 char szDrive[2]; 00307 HMODULE hModule; 00308 ENUMTYPE et = {sizeof (ENUMTYPE), ENUM_TYPE_VERSION, 0, NULL}; 00309 PBYTE pBuffer; 00310 PSTR pstrBuffer; 00311 PSTR pstrTraversal; 00312 00313 WARNING((__TEXT("MigrateSystem9x called\n"))); 00314 00315 // 00316 // Produce the Win9x Color Directory. 00317 // 00318 00319 GetWindowsDirectoryA(szColorDir, MAX_PATH); 00320 if (szColorDir[lstrlenA(szColorDir)-1] != '\\') 00321 { 00322 lstrcatA(szColorDir,"\\"); 00323 } 00324 lstrcatA(szColorDir, "system\\color\\"); 00325 00326 GetWindowsDirectoryA(szNewColorDir, MAX_PATH); 00327 if (szNewColorDir[lstrlenA(szNewColorDir)-1] != '\\') 00328 { 00329 lstrcatA(szNewColorDir,"\\"); 00330 } 00331 lstrcatA(szNewColorDir, "system32\\spool\\drivers\\color\\"); 00332 00333 00334 // 00335 // If this is a Win95 system we have nothing to do because 00336 // Win95 doesn't have a color profile database. 00337 // 00338 00339 00340 // 00341 // We can't have mscms as an implib because when they try to load us in 00342 // Win95, they won't find mscms.dll and reject us. 00343 // 00344 00345 hModule = LoadLibrary(gszMSCMSdll); 00346 if (hModule) { 00347 #ifdef ICM_MIG_DEBUG 00348 WritePrivateProfileStringA("ICM Debug", "hModule", "not NULL", gszMigInf); 00349 WritePrivateProfileStringA("ICM Debug", "gbWin98", "TRUE", gszMigInf); 00350 #endif 00351 00352 pEnumColorProfiles = (PFNENUMCOLORPROFILES)GetProcAddress(hModule, gszEnumColorProfiles); 00353 if (pEnumColorProfiles) { 00354 00355 #ifdef ICM_MIG_DEBUG 00356 WritePrivateProfileStringA("ICM Debug", "pEnumColorProfiles", "not NULL", gszMigInf); 00357 #endif 00358 00359 // 00360 // Compute the size of the EnumColorProfiles buffer. 00361 // 00362 00363 dwSize = 0; 00364 pEnumColorProfiles(NULL, &et, NULL, &dwSize, &nProfiles); 00365 00366 if(dwSize==0) 00367 { 00368 #ifdef ICM_MIG_DEBUG 00369 WritePrivateProfileStringA("ICM Debug", "dwSize", "0", gszMigInf); 00370 #endif 00371 // 00372 // Need to exit - nothing to do if there are no profiles installed, 00373 // except to move the directory and registry settings. 00374 // 00375 WARNING((__TEXT("No profiles installed\n"))); 00376 goto EndMigrateSystem9x; 00377 } 00378 00379 00380 // 00381 // Enumerate all the currently installed color profiles. 00382 // 00383 00384 #ifdef ICM_MIG_DEBUG 00385 WritePrivateProfileStringA("ICM Debug", "Enumerate", "Start", gszMigInf); 00386 #endif 00387 00388 pBuffer = (BYTE *)malloc(dwSize); 00389 pstrBuffer = (PSTR)pBuffer; 00390 00391 #ifdef ICM_MIG_DEBUG 00392 WritePrivateProfileStringA("ICM Debug", "Enumerate", "TRUE", gszMigInf); 00393 #endif 00394 00395 if(pEnumColorProfiles(NULL, &et, pBuffer, &dwSize, &nProfiles)) 00396 { 00397 #ifdef ICM_MIG_DEBUG 00398 WritePrivateProfileStringA("ICM Debug", "Enumerate", "for", gszMigInf); 00399 #endif 00400 00401 for(pstrTraversal = pstrBuffer; 00402 nProfiles--; 00403 pstrTraversal += 1 + lstrlenA(pstrTraversal)) { 00404 00405 // 00406 // Write the fact into the Migration Information file. 00407 // 00408 00409 WritePrivateProfileStringA("Installed ICM Profiles", pstrTraversal, "1", gszMigInf); 00410 } 00411 } 00412 free(pBuffer); 00413 } 00414 #ifdef ICM_MIG_DEBUG 00415 else { 00416 WritePrivateProfileStringA("ICM Debug", "pEnumColorProfiles", "NULL", gszMigInf); 00417 } 00418 #endif 00419 00420 00421 EndMigrateSystem9x: 00422 if (hModule) 00423 { 00424 FreeLibrary(hModule); 00425 } 00426 } 00427 #ifdef ICM_MIG_DEBUG 00428 else { 00429 WritePrivateProfileStringA("ICM Debug", "hModule", "NULL", gszMigInf); 00430 WritePrivateProfileStringA("ICM Debug", "gbWin98", "FALSE", gszMigInf); 00431 } 00432 #endif 00433 00434 // 00435 // We'll handle the ICM branch of the registry 00436 // 00437 00438 WritePrivateProfileStringA("Handled", gszFullICMRegPath, "Registry", gszMigInf); 00439 00440 00441 // 00442 // We'll be moving the entire subdirectory. 00443 // 00444 00445 WritePrivateProfileStringA("Moved", szColorDir, szNewColorDir, gszMigInf); 00446 00447 00448 return ERROR_SUCCESS; 00449 } 00450 00451 00452 /****************************************************************************** 00453 * 00454 * InitializeNT 00455 * 00456 * Function: 00457 * This function is called when upgrading to NT 5.0 from Win9x on the NT 00458 * side. Its main purpose is to initialize us. 00459 * 00460 * Arguments: 00461 * None of the arguments are used 00462 * 00463 * Returns: 00464 * ERROR_SUCCESS to indicate success 00465 * 00466 ******************************************************************************/ 00467 00468 LONG 00469 CALLBACK 00470 InitializeNT( 00471 IN LPCWSTR pszWorkingDir, 00472 IN LPCWSTR pszSourceDir, 00473 LPVOID pvReserved 00474 ) 00475 { 00476 SetupOpenLog(FALSE); 00477 SetupLogError("ICM Migration: InitializeNT called\r\n", LogSevInformation); 00478 return ERROR_SUCCESS; 00479 } 00480 00481 00482 /****************************************************************************** 00483 * 00484 * MigrateUserNT 00485 * 00486 * Function: 00487 * This function is called on the NT to upgrade per user settings. 00488 * 00489 * Arguments: 00490 * None of the arguments are used 00491 * 00492 * Returns: 00493 * ERROR_SUCCES to indicate success 00494 * 00495 ******************************************************************************/ 00496 00497 LONG 00498 CALLBACK 00499 MigrateUserNT( 00500 IN HANDLE hUnattendInf, 00501 IN HKEY hUserRegKey, 00502 IN LPCWSTR pszUserName, 00503 LPVOID pvReserved 00504 ) 00505 { 00506 SetupLogError("ICM Migration: MigrateUserNT called\r\n", LogSevInformation); 00507 00508 // 00509 // Nothing to do 00510 // 00511 00512 return ERROR_SUCCESS; 00513 } 00514 00515 00516 /****************************************************************************** 00517 * 00518 * MigrateSystemNT 00519 * 00520 * Function: 00521 * This function is called on the Win9x to upgrade system settings. This 00522 * is where we upgrade ICM 2.0 00523 * 00524 * Arguments: 00525 * None of the other arguments are used 00526 * 00527 * Returns: 00528 * ERROR_SUCCES to indicate success 00529 * 00530 ******************************************************************************/ 00531 00532 LONG 00533 CALLBACK 00534 MigrateSystemNT( 00535 IN HANDLE hUnattendInf, 00536 LPVOID pvReserved 00537 ) 00538 { 00539 HINSTANCE hModule; 00540 LONG rc = ERROR_FILE_NOT_FOUND; 00541 CHAR szMessage[MAX_PATH]; 00542 00543 SetupLogError("ICM Migration: MigrateSystemNT called\r\n", LogSevInformation); 00544 00545 // 00546 // We can't have mscms as an implib because when they try to load us in 00547 // Win95, they won't find mscms.dll and reject us. 00548 // 00549 00550 hModule = LoadLibrary(gszMSCMSdll); 00551 if (!hModule) 00552 { 00553 sprintf(szMessage, "ICM Migration: Fatal Error, cannot load mscms.dll. Error %d\r\n", GetLastError()); 00554 SetupLogError(szMessage, LogSevFatalError); 00555 return rc; 00556 } 00557 00558 pInstallColorProfileA = (PFNINSTALLCOLORPROFILEA)GetProcAddress(hModule, gszInstallColorProfileA); 00559 pInstallColorProfile = (PFNINSTALLCOLORPROFILE)GetProcAddress(hModule, gszInstallColorProfile); 00560 00561 if (!pInstallColorProfile || !pInstallColorProfileA) 00562 { 00563 SetupLogError("ICM Migration: Fatal Error, cannot find mscms functions. \r\n", LogSevFatalError); 00564 goto EndMigrateSystemNT; 00565 } 00566 00567 InternalUpgradeICM(); // Upgrade over Win9x 00568 InstallProfiles(); // Install all profiles in the old color directory 00569 DeleteOldICMKey(); 00570 00571 rc = ERROR_SUCCESS; 00572 00573 EndMigrateSystemNT: 00574 00575 if (hModule) 00576 { 00577 FreeLibrary(hModule); 00578 } 00579 00580 return rc; 00581 } 00582 00583 00584 /****************************************************************************** 00585 * 00586 * DeleteOldICMKey 00587 * 00588 * Function: 00589 * This function deletes the ICM key and subkeys from the Windows branch. 00590 * 00591 * Arguments: 00592 * None 00593 * 00594 * Returns: 00595 * Nothing 00596 * 00597 ******************************************************************************/ 00598 00599 VOID 00600 DeleteOldICMKey() 00601 { 00602 HKEY hkICM = NULL; // key to ICM branch in registry 00603 DWORD nSubkeys, i; 00604 TCHAR szKeyName[32]; 00605 00606 // 00607 // Open the registry path where profiles used to be kept 00608 // 00609 00610 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, gszICMRegPath, 0, NULL, 00611 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 00612 NULL, &hkICM, NULL) != ERROR_SUCCESS) 00613 { 00614 00615 SetupLogError("ICM Migration: Cannot open ICM branch of registry\r\n", LogSevError); 00616 return; 00617 } 00618 00619 if (RegQueryInfoKey(hkICM, NULL, NULL, 0, &nSubkeys, NULL, NULL, 00620 NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 00621 { 00622 SetupLogError("ICM Migration: Cannot enumerate ICM branch of registry\r\n", LogSevError); 00623 goto EndDeleteOldICMKey; 00624 } 00625 00626 // 00627 // Go through all the device classes and delete all subkeys - this should 00628 // only be one level deep 00629 // 00630 00631 for (i=nSubkeys; i>0; i--) 00632 { 00633 RegEnumKey(hkICM, i-1, szKeyName, sizeof(szKeyName)); 00634 RegDeleteKey(hkICM, szKeyName); 00635 } 00636 00637 EndDeleteOldICMKey: 00638 if (hkICM) 00639 { 00640 RegCloseKey(hkICM); 00641 } 00642 RegDeleteKey(HKEY_LOCAL_MACHINE, gszICMRegPath); 00643 00644 return; 00645 } 00646 00647 00648 // 00649 // Move directory with contents. 00650 // Note this is not recursive. 00651 // The purpose of this routine is to move the old color directory to the 00652 // new color directory. During setup the new color directory may have already 00653 // been created and populated with files. Vendor apps may have populated the 00654 // old color directory with private subdirectories and files which will not 00655 // appear in the new directory created by setup. This routine is designed 00656 // to move those files. 00657 // 00658 // Note it'll fail to move a subdirectory of the old color directory if 00659 // a similar subdirectory exists in the new color directory - this should not 00660 // be the case. 00661 // 00662 // s and d should have the trailing slash. 00663 // 00664 00665 void MyMoveDir(char *s, char *d) { 00666 WIN32_FIND_DATA rf; 00667 HANDLE hf; 00668 char s2[MAX_PATH]; 00669 char s_[MAX_PATH]; 00670 char d_[MAX_PATH]; 00671 char err[MAX_PATH]; 00672 00673 // 00674 // If MoveFileEx succeeds, we're done. 00675 // 00676 00677 if(!MoveFileEx(s, d, MOVEFILE_REPLACE_EXISTING)) { 00678 sprintf(s2, "%s*", s); 00679 hf = FindFirstFile(s2, &rf); 00680 do { 00681 // don't move . and .. 00682 if(!(strcmp(".", rf.cFileName)==0 || 00683 strcmp("..", rf.cFileName)==0) ) { 00684 sprintf(s_, "%s%s", s, rf.cFileName); 00685 sprintf(d_, "%s%s", d, rf.cFileName); 00686 if(!MoveFileEx(s_, d_, MOVEFILE_REPLACE_EXISTING)) { 00687 int e = GetLastError(); 00688 sprintf(err, "ICM Migration: Failed the move of %s with %d\r\n", s_, e); 00689 SetupLogError(err, LogSevError); 00690 } else { 00691 sprintf(err, "ICM Migration: Moved %s to %s\n", s_, d_); 00692 SetupLogError(err, LogSevInformation); 00693 } 00694 } 00695 00696 } while(FindNextFile(hf, &rf)); 00697 FindClose(hf); 00698 } 00699 00700 // 00701 // source directory should theoretically be empty at this point 00702 // If there are errors, we'll leave files behind and report this in 00703 // the setup log as a LogSevError. 00704 // 00705 } 00706 00707 00708 00709 /****************************************************************************** 00710 * 00711 * InstallProfiles 00712 * 00713 * Function: 00714 * This function installs all profiles in %windir%\system\color. 00715 * This is used when upgrading from Win9x to NT 5.0. 00716 * 00717 * Arguments: 00718 * None 00719 * 00720 * Returns: 00721 * Nothing 00722 * 00723 ******************************************************************************/ 00724 00725 VOID 00726 InstallProfiles() 00727 { 00728 WIN32_FIND_DATAA wfd; 00729 PSTR pNewColorDirEnd; 00730 HANDLE hFindFile; 00731 CHAR szOldColorDir[MAX_PATH]; 00732 CHAR szNewColorDir[MAX_PATH]; 00733 CHAR szReturnString[2]; 00734 CHAR szDefaultString[2]; 00735 CHAR szMessage[2*MAX_PATH+100]; 00736 00737 GetWindowsDirectoryA(szOldColorDir, MAX_PATH); 00738 if (szOldColorDir[lstrlenA(szOldColorDir)-1] != '\\') 00739 lstrcatA(szOldColorDir, "\\"); 00740 lstrcatA(szOldColorDir, "system\\color\\"); 00741 00742 00743 GetWindowsDirectoryA(szNewColorDir, MAX_PATH); 00744 if (szNewColorDir[lstrlenA(szNewColorDir)-1] != '\\') 00745 { 00746 lstrcatA(szNewColorDir, "\\"); 00747 } 00748 lstrcatA(szNewColorDir, "system32\\spool\\drivers\\color\\"); 00749 00750 ASSERT(pInstallColorProfileA != NULL); 00751 00752 00753 // 00754 // Eat any errors on the MoveFile. This is just in case the migration 00755 // was stopped after a previous move and now the source doesn't exist. 00756 // 00757 00758 MyMoveDir(szOldColorDir, szNewColorDir); 00759 00760 // 00761 // Now we have presumably moved everything so run through the list of 00762 // previously installed profiles and install those in the new directory 00763 // (if we find them). 00764 // 00765 00766 pNewColorDirEnd = szNewColorDir + lstrlenA(szNewColorDir); 00767 lstrcatA(szNewColorDir, "*.*"); 00768 00769 00770 00771 szDefaultString[0]='0'; 00772 szDefaultString[1]=0; 00773 hFindFile = FindFirstFileA(szNewColorDir, &wfd); 00774 00775 00776 if (hFindFile != INVALID_HANDLE_VALUE) 00777 { 00778 do 00779 { 00780 lstrcpyA(pNewColorDirEnd, wfd.cFileName); 00781 00782 // 00783 // Check to see if the profile was installed on Win9x 00784 // 00785 00786 GetPrivateProfileStringA("Installed ICM Profiles", wfd.cFileName, szDefaultString, szReturnString, 2, gszMigInf); 00787 00788 // 00789 // If it was installed, attempt to install it on NT 00790 // 00791 00792 if(szReturnString[0]=='1') { 00793 if (!(*pInstallColorProfileA)(NULL, szNewColorDir)) 00794 { 00795 sprintf(szMessage, "ICM Migration: Error %d installing profile %s\r\n", GetLastError(), szNewColorDir); 00796 SetupLogError(szMessage, LogSevError); 00797 } 00798 else 00799 { 00800 sprintf(szMessage, "ICM Migration: Installed profile %s\r\n", szNewColorDir); 00801 SetupLogError(szMessage, LogSevInformation); 00802 } 00803 } 00804 00805 } while (FindNextFileA(hFindFile, &wfd)); 00806 00807 FindClose(hFindFile); 00808 } 00809 else 00810 { 00811 SetupLogError("ICM Migration: FindFirstFile returned an invalid handle\r\n", LogSevFatalError); 00812 } 00813 } 00814 00815 00816 /****************************************************************************** 00817 * 00818 * InternalUpgradeICM 00819 * 00820 * Function: 00821 * This function forms the core of the upgrade code. It installs all 00822 * profiles in the regsitry, and associates with the right devices 00823 * 00824 * Arguments: 00825 * None 00826 * 00827 * Returns: 00828 * Nothing 00829 * 00830 ******************************************************************************/ 00831 00832 VOID 00833 InternalUpgradeICM() 00834 { 00835 HKEY hkICM = NULL; // key to ICM branch in registry 00836 HKEY hkDevice = NULL; // key to ICM device branch in registry 00837 int i; // counter variable 00838 TCHAR *pszClasses[] = { // different profile classes 00839 __TEXT("mntr"), 00840 __TEXT("prtr"), 00841 __TEXT("scnr"), 00842 __TEXT("link"), 00843 __TEXT("abst"), 00844 __TEXT("spac"), 00845 __TEXT("nmcl") 00846 }; 00847 CHAR szMessage[MAX_PATH]; 00848 LONG errcode; 00849 00850 // 00851 // Open the registry path where profiles are kept 00852 // 00853 00854 if (errcode = RegCreateKeyEx(HKEY_LOCAL_MACHINE, gszICMRegPath, 0, NULL, 00855 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, 00856 &hkICM, NULL) != ERROR_SUCCESS) 00857 { 00858 sprintf(szMessage, "ICM Migration: Fatal Error, cannot open registry entry (%s) code:%d\r\n", 00859 gszICMRegPath, errcode); 00860 SetupLogError(szMessage, LogSevFatalError); 00861 return; 00862 } 00863 00864 // 00865 // Go through all the device classes and install the profiles 00866 // 00867 00868 for (i=0; i<sizeof(pszClasses)/sizeof(PTSTR); i++) 00869 { 00870 if (RegOpenKeyEx(hkICM, pszClasses[i], 0, KEY_ALL_ACCESS, &hkDevice) != ERROR_SUCCESS) 00871 { 00872 continue; // go to next key 00873 } 00874 00875 sprintf(szMessage, "ICM Migration: Upgrading %s\r\n", pszClasses[i]); 00876 SetupLogError(szMessage, LogSevInformation); 00877 UpgradeClass(hkDevice); 00878 00879 RegCloseKey(hkDevice); 00880 } 00881 00882 // 00883 // Set default monitor profile 00884 // 00885 00886 // AssociateMonitorProfile(); - Not needed for Memphis 00887 // If Pnp moves everything from Win9x PnP S/W section to NT 5.0 PnP S/W 00888 // section, then we don't need this for NT either 00889 00890 if (hkICM) 00891 { 00892 RegCloseKey(hkICM); 00893 } 00894 00895 return; 00896 } 00897 00898 00899 /****************************************************************************** 00900 * 00901 * UpgradeClass 00902 * 00903 * Function: 00904 * This function recursively calls itself to go down a registry path 00905 * till it reaches the leaf, and installs all profiles it finds there 00906 * 00907 * Arguments: 00908 * hKey - registry key for root node 00909 * 00910 * Returns: 00911 * Nothing 00912 * 00913 ******************************************************************************/ 00914 00915 VOID 00916 UpgradeClass( 00917 HKEY hKey 00918 ) 00919 { 00920 HKEY hSubkey; 00921 DWORD nSubkeys, nValues, i, cbName, cbValue; 00922 TCHAR szKeyName[32]; 00923 CHAR szMessage[MAX_PATH]; 00924 00925 // 00926 // If there is an error, return 00927 // 00928 00929 if (RegQueryInfoKey(hKey, NULL, NULL, 0, &nSubkeys, NULL, NULL, 00930 &nValues, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 00931 { 00932 return; 00933 } 00934 00935 if (nSubkeys > 0) 00936 { 00937 // 00938 // This is not the leaf node, recurse 00939 // 00940 00941 for (i=nSubkeys; i>0; i--) 00942 { 00943 RegEnumKey(hKey, i-1, szKeyName, sizeof(szKeyName)); 00944 if (RegOpenKeyEx(hKey, szKeyName, 0, KEY_ALL_ACCESS, &hSubkey) == ERROR_SUCCESS) 00945 { 00946 UpgradeClass(hSubkey); 00947 RegCloseKey(hSubkey); 00948 RegDeleteKey(hKey, szKeyName); 00949 } 00950 } 00951 } 00952 else 00953 { 00954 // 00955 // This is the leaf node - install all the profiles registered 00956 // 00957 00958 ASSERT(pInstallColorProfile != NULL); 00959 00960 for (i=nValues; i>0; i--) 00961 { 00962 cbName = MAX_PATH; 00963 cbValue = MAX_PATH; 00964 if (RegEnumValue(hKey, i-1, szName, &cbName, 0, NULL, (LPBYTE)szValue, 00965 &cbValue) == ERROR_SUCCESS) 00966 { 00967 if (! lstrcmpn(szName, (PTSTR)gszProfile, lstrlen(gszProfile))) 00968 { 00969 if (! (*pInstallColorProfile)(NULL, szValue)) 00970 { 00971 sprintf(szMessage, "ICM Migration: Error installing profile %s\r\n", szValue); 00972 SetupLogError(szMessage, LogSevError); 00973 } 00974 else 00975 { 00976 sprintf(szMessage, "ICM Migration: Installed profile %s\r\n", szValue); 00977 SetupLogError(szMessage, LogSevInformation); 00978 } 00979 } 00980 else 00981 { 00982 PTSTR pProfile; 00983 00984 // 00985 // We might be upgrading over Memphis or later 00986 // In Memphis it is "file name" "value" instead of 00987 // "profilexx" "value" in Win95 & OSR2 00988 // 00989 00990 if (szName[1] == ':') 00991 { 00992 // 00993 // Assume full path name 00994 // 00995 00996 pProfile = szName; 00997 00998 } 00999 else 01000 { 01001 GetWindowsDirectory(szValue, MAX_PATH); 01002 if (szValue[lstrlen(szValue)-1] != '\\') 01003 lstrcat(szValue, __TEXT("\\")); 01004 lstrcat(szValue, __TEXT("system\\color\\")); 01005 lstrcat(szValue, szName); 01006 pProfile = szValue; 01007 } 01008 01009 if (! (*pInstallColorProfile)(NULL, pProfile)) 01010 { 01011 sprintf(szMessage, "ICM Migration: Error installing profile %s\r\n", pProfile); 01012 SetupLogError(szMessage, LogSevError); 01013 } 01014 else 01015 { 01016 sprintf(szMessage, "ICM Migration: Installed Profile %s\r\n", pProfile); 01017 SetupLogError(szMessage, LogSevInformation); 01018 } 01019 } 01020 RegDeleteValue(hKey, szName); 01021 } 01022 } 01023 } 01024 01025 return; 01026 } 01027 01028 01029 /****************************************************************************** 01030 * 01031 * lstrcmpn 01032 * 01033 * Function: 01034 * This function compares dwLen characters of two strings and decides if 01035 * they are equal 01036 * 01037 * Arguments: 01038 * pStr1 - pointer to string 1 01039 * pStr2 - pointer to string 2 01040 * dwLen - number of characters to compare 01041 * 01042 * Returns: 01043 * Zero if the strings are equal, non zero otherwise 01044 * 01045 ******************************************************************************/ 01046 01047 int 01048 lstrcmpn( 01049 PTSTR pStr1, 01050 PTSTR pStr2, 01051 DWORD dwLen 01052 ) 01053 { 01054 // 01055 // Assume no NULL strings 01056 // 01057 01058 while (*pStr1 && *pStr2 && --dwLen) 01059 { 01060 if (*pStr1 != *pStr2) 01061 break; 01062 01063 pStr1++; 01064 pStr2++; 01065 } 01066 01067 return (int)(*pStr1 - *pStr2); 01068 } 01069 #if DBG 01070 01071 /****************************************************************************** 01072 * 01073 * MyDebugPrint 01074 * 01075 * Function: 01076 * This function takes a format string and paramters, composes a string 01077 * and sends it out to the debug port. Available only in debug build. 01078 * 01079 * Arguments: 01080 * pFormat - pointer to format string 01081 * ....... - parameters based on the format string like printf() 01082 * 01083 * Returns: 01084 * No return value 01085 * 01086 ******************************************************************************/ 01087 01088 VOID 01089 MyDebugPrintA( 01090 PSTR pFormat, 01091 ... 01092 ) 01093 { 01094 char szBuffer[256]; 01095 va_list arglist; 01096 01097 va_start(arglist, pFormat); 01098 wvsprintfA(szBuffer, pFormat, arglist); 01099 va_end(arglist); 01100 01101 OutputDebugStringA(szBuffer); 01102 01103 return; 01104 } 01105 01106 01107 VOID 01108 MyDebugPrintW( 01109 PWSTR pFormat, 01110 ... 01111 ) 01112 { 01113 WCHAR szBuffer[256]; 01114 va_list arglist; 01115 01116 va_start(arglist, pFormat); 01117 wvsprintfW(szBuffer, pFormat, arglist); 01118 va_end(arglist); 01119 01120 OutputDebugStringW(szBuffer); 01121 01122 return; 01123 } 01124 01125 /****************************************************************************** 01126 * 01127 * StripDirPrefixA 01128 * 01129 * Function: 01130 * This function takes a path name and returns a pointer to the filename 01131 * part. This is availabel only for the debug build. 01132 * 01133 * Arguments: 01134 * pszPathName - path name of file (can be file name alone) 01135 * 01136 * Returns: 01137 * A pointer to the file name 01138 * 01139 ******************************************************************************/ 01140 01141 PSTR 01142 StripDirPrefixA( 01143 PSTR pszPathName 01144 ) 01145 { 01146 DWORD dwLen = lstrlenA(pszPathName); 01147 01148 pszPathName += dwLen - 1; // go to the end 01149 01150 while (*pszPathName != '\\' && dwLen--) 01151 { 01152 pszPathName--; 01153 } 01154 01155 return pszPathName + 1; 01156 } 01157 01158 #endif 01159 01160 #ifdef STANDALONE 01161 01162 // 01163 // For testing 01164 // 01165 01166 main() 01167 { 01168 UpgradeICM(NULL, NULL, NULL, 0); 01169 01170 TCHAR buffer[MAX_PATH]; 01171 MigrateInit(buffer, NULL, 0, NULL, NULL); 01172 MigrateInit(NULL, NULL, 0, NULL, NULL); 01173 MigrateLocalMachine(NULL, NULL); 01174 return 0; 01175 } 01176 #endif 01177

Generated on Sat May 15 19:40:20 2004 for test by doxygen 1.3.7