/*++ Copyright (c) 1997 Microsoft Corporation All rights reserved. Module Name: FileQ.c Abstract: File queue routines for upgrade Author: Muhunthan Sivapragasam (MuhuntS) 22-Jan-1996 Revision History: --*/ #include "precomp.h" // // If the source disk is missing we will retry it 4 times waiting for // 3 seconds between every try // #define MISSING_MEDIA_RETRY_COUNT 4 #define MISSING_MEDIA_RETRY_INTERVAL 3000 typedef struct _FILE_QUEUE_CONTEXT { PVOID QueueContext; } FILE_QUEUE_CONTEXT, *PFILE_QUEUE_CONTEXT; UINT MyQueueCallback( IN PVOID QueueContext, IN UINT Notification, IN UINT_PTR Param1, IN UINT_PTR Param2 ) /*++ Routine Description: File queue callback routine for the upgrade. We will not prompt the user for missing file. But we will retry few times before failing Arguments: QueueContext : Points to FILE_QUEUE_CONTEXT Notification : The event which is being notified Param1 : Depends on the notification Param2 : Depends on the notification Return Value: None --*/ { PFILE_QUEUE_CONTEXT pFileQContext=(PFILE_QUEUE_CONTEXT)QueueContext; PSOURCE_MEDIA_W pSource; PFILEPATHS_W pFilePaths; switch (Notification) { case SPFILENOTIFY_COPYERROR: // // We know atleast pjlmon will be missing since it is copied // during textmode setup // pFilePaths = (PFILEPATHS_W) Param1; DebugMsg("Error %d copying %ws to %ws.", pFilePaths->Win32Error, pFilePaths->Source, pFilePaths->Target); return FILEOP_SKIP; case SPFILENOTIFY_NEEDMEDIA: pSource = (PSOURCE_MEDIA_W)Param1; // // Setup is going to add \i386 to the end. Tell it to look // right in the directory we give. Particularly needed for the // upgrade over the network case // if ( wcscmp(pSource->SourcePath, UpgradeData.pszSourceW) ) { wcscpy((LPWSTR)Param2, UpgradeData.pszSourceW); return FILEOP_NEWPATH; } DebugMsg("Error copying %ws from %ws.", pSource->SourceFile, pSource->SourcePath); return FILEOP_SKIP; } return SetupDefaultQueueCallbackW(pFileQContext->QueueContext, Notification, Param1, Param2); } BOOL InitFileCopyOnNT( IN HDEVINFO hDevInfo ) /*++ Routine Description: On NT we will call ntprint.dll via SetupDiCallClassInstaller api with the DI_NOVCP flag so that all the necessary printer driver files are queued and copied at the end. This sets the necessary queue etc before calling the class installer Arguments: hDevInfo : Handle to printer device info list. Return Value: TRUE on success. FALSE on error --*/ { BOOL bRet = FALSE; HSPFILEQ CopyQueue; PFILE_QUEUE_CONTEXT pFileQContext; SP_DEVINSTALL_PARAMS_W DevInstallParams; // // Call the current device installation parameters // DevInstallParams.cbSize = sizeof(DevInstallParams); if ( !SetupDiGetDeviceInstallParamsW(hDevInfo, NULL, &DevInstallParams) ) return FALSE; // // Set the parameters so that ntprint will just queue files and not commit // the file copy operations // if ( !(pFileQContext = AllocMem(sizeof(FILE_QUEUE_CONTEXT))) ) goto Cleanup; pFileQContext->QueueContext = SetupInitDefaultQueueCallbackEx( INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0, NULL); DevInstallParams.FileQueue = SetupOpenFileQueue(); DevInstallParams.InstallMsgHandlerContext = pFileQContext; DevInstallParams.InstallMsgHandler = MyQueueCallback; DevInstallParams.Flags |= DI_NOVCP; DevInstallParams.hwndParent = INVALID_HANDLE_VALUE; // // The files should be from the source dir // wcscpy(DevInstallParams.DriverPath, UpgradeData.pszSourceW); if ( DevInstallParams.FileQueue == INVALID_HANDLE_VALUE || pFileQContext->QueueContext == NULL || !SetupDiSetDeviceInstallParamsW(hDevInfo, NULL, &DevInstallParams) ) { if ( DevInstallParams.FileQueue != INVALID_HANDLE_VALUE ) SetupCloseFileQueue(DevInstallParams.FileQueue); if ( pFileQContext->QueueContext ) SetupTermDefaultQueueCallback(pFileQContext->QueueContext); } else { bRet = TRUE; } Cleanup: if ( !bRet ) FreeMem(pFileQContext); return bRet; } BOOL CommitFileQueueToCopyFiles( IN HDEVINFO hDevInfo ) /*++ Routine Description: After calling ntprint for each printer driver to queue up the files this routine is called to commit the file queue and do the actual file copy operations Arguments: hDevInfo : Handle to printer device info list. Return Value: TRUE on success. FALSE on error --*/ { BOOL bRet = FALSE; SP_DEVINSTALL_PARAMS_W DevInstallParams; PFILE_QUEUE_CONTEXT pFileQContext; DevInstallParams.cbSize = sizeof(DevInstallParams); if ( !SetupDiGetDeviceInstallParamsW(hDevInfo, NULL, &DevInstallParams) ) return FALSE; pFileQContext = DevInstallParams.InstallMsgHandlerContext; bRet = SetupCommitFileQueueW(DevInstallParams.hwndParent, DevInstallParams.FileQueue, DevInstallParams.InstallMsgHandler, pFileQContext); SetupCloseFileQueue(DevInstallParams.FileQueue); SetupTermDefaultQueueCallback(pFileQContext->QueueContext); FreeMem(pFileQContext); return bRet; }