932 lines
29 KiB
C++
932 lines
29 KiB
C++
/******************************************************************************
|
||
* Temp conversion utility to take registry entries and populate the class store with those entries.
|
||
*****************************************************************************/
|
||
|
||
/******************************************************************************
|
||
includes
|
||
******************************************************************************/
|
||
#include "precomp.hxx"
|
||
|
||
/******************************************************************************
|
||
defines and prototypes
|
||
******************************************************************************/
|
||
|
||
extern CLSID CLSID_ClassStore;
|
||
extern const IID IID_IClassStore;
|
||
extern const IID IID_IClassAdmin;
|
||
|
||
LONG
|
||
UpdateClassEntryFromAutoConvert(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry );
|
||
LONG
|
||
UpdateClassEntryFromTreatAs(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry );
|
||
LONG
|
||
UpdateClassEntryFromServerType(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry );
|
||
LONG
|
||
UpdateClassEntryFromTypelib(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry );
|
||
|
||
LONG
|
||
UpdateClassEntryFromAppID(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry,
|
||
char * pAppidBuffer );
|
||
|
||
ULONG
|
||
GeneratePackageDetails(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
PACKAGEDETAIL * pPackageDetails );
|
||
|
||
ULONG
|
||
UpdateClassEntryFromServerType(
|
||
MESSAGE * pMessage,
|
||
APP_ENTRY * pAppEntry,
|
||
BasicRegistry * pCLSID );
|
||
|
||
ULONG
|
||
PackageFromServerType(
|
||
MESSAGE * pMessage,
|
||
DWORD Context,
|
||
APP_ENTRY * pAppEntry,
|
||
BasicRegistry * pServerTypeKey,
|
||
BasicRegistry * pCLSID );
|
||
|
||
ULONG
|
||
UpdateClassEntryFromServerType(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
APP_ENTRY * pAppEntry );
|
||
|
||
LONG
|
||
UpdatePackageFromClsid(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
char * pClsidString,
|
||
char * pAppid );
|
||
|
||
LONG
|
||
UpdatePackage(
|
||
MESSAGE * pMessage,
|
||
BOOL fUsageFlag,
|
||
DWORD Context,
|
||
char * pClsidString,
|
||
char * pAppid,
|
||
char * ServerName,
|
||
DWORD * pMajorVersion,
|
||
DWORD * pMinorVersion,
|
||
DWORD * pLocale );
|
||
|
||
|
||
CLASSPATHTYPE
|
||
GetPathType(
|
||
char * pExtension );
|
||
|
||
LPOLESTR
|
||
GetPath(
|
||
char * pPath );
|
||
|
||
LPOLESTR
|
||
GetSetupCommand(
|
||
char * pName );
|
||
|
||
LPOLESTR
|
||
MakePackageName(
|
||
char * pName );
|
||
|
||
void
|
||
|
||
SetCSPlatform( CSPLATFORM * pCSPlatform );
|
||
|
||
/******************************************************************************
|
||
Globals
|
||
******************************************************************************/
|
||
extern char * MapDriveToServerName[ 26 ];
|
||
|
||
|
||
LONG
|
||
UpdateDatabaseFromCLSID(
|
||
MESSAGE * pMessage )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Update the internal database from clsid entries under the root key
|
||
specified by the message.
|
||
In Arguments:
|
||
Message - A message block that contains the root of the key that has
|
||
class id etc related information.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
A Win32 error code specifying success or the kind of failure.
|
||
Remarks:
|
||
The routine only returns an error code of ERROR_NO_MORE_ITEMS.
|
||
*****************************************************************************/
|
||
{
|
||
BasicRegistry * pHKCR = new BasicRegistry( pMessage->hRoot ); // HKCR
|
||
BasicRegistry * pCLSIDUnderHKCR;
|
||
CLSDICT * pClsDict = pMessage->pClsDict;
|
||
BOOL fNewEntry = 0;
|
||
int Index;
|
||
LONG CLSIDError = ERROR_SUCCESS;
|
||
CLASS_ENTRY * pClassEntry;
|
||
|
||
//
|
||
// Get the first clsid key under HKCR
|
||
//
|
||
|
||
if ( pHKCR->Find( "CLSID", &pCLSIDUnderHKCR ) != ERROR_SUCCESS )
|
||
return ERROR_NO_MORE_ITEMS;
|
||
|
||
|
||
//
|
||
// Go thru all the subkeys under CLSID and get the details under the keys.
|
||
//
|
||
|
||
for ( Index = 0, fNewEntry = 0;
|
||
CLSIDError != ERROR_NO_MORE_ITEMS;
|
||
++Index )
|
||
{
|
||
char CLSIDBuffer[256];
|
||
DWORD SizeOfCLSIDBuffer = sizeof(CLSIDBuffer)/sizeof(char);
|
||
char AppidBuffer[ 256 ];
|
||
BasicRegistry * pCLSID;
|
||
|
||
|
||
//
|
||
// Get the name of the key - the next one under HKCRCLSID that
|
||
// matches our time stamp criteria.
|
||
//
|
||
|
||
CLSIDError = pCLSIDUnderHKCR->NextKey(
|
||
CLSIDBuffer,
|
||
&SizeOfCLSIDBuffer,
|
||
&pCLSID,
|
||
pMessage->ftLow,
|
||
pMessage->ftHigh);
|
||
|
||
if ( (CLSIDError == ERROR_SUCCESS ) &&
|
||
(CLSIDBuffer[0] == '{') )
|
||
{
|
||
|
||
//
|
||
// We got a valid classid entry. See if it is in the database
|
||
// already, if not make a new entry and update that with the
|
||
// classid related details.
|
||
//
|
||
|
||
char * pT = new char [SizeOfCLSIDBuffer+1];
|
||
strcpy( pT, CLSIDBuffer );
|
||
|
||
if ( (pClassEntry = pClsDict->Search( CLSIDBuffer ) ) == 0 )
|
||
{
|
||
pClassEntry = new CLASS_ENTRY;
|
||
fNewEntry = 1;
|
||
}
|
||
|
||
memcpy( pClassEntry->ClsidString,
|
||
&CLSIDBuffer,
|
||
SIZEOF_STRINGIZED_CLSID );
|
||
|
||
//
|
||
// Update class entry from subkeys.
|
||
//
|
||
|
||
// update frm "autoconvert" value. ignore error, since optional.
|
||
|
||
UpdateClassEntryFromAutoConvert( pMessage, pCLSID, pClassEntry );
|
||
|
||
// update frm "treatas" value. ignore error, since optional.
|
||
|
||
UpdateClassEntryFromTreatAs( pMessage, pCLSID, pClassEntry );
|
||
|
||
//
|
||
// Update from clsid. Although this is optional, the appid setting
|
||
// is important in that it determines if a classid falls under an
|
||
// appid that is supported by a package or if it is a clsid that
|
||
// does not have an appid. A package can have both - clsids
|
||
// which have appids or those that dont.
|
||
//
|
||
|
||
BOOL fAdded = FALSE;
|
||
|
||
// Check if this class id has an app id.
|
||
|
||
if ( UpdateClassEntryFromAppID( pMessage,
|
||
pCLSID,
|
||
pClassEntry,
|
||
&AppidBuffer[0] ) )
|
||
{
|
||
|
||
// yes this classid has an appid, so enter into the app detail
|
||
// structure corresponding to the appid.
|
||
|
||
fAdded = UpdatePackageFromClsid( pMessage, pCLSID, pT, &AppidBuffer[0] );
|
||
}
|
||
else
|
||
{
|
||
|
||
// no, this classid does not have an appid associated, so
|
||
// enter this into the null appid group.
|
||
|
||
fAdded = UpdatePackageFromClsid( pMessage, pCLSID, pT, 0 );
|
||
}
|
||
|
||
if ( fNewEntry && fAdded)
|
||
pClsDict->Insert( pClassEntry );
|
||
}
|
||
else if ( CLSIDError == ERROR_SUCCESS )
|
||
{
|
||
delete pCLSID;
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// delete the CLSID key under HKCR
|
||
//
|
||
|
||
delete pCLSIDUnderHKCR;
|
||
|
||
if ( CLSIDError == ERROR_NO_MORE_ITEMS )
|
||
return ERROR_SUCCESS;
|
||
|
||
|
||
return ERROR_SUCCESS;
|
||
}
|
||
|
||
LONG
|
||
UpdatePackageFromClsid(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
char * pClsidString,
|
||
char * pAppid )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
To update package details from package id.
|
||
In Arguments:
|
||
pMessage - Message block passing info between modules.
|
||
pCLSID - An open Key to the registry for the specified clsid.
|
||
pClsidString- A stringized clsid used for entring into appid database.
|
||
pAppid - Stringized appid to enter into the package database.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
Status. 1 - need to add CLSID, 0 - don't need to add CLSID
|
||
Remarks:
|
||
A package is a collection of individual executables. Under the CLSID key
|
||
in a registry can be a number of packages: inproc handlers, inproc
|
||
servers and local and remote servers. Each of these qualify as
|
||
individual packages unless packaged in say a cab file. That overall
|
||
packaging is specified by the package path field in the message.
|
||
Therefore this routine goes thru all individual packages as specified
|
||
under the CLSID key and attempts to generate packages for them. The
|
||
Update package routine then decides what the package type is based on
|
||
whether the message field has a package path specified. It is very
|
||
possible (and happens for .Cab files) for CLSID entries of local server
|
||
inproc handler etc to end up in one package
|
||
|
||
*****************************************************************************/
|
||
{
|
||
// class context mapping array.
|
||
|
||
static DWORD ClassContextArray[] =
|
||
{
|
||
CLSCTX_INPROC_HANDLER,
|
||
CLSCTX_INPROC_SERVER,
|
||
CLSCTX_LOCAL_SERVER,
|
||
CLSCTX_REMOTE_SERVER
|
||
// BUGBUG - what about the 16-bit cases?
|
||
// ,
|
||
// CLSCTX_INPROC_SERVER16,
|
||
// CLSCTX_LOCAL_SERVER,
|
||
// CLSCTX_INPROC_HANDLER16
|
||
};
|
||
|
||
// Keys that map to a class context.
|
||
// Must have same number of elements as ClassContextArray.
|
||
|
||
static char * pKeyNamesArray[] =
|
||
{
|
||
"InprocHandler32",
|
||
"InprocServer32",
|
||
"LocalServer32",
|
||
"RemoteServer32"
|
||
// ,
|
||
// "InprocServer",
|
||
// "LocalServer",
|
||
// "InprocHandler"
|
||
};
|
||
|
||
LONG lReturn = 0;
|
||
|
||
int Index;
|
||
|
||
for ( Index = 0;
|
||
Index < sizeof(pKeyNamesArray) / sizeof(pKeyNamesArray[0]) ;
|
||
Index++ )
|
||
{
|
||
// Search for all the server types under the CLSID. If available, create
|
||
// packages for those server types.
|
||
|
||
BasicRegistry * pServerTypeKey;
|
||
LONG E;
|
||
|
||
// check if a potential package of the type specified exists in the
|
||
// registry. In other words, check if one of the above specified keys
|
||
// exists under the clsid key.
|
||
//
|
||
|
||
E = pCLSID->Find( pKeyNamesArray[ Index ], &pServerTypeKey );
|
||
|
||
if ( E == ERROR_SUCCESS )
|
||
{
|
||
|
||
//
|
||
// Yes, a key for the specified server type exists.
|
||
// Get its named value. Based on this we will attempt to enter
|
||
// a new package in our database.
|
||
//
|
||
|
||
char ServerName[_MAX_PATH];
|
||
DWORD ServerNameLength;
|
||
|
||
ServerNameLength = sizeof( ServerName) / sizeof( char );
|
||
|
||
E = pServerTypeKey->QueryValueEx( 0,
|
||
&ServerName[0],
|
||
&ServerNameLength );
|
||
|
||
//
|
||
// A server name may have a switch specified for execution. That
|
||
// is not significant for our class store update, but is significant
|
||
// in that it should not be part of the server name to enter into
|
||
// the class store. Make sure we ignore it.
|
||
//
|
||
|
||
if ( E == ERROR_SUCCESS )
|
||
{
|
||
// remove any '/' switch characters, so we dont get confused.
|
||
|
||
char * p = strchr( &ServerName[0], '/' );
|
||
|
||
if ( p )
|
||
{
|
||
while ( *(--p) == ' ' );
|
||
*(p+1) = '\0';
|
||
}
|
||
|
||
//
|
||
// call common routine to update package from clsid and appid
|
||
// details.
|
||
//
|
||
|
||
UpdatePackage( pMessage,
|
||
0, // clsid update - not a typelib id update
|
||
ClassContextArray[ Index ],
|
||
pClsidString,
|
||
pAppid,
|
||
&ServerName[0],
|
||
0,
|
||
0,
|
||
0 );
|
||
|
||
}
|
||
else
|
||
{
|
||
// It is possible that the tag may not have a name, in
|
||
// which case we need to create a package entry using the
|
||
// original package path.
|
||
UpdatePackage( pMessage,
|
||
0, // clsid update
|
||
ClassContextArray[ Index ],
|
||
pClsidString,
|
||
pAppid,
|
||
pMessage->pPackagePath,
|
||
0,
|
||
0,
|
||
0 );
|
||
}
|
||
delete pServerTypeKey;
|
||
// We've found one entry and that's enough to get everything we
|
||
// need to know to be able to populate the class store so we're
|
||
// going to break out of the for loop here.
|
||
// BUGBUG - For beta 2 we need to simplify this code so that we
|
||
// don't even bother looking for this. Most of this code
|
||
// is here to support features that the class store was going to
|
||
// have once upon a time. Since then, the class store has been
|
||
// redesigned and we really don't need all of this junk.
|
||
lReturn = 1;
|
||
break;
|
||
}
|
||
|
||
}
|
||
return lReturn;
|
||
}
|
||
|
||
LONG
|
||
UpdatePackage(
|
||
MESSAGE * pMessage,
|
||
BOOL fUsage,
|
||
DWORD Context,
|
||
char * pClsidString,
|
||
char * pAppid,
|
||
char * ServerName,
|
||
DWORD * pMajor,
|
||
DWORD * pMinor,
|
||
LCID * pLocale )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Update package details in database based on clsid and appid.
|
||
In Arguments:
|
||
pMessage - Message block passing arguments between modules.
|
||
fUsageFlag - 0 if clsid is being updated in appid list or 1 if a
|
||
typelib is being updated in appid list.
|
||
pClsidString- A stringized clsid/typelibid used for entring into
|
||
appid database.
|
||
pAppid - Stringized appid to enter into the package database.
|
||
ServerName - String used to identify the original server name.
|
||
pMajor - Major version number
|
||
pMinor - Minor version number
|
||
pLocale - locale.
|
||
Out Arguments:
|
||
InOut Arguments:
|
||
Return Arguments:
|
||
Remarks:
|
||
Version#s and locale info are pointers. This routine is used by typelib
|
||
update routine also. They usually have version and locale info, but
|
||
general packages do not. Therefore the routine has pointers to indicate
|
||
if info is available and if so, update it.
|
||
|
||
If the message has a package path, it indicates that the server
|
||
supporting the classid is part of that package. So the package path
|
||
determines the package type etc and overrides any server names specified
|
||
in the CLSID key
|
||
|
||
We are also making an assumption that there is no appid associated with
|
||
a typelib, so we can asssume that all typelib entries go to the null
|
||
appid list only. If this changes, then use the AddTypelib method in
|
||
APP_ENTRY to update the app entry.
|
||
|
||
|
||
THIS ROUTINE NEEDS CLEANUP - IT IS A HACK AFTER HACK AFTER HACK
|
||
*****************************************************************************/
|
||
{
|
||
PDICT * pPackageDict = pMessage->pPackageDict;
|
||
PACKAGE_ENTRY * pPackageEntry;
|
||
char Name[ _MAX_FNAME ];
|
||
char Ext[ _MAX_EXT ];
|
||
char PackageName[ _MAX_PATH ];
|
||
PACKAGEDETAIL PackageDetails;
|
||
LONG Error = 0;
|
||
APP_ENTRY * pAppEntry;
|
||
char * p;
|
||
CSPLATFORM CSPlatform;
|
||
SetCSPlatform( &CSPlatform);
|
||
|
||
|
||
// clear the package details structure.
|
||
|
||
memset(&PackageDetails, '\0', sizeof( PackageDetails ));
|
||
|
||
|
||
//
|
||
// If package path exists, then the extension etc determine the package
|
||
// type. If not, the server name (localserver/handler name etc) determines
|
||
// the package type.
|
||
//
|
||
|
||
|
||
if ( p = pMessage->pPackagePath )
|
||
{
|
||
_splitpath( pMessage->pPackagePath, NULL, NULL, Name, Ext );
|
||
}
|
||
else
|
||
{
|
||
p = ServerName;
|
||
_splitpath( ServerName, NULL, NULL, Name, Ext );
|
||
}
|
||
|
||
if (pMessage->pPackageName)
|
||
{
|
||
strcpy(PackageName, pMessage->pPackageName);
|
||
}
|
||
else
|
||
{
|
||
strcpy( PackageName, Name );
|
||
strcat( PackageName, Ext );
|
||
pMessage->pPackageName = new char[strlen(PackageName)+1];
|
||
strcpy(pMessage->pPackageName, PackageName);
|
||
}
|
||
|
||
|
||
// Check if we already have the package name in the dictionary.
|
||
|
||
pPackageEntry = pPackageDict->Search( &PackageName[0], Context );
|
||
|
||
// if we do not, make a new package entry.
|
||
|
||
if (!pPackageEntry)
|
||
{
|
||
pPackageEntry = new PACKAGE_ENTRY;
|
||
strcpy( &pPackageEntry->PackageName[0], &PackageName[0] );
|
||
|
||
PackageDetails.dwContext =( pMessage->pPackagePath )
|
||
? CLSCTX_INPROC_SERVER + CLSCTX_LOCAL_SERVER :
|
||
Context; // Context temp workaround
|
||
if ( pMessage->fPathTypeKnown )
|
||
PackageDetails.PathType = pMessage->PathType;
|
||
else
|
||
PackageDetails.PathType = GetPathType( &Ext[0] );
|
||
|
||
if ( (pMessage->pAuxPath) && (PackageDetails.PathType == DrwFilePath))
|
||
PackageDetails.pszPath = GetPath( pMessage->pAuxPath );
|
||
else
|
||
PackageDetails.pszPath = GetPath( p );
|
||
|
||
PackageDetails.pszIconPath = GetPath( p );
|
||
if ( pMessage->pSetupCommand )
|
||
PackageDetails.pszSetupCommand = GetPath( pMessage->pSetupCommand );
|
||
PackageDetails.dwActFlags = pMessage->ActFlags;
|
||
PackageDetails.pszPackageName = MakePackageName( &PackageName[0] );
|
||
PackageDetails.pszProductName = MakePackageName( &Name[0] );
|
||
|
||
PackageDetails.Platform = CSPlatform;
|
||
|
||
if (pLocale )
|
||
PackageDetails.Locale = *pLocale;
|
||
else
|
||
PackageDetails.Locale =
|
||
MAKELCID(
|
||
MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
|
||
SORT_DEFAULT );
|
||
|
||
if ( pMajor )
|
||
PackageDetails.dwVersionHi = *pMajor;
|
||
else
|
||
PackageDetails.dwVersionHi = 0;
|
||
if ( pMinor )
|
||
PackageDetails.dwVersionLo = *pMinor;
|
||
else
|
||
PackageDetails.dwVersionLo = 0;
|
||
|
||
PackageDetails.cApps = 0;
|
||
PackageDetails.pAppDetail = 0;
|
||
|
||
|
||
|
||
// set the package details.
|
||
|
||
pPackageEntry->SetPackageDetail( &PackageDetails );
|
||
|
||
|
||
// store the original name so that we can dump it.
|
||
|
||
pPackageEntry->SetOriginalName( ServerName );
|
||
|
||
|
||
// Add this into the package dictionary.
|
||
|
||
pMessage->pPackageDict->Insert( pPackageEntry );
|
||
|
||
}
|
||
|
||
|
||
// search for the app entry. The class entry needs to be entered
|
||
// there. If there is no app id specified (appentry is null )
|
||
// get the app entry whose ID is 0. All classes that do not have
|
||
// an app id specified, will go into this bucket. Finally we will
|
||
// assign an appid to it and enter into the class store.
|
||
|
||
if ( !pAppid )
|
||
{
|
||
// There is no appid. Enter the clsid entry in the null appid.
|
||
|
||
if ( fUsage == 0 )
|
||
pPackageEntry->AddClsidToNullAppid( pClsidString );
|
||
else
|
||
pPackageEntry->AddTypelibToNullAppid( pClsidString );
|
||
}
|
||
else
|
||
{
|
||
pAppEntry = pPackageEntry->SearchAppEntry( pAppid );
|
||
if ( !pAppEntry )
|
||
{
|
||
pAppEntry = new APP_ENTRY;
|
||
pAppEntry->SetAppIDString( pAppid );
|
||
pPackageEntry->AddAppEntry( pAppEntry );
|
||
}
|
||
pAppEntry->AddClsid( pClsidString );
|
||
|
||
|
||
}
|
||
|
||
return 0;
|
||
|
||
|
||
}
|
||
|
||
CLASSPATHTYPE
|
||
GetPathType(
|
||
char * pExt )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Map the file extension to CLASSPATHTYPE
|
||
In:
|
||
pExt - File Extension to map
|
||
Out:
|
||
None.
|
||
InOut:
|
||
None.
|
||
Return:
|
||
CLASSPATHTYPE of the file extension.
|
||
Remarks:
|
||
olb is apparently an extension that implies "old type library"-whatever
|
||
that is.
|
||
If no standard mapping is found, a CLASSPATHTYPE of ExeNamePath is
|
||
returned.
|
||
*****************************************************************************/
|
||
{
|
||
// extensions to map.
|
||
|
||
static char * ExtArray[] =
|
||
{ ".dll",
|
||
".exe",
|
||
".cab",
|
||
".tlb",
|
||
".inf",
|
||
".olb"
|
||
};
|
||
|
||
// CLASSPATHTYPEs to map the extensions to.
|
||
|
||
static CLASSPATHTYPE PathType[] =
|
||
{
|
||
DllNamePath,
|
||
ExeNamePath,
|
||
CabFilePath,
|
||
TlbNamePath,
|
||
InfFilePath,
|
||
TlbNamePath
|
||
};
|
||
|
||
int index;
|
||
int fFound = -1;
|
||
|
||
|
||
for ( index = 0;
|
||
index < sizeof( ExtArray ) / sizeof( char * );
|
||
++index )
|
||
{
|
||
if ( _stricmp( pExt, ExtArray[index] ) == 0 )
|
||
{
|
||
fFound = index;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( fFound != -1 )
|
||
{
|
||
return PathType[ index ];
|
||
}
|
||
else
|
||
return ExeNamePath;
|
||
|
||
}
|
||
|
||
LPOLESTR
|
||
GetPath(
|
||
char * pPath )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Map a char * path to a wide character path
|
||
In Arguments:
|
||
pPath - Path to the file to translate to wide char.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
The translated file path.
|
||
Remarks:
|
||
*****************************************************************************/
|
||
{
|
||
if ( pPath )
|
||
{
|
||
LPOLESTR p = new OLECHAR[ (MAX_PATH+1) * 2 ];
|
||
mbstowcs( p, pPath, strlen(pPath)+1 );
|
||
return p;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
LPOLESTR
|
||
GetSetupCommand(
|
||
char * pSetupCommandLine )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Translate setup command line to wide char.
|
||
In Arguments:
|
||
Setup command line.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
The translated setup command line.
|
||
Remarks:
|
||
For now the setup command line is setup.exe
|
||
*****************************************************************************/
|
||
{
|
||
LPOLESTR p = new OLECHAR[ (MAX_PATH+1) * 2 ];
|
||
mbstowcs( p, "setup.exe", strlen("setup.exe")+1 );
|
||
return p;
|
||
}
|
||
|
||
|
||
LPOLESTR
|
||
MakePackageName(
|
||
char * pName )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Translate package name to wide char.
|
||
In Arguments:
|
||
package name to translate.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
translated command line
|
||
Remarks:
|
||
*****************************************************************************/
|
||
{
|
||
LPOLESTR p = new OLECHAR[ (MAX_PATH+1) * 2 ];
|
||
mbstowcs( p, pName, strlen(pName)+1 );
|
||
return p;
|
||
|
||
}
|
||
|
||
LONG
|
||
UpdateClassEntryFromAutoConvert(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Update the classid entry in the data base with the autoconvert field.
|
||
In Arguments:
|
||
pMessage - Message block passing arguments between modules.
|
||
pCLSID - pointer to class representing the registry key.
|
||
pClassEntry - The class entry data structure to update.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
Status.
|
||
Remarks:
|
||
*****************************************************************************/
|
||
{
|
||
LONG error;
|
||
char Data[SIZEOF_STRINGIZED_CLSID];
|
||
DWORD SizeOfData = sizeof(Data)/sizeof(char);
|
||
|
||
error = pCLSID->QueryValue( "AutoConvertTo", &Data[0], &SizeOfData );
|
||
|
||
if ( error == ERROR_SUCCESS )
|
||
{
|
||
StringToCLSID(
|
||
&Data[1],
|
||
&pClassEntry->ClassAssociation.AutoConvertClsid );
|
||
}
|
||
return error;
|
||
}
|
||
|
||
LONG
|
||
UpdateClassEntryFromTreatAs(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Update the class entry in the database with the Treatas key.
|
||
In Arguments:
|
||
pMessage - Message block passing arguments between modules.
|
||
pCLSID - pointer to class representing the registry key.
|
||
pClassEntry - The class entry data structure to update.
|
||
Out Arguments:
|
||
None.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
Status.
|
||
Remarks:
|
||
*****************************************************************************/
|
||
{
|
||
LONG error;
|
||
char Data[SIZEOF_STRINGIZED_CLSID];
|
||
DWORD SizeOfData = sizeof(Data)/sizeof(char);
|
||
|
||
error = pCLSID->QueryValue( "TreatAs", &Data[0], &SizeOfData );
|
||
if ( error == ERROR_SUCCESS )
|
||
{
|
||
StringToCLSID(
|
||
&Data[1],
|
||
&pClassEntry->ClassAssociation.TreatAsClsid );
|
||
}
|
||
return error;
|
||
}
|
||
|
||
LONG
|
||
UpdateClassEntryFromAppID(
|
||
MESSAGE * pMessage,
|
||
BasicRegistry * pCLSID,
|
||
CLASS_ENTRY * pClassEntry,
|
||
char * pAppidBuffer )
|
||
/*****************************************************************************
|
||
Purpose:
|
||
Update the class entry in the database with the Appid key.
|
||
In Arguments:
|
||
pMessage - Message block passing arguments between modules.
|
||
pCLSID - pointer to class representing the registry key.
|
||
pClassEntry - The class entry data structure to update.
|
||
Out Arguments:
|
||
pAppIdBuffer- Buffer which receives the stringized appid value.
|
||
InOut Arguments:
|
||
None.
|
||
Return Arguments:
|
||
Status.
|
||
Remarks:
|
||
This routine looks for the presence of an appid on a clsid. The appid
|
||
key will determine the appdetails structure that the clsid will go into.
|
||
|
||
*****************************************************************************/
|
||
{
|
||
|
||
LONG error;
|
||
APP_ENTRY * pAppEntry = 0;
|
||
DWORD SizeOfAppIDValue = SIZEOF_STRINGIZED_CLSID;
|
||
char AppIDValue[ SIZEOF_STRINGIZED_CLSID ];
|
||
BOOL fNewEntry = 0;
|
||
|
||
|
||
|
||
error = pCLSID->QueryValueEx( "AppID", &AppIDValue[0], &SizeOfAppIDValue );
|
||
|
||
if ( error == ERROR_SUCCESS )
|
||
{
|
||
memcpy( pAppidBuffer, &AppIDValue[0], SIZEOF_STRINGIZED_CLSID );
|
||
return 1;
|
||
}
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
void
|
||
SetCSPlatform(
|
||
CSPLATFORM * pCSPlatform )
|
||
{
|
||
// OSVERSIONINFO VersionInformation;
|
||
|
||
// VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||
// GetVersionEx(&VersionInformation);
|
||
|
||
// pCSPlatform->dwPlatformId = VersionInformation.dwPlatformId;
|
||
// pCSPlatform->dwVersionHi = VersionInformation.dwMajorVersion;
|
||
// pCSPlatform->dwVersionLo = VersionInformation.dwMinorVersion;
|
||
|
||
#if 0
|
||
// this is not supported for Beta 1
|
||
pCSPlatform->dwPlatformId = -1; // any OS platform
|
||
pCSPlatform->dwVersionHi = 0;
|
||
pCSPlatform->dwVersionLo = 0;
|
||
#else
|
||
pCSPlatform->dwPlatformId = VER_PLATFORM_WIN32_NT;
|
||
pCSPlatform->dwVersionHi = 5;
|
||
pCSPlatform->dwVersionLo = 0;
|
||
#endif
|
||
|
||
// pCSPlatform->dwProcessorArch = PROCESSOR_ARCHITECTURE_INTEL;
|
||
|
||
SYSTEM_INFO si;
|
||
GetSystemInfo(&si);
|
||
|
||
pCSPlatform->dwProcessorArch = si.wProcessorArchitecture;
|
||
}
|
||
|