//
// MINSTALL.DLL (c) Copyright 2002-2005 Martin Kiewitz
//
// This file is part of MINSTALL.DLL for OS/2 / eComStation
//
// MINSTALL.DLL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// MINSTALL.DLL is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with MINSTALL.DLL. If not, see .
//
#define INCL_NOPMAPI
#define INCL_BASE
#define INCL_DOSMODULEMGR
// #define INCL_OS2MM
#include
// #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
FILECONTROL CONTROLSCR;
FILECONTROL FILELISTSCR;
FILECONTROL CHANGESCR;
HAB MINSTALL_PMHandle = NULLHANDLE;
HMQ MINSTALL_MSGQHandle = NULLHANDLE;
HMTX MINSTALL_MutexSemamorph = NULLHANDLE;
CHAR MINSTALL_MMBase[MINSTMAX_PATHLENGTH];
CHAR MINSTALL_BootDrive[3];
CHAR MINSTALL_BootLetter[2];
CHAR MINSTALL_MMBaseDrive[3];
CHAR MINSTALL_MMBaseLetter[2];
// Path means pathname, Dir means Directory (directory includes ending '\'
CHAR MINSTALL_SourcePath[MINSTMAX_PATHLENGTH];
CHAR MINSTALL_SourceDir[MINSTMAX_PATHLENGTH];
CHAR MINSTALL_InstallPath[MINSTMAX_PATHLENGTH];
CHAR MINSTALL_InstallDir[MINSTMAX_PATHLENGTH];
CHAR MINSTALL_DLLDir[MINSTMAX_PATHLENGTH];
CHAR MINSTALL_CompListINI[MINSTMAX_PATHLENGTH];
CHAR MINSTLOG_FileName[MINSTMAX_PATHLENGTH];
FILE *MINSTLOG_FileHandle = 0;
CHAR MINSTALL_TempMacroSpace[MINSTMAX_PATHLENGTH];
ULONG MINSTALL_PublicGroupCount = 0;
PMINSTPUBGROUP MINSTALL_PublicGroupArrayPtr = 0;
// Contains all processed things
ULONG MINSTALL_Done = 0;
ULONG MINSTALL_ErrorMsgID = 0;
CHAR MINSTALL_ErrorMsg[1024];
CHAR MINSTALL_CIDDescription[1024];
// Master-Control-File Variables...
USHORT MCF_GroupCount = 0; // Total count in MCF_GroupArray
PMINSTGRP MCF_GroupArrayPtr = 0;
USHORT MCF_SourceDirCount = 0; // ... in MCF_SourceDirArray
PMINSTDIR MCF_SourceDirArrayPtr = 0;
USHORT MCF_DestinDirCount = 0; // ... in MCF_DestinDirArray
PMINSTDIR MCF_DestinDirArrayPtr = 0;
USHORT FCF_FileCount = 0; // ... in FCF_FileArray
PMINSTFILE FCF_FileArrayPtr = 0;
CHAR MCF_PackageName[MINSTMAX_STRLENGTH];
ULONG MCF_CodePage = 0;
ULONG MCF_MUnitCount = 0;
CHAR MCF_Medianame[MINSTMAX_STRLENGTH];
BOOL MINSTALL_GeninUsed = FALSE;
BOOL MINSTALL_IsBaseInstallation = FALSE;
// This is set till first MINSTALL_Init() was completed.
BOOL MINSTALL_IsFirstInit = TRUE;
BOOL MINSTALL_SystemShouldReboot = FALSE;
/* HMODULE FCF_CARDINFOHandle = 0; */
/* PMINSTFILE FCF_CARDINFOFilePtr = 0; */
HMODULE FCF_LastCARDINFOHandle = NULLHANDLE;
// Custom-API related public variables...
HEV CustomAPI_InitEventHandle = 0;
TID CustomAPI_ThreadID = 0;
BOOL CustomAPI_ThreadCreated = FALSE;
HAB CustomAPI_PMHandle = 0;
HMQ CustomAPI_MSGQHandle = 0;
HWND CustomAPI_WindowHandle = 0;
ULONG CustomAPI_ConfigSysLine = 0;
// Custom-DLL related public variables...
PVOID CustomDLL_EntryPoint = 0;
PSZ CustomDLL_EntryParms = NULL;
PSZ CustomDLL_CustomData = NULL;
// INI-Control-File
PMINSTINI_DEFENTRY ICF_CheckFuncList = NULL;
PMINSTINI_DEFENTRY ICF_CheckParmList = NULL;
PMINSTINI_DEFENTRY ICF_CurFuncEntry = NULL;
PMINSTINI_DEFENTRY ICF_CurParmEntry = NULL;
ULONG ICF_FilledParms = 0;
// ****************************************************************************
BOOL EXPENTRY MINSTALL_Init (ULONG BootDrive, HAB PMHandle, HMQ MSGQHandle, PSZ MMBase, PSZ LogFileName) {
PCHAR CurPos;
CHAR DelayedDir[MINSTMAX_PATHLENGTH];
APIRET rc;
HMODULE GeninDLLHandle = 0;
// Remember PM and MSGQ-Handles...
MINSTALL_PMHandle = PMHandle;
MINSTALL_MSGQHandle = MSGQHandle;
// Reset some strings...
MINSTALL_MMBase[0] = 0;
MINSTALL_MMBaseDrive[0] = 0;
MINSTALL_MMBaseLetter[0] = 0;
MINSTALL_InstallPath[0] = 0;
MINSTALL_InstallDir[0] = 0;
MINSTALL_DLLDir[0] = 0;
MINSTALL_CompListINI[0] = 0;
MINSTLOG_FileName[0] = 0;
MINSTALL_Done = 0;
if (!MSG_Init ("minstall.msg"))
return FALSE;
if (!MMBase[0]) {
// MMBase not set, so check environment
if (DosScanEnv("MMBASE", &MMBase)) {
MINSTALL_TrappedError (MINSTMSG_MMBaseNotFound); return FALSE; }
}
// Copy MMBase over to MINSTALL-variable...
if (!STRING_CombinePSZ ((PCHAR)&MINSTALL_MMBase, MINSTMAX_PATHLENGTH, MMBase, ""))
return FALSE;
CurPos = MINSTALL_MMBase;
// Look till ';' or EOS...
while ((*CurPos!=0) & (*CurPos!=0x3B))
CurPos++;
if (*CurPos==0x3B)
*CurPos = 0; // Set Terminator, if ';' found
MINSTALL_MMBaseDrive[0] = MINSTALL_MMBase[0];
MINSTALL_MMBaseDrive[1] = MINSTALL_MMBase[1];
MINSTALL_MMBaseDrive[2] = 0;
MINSTALL_MMBaseLetter[0] = MINSTALL_MMBaseDrive[0];
MINSTALL_MMBaseLetter[1] = 0;
// Build Install/DLL-Path for MINSTALL...
if (!STRING_CombinePSZ (MINSTALL_InstallPath, MINSTMAX_PATHLENGTH, MINSTALL_MMBase, "\\INSTALL"))
return FALSE;
if (!STRING_CombinePSZ (MINSTALL_InstallDir, MINSTMAX_PATHLENGTH, MINSTALL_InstallPath, "\\"))
return FALSE;
if (!STRING_CombinePSZ (MINSTALL_DLLDir, MINSTMAX_PATHLENGTH, MINSTALL_MMBase, "\\DLL\\"))
return FALSE;
if (!STRING_CombinePSZ (MINSTALL_CompListINI, MINSTMAX_PATHLENGTH, MINSTALL_InstallDir, "COMPLIST.INI"))
return FALSE;
if ((BootDrive==0) || (BootDrive>26)) {
if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &BootDrive, sizeof(BootDrive)) || (BootDrive<3))
return FALSE; // We only accept C: -> Z:
}
MINSTALL_BootDrive[0] = BootDrive+0x40; // 3 -> C
MINSTALL_BootDrive[1] = 0x3A; // ':'
MINSTALL_BootDrive[2] = 0; // NUL
MINSTALL_BootLetter[0] = BootDrive+0x40; // 3 -> C
MINSTALL_BootLetter[1] = 0; // NUL
// Find out Log-filename...
if (LogFileName) {
// We are supposed to use a logfilename
if (LogFileName[0]) {
if (!STRING_CopyPSZ (MINSTLOG_FileName, MINSTMAX_PATHLENGTH, LogFileName))
return FALSE;
} else {
if (!STRING_CombinePSZ (MINSTLOG_FileName, MINSTMAX_PATHLENGTH, MINSTALL_InstallDir, "MINSTALL.LOG"))
return FALSE;
}
if (MINSTALL_IsFirstInit) { // Only on 1st MINSTALL_Init()
// Now try to delete the logfile. If this works, we use it. Otherwise
// we try to set logfile to x:\OS2\INSTALL where x: is the bootdrive
// if this also fails, we will set logfile to NULL
rc = DosDelete(MINSTLOG_FileName);
if ((rc!=NO_ERROR) && (rc!=ERROR_FILE_NOT_FOUND)) {
// Now try to put logfile into x:\OS2\INSTALL...
if (!STRING_CombinePSZ (MINSTLOG_FileName, MINSTMAX_PATHLENGTH, MINSTALL_BootDrive, "\\OS2\\INSTALL\\MINSTALL.LOG"))
return FALSE;
rc = DosDelete(MINSTLOG_FileName);
if ((rc!=NO_ERROR) && (rc!=ERROR_FILE_NOT_FOUND)) {
MINSTLOG_FileName[0] = 0; // Set LogFile to NULL
}
}
}
}
// Detect replacement GENIN.DLL - if it's not found, bomb out...
// DEBUGDEBUGDEBUG
// if (GeninDLLHandle = DLL_Load("GENIN.DLL")) {
// if (!DLL_GetEntryPoint(GeninDLLHandle, "GeninReplacementIdentifier")) {
// MINSTALL_TrappedError (MINSTMSG_GeninReplacementRequired); return FALSE; }
// DLL_UnLoad (GeninDLLHandle);
// }
// Init file-delaying API (even if it's not actually used)
if (!STRING_CombinePSZ (DelayedDir, MINSTMAX_PATHLENGTH, MINSTALL_InstallDir, "DELAYED"))
return FALSE;
if (CONFIGSYS_DelayInit (BootDrive, "MMLOCKED.LST", DelayedDir)!=CONFIGSYS_DONE)
return FALSE;
// Finally generate a Mutex-Semamorph, so that we can be sure that we are
// the only instance of MINSTALL active on the system.
if (MINSTALL_MutexSemamorph==NULLHANDLE) {
if (DosCreateMutexSem("\\SEM32\\MKMULTIMEDIAINSTALLER", &MINSTALL_MutexSemamorph, 0, FALSE)) {
MINSTALL_TrappedError (MINSTMSG_AlreadyRunning); return FALSE; }
}
MINSTALL_IsFirstInit = FALSE;
return TRUE;
}
// This will load in the full installation of an MMOS/2 feature
// It will also parse variables and check for their validity. If it returns
// FALSE, this means that something went wrong and the installation can not
// be done. The caller is supposed to call MINSTALL_CleanUp() afterwards to
// deallocate any buffers. This has to be done manually.
BOOL EXPENTRY MINSTALL_InitPackage (PSZ SourcePath) {
ULONG Temp;
if (MINSTALL_IsFirstInit) {
MINSTALL_TrappedError (MINSTMSG_NeedingInit); return FALSE; }
if (MINSTALL_Done & MINSTDONE_BEGANPACKAGEINIT) {
MINSTALL_TrappedError (MINSTMSG_NeedingCleanUp); return FALSE; }
// We havent done anything yet...
MINSTALL_Done = MINSTDONE_BEGANPACKAGEINIT;
MINSTLOG_OpenFile();
MINSTLOG_ToFile ("================================================================ MINSTALL v1.03\n");
MINSTLOG_ToFile ("MINSTALL_InitPackage()...\n");
if (SourcePath[0]!=0) {
if (!STRING_CombinePSZ((PCHAR)MINSTALL_SourcePath, MINSTMAX_PATHLENGTH, SourcePath, ""))
return FALSE;
} else {
// Get current Path and set it as SourcePath
if (!FILE_GetCurrentPath(MINSTALL_SourcePath, MINSTMAX_PATHLENGTH))
return FALSE;
}
if (!STRING_CombinePSZ(MINSTALL_SourceDir, MINSTMAX_PATHLENGTH, SourcePath, "\\"))
return FALSE;
MINSTLOG_ToFile (" SourcePath = %s, TargetPath = %s\n", MINSTALL_SourcePath, MINSTALL_MMBase);
// Load CONTROL.scr file from SourcePath...
if (!STRING_CombinePSZ((PCHAR)&CONTROLSCR.Name, MINSTMAX_PATHLENGTH, MINSTALL_SourceDir, "control.scr"))
return FALSE;
MINSTLOG_ToFile ("LoadMasterControl()...\n");
if (!MINSTALL_LoadMasterControl()) return FALSE;
MINSTLOG_ToFile ("LoadMasterControl DONE\n");
if (MCF_MUnitCount!=1) {
MINSTALL_TrappedError (MINSTMSG_MultiDisksUnsupported); return FALSE;
}
if (FILELISTSCR.Name[0]==0) {
MINSTALL_TrappedError (MINSTMSG_NoFileControlSpecified);return FALSE;
}
// Load in File-Control-Script...
MINSTLOG_ToFile ("LoadFileControl()...\n");
if (!MINSTALL_LoadFileControl()) return FALSE;
MINSTLOG_ToFile ("LoadFileControl DONE\n");
if (!MINSTALL_FilterControlFileData()) return FALSE;
if (!MINSTALL_LoadCARDINFO()) return FALSE;
if (!MINSTALL_LoadCustomControl()) return FALSE;
// Finally create Public Group for caller
if (!MINSTALL_GeneratePublicGroup()) return FALSE;
MINSTALL_ErrorMsgID = 0;
MINSTALL_Done |= MINSTDONE_COMPLETEDPACKAGEINIT;
MINSTLOG_ToAll (" ...Package successfully initialized!\n");
return TRUE;
}
BOOL EXPENTRY MINSTALL_InstallPackage (VOID) {
if (MINSTALL_IsFirstInit) {
MINSTALL_TrappedError (MINSTMSG_NeedingInit); return FALSE; }
MINSTLOG_ToFile ("MINSTALL_InstallPackage()...\n");
if (!(MINSTALL_Done & MINSTDONE_COMPLETEDPACKAGEINIT)) {
MINSTALL_TrappedError (MINSTMSG_PackageNotInitialized); return FALSE; }
// Select files&directories depending on group selection done by caller
MINSTALL_SelectFiles();
// Generate Destination Directories, copy files and process scripts...
if (!MINSTALL_CreateDestinDirectories()) return FALSE;
MINSTLOG_ToFile ("MINSTALL_CopyFiles()...\n");
if (!MINSTALL_CopyFiles()) return FALSE;
MINSTLOG_ToFile ("MINSTALL_CopyFiles DONE\n");
MINSTLOG_ToFile ("MINSTALL_LinkInImports()...\n");
if (!MINSTALL_LinkInImports()) return FALSE;
MINSTLOG_ToFile ("MINSTALL_LinkInImports DONE\n");
// Hardcoded in MMI_IMPORTS.C
MINSTALL_MigrateMMPMMMIOFile();
MINSTLOG_ToFile ("MINSTALL_ExecuteCustomDLLs()...\n");
if (!MINSTALL_ExecuteCustomDLLs()) return FALSE;
MINSTLOG_ToFile ("MINSTALL_ExecuteCustomDLLs DONE\n");
MINSTLOG_ToFile ("MINSTALL_ProcessScripts()...\n");
if (!MINSTALL_ProcessCARDINFO()) return FALSE;
if (!MINSTALL_ProcessScripts()) return FALSE;
MINSTLOG_ToFile ("MINSTALL_ExecuteCustomTermDLLs()...\n");
if (!MINSTALL_ExecuteCustomTermDLLs()) return FALSE;
// Do special things on base installations...
if (MINSTALL_IsBaseInstallation) {
MINSTALL_LowerMasterVolume();
}
MINSTLOG_ToFile ("MINSTALL_ExecuteCustomTermDLLs DONE\n");
if (!MINSTALL_SaveInstalledVersions()) return FALSE;
MINSTALL_ErrorMsgID = 0;
MINSTALL_SystemShouldReboot = TRUE;
MINSTLOG_ToFile ("MINSTALL_InstallPackage DONE\n");
return TRUE;
}
// Does all sorts of cleanup. May not fail in any way.
VOID EXPENTRY MINSTALL_CleanUp (VOID) {
MINSTLOG_ToFile ("MINSTALL_CleanUp()...\n");
if (MINSTALL_Done & MINSTDONE_LINKINIMPORTS)
MINSTALL_CleanUpImports();
if (MINSTALL_Done & MINSTDONE_PUBLICGROUP)
MINSTALL_CleanUpPublicGroup();
if (MINSTALL_Done & MINSTDONE_LOADCUSTOMCTRLSCR)
MINSTALL_CleanUpCustomControl();
if (MINSTALL_Done & MINSTDONE_LOADCARDINFO)
MINSTALL_CleanUpCARDINFO();
if (MINSTALL_Done & MINSTDONE_LOADFILECTRLSCR)
MINSTALL_CleanUpFileControl();
if (MINSTALL_Done & MINSTDONE_LOADMASTERCTRLSCR)
MINSTALL_CleanUpMasterControl();
MINSTLOG_ToFile ("MINSTALL_CleanUp DONE\n");
MINSTALL_Done = 0;
MINSTALL_ErrorMsgID = 0;
MINSTLOG_CloseFile();
}
PSZ EXPENTRY MINSTALL_GetErrorMsgPtr (void) {
if (MINSTALL_ErrorMsgID) {
return MINSTALL_ErrorMsg;
}
return NULL;
}
USHORT EXPENTRY MINSTALL_GetErrorMsgCIDCode (void) {
switch (MINSTALL_ErrorMsgID) {
case 0:
if (MINSTALL_SystemShouldReboot) {
return CIDRET_SuccessReboot;
} else {
return CIDRET_Success;
}
case MINSTMSG_CouldNotFindSourceFile:
case MINSTMSG_CICouldNotLoadCustomDLL:
case MINSTMSG_CouldNotAccessFile:
return CIDRET_DataResourceNotFound;
case MINSTMSG_GenericError:
return CIDRET_UnexpectedCondition;
case MINSTMSG_DiskFull:
return CIDRET_NotEnoughDiskSpace;
default:
return CIDRET_SuccessErrorLogged;
}
}
PSZ EXPENTRY MINSTALL_GetErrorMsgCIDCodeDescription (void) {
MINSTALL_CIDDescription[0] = 0;
switch (MINSTALL_ErrorMsgID) {
case 0:
if (MINSTALL_SystemShouldReboot) {
MSG_Get((PVOID)&MINSTALL_CIDDescription, 1024, MINSTMSG_CIDSuccessReboot); break;
} else {
MSG_Get((PVOID)&MINSTALL_CIDDescription, 1024, MINSTMSG_CIDSuccess); break;
}
case MINSTMSG_CouldNotFindSourceFile:
case MINSTMSG_CICouldNotLoadCustomDLL:
case MINSTMSG_CouldNotAccessFile:
MSG_Get((PVOID)&MINSTALL_CIDDescription, 1024, MINSTMSG_CIDDataResourceNotFound); break;
case MINSTMSG_GenericError:
MSG_Get((PVOID)&MINSTALL_CIDDescription, 1024, MINSTMSG_CIDUnexpectedCondition); break;
case MINSTMSG_DiskFull:
MSG_Get((PVOID)&MINSTALL_CIDDescription, 1024, MINSTMSG_CIDNotEnoughDiskSpace); break;
default:
MSG_Get((PVOID)&MINSTALL_CIDDescription, 1024, MINSTMSG_CIDSuccessErrorsLogged); break;
}
return (PSZ)&MINSTALL_CIDDescription;
}
PSZ EXPENTRY MINSTALL_GetSourcePathPtr (void) {
return MINSTALL_SourcePath;
}
PSZ EXPENTRY MINSTALL_GetTargetPathPtr (void) {
return MINSTALL_MMBase;
}
ULONG EXPENTRY MINSTALL_GetPublicGroupArrayPtr (PMINSTPUBGROUP *PubGroupArrayPtr) {
if (MINSTALL_Done & MINSTDONE_COMPLETEDPACKAGEINIT) {
*PubGroupArrayPtr = MINSTALL_PublicGroupArrayPtr;
return MINSTALL_PublicGroupCount;
}
return 0;
}
PSZ EXPENTRY MINSTALL_GetPublicGroupCustomDataPtr (ULONG GroupID) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
ULONG CurGroupNo = 0;
while (CurGroupNoID==GroupID) {
if (!(CurGroup->Flags & MINSTGRP_Flags_DontListPublic)) {
if (CurGroup->GeninPtr) {
// If GENIN information present, calculate realtime
MINSTALL_FillCARDINFOCustomData (CurGroup);
}
return CurGroup->CustomData;
}
break;
}
CurGroupNo++; CurGroup++;
}
return NULL;
}
BOOL EXPENTRY MINSTALL_SetPublicGroupCustomData (ULONG GroupID, PSZ CustomDataPtr) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
ULONG CurGroupNo = 0;
while (CurGroupNoID==GroupID) {
if (!(CurGroup->Flags & MINSTGRP_Flags_DontListPublic)) {
if (STRING_CopyPSZ(CurGroup->CustomData, MINSTMAX_CUSTOMDATALENGTH, CustomDataPtr)) {
if (CurGroup->GeninPtr) {
// If GENIN information present, automatically select
if (!MINSTALL_UseCARDINFOCustomData(CurGroup))
return FALSE;
}
}
return TRUE;
}
break;
}
CurGroupNo++; CurGroup++;
}
return TRUE;
}
PSZ EXPENTRY MINSTALL_GetPackageTitlePtr (void) {
if (MINSTALL_Done & MINSTDONE_COMPLETEDPACKAGEINIT) {
return MCF_PackageName; // Simple, ey? ;-)
}
return NULL;
}
VOID EXPENTRY MINSTALL_SelectGroup (ULONG GroupID) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
PMINSTPUBGROUP PubGroup = MINSTALL_PublicGroupArrayPtr;
ULONG CurGroupNo = 0;
// Cycle through all groups and match GroupID. Selecting possible only on
// groups that are listed in PublicGroup and SelectionForced not set.
while (CurGroupNoID==GroupID) {
if (!(CurGroup->Flags & MINSTGRP_Flags_DontListPublic)) {
CurGroup->Flags |= MINSTGRP_Flags_Selected;
}
break;
}
CurGroupNo++; CurGroup++;
}
// Update Public-Group as well...
CurGroupNo = 0;
while (CurGroupNoID==GroupID) {
if (!(PubGroup->SelectionForced)) {
PubGroup->Selected = TRUE;
}
}
CurGroupNo++; PubGroup++;
}
}
VOID EXPENTRY MINSTALL_DeSelectGroup (ULONG GroupID) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
PMINSTPUBGROUP PubGroup = MINSTALL_PublicGroupArrayPtr;
ULONG CurGroupNo = 0;
// Cycle through all groups and match GroupID. Selecting possible only on
// groups that are listed in PublicGroup and SelectionForced not set.
while (CurGroupNoID==GroupID) {
if (!(CurGroup->Flags & MINSTGRP_Flags_DontListPublic)) {
CurGroup->Flags &= !MINSTGRP_Flags_Selected;
}
break;
}
CurGroupNo++; CurGroup++;
}
// Update Public-Group as well...
CurGroupNo = 0;
while (CurGroupNoID==GroupID) {
if (!(PubGroup->SelectionForced)) {
PubGroup->Selected = FALSE;
}
}
CurGroupNo++; PubGroup++;
}
}
VOID EXPENTRY MINSTALL_SetCARDINFOCardCountForGroup (ULONG GroupID, ULONG SelectedCards) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
PMINSTPUBGROUP PubGroup = MINSTALL_PublicGroupArrayPtr;
ULONG CurGroupNo = 0;
// Cycle through all groups and match GroupID. Set SelectedCards only, if
// Genin-Information present.
while (CurGroupNoID==GroupID) {
if (CurGroup->GeninPtr) {
if (SelectedCards<=CurGroup->GeninPtr->MaxCardCount)
CurGroup->GeninPtr->SelectedCards = SelectedCards;
}
break;
}
CurGroupNo++; CurGroup++;
}
}
ULONG EXPENTRY MINSTALL_GetCARDINFOChoiceForGroup (ULONG GroupID, ULONG CardNo, ULONG PromptNo) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
ULONG CurGroupNo = 0;
if ((!CardNo) || (!PromptNo)) return; // Invalid input
CardNo--; PromptNo--;
// Cycle through all groups and match GroupID. Set Choice only, if Genin-
// Information present.
while (CurGroupNoID==GroupID) {
if (CurGroup->GeninPtr) {
// Check, if CardNo/PromptNo is a valid value
if (CardNo>=CurGroup->GeninPtr->SelectedCards)
return 0;
if (PromptNo>=CurGroup->GeninPtr->PromptsCount)
return 0;
return (CurGroup->GeninPtr->PromptSelectedValueNo[CardNo][PromptNo])+1;
}
break;
}
CurGroupNo++; CurGroup++;
}
return 0;
}
// ChoiceNo in that case is 1-based
VOID EXPENTRY MINSTALL_SetCARDINFOChoiceForGroup (ULONG GroupID, ULONG CardNo, ULONG PromptNo, ULONG ChoiceNo) {
PMINSTGRP CurGroup = MCF_GroupArrayPtr;
ULONG CurGroupNo = 0;
ULONG CurChoiceNo = 0;
PSZ CurValuePtr = 0;
if ((!CardNo) || (!PromptNo) || (!ChoiceNo)) return; // Invalid input
CardNo--; PromptNo--; ChoiceNo--;
// Cycle through all groups and match GroupID. Set Choice only, if Genin-
// Information present.
while (CurGroupNoID==GroupID) {
if (CurGroup->GeninPtr) {
// We got GroupID, so cycle through all Values and set selected
// PSZ pointer. Also check, if ChoiceNo is a valid value
// Check, if CardNo/PromptNo is a valid value
if (CardNo>=CurGroup->GeninPtr->SelectedCards)
return;
if (PromptNo>=CurGroup->GeninPtr->PromptsCount)
return;
if (ChoiceNo>=CurGroup->GeninPtr->PromptChoiceCount[PromptNo])
return;
CurValuePtr = CurGroup->GeninPtr->PromptChoiceValues[PromptNo];
while (CurChoiceNoGeninPtr->PromptSelectedValue[CardNo][PromptNo] = CurValuePtr;
CurGroup->GeninPtr->PromptSelectedValueNo[CardNo][PromptNo] = ChoiceNo;
}
break;
}
CurGroupNo++; CurGroup++;
}
}