Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

464 lines
12 KiB

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <setupapi.h>
#include <crt\string.h>
#include <sputils.h>
#include <tchar.h>
/*
============================================================================
Compute the disk space requirements for all OC components.
============================================================================
*/
//
// String Macros
//
#define AS(x) ( sizeof(x) / sizeof(x[0]) )
#define LSTRCPY(x,y) ( lstrcpyn(x, y, AS(x)) )
#define LSTRCAT(x,y) ( lstrcpyn(x + lstrlen(x), y, AS(x) - lstrlen(x)) )
//
// Handle to the inf we're operating on.
//
HINF hInputinf;
HINF hLayoutinf;
//
// Initialize input parameters.
//
BOOL Verbose = FALSE;
TCHAR InfPath[MAX_PATH];
PCWSTR InputInf = NULL;
PCWSTR LayoutPath = NULL;
//
// backward-compatible SetupGetInfSections
//
#undef SetupGetInfSections
BOOL
SetupGetInfSections (
IN HINF InfHandle,
OUT PTSTR Buffer, OPTIONAL
IN UINT Size, OPTIONAL
OUT UINT *SizeNeeded OPTIONAL
);
//
// ============================================================================
//
// Find out what the user wants us to do.
//
// ============================================================================
//
BOOL GetParams(
int argc,
char *argv[ ]
)
{
char *p;
int i;
PTSTR tstr_ptr = NULL;
for( i = 0; i < argc; i++ ) {
if( *argv[i] == '-' ) {
p = argv[i];
//
// Verbose?
//
if( !_strcmpi( p, "-v" ) ) {
Verbose = TRUE;
continue;
}
//
// Inf file?
//
if( !_strnicmp( p, "-inf:", 5 ) ) {
p = p + 5;
InputInf = pSetupAnsiToUnicode(p);
//
// Now extract the path for this inf.
//
lstrcpy( InfPath, InputInf );
tstr_ptr = wcsrchr( InfPath, TEXT( '\\' ) );
if( tstr_ptr ) {
*tstr_ptr = 0;
}
continue;
}
//
// Files location location?
//
if( !_strnicmp( p, "-layout:", 8 ) ) {
p = p + 8;
LayoutPath = pSetupAnsiToUnicode(p);
continue;
}
}
}
//
// Check Params.
//
if( InfPath == NULL ) {
return FALSE;
}
if( LayoutPath == NULL ) {
return FALSE;
}
return TRUE;
}
//
// ============================================================================
//
// Tell the user how to use us.
//
// ============================================================================
//
void Usage( )
{
printf( "Compute disk space requirements for files listed in an inf\n" );
printf( "\n" );
printf( "\n" );
printf( " -inf:<path> This is the path to the inf (including the\n" );
printf( " inf file name). E.g. -inf:c:\\dosnet.inf\n" );
printf( "\n" );
printf( " -layout:<path> This is the path to layout.inf (including the\n" );
printf( " inf file name). E.g. -inf:c:\\layout.inf\n" );
printf( "\n" );
printf( " -v Run in verbose mode.\n" );
printf( "\n" );
printf( "\n" );
}
//
// ============================================================================
//
// Process a single section in the inf.
//
// ============================================================================
//
VOID
ProcessInf(
HINF hInputinf,
PTSTR TargetInfPath
)
/*
Process the inf. Look at each section and ask SetupApi to give us the
disk space requirements for installing this section. If we get input
back from setupapi, then update the SizeApproximation entry in this
section.
*/
{
DWORD SizeNeeded = 0;
PTSTR Sections,CurrentSection;
HDSKSPC hDiskSpace;
BOOL b;
TCHAR CurrentDrive[MAX_PATH];
LONGLONG SpaceRequired;
DWORD dwError;
//
// get a list of all the sections in this inf.
//
if( !SetupGetInfSections(hInputinf, NULL, 0, &SizeNeeded) ) {
fprintf( stderr, "Unable to get section names, ec=0x%08x\n", GetLastError());
return;
}
if( SizeNeeded == 0 ) {
fprintf( stderr, "There are no sections in this file.\n");
return;
}
Sections = pSetupMalloc (SizeNeeded + 1);
if (!Sections) {
fprintf( stderr, "Unable to allocate memory, ec=0x%08x\n", GetLastError());
return;
}
if(!SetupGetInfSections(hInputinf, Sections, SizeNeeded, NULL) ) {
fprintf( stderr, "Unable to get section names, ec=0x%08x\n", GetLastError());
return;
}
if( Verbose ) {
fprintf( stderr, "\nProcessing inf file: %ws.\n", TargetInfPath );
}
//
// Now process each section.
//
CurrentSection = Sections;
while( *CurrentSection ) {
if( Verbose ) {
fprintf( stderr, "\tProcessing Section: %ws.\n", CurrentSection );
}
//
// Get a diskspace structure.
//
hDiskSpace = SetupCreateDiskSpaceList( NULL, 0, SPDSL_IGNORE_DISK );
if( !hDiskSpace ) {
fprintf( stderr, "\t\tUnable to allocate a DiskSpace structure. ec=0x%08x\n", GetLastError());
continue;
}
b = SetupAddInstallSectionToDiskSpaceList( hDiskSpace,
hInputinf,
hLayoutinf,
CurrentSection,
0,
0 );
if( b ) {
//
// There must have been a copyfile section and we got some info.
//
//
// Figure out which drive we're running on. we're going to
// assume that this disk has a reasonable cluster-size and just
// use it.
//
if( !GetWindowsDirectory( CurrentDrive, MAX_PATH ) ) {
fprintf( stderr, "\t\tUnable to retrieve current directory. ec=0x%08x\n", GetLastError());
continue;
}
CurrentDrive[2] = 0;
if( Verbose ) {
fprintf( stderr, "\t\tChecking space requirements on drive %ws.\n", CurrentDrive );
}
//
// Now query the disk space requirements against this drive.
//
SpaceRequired = 0;
b = SetupQuerySpaceRequiredOnDrive( hDiskSpace,
CurrentDrive,
&SpaceRequired,
NULL,
0 );
if( !b ) {
//
// This probably happened because there was no CopyFiles section.
//
dwError = GetLastError();
if( dwError != ERROR_INVALID_DRIVE ) {
fprintf( stderr, "\t\tUnable to query space requirements. ec=0x%08x\n", GetLastError());
} else {
if( Verbose ) {
fprintf( stderr, "\t\tI don't think this section has a CopyFiles entry.\n");
}
}
}
//
// We got the space requirements. now all we have to do is spew them into the inf.
//
if( Verbose ) {
fprintf( stderr, "\t\tRequired space: %I64d\n", SpaceRequired );
}
if( SpaceRequired > 0 ) {
swprintf( CurrentDrive, TEXT("%I64d"), SpaceRequired );
b = WritePrivateProfileString( CurrentSection,
TEXT("SizeApproximation"),
CurrentDrive,
TargetInfPath );
if( !b ) {
fprintf( stderr, "\t\tUnable to write space requirements to %ws. ec=0x%08x\n", InfPath, GetLastError());
continue;
}
}
}
//
// Free that diskspace structure.
//
SetupDestroyDiskSpaceList( hDiskSpace );
CurrentSection += lstrlen(CurrentSection) + 1;
}
pSetupFree( Sections );
}
int
__cdecl
main( int argc, char *argv[ ], char *envp[ ] )
{
INFCONTEXT InputContext;
LONG i, LineCount;
BOOL b;
TCHAR TargetInfPath[MAX_PATH];
TCHAR FileName[MAX_INF_STRING_LENGTH];
HINF hTargetInf;
int Result = 1;
//
// Check Params.
//
if(!pSetupInitializeUtils()) {
fprintf( stderr, "Initialization failed\n" );
return 1;
}
if( !GetParams( argc, argv ) ) {
Usage();
Result = 1;
goto cleanup;
}
//
// Open the inf file.
//
hInputinf = SetupOpenInfFileW( InputInf, NULL, INF_STYLE_WIN4, NULL );
if( hInputinf == INVALID_HANDLE_VALUE ) {
if( Verbose ) {
fprintf( stderr, "The file %ws was not opened!\n", InputInf );
}
Result = 1;
goto cleanup;
}
//
// Open the specified layout.inf file.
//
hLayoutinf = SetupOpenInfFileW( LayoutPath, NULL, INF_STYLE_WIN4, NULL );
if( hLayoutinf == INVALID_HANDLE_VALUE ) {
if( Verbose ) {
fprintf( stderr, "The file %ws was not opened!\n", LayoutPath );
}
Result = 1;
goto cleanup;
}
//
// Now loop through all the entries in the "components"
// section and process their infs.
//
LineCount = SetupGetLineCount( hInputinf,
TEXT("Components") );
for( i = 0; i < LineCount; i++ ) {
//
// Get this line.
//
b = SetupGetLineByIndex( hInputinf,
TEXT("Components"),
i,
&InputContext );
if( b ) {
//
// got it. Get the inf name for this component (there
// may not be one).
//
if(SetupGetStringField(&InputContext, 3,FileName,MAX_INF_STRING_LENGTH,NULL) &&
FileName[0] != TEXT('\0')) {
//
// Yep, there's an inf that we need to look at.
// Build a path to it and open a handle to it.
//
LSTRCPY( TargetInfPath, InfPath );
LSTRCAT( TargetInfPath, TEXT("\\") );
LSTRCAT( TargetInfPath, FileName );
hTargetInf = SetupOpenInfFileW( TargetInfPath, NULL, INF_STYLE_WIN4, NULL );
if( hTargetInf == INVALID_HANDLE_VALUE ) {
if( Verbose ) {
fprintf( stderr, "The file %ws was not opened!\n", TargetInfPath );
}
continue;
}
//
// Now process it.
//
ProcessInf( hTargetInf, TargetInfPath );
} else {
//
// There must not have been an inf in this
// line.
//
if( Verbose ) {
fprintf( stderr, "I didn't find an inf entry on this line.\n");
}
}
}
}
SetupCloseInfFile( hInputinf );
SetupCloseInfFile( hLayoutinf );
Result = 0;
cleanup:
pSetupUninitializeUtils();
return Result;
}