#include "precomp.h" #pragma hdrstop /**************************************************************************/ /***** Shell Component - Init routines ************************************/ /**************************************************************************/ //#ifdef SYMTAB_STATS //extern void SymTabStatDump(void); //#endif extern SZ SzGetNextCmdLineString(PSZ); extern BOOL fFullScreen; extern PSTR LOCAL_SOURCE_DIRECTORY; extern VOID Usage(HANDLE); // // Helper macro to make object attribute initialization a little cleaner. // #define INIT_OBJA(Obja,UnicodeString,UnicodeText) \ \ RtlInitUnicodeString((UnicodeString),(UnicodeText)); \ \ InitializeObjectAttributes( \ (Obja), \ (UnicodeString), \ OBJ_CASE_INSENSITIVE, \ NULL, \ NULL \ ) SZ szShlScriptSection = NULL; CHP szArcPrefix[] = "\\ArcName\\"; #define ArcPrefixLen ((sizeof(szArcPrefix) / sizeof(CHP)) - 1) CHP szNtPrefix[] = "\\Device\\"; #define NtPrefixLen ((sizeof(szNtPrefix) / sizeof(CHP)) - 1) // // Define a work area for path manipulation (note that we make // it large enough for Unicode as well, so it can do dual duty.) // CHP TemporaryPathBuffer[cchlFullPathMax * sizeof(WCHAR)]; // // Buffer used in querying object directories // UCHAR ObjBuffer[1024]; SZ szDosType = "DOS"; SZ szUncType = "UNC"; typedef struct _INITSYMHANDLE *PINITSYMHANDLE; typedef struct _INITSYMHANDLE { SZ szName; HANDLE Handle; } INITSYMHANDLE; typedef struct _INITSYMNUMBER *PINITSYMNUMBER; typedef struct _INITSYMNUMBER { SZ szName; DWORD dwNumber; } INITSYMNUMBER; INITSYMHANDLE InitSymHandle[] = { // // Predefined registry handles // { "REG_H_LOCAL", HKEY_LOCAL_MACHINE }, { "REG_H_CLASSES", HKEY_CLASSES_ROOT }, { "REG_H_USERS", HKEY_USERS }, { "REG_H_CUSER", HKEY_CURRENT_USER }, // { NULL, 0 } }; INITSYMNUMBER InitSymNumber[] = { // // Registry key creation options // { "REG_OPT_VOLATILE", REG_OPTION_VOLATILE }, { "REG_OPT_NONVOL", REG_OPTION_NON_VOLATILE }, // // Registry value types // { "REG_VT_NONE", REG_NONE }, { "REG_VT_BIN", REG_BINARY }, { "REG_VT_SZ", REG_SZ }, { "REG_VT_EXPAND_SZ", REG_EXPAND_SZ }, { "REG_VT_MULTI_SZ", REG_MULTI_SZ }, { "REG_VT_DWORD", REG_DWORD }, { "REG_VT_RESOURCE_LIST", REG_RESOURCE_LIST }, { "REG_VT_FULL_RESOURCE_DESCRIPTOR", REG_FULL_RESOURCE_DESCRIPTOR }, { "REG_VT_RESOURCE_REQUIREMENTS_LIST", REG_RESOURCE_REQUIREMENTS_LIST }, // // Registry access mask bits // { "REG_KEY_QUERY_VALUE", KEY_QUERY_VALUE }, { "REG_KEY_SET_VALUE", KEY_SET_VALUE }, { "REG_KEY_CREATE_SUB_KEY", KEY_CREATE_SUB_KEY }, { "REG_KEY_ENUMERATE_SUB_KEYS", KEY_ENUMERATE_SUB_KEYS }, { "REG_KEY_NOTIFY", KEY_NOTIFY }, { "REG_KEY_READ", KEY_READ }, { "REG_KEY_WRITE", KEY_WRITE }, { "REG_KEY_READWRITE", KEY_READ | KEY_WRITE }, { "REG_KEY_EXECUTE", KEY_EXECUTE }, { "REG_KEY_ALL_ACCESS", KEY_ALL_ACCESS }, // // Registry errors BugBug** should replace with values from winerror.h // { "REG_ERROR_SUCCESS", 0L }, // // Service Types (Bit Mask) // { "SERVICE_KERNEL_DRIVER", SERVICE_KERNEL_DRIVER }, { "SERVICE_FILE_SYSTEM_DRIVER", SERVICE_FILE_SYSTEM_DRIVER }, { "SERVICE_ADAPTER", SERVICE_ADAPTER }, { "SERVICE_WIN32_OWN_PROCESS", SERVICE_WIN32_OWN_PROCESS }, { "SERVICE_WIN32_SHARE_PROCESS", SERVICE_WIN32_SHARE_PROCESS }, // // Start Type // { "SERVICE_BOOT_START", SERVICE_BOOT_START }, { "SERVICE_SYSTEM_START", SERVICE_SYSTEM_START }, { "SERVICE_AUTO_START", SERVICE_AUTO_START }, { "SERVICE_DEMAND_START", SERVICE_DEMAND_START }, { "SERVICE_DISABLED", SERVICE_DISABLED }, // // Error control type // { "SERVICE_ERROR_IGNORE", SERVICE_ERROR_IGNORE }, { "SERVICE_ERROR_NORMAL", SERVICE_ERROR_NORMAL }, { "SERVICE_ERROR_SEVERE", SERVICE_ERROR_SEVERE }, { "SERVICE_ERROR_CRITICAL", SERVICE_ERROR_CRITICAL }, // // ShellCode values // { "SHELL_CODE_OK", SHELL_CODE_OK }, { "SHELL_CODE_NO_SUCH_INF", SHELL_CODE_NO_SUCH_INF }, { "SHELL_CODE_NO_SUCH_SECTION", SHELL_CODE_NO_SUCH_SECTION }, { "SHELL_CODE_ERROR", SHELL_CODE_ERROR }, // // Exit_Code values // { "SETUP_ERROR_SUCCESS", SETUP_ERROR_SUCCESS }, { "SETUP_ERROR_USERCANCEL", SETUP_ERROR_USERCANCEL }, { "SETUP_ERROR_GENERAL", SETUP_ERROR_GENERAL }, // { NULL, 0 } }; BOOL fCheckInfValidity = fFalse; BOOL FMakeWindows(HANDLE hInstance); BOOL FProcessForDriveType(SZ, SZ, SZ, SZ); BOOL FProcessInfSrcPath( SZ szInf, SZ szCWD, SZ szProcessedDir ); HWND FindProperParent ( void ) ; HANDLE hVerDLL = NULL; #define FExistFile(sz) ((BOOL)(PfhOpenFile(sz, ofmExistRead) != (PFH)NULL)) // // Symbols that are defined in the command line are kept in a list of // VALUE_BLOCKs until the symbol table is created, point at which they // are added to the symbol table and the VALUE_BLOCK list is destroyed. // typedef struct _VALUE_BLOCK *PVALUE_BLOCK; typedef struct _VALUE_BLOCK { PVALUE_BLOCK pNext; // Next in chain SZ szSymbol; // Symbol SZ szValue; // Value } VALUE_BLOCK; PVALUE_BLOCK pCmdLineSymbols = NULL; /* ** Purpose: ** Generates a Usage message. ** Arguments: ** hInst: For retrieving string resources. ** Returns: ** none ***************************************************************************/ VOID Usage(hInst) HANDLE hInst; { CHP rgch[1024]; CCHP cchpBuf = 1024; CCHP cchp, cchpCurrent = 0; UINT wID[] = { IDS_USAGE_MSG1, IDS_USAGE_MSG2, IDS_USAGE_USAGE, IDS_USAGE_F, IDS_USAGE_I, IDS_USAGE_C, IDS_USAGE_S, IDS_USAGE_T, IDS_USAGE_V } ; INT i, j; EvalAssert(LoadString(hInst, IDS_USAGE_TITLE, rgchBufTmpShort, cchpBufTmpShortMax)); for( i = 0, j = sizeof( wID ) / sizeof( UINT ); i < j; i++ ) { Assert(cchpBuf > 0); EvalAssert((cchp = LoadString(hInst, wID[i], rgch + cchpCurrent, cchpBuf)) != 0); cchpCurrent = cchpCurrent + cchp; cchpBuf = cchpBuf - cchp; } while (!MessageBox(hWndShell, rgch, rgchBufTmpShort, MB_OK)) { if (!FHandleOOM(hWndShell)) { break; } } } /* ** Purpose: ** Generates a message indicating that maintenance-mode setup ** functionality is now accessible via Control Panel applets. ** Arguments: ** hInst: For retrieving string resources. ** Returns: ** none ***************************************************************************/ VOID MaintSetupObsoleteMsg(hInst) HANDLE hInst; { CHP rgch[1024]; CCHP cchpBuf = 1024; CCHP cchp, cchpCurrent = 0; UINT wID[] = { IDS_MAINTOBS_MSG1 }; INT i, j; EvalAssert(LoadString(hInst, IDS_WINDOWS_NT_SETUP, rgchBufTmpShort, cchpBufTmpShortMax)); for( i = 0, j = sizeof( wID ) / sizeof( UINT ); i < j; i++ ) { Assert(cchpBuf > 0); EvalAssert((cchp = LoadString(hInst, wID[i], rgch + cchpCurrent, cchpBuf)) != 0); cchpCurrent = cchpCurrent + cchp; cchpBuf = cchpBuf - cchp; } while (!MessageBox(hWndShell, rgch, rgchBufTmpShort, MB_ICONINFORMATION | MB_OK)) { if (!FHandleOOM(hWndShell)) { break; } } } /* ** Purpose: ** Gets the next string on the Command Line. ** Arguments: ** pszCmdLine: Command Line argument as received in WinMain(). ** Returns: ** SZ ***************************************************************************/ SZ SzGetNextCmdLineString(pszCmdLine) PSZ pszCmdLine; { SZ szCur = *pszCmdLine; SZ szAnswer; while (FWhiteSpaceChp(*szCur)) szCur = SzNextChar(szCur); if (*szCur == '"') { SZ szWriteCur; CB cbWrite = (CB)0; while ((szWriteCur = szAnswer = (SZ)SAlloc((CB)4096)) == (SZ)NULL) if (!FHandleOOM(hWndShell)) return((SZ)NULL); szCur = SzNextChar(szCur); while (fTrue) { SZ szNext; if (*szCur == '"' && *(szCur = SzNextChar(szCur)) != '"') break; if (*szCur == '\0') { SFree(szAnswer); return((SZ)NULL); } szNext = SzNextChar(szCur); while (szCur < szNext) { if (++cbWrite >= 4096) { SFree(szAnswer); return((SZ)NULL); } *szWriteCur++ = *szCur++; } } *szWriteCur = '\0'; Assert(strlen(szAnswer) == cbWrite); Assert(cbWrite + 1 <= (CB)4096); if (cbWrite + 1 < (CB)4096) szAnswer = SRealloc((PB)szAnswer, cbWrite + 1); Assert(szAnswer != (SZ)NULL); } else if (*(*pszCmdLine = szCur) == '\0') return((SZ)NULL); else { CHP chpSav; while (*szCur != '\0' && !FWhiteSpaceChp(*szCur)) szCur = SzNextChar(szCur); chpSav = *szCur; *szCur = '\0'; while ((szAnswer = SzDupl(*pszCmdLine)) == (SZ)NULL) if (!FHandleOOM(hWndShell)) break; *szCur = chpSav; } while (*szCur != '\0' && FWhiteSpaceChp(*szCur)) szCur = SzNextChar(szCur); *pszCmdLine = szCur; return(szAnswer); } /* ** Purpose: ** Parses the Command Line received in WinMain(). ** Arguments: ** ?? ** Returns: ** BOOL ***************************************************************************/ INT ParseCmdLine( HANDLE hInst, SZ szCmdLine, PSZ pszInfSrcPath, PSZ pszDestDir, PSZ pszSrcDir, PSZ pszCWD, INT * pwModeSetup ) { BOOL fSetupInfSpecified = fFalse; BOOL fScriptSectionSpecified = fFalse; BOOL fSourcePathSpecified = fFalse; SZ szBase; INT cchp; SZ szCur; SZ szLastBackSlash = NULL; CHAR szInfPath[MAX_PATH]; BOOL bStatus; *pwModeSetup = wModeSetupNormal; while(FWhiteSpaceChp(*szCmdLine)) { szCmdLine = SzNextChar(szCmdLine); } while(*szCmdLine) { if (*szCmdLine == '-' || *szCmdLine == '/') { szCmdLine++; switch (*szCmdLine++){ case 'c': case 'C': if(fScriptSectionSpecified || (szShlScriptSection = SzGetNextCmdLineString(&szCmdLine)) == NULL) { Usage(hInst); return(CMDLINE_ERROR); } if(*(szShlScriptSection) == '\0' || *(szShlScriptSection) == ']' || *(szShlScriptSection) == '[') { LoadString( hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax ); LoadString( hInst, IDS_BAD_SHL_SCRIPT_SECT, rgchBufTmpLong, cchpBufTmpLongMax ); MessageBox( hWndShell, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND ); Usage(hInst); return(CMDLINE_ERROR); } fScriptSectionSpecified = fTrue; break; // // Allow /k but ignore it. It's processed in setup.c. // case 'f': case 'F': case 'k': case 'K': break; case 'w': case 'W': // // Since the /w parameter has already been handled // (see SETUP.C), eat the argument. // if(szBase = SzGetNextCmdLineString(&szCmdLine)) { SFree(szBase); } break; case 'i': case 'I': if (fSetupInfSpecified || (*pszInfSrcPath = SzGetNextCmdLineString(&szCmdLine)) == (SZ)NULL) { Usage(hInst); return(CMDLINE_ERROR); } if (**pszInfSrcPath == '\0') { LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax); LoadString(hInst, IDS_BAD_INF_SRC, rgchBufTmpLong, cchpBufTmpLongMax); MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND); Usage(hInst); return(CMDLINE_ERROR); } fSetupInfSpecified = fTrue; break; case 'g': case 'G': if (*pwModeSetup != wModeSetupNormal) { Usage(hInst); return(CMDLINE_ERROR); } *pwModeSetup = wModeGuiInitialSetup; break; case 's': case 'S': *pszSrcDir = SzGetNextCmdLineString(&szCmdLine); if(*pszSrcDir == NULL) { Usage(hInst); return(CMDLINE_ERROR); } if(**pszSrcDir == '\0') { LoadString( hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax ); LoadString( hInst, IDS_BAD_SRC_PATH, rgchBufTmpLong, cchpBufTmpLongMax ); MessageBox( hWndShell, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND ); Usage(hInst); return(CMDLINE_ERROR); } fSourcePathSpecified = fTrue; break; case 't': case 'T': { SZ szSymbol; SZ szEqual; SZ szValue; PVALUE_BLOCK pVb; if ( ( szSymbol = SzGetNextCmdLineString( &szCmdLine ) ) == NULL ) { Usage(hInst); return CMDLINE_ERROR; } if ( ( szEqual = SzGetNextCmdLineString( &szCmdLine ) ) == NULL ) { Usage(hInst); return CMDLINE_ERROR; } if ( ( szValue = SzGetNextCmdLineString( &szCmdLine ) ) == NULL ) { Usage(hInst); return CMDLINE_ERROR; } if ( (*szEqual != '=') || (*(szEqual+1) != '\0' ) ) { Usage(hInst); return CMDLINE_ERROR; } while ( (pVb = (PVALUE_BLOCK)SAlloc( sizeof( VALUE_BLOCK ) )) == NULL ) { if ( !FHandleOOM(hWndShell)) { return CMDLINE_ERROR; } } pVb->szSymbol = szSymbol; pVb->szValue = szValue; if ( pCmdLineSymbols ) { pVb->pNext = pCmdLineSymbols; } else { pVb->pNext = NULL; } pCmdLineSymbols = pVb; } break; case 'v': case 'V': fCheckInfValidity = fTrue; break; case '?': default: Usage(hInst); return(CMDLINE_SETUPDONE); } // switch } else { Usage(hInst); return(CMDLINE_ERROR); } // if we have - or / while (FWhiteSpaceChp(*szCmdLine)) { szCmdLine = SzNextChar(szCmdLine); } } // while unseen chars on cmd line while((szCur = *pszCWD = (SZ)SAlloc((CB)4096)) == NULL) { if(!FHandleOOM(hWndShell)) { return(CMDLINE_ERROR); } } // // Want name of exe, not name of this dll. // if ((cchp = GetModuleFileName(hInst, (LPSTR)szCur, 4095)) >= 4095) { LoadString(hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax); LoadString(hInst, IDS_EXE_PATH_LONG, rgchBufTmpLong,cchpBufTmpLongMax); MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,MB_OK | MB_ICONHAND); SFree(szCur); return(CMDLINE_ERROR); } if (PfhOpenFile(szCur, ofmExistRead) == NULL) { LoadString(hInst, IDS_INTERNAL_ERROR, rgchBufTmpShort, cchpBufTmpShortMax); LoadString(hInst, IDS_GET_MOD_FAIL, rgchBufTmpLong, cchpBufTmpLongMax); MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND); SFree(*pszCWD); return(CMDLINE_ERROR); } while(*szCur) { if(*szCur++ == '\\') { szLastBackSlash = szCur; } } if (szLastBackSlash == (SZ)NULL) { LoadString(hInst, IDS_INTERNAL_ERROR, rgchBufTmpShort, cchpBufTmpShortMax); LoadString(hInst, IDS_GET_MOD_FAIL, rgchBufTmpLong, cchpBufTmpLongMax); MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND); SFree(*pszCWD); return(CMDLINE_ERROR); } if(!fSetupInfSpecified) { szCur = szLastBackSlash; while (*szCur != '\0') { if (*szCur == '.') { *szCur = '\0'; break; } szCur++; } while((szBase = SzDupl(szLastBackSlash)) == (SZ)NULL) { if(!FHandleOOM(hWndShell)) { return(CMDLINE_ERROR); } } } *szLastBackSlash = '\0'; if(strlen(*pszCWD) + 1 < 4096) { *pszCWD = SRealloc(*pszCWD,strlen(*pszCWD)+1); } if(!fSourcePathSpecified) { while((*pszSrcDir = SzDupl(*pszCWD)) == (SZ)NULL) { if (!FHandleOOM(hWndShell)) { return(CMDLINE_ERROR); } } } // // if setup inf is not specified, then user is attempting to enter // maintenance-mode setup, which is obsolete. Give the user a friendly // message informing them of this, and directing them to the new functionality // in the Control Panel. // if(!fSetupInfSpecified) { Assert(szBase); SFree(szBase); MaintSetupObsoleteMsg(hInst); return CMDLINE_ERROR; /* LoadString(hInst,IDS_SETUP_INF,rgchBufTmpLong,cchpBufTmpLongMax); while((*pszInfSrcPath = SAlloc(strlen(szBase)+strlen(rgchBufTmpLong)+2)) == NULL) { if (!FHandleOOM(hWndShell)) { return( CMDLINE_ERROR ); } } strcpy(*pszInfSrcPath,szBase); lstrcat(*pszInfSrcPath,"."); lstrcat(*pszInfSrcPath,rgchBufTmpLong); */ } // // Process the setup inf found ( check to see if it exists ) in the // cwd or in windows system .. and get a full path back to the processed // setup inf location // bStatus = FProcessInfSrcPath(*pszInfSrcPath,*pszCWD,szInfPath); if(!bStatus) { LoadString( hInst, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax ); LoadString( hInst, IDS_BAD_INF_SRC, rgchBufTmpLong, cchpBufTmpLongMax); MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort,MB_OK | MB_ICONHAND); Usage(hInst); return(CMDLINE_ERROR); } SFree(*pszInfSrcPath); *pszInfSrcPath = SAlloc(strlen( szInfPath ) + 1 ); strcpy(*pszInfSrcPath, szInfPath); *pszDestDir = NULL; if(!fScriptSectionSpecified) { LoadString(hInst,IDS_SHELL_CMDS_SECT,rgchBufTmpShort,cchpBufTmpShortMax); while((szShlScriptSection = SzDupl(rgchBufTmpShort)) == (SZ)NULL) { if(!FHandleOOM(hWndShell)) { return(CMDLINE_ERROR); } } } return(CMDLINE_SUCCESS); } BOOL CreateShellWindow( IN HANDLE hInstance, IN INT nCmdShow, IN BOOL CleanUp ) { HDC hdc; TEXTMETRIC tm; WNDCLASS wc; BOOL RegisterStatus; if(!CleanUp) { nCmdShow = SW_SHOWMAXIMIZED; hInst = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wc.lpfnWndProc = ShellWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_STF_ICON)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; } wc.lpszClassName = "Stuff-Shell"; if(CleanUp) { ProInit(FALSE); ControlInit(FALSE); DlgDefClassInit(hInstance,FALSE); ButtonControlTerm(); UnregisterClass(wc.lpszClassName,hInst); return(TRUE); } else { RegisterStatus = RegisterClass(&wc); RegisterStatus &= ButtonControlInit(hInstance); RegisterStatus &= DlgDefClassInit(hInstance,TRUE); RegisterStatus &= ControlInit(TRUE); RegisterStatus &= ProInit(TRUE); } if(!RegisterStatus) { LoadString(hInstance,IDS_ERROR,rgchBufTmpShort,cchpBufTmpShortMax); LoadString(hInstance,IDS_REGISTER_CLASS,rgchBufTmpLong,cchpBufTmpLongMax); MessageBox( NULL, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL ); return(fFalse); } hdc = GetDC(NULL); if (hdc) { GetTextMetrics(hdc, &tm); dxChar = tm.tmAveCharWidth; dyChar = tm.tmHeight; ReleaseDC(NULL, hdc); } if(!FMakeWindows(hInstance)) { LoadString(hInstance,IDS_ERROR,rgchBufTmpShort,cchpBufTmpShortMax); LoadString(hInstance,IDS_CREATE_WINDOW,rgchBufTmpLong,cchpBufTmpLongMax); MessageBox( NULL, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL ); return(fFalse); } if ( ! fFullScreen ) { RECT rWind ; GetWindowRect( hWndShell, & rWind ) ; MoveWindow( hWndShell, 20000, 20000, rWind.right - rWind.left, rWind.bottom - rWind.top, FALSE ) ; nCmdShow = SW_SHOWNOACTIVATE ; } ShowWindow(hWndShell,nCmdShow); UpdateWindow(hWndShell); if (!FInitHook()) { // // BUGBUG.. Do we need to process this error, or do we just lose // the capability to process keyboard hooks // } return(fTrue); } /* ** Purpose: ** Initializes structures. ** Arguments: ** ?? ** Returns: ** BOOL ***************************************************************************/ BOOL FInitApp( HANDLE hInstance, SZ szInfSrcPath, SZ szDestDir, SZ szSrcDir, SZ szCWD, INT wModeSetup ) { GRC grc = grcOkay; INT Line; CHAR szName[cchlFullPathMax]; CHAR szDriveType[10]; CHAR szProcessedDir[cchlFullPathMax]; PINFCONTEXT pContext; PINFTEMPINFO pTempInfo; SZ szInstallType; ChkArg(hInstance != (HANDLE)NULL, 1, fFalse); ChkArg(szInfSrcPath != (SZ)NULL && *szInfSrcPath != '\0', 2, fFalse); ChkArg(szSrcDir != (SZ)NULL && *szSrcDir != '\0', 4, fFalse); ChkArg(szCWD != (SZ)NULL && *szCWD != '\0', 5, fFalse); Assert(szShlScriptSection != (SZ)NULL && *(szShlScriptSection) != '\0'); // // Create INF permanent and temporary info. // PathToInfName( szInfSrcPath, szName ); while ( !(pTempInfo = (PINFTEMPINFO)CreateInfTempInfo( AddInfPermInfo( szName ) )) ) { if (!FHandleOOM(hWndShell)) return(fFalse); } // // Create global context. // while ( !(pContext = (PINFCONTEXT)SAlloc( (CB)sizeof(CONTEXT) )) ) { if (!FHandleOOM(hWndShell)) return(fFalse); } pContext->pInfTempInfo = pTempInfo; pContext->pNext = NULL; PushContext( pContext ); pLocalContext()->szShlScriptSection = szShlScriptSection; // // Add all the symbols specified in the command line // while ( pCmdLineSymbols ) { PVALUE_BLOCK p = pCmdLineSymbols; pCmdLineSymbols = pCmdLineSymbols->pNext; while (!FAddSymbolValueToSymTab(p->szSymbol, p->szValue)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } SFree( p->szSymbol ); SFree( p->szValue ); SFree( p ); } FInitParsingTables(); GetWindowsDirectory(szProcessedDir,sizeof(szProcessedDir)); while(!FAddSymbolValueToSymTab("STF_WINDOWS_DIR",szProcessedDir)) { if(!FHandleOOM(hWndShell)) { return(fFalse); } } GetSystemDirectory(szProcessedDir,sizeof(szProcessedDir)); while(!FAddSymbolValueToSymTab("STF_SYSTEM_DIR",szProcessedDir)) { if(!FHandleOOM(hWndShell)) { return(fFalse); } } // // Process SRC DIR // if (!FProcessForDriveType(szSrcDir, szDriveType, szCWD, szProcessedDir)) { return(fFalse); } while (!FAddSymbolValueToSymTab("STF_SRCTYPE", szDriveType)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } while (!FAddSymbolValueToSymTab("STF_SRCDIR", szProcessedDir)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } // // Process DEST DIR // if (szDestDir != NULL) { if (!FProcessForDriveType(szDestDir, szDriveType, szCWD, szProcessedDir)) { return(fFalse); } while (!FAddSymbolValueToSymTab("STF_DSTTYPE", szDriveType)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } while (!FAddSymbolValueToSymTab("STF_DSTDIR", szProcessedDir)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } } else { while (!FAddSymbolValueToSymTab("STF_DSTTYPE", "NONE")) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } } // // Process INF SRC PATH // while (!FAddSymbolValueToSymTab("STF_SRCINFPATH", szInfSrcPath)) if (!FHandleOOM(hWndShell)) return(fFalse); while (!FAddSymbolValueToSymTab("STF_CONTEXTINFNAME", szInfSrcPath)) if (!FHandleOOM(hWndShell)) return(fFalse); // // Get the SETUP working directory // while (!FAddSymbolValueToSymTab("STF_CWDDIR", szCWD)) if (!FHandleOOM(hWndShell)) return(fFalse); while (!FAddSymbolValueToSymTab("STF_SYS_INIT", "NO")) if (!FHandleOOM(hWndShell)) return(fFalse); { char NumTmp[9]; HWND hw ; hw = hwParam ? FindProperParent() : hWndShell ; wsprintf(NumTmp,"%lx",hw); while (!FAddSymbolValueToSymTab("STF_HWND", NumTmp)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } } { // // Registry constants // char NumTmp[20]; PINITSYMHANDLE pSymHandle; PINITSYMNUMBER pSymNumber; // // Handles // pSymHandle = InitSymHandle; while ( pSymHandle->szName ) { wsprintf(NumTmp,"|%ld", pSymHandle->Handle ); while (!FAddSymbolValueToSymTab(pSymHandle->szName, NumTmp)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } pSymHandle++; } // // Numeric values // pSymNumber = InitSymNumber; while ( pSymNumber->szName ) { wsprintf(NumTmp,"%ld", pSymNumber->dwNumber ); while (!FAddSymbolValueToSymTab(pSymNumber->szName, NumTmp)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } pSymNumber++; } } if (wModeSetup == wModeSetupNormal) { szInstallType = "NORMAL"; } #if 0 else if (wModeSetup == wModeSetupToShare) { szInstallType = "SETUPTOSHARE"; } #endif else if (wModeSetup == wModeGuiInitialSetup) { szInstallType = "SETUPBOOTED"; } else { AssertRet(fFalse, fFalse); } while (!FAddSymbolValueToSymTab("STF_INSTALL_TYPE", szInstallType)) { if (!FHandleOOM(hWndShell)) { return(fFalse); } } #if DBG fCheckInfValidity = fTrue; #endif /* DBG */ while ((grc = GrcOpenInf(szInfSrcPath, pGlobalContext()->pInfTempInfo)) != grcOkay) if (EercErrorHandler(hWndShell, grc, fTrue, szInfSrcPath, 0, 0) != eercRetry) return(fFalse); while ((grc = GrcFillSrcDescrListFromInf()) != grcOkay) if (EercErrorHandler(hWndShell, grc, fTrue, szInfSrcPath, 0, 0) != eercRetry) return(fFalse); if ((Line = FindFirstLineFromInfSection(pLocalContext()->szShlScriptSection)) == -1) { LoadString(hInstance, IDS_ERROR, rgchBufTmpShort, cchpBufTmpShortMax); LoadString(hInstance, IDS_CANT_FIND_SHL_SECT, rgchBufTmpLong, cchpBufTmpLongMax); MessageBox(hWndShell, rgchBufTmpLong, rgchBufTmpShort, MB_OK | MB_ICONHAND); return(fFalse); } if ((psptShellScript = PsptInitParsingTable(rgscp)) == (PSPT)NULL || !FInitFlowPspt()) { Assert(fFalse); return(fFalse); } PostMessage(hWndShell, STF_SHL_INTERP, Line+1, 0L); return(fTrue); } /* * FMakeWindows -- create Windows used by Setup */ BOOL FMakeWindows( IN HANDLE hInstance ) { int xSize = GetSystemMetrics(SM_CXSCREEN), ySize = GetSystemMetrics(SM_CYSCREEN) ; DWORD dwStyle = WS_POPUP | WS_CLIPCHILDREN ; if ( ! fFullScreen ) { xSize = 2 ; ySize = 2 ; dwStyle = WS_POPUP ; } if ( hwParam ) { DWORD dwThreadId = GetCurrentThreadId() ; DWORD dwParentThreadId = GetWindowThreadProcessId( hwParam, NULL ) ; AttachThreadInput( dwThreadId, dwParentThreadId, TRUE ) ; } // // Create the main setup window // hWndShell = CreateWindowEx( fFullScreen ? 0 : WS_EX_TRANSPARENT, "Stuff-Shell", "Setup", dwStyle, 0, 0, xSize, ySize, hwParam, NULL, hInstance, NULL ); // // return status of operation // if ( hWndShell == (HWND)NULL ) { return( fFalse ); } return( fTrue ); } BOOL FProcessForDriveType( SZ szDir, SZ szDriveType, SZ szCWD, SZ szProcessedDir ) { ChkArg(szDir != (SZ)NULL, 1, fFalse); ChkArg(szDriveType != (SZ)NULL, 2, fFalse); ChkArg(szProcessedDir != (SZ)NULL, 3, fFalse); // // Only drive types are DOS and UNC. // if(ISUNC(szDir)) { lstrcpy(szDriveType,szUncType); lstrcpy(szProcessedDir,szDir); } else { lstrcpy(szDriveType,szDosType); // // Handle drive-relative paths. // if(*szDir == '\\') { // // root relative szDir, get current drive and slap it in // *szProcessedDir = (UCHAR)_getdrive() + (UCHAR)'A' - (UCHAR)1; *(szProcessedDir + 1) = ':'; *(szProcessedDir + 2) = '\0'; } else { if(*(szDir + 1) == ':') { // // Drive relative path (we don't need to do anything) // *szProcessedDir = '\0'; } else { // // No root specified, so we assume the directory is relative to // szCWD // lstrcpy(szProcessedDir,szCWD); } } lstrcat(szProcessedDir,szDir); } // // The szProcessedDir should be terminated by a '\\' // if (*(szProcessedDir + lstrlen(szProcessedDir) - 1) != '\\') { lstrcat(szProcessedDir,"\\"); } return(fTrue); } BOOL FProcessInfSrcPath( SZ szInf, SZ szCWD, SZ szProcessedDir ) { #define INF_ABSOLUTE 0 #define INF_RELATIVE 1 INT PathType = INF_RELATIVE; PFH pfh = (PFH)NULL; // // Check to see if the inf path specified is a relative path or // an absolute path // if ( lstrlen( szInf ) >= 2 ) { // // See if the INF has a drive relative src path spec // if (ISUNC( szInf ) ) { lstrcpy(szProcessedDir, szInf); PathType = INF_ABSOLUTE; } else if (*szInf == '\\') { // // root relative szInf // *szProcessedDir = (UCHAR)_getdrive() + (UCHAR)'A' - (UCHAR)1; *(szProcessedDir + 1) = ':'; *(szProcessedDir + 2) = '\0'; lstrcat(szProcessedDir, szInf); PathType = INF_ABSOLUTE; } else if (*(szInf + 1) == ':') { // // drive relative path (we don't need to do anything) // lstrcpy(szProcessedDir, szInf); PathType = INF_ABSOLUTE; } } // // If it is an absolute path try opening the INF as is // if ( PathType == INF_ABSOLUTE ) { if (( pfh = PfhOpenFile(szProcessedDir, ofmRead)) != (PFH)NULL ) { EvalAssert(FCloseFile(pfh)); return( TRUE ); } else { return( FALSE ); } } // // Path is a relative path, try first combining the szCWD and the inf. // lstrcpy( szProcessedDir, szCWD ); lstrcat( szProcessedDir, szInf ); if (( pfh = PfhOpenFile(szProcessedDir, ofmRead)) != (PFH)NULL ) { EvalAssert(FCloseFile(pfh)); return( TRUE ); } // // Then try combining the windows system directory and the INF // EvalAssert( GetSystemDirectory( szProcessedDir, MAX_PATH ) <= MAX_PATH ); lstrcat( szProcessedDir, "\\" ); lstrcat( szProcessedDir, szInf ); if (( pfh = PfhOpenFile(szProcessedDir, ofmRead)) != (PFH)NULL ) { EvalAssert(FCloseFile(pfh)); return( TRUE ); } // // Inf not found // return( FALSE ); } HWND FindProperParent ( void ) { RECT rect ; HWND hwMaster, hwParent ; POINT ptMax ; hwParent = hwMaster = GetDesktopWindow() ; // If we have a main window that is not the blue screen, // make sure that we have a valid parent that is visible. if ( hwParam ) { BOOL bOk = FALSE ; ptMax.x = GetSystemMetrics( SM_CXFULLSCREEN ) ; ptMax.y = GetSystemMetrics( SM_CYFULLSCREEN ) ; hwMaster = hwParam ; do { if ( IsWindow( hwMaster ) && GetWindowRect( hwMaster, & rect ) ) { bOk = rect.left >= 0 && rect.left < ptMax.x && rect.top >= 0 && rect.top < ptMax.y ; } if ( ! bOk ) { hwMaster = GetParent( hwMaster ) ; } } while ( ! bOk && hwMaster != NULL ) ; if ( bOk ) hwParent = hwMaster ; } return hwPseudoParent = hwParent ; }