/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORP., 2000 * * TITLE: Entry.cpp * * VERSION: 1.0 * * AUTHOR: KeisukeT * * DATE: 27 Mar, 2000 * * DESCRIPTION: * Co/Installer/DLL entry point. * *******************************************************************************/ // // Precompiled header // #include "precomp.h" #pragma hdrstop // // Include // #include "sti_ci.h" #include #include "firstpg.h" #include "portsel.h" #include "nameit.h" #include "finalpg.h" #include "prevpg.h" #include "device.h" #include "stiregi.h" #include "userdbg.h" // // Global // HINSTANCE g_hDllInstance = NULL; // // Function // extern "C" BOOL APIENTRY DllMain( IN HINSTANCE hDll, IN ULONG ulReason, IN LPVOID lpReserved ) /*++ Routine Description: DllMain Entrypoint when this DLL is loaded. Arguments: IN HINSTANCE hDll Handle to this DLL instance. IN ULONG ulReason The reason this entry is called. IN LPVOID lpReserved Return Value: TRUE always. Side effects: None --*/ { if (ulReason == DLL_PROCESS_ATTACH) { // // Initialize globals. // g_hDllInstance = hDll; // // Initialize Fusion // SHFusionInitializeFromModuleID( hDll, 123 ); DisableThreadLibraryCalls(hDll); InitCommonControls(); DBG_INIT(g_hDllInstance); // MyDebugInit(); } else if (ulReason == DLL_PROCESS_DETACH) { // // Shutdown Fusion // SHFusionUninitialize(); } return TRUE; } // DllMain () extern "C" DWORD APIENTRY ClassInstall ( IN DI_FUNCTION diFunction, IN HDEVINFO hDevInfo, IN PSP_DEVINFO_DATA pDevInfoData ) /*++ Routine Description: ClassInstall Entrypoint of WIA class installer. Arguments: IN DI_FUNCTION diFunction Function to perform. IN HDEVINFO hDevInfo, Handle to Device Information. IN PSP_DEVINFO_DATA pDevInfoData Pointer to Device Data. Return Value: NO_ERROR - Operation succeeded. ERROR_DI_DO_DEFAULT - Operation succeeded, or failed but let it continue. Other - Operation failed and unable to continue. Side effects: None --*/ { DWORD dwReturn; DWORD dwError; DWORD dwSize; SP_INSTALLWIZARD_DATA InstallWizardData; SP_DEVINSTALL_PARAMS spDevInstallParams; BOOL fCleanupContext; PINSTALLER_CONTEXT pInstallerContext; DebugTrace(TRACE_PROC_ENTER,(("ClassInstall: Enter... \r\n"))); DebugTrace(TRACE_STATUS,(("ClassInstall: Processing %ws message.\r\n"), DifDebug[diFunction].DifString)); // // Initialize locals. // dwReturn = ERROR_DI_DO_DEFAULT; dwError = ERROR_SUCCESS; dwSize = 0; fCleanupContext = FALSE; pInstallerContext = NULL; memset(&InstallWizardData, 0, sizeof(InstallWizardData)); memset(&spDevInstallParams, 0, sizeof(spDevInstallParams)); // // Dispatch requests. // switch(diFunction){ case DIF_INSTALLWIZARD: { fCleanupContext = TRUE; // // Get install parameter(s). // InstallWizardData.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); if(!SetupDiGetClassInstallParams(hDevInfo, pDevInfoData, &InstallWizardData.ClassInstallHeader, sizeof(InstallWizardData), NULL) ) { dwError = GetLastError(); // DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiGetClassInstallParams failed. Err=0x%x. dwSize=0x%x\n"), dwError, dwSize)); DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiGetClassInstallParams failed. Err=0x%x\n"), dwError)); dwReturn = ERROR_DI_DONT_INSTALL; goto ClassInstall_return; } // // Check if operation is correct. // if (InstallWizardData.ClassInstallHeader.InstallFunction != diFunction) { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! InstallHeader.InstallFunction is incorrect..\r\n"))); dwReturn = ERROR_DI_DONT_INSTALL; goto ClassInstall_return; } // // Check if we still have enough room to add pages. // if( (MAX_INSTALLWIZARD_DYNAPAGES - NUM_WIA_PAGES) < InstallWizardData.NumDynamicPages ){ DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! No room for WIA installer pages.\r\n"))); dwReturn = ERROR_DI_DONT_INSTALL; goto ClassInstall_return; } // // Allocate context structure. // if(NULL == InstallWizardData.PrivateData){ pInstallerContext = new INSTALLER_CONTEXT; if(NULL == pInstallerContext){ DebugTrace(TRACE_WARNING,(("ClassInstall: ERROR!! Insufficient memory.\r\n"))); dwReturn = ERROR_DI_DONT_INSTALL; goto ClassInstall_return; } InstallWizardData.PrivateData = (DWORD_PTR)pInstallerContext; memset((PBYTE)pInstallerContext, 0, sizeof(INSTALLER_CONTEXT)); } else { DebugTrace(TRACE_WARNING,(("ClassInstall: WARNING!! Installer context already exists.\r\n"))); } // // See who invoked installer. // pInstallerContext->bShowFirstPage = InstallWizardData.PrivateFlags & SCIW_PRIV_SHOW_FIRST; pInstallerContext->bCalledFromControlPanal = InstallWizardData.PrivateFlags & SCIW_PRIV_CALLED_FROMCPL; // // Save device info set. // pInstallerContext->hDevInfo = hDevInfo; // // Save wizard windows handle. // pInstallerContext->hwndWizard = InstallWizardData.hwndWizardDlg; // // Create/Initialize all wizard pages and a device class object. // CFirstPage *tempFistPage = new CFirstPage(pInstallerContext); CPrevSelectPage *tempPrevSelectPage = new CPrevSelectPage(pInstallerContext); CPortSelectPage *tempPortSelectPage = new CPortSelectPage(pInstallerContext); CNameDevicePage *tempNameDevicePage = new CNameDevicePage(pInstallerContext); CInstallPage *tempInstallPage = new CInstallPage(pInstallerContext); if( (NULL == tempFistPage) || (NULL == tempPrevSelectPage) || (NULL == tempPortSelectPage) || (NULL == tempNameDevicePage) || (NULL == tempInstallPage) ) { DebugTrace(TRACE_WARNING,(("ClassInstall: ERROR!! Insufficient memory.\r\n"))); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // // Save created to context. // pInstallerContext->pFirstPage = (PVOID) tempFistPage; pInstallerContext->pPrevSelectPage = (PVOID) tempPrevSelectPage; pInstallerContext->pPortSelectPage = (PVOID) tempPortSelectPage; pInstallerContext->pNameDevicePage = (PVOID) tempNameDevicePage; pInstallerContext->pFinalPage = (PVOID) tempInstallPage; // // Add created pages. // InstallWizardData.DynamicPages[InstallWizardData.NumDynamicPages++] = tempFistPage->Handle(); InstallWizardData.DynamicPages[InstallWizardData.NumDynamicPages++] = tempPrevSelectPage->Handle(); InstallWizardData.DynamicPages[InstallWizardData.NumDynamicPages++] = tempPortSelectPage->Handle(); InstallWizardData.DynamicPages[InstallWizardData.NumDynamicPages++] = tempNameDevicePage->Handle(); InstallWizardData.DynamicPages[InstallWizardData.NumDynamicPages++] = tempInstallPage->Handle(); // // Indicate "pages are added". // InstallWizardData.DynamicPageFlags |= DYNAWIZ_FLAG_PAGESADDED; // // Set the parameters back. // SetupDiSetClassInstallParams (hDevInfo, pDevInfoData, &InstallWizardData.ClassInstallHeader, sizeof(InstallWizardData)); fCleanupContext = FALSE; dwReturn = NO_ERROR; goto ClassInstall_return; break; } // case DIF_INSTALLWIZARD: case DIF_DESTROYWIZARDDATA: { // // Get install parameter(s). // InstallWizardData.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); if(!SetupDiGetClassInstallParams(hDevInfo, pDevInfoData, &InstallWizardData.ClassInstallHeader, sizeof(InstallWizardData), &dwSize) ) { dwError = GetLastError(); DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiGetClassInstallParams failed. Err=0x%x\n"), dwError)); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // // // // Check if operation is correct. // // // // if (InstallWizardData.ClassInstallHeader.InstallFunction != diFunction) { // DebugTrace(TRACE_WARNING,(("ClassInstall: ERROR!! InstallHeader.InstallFunction is incorrect..\r\n"))); // // dwReturn = ERROR_DI_DO_DEFAULT; // goto ClassInstall_return; // } // // Free all allocated resources. // fCleanupContext = TRUE; pInstallerContext = (PINSTALLER_CONTEXT)InstallWizardData.PrivateData; InstallWizardData.PrivateData = NULL; dwReturn = NO_ERROR; goto ClassInstall_return; break; } // case DIF_DESTROYWIZARDDATA: case DIF_INSTALLDEVICE: { BOOL bSucceeded; BOOL bIsPnp; // // Sanity check of DevInfoSet and DevInfoData. // if( (NULL == pDevInfoData) || (!IS_VALID_HANDLE(hDevInfo)) ) { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! Wrong Infoset(0x%x) or instance(0x%x). Unable to continue.\r\n"),pDevInfoData,hDevInfo)); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // // Get device install parameters. // memset(&spDevInstallParams, 0, sizeof(spDevInstallParams)); spDevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if(!SetupDiGetDeviceInstallParams(hDevInfo, pDevInfoData, &spDevInstallParams)) { DebugTrace(TRACE_STATUS,(("ClassInstall: SetupDiGetDeviceInstallParams failed Err=0x%x.\r\n"), GetLastError())); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // // Check NULL driver installation. // if(spDevInstallParams.FlagsEx & DI_FLAGSEX_SETFAILEDINSTALL){ // // Installing NULL driver. Let default handler handle it. // dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // if(spDevInstallParams.FlagsEx & DI_FLAGSEX_SETFAILEDINSTALL) // // See if it's root-enumerated or not. // if(IsDeviceRootEnumerated(hDevInfo, pDevInfoData)){ bIsPnp = FALSE; } else { bIsPnp = TRUE; } // // Create CDevice class. // // // Start the WIA service. We start it here so that it will be running when we finish, so // it will receive the PnP device arrival notification. // Notice we don't change the startup-type here - this will be done later if the device // installation was successful. // StartWiaService(); CDevice cdThis(hDevInfo, pDevInfoData, bIsPnp); // // Let it create unique FriendlyName. // bSucceeded = cdThis.NameDefaultUniqueName(); if(bSucceeded){ // // Do pre-installation process. // bSucceeded = cdThis.PreInstall(); if(bSucceeded){ // // Do actual installation. // bSucceeded = cdThis.Install(); if(!bSucceeded){ dwReturn = ERROR_DI_DONT_INSTALL; DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! Installation failed in CDevice class.\r\n"))); } } else { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! PreInstall failed in CDevice class.\r\n"))); } } else { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! NameDefaultUniqueName failed in CDevice class.\r\n"))); dwReturn = ERROR_DI_DONT_INSTALL; } if(bSucceeded){ // // So far, installation is working fine. Do final touch. // bSucceeded = cdThis.PostInstall(TRUE); if(!bSucceeded){ dwReturn = ERROR_DI_DONT_INSTALL; DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! PostInstall failed in CDevice class.\r\n"))); } // // At this point, we consider the installation is succeeded. // dwReturn = NO_ERROR; // // Get device install parameters again. // memset(&spDevInstallParams, 0, sizeof(spDevInstallParams)); spDevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if(!SetupDiGetDeviceInstallParams(hDevInfo, pDevInfoData, &spDevInstallParams)) { dwReturn = GetLastError();; DebugTrace(TRACE_STATUS,(("ClassInstall: SetupDiGetDeviceInstallParams failed Err=0x%x.\r\n"), dwReturn)); goto ClassInstall_return; } // // We need to notify WIA service about new device addition. // if(NULL == spDevInstallParams.ClassInstallReserved){ spDevInstallParams.ClassInstallReserved = (ULONG_PTR)new CLEANUPITEM; if(NULL != spDevInstallParams.ClassInstallReserved){ memset((PVOID)(spDevInstallParams.ClassInstallReserved), 0, sizeof(CLEANUPITEM)); } else { // if(NULL == spDevInstallParams.ClassInstallReserved) DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! Unable to allocate CLEANUPITEM.\r\n"))); } } // if(NULL == spDevInstallParams.ClassInstallReserved) if(NULL != spDevInstallParams.ClassInstallReserved){ ((PCLEANUPITEM)spDevInstallParams.ClassInstallReserved)->bInstalled = TRUE; if(SetupDiSetDeviceInstallParams(hDevInfo, pDevInfoData, &spDevInstallParams)) { // // Installation succeeded. // DebugTrace(TRACE_STATUS,(("ClassInstall: WIA service will reenumerate device.\r\n"))); } else { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiSetDeviceInstallParams() failed. Err=0x%x.\r\n"), GetLastError())); } } else { // if(NULL != spDevInstallParams.ClassInstallReserved) DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! No CLEANUPITEM in context.\r\n"))); } // else(NULL != spDevInstallParams.ClassInstallReserved) } else { // // There's an error during installation. Revert. // cdThis.PostInstall(FALSE); dwReturn = ERROR_DI_DONT_INSTALL; DebugTrace(TRACE_ERROR,(("ClassInstall: Reverting installation...\r\n"))); } goto ClassInstall_return; break; } // case DIF_INSTALLDEVICE: case DIF_REMOVE: { SP_REMOVEDEVICE_PARAMS rdp; // // Check if operation is correct. // memset (&rdp, 0, sizeof(SP_REMOVEDEVICE_PARAMS)); rdp.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); if (!SetupDiGetClassInstallParams (hDevInfo, pDevInfoData, &rdp.ClassInstallHeader, sizeof(SP_REMOVEDEVICE_PARAMS), NULL)) { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiGetClassInstallParams failed Err=0x%x.\r\n"), GetLastError())); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // if (!SetupDiGetClassInstallParams () if (rdp.ClassInstallHeader.InstallFunction != DIF_REMOVE) { dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // // Create CDevice object. // CDevice cdThis(hDevInfo, pDevInfoData, TRUE); // // Remove the device. // dwReturn = cdThis.Remove(&rdp); // // Get device install parameters. // memset(&spDevInstallParams, 0, sizeof(spDevInstallParams)); spDevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if(!SetupDiGetDeviceInstallParams(hDevInfo, pDevInfoData, &spDevInstallParams)) { dwReturn = GetLastError();; DebugTrace(TRACE_STATUS,(("ClassInstall: SetupDiGetDeviceInstallParams failed Err=0x%x.\r\n"), dwReturn)); goto ClassInstall_return; } // // We need to notify WIA service about new device addition. // if(NULL == spDevInstallParams.ClassInstallReserved){ spDevInstallParams.ClassInstallReserved = (ULONG_PTR)new CLEANUPITEM; if(NULL != spDevInstallParams.ClassInstallReserved){ memset((PVOID)(spDevInstallParams.ClassInstallReserved), 0, sizeof(CLEANUPITEM)); } else { // if(NULL == spDevInstallParams.ClassInstallReserved) DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! Unable to allocate CLEANUPITEM.\r\n"))); } } // if(NULL == spDevInstallParams.ClassInstallReserved) if(NULL != spDevInstallParams.ClassInstallReserved){ ((PCLEANUPITEM)spDevInstallParams.ClassInstallReserved)->bRemoved = TRUE; if(SetupDiSetDeviceInstallParams(hDevInfo, pDevInfoData, &spDevInstallParams)) { // // Installation succeeded. // DebugTrace(TRACE_STATUS,(("ClassInstall: WIA service will reenumerate device.\r\n"))); } else { DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiSetDeviceInstallParams() failed. Err=0x%x.\r\n"), GetLastError())); } } else { // if(NULL != spDevInstallParams.ClassInstallReserved) DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! No CLEANUPITEM in context.\r\n"))); } // else(NULL != spDevInstallParams.ClassInstallReserved) goto ClassInstall_return; break; } // case DIF_REMOVE: case DIF_SELECTBESTCOMPATDRV: { SP_DRVINSTALL_PARAMS spDriverInstallParams; SP_DRVINFO_DATA spDriverInfoData; PSP_DRVINFO_DETAIL_DATA pspDriverInfoDetailData; DWORD dwLastError; DWORD dwSizeLocal; DWORD Idx; // // Get driver info. // memset(&spDriverInfoData, 0, sizeof(spDriverInfoData)); spDriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); for(Idx = 0; SetupDiEnumDriverInfo(hDevInfo, pDevInfoData, SPDIT_COMPATDRIVER, Idx, &spDriverInfoData); Idx++){ // // Get driver install params. // memset(&spDriverInstallParams, 0, sizeof(spDriverInstallParams)); spDriverInstallParams.cbSize = sizeof(SP_DRVINSTALL_PARAMS); if(!SetupDiGetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams)){ DebugTrace(TRACE_ERROR,("ClassInstall: ERROR!! SetupDiGetDriverInstallParams() failed LastError=0x%x.\r\n", GetLastError())); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // if(!SetupDiGetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams)) // // Get buffer size required for driver derail data. // dwSizeLocal = 0; SetupDiGetDriverInfoDetail(hDevInfo, pDevInfoData, &spDriverInfoData, NULL, 0, &dwSizeLocal); dwLastError = GetLastError(); if(ERROR_INSUFFICIENT_BUFFER != dwLastError){ DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! SetupDiGetDriverInfoDetail() doesn't return required size.Er=0x%x\r\n"),dwLastError)); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // if(ERROR_INSUFFICIENT_BUFFER != dwLastError) // // Allocate required size of buffer for driver detailed data. // pspDriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)new char[dwSizeLocal]; if(NULL == pspDriverInfoDetailData){ DebugTrace(TRACE_ERROR,(("ClassInstall: ERROR!! Unable to allocate driver detailed info buffer.\r\n"))); dwReturn = ERROR_DI_DO_DEFAULT; goto ClassInstall_return; } // if(NULL == pspDriverInfoDetailData) // // Initialize allocated buffer. // memset(pspDriverInfoDetailData, 0, dwSizeLocal); pspDriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); // // Get detailed data of selected device driver. // if(!SetupDiGetDriverInfoDetail(hDevInfo, pDevInfoData, &spDriverInfoData, pspDriverInfoDetailData, dwSizeLocal, NULL) ) { DebugTrace(TRACE_ERROR,("ClassInstall: ERROR!! SetupDiGetDriverInfoDetail() failed LastError=0x%x.\r\n", GetLastError())); delete[] pspDriverInfoDetailData; continue; } // if(NULL == pspDriverInfoDetailData) // // See if INF filename is valid. // if(NULL == pspDriverInfoDetailData->InfFileName){ DebugTrace(TRACE_ERROR,("ClassInstall: ERROR!! SetupDiGetDriverInfoDetail() returned invalid INF name.\r\n")); delete[] pspDriverInfoDetailData; continue; } // if(NULL == pspDriverInfoDetailData->InfFileName) // // If it's Inbox driver, set DNF_BASIC_DRIVER. // if( IsWindowsFile(pspDriverInfoDetailData->InfFileName) && IsProviderMs(pspDriverInfoDetailData->InfFileName ) ) { // // This is inbox INF. set DNF_BASIC_DRIVER. // spDriverInstallParams.Flags |= DNF_BASIC_DRIVER; SetupDiSetDriverInstallParams(hDevInfo, pDevInfoData, &spDriverInfoData, &spDriverInstallParams); } // if(IsWindowsFilw() && IsProviderMs()) // // Clean up. // delete[] pspDriverInfoDetailData; } // for(Idx = 0; SetupDiEnumDriverInfo(hDevInfo, pDevInfoData, SPDIT_COMPATDRIVER, Idx, &spDriverInfoData), Idx++) goto ClassInstall_return; break; } // case DIF_SELECTBESTCOMPATDRV: case DIF_DESTROYPRIVATEDATA: { PCLEANUPITEM pCleanupItem; // // Get device install parameters. // spDevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if(!SetupDiGetDeviceInstallParams(hDevInfo, pDevInfoData, &spDevInstallParams)) { dwReturn = GetLastError();; DebugTrace(TRACE_STATUS,(("ClassInstall: SetupDiGetDeviceInstallParams failed Err=0x%x.\r\n"), dwReturn)); goto ClassInstall_return; } // // See if any cleanup required. // pCleanupItem = (PCLEANUPITEM)spDevInstallParams.ClassInstallReserved; if(NULL != pCleanupItem){ // // A device is installed/uninstalled. // DebugTrace(TRACE_STATUS,("ClassInstall: Clean up item is created..\r\n")); if( (TRUE == pCleanupItem->bInstalled) || (TRUE == pCleanupItem->bRemoved) ) { DebugTrace(TRACE_STATUS,("ClassInstall: Let WIA service refresh device list.\r\n")); WiaDeviceEnum(); } delete pCleanupItem; pCleanupItem = NULL; } // if(NULL != pCleanupItem) } // case DIF_DESTROYPRIVATEDATA: // case DIF_ENABLECLASS: // case DIF_FIRSTTIMESETUP: default: break; } // switch(diFunction) ClassInstall_return: if(fCleanupContext){ if(NULL != pInstallerContext){ if(NULL != pInstallerContext->pFirstPage){ delete (CFirstPage *)(pInstallerContext->pFirstPage); } if(NULL != pInstallerContext->pPrevSelectPage){ delete (CPrevSelectPage *)(pInstallerContext->pPrevSelectPage); } if(NULL != pInstallerContext->pPortSelectPage){ delete (CPortSelectPage *)(pInstallerContext->pPortSelectPage); } if(NULL != pInstallerContext->pNameDevicePage){ delete (CNameDevicePage *)(pInstallerContext->pNameDevicePage); } if(NULL != pInstallerContext->pFinalPage){ delete (CInstallPage *)(pInstallerContext->pFinalPage); } // // Removed this delete call for the pDevice pointer. The Wizard pages // delete this memory when a user presses "cancel" or closes the Wizard // dialog. // // COOPP - 01-18-2001. Quick fix to BUG #284981 Heap Corruption // // Note for future: As discussed with KeisukeT, a better design would be // adding a shared pInstallerContext pointer in the BASE class of the // Wizard pages. This would allow this routine to remain enabled as a // "catch-all" case. (Catching the case if the Wizard dialogs did not free // the memory first) // // if(NULL != pInstallerContext->pDevice){ // delete pInstallerContext->pDevice; //} // delete pInstallerContext; } // if(NULL != pInstallerContext) } DebugTrace(TRACE_PROC_LEAVE,(("ClassInstall: Leaving... Ret=0x%x.\r\n"), dwReturn)); return dwReturn; } // ClassInstall() extern "C" DWORD APIENTRY CoinstallerEntry( IN DI_FUNCTION diFunction, IN HDEVINFO hDevInfo, IN PSP_DEVINFO_DATA pDevInfoData, IN OUT PCOINSTALLER_CONTEXT_DATA pCoinstallerContext ) /*++ Routine Description: CoinstallerEntry Entrypoint of WIA class coinstaller. Arguments: IN DI_FUNCTION diFunction, Function to perform. IN HDEVINFO hDevInfo, Handle to Device Information. IN PSP_DEVINFO_DATA pDevInfoData, Pointer to Device Data. IN OUT PCOINSTALLER_CONTEXT_DATA pCoinstallerContext Context data for coinstaller. Return Value: NO_ERROR - Operation succeeded. ERROR_DI_POSTPROCESSING_REQUIRED - Need post processing after installation has done. Side effects: None --*/ { DWORD dwReturn; DebugTrace(TRACE_PROC_ENTER,(("CoinstallerEntry: Enter... \r\n"))); // // Initialize local. // dwReturn = NO_ERROR; // // Do Pre/Post process. // if(pCoinstallerContext->PostProcessing){ // // Do post-process. // dwReturn = CoinstallerPostProcess(diFunction, hDevInfo, pDevInfoData, pCoinstallerContext); } else { // // Do pre-process. // dwReturn = CoinstallerPreProcess(diFunction, hDevInfo, pDevInfoData, pCoinstallerContext); } // if(pCoinstallerContext->PostProcessing) // CoinstallerEntry_return: DebugTrace(TRACE_PROC_LEAVE,(("CoinstallerEntry: Leaving... Ret=0x%x.\r\n"), dwReturn)); return dwReturn; } // CoinstallerEntry() DWORD APIENTRY CoinstallerPreProcess( IN DI_FUNCTION diFunction, IN HDEVINFO hDevInfo, IN PSP_DEVINFO_DATA pDevInfoData, IN OUT PCOINSTALLER_CONTEXT_DATA pCoinstallerContext ) { DWORD dwReturn; DebugTrace(TRACE_PROC_ENTER,(("CoinstallerPreProcess: Enter... \r\n"))); DebugTrace(TRACE_STATUS,(("CoinstallerPreProcess: Processing %ws message.\r\n"), DifDebug[diFunction].DifString)); // // Initialize local. // dwReturn = NO_ERROR; // // Dispatch requests. // switch(diFunction){ case DIF_INSTALLDEVICE: { BOOL bSucceeded; // // Initialize private data. // if(NULL != pCoinstallerContext->PrivateData){ DebugTrace(TRACE_WARNING,(("CoinstallerPreProcess: WARNING!! Private has value other than NULL.\r\n"))); } pCoinstallerContext->PrivateData = NULL; // // Create CDevice class. // CDevice *pDevice = new CDevice(hDevInfo, pDevInfoData, TRUE); if(NULL == pDevice){ DebugTrace(TRACE_ERROR,(("CoinstallerPreProcess: ERROR!! Insufficient memory.\r\n"))); dwReturn = NO_ERROR; goto CoinstallerPreProcess_return; } // if(NULL == pDevice) // // Let it create unique FriendlyName. // bSucceeded = pDevice->NameDefaultUniqueName(); if(bSucceeded){ // // Do pre-installation process. // bSucceeded = pDevice->PreInstall(); if(!bSucceeded){ DebugTrace(TRACE_ERROR,(("CoinstallerPreProcess: ERROR!! Pre-Installation failed in CDevice class.\r\n"))); delete pDevice; dwReturn = NO_ERROR; goto CoinstallerPreProcess_return; } } else { DebugTrace(TRACE_ERROR,(("CoinstallerPreProcess: ERROR!! NameDefaultUniqueName failed in CDevice class.\r\n"))); delete pDevice; dwReturn = NO_ERROR; goto CoinstallerPreProcess_return; } // // Post-installation have to free allocated object. // pCoinstallerContext->PrivateData = (PVOID)pDevice; dwReturn = ERROR_DI_POSTPROCESSING_REQUIRED; goto CoinstallerPreProcess_return; break; } // case DIF_INSTALLDEVICE: default: break; } // switch(diFunction) CoinstallerPreProcess_return: DebugTrace(TRACE_PROC_LEAVE,(("CoinstallerPreProcess: Leaving... Ret=0x%x.\r\n"), dwReturn)); return dwReturn; } // CoinstallerPreProcess() DWORD APIENTRY CoinstallerPostProcess( IN DI_FUNCTION diFunction, IN HDEVINFO hDevInfo, IN PSP_DEVINFO_DATA pDevInfoData, IN OUT PCOINSTALLER_CONTEXT_DATA pCoinstallerContext ) { DWORD dwReturn; DebugTrace(TRACE_PROC_ENTER,(("CoinstallerPostProcess: Enter... \r\n"))); DebugTrace(TRACE_STATUS,(("CoinstallerPostProcess: Processing %ws message.\r\n"), DifDebug[diFunction].DifString)); // // Initialize local. // dwReturn = NO_ERROR; // // Dispatch requests. // switch(diFunction){ case DIF_INSTALLDEVICE: { BOOL bSucceeded; CDevice *pDevice; if(NO_ERROR == pCoinstallerContext->InstallResult){ bSucceeded = TRUE; } else { bSucceeded = FALSE; } // // Get pointer to the CDevice class created in pre-process. // pDevice = (CDevice *)pCoinstallerContext->PrivateData; // // Do post-installation process. // pDevice->PostInstall(bSucceeded); // // Delete CDevice object. // delete pDevice; pCoinstallerContext->PrivateData = NULL; dwReturn = NO_ERROR; goto CoinstallerPostProcess_return; break; } // case DIF_INSTALLDEVICE: default: break; } // switch(diFunction) CoinstallerPostProcess_return: DebugTrace(TRACE_PROC_LEAVE,(("CoinstallerPostProcess: Leaving... Ret=0x%x.\r\n"), dwReturn)); return dwReturn; } // CoinstallerPostProcess(