|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
utils.c
Abstract:
Contains some functions used by all modules.
Author:
Bogdan Andreiu (bogdana) 10-Feb-1997 Jason Allor (jasonall) 24-Feb-1998 (took over the project)
Revision History:
10-Feb-1997 bogdana First draft: the greatest part of the functions 20_Feb-1997 bogdana Added three multistring processing functions 19-Mar-1997 bogdana Added LogLine and modified LogOCFunction 12-Apr-1997 bogdana Modified the multistring processing routines --*/
#include "octest.h"
/*++
Routine Description: (3.1)
Logs information about the OC Function received from the OC Manager Arguments:
lpcvComponentId: the name of the component (PVOID because it might be ANSI or Unicode) lpcvSubcomponentId: the subcomponent's name (NULL if none) uiFunction: one of OC_XXX functions uiParam1: the first param of the call pvParam2: the second param of the call Return Value:
void
--*/ VOID LogOCFunction(IN LPCVOID lpcvComponentId, IN LPCVOID lpcvSubcomponentId, IN UINT uiFunction, IN UINT uiParam1, IN PVOID pvParam2) { double fn = 3.1; UINT uiCount; TCHAR tszMsg[MAX_MSG_LEN]; WCHAR wszFromANSI[MAX_MSG_LEN]; CHAR cszFromUnicode[MAX_MSG_LEN]; DWORD dwEndVariation;
PSETUP_INIT_COMPONENT psicInitComp; SYSTEMTIME st; //
// Don't log OC_PRIVATE_BASE calls. There are too many of them
// and they just clutter up the log. Failures will still be logged.
//
if (uiFunction >= OC_PRIVATE_BASE) return; //
// Display the current time. This is a way of checking if the
// notifications are received in the proper sequence.
//
GetLocalTime(&st); _stprintf (tszMsg, TEXT("[%02.2d:%02.2d:%02.2d] "), (INT)st.wHour, (INT)st.wMinute, (INT)st.wSecond);
//
// The second line contains the function and the return value
//
for (uiCount = 0; uiCount < MAX_OC_FUNCTIONS; uiCount++) { if (octFunctionNames[uiCount].uiOCFunction == uiFunction) { _stprintf(tszMsg, TEXT("%s %s"), tszMsg, octFunctionNames[uiCount].tszOCText); break; } } Log(fn, INFO, TEXT("-----------------------------------")); LogBlankLine(); Log(fn, INFO, tszMsg);
if (uiFunction != OC_PREINITIALIZE) { if (!lpcvComponentId || _tcscmp((PTSTR)lpcvComponentId, TEXT("")) == 0) { _stprintf(tszMsg, TEXT("Component = (null) ")); } else { _stprintf(tszMsg, TEXT("Component = %s "), (PTSTR)lpcvComponentId); } if (!lpcvSubcomponentId || _tcscmp((PTSTR)lpcvSubcomponentId, TEXT("")) == 0) { _stprintf(tszMsg, TEXT("%sSubcomponent = (null)"), tszMsg); } else { _stprintf(tszMsg, TEXT("%sSubcomponent = %s"), tszMsg, (PTSTR)lpcvSubcomponentId); } } else { //
// The SubcomponentId should be the non-native version,
// if it is supported by the OC Manager
//
#ifdef UNICODE
if (uiParam1 & OCFLAG_UNICODE) { //
// The ComponentId is Unicode
//
if (uiParam1 & OCFLAG_ANSI) { //
// The second param is ANSI, convert to Unicode for
// printing it
//
mbstowcs(wszFromANSI, (PCHAR)lpcvSubcomponentId, strlen((PCHAR)lpcvSubcomponentId)); wszFromANSI[strlen((PCHAR)lpcvSubcomponentId)] = L'\0'; } else { //
// Nothing to do if ANSI not supported
//
wszFromANSI[0] = TEXT('\0'); } _stprintf(tszMsg, TEXT("Component = %s (Unicode) %s (ANSI)"), lpcvComponentId, wszFromANSI); } else { //
// Only ANSI supported
//
mbstowcs(wszFromANSI, (PCHAR)lpcvComponentId, strlen((PCHAR)lpcvComponentId)); wszFromANSI[strlen((PCHAR)lpcvSubcomponentId)] = L'\0'; _stprintf(tszMsg, TEXT("Component = %s (ANSI only)"), wszFromANSI); }
#else
//
// ANSI
//
if (uiParam1 & OCFLAG_UNICODE) { //
// The ComponentId is Unicode
//
wcstombs(cszFromUnicode, (PWCHAR)lpcvComponentId, wcslen((PWCHAR)lpcvComponentId)); cszFromUnicode[wcslen((PWCHAR)lpcvComponentId)] = '\0'; sprintf(tszMsg, "Component = %s (ANSI) %s (Unicode)", (PCHAR)lpcvSubcomponentId, cszFromUnicode); } else {
sprintf(tszMsg, "Component = %s (ANSI only)", (PCHAR)lpcvSubcomponentId); }
#endif
} //
// Log this first line of information
//
Log(fn, INFO, tszMsg);
//
// Check if the function is in range
//
__ASSERT(uiCount < MAX_OC_FUNCTION);
//
// Now we're ready to print the details
//
switch (uiFunction) { case OC_PREINITIALIZE: break; case OC_INIT_COMPONENT: //
// We have a bunch of information to print here
//
psicInitComp = (PSETUP_INIT_COMPONENT)pvParam2; //
// Assert that the Param2 is not NULL, we can dereference it
//
__ASSERT(psicInitComp != NULL); Log(fn, INFO, TEXT("OCManagerVersion = %d"), psicInitComp->OCManagerVersion); Log(fn, INFO, TEXT("ComponentVersion = %d"), psicInitComp->ComponentVersion);
//
// The mode first
//
_tcscpy(tszMsg, TEXT("Mode ")); switch (psicInitComp->SetupData.SetupMode) { case SETUPMODE_UNKNOWN: _tcscat(tszMsg, TEXT("Unknown")); break; case SETUPMODE_MINIMAL: _tcscat(tszMsg, TEXT("Minimal")); break; case SETUPMODE_TYPICAL: _tcscat(tszMsg, TEXT("Typical")); break; case SETUPMODE_LAPTOP: _tcscat(tszMsg, TEXT("Laptop")); break; case SETUPMODE_CUSTOM: _tcscat(tszMsg, TEXT("Custom")); break; default: break; }
//
// ... then the product type
//
_tcscat(tszMsg, TEXT(" ProductType ")); switch (psicInitComp->SetupData.ProductType) { case PRODUCT_WORKSTATION: _tcscat(tszMsg, TEXT("Workstation")); break; case PRODUCT_SERVER_PRIMARY: _tcscat(tszMsg, TEXT("Server Primary")); break; case PRODUCT_SERVER_STANDALONE: _tcscat(tszMsg, TEXT("Server Standalone")); break; case PRODUCT_SERVER_SECONDARY: _tcscat(tszMsg, TEXT("Server Secondary")); break; default: break; }
//
// ... then the operation
//
_tcscat(tszMsg, TEXT(" Operation ")); switch (psicInitComp->SetupData.OperationFlags) { case SETUPOP_WIN31UPGRADE: _tcscat(tszMsg, TEXT("Win 3.1")); break; case SETUPOP_WIN95UPGRADE: _tcscat(tszMsg, TEXT("Win95")); break; case SETUPOP_NTUPGRADE: _tcscat(tszMsg, TEXT("NT")); break; case SETUPOP_BATCH: _tcscat(tszMsg, TEXT("Batch")); break; case SETUPOP_STANDALONE: _tcscat(tszMsg, TEXT("Standalone")); break; default: break; }
Log(fn, INFO, tszMsg); ZeroMemory(tszMsg, MAX_MSG_LEN); if (psicInitComp->SetupData.SourcePath[0] != TEXT('\0')) { _stprintf(tszMsg, TEXT("Source Path = %s"), psicInitComp->SetupData.SourcePath); } if (psicInitComp->SetupData.UnattendFile[0] != TEXT('\0')) { _stprintf(tszMsg, TEXT("%s, UnattendedFile = %s"), tszMsg, psicInitComp->SetupData.UnattendFile); } break;
case OC_SET_LANGUAGE: Log(fn, INFO, TEXT("Primary = %d Secondary = %d"), PRIMARYLANGID((WORD)uiParam1), SUBLANGID((WORD)uiParam1)); break; case OC_QUERY_IMAGE: break; case OC_REQUEST_PAGES: switch (uiParam1) { case WizPagesWelcome: _tcscpy(tszMsg, TEXT("Welcome Pages ")); break; case WizPagesMode: _tcscpy(tszMsg, TEXT("Mode Pages")); break; case WizPagesEarly: _tcscpy(tszMsg, TEXT("Early Pages")); break; case WizPagesPrenet: _tcscpy(tszMsg, TEXT("Prenet Pages")); break; case WizPagesPostnet: _tcscpy(tszMsg, TEXT("Postnet Pages")); break; case WizPagesLate: _tcscpy(tszMsg, TEXT("Late Pages")); break; case WizPagesFinal: _tcscpy(tszMsg, TEXT("Final Pages")); break; default: break; } Log(fn, INFO, TEXT("Maximum %s = %d"), tszMsg, ((PSETUP_REQUEST_PAGES)pvParam2)->MaxPages); break;
case OC_QUERY_CHANGE_SEL_STATE: Log(fn, INFO, TEXT("Component %s %s"), ((uiParam1 == 0)?TEXT("unselected"):TEXT("selected")), (((INT)pvParam2 == OCQ_ACTUAL_SELECTION)?TEXT("Now"):TEXT(""))); break; default: break; } LogBlankLine(); return;
} // LogOCFunction //
/*++
Routine Description:
Check if a radio button is checked or not.
Arguments:
hwndDialog - handle to the dialog box.
CtrlId - the Control ID.
Return Value:
TRUE if the button is checked, FALSE if not.
--*/ BOOL QueryButtonCheck(IN HWND hwndDlg, IN INT iCtrlID) { HWND hwndCtrl = GetDlgItem(hwndDlg, iCtrlID); INT iCheck = (INT)SendMessage(hwndCtrl, BM_GETCHECK, 0, 0);
return (iCheck == BST_CHECKED);
} // QueryButtonCheck //
/*++
Routine Description:
Prints the space required on each drive. Arguments:
DiskSpace - the structure that describes the disk space required. Return Value:
None.
--*/ VOID PrintSpaceOnDrives(IN HDSKSPC DiskSpace) { DWORD dwRequiredSize, dwReturnBufferSize; PTCHAR tszReturnBuffer, tszPointerToStringToFree; TCHAR tszMsg[MAX_MSG_LEN]; LONGLONG llSpaceRequired;
SetupQueryDrivesInDiskSpaceList(DiskSpace, NULL, 0, &dwRequiredSize); dwReturnBufferSize = dwRequiredSize;
__Malloc(&tszReturnBuffer, (dwReturnBufferSize * sizeof(TCHAR))); SetupQueryDrivesInDiskSpaceList(DiskSpace, tszReturnBuffer, dwReturnBufferSize, &dwRequiredSize); //
// We need to do this because we'll modify ReturnBuffer
//
tszPointerToStringToFree = tszReturnBuffer; if (GetLastError() == NO_ERROR) { //
// Parse the ReturnBuffer
//
while (*tszReturnBuffer != TEXT('\0')) { SetupQuerySpaceRequiredOnDrive(DiskSpace, tszReturnBuffer, &llSpaceRequired, 0, 0); _stprintf(tszMsg, TEXT("Drive: %s Space required = %I64x, %I64d\n"), tszReturnBuffer, llSpaceRequired, llSpaceRequired); OutputDebugString(tszMsg); //
// The next string is ahead
//
tszReturnBuffer += _tcslen(tszReturnBuffer) + 1; }
} __Free(&tszPointerToStringToFree); return;
} // PrintSpaceOnDrives //
//
// Routines that deal with multistrings.
// All assume that the multistring is double NULL terminated
//
/*++
Routine Description:
Converts a multistring to a string, by replacing the '\0' characters with blanks. Both strings should be properly allocated. Arguments:
MultiStr - supplies the multi string.
Str - recieves the string.
Return Value:
None.
--*/ VOID MultiStringToString(IN PTSTR tszMultiStr, OUT PTSTR tszStr) { PTSTR tszAux;
__ASSERT((tszMultiStr != NULL) && (tszStr != NULL));
tszAux = tszMultiStr; while (*tszAux != TEXT('\0')) { _tcscpy(tszStr, tszAux); //
// Replace the '\0' with ' ' and terminate correctly Str
//
tszStr[tszAux - tszMultiStr + _tcslen(tszAux)] = TEXT(' '); tszStr[tszAux - tszMultiStr + _tcslen(tszAux) + 1] = TEXT('\0'); tszAux += _tcslen(tszAux) + 1; } //
// End properly Str (the last ' ' is useless)
//
tszStr[tszAux - tszMultiStr + _tcslen(tszAux)] = TEXT('\0');
return;
} // MultiStringToString //
/*++
Routine Description:
Calculates the size of a multi string (we can't use _tcslen). Note that the size is in BYTES Arguments:
tszMultiStr - the multi string.
Return Value:
The length (in bytes) of the multi string.
--*/ INT MultiStringSize(IN PTSTR tszMultiStr) { PTSTR tszAux; UINT uiLength = 0;
__ASSERT(tszMultiStr != NULL);
tszAux = tszMultiStr;
while (*tszAux != TEXT('\0')) { //
// We should count the '\0' after the string
//
uiLength += _tcslen(tszAux) + 1; tszAux += _tcslen(tszAux) + 1; } //
// We didn't count the ending '\0', so add it now
//
return ((uiLength + 1) * sizeof(TCHAR));
} // MultiStringSize //
/*++
Routine Description:
Copies a multistring.
Arguments:
tszMultiStrDestination: the destination multi string. tszMultiStrSource: the source multi string.
Return Value:
None.
--*/ VOID CopyMultiString(OUT PTSTR tszMultiStrDestination, IN PTSTR tszMultiStrSource) { UINT uiCount = 0; PTSTR tszAuxS, tszAuxD;
__ASSERT((tszMultiStrSource != NULL) && (tszMultiStrDestination != NULL));
tszAuxS = tszMultiStrSource; tszAuxD = tszMultiStrDestination;
//
// Copies the multi string
//
while (*tszAuxS != TEXT('\0')) { _tcscpy(tszAuxD, tszAuxS); tszAuxD += _tcslen(tszAuxD) + 1; tszAuxS += _tcslen(tszAuxS) + 1; } //
// Add the terminating NULL
//
*tszAuxD = TEXT('\0');
return;
} // CopyMultiString //
/*++
Routine Description: InitGlobals
Initializes global variables
Arguments:
none
Return Value:
void
--*/ VOID InitGlobals() { g_bUsePrivateFunctions = FALSE; g_bFirstTime = TRUE; g_uiCurrentPage = 0; g_bAccessViolation = FALSE; g_bTestExtended = FALSE; nStepsFinal = NO_STEPS_FINAL; g_bNoWizPage = FALSE; g_bCrashUnicode = FALSE; g_bInvalidBitmap = FALSE; g_bHugeSize = FALSE; g_bCloseInf = FALSE; hInfGlobal = NULL; g_bNoNeedMedia = TRUE;
g_bCleanReg = FALSE;
g_uiFunctionToAV = 32574;
g_bNoLangSupport = FALSE;
g_bReboot = FALSE; } // InitGlobals //
|