/* * w95inf16.c * * Copyright (c) 1995 Microsoft Corporation * * 16bit portion of the INFINST program. This DLL contains all the * stuff to drive GenInstall (a 16 bit DLL) * */ #include "w95inf16.h" #include #include #include #include //#include "..\core\infinst.h" #define SHORTSTRING 256 /* * GLOBALS */ HINSTANCE hInstance; CHAR szDll16[] = "W95INF16.DLL"; CHAR szDll32[] = "W95INF32.DLL"; static char g_szRunOnceExe[] = {"runonce"}; /* * S T R I N G S */ char *szSectVersion = "version"; char *szKeySignature = "signature"; char *szValSignature = "$CHICAGO$"; /* * Declarations */ BOOL FAR PASCAL w95thk_ThunkConnect16(LPSTR pszDLL16, LPSTR pszDll32, WORD hInst, DWORD dwReason); WORD WINAPI CtlSetLddPath16(UINT uiLDID, LPSTR lpszPath); WORD WINAPI GenInstall16(LPSTR lpszInf, LPSTR lpszSection, LPSTR lpszDirectory); BOOL WINAPI GenFormStrWithoutPlaceHolders16( LPSTR lpszDst, LPSTR lpszSrc, LPSTR lpszInfFilename ); /* * Library Initialization * * Call by LibInit */ BOOL FAR PASCAL LibMain(HINSTANCE hInst, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine) { // Keep Copy of Instance hInstance = hInst; DEBUGMSG("W95INF16.DLL - LibMain()"); return( TRUE ); } /* * Thunk Entry Point */ BOOL FAR PASCAL DllEntryPoint(DWORD dwReason, WORD hInst, WORD wDS, WORD wHeapSize, DWORD dwReserved1, WORD wReserved2) { DEBUGMSG("W95INF16.DLL - DllEntryPoint()"); if (! (w95thk_ThunkConnect16(szDll16, szDll32, hInst, dwReason))) { DEBUGMSG("W95INF16.DLL - w95thk_ThunkConnect16() Failed"); return( FALSE ); } return( TRUE ); } /* * O P E N _ V A L I D A T E _ I N F * * Routine: OpenValidateInf * * Purpose: Open INF and validate internals * * Notes: Stolen from setupx * * */ RETERR OpenValidateInf(LPCSTR lpszInfFile, HINF FAR * phInf ) { RETERR err; HINF hInfFile; char szTmpBuf[SHORTSTRING]; ASSERT(lpszInfFile); ASSERT(phInf); DEBUGMSG("OpenValidateInf([%s])", lpszInfFile ); /* * Open the INF */ err = IpOpen( lpszInfFile, &hInfFile ); if (err != OK) { DEBUGMSG("IpOpen(%s) returned %u",(LPSTR) lpszInfFile,err); return err; } /* * Get INF signature */ err = IpGetProfileString( hInfFile, szSectVersion, szKeySignature, szTmpBuf, sizeof(szTmpBuf)); if (err != OK) { DEBUGMSG("IpGetProfileString returned %u",err); return err; } /* * Check INF signature */ if ( lstrcmpi(szTmpBuf,szValSignature) != 0 ) { DEBUGMSG("signature error in %s",(LPSTR) lpszInfFile); IpClose(hInfFile); return ERR_IP_INVALID_INFFILE; } /* * Set Out Parameter phInf */ *phInf = hInfFile; DEBUGMSG("OpenValidateInf([%s]) Complete", lpszInfFile ); return OK; } /* * I N S T A L L F I L E S F R O M I N F * * Routine: InstallFilesFromINF() * * Purpose: Call GenInstall to GenInstall a section of an INF * using specified flags * */ RETERR InstallFilesFromINF(HWND hwndParent, LPCSTR lpszINF, LPCSTR lpszSection, WORD wFlags) { RETERR err = OK; HINF hInf; ASSERT(lpszINF); ASSERT(lpszSection); DEBUGMSG("InstallFilesFromINF([%s], [%s], [%x])", lpszINF, lpszSection, wFlags ); /* * Open INF */ err = OpenValidateInf(lpszINF, &hInf); if (err != OK) { DEBUGMSG("OpenValidateInf(%s) returned %u",lpszINF, err); return err; } ASSERT(hInf); /* * GenInstall Go Do your thing */ err = GenInstall(hInf,lpszSection, wFlags ); /* * Close INF */ IpClose(hInf); return err; } /* * I N S T A L L S T O P * * Routine: InstallStop() * * Purpose: Perform install cleanup such as group converter * (program group stuff) and renaming * * CODE STOLEN FROM SETUPX.DLL * * */ RETERR InstallStop( BYTE FAR *fNeedBoot ) { char szSubkey[MAX_PATH]; char szGrpConv[MAX_PATH] = {"grpconv -o"}; HKEY hkey; RETERR reRet = OK; if ( *fNeedBoot ) { /* * Make the RunOnce do GrpConvert */ lstrcpy(szSubkey, REGSTR_PATH_RUNONCE); if (RegOpenKey(HKEY_LOCAL_MACHINE, szSubkey, &hkey) == ERROR_SUCCESS) { RegSetValueEx(hkey, "GrpConv", 0, REG_SZ, (LPBYTE)szGrpConv, lstrlen(szGrpConv) ); RegCloseKey(hkey); } } else { WinExec( szGrpConv, SW_SHOWNORMAL ); } return( reRet); } WORD WINAPI GenInstall16(LPSTR lpszInf, LPSTR lpszSection, LPSTR lpszDirectory) { VCPUIINFO VcpUiInfo; RETERR err; HWND hwndParent = 0; BYTE fNeedBoot = 1; char szPrevSourcePath[MAX_PATH+1] = ""; BOOL fNeedToRestorePrevSourcePath = FALSE; /* * Save source path for restoration * * If we get a non-zero length string for the old * source path then we will restore it when finished */ err = CtlGetLddPath(LDID_SRCPATH,szPrevSourcePath); if ((err == OK) && (lstrlen(szPrevSourcePath))) { DEBUGMSG("Saved Sourcpath [%s]", szPrevSourcePath ); fNeedToRestorePrevSourcePath = TRUE; } /* * Set Source Path for GenInstall */ DEBUGMSG("Setting Source path to [%s]", lpszDirectory ); CtlSetLddPath(LDID_SRCPATH, lpszDirectory ); /* * Set Up GenInstall UI */ _fmemset(&VcpUiInfo,0,sizeof(VcpUiInfo)); VcpUiInfo.flags = VCPUI_CREATEPROGRESS; VcpUiInfo.hwndParent = hwndParent; // Our parent VcpUiInfo.hwndProgress = NULL; // No progress DLG VcpUiInfo.idPGauge = 0; VcpUiInfo.lpfnStatCallback = NULL; // No stat callback VcpUiInfo.lUserData = 0L; // No client data. /* * Open VCP to batch copy requests */ DEBUGMSG("Setting up VCP"); err = VcpOpen((VIFPROC) vcpUICallbackProc, (LPARAM)(LPVCPUIINFO)&VcpUiInfo); if (err != OK) { DEBUGMSG("VcpOpen returned %u",err); return err; } DEBUGMSG("VCP Setup Complete"); /* * Call GenInstall to Install Files */ DEBUGMSG("Installing Files using InstallFilesFromINF()"); err = InstallFilesFromINF(hwndParent, lpszInf, lpszSection, GENINSTALL_DO_FILES); DEBUGMSG("InstallFilesFromINF() Returned %d", err); if (err == OK) { err = VcpClose(VCPFL_COPY | VCPFL_DELETE | VCPFL_RENAME, NULL); if (err != OK) { DEBUGMSG("VcpClose returned %u", err); return(err); } } else { err = VcpClose(VCPFL_ABANDON, NULL); if (err != OK) { DEBUGMSG("VcpClose returned %u", err); return(err); } } /* * Now have GenInstall do rest of install */ DEBUGMSG("Installing everything else using InstallFilesFromINF()"); err = InstallFilesFromINF(hwndParent, lpszInf, lpszSection, GENINSTALL_DO_ALL ^ GENINSTALL_DO_FILES); if (err != OK) { DEBUGMSG("InstallFilesFromINF() Non Files returned %d", err ); return(err); } /* * Kick off run-once stuff to run grpconverter and rename * directories */ err = InstallStop(&fNeedBoot); if (err != OK) { DEBUGMSG("InstallStop() (runonce, group converter) failed: %d", err ); return(err); } /* * Restore Source LDID */ if (fNeedToRestorePrevSourcePath) { DEBUGMSG("Restoring source path to: %s",(LPSTR) szPrevSourcePath); err=CtlSetLddPath(LDID_SRCPATH,szPrevSourcePath); ASSERT(err == OK); } return(err); } VOID WINAPI GetSETUPXErrorText16(DWORD dwError,LPSTR pszErrorDesc, DWORD cbErrorDesc) { WORD wID; // ID of string resource in SETUPX with error description // get string ID with this error from setupx wID = suErrorToIds((WORD) dwError,E2I_SETUPX); if (wID) { CHAR szSetupxFilename[13]; // big enough for 8.3 HMODULE hInstSetupx; // get setupx filename out of resource LoadString(hInstance,IDS_SETUPX_FILENAME,szSetupxFilename, sizeof(szSetupxFilename)); // get the module handle for setupx hInstSetupx = GetModuleHandle(szSetupxFilename); ASSERT(hInstSetupx); // pretty weird if this fails if (hInstSetupx) { // load the string from setupx if (LoadString(hInstSetupx,wID,pszErrorDesc,(int) cbErrorDesc)) { return; // got it } } } // we get here if couldn't map error to string ID, couldn't get // SETUPX module handle, or couldn't find string ID in setupx. 1st // case is relatively likely, other cases are pretty unlikely. { CHAR szFmt[SMALL_BUF_LEN+1]; // load generic text and insert error number LoadString(hInstance,IDS_GENERIC_SETUPX_ERR,szFmt,sizeof(szFmt)); wsprintf(pszErrorDesc,szFmt,wID); } } WORD WINAPI CtlSetLddPath16(UINT uiLDID, LPSTR lpszPath) { return(CtlSetLddPath(uiLDID, lpszPath)); } BOOL WINAPI GenFormStrWithoutPlaceHolders16( LPSTR lpszDst, LPSTR lpszSrc, LPSTR lpszInfFilename ) { RETERR err = OK; HINF hInf; err = OpenValidateInf(lpszInfFilename, &hInf); if (err != OK) { DEBUGMSG("OpenValidateInf(%s) returned %u",lpszInfFilename, err); return FALSE; } GenFormStrWithoutPlaceHolders( lpszDst, (LPCSTR) lpszSrc, hInf ); IpClose( hInf ); return TRUE; }